// // 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); } }
// // called by the .bytecode directive // void setVersion(Number version) { // int V1_1 = 3 << 16 | 45; // int V1_2 = 0 << 16 | 46; // int V1_3 = 0 << 16 | 47; // int V1_4 = 0 << 16 | 48; // int V1_5 = 0 << 16 | 49; // int V1_6 = 0 << 16 | 50; // int V1_7 = 0 << 16 | 51; String str = version.toString(); String key = "[" + str + "]"; if ("[5][1.5][5.0][49.0]".contains(key)) { this.class_env.setVersion((short) 49, (short) 0); } else if ("[6][1.6][6.0][50.0]".contains(key)) { this.class_env.setVersion((short) 50, (short) 0); } else if ("[7][1.7][7.0][51.0]".contains(key)) { this.class_env.setVersion((short) 51, (short) 0); } else if ("[4][1.4][4.0][48.0]".contains(key)) { this.class_env.setVersion((short) 48, (short) 0); } else if ("[3][1.3][3.0][47.0]".contains(key)) { this.class_env.setVersion((short) 47, (short) 0); } else if ("[2][1.2][2.0][46.0]".contains(key)) { this.class_env.setVersion((short) 46, (short) 0); } else if ("[1][1.1][1.0][45.3]".contains(key)) { this.class_env.setVersion((short) 45, (short) 3); } else { int idx = str.indexOf("."); try { if (idx > 0) { class_env.setVersion( Short.parseShort(str.substring(0, idx)), Short.parseShort(str.substring(idx + 1, str.length()))); } else { class_env.setVersion(version.shortValue(), (short) 0); } } catch (Exception ex) { report_error("invalid bytecode version number : " + str); } } }
// // 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 */ }