private Code readBinaryOp( int opcode, boolean wideBase, boolean wideRest, int offset, HashMap<Integer, Code.Label> labels) throws IOException { int leftOperand = readBase(wideBase); int rightOperand = readBase(wideBase); int typeIdx = readRest(wideRest); Type type = typePool[typeIdx]; switch (opcode) { case Code.OPCODE_asserteq: case Code.OPCODE_assertne: case Code.OPCODE_assertlt: case Code.OPCODE_assertle: case Code.OPCODE_assertgt: case Code.OPCODE_assertge: case Code.OPCODE_assertel: case Code.OPCODE_assertss: case Code.OPCODE_assertse: { int msgIdx = readRest(wideRest); String msg = stringPool[msgIdx]; Code.Comparator cop = Code.Comparator.values()[opcode - Code.OPCODE_asserteq]; return Code.Assert(type, leftOperand, rightOperand, cop, msg); } case Code.OPCODE_assumeeq: case Code.OPCODE_assumene: case Code.OPCODE_assumelt: case Code.OPCODE_assumele: case Code.OPCODE_assumegt: case Code.OPCODE_assumege: case Code.OPCODE_assumeel: case Code.OPCODE_assumess: case Code.OPCODE_assumese: { int msgIdx = readRest(wideRest); String msg = stringPool[msgIdx]; Code.Comparator cop = Code.Comparator.values()[opcode - Code.OPCODE_assumeeq]; return Code.Assume(type, leftOperand, rightOperand, cop, msg); } case Code.OPCODE_ifeq: case Code.OPCODE_ifne: case Code.OPCODE_iflt: case Code.OPCODE_ifle: case Code.OPCODE_ifgt: case Code.OPCODE_ifge: case Code.OPCODE_ifel: case Code.OPCODE_ifss: case Code.OPCODE_ifse: { int target = readTarget(wideRest, offset); Code.Label l = findLabel(target, labels); Code.Comparator cop = Code.Comparator.values()[opcode - Code.OPCODE_ifeq]; return Code.If(type, leftOperand, rightOperand, cop, l.label); } } throw new RuntimeException("unknown opcode encountered (" + opcode + ")"); }
private Code readEmpty( int opcode, boolean wideBase, boolean wideRest, int offset, HashMap<Integer, Code.Label> labels) throws IOException { switch (opcode) { case Code.OPCODE_const: { int target = readBase(wideBase); int idx = readRest(wideRest); Constant c = constantPool[idx]; return Code.Const(target, c); } case Code.OPCODE_goto: { int target = readTarget(wideRest, offset); Code.Label lab = findLabel(target, labels); return Code.Goto(lab.label); } case Code.OPCODE_nop: return Code.Nop; case Code.OPCODE_returnv: return Code.Return(); } throw new RuntimeException("unknown opcode encountered (" + opcode + ")"); }
private static Code.LoopEnd findLoopLabel(int target, HashMap<Integer, Code.Label> labels) { Code.Label label = labels.get(target); if (label == null) { Code.LoopEnd end = Code.LoopEnd("label" + labelCount++); labels.put(target, end); return end; } else { Code.LoopEnd end = Code.LoopEnd(label.label); labels.put(target, end); return end; } }
private static Code.Label findLabel(int target, HashMap<Integer, Code.Label> labels) { Code.Label label = labels.get(target); if (label == null) { label = Code.Label("label" + labelCount++); labels.put(target, label); } return label; }
private Code readOther( int opcode, boolean wideBase, boolean wideRest, int offset, HashMap<Integer, Code.Label> labels) throws IOException { switch (opcode) { case Code.OPCODE_trycatch: { int operand = readBase(wideBase); int target = readTarget(wideRest, offset); Code.Label l = findLabel(target, labels); int nCatches = readRest(wideRest); ArrayList<Pair<Type, String>> catches = new ArrayList<Pair<Type, String>>(); for (int i = 0; i != nCatches; ++i) { Type type = typePool[readRest(wideRest)]; Code.Label handler = findLabel(readTarget(wideRest, offset), labels); catches.add(new Pair<Type, String>(type, handler.label)); } return Code.TryCatch(operand, l.label, catches); } case Code.OPCODE_update: { int target = readBase(wideBase); int nOperands = readBase(wideBase) - 1; int operand = readBase(wideBase); int[] operands = new int[nOperands]; for (int i = 0; i != nOperands; ++i) { operands[i] = readBase(wideBase); } Type beforeType = typePool[readRest(wideRest)]; Type afterType = typePool[readRest(wideRest)]; int nFields = readRest(wideRest); ArrayList<String> fields = new ArrayList<String>(); for (int i = 0; i != nFields; ++i) { String field = stringPool[readRest(wideRest)]; fields.add(field); } return Code.Update(beforeType, target, operand, operands, afterType, fields); } } throw new RuntimeException("unknown opcode encountered (" + opcode + ")"); }
private Code readUnaryOp( int opcode, boolean wideBase, boolean wideRest, int offset, HashMap<Integer, Code.Label> labels) throws IOException { int operand = readBase(wideBase); int typeIdx = readRest(wideRest); Type type = typePool[typeIdx]; switch (opcode) { case Code.OPCODE_debug: return Code.Debug(operand); case Code.OPCODE_ifis: { int resultIdx = readRest(wideRest); Type result = typePool[resultIdx]; int target = readTarget(wideRest, offset); Code.Label l = findLabel(target, labels); return Code.IfIs(type, operand, result, l.label); } case Code.OPCODE_throw: return Code.Throw(type, operand); case Code.OPCODE_return: return Code.Return(type, operand); case Code.OPCODE_switch: { ArrayList<Pair<Constant, String>> cases = new ArrayList<Pair<Constant, String>>(); int target = readTarget(wideRest, offset); Code.Label defaultLabel = findLabel(target, labels); int nCases = readRest(wideRest); for (int i = 0; i != nCases; ++i) { int constIdx = readRest(wideRest); Constant constant = constantPool[constIdx]; target = readTarget(wideRest, offset); Code.Label l = findLabel(target, labels); cases.add(new Pair<Constant, String>(constant, l.label)); } return Code.Switch(type, operand, defaultLabel.label, cases); } } throw new RuntimeException("unknown opcode encountered (" + opcode + ")"); }
private Code readNaryAssign(int opcode, boolean wideBase, boolean wideRest) throws IOException { int target = readBase(wideBase); int nOperands = readBase(wideBase); int[] operands = new int[nOperands]; for (int i = 0; i != nOperands; ++i) { operands[i] = readBase(wideBase); } int typeIdx = readRest(wideRest); Type type = typePool[typeIdx]; switch (opcode) { case Code.OPCODE_indirectinvokefn: case Code.OPCODE_indirectinvokemd: { if (!(type instanceof Type.FunctionOrMethod)) { throw new RuntimeException("expected function or method type"); } int operand = operands[0]; operands = Arrays.copyOfRange(operands, 1, operands.length); return Code.IndirectInvoke((Type.FunctionOrMethod) type, target, operand, operands); } case Code.OPCODE_invokefn: case Code.OPCODE_invokemd: { if (!(type instanceof Type.FunctionOrMethod)) { throw new RuntimeException("expected function or method type"); } int nameIdx = readRest(wideRest); NameID nid = namePool[nameIdx]; return Code.Invoke((Type.FunctionOrMethod) type, target, operands, nid); } case Code.OPCODE_lambdafn: case Code.OPCODE_lambdamd: { if (!(type instanceof Type.FunctionOrMethod)) { throw new RuntimeException("expected function or method type"); } // Lambda's are the only instances of NULLABLENARYASSIGN's for (int i = 0; i != operands.length; ++i) { operands[i] -= 1; } int nameIdx = readRest(wideRest); NameID nid = namePool[nameIdx]; return Code.Lambda((Type.FunctionOrMethod) type, target, operands, nid); } case Code.OPCODE_newmap: { if (!(type instanceof Type.Map)) { throw new RuntimeException("expected map type"); } return Code.NewMap((Type.Map) type, target, operands); } case Code.OPCODE_newrecord: { if (!(type instanceof Type.Record)) { throw new RuntimeException("expected record type"); } return Code.NewRecord((Type.Record) type, target, operands); } case Code.OPCODE_newlist: { if (!(type instanceof Type.List)) { throw new RuntimeException("expected list type"); } return Code.NewList((Type.List) type, target, operands); } case Code.OPCODE_newset: { if (!(type instanceof Type.Set)) { throw new RuntimeException("expected set type"); } return Code.NewSet((Type.Set) type, target, operands); } case Code.OPCODE_newtuple: { if (!(type instanceof Type.Tuple)) { throw new RuntimeException("expected tuple type"); } return Code.NewTuple((Type.Tuple) type, target, operands); } case Code.OPCODE_sublist: { if (!(type instanceof Type.EffectiveList)) { throw new RuntimeException("expected list type"); } return Code.SubList( (Type.EffectiveList) type, target, operands[0], operands[1], operands[2]); } case Code.OPCODE_substring: { if (!(type instanceof Type.Strung)) { throw new RuntimeException("expected string type"); } return Code.SubString(target, operands[0], operands[1], operands[2]); } } throw new RuntimeException("unknown opcode encountered (" + opcode + ")"); }
private Code readNaryOp( int opcode, boolean wideBase, boolean wideRest, int offset, HashMap<Integer, Code.Label> labels) throws IOException { int nOperands = readBase(wideBase); int[] operands = new int[nOperands]; for (int i = 0; i != nOperands; ++i) { operands[i] = readBase(wideBase); } if (opcode == Code.OPCODE_loop) { // special case which doesn't have a type. int target = readTarget(wideRest, offset); Code.LoopEnd l = findLoopLabel(target, labels); return Code.Loop(l.label, operands); } int typeIdx = readRest(wideRest); Type type = typePool[typeIdx]; switch (opcode) { case Code.OPCODE_forall: { if (!(type instanceof Type.EffectiveCollection)) { throw new RuntimeException("expected collection type"); } int target = readTarget(wideRest, offset); Code.LoopEnd l = findLoopLabel(target, labels); int indexOperand = operands[0]; int sourceOperand = operands[1]; operands = Arrays.copyOfRange(operands, 2, operands.length); return Code.ForAll( (Type.EffectiveCollection) type, sourceOperand, indexOperand, operands, l.label); } case Code.OPCODE_indirectinvokefnv: case Code.OPCODE_indirectinvokemdv: { if (!(type instanceof Type.FunctionOrMethod)) { throw new RuntimeException("expected function or method type"); } int operand = operands[0]; operands = Arrays.copyOfRange(operands, 1, operands.length); return Code.IndirectInvoke( (Type.FunctionOrMethod) type, Code.NULL_REG, operand, operands); } case Code.OPCODE_invokefnv: case Code.OPCODE_invokemdv: { if (!(type instanceof Type.FunctionOrMethod)) { throw new RuntimeException("expected function or method type"); } int nameIdx = readRest(wideRest); ; NameID nid = namePool[nameIdx]; return Code.Invoke((Type.FunctionOrMethod) type, Code.NULL_REG, operands, nid); } } throw new RuntimeException("unknown opcode encountered (" + opcode + ")"); }
private Code readBinaryAssign(int opcode, boolean wideBase, boolean wideRest) throws IOException { int target = readBase(wideBase); int leftOperand = readBase(wideBase); int rightOperand = readBase(wideBase); int typeIdx = readRest(wideRest); Type type = typePool[typeIdx]; switch (opcode) { case Code.OPCODE_append: case Code.OPCODE_appendl: case Code.OPCODE_appendr: { if (!(type instanceof Type.EffectiveList)) { throw new RuntimeException("expecting list type"); } Code.BinListKind kind = Code.BinListKind.values()[opcode - Code.OPCODE_append]; return Code.BinListOp((Type.EffectiveList) type, target, leftOperand, rightOperand, kind); } case Code.OPCODE_sappend: case Code.OPCODE_sappendl: case Code.OPCODE_sappendr: { if (!(type instanceof Type.Strung)) { throw new RuntimeException("expecting string type"); } Code.BinStringKind kind = Code.BinStringKind.values()[opcode - Code.OPCODE_sappend]; return Code.BinStringOp(target, leftOperand, rightOperand, kind); } case Code.OPCODE_indexof: { if (!(type instanceof Type.EffectiveIndexible)) { throw new RuntimeException("expecting indexible type"); } return Code.IndexOf((Type.EffectiveIndexible) type, target, leftOperand, rightOperand); } case Code.OPCODE_add: case Code.OPCODE_sub: case Code.OPCODE_mul: case Code.OPCODE_div: case Code.OPCODE_rem: case Code.OPCODE_range: case Code.OPCODE_bitwiseor: case Code.OPCODE_bitwisexor: case Code.OPCODE_bitwiseand: case Code.OPCODE_lshr: case Code.OPCODE_rshr: { Code.BinArithKind kind = Code.BinArithKind.values()[opcode - Code.OPCODE_add]; return Code.BinArithOp(type, target, leftOperand, rightOperand, kind); } case Code.OPCODE_union: case Code.OPCODE_unionl: case Code.OPCODE_unionr: case Code.OPCODE_intersect: case Code.OPCODE_intersectl: case Code.OPCODE_intersectr: case Code.OPCODE_difference: case Code.OPCODE_differencel: { if (!(type instanceof Type.EffectiveSet)) { throw new RuntimeException("expecting set type"); } Code.BinSetKind kind = Code.BinSetKind.values()[opcode - Code.OPCODE_union]; return Code.BinSetOp((Type.EffectiveSet) type, target, leftOperand, rightOperand, kind); } } throw new RuntimeException("unknown opcode encountered (" + opcode + ")"); }
private Code readUnaryAssign(int opcode, boolean wideBase, boolean wideRest) throws IOException { int target = readBase(wideBase); int operand = readBase(wideBase); int typeIdx = readRest(wideRest); Type type = typePool[typeIdx]; switch (opcode) { case Code.OPCODE_convert: { int i = readRest(wideRest); Type t = typePool[i]; return Code.Convert(type, target, operand, t); } case Code.OPCODE_assign: return Code.Assign(type, target, operand); case Code.OPCODE_dereference: { if (!(type instanceof Type.Reference)) { throw new RuntimeException("expected reference type"); } return Code.Dereference((Type.Reference) type, target, operand); } case Code.OPCODE_fieldload: { if (!(type instanceof Type.EffectiveRecord)) { throw new RuntimeException("expected record type"); } int i = readRest(wideRest); String field = stringPool[i]; return Code.FieldLoad((Type.EffectiveRecord) type, target, operand, field); } case Code.OPCODE_invert: return Code.Invert(type, target, operand); case Code.OPCODE_newobject: { if (!(type instanceof Type.Reference)) { throw new RuntimeException("expected reference type"); } return Code.NewObject((Type.Reference) type, target, operand); } case Code.OPCODE_lengthof: { if (!(type instanceof Type.EffectiveCollection)) { throw new RuntimeException("expected collection type"); } return Code.LengthOf((Type.EffectiveCollection) type, target, operand); } case Code.OPCODE_move: return Code.Move(type, target, operand); case Code.OPCODE_neg: return Code.UnArithOp(type, target, operand, Code.UnArithKind.NEG); case Code.OPCODE_numerator: return Code.UnArithOp(type, target, operand, Code.UnArithKind.NUMERATOR); case Code.OPCODE_denominator: return Code.UnArithOp(type, target, operand, Code.UnArithKind.DENOMINATOR); case Code.OPCODE_not: { if (!(type instanceof Type.Bool)) { throw new RuntimeException("expected bool type"); } return Code.Not(target, operand); } case Code.OPCODE_tupleload: { if (!(type instanceof Type.EffectiveTuple)) { throw new RuntimeException("expected tuple type"); } int index = readRest(wideRest); return Code.TupleLoad((Type.Tuple) type, target, operand, index); } } throw new RuntimeException("unknown opcode encountered (" + opcode + ")"); }