/** * Adds a merged type in the type table of this symbol table. Does nothing if the type table * already contains a similar type. * * @param typeTableIndex1 a {@link Symbol#TYPE_TAG} type, specified by its index in the type * table. * @param typeTableIndex2 another {@link Symbol#TYPE_TAG} type, specified by its index in the type * table. * @return the index of a new or already existing {@link Symbol#TYPE_TAG} type Symbol, * corresponding to the common super class of the given types. */ int addMergedType(final int typeTableIndex1, final int typeTableIndex2) { // TODO sort the arguments? The merge result should be independent of their order. long data = typeTableIndex1 | (((long) typeTableIndex2) << 32); int hashCode = hash(Symbol.MERGED_TYPE_TAG, typeTableIndex1 + typeTableIndex2); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == Symbol.MERGED_TYPE_TAG && entry.hashCode == hashCode && entry.data == data) { return entry.info; } entry = entry.next; } String type1 = typeTable[typeTableIndex1].value; String type2 = typeTable[typeTableIndex2].value; int commonSuperTypeIndex = addType(classWriter.getCommonSuperClass(type1, type2)); put(new Entry(typeCount, Symbol.MERGED_TYPE_TAG, data, hashCode)).info = commonSuperTypeIndex; return commonSuperTypeIndex; }
@Override public final void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) { this.version = version; this.access = access; this.name = newClass(name); thisName = name; if (ClassReader.SIGNATURES && signature != null) { this.signature = newUTF8(signature); } this.superName = superName == null ? 0 : newClass(superName); if (interfaces != null && interfaces.length > 0) { interfaceCount = interfaces.length; this.interfaces = new int[interfaceCount]; for (int i = 0; i < interfaceCount; ++i) { this.interfaces[i] = newClass(interfaces[i]); } } }
/** * Adds a class reference to the constant pool of the class being build. * Does nothing if the constant pool already contains a similar item. * <i>This method is intended for {@link Attribute} sub classes, and is * normally not needed by class generators or adapters.</i> * * @param value * the internal name of the class. * @return the index of a new or already existing class reference item. */ public int newClass(final String value) { return newClassItem(value).index; }
@Override public final void visitOuterClass(final String owner, final String name, final String desc) { enclosingMethodOwner = newClass(owner); if (name != null && desc != null) { enclosingMethod = newNameType(name, desc); } }
if (cst instanceof Integer) { int val = ((Integer) cst).intValue(); return newInteger(val); } else if (cst instanceof Byte) { int val = ((Byte) cst).intValue(); return newInteger(val); } else if (cst instanceof Character) { int val = ((Character) cst).charValue(); return newInteger(val); } else if (cst instanceof Short) { int val = ((Short) cst).intValue(); return newInteger(val); } else if (cst instanceof Boolean) { int val = ((Boolean) cst).booleanValue() ? 1 : 0; return newInteger(val); } else if (cst instanceof Float) { float val = ((Float) cst).floatValue(); return newFloat(val); } else if (cst instanceof Long) { long val = ((Long) cst).longValue(); return newLong(val); } else if (cst instanceof Double) { double val = ((Double) cst).doubleValue(); return newDouble(val); } else if (cst instanceof String) { return newString((String) cst); } else if (cst instanceof Type) { Type t = (Type) cst; int s = t.getSort();
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES); return cw.toByteArray();
/** * Adds a method reference to the constant pool of the class being build. * Does nothing if the constant pool already contains a similar item. * * @param owner * the internal name of the method's owner class. * @param name * the method's name. * @param desc * the method's descriptor. * @param itf * <tt>true</tt> if <tt>owner</tt> is an interface. * @return a new or already existing method reference item. */ Item newMethodItem(final String owner, final String name, final String desc, final boolean itf) { int type = itf ? IMETH : METH; key3.set(type, owner, name, desc); Item result = get(key3); if (result == null) { put122(type, newClass(owner), newNameType(name, desc)); result = new Item(index++, key3); put(result); } return result; }
bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name, bsm.desc)); Object bsmArg = bsmArgs[i]; hashCode ^= bsmArg.hashCode(); bootstrapMethods.putShort(newConst(bsmArg)); result = new Item(bootstrapMethodIndex); result.set(position, hashCode); put(result); result = get(key3); if (result == null) { put122(INDY, bootstrapMethodIndex, newNameType(name, desc)); result = new Item(index++, key3); put(result);
/** * Adds a class reference to the constant pool of the class being build. * Does nothing if the constant pool already contains a similar item. * <i>This method is intended for {@link Attribute} sub classes, and is * normally not needed by class generators or adapters.</i> * * @param value * the internal name of the class. * @return a new or already existing class reference item. */ Item newClassItem(final String value) { key2.set(CLASS, value, null, null); Item result = get(key2); if (result == null) { pool.put12(CLASS, newUTF8(value)); result = new Item(index++, key2); put(result); } return result; }
/** * Returns the index of the common super type of the two given types. This * method calls {@link #getCommonSuperClass} and caches the result in the * {@link #items} hash table to speedup future calls with the same * parameters. * * @param type1 * index of an internal name in {@link #typeTable}. * @param type2 * index of an internal name in {@link #typeTable}. * @return the index of the common super type of the two given types. */ int getMergedType(final int type1, final int type2) { key2.type = TYPE_MERGED; key2.longVal = type1 | (((long) type2) << 32); key2.hashCode = 0x7FFFFFFF & (TYPE_MERGED + type1 + type2); Item result = get(key2); if (result == null) { String t = typeTable[type1].strVal1; String u = typeTable[type2].strVal1; key2.intVal = addType(getCommonSuperClass(t, u)); result = new Item((short) 0, key2); put(result); } return result.intVal; }
final String desc) { key4.set(HANDLE_BASE + tag, owner, name, desc); Item result = get(key4); if (result == null) { if (tag <= Opcodes.H_PUTSTATIC) { put112(HANDLE, tag, newField(owner, name, desc)); } else { put112(HANDLE, tag, newMethod(owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE)); put(result);
newUTF8("BootstrapMethods"); newUTF8("Signature"); newUTF8("SourceFile"); newUTF8("SourceDebugExtension"); newUTF8("EnclosingMethod"); newUTF8("Deprecated"); ++attributeCount; size += 6; newUTF8("Synthetic"); ++attributeCount; size += 8 + innerClasses.length; newUTF8("InnerClasses"); newUTF8("RuntimeVisibleAnnotations"); newUTF8("RuntimeInvisibleAnnotations"); out.putShort(newUTF8("BootstrapMethods")); out.putInt(bootstrapMethods.length + 2).putShort( bootstrapMethodsCount); out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
/** * Adds a float to the constant pool of the class being build. Does nothing * if the constant pool already contains a similar item. * * @param value * the float value. * @return a new or already existing float item. */ Item newFloat(final float value) { key.set(value); Item result = get(key); if (result == null) { pool.putByte(FLOAT).putInt(key.intVal); result = new Item(index++, key); put(result); } return result; }
/** * Adds a name and type to the constant pool of the class being build. Does * nothing if the constant pool already contains a similar item. * * @param name * a name. * @param desc * a type descriptor. * @return a new or already existing name and type item. */ Item newNameTypeItem(final String name, final String desc) { key2.set(NAME_TYPE, name, desc, null); Item result = get(key2); if (result == null) { put122(NAME_TYPE, newUTF8(name), newUTF8(desc)); result = new Item(index++, key2); put(result); } return result; }
byte[] bytecode = cw.toByteArray(); DynamicClassLoader loader = (DynamicClassLoader) LOADER.deref(); return loader.defineClass(COMPILE_STUB_PREFIX + "." + ret.name, bytecode, frm);
/** * Adds the given "uninitialized" type to {@link #typeTable} and returns its * index. This method is used for UNINITIALIZED types, made of an internal * name and a bytecode offset. * * @param type * the internal name to be added to the type table. * @param offset * the bytecode offset of the NEW instruction that created this * UNINITIALIZED type value. * @return the index of this internal name in the type table. */ int addUninitializedType(final String type, final int offset) { key.type = TYPE_UNINIT; key.intVal = offset; key.strVal1 = type; key.hashCode = 0x7FFFFFFF & (TYPE_UNINIT + type.hashCode() + offset); Item result = get(key); if (result == null) { result = addType(key); } return result.index; }
if (local[i] instanceof String) { frame[frameIndex++] = Frame.OBJECT | cw.addType((String) local[i]); } else if (local[i] instanceof Integer) { frame[frameIndex++] = ((Integer) local[i]).intValue(); } else { frame[frameIndex++] = Frame.UNINITIALIZED | cw.addUninitializedType("", ((Label) local[i]).position); if (stack[i] instanceof String) { frame[frameIndex++] = Frame.OBJECT | cw.addType((String) stack[i]); } else if (stack[i] instanceof Integer) { frame[frameIndex++] = ((Integer) stack[i]).intValue(); } else { frame[frameIndex++] = Frame.UNINITIALIZED | cw.addUninitializedType("", ((Label) stack[i]).position);
| cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE); } else { v = OBJECT | cw.addType("java/lang/Object"); v = OBJECT | cw.addType("java/lang/Object"); } else {
@Override public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { ++handlerCount; Handler h = new Handler(); h.start = start; h.end = end; h.handler = handler; h.desc = type; h.type = type != null ? cw.newClass(type) : 0; if (lastHandler == null) { firstHandler = h; } else { lastHandler.next = h; } lastHandler = h; }