예제 #1
0
 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 + ")");
 }
예제 #2
0
 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 + ")");
 }
예제 #3
0
 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;
   }
 }
예제 #4
0
 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;
 }
예제 #5
0
 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 + ")");
 }
예제 #6
0
 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 + ")");
 }
예제 #7
0
 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 + ")");
 }
예제 #8
0
  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 + ")");
  }
예제 #9
0
 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 + ")");
 }
예제 #10
0
  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 + ")");
  }