blob: 6b60f292bbbcd59a4439755f43409be63b57761d [file] [log] [blame]
// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.code;
import com.android.tools.r8.graph.OffsetToObjectMapping;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.List;
public class InstructionFactory extends BaseInstructionFactory {
static private Instruction readFrom(ShortBufferBytecodeStream stream,
OffsetToObjectMapping mapping) {
int high = stream.nextByte();
int opcode = stream.nextByte();
return create(high, opcode, stream, mapping);
}
public Instruction[] readSequenceFrom(ShortBuffer buffer, int startIndex, int length,
OffsetToObjectMapping mapping) {
ShortBufferBytecodeStream range =
new ShortBufferBytecodeStream(buffer, startIndex, length);
List<Instruction> insn = new ArrayList<>(length);
while (range.hasMore()) {
Instruction instruction = readFrom(range, mapping);
insn.add(instruction);
}
return insn.toArray(Instruction.EMPTY_ARRAY);
}
private static class ShortBufferBytecodeStream implements BytecodeStream {
private final int length;
private final int startIndex;
private final ShortBuffer source;
private int offset = 0;
private int nextByte;
private boolean cacheContainsValidByte = false;
ShortBufferBytecodeStream(ShortBuffer source, int startIndex, int length) {
this.startIndex = startIndex;
this.length = length;
this.source = source;
}
@Override
public int nextShort() {
assert !cacheContainsValidByte : "Unread byte in cache.";
assert offset < length;
int result = source.get(startIndex + offset);
offset += 1;
return result;
}
@Override
public int nextByte() {
if (cacheContainsValidByte) {
cacheContainsValidByte = false;
return nextByte;
} else {
int next = nextShort();
nextByte = next & 0xff;
cacheContainsValidByte = true;
return (next >> 8) & 0xff;
}
}
@Override
public boolean hasMore() {
return length - offset > 0;
}
@Override
public int getOffset() {
return offset;
}
}
}