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 + ")"); }