Пример #1
0
 //
 // used to initialize the infoTable table (see below)
 //
 private static void addInfo(String name, int opcode, String args) {
   InsnInfo info = new InsnInfo();
   info.name = name;
   info.opcode = opcode;
   info.args = args;
   infoTable.put(name, info);
 }
Пример #2
0
 //
 // used for relative branch targets (ie $+5, $-12, ...)
 //
 void plantRelativeGoto(String name, int val) throws jasError {
   InsnInfo insn = InsnInfo.get(name);
   if (insn.args.equals("label")) {
     bufferInsn(new Insn(insn.opcode, val, true));
   } else { // forward the request for "normal" instructions
     plant(name, val);
   }
 }
Пример #3
0
  //
  // used for ldc <quoted-string>
  //
  void plantString(String name, String val) throws jasError {
    InsnInfo insn = InsnInfo.get(name);
    autoNumber();
    flushInsnBuffer();

    if (name.startsWith("ldc")) {
      bufferInsn(new Insn(insn.opcode, new StringCP(val)));
    } else {
      throw new jasError("Bad arguments for instruction " + name);
    }
  }
Пример #4
0
  //
  // used for iinc
  //
  void plant(String name, int v1, int v2) throws jasError {
    InsnInfo insn = InsnInfo.get(name);
    autoNumber();
    flushInsnBuffer();

    if (insn.args.equalsIgnoreCase("ii")) {
      bufferInsn(new IincInsn(v1, v2, insn.args.charAt(0) == 'I'));
    } else {
      throw new jasError("Bad arguments for instruction " + name);
    }
  }
Пример #5
0
  //
  // used for instructions that take no arguments
  //
  void plant(String name) throws jasError {
    InsnInfo insn = InsnInfo.get(name);
    autoNumber();
    flushInsnBuffer();

    if (insn.args.equals("")) {
      bufferInsn(new Insn(insn.opcode));
    } else {
      throw new jasError("Missing arguments for instruction " + name);
    }
  }
Пример #6
0
  //
  // used for instructions that take a field and a signature as parameters
  // (e.g. getstatic, putstatic)
  //
  void plant(String name, String v1, String v2) throws jasError {
    InsnInfo info = InsnInfo.get(name);
    CodeAttr code = _getCode();
    autoNumber();
    flushInsnBuffer();

    if (info.args.equals("field")) {
      String split[] = ScannerUtils.splitClassField(v1);
      if (split[1] == null) throw new jasError("can't extract field from " + v1);
      bufferInsn(new Insn(info.opcode, new FieldCP(split[0], split[1], v2)));
    } else {
      throw new jasError("Bad arguments for instruction " + name);
    }
  }
Пример #7
0
  //
  // used for instructions that take a word as a parameter
  // (e.g. branches, newarray, invokemethod)
  //
  void plant(String name, String val) throws jasError {
    InsnInfo insn = InsnInfo.get(name);
    CodeAttr code = _getCode();
    autoNumber();
    flushInsnBuffer();

    if (insn.args.equals("method")) {
      String split[] = ScannerUtils.splitClassMethodSignature(val);
      bufferInsn(new Insn(insn.opcode, new MethodCP(split[0], split[1], split[2])));
    } else if (insn.args.equals("interface")) {
      String split[] = ScannerUtils.splitClassMethodSignature(val);
      bufferInsn(
          new InvokeinterfaceInsn(
              new InterfaceCP(split[0], split[1], split[2]),
              ScannerUtils.getArgumentsAndReturnSizes(split[2]) >> 2));
    } else if (name.startsWith("ldc")) {
      bufferInsn(new Insn(insn.opcode, new ClassCP(val)));
    } else if (insn.args.equals("atype")) {
      int atype = 0;
      if (val.equals("boolean")) {
        atype = 4;
      } else if (val.equals("char")) {
        atype = 5;
      } else if (val.equals("float")) {
        atype = 6;
      } else if (val.equals("double")) {
        atype = 7;
      } else if (val.equals("byte")) {
        atype = 8;
      } else if (val.equals("short")) {
        atype = 9;
      } else if (val.equals("int")) {
        atype = 10;
      } else if (val.equals("long")) {
        atype = 11;
      } else {
        throw new jasError("Bad array type: " + name);
      }
      bufferInsn(new Insn(insn.opcode, atype, false));
    } else if (insn.args.indexOf("label") >= 0) {
      bufferInsn(new Insn(insn.opcode, getLabel(val), scanner.line_num));
    } else if (insn.args.equals("class")) {
      bufferInsn(new Insn(insn.opcode, new ClassCP(val)));
    } else {
      throw new jasError("(gloups)Bad arguments for instruction " + name);
    }
  }
Пример #8
0
  //
  // used for instructions that take an integer parameter
  // (branches are part of this, the int is converted to a label)
  //
  void plant(String name, int val) throws jasError {
    InsnInfo insn = InsnInfo.get(name);
    CodeAttr code = _getCode();
    autoNumber();
    flushInsnBuffer();

    if (insn.args.equalsIgnoreCase("i")) {
      bufferInsn(new Insn(insn.opcode, val, insn.args.charAt(0) == 'I'));
    } else if (name.startsWith("ldc")) {
      bufferInsn(new Insn(insn.opcode, new IntegerCP(val)));
    } else if (insn.args.equals("label")) {
      plant(name, String.valueOf(val)); // the target is not signed
      // assume it is a label
    } else {
      throw new jasError("Bad arguments for instruction " + name);
    }
  }
Пример #9
0
  //
  // used for invokeinterface and multianewarray
  //
  void plant(String name, String val, int nargs) throws jasError {
    InsnInfo insn = InsnInfo.get(name);
    CodeAttr code = _getCode();
    autoNumber();
    flushInsnBuffer();

    if (insn.args.equals("interface")) {
      String split[] = ScannerUtils.splitClassMethodSignature(val);
      bufferInsn(
          new InvokeinterfaceInsn(
              new InterfaceCP(split[0], split[1], split[2]),
              ScannerUtils.getArgumentsAndReturnSizes(split[2]) >> 2));

    } else if (insn.args.equals("marray")) {
      bufferInsn(new MultiarrayInsn(new ClassCP(val), nargs));
    } else {
      throw new jasError("Bad arguments for instruction " + name);
    }
  }
Пример #10
0
  //
  // used for ldc and other instructions that take a numeric argument
  //
  void plant(String name, Number val) throws jasError {
    InsnInfo insn = InsnInfo.get(name);
    CodeAttr code = _getCode();
    autoNumber();
    flushInsnBuffer();

    if (insn.args.equalsIgnoreCase("i") && (val instanceof Integer)) {
      bufferInsn(new Insn(insn.opcode, val.intValue(), insn.args.charAt(0) == 'I'));
    } else if (name.startsWith("ldc")) {
      if (val instanceof Integer) {
        bufferInsn(new Insn(insn.opcode, new IntegerCP(val.intValue())));
      } else if (val instanceof Float) {
        bufferInsn(new Insn(insn.opcode, new FloatCP(val.floatValue())));
      } else if (val instanceof Long) {
        bufferInsn(new Insn(insn.opcode, new LongCP(val.longValue())));
      } else if (val instanceof Double) {
        bufferInsn(new Insn(insn.opcode, new DoubleCP(val.doubleValue())));
      }
    } else {
      throw new jasError("Bad arguments for instruction " + name);
    }
  }
Пример #11
0
  //
  // recognize and return the next complete token
  //
  public token next_token() throws java.io.IOException, jasError {
    token_line_num = line_num;

    for (; ; )
      switch (next_char) {
        case ';': // a comment
        case '\n':
          // return single SEP token (skip multiple newlines
          // interspersed with whitespace or comments)
          skip_empty_lines();
          token_line_num = line_num;
          return new token(sym.SEP);

        case -1: // EOF token
          char_num = -1;
          return new token(sym.EOF);

        case '-':
        case '+':
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case '.': // a number
          {
            int pos = 0;
            do {
              chars[pos] = (char) next_char;
              pos++;
              if (pos == chars_size) chars_expand();
              advance();
            } while (!separator(next_char));

            String str = new String(chars, 0, pos);
            token tok;

            // This catches directives like ".method"
            if ((tok = ReservedWords.get(str)) != null) return tok;

            Number num;
            try {
              num = ScannerUtils.convertNumber(str);
            } catch (NumberFormatException e) {
              if (chars[0] != '.') throw new jasError("Badly formatted number");
              throw new jasError("Unknown directive or badly formed number.");
            }

            if (num instanceof Integer) {
              int_line = line.toString();
              int_line_num = token_line_num;
              int_char_num = char_num;
              return new int_token(sym.Int, num.intValue());
            }
            return new num_token(sym.Num, num);
          }

        case '"': // quoted string
          {
            boolean already = false;
            for (int pos = 0; ; ) {
              if (already) already = false;
              else advance();

              if (next_char == '"') {
                advance(); // skip close quote
                return new str_token(sym.Str, new String(chars, 0, pos));
              }

              if (next_char == -1) throw new jasError("Unterminated string");

              char chval = (char) next_char;

              if (chval == '\\') {
                advance();
                switch (next_char) {
                  case -1:
                    already = true;
                    continue;
                  case 'n':
                    chval = '\n';
                    break;
                  case 'r':
                    chval = '\r';
                    break;
                  case 't':
                    chval = '\t';
                    break;
                  case 'f':
                    chval = '\f';
                    break;
                  case 'b':
                    chval = '\b';
                    break;
                  case '"':
                    chval = '"';
                    break;
                  case '\'':
                    chval = '\'';
                    break;
                  case '\\':
                    chval = '\\';
                    break;

                  case 'u':
                    chval = uniEscape();
                    if (next_char == -1) {
                      already = true;
                      continue;
                    }
                    break;

                  case '0':
                  case '1':
                  case '2':
                  case '3':
                  case '4':
                  case '5':
                  case '6':
                  case '7':
                    {
                      int res = next_char & 7;
                      advance();
                      if (next_char < '0' || next_char > '7') already = true;
                      else {
                        res = res * 8 + (next_char & 7);
                        advance();
                        if (next_char < '0' || next_char > '7') already = true;
                        else {
                          int val = res * 8 + (next_char & 7);
                          if (val >= 0x100) already = true;
                          else res = val;
                        }
                      }
                      chval = (char) res;
                    }
                    break;

                  default:
                    throw new jasError("Bad backslash escape sequence");
                }
              }
              chars[pos] = chval;
              pos++;
              if (pos == chars_size) chars_expand();
            }
          }

        case '\'': // quotation for overloading reserved words
          for (int pos = 0; ; ) {
            advance();
            if (separator(next_char)) throw new jasError("Unterminated ''-enclosed name");
            if (next_char == '\'') {
              if (pos == 0) throw new jasError("Empty ''-enclosed name");
              advance(); // skip close quote
              if (!separator(next_char)) throw new jasError("Not separator after ''-enclosed name");
              return new str_token(sym.Word, new String(chars, 0, pos));
            }
            char chval = (char) next_char;
            if (next_char == '\\') chval = nameEscape();
            chars[pos] = chval;
            pos++;
            if (pos == chars_size) chars_expand();
          }

        case ' ':
        case '\t':
        case '\r': // whitespace
          advance();
          break;

        case '=': // EQUALS token
          advance();
          return new token(sym.EQ);

        case ':': // COLON token
          advance();
          return new token(sym.COLON);

        default:
          {
            // read up until a separatorcharacter
            int pos = 0;
            boolean only_name = false;

            do {
              char chval = (char) next_char;
              if (next_char == '\\') {
                chval = nameEscape();
                only_name = true;
              }
              chars[pos] = chval;
              pos++;
              if (pos == chars_size) chars_expand();
              advance();
            } while (!separator(next_char));
            // convert the byte array into a String
            String str = new String(chars, 0, pos);

            if (!only_name) {
              token tok;

              // Jasmin keyword or directive ?
              if ((tok = ReservedWords.get(str)) != null) return tok;

              // its a JVM instruction ?
              if (InsnInfo.contains(str)) return new str_token(sym.Insn, str);

              if (str.charAt(0) == '$') {
                String s = str.substring(1);
                Object v;
                int n = 10;
                boolean neg = false;
                boolean sign = false;
                switch (s.charAt(0)) {
                  default:
                    break;

                  case '-':
                    neg = true;
                    ;
                  case '+':
                    s = s.substring(1);
                    if (s.startsWith("0x")) {
                      n = 16;
                      s = s.substring(2);
                    }
                    try {
                      n = Integer.parseInt(s, n);
                    } catch (NumberFormatException e) {
                      throw new jasError("Badly relative offset number");
                    }
                    if (neg) n = -n;
                    return new relative_num_token(sym.Relative, n);
                }
                // Perform variable substitution
                if ((v = dict.get(s)) != null) return (token) v;
              } // not begin from '$'
            } // !only_name
            // Unrecognized string token (e.g. a classname)
            return new str_token(sym.Word, str);
          } /* default */
      } /* switch and for */
  }