| // 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; |
| } |
| } |
| } |