List of usage examples for org.objectweb.asm Opcodes INVOKESPECIAL
int INVOKESPECIAL
To view the source code for org.objectweb.asm Opcodes INVOKESPECIAL.
Click Source Link
From source file:edu.mit.streamjit.util.bytecode.MethodResolver.java
License:Open Source License
private void interpret(MethodInsnNode insn, FrameState frame, BBInfo block) { Klass k = getKlassByInternalName(insn.owner); MethodType mt = typeFactory.getMethodType(insn.desc); Method m;/* ww w. j av a 2s . c o m*/ if (insn.getOpcode() == Opcodes.INVOKESTATIC) m = k.getMethod(insn.name, mt); else if (insn.getOpcode() == Opcodes.INVOKESPECIAL && insn.name.equals("<init>")) { //TODO: invokespecial rules are more complex than this //We consider constructors to return their type. mt = mt.withReturnType(typeFactory.getType(k)); m = k.getMethod(insn.name, mt); } else { //The receiver argument is not in the descriptor, but we represent it in //the IR type system. if (insn.getOpcode() != Opcodes.INVOKESTATIC) mt = mt.prependArgument(typeFactory.getRegularType(k)); m = k.getMethodByVirtual(insn.name, mt); } CallInst inst = new CallInst(m); block.block.instructions().add(inst); //Args are pushed from left-to-right, popped from right-to-left. for (int i = mt.getParameterTypes().size() - 1; i >= 0; --i) inst.setArgument(i, frame.stack.pop()); //If we called a ctor, we have an uninit object on the stack. Replace //it with the constructed object, or with uninitializedThis if we're a //ctor ourselves and we called a superclass ctor. if (m.isConstructor()) { //TODO: always a direct superclass? seems likely but unsure. Value replacement = method.isConstructor() && method.getParent().getSuperclass().equals(k) ? uninitializedThis : inst; Value toBeReplaced = frame.stack.pop(); // assert toBeReplaced instanceof UninitializedValue; frame.replace(toBeReplaced, replacement); } else if (!(mt.getReturnType() instanceof VoidType)) frame.stack.push(inst); }
From source file:edu.mit.streamjit.util.bytecode.MethodUnresolver.java
License:Open Source License
private void emit(CallInst i, InsnList insns) { Method m = i.getMethod();/*from w w w . j a v a 2 s . c om*/ boolean callingSuperCtor = false; if (m.isConstructor()) { //If we're calling super(), load this. //TODO: this will get confused if we call a superclass constructor //for any reason other than our own initialization! if (method.isConstructor() && method.getParent().getSuperclass().equals(m.getParent())) { load(method.arguments().get(0), insns); callingSuperCtor = true; } else { insns.add(new TypeInsnNode(Opcodes.NEW, internalName(m.getType().getReturnType().getKlass()))); insns.add(new InsnNode(Opcodes.DUP)); } } int opcode; if (m.modifiers().contains(Modifier.STATIC)) opcode = Opcodes.INVOKESTATIC; else if (m.isConstructor() || m.getAccess().equals(Access.PRIVATE) || //We're calling a superclass method we've overridden. (Iterables.contains(method.getParent().superclasses(), m.getParent())) && method.getParent().getMethodByVirtual(m.getName(), m.getType()) != m) opcode = Opcodes.INVOKESPECIAL; else if (m.getParent().modifiers().contains(Modifier.INTERFACE)) //TODO: may not be correct? opcode = Opcodes.INVOKEINTERFACE; else opcode = Opcodes.INVOKEVIRTUAL; String owner = internalName(m.getParent()); //hack to make cloning arrays work if (opcode == Opcodes.INVOKESPECIAL && m.getName().equals("clone") && i.getArgument(0).getType() instanceof ArrayType) { opcode = Opcodes.INVOKEVIRTUAL; owner = internalName(((ArrayType) i.getArgument(0).getType()).getKlass()); } for (Value v : i.arguments()) load(v, insns); insns.add(new MethodInsnNode(opcode, owner, m.getName(), i.callDescriptor())); if (!(i.getType() instanceof VoidType) && !callingSuperCtor) store(i, insns); }
From source file:edu.ubc.mirrors.holograms.FrameVerifier.java
License:Open Source License
@Override public FrameValue naryOperation(AbstractInsnNode insn, List<? extends FrameValue> values) throws AnalyzerException { if (insn.getOpcode() == Opcodes.INVOKESPECIAL) { MethodInsnNode methodNode = (MethodInsnNode) insn; if (methodNode.name.charAt(0) == '<') { FrameValue target = values.get(0); Type targetType = target.getBasicValue().getType(); Type ownerType = Type.getObjectType(methodNode.owner); BasicValue owner = new BasicValue(ownerType); FrameValue expected = new FrameValue(owner, insn); if (!target.isUninitialized()) { throw new AnalyzerException(insn, "Argument 0", expected, target); }//from ww w.j a v a2 s . co m if (!targetType.equals(ownerType) && !(target.isUninitializedThis() && simplerVerifier.getSuperClass(targetType).equals(ownerType))) { throw new AnalyzerException(insn, "Argument 0", expected, target); } FrameValue result = FrameValue.fromBasicValue(target.getBasicValue()); int locals = currentFrame.getLocals(); for (int local = 0; local < locals; local++) { if (currentFrame.getLocal(local) == target) { currentFrame.setLocal(local, result); } } Stack<FrameValue> stack = new Stack<FrameValue>(); while (currentFrame.getStackSize() > 0) { FrameValue value = currentFrame.pop(); if (value == target) { value = result; } stack.push(value); } while (!stack.empty()) { currentFrame.push(stack.pop()); } } } List<BasicValue> basicValues = new ArrayList<BasicValue>(values.size()); for (FrameValue value : values) { basicValues.add(value.getBasicValue()); } return FrameValue.fromBasicValue(simplerVerifier.naryOperation(insn, basicValues)); }
From source file:edu.ubc.mirrors.holograms.HologramClassGenerator.java
License:Open Source License
@Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {//from w w w . ja va 2s.co m this.name = name; this.isInterface = (Opcodes.ACC_INTERFACE & access) != 0; this.superName = getHologramSuperclassName(isInterface, name, superName); interfaces = getHologramInterfaces(name, isInterface, interfaces); // Force everything to be public, since HologramClassLoader has to reflectively // construct holograms. Again, not a problem because the VM will see the original flags on the ClassMirror instead. // Also remove enum flags. int hologramAccess = forcePublic(access); // Also remove abstract flag. Shouldn't be necessary, but the VM (OpenJDK at least) // creates objects that claim to be an instance of VirtualMachineError, which is abstract. if (name.equals("hologram/java/lang/VirtualMachineError")) { hologramAccess = ~Opcodes.ACC_ABSTRACT & access; } // We need at least 1.5 to use class literal constants // TODO-RS: Work out a better way to interpret 45.X numbers correctly if (version == Opcodes.V1_1 || version < Opcodes.V1_5) { version = 49; } super.visit(version, hologramAccess, name, signature, this.superName, interfaces); if (this.name.equals(hologramThrowableType.getInternalName())) { // Generate aliases for the original superclass' fillInStackTrace and getStackTrace methods, // so we can call them in stubs without hitting hologram code. MethodVisitor v = super.visitMethod(Opcodes.ACC_PUBLIC, "superFillInStackTrace", Type.getMethodDescriptor(Type.VOID_TYPE), null, null); v.visitCode(); v.visitVarInsn(Opcodes.ALOAD, 0); v.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Throwable.class), "fillInStackTrace", Type.getMethodDescriptor(Type.getType(Throwable.class))); v.visitInsn(Opcodes.RETURN); v.visitMaxs(1, 1); v.visitEnd(); v = super.visitMethod(Opcodes.ACC_PUBLIC, "superGetStackTrace", Type.getMethodDescriptor(Type.getType(StackTraceElement[].class)), null, null); v.visitCode(); v.visitVarInsn(Opcodes.ALOAD, 0); v.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Throwable.class), "getStackTrace", Type.getMethodDescriptor(Type.getType(StackTraceElement[].class))); v.visitInsn(Opcodes.ARETURN); v.visitMaxs(1, 1); v.visitEnd(); } }
From source file:edu.ubc.mirrors.holograms.HologramClassGenerator.java
License:Open Source License
@Override public void visitEnd() { // Generate the static field used to store the corresponding ClassMirror int staticAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC; super.visitField(staticAccess, "classMirror", classMirrorType.getDescriptor(), null, null); // Generate the constructor that takes a mirror instance as an Object parameter String constructorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object.class)); if (name.equals(getHologramType(Type.getType(Throwable.class), true).getInternalName())) { // This doesn't extend ObjectHologram so we have to set the field directly super.visitField(Opcodes.ACC_PUBLIC, "mirror", objectMirrorType.getDescriptor(), null, null); MethodVisitor methodVisitor = super.visitMethod(Opcodes.ACC_PUBLIC, "<init>", constructorDesc, null, null);//from ww w . ja va 2s. c om methodVisitor.visitCode(); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE)); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitVarInsn(Opcodes.ALOAD, 1); methodVisitor.visitTypeInsn(Opcodes.CHECKCAST, objectMirrorType.getInternalName()); methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, name, "mirror", Type.getDescriptor(ObjectMirror.class)); methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(2, 2); methodVisitor.visitEnd(); methodVisitor = super.visitMethod(Opcodes.ACC_PUBLIC, "getMirror", Type.getMethodDescriptor(objectMirrorType), null, null); methodVisitor.visitCode(); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitFieldInsn(Opcodes.GETFIELD, name, "mirror", Type.getDescriptor(ObjectMirror.class)); methodVisitor.visitInsn(Opcodes.ARETURN); methodVisitor.visitMaxs(1, 1); methodVisitor.visitEnd(); } else if (!isInterface) { MethodVisitor methodVisitor = super.visitMethod(Opcodes.ACC_PUBLIC, "<init>", constructorDesc, null, null); methodVisitor.visitCode(); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitVarInsn(Opcodes.ALOAD, 1); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", constructorDesc); methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(2, 2); methodVisitor.visitEnd(); } // Add a class initialization method to initialize the static fields, // if one doesn't exist already. if (!hasClinit) { InstructionAdapter mv = new InstructionAdapter( super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "<clinit>", "()V", null, null)); mv.visitCode(); HologramMethodGenerator.initializeStaticFields(Type.getObjectType(this.name), mv); mv.areturn(Type.VOID_TYPE); mv.visitMaxs(2, 2); mv.visitEnd(); } super.visitEnd(); }
From source file:edu.ubc.mirrors.holograms.HologramClassGenerator.java
License:Open Source License
public static void generateArray(ClassVisitor visitor, HologramClassLoader loader, HologramClassMirror hologramClassMirror) { boolean isInterface = !hologramClassMirror.isImplementationClass(); ClassMirror classMirror = hologramClassMirror.getOriginal(); Type originalType = Reflection.typeForClassMirror(classMirror); Type originalElementType = originalType.getElementType(); int dims = originalType.getDimensions(); String internalName = getHologramType(originalType, !isInterface).getInternalName(); ClassMirror superClassMirror = null; String superName = isInterface ? Type.getInternalName(Object.class) : Type.getInternalName(ObjectArrayHologram.class); Set<String> interfaces = new HashSet<String>(); int access = Opcodes.ACC_PUBLIC | (isInterface ? Opcodes.ACC_INTERFACE : 0); if (originalElementType.getSort() == Type.OBJECT || originalElementType.getSort() == Type.ARRAY) { ClassMirror elementClass = loader.loadOriginalClassMirror(originalElementType.getClassName()); superClassMirror = elementClass.getSuperClassMirror(); if (isInterface) { if (superClassMirror != null) { Type superType = Reflection.makeArrayType(dims, Type.getObjectType(superClassMirror.getClassName().replace('.', '/'))); String superInterfaceName = getHologramType(superType).getInternalName(); interfaces.add(superInterfaceName); }/*from w w w . ja va2 s.c om*/ for (ClassMirror interfaceMirror : elementClass.getInterfaceMirrors()) { Type superType = Reflection.makeArrayType(dims, Type.getObjectType(interfaceMirror.getClassName().replace('.', '/'))); String interfaceName = getHologramType(superType).getInternalName(); interfaces.add(interfaceName); } interfaces.add(hologramType.getInternalName()); Type nMinus1Type = Reflection.makeArrayType(dims - 1, Type.getType(Object.class)); interfaces.add(getHologramType(nMinus1Type).getInternalName()); } } if (!isInterface) { interfaces.add(getHologramType(originalType, false).getInternalName()); } visitor.visit(Opcodes.V1_5, access, internalName, null, superName, interfaces.toArray(new String[0])); if (isInterface) { // Generate clone() String cloneDesc = Type.getMethodDescriptor(objectType); MethodVisitor mv = visitor.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "clone", cloneDesc, null, null); mv.visitEnd(); } else { // Generate thunk constructors String initDesc = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(ObjectArrayMirror.class)); MethodVisitor mv = visitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", initDesc, null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", initDesc); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); initDesc = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE); mv = visitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", initDesc, null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ILOAD, 1); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", initDesc); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } // Generate the static field used to store the corresponding ClassMirror and the static initializer to set it int staticAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC; visitor.visitField(staticAccess, "classMirror", classMirrorType.getDescriptor(), null, null); InstructionAdapter mv = new InstructionAdapter( visitor.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "<clinit>", "()V", null, null)); mv.visitCode(); HologramMethodGenerator.initializeStaticFields(Type.getObjectType(internalName), mv); mv.areturn(Type.VOID_TYPE); mv.visitMaxs(2, 2); mv.visitEnd(); visitor.visitEnd(); }
From source file:edu.ubc.mirrors.holograms.HologramMethodGenerator.java
License:Open Source License
@Override public void visitMethodInsn(int opcode, String owner, String name, String desc) { // Various special cases here to adjust for the fact that Object and Throwable // are still in the hierarchy and have some methods with incompatible types. Type stringHologramType = getHologramType(String.class); if (name.equals("toString") && desc.equals(Type.getMethodDescriptor(stringHologramType))) { desc = Type.getMethodDescriptor(Type.getType(String.class)); if (owner.equals(Type.getInternalName(Hologram.class))) { owner = OBJECT_TYPE.getInternalName(); // Handle calling Object.toString() with an invokespecial opcode, // which doesn't work any more since we've changed the superclass. if (opcode == Opcodes.INVOKESPECIAL) { opcode = Opcodes.INVOKESTATIC; owner = objectHologramType.getInternalName(); name = "hologramToString"; desc = Type.getMethodDescriptor(stringType, hologramType); }/*from www . j av a 2 s . com*/ } super.visitMethodInsn(opcode, owner, name, desc); getClassMirror(this.owner); invokestatic(objectHologramType.getInternalName(), "makeStringHologram", Type.getMethodDescriptor(hologramType, stringType, classMirrorType)); checkcast(stringHologramType); return; } if (name.equals("getClass") && desc.equals(Type.getMethodDescriptor(getHologramType(Class.class)))) { invokeinterface(Type.getInternalName(Hologram.class), "getMirror", Type.getMethodDescriptor(objectMirrorType)); invokeinterface(objectMirrorType.getInternalName(), "getClassMirror", Type.getMethodDescriptor(Type.getType(ClassMirror.class))); invokestatic(objectHologramType.getInternalName(), "make", Type.getMethodDescriptor(hologramType, objectMirrorType)); checkcast(getHologramType(Class.class)); return; } if (owner.equals(Type.getInternalName(Hologram.class))) { if (name.equals("<init>") && this.owner.equals(getHologramType(Throwable.class))) { owner = Type.getInternalName(Throwable.class); } else if (name.equals("<init>") || name.equals("toString")) { owner = objectHologramType.getInternalName(); } else { owner = OBJECT_TYPE.getInternalName(); } } if (name.equals("clone")) { if (desc.equals(Type.getMethodDescriptor(hologramType))) { desc = Type.getMethodDescriptor(OBJECT_TYPE); // Object.clone() on an array type is legal since array types // are treated specially by the JVM, but the mirror interfaces // are not granted the same leeway. Object t = stackType(0); if (t instanceof String) { String internalName = (String) t; Type type = Type.getObjectType(internalName); if (HologramClassGenerator.getOriginalType(type).getSort() == Type.ARRAY) { owner = internalName; } } } if (owner.equals(Type.getType(ObjectArrayMirror.class).getInternalName()) || (owner.startsWith("hologramarray") && !owner.startsWith("hologramarrayimpl"))) { String originalName = getOriginalInternalClassName(owner); owner = getHologramType(Type.getObjectType(originalName), true).getInternalName(); checkcast(Type.getObjectType(owner)); } } // if (owner.equals(getHologramType(Throwable.class).getInternalName())) { // if (name.equals("<init>") && desc.equals(Type.getMethodDescriptor(Type.VOID_TYPE, getHologramType(String.class)))) { // desc = Type.getMethodDescriptor(Type.VOID_TYPE, objectHologramType); // } // } if (owner.equals(hologramThrowableType.getInternalName()) && name.equals("fillInStackTrace") && desc.equals(Type.getMethodDescriptor(hologramThrowableType))) { desc = Type.getMethodDescriptor(throwableType); owner = throwableType.getInternalName(); } if (name.equals("equals") && desc.equals(Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getType(Hologram.class)))) { desc = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, OBJECT_TYPE); } if (name.equals("<init>") && !owner.equals(Type.getInternalName(Throwable.class))) { int argsSize = Type.getArgumentsAndReturnSizes(desc) >> 2; desc = HologramClassGenerator.addMirrorParam(desc); Object targetType = stackType(argsSize - 1); if (targetType.equals(Opcodes.UNINITIALIZED_THIS)) { // If the target is an uninitialized this (i.e. we're calling super(...) // or this(...)), pass along the extra mirror argument load((methodType.getArgumentsAndReturnSizes() >> 2) - 1, instanceMirrorType); } else if (targetType instanceof Label) { // If the target is just uninitialized (i.e. we're calling <init> after // a new), create the mirror getClassMirror(Type.getObjectType(owner)); invokeinterface(classMirrorType.getInternalName(), "newRawInstance", Type.getMethodDescriptor(instanceMirrorType)); } else { // Shouldn't happen throw new RuntimeException("Calling <init> on already initialized type: " + targetType); } } super.visitMethodInsn(opcode, owner, name, desc); if (owner.equals(Type.getInternalName(Throwable.class)) && name.equals("getStackTraceElement")) { Type steType = Type.getType(StackTraceElement.class); invokestatic(Type.getInternalName(ObjectHologram.class), "cleanStackTraceElement", Type.getMethodDescriptor(steType, steType)); } }
From source file:edu.ubc.mirrors.raw.NativeClassGenerator.java
License:Open Source License
@Override public void visitEnd() { if (!isInterface) { // Generate the no-argument constructor String constructorDesc = Type.getMethodDescriptor(Type.VOID_TYPE); MethodVisitor methodVisitor = super.visitMethod(Opcodes.ACC_PUBLIC, "<init>", constructorDesc, null, null);//from w ww . j a v a2 s . com methodVisitor.visitCode(); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", constructorDesc); methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(1, 1); methodVisitor.visitEnd(); } super.visitEnd(); }
From source file:edu.umd.cs.guitar.testcase.plugin.edg.ClassDBVisitor.java
License:Open Source License
@Override public void visitMethodInsn(int opcode, String owner, String name, String desc) { currentMethod.setEmpty(false);//from w w w . j a v a 2 s. c o m switch (opcode) { case Opcodes.INVOKEVIRTUAL: case Opcodes.INVOKESTATIC: case Opcodes.INVOKESPECIAL: Class c = getClass(owner); MethodDescriptor m = getMethod(c, name, desc); currentMethod.addInvokes(m); break; } }
From source file:erjang.EDouble.java
License:Apache License
@Override public org.objectweb.asm.Type emit_const(MethodVisitor fa) { Type type = EDOUBLE_TYPE;/*w ww.j a v a 2s . com*/ fa.visitTypeInsn(Opcodes.NEW, type.getInternalName()); fa.visitInsn(Opcodes.DUP); fa.visitLdcInsn(new Double(value)); fa.visitMethodInsn(Opcodes.INVOKESPECIAL, type.getInternalName(), "<init>", "(D)V"); return type; }