List of usage examples for org.objectweb.asm MethodVisitor visitJumpInsn
public void visitJumpInsn(final int opcode, final Label label)
From source file:org.moe.natj.processor.cxx.BCGen.java
License:Apache License
/** * Generates code which pops the top CxxObject on the stack and replaces it with its _cxx_rt_peer. * * @param mv Method visitor//from w w w.j a v a2 s . co m * @param checkNull Handle null object case */ public static void swapCxxObjectWithItsPeer(MethodVisitor mv, final boolean checkNull) { final Label then; final Label join; if (checkNull) { then = new Label(); join = new Label(); // if mv.visitInsn(DUP); mv.visitJumpInsn(IFNONNULL, then); // else mv.visitInsn(POP); mv.visitInsn(LCONST_0); mv.visitJumpInsn(GOTO, join); // then mv.visitLabel(then); } else { join = null; } mv.visitTypeInsn(CHECKCAST, CxxSupport.CXX_OBJECT_ITF.getInternalName()); mv.visitMethodInsn(INVOKEINTERFACE, CxxSupport.CXX_OBJECT_ITF.getInternalName(), "_cxx_rt_peer", Type.getMethodDescriptor(Type.LONG_TYPE), true); if (checkNull) { // join mv.visitLabel(join); } }
From source file:org.moe.natj.processor.cxx.BCGen.java
License:Apache License
private static void CxxRuntime_getOrConstruct_dynamicType(MethodVisitor mv, CxxType type, CxxUtils.LocalManager localManager, CxxClassInfo itf, ITypeResolverPlugin plugin) { final int nextIndex = localManager.getNextIndex(); final CxxUtils.Local peer = localManager.getNext("__cxx_GOC" + nextIndex, Type.LONG_TYPE, 2); final CxxUtils.Local rslt = localManager.getNext("__cxx_GOC" + nextIndex + "_R", itf.mapperType, 1); final Label endL = new Label(); // Local variable start labels mv.visitLabel(peer.start);// ww w .j av a 2 s . com mv.visitLabel(rslt.start); // Save peer mv.visitVarInsn(LSTORE, peer.index); // CxxRuntime.get(peer) mv.visitVarInsn(LLOAD, peer.index); mv.visitMethodInsn(INVOKESTATIC, CxxSupport.CXX_RUNTIME.getInternalName(), "get", Type.getMethodDescriptor(CxxSupport.CXX_OBJECT_ITF, Type.LONG_TYPE), false); mv.visitInsn(DUP); mv.visitTypeInsn(INSTANCEOF, itf.mapperType.getInternalName()); mv.visitJumpInsn(IFNE, endL); // Construct mv.visitInsn(POP); mv.visitVarInsn(LLOAD, peer.index); mv.visitVarInsn(LLOAD, peer.index); final String getterMethod; if (type.isConstCxxObjectKind()) { getterMethod = "getConstClassForType"; } else { getterMethod = "getClassForType"; } mv.visitMethodInsn(INVOKESTATIC, plugin.getImplementingClass() + "$__cxx_TypeRes", getterMethod, Type.getMethodDescriptor(Type.getObjectType("java/lang/Class"), Type.LONG_TYPE), false); mv.visitMethodInsn(INVOKESTATIC, CxxSupport.CXX_RUNTIME.getInternalName(), "construct", Type.getMethodDescriptor(CxxSupport.CXX_OBJECT_ITF, Type.LONG_TYPE, Type.getObjectType("java/lang/Class")), false); // Join mv.visitLabel(endL); mv.visitTypeInsn(CHECKCAST, itf.mapperType.getInternalName()); mv.visitVarInsn(ASTORE, rslt.index); mv.visitVarInsn(ALOAD, rslt.index); // Local variable end labels mv.visitLabel(peer.end); mv.visitLabel(rslt.end); }
From source file:org.moe.natj.processor.cxx.BCGen.java
License:Apache License
private static void CxxRuntime_getOrConstruct_binding(MethodVisitor mv, CxxUtils.LocalManager localManager, CxxClassInfo itf, Type implClass, boolean isConst) { final int nextIndex = localManager.getNextIndex(); final CxxUtils.Local peer = localManager.getNext("__cxx_GOC" + nextIndex, Type.LONG_TYPE, 2); final CxxUtils.Local rslt = localManager.getNext("__cxx_GOC" + nextIndex + "_R", itf.mapperType, 1); final Label endL = new Label(); final Label constructL = new Label(); // Local variable start labels mv.visitLabel(peer.start);//from www . ja v a 2s. com mv.visitLabel(rslt.start); // Save peer mv.visitVarInsn(LSTORE, peer.index); // CxxRuntime.get(peer) mv.visitVarInsn(LLOAD, peer.index); mv.visitMethodInsn(INVOKESTATIC, CxxSupport.CXX_RUNTIME.getInternalName(), "get", Type.getMethodDescriptor(CxxSupport.CXX_OBJECT_ITF, Type.LONG_TYPE), false); mv.visitInsn(DUP); mv.visitTypeInsn(INSTANCEOF, itf.mapperType.getInternalName()); mv.visitJumpInsn(IFEQ, constructL); // Check const-nes mv.visitInsn(DUP); mv.visitTypeInsn(INSTANCEOF, CxxSupport.CXX_CONST_IMPL_ITF.getInternalName()); mv.visitJumpInsn(isConst ? IFEQ : IFNE, constructL); // Store mv.visitTypeInsn(CHECKCAST, itf.mapperType.getInternalName()); mv.visitVarInsn(ASTORE, rslt.index); mv.visitJumpInsn(GOTO, endL); // Construct mv.visitLabel(constructL); mv.visitInsn(POP); mv.visitTypeInsn(NEW, implClass.getInternalName()); mv.visitInsn(DUP); mv.visitVarInsn(LLOAD, peer.index); mv.visitMethodInsn(INVOKESPECIAL, implClass.getInternalName(), "<init>", "(J)V", false); mv.visitVarInsn(ASTORE, rslt.index); // Join mv.visitLabel(endL); mv.visitVarInsn(ALOAD, rslt.index); // Local variable end labels mv.visitLabel(peer.end); mv.visitLabel(rslt.end); }
From source file:org.nuclos.server.customcode.codegenerator.ClassDebugAdapter.java
License:Open Source License
private void insertDebugResolveMethod() { /*/*from w w w . j a v a2 s . c o m*/ private String __resolve(String methodAndIndex) { if(methodAndIndex.equals("method1")) return "var1"; if(methodAndIndex.equals("method2")) return "var2"; [ ... ] if(methodAndIndex.equals("methodX")) return "varX"; return "-"; } */ MethodVisitor mv = cv.visitMethod(ACC_PRIVATE + ACC_STATIC, "__resolve", "(Ljava/lang/String;)Ljava/lang/String;", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); for (String mapKey : varLookup.keySet()) { mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn(mapKey); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z"); Label l1 = new Label(); mv.visitJumpInsn(IFEQ, l1); Label l2 = new Label(); mv.visitLabel(l2); mv.visitLdcInsn(varLookup.get(mapKey)); mv.visitInsn(ARETURN); mv.visitLabel(l1); mv.visitFrame(F_SAME, 0, null, 0, null); } mv.visitLdcInsn("-"); mv.visitInsn(ARETURN); mv.visitMaxs(2, 2); mv.visitEnd(); }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * Add the <clinit> method. This initializes the static fields that have initializers. * @param classRep// ww w .j av a 2s.c om * @param cv * @param initializeForAsserts * @throws JavaGenerationException */ private static void encodeClassInitializer(JavaClassRep classRep, ClassVisitor cv, boolean initializeForAsserts) throws JavaGenerationException { // Add initializers for the statically-initialized fields. final int nFields = classRep.getNFieldDeclarations(); if (!classRep.hasInitializedStaticField() && !initializeForAsserts) { //we don't need to bother adding a static initializer if there are no static fields to initialize. //note that javac also has this optimization. return; } MethodVisitor mv = cv.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null); // Start the method's code. mv.visitCode(); final JavaTypeName classRepTypeName = classRep.getClassName(); /* * If this class contains assert statements we need to initialize the static final synthetic boolean field * '$assertionsDisabled'. * This is done by loading the Class constant for the top level class. The method 'desiredAssertionStatus()' * is then invoked on this Class object and the returned value is used to initialize $assertionsDisabled. */ if (initializeForAsserts) { // Get the fully-qualified internal class name. final String className = classRepTypeName.getJVMInternalName(); // Get the top level class name. String topLevelClassName = getTopLevelClassJVMInternalName(className); // Load the Class constant for the top level class mv.visitLdcInsn(Type.getType("L" + topLevelClassName + ";")); // Now that we have the Class constant for the top level class we invoke the method // desiredAssertionStatus on it and use the resulting value to initialize the static field $assertionsDisabled in this class. mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z"); Label l0 = new Label(); mv.visitJumpInsn(Opcodes.IFNE, l0); mv.visitInsn(Opcodes.ICONST_1); Label l1 = new Label(); mv.visitJumpInsn(Opcodes.GOTO, l1); mv.visitLabel(l0); mv.visitInsn(Opcodes.ICONST_0); mv.visitLabel(l1); mv.visitFieldInsn(Opcodes.PUTSTATIC, className, "$assertionsDisabled", "Z"); } for (int i = 0; i < nFields; ++i) { JavaFieldDeclaration fieldDecl = classRep.getFieldDeclaration(i); JavaExpression initializer = fieldDecl.getInitializer(); if (initializer != null && Modifier.isStatic(fieldDecl.getModifiers())) { GenerationContext context = new GenerationContext(new HashMap<String, JavaTypeName>(), new HashMap<String, Integer>(), 0, mv, classRepTypeName); //evaluate the initializer encodeExpr(initializer, context); //do the assignment mv.visitFieldInsn(Opcodes.PUTSTATIC, classRep.getClassName().getJVMInternalName(), fieldDecl.getFieldName(), fieldDecl.getFieldType().getJVMDescriptor()); } } // return. mv.visitInsn(Opcodes.RETURN); //mark the end of the method with a call to visitMaxs mv.visitMaxs(0, 0); // End the method. mv.visitEnd(); }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
private static boolean encodeIfThenElseStatement(JavaStatement.IfThenElseStatement iteStatement, GenerationContext context) throws JavaGenerationException { MethodVisitor mv = context.getMethodVisitor(); JavaExpression conditionExpr = iteStatement.getCondition(); JavaStatement thenStatement = iteStatement.getThenStatement(); JavaStatement elseStatement = iteStatement.getElseStatement(); if (conditionExpr instanceof JavaExpression.OperatorExpression) { //generate more efficient code in the case of if (boolean-valued-operator)... //This case exists to handle the special case where an operator occurs as the child of an if-then-else (or ternary operator) //conditional. For example, in the situation: ///*from w w w .j a v a2 s . com*/ //if (x != null) {...} else {...} // // we do not want to evaluate x != null to a boolean value, push that value on the stack, // and then test it prior to selecting the correct branch. Rather, we can combine the evaluation // and jump operations into a single step. JavaExpression.OperatorExpression operatorExpr = (JavaExpression.OperatorExpression) conditionExpr; JavaOperator operator = operatorExpr.getJavaOperator(); if (operator.isLogicalOp() || operator.isRelationalOp()) { Label trueContinuation = new Label(); context.addStatementJumpLabel(trueContinuation); Label falseContinuation = new Label(); context.addStatementJumpLabel(falseContinuation); encodeBooleanValuedOperatorHelper(operatorExpr, context, trueContinuation, falseContinuation); return encodeThenStatementElseStatement(trueContinuation, falseContinuation, thenStatement, elseStatement, context); } throw new JavaGenerationException( "Unrecognized boolean-valued conditional operator " + operator.getSymbol() + "."); } //encode the condition. It will be boolean valued. encodeExpr(iteStatement.getCondition(), context); //if false, jump to falseContinuation Label falseContinuation = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, falseContinuation); return encodeThenStatementElseStatement(null, falseContinuation, thenStatement, elseStatement, context); }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
private static boolean encodeThenStatementElseStatement(Label trueContinuation, Label falseContinuation, JavaStatement thenStatement, JavaStatement elseStatement, GenerationContext context) throws JavaGenerationException { MethodVisitor mv = context.getMethodVisitor(); if (trueContinuation != null) { mv.visitLabel(trueContinuation); }/*from w ww. j a v a 2 s. c o m*/ //in general the "then" part will have its own inner scope, but we optimize this out in the case of ExpressionStatements which //can't introduce new variables. GenerationContext thenContext = (thenStatement instanceof JavaStatement.ExpressionStatement) ? context : new GenerationContext(context); boolean thenIsTerminating = encodeStatement(thenStatement, thenContext); context.addJumpReturnLabelInfo(thenContext); if (elseStatement.emptyStatement()) { //don't bother to encode the goto skipping over the else part if there is not else part. mv.visitLabel(falseContinuation); //the if-then-else is not terminating, because the else part, which is just {}, is not terminating return false; } Label label2 = null; if (!thenIsTerminating) { label2 = new Label(); context.addStatementJumpLabel(label2); mv.visitJumpInsn(Opcodes.GOTO, label2); } mv.visitLabel(falseContinuation); //in general the "else" part will have its own inner scope, but we optimize this out in the case of ExpressionStatements which //can't introduce new variables. GenerationContext elseContext = (elseStatement instanceof JavaStatement.ExpressionStatement) ? context : new GenerationContext(context); boolean elseIsTerminating = encodeStatement(elseStatement, elseContext); context.addJumpReturnLabelInfo(elseContext); if (!thenIsTerminating) { mv.visitLabel(label2); } return thenIsTerminating && elseIsTerminating; }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
private static boolean encodeTryCatchStatement(JavaStatement.Block block, GenerationContext context) throws JavaGenerationException { MethodVisitor mv = context.getMethodVisitor(); List<JavaExceptionHandler> exceptionHandlers = block.getExceptionHandlers(); if (exceptionHandlers.isEmpty()) { throw new IllegalStateException(); }//from w w w . j av a 2 s .c o m // Spawn a child context for the try block. GenerationContext tryBlockContext = new GenerationContext(context); boolean isTerminating = false; // starts out false (for the case with no statements..) Label tryStartLabel = new Label(); mv.visitLabel(tryStartLabel); // Append the instructions comprising the block's component statements. int nStatements = block.getNBlockStatements(); for (int i = 0; i < nStatements; i++) { JavaStatement blockStatement = block.getNthBlockStatement(i); // skip comments. if (blockStatement instanceof Comment) { continue; } // is terminating if the last statement is terminating. isTerminating = encodeStatement(blockStatement, tryBlockContext); context.addJumpReturnLabelInfo(tryBlockContext); } // Add an instruction to jump to after the exception handlers, if the statement block isn't terminating. Label tryCatchEndLabel = new Label(); context.addStatementJumpLabel(tryCatchEndLabel); if (!isTerminating) { mv.visitJumpInsn(Opcodes.GOTO, tryCatchEndLabel); } Label tryEndLabel = new Label(); mv.visitLabel(tryEndLabel); // Add exception handlers as necessary. // Now set handlers to handle any exceptions. for (int i = 0, nExceptionHandlers = exceptionHandlers.size(); i < nExceptionHandlers; ++i) { JavaExceptionHandler eh = exceptionHandlers.get(i); JavaTypeName exceptionType = JavaTypeName.make(eh.getExceptionClass()); // exception class is a non-array reference type. //encode the start of the catch block. Label catchLabel = new Label(); mv.visitLabel(catchLabel); // Create a child context for the catch block. GenerationContext catchContext = new GenerationContext(context); // The thrown exception object will be the only item on the stack. // Store it into a new local variable. String exceptionVarName = eh.getExceptionVarName(); int exceptionVarIndex = catchContext.addLocalVar(exceptionVarName, exceptionType); mv.visitVarInsn(Opcodes.ASTORE, exceptionVarIndex); boolean catchIsTerminating = encodeStatement(eh.getHandlerCode(), catchContext); context.addJumpReturnLabelInfo(catchContext); if (!catchIsTerminating) { mv.visitJumpInsn(Opcodes.GOTO, tryCatchEndLabel); } // In the end, we're only terminating if all the catch blocks are terminating. isTerminating &= catchIsTerminating; //encode the try/catch block. This can be done in any order, any time after all labels passed as arguments have been visited, // between visitCode() and visitMaxs(). encodeTryCatchBlock(tryStartLabel, tryEndLabel, catchLabel, exceptionType, tryBlockContext); } //mark the end of the whole try/catch code mv.visitLabel(tryCatchEndLabel); return isTerminating; }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
private static boolean encodeUnconditionalLoop(JavaStatement.UnconditionalLoop ul, GenerationContext context) throws JavaGenerationException { //implemented as: //label label1: //{ body statements} //goto label1 MethodVisitor mv = context.getMethodVisitor(); Label label1 = new Label(); mv.visitLabel(label1);/*w w w. ja va2s . co m*/ context.addStatementJumpLabel(ul.getLabel(), label1); //the body defines a new scope. GenerationContext bodyContext = new GenerationContext(context); boolean bodyIsTerminating = encodeStatement(ul.getBody(), bodyContext); context.addJumpReturnLabelInfo(bodyContext); if (!bodyIsTerminating) { mv.visitJumpInsn(Opcodes.GOTO, label1); } return true; }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * Encode a method invocation that is wrapped in a synchronized block. * See Sun bug id #4414101 for a discussion of this generated code. * //from ww w . j a v a 2 s .c o m * @param smi - the SynchronizedMethodInvocation object. * @param context - the context of the code generation. * @return - true if the SynchronizedMethodInvocation is terminating. * @throws JavaGenerationException */ private static boolean encodeSynchronizedMethodInvocation(JavaStatement.SynchronizedMethodInvocation smi, GenerationContext context) throws JavaGenerationException { MethodVisitor mv = context.getMethodVisitor(); // Get the JavaExpression for the object to synchronize on and generate the bytecode. JavaExpression objectToSynchOn = smi.getSynchronizingObject(); encodeExpr(objectToSynchOn, context); // The object to synchronize on is now on the stack. Duplicate it, // move one to storage as a local variable, and to MONITORENTER on the other. mv.visitInsn(Opcodes.DUP); int mutexIndex = context.addLocalVar("$mutex", JavaTypeName.OBJECT); mv.visitVarInsn(Opcodes.ASTORE, mutexIndex); mv.visitInsn(Opcodes.MONITORENTER); // We need to wrap the method invocation in a try/catch block so // the monitor can be exited properly if the method invocation throws // an exception. Label tryCatchStart = new Label(); mv.visitLabel(tryCatchStart); // Note: if this is generalized to handle any synchronized statement (for example, a synchronized block), // then the scope of entries in the exception table here will have to be modified to exclude return instructions. // See encodeTryCatchStatement() for how to do this. // Here, the only statement in the try block is a single expressionStatement, which has no return instructions, // so we don't have to worry about handling this case. // Get the method invocation and generate the corresponding bytecode. MethodInvocation methodInvocation = smi.getMethodInvocation(); encodeExpr(methodInvocation, context); // Load the mutex object back onto the stack and do MonitorExit. mv.visitVarInsn(Opcodes.ALOAD, mutexIndex); mv.visitInsn(Opcodes.MONITOREXIT); // Label the end of the try block around the method invocation. Label tryEnd = new Label(); mv.visitLabel(tryEnd); // At this point we want to code an instruction to jump past the exception handling // code. Label tryCatchEnd = new Label(); mv.visitJumpInsn(Opcodes.GOTO, tryCatchEnd); // Label the start of the exception handling code. Label catchStart = new Label(); mv.visitLabel(catchStart); // The exception is on the stack. Store it as a local. int exceptionIndex = context.addLocalVar("exception", JavaTypeName.OBJECT); mv.visitVarInsn(Opcodes.ASTORE, exceptionIndex); // Retrieve the mutex object and do MONITOREXIT. mv.visitVarInsn(Opcodes.ALOAD, mutexIndex); mv.visitInsn(Opcodes.MONITOREXIT); // Label the end of the exception handling code that deals with the monitor. Label exceptionMonitorExitEnd = new Label(); mv.visitLabel(exceptionMonitorExitEnd); // Retrieve the exception and throw it. mv.visitVarInsn(Opcodes.ALOAD, exceptionIndex); mv.visitInsn(Opcodes.ATHROW); // Vist the label to mark the end of the try/catch. mv.visitLabel(tryCatchEnd); // Set up the try/catch block to catch exceptions thrown by the method invocation // and handle exiting the monitor. mv.visitTryCatchBlock(tryCatchStart, tryEnd, catchStart, null); // Set up a try catch block so that if an exception is thrown by trying to exit // the monitor in the case of an exception from the method invocation we will keep trying to // exit the monitor. mv.visitTryCatchBlock(catchStart, exceptionMonitorExitEnd, catchStart, null); return false; }