List of usage examples for org.objectweb.asm Opcodes GOTO
int GOTO
To view the source code for org.objectweb.asm Opcodes GOTO.
Click Source Link
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); }// w w w . j av 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 a v a 2 s . co 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);/*from w w w . j a v a 2 s . c om*/ 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 .jav a2 s . c om*/ * @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; }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
private static boolean encodeLabelledContinue(JavaStatement.LabelledContinue lc, GenerationContext context) { MethodVisitor mv = context.getMethodVisitor(); Label label = context.getNamedStatementJumpLabel(lc.getLabel()); if (label == null) { throw new IllegalStateException("label to continue to cannot be null."); }/*from ww w .j a v a2s. com*/ // Label the goto instruction and the instruction after the goto. // This instruction will be excluded from relevant ranges covered in the exception table. // Add a label for the goto instruction. Label gotoLabel = new Label(); mv.visitLabel(gotoLabel); // Visit the goto instruction. mv.visitJumpInsn(Opcodes.GOTO, label); // Add a label following the goto instruction. Label afterGotoLabel = new Label(); mv.visitLabel(afterGotoLabel); context.addJumpReturnLabelInfo(new JumpReturnLabelInfo(gotoLabel, afterGotoLabel, label)); return true; }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
private static JavaTypeName encodeThenTrueElseFalse(Label trueContinuation, Label falseContinuation, GenerationContext context) {//from w w w .java2 s.co m MethodVisitor mv = context.getMethodVisitor(); mv.visitLabel(trueContinuation); mv.visitInsn(Opcodes.ICONST_1); Label nextLabel = new Label(); mv.visitJumpInsn(Opcodes.GOTO, nextLabel); mv.visitLabel(falseContinuation); mv.visitInsn(Opcodes.ICONST_0); mv.visitLabel(nextLabel); return JavaTypeName.BOOLEAN; }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
private static JavaTypeName encodeThenExprElseExpr(Label trueContinuation, Label falseContinuation, JavaExpression thenExpr, JavaExpression elseExpr, GenerationContext context) throws JavaGenerationException { MethodVisitor mv = context.getMethodVisitor(); if (trueContinuation != null) { mv.visitLabel(trueContinuation); }//from w w w .j a v a 2s . co m //encode the then-part expression JavaTypeName thenType = encodeExpr(thenExpr, context); Label nextLabel = new Label(); mv.visitJumpInsn(Opcodes.GOTO, nextLabel); mv.visitLabel(falseContinuation); //encode the else-part expression JavaTypeName elseType = encodeExpr(elseExpr, context); mv.visitLabel(nextLabel); //The Java language specification section 15.25 defines the rules for the return types of ternary operators. //These are complicated, and we don't support this. The basic case supported is when both static types are the same. //There is a hack to support the case when the 2 types are different: //This case happens a bit in our code generation. The proper fix would be to not create this situation during code generation. if (thenType.equals(elseType)) { return thenType; } else if (thenType.equals(JavaTypeName.RTVALUE)) { //this is a hack, see the above comment return thenType; } else if (elseType.equals(JavaTypeName.RTVALUE)) { //this is a hack, see the above comment return elseType; } else { throw new JavaGenerationException( "The '?' operator must have then parts and else parts of exactly the same static types."); } }
From source file:org.sonar.java.bytecode.cfg.BytecodeCFGBuilderTest.java
License:Open Source License
@Test public void visited_label_should_be_assigned_to_true_successor() throws Exception { Label label0 = new Label(); Label label1 = new Label(); BytecodeCFG cfg = new Instructions().visitVarInsn(Opcodes.ALOAD, 0).visitJumpInsn(Opcodes.IFNULL, label0) .visitJumpInsn(Opcodes.IFEQ, label0).visitInsn(Opcodes.ICONST_0).visitJumpInsn(Opcodes.GOTO, label1) .visitLabel(label0).visitInsn(Opcodes.ICONST_1).visitLabel(label1).visitInsn(Opcodes.IRETURN).cfg(); BytecodeCFG.Block block3 = cfg.blocks.get(3); assertThat(block3.terminator.opcode).isEqualTo(Opcodes.IFEQ); assertThat(block3.falseSuccessor()).isNotNull().isSameAs(cfg.blocks.get(4)); assertThat(block3.trueSuccessor()).isNotNull().isSameAs(cfg.blocks.get(2)); assertThat(block3.successors).hasSize(2); assertThat(block3.successors()).hasSize(2); }
From source file:org.sonar.java.bytecode.cfg.BytecodeCFGBuilderTest.java
License:Open Source License
@Test public void goto_successors() throws Exception { Label label0 = new Label(); Label label1 = new Label(); BytecodeCFG cfg = new Instructions().visitVarInsn(Opcodes.ALOAD, 0).visitJumpInsn(Opcodes.IFNULL, label0) .visitVarInsn(Opcodes.ALOAD, 0).visitJumpInsn(Opcodes.IFNULL, label1).visitVarInsn(Opcodes.ALOAD, 0) .visitVarInsn(Opcodes.ALOAD, 0).visitJumpInsn(Opcodes.IFEQ, label0).visitInsn(Opcodes.ICONST_0) .visitJumpInsn(Opcodes.GOTO, label1).visitLabel(label0).visitInsn(Opcodes.ICONST_1) .visitLabel(label1).visitInsn(Opcodes.IRETURN).cfg(); assertThat(cfg.blocks.get(6).successors).containsExactly(cfg.blocks.get(4)); }
From source file:org.sonar.java.bytecode.se.BytecodeEGWalkerExecuteTest.java
License:Open Source License
@Test public void test_invalid_branch_instruction() { assertThatThrownBy(() -> walker.branchingState(new Instruction(Opcodes.GOTO), ProgramState.EMPTY_STATE)) .isInstanceOf(IllegalStateException.class); }