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