List of usage examples for org.objectweb.asm Opcodes INVOKEVIRTUAL
int INVOKEVIRTUAL
To view the source code for org.objectweb.asm Opcodes INVOKEVIRTUAL.
Click Source Link
From source file:com.offbynull.coroutines.instrumenter.ContinuationPointInstructionUtils.java
License:Open Source License
static InsnList loadAndCastToOriginal(Type originalType, Variable variable) { Validate.notNull(originalType);// w w w. j a v a 2 s.c o m Validate.notNull(variable); Validate.isTrue(variable.getType().equals(Type.getType(Object.class))); InsnList ret = new InsnList(); switch (originalType.getSort()) { case Type.BOOLEAN: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Boolean")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false)); break; case Type.BYTE: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Byte")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false)); break; case Type.SHORT: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Short")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false)); break; case Type.CHAR: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Character")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false)); break; case Type.INT: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Integer")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false)); break; case Type.FLOAT: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Float")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false)); break; case Type.LONG: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Long")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false)); break; case Type.DOUBLE: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Double")); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false)); break; case Type.ARRAY: case Type.OBJECT: ret.add(loadVar(variable)); // load it in to the returnValObj ret.add(new TypeInsnNode(Opcodes.CHECKCAST, originalType.getInternalName())); break; case Type.VOID: break; case Type.METHOD: default: throw new IllegalArgumentException(); } return ret; }
From source file:com.offbynull.coroutines.instrumenter.generators.DebugGenerators.java
License:Open Source License
/** * Generates instructions for generating marker instructions. These marker instructions are meant to be is useful for debugging * instrumented code. For example, you can spot a specific portion of instrumented code by looking for specific markers in the assembly * output.//from w ww.j a v a 2 s.c o m * @param markerType marker type (determines what kind of instructions are generated) * @param text text to print out * @return instructions to call System.out.println with a string constant * @throws NullPointerException if any argument is {@code null} */ public static InsnList debugMarker(MarkerType markerType, String text) { Validate.notNull(markerType); Validate.notNull(text); InsnList ret = new InsnList(); switch (markerType) { case NONE: break; case CONSTANT: ret.add(new LdcInsnNode(text)); ret.add(new InsnNode(Opcodes.POP)); break; case STDOUT: ret.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;")); ret.add(new LdcInsnNode(text)); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false)); break; default: throw new IllegalStateException(); } return ret; }
From source file:com.offbynull.coroutines.instrumenter.generators.DebugGenerators.java
License:Open Source License
/** * Generates instructions for printing out a string using {@link System#out}. This is useful for debugging. For example, you * can print out lines around your instrumented code to make sure that what you think is being run is actually being run. * @param text debug text generation instruction list -- must leave a String on the stack * @return instructions to call System.out.println with a string constant * @throws NullPointerException if any argument is {@code null} *///from w ww.j a v a 2s. com public static InsnList debugPrint(InsnList text) { Validate.notNull(text); InsnList ret = new InsnList(); ret.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;")); ret.add(text); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false)); return ret; }
From source file:com.offbynull.coroutines.instrumenter.SynchronizationGenerators.java
License:Open Source License
/** * Generates instruction to enter a monitor (top item on the stack) and store it in the {@link LockState} object sitting in the * lockstate variable./*from w ww .j av a 2 s . c o m*/ * @param markerType debug marker type * @param lockVars variables for lock/synchpoint functionality * @return instructions to enter a monitor and store it in the {@link LockState} object * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if lock variables aren't set (the method doesn't contain any monitorenter/monitorexit instructions) */ public static InsnList enterMonitorAndStore(MarkerType markerType, LockVariables lockVars) { Validate.notNull(markerType); Validate.notNull(lockVars); Variable lockStateVar = lockVars.getLockStateVar(); Validate.isTrue(lockStateVar != null); Type clsType = Type.getType(LOCKSTATE_ENTER_METHOD.getDeclaringClass()); Type methodType = Type.getType(LOCKSTATE_ENTER_METHOD); String clsInternalName = clsType.getInternalName(); String methodDesc = methodType.getDescriptor(); String methodName = LOCKSTATE_ENTER_METHOD.getName(); // NOTE: This adds to the lock state AFTER locking. return merge(debugMarker(markerType, "Entering monitor and storing"), // [obj] new InsnNode(Opcodes.DUP), // [obj, obj] new InsnNode(Opcodes.MONITORENTER), // [obj] new VarInsnNode(Opcodes.ALOAD, lockStateVar.getIndex()), // [obj, lockState] new InsnNode(Opcodes.SWAP), // [lockState, obj] new MethodInsnNode(Opcodes.INVOKEVIRTUAL, // [] clsInternalName, methodName, methodDesc, false)); }
From source file:com.offbynull.coroutines.instrumenter.SynchronizationGenerators.java
License:Open Source License
/** * Generates instruction to exit a monitor (top item on the stack) and remove it from the {@link LockState} object sitting in the * lockstate variable./*from w w w. j av a2 s . com*/ * @param markerType debug marker type * @param lockVars variables for lock/synchpoint functionality * @return instructions to exit a monitor and remove it from the {@link LockState} object * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if lock variables aren't set (the method doesn't contain any monitorenter/monitorexit instructions) */ public static InsnList exitMonitorAndDelete(MarkerType markerType, LockVariables lockVars) { Validate.notNull(markerType); Validate.notNull(lockVars); Variable lockStateVar = lockVars.getLockStateVar(); Validate.isTrue(lockStateVar != null); Type clsType = Type.getType(LOCKSTATE_EXIT_METHOD.getDeclaringClass()); Type methodType = Type.getType(LOCKSTATE_EXIT_METHOD); String clsInternalName = clsType.getInternalName(); String methodDesc = methodType.getDescriptor(); String methodName = LOCKSTATE_EXIT_METHOD.getName(); // NOTE: This removes the lock AFTER unlocking. return merge(debugMarker(markerType, "Exiting monitor and unstoring"), // [obj] new InsnNode(Opcodes.DUP), // [obj, obj] new InsnNode(Opcodes.MONITOREXIT), // [obj] new VarInsnNode(Opcodes.ALOAD, lockStateVar.getIndex()), // [obj, lockState] new InsnNode(Opcodes.SWAP), // [lockState, obj] new MethodInsnNode(Opcodes.INVOKEVIRTUAL, // [] clsInternalName, methodName, methodDesc, false)); }
From source file:com.spotify.missinglink.ClassLoader.java
License:Apache License
private static void handleMethodCall(Set<CalledMethod> thisCalls, int lineNumber, MethodInsnNode insn) { boolean isStatic; switch (insn.getOpcode()) { case Opcodes.INVOKEVIRTUAL: case Opcodes.INVOKEINTERFACE: isStatic = false;//from w ww .ja v a 2s . co m break; case Opcodes.INVOKESPECIAL: isStatic = false; break; case Opcodes.INVOKESTATIC: isStatic = true; break; default: throw new RuntimeException("Unexpected method call opcode: " + insn.getOpcode()); } if (insn.owner.charAt(0) != '[') { thisCalls.add(new CalledMethodBuilder().owner(TypeDescriptors.fromClassName(insn.owner)) .descriptor(MethodDescriptors.fromDesc(insn.desc, insn.name)).isStatic(isStatic) .lineNumber(lineNumber).build()); } }
From source file:com.sun.fortress.compiler.asmbytecodeoptimizer.Inlining.java
License:Open Source License
public static boolean isBuiltinInstanceMethod(ByteCodeMethodVisitor bcmv, Insn insn) { if (insn instanceof MethodInsn) { MethodInsn mi = (MethodInsn) insn; if ((mi.opcode == Opcodes.INVOKEVIRTUAL) && (isCompilerBuiltin(mi.owner))) { return true; }//from w w w.j av a2 s .c o m } return false; }
From source file:com.sun.fortress.compiler.asmbytecodeoptimizer.Inlining.java
License:Open Source License
public static boolean isLibraryInstanceMethod(ByteCodeMethodVisitor bcmv, Insn insn) { if (insn instanceof MethodInsn) { MethodInsn mi = (MethodInsn) insn; if ((mi.opcode == Opcodes.INVOKEVIRTUAL) && (isCompilerLibrary(mi.owner))) { return true; }/* w ww . ja va 2s. c o m*/ } return false; }
From source file:com.sun.fortress.compiler.codegen.CodeGen.java
License:Open Source License
public void printString(CodeGenMethodVisitor mv, String s) { mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitLdcInsn(s);// w w w. j ava 2 s. c o m mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); }
From source file:com.sun.fortress.compiler.codegen.CodeGen.java
License:Open Source License
public void forObjectDeclPrePass(ObjectDecl x) { debug("Begin forObjectDeclPrePass for ", x); TraitTypeHeader header = x.getHeader(); List<TraitTypeWhere> extendsC = header.getExtendsClause(); boolean canCompile = // x.getParams().isNone() && // no parameters // header.getStaticParams().isEmpty() && // no static parameter header.getWhereClause().isNone() && // no where clause header.getThrowsClause().isNone() && // no throws clause header.getContract().isNone() && // no contract // header.getDecls().isEmpty() && // no members Modifiers.ObjectMod.containsAll(header.getMods()) // ( extendsC.size() <= 1 ); // 0 or 1 super trait ;// w w w . java 2 s .co m if (!canCompile) throw sayWhat(x); // Map<String, String> xlation = new HashMap<String, String>(); List<String> splist = new ArrayList<String>(); final List<StaticParam> original_static_params = header.getStaticParams(); Option<List<Param>> original_params = NodeUtil.getParams(x); Naming.XlationData xldata = xlationData(Naming.OBJECT_GENERIC_TAG); boolean savedInAnObject = inAnObject; inAnObject = true; Id classId = NodeUtil.getName(x); final ClassNameBundle cnb = new_ClassNameBundle(classId, original_static_params, xldata); String erasedSuperI = (EMIT_ERASED_GENERICS && cnb.isGeneric) ? cnb.stemClassName : ""; String[] superInterfaces = NamingCzar.extendsClauseToInterfaces(extendsC, component.getName(), erasedSuperI); if (EMIT_ERASED_GENERICS && cnb.isGeneric) { emitErasedClassFor(cnb, (TraitObjectDecl) x); } String abstractSuperclass; if (superInterfaces.length > 0) { abstractSuperclass = superInterfaces[0] + NamingCzar.springBoard; } else { abstractSuperclass = NamingCzar.internalObject; } traitOrObjectName = cnb.className; debug("forObjectDeclPrePass ", x, " classFile = ", traitOrObjectName); boolean isSingletonObject = NodeUtil.getParams(x).isNone(); List<Param> params; if (!isSingletonObject) { params = NodeUtil.getParams(x).unwrap(); //TUPLE CONSTRUCTOR PROBLEM String init_sig = NamingCzar.jvmSignatureFor(params, "V", thisApi()); // Generate the factory method String sig = NamingCzar.jvmSignatureFor(params, cnb.classDesc, thisApi()); String mname; CodeGen cg = this; String PCN = null; String PCNOuter = null; ArrayList<InitializedStaticField> isf_list = new ArrayList<InitializedStaticField>(); if (cnb.isGeneric) { ArrowType at = FnNameInfo.typeAndParamsToArrow(NodeUtil.getSpan(x), NodeFactory.makeTraitType(classId, STypesUtil.staticParamsToArgs(original_static_params)), original_params.unwrap()); String generic_arrow_type = NamingCzar.jvmTypeDesc(at, thisApi(), false); PCNforClosure pair = nonCollidingClosureName(generic_arrow_type, Naming.NO_SELF, (IdOrOp) x.getHeader().getName(), original_static_params, this.packageAndClassName); PCN = pair.PCN; PCNOuter = pair.PCNOuter; xldata = pair.xldata; cg = new CodeGen(this); cg.cw = new CodeGenClassWriter(ClassWriter.COMPUTE_FRAMES, cw); // This creates the closure bits // The name is disambiguated by the class in which it appears. mname = InstantiatingClassloader.closureClassPrefix(PCN, cg.cw, PCN, sig, null, isf_list); } else { mname = nonCollidingSingleName(x.getHeader().getName(), sig, ""); } CodeGenClassWriter cw = cg.cw; CodeGenMethodVisitor mv = cw.visitCGMethod(ACC_STATIC + ACC_PUBLIC, mname, sig, null, null); mv.visitTypeInsn(NEW, cnb.className); mv.visitInsn(DUP); // iterate, pushing parameters, beginning at zero. // TODO actually handle N>0 parameters. int numParams = params.size(); //if only a single parameter which is a tuple, signature will give them individually if (numParams == 1 && (params.get(0).getIdType().unwrap() instanceof TupleType)) { Param p0 = params.get(0); TupleType tuple_type = ((TupleType) p0.getIdType().unwrap()); List<Type> tuple_types = tuple_type.getElements(); numParams = tuple_types.size(); } for (int stack_offset = 0; stack_offset < numParams; stack_offset++) { // when we unbox, this will be type-dependent mv.visitVarInsn(ALOAD, stack_offset); } mv.visitMethodInsn(INVOKESPECIAL, cnb.className, "<init>", init_sig); mv.visitInsn(ARETURN); mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter); mv.visitEnd(); if (cnb.isGeneric) { InstantiatingClassloader.optionalStaticsAndClassInitForTO(isf_list, cg.cw); cg.cw.dumpClass(PCNOuter, xldata); } } else { // singleton params = Collections.<Param>emptyList(); } CodeGenClassWriter prev = cw; /* Yuck, ought to allocate a new codegen here. */ initializedStaticFields_TO = new ArrayList<InitializedStaticField>(); cw = new CodeGenClassWriter(ClassWriter.COMPUTE_FRAMES, cw); cw.visitSource(NodeUtil.getSpan(x).begin.getFileName(), null); // Until we resolve the directory hierarchy problem. // cw.visit( V1_5, ACC_PUBLIC + ACC_SUPER+ ACC_FINAL, // classFile, null, NamingCzar.internalObject, new String[] { parent }); cw.visit(InstantiatingClassloader.JVM_BYTECODE_VERSION, ACC_PUBLIC + ACC_SUPER + ACC_FINAL, cnb.className, null, abstractSuperclass, superInterfaces); if (isSingletonObject) { initializedStaticFields_TO.add(new InitializedStaticField() { @Override public void forClinit(MethodVisitor imv) { imv.visitTypeInsn(NEW, cnb.className); imv.visitInsn(DUP); imv.visitMethodInsn(INVOKESPECIAL, cnb.className, "<init>", Naming.voidToVoid); imv.visitFieldInsn(PUTSTATIC, cnb.className, NamingCzar.SINGLETON_FIELD_NAME, cnb.classDesc); } @Override public String asmName() { return NamingCzar.SINGLETON_FIELD_NAME; } @Override public String asmSignature() { return cnb.classDesc; } }); /* Used to pass splist to the static-parametered form * but it was always empty. Tests work like that. * Bit of a WTF, keep an eye on this. * Repurpose splist (non-null) for the computation and * caching of RTTI, which also goes in a static. */ addStaticVar(new VarCodeGen.StaticBinding(classId, NodeFactory.makeTraitType(classId), cnb.stemClassName, NamingCzar.SINGLETON_FIELD_NAME, cnb.classDesc)); // // Singleton; generate field in class to hold sole instance. // cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, // NamingCzar.SINGLETON_FIELD_NAME, cnb.classDesc, // null /* for non-generic */, null /* instance has no value */); } currentTraitObjectDecl = x; //create CodeGen for init method // has different set of parameter variables in scope CodeGen initCodeGen = initializeInitMethod(params); initCodeGen.initializedInstanceFields_O = new ArrayList<InitializedInstanceField>(); // List<Binding> fieldsForEnv = new ArrayList<Binding>(); initCodeGen.instanceFields = new InstanceFields(); BATree<String, VarCodeGen> savedLexEnv = lexEnv.copy(); // for each parameter // 1) add field to the class // 2) add field along with initializer to list of instance fields to put in the constructor // 3) add parameter to local scope of init method // 4) add field to scope for use in methods for (int i = 0; i < params.size(); i++) { Param p = params.get(i); String paramName = p.getName().getText(); Type paramType = (Type) p.getIdType().unwrap(); String typeDesc = NamingCzar.jvmBoxedTypeDesc(paramType, thisApi()); Id id = NodeFactory.makeId(NodeUtil.getSpan(p.getName()), paramName); VarCodeGen vcg = new VarCodeGen.FieldVar(id, paramType, cnb.className, paramName, typeDesc); //1) add field to class cw.visitField(ACC_PUBLIC + ACC_FINAL, paramName, typeDesc, null /* for non-generic */, null /* instance has no value */); //2) add field with initializer as a refernce to the parameter initCodeGen.instanceFields.put(vcg, ExprFactory.makeVarRef(id)); //3) add param to scope for init method only initCodeGen.addStaticVar(new VarCodeGen.ParamVar(id, paramType, initCodeGen)); //4) add field to scope for method codegen addStaticVar(vcg); } // find declared fields in the list of decls and // 1) add field to the class // 2) add field along with initializer to list of instance fields to put in the constructor // 3) add field to scope for use in methods for (Decl d : header.getDecls()) { if (d instanceof VarDecl) { // TODO need to spot for "final" fields. Right now we assume mutable, not final. final VarDecl vd = (VarDecl) d; final CodeGen cg = this; int numDecls = vd.getLhs().size(); for (int i = 0; i < numDecls; i++) { LValue l = vd.getLhs().get(i); String fieldName = l.getName().getText(); Type fieldType = (Type) l.getIdType().unwrap(); String typeDesc = NamingCzar.jvmBoxedTypeDesc(fieldType, thisApi()); Id id = NodeFactory.makeId(NodeUtil.getSpan(l.getName()), fieldName); VarCodeGen fieldVcg = new VarCodeGen.MutableFieldVar(id, fieldType, cnb.className, fieldName, typeDesc); //1) add field to class cw.visitField(ACC_PUBLIC, fieldName, typeDesc, null /* for non-generic */, null /* instance has no value */); //2) set up initializer if (vd.getInit().isNone()) sayWhat(vd, "no initializer for declared field(s)"); Expr init = vd.getInit().unwrap(); if (numDecls != 1 && init instanceof TupleExpr) { List<Expr> tupleExprs = ((TupleExpr) init).getExprs(); if (tupleExprs.size() != numDecls) sayWhat(vd, "incorrect initialization for declared fields tuple"); init = tupleExprs.get(i); } initCodeGen.instanceFields.put(fieldVcg, init); //3) add field to scope for method codegen addStaticVar(fieldVcg); } } } debug("Dump overloaded method chaining for ", x); Map<IdOrOpOrAnonymousName, MultiMap<Integer, Functional>> overloads = dumpOverloadedMethodChaining( superInterfaces, false); if (OVERLOADED_METHODS) typeLevelOverloadedNamesAndSigs = generateTopLevelOverloads(thisApi(), overloads, typeAnalyzer, cw, this, new OverloadSet.TraitOrObjectFactory(Opcodes.INVOKEVIRTUAL, cnb, this)); debug("End of dump overloaded method chaining for ", x); debug("Process declarations for ", x); for (Decl d : header.getDecls()) { // This does not work yet. d.accept(this); } debug("End of processing declarations for ", x); initCodeGen.instanceInitForObject(abstractSuperclass); debug("Dump method chaining for ", x); dumpMethodChaining(superInterfaces, false); // dumpErasedMethodChaining(superInterfaces, false); debug("End of dump method chaining for ", x); /* RTTI stuff */ mv = cw.visitCGMethod(Opcodes.ACC_PUBLIC, // acccess Naming.RTTI_GETTER, // name Naming.STATIC_PARAMETER_GETTER_SIG, // sig null, // generics sig? null); // exceptions mv.visitCode(); mv.visitFieldInsn(GETSTATIC, cnb.className, Naming.RTTI_FIELD, Naming.RTTI_CONTAINER_DESC); areturnEpilogue(); emitRttiField(cnb); /* end RTTI stuff */ lexEnv = savedLexEnv; optionalStaticsAndClassInitForTO(classId, cnb, isSingletonObject); if (cnb.isGeneric) { cw.dumpClass(cnb.fileName, xldata.setTraitObjectTag(Naming.OBJECT_GENERIC_TAG)); } else { cw.dumpClass(cnb.className); } cw = prev; initializedInstanceFields_O = null; initializedStaticFields_TO = null; currentTraitObjectDecl = null; traitOrObjectName = null; inAnObject = savedInAnObject; // Needed (above) to embed a reference to the Rtti information for this type. RttiClassAndInterface(x, cnb, xldata); debug("End forObjectDeclPrePass for ", x); }