package org.jerlang.stdlib.beam_lib; import java.io.DataInputStream; import java.io.IOException; import org.jerlang.Opcode; import org.jerlang.erts.emulator.Instruction; public class CodeChunkReader extends AbstractChunkReader<CodeChunk> { private final InstructionReader instructionReader; public CodeChunkReader(Chunk chunk, DataInputStream inputStream, AtomChunk atomChunk, LiteralTableChunk literalTableChunk) { super(chunk, inputStream); instructionReader = new InstructionReader(inputStream, atomChunk, literalTableChunk); } public CodeChunk read() throws Throwable { CodeChunk codeChunk = new CodeChunk(chunk()); checkInfoSize(read4Bytes()); checkVersion(read4Bytes()); checkMaxOpcode(read4Bytes()); codeChunk.setInfo(read4Bytes(), read4Bytes()); int count = 0; while (codeChunk.add(nextInstruction(count++))); return codeChunk; } private void check(boolean condition, String message) { if (condition) { throw new Error(message); } } private void checkInfoSize(int infoSize) throws IOException { check(infoSize != 16, "Unexpected info-size header value: " + infoSize); } private void checkVersion(int version) throws IOException { check(version != 0, "Unsupported instruction set version: " + version); } private void checkMaxOpcode(int maxOpcode) throws IOException { check(maxOpcode > Opcode.max(), "maxOpcode > " + Opcode.max()); } private Instruction nextInstruction(int count) throws Throwable { Opcode opcode = Opcode.decode(read1Byte()); return instructionReader.read(count, opcode); } }