List of usage examples for org.objectweb.asm MethodVisitor visitLabel
public void visitLabel(final Label label)
From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java
License:Apache License
public void writeWhileLoop(WhileStatement loop) { controller.getAcg().onLineNumber(loop, "visitWhileLoop"); writeStatementLabel(loop);//from ww w . j a v a 2s . c o m MethodVisitor mv = controller.getMethodVisitor(); controller.getCompileStack().pushLoop(loop.getStatementLabels()); Label continueLabel = controller.getCompileStack().getContinueLabel(); Label breakLabel = controller.getCompileStack().getBreakLabel(); mv.visitLabel(continueLabel); this.visitConditionOfLoopingStatement(loop.getBooleanExpression(), breakLabel, mv); loop.getLoopBlock().visit(controller.getAcg()); mv.visitJumpInsn(GOTO, continueLabel); mv.visitLabel(breakLabel); controller.getCompileStack().pop(); }
From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java
License:Apache License
public void writeDoWhileLoop(DoWhileStatement loop) { controller.getAcg().onLineNumber(loop, "visitDoWhileLoop"); writeStatementLabel(loop);/*from w w w .j av a2 s . c o m*/ MethodVisitor mv = controller.getMethodVisitor(); controller.getCompileStack().pushLoop(loop.getStatementLabels()); Label continueLabel = controller.getCompileStack().getContinueLabel(); Label breakLabel = controller.getCompileStack().getBreakLabel(); mv.visitLabel(continueLabel); loop.getLoopBlock().visit(controller.getAcg()); this.visitConditionOfLoopingStatement(loop.getBooleanExpression(), breakLabel, mv); mv.visitJumpInsn(GOTO, continueLabel); mv.visitLabel(breakLabel); controller.getCompileStack().pop(); }
From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java
License:Apache License
public void writeIfElse(IfStatement ifElse) { controller.getAcg().onLineNumber(ifElse, "visitIfElse"); writeStatementLabel(ifElse);/*ww w . ja v a 2 s. c om*/ MethodVisitor mv = controller.getMethodVisitor(); ifElse.getBooleanExpression().visit(controller.getAcg()); Label l0 = controller.getOperandStack().jump(IFEQ); // if-else is here handled as a special version // of a boolean expression controller.getCompileStack().pushBooleanExpression(); ifElse.getIfBlock().visit(controller.getAcg()); controller.getCompileStack().pop(); if (ifElse.getElseBlock() instanceof EmptyStatement) { mv.visitLabel(l0); } else { Label l1 = new Label(); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); controller.getCompileStack().pushBooleanExpression(); ifElse.getElseBlock().visit(controller.getAcg()); controller.getCompileStack().pop(); mv.visitLabel(l1); } }
From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java
License:Apache License
public void writeTryCatchFinally(TryCatchStatement statement) { controller.getAcg().onLineNumber(statement, "visitTryCatchFinally"); writeStatementLabel(statement);//from www . j av a 2s .c o m MethodVisitor mv = controller.getMethodVisitor(); CompileStack compileStack = controller.getCompileStack(); OperandStack operandStack = controller.getOperandStack(); Statement tryStatement = statement.getTryStatement(); Statement finallyStatement = statement.getFinallyStatement(); // start try block, label needed for exception table Label tryStart = new Label(); mv.visitLabel(tryStart); BlockRecorder tryBlock = makeBlockRecorder(finallyStatement); tryBlock.startRange(tryStart); tryStatement.visit(controller.getAcg()); // goto finally part Label finallyStart = new Label(); mv.visitJumpInsn(GOTO, finallyStart); Label tryEnd = new Label(); mv.visitLabel(tryEnd); tryBlock.closeRange(tryEnd); // pop for "makeBlockRecorder(finallyStatement)" controller.getCompileStack().pop(); BlockRecorder catches = makeBlockRecorder(finallyStatement); for (CatchStatement catchStatement : statement.getCatchStatements()) { ClassNode exceptionType = catchStatement.getExceptionType(); String exceptionTypeInternalName = BytecodeHelper.getClassInternalName(exceptionType); // start catch block, label needed for exception table Label catchStart = new Label(); mv.visitLabel(catchStart); catches.startRange(catchStart); // create exception variable and store the exception Parameter exceptionVariable = catchStatement.getVariable(); compileStack.pushState(); compileStack.defineVariable(exceptionVariable, true); // handle catch body catchStatement.visit(controller.getAcg()); // place holder to avoid problems with empty catch blocks mv.visitInsn(NOP); // pop for the variable controller.getCompileStack().pop(); // end of catch Label catchEnd = new Label(); mv.visitLabel(catchEnd); catches.closeRange(catchEnd); // goto finally start mv.visitJumpInsn(GOTO, finallyStart); compileStack.writeExceptionTable(tryBlock, catchStart, exceptionTypeInternalName); } // used to handle exceptions in catches and regularly visited finals Label catchAny = new Label(); // add "catch any" block to exception table for try part we do this // after the exception blocks, because else this one would supersede // any of those otherwise compileStack.writeExceptionTable(tryBlock, catchAny, null); // same for the catch parts compileStack.writeExceptionTable(catches, catchAny, null); // pop for "makeBlockRecorder(catches)" compileStack.pop(); // start finally mv.visitLabel(finallyStart); finallyStatement.visit(controller.getAcg()); // goto after all-catching block Label skipCatchAll = new Label(); mv.visitJumpInsn(GOTO, skipCatchAll); // start a block catching any Exception mv.visitLabel(catchAny); // store exception // TODO: maybe define a Throwable and use it here instead of Object operandStack.push(ClassHelper.OBJECT_TYPE); int anyExceptionIndex = compileStack.defineTemporaryVariable("exception", true); // GROOVY-9199 controller.resetLineNumber(); int line = finallyStatement.getLineNumber(); if (line > 0) mv.visitLineNumber(line, catchAny); finallyStatement.visit(controller.getAcg()); // load the exception and rethrow it mv.visitVarInsn(ALOAD, anyExceptionIndex); mv.visitInsn(ATHROW); mv.visitLabel(skipCatchAll); compileStack.removeVar(anyExceptionIndex); }
From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java
License:Apache License
protected void writeCaseStatement(CaseStatement statement, int switchVariableIndex, Label thisLabel, Label nextLabel) {//from w w w . j a va 2s . c om controller.getAcg().onLineNumber(statement, "visitCaseStatement"); MethodVisitor mv = controller.getMethodVisitor(); OperandStack operandStack = controller.getOperandStack(); mv.visitVarInsn(ALOAD, switchVariableIndex); statement.getExpression().visit(controller.getAcg()); operandStack.box(); controller.getBinaryExpressionHelper().getIsCaseMethod().call(mv); operandStack.replace(ClassHelper.boolean_TYPE); Label l0 = controller.getOperandStack().jump(IFEQ); mv.visitLabel(thisLabel); statement.getCode().visit(controller.getAcg()); // now if we don't finish with a break we need to jump past // the next comparison if (nextLabel != null) { mv.visitJumpInsn(GOTO, nextLabel); } mv.visitLabel(l0); }
From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java
License:Apache License
public void writeSynchronized(SynchronizedStatement statement) { controller.getAcg().onLineNumber(statement, "visitSynchronizedStatement"); writeStatementLabel(statement);//from w w w .j a va 2 s. co m final MethodVisitor mv = controller.getMethodVisitor(); CompileStack compileStack = controller.getCompileStack(); statement.getExpression().visit(controller.getAcg()); controller.getOperandStack().box(); final int index = compileStack.defineTemporaryVariable("synchronized", ClassHelper.OBJECT_TYPE, true); final Label synchronizedStart = new Label(); final Label synchronizedEnd = new Label(); final Label catchAll = new Label(); mv.visitVarInsn(ALOAD, index); mv.visitInsn(MONITORENTER); mv.visitLabel(synchronizedStart); // place holder for "empty" synchronized blocks, for example // if there is only a break/continue. mv.visitInsn(NOP); Runnable finallyPart = () -> { mv.visitVarInsn(ALOAD, index); mv.visitInsn(MONITOREXIT); }; BlockRecorder fb = new BlockRecorder(finallyPart); fb.startRange(synchronizedStart); compileStack.pushBlockRecorder(fb); statement.getCode().visit(controller.getAcg()); fb.closeRange(catchAll); compileStack.writeExceptionTable(fb, catchAll, null); compileStack.pop(); //pop fb finallyPart.run(); mv.visitJumpInsn(GOTO, synchronizedEnd); mv.visitLabel(catchAll); finallyPart.run(); mv.visitInsn(ATHROW); mv.visitLabel(synchronizedEnd); compileStack.removeVar(index); }
From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java
License:Apache License
protected void createSyntheticStaticFields() { if (referencedClasses.isEmpty()) { return;/*from w w w . j av a 2 s . c o m*/ } MethodVisitor mv; for (Map.Entry<String, ClassNode> entry : referencedClasses.entrySet()) { String staticFieldName = entry.getKey(); ClassNode cn = entry.getValue(); // generate a field node FieldNode fn = controller.getClassNode().getDeclaredField(staticFieldName); if (fn != null) { boolean type = fn.getType().equals(ClassHelper.CLASS_Type); boolean modifiers = fn.getModifiers() == ACC_STATIC + ACC_SYNTHETIC; if (!type || !modifiers) { String text = ""; if (!type) text = " with wrong type: " + fn.getType() + " (java.lang.Class needed)"; if (!modifiers) text = " with wrong modifiers: " + fn.getModifiers() + " (" + (ACC_STATIC + ACC_SYNTHETIC) + " needed)"; throwException("tried to set a static synthetic field " + staticFieldName + " in " + controller.getClassNode().getName() + " for class resolving, but found already a node of that name " + text); } } else { classVisitor.visitField(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, staticFieldName, "Ljava/lang/Class;", null, null); } mv = classVisitor.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$get$" + staticFieldName, "()Ljava/lang/Class;", null, null); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, controller.getInternalClassName(), staticFieldName, "Ljava/lang/Class;"); mv.visitInsn(DUP); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitInsn(POP); mv.visitLdcInsn(BytecodeHelper.getClassLoadingTypeDescription(cn)); mv.visitMethodInsn(INVOKESTATIC, controller.getInternalClassName(), "class$", "(Ljava/lang/String;)Ljava/lang/Class;", false); mv.visitInsn(DUP); mv.visitFieldInsn(PUTSTATIC, controller.getInternalClassName(), staticFieldName, "Ljava/lang/Class;"); mv.visitLabel(l0); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } mv = classVisitor.visitMethod(ACC_STATIC + ACC_SYNTHETIC, "class$", "(Ljava/lang/String;)Ljava/lang/Class;", null, null); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false); Label l1 = new Label(); mv.visitLabel(l1); mv.visitInsn(ARETURN); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ASTORE, 1); mv.visitTypeInsn(NEW, "java/lang/NoClassDefFoundError"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ClassNotFoundException", "getMessage", "()Ljava/lang/String;", false); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NoClassDefFoundError", "<init>", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); mv.visitTryCatchBlock(l0, l2, l2, "java/lang/ClassNotFoundException"); // br using l2 as the 2nd param seems create the right table entry mv.visitMaxs(3, 2); }
From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java
License:Apache License
@Override public void visitClosureListExpression(final ClosureListExpression expression) { MethodVisitor mv = controller.getMethodVisitor(); controller.getCompileStack().pushVariableScope(expression.getVariableScope()); List<Expression> expressions = expression.getExpressions(); final int size = expressions.size(); // init declarations for (int i = 0; i < size; i += 1) { Expression expr = expressions.get(i); if (expr instanceof DeclarationExpression) { DeclarationExpression de = (DeclarationExpression) expr; BinaryExpression be = new BinaryExpression(de.getLeftExpression(), de.getOperation(), de.getRightExpression()); expressions.set(i, be);//from w w w .jav a2 s . c o m de.setRightExpression(ConstantExpression.NULL); visitDeclarationExpression(de); } } List<Object> instructions = new LinkedList<>(); BytecodeSequence seq = new BytecodeSequence(instructions); BlockStatement bs = new BlockStatement(); bs.addStatement(seq); Parameter closureIndex = new Parameter(ClassHelper.int_TYPE, "__closureIndex"); ClosureExpression ce = new ClosureExpression(new Parameter[] { closureIndex }, bs); ce.setVariableScope(expression.getVariableScope()); // to keep stack height put a null on stack instructions.add(ConstantExpression.NULL); // init table final Label dflt = new Label(); final Label tableEnd = new Label(); final Label[] labels = new Label[size]; instructions.add(new BytecodeInstruction() { public void visit(MethodVisitor mv) { mv.visitVarInsn(ILOAD, 1); mv.visitTableSwitchInsn(0, size - 1, dflt, labels); } }); // visit cases for (int i = 0; i < size; i += 1) { Label label = new Label(); Expression expr = expressions.get(i); labels[i] = label; instructions.add(new BytecodeInstruction() { public void visit(MethodVisitor mv) { mv.visitLabel(label); // expressions will leave a value on stack, so need to pop the alibi null mv.visitInsn(POP); } }); instructions.add(expr); instructions.add(new BytecodeInstruction() { public void visit(MethodVisitor mv) { mv.visitJumpInsn(GOTO, tableEnd); } }); } // default case instructions.add(new BytecodeInstruction() { public void visit(MethodVisitor mv) { mv.visitLabel(dflt); } }); ConstantExpression text = new ConstantExpression("invalid index for closure"); ConstructorCallExpression cce = new ConstructorCallExpression( ClassHelper.make(IllegalArgumentException.class), text); ThrowStatement ts = new ThrowStatement(cce); instructions.add(ts); // return instructions.add(new BytecodeInstruction() { public void visit(MethodVisitor mv) { mv.visitLabel(tableEnd); mv.visitInsn(ARETURN); } }); // load main Closure visitClosureExpression(ce); // we need later an array to store the curried // closures, so we create it here and ave it // in a temporary variable BytecodeHelper.pushConstant(mv, size); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); int listArrayVar = controller.getCompileStack().defineTemporaryVariable("_listOfClosures", true); // add curried versions for (int i = 0; i < size; i += 1) { // stack: closure // we need to create a curried closure version // so we store the type on stack mv.visitTypeInsn(NEW, "org/codehaus/groovy/runtime/CurriedClosure"); // stack: closure, type // for a constructor call we need the type two times // and the closure after them mv.visitInsn(DUP2); mv.visitInsn(SWAP); // stack: closure,type,type,closure // so we can create the curried closure mv.visitInsn(ICONST_1); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitLdcInsn(i); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); mv.visitInsn(AASTORE); mv.visitMethodInsn(INVOKESPECIAL, "org/codehaus/groovy/runtime/CurriedClosure", "<init>", "(Lgroovy/lang/Closure;[Ljava/lang/Object;)V", false); // stack: closure,curriedClosure // we need to save the result mv.visitVarInsn(ALOAD, listArrayVar); mv.visitInsn(SWAP); BytecodeHelper.pushConstant(mv, i); mv.visitInsn(SWAP); mv.visitInsn(AASTORE); // stack: closure } // we don't need the closure any longer, so remove it mv.visitInsn(POP); // we load the array and create a list from it mv.visitVarInsn(ALOAD, listArrayVar); createListMethod.call(mv); // remove the temporary variable to keep the // stack clean controller.getCompileStack().removeVar(listArrayVar); controller.getOperandStack().pop(); }
From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java
License:Apache License
public void onLineNumber(final ASTNode statement, final String message) { if (statement == null || statement instanceof BlockStatement) return;/* w w w . j a v a 2s.c o m*/ currentASTNode = statement; int line = statement.getLineNumber(); if (line < 0 || (!ASM_DEBUG && line == controller.getLineNumber())) return; controller.setLineNumber(line); MethodVisitor mv = controller.getMethodVisitor(); if (mv != null) { Label l = new Label(); mv.visitLabel(l); mv.visitLineNumber(line, l); } }
From source file:org.codehaus.groovy.classgen.Verifier.java
License:Apache License
private void addStaticMetaClassField(final ClassNode node, final String classInternalName) { String _staticClassInfoFieldName = "$staticClassInfo"; while (node.getDeclaredField(_staticClassInfoFieldName) != null) _staticClassInfoFieldName = _staticClassInfoFieldName + "$"; final String staticMetaClassFieldName = _staticClassInfoFieldName; FieldNode staticMetaClassField = node.addField(staticMetaClassFieldName, ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, ClassHelper.make(ClassInfo.class, false), null); staticMetaClassField.setSynthetic(true); node.addSyntheticMethod("$getStaticMetaClass", ACC_PROTECTED, ClassHelper.make(MetaClass.class), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BytecodeSequence(new BytecodeInstruction() { @Override//from w ww.j a va 2 s. co m public void visit(MethodVisitor mv) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); if (BytecodeHelper.isClassLiteralPossible(node) || BytecodeHelper.isSameCompilationUnit(classNode, node)) { BytecodeHelper.visitClassLiteral(mv, node); } else { mv.visitMethodInsn(INVOKESTATIC, classInternalName, "$get$$class$" + classInternalName.replaceAll("/", "\\$"), "()Ljava/lang/Class;", false); } Label l1 = new Label(); mv.visitJumpInsn(IF_ACMPEQ, l1); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/ScriptBytecodeAdapter", "initMetaClass", "(Ljava/lang/Object;)Lgroovy/lang/MetaClass;", false); mv.visitInsn(ARETURN); mv.visitLabel(l1); mv.visitFieldInsn(GETSTATIC, classInternalName, staticMetaClassFieldName, "Lorg/codehaus/groovy/reflection/ClassInfo;"); mv.visitVarInsn(ASTORE, 1); mv.visitVarInsn(ALOAD, 1); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/reflection/ClassInfo", "getClassInfo", "(Ljava/lang/Class;)Lorg/codehaus/groovy/reflection/ClassInfo;", false); mv.visitInsn(DUP); mv.visitVarInsn(ASTORE, 1); mv.visitFieldInsn(PUTSTATIC, classInternalName, staticMetaClassFieldName, "Lorg/codehaus/groovy/reflection/ClassInfo;"); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "org/codehaus/groovy/reflection/ClassInfo", "getMetaClass", "()Lgroovy/lang/MetaClass;", false); mv.visitInsn(ARETURN); } })); }