asmclassgenerator.java
来自「大名鼎鼎的java动态脚本语言。已经通过了sun的认证」· Java 代码 · 共 1,596 行 · 第 1/5 页
JAVA
1,596 行
); cw.visitSource(sourceFile,null); super.visitClass(classNode); // set the optional enclosing method attribute of the current inner class// br comment out once Groovy uses the latest CVS HEAD of ASM// MethodNode enclosingMethod = classNode.getEnclosingMethod();// String ownerName = BytecodeHelper.getClassInternalName(enclosingMethod.getDeclaringClass().getName());// String descriptor = BytecodeHelper.getMethodDescriptor(enclosingMethod.getReturnType(), enclosingMethod.getParameters());// EnclosingMethodAttribute attr = new EnclosingMethodAttribute(ownerName,enclosingMethod.getName(),descriptor);// cw.visitAttribute(attr); createSyntheticStaticFields(); for (Iterator iter = innerClasses.iterator(); iter.hasNext();) { ClassNode innerClass = (ClassNode) iter.next(); String innerClassName = innerClass.getName(); String innerClassInternalName = BytecodeHelper.getClassInternalName(innerClassName); { int index = innerClassName.lastIndexOf('$'); if (index>=0) innerClassName = innerClassName.substring(index+1); } String outerClassName = internalClassName; // default for inner classes MethodNode enclosingMethod = innerClass.getEnclosingMethod(); if (enclosingMethod != null) { // local inner classes do not specify the outer class name outerClassName = null; innerClassName = null; } cw.visitInnerClass( innerClassInternalName, outerClassName, innerClassName, innerClass.getModifiers()); } // br TODO an inner class should have an entry of itself cw.visitEnd(); } catch (GroovyRuntimeException e) { e.setModule(classNode.getModule()); throw e; } } private String[] buildExceptions(ClassNode[] exceptions) { if (exceptions==null) return null; String[] ret = new String[exceptions.length]; for (int i = 0; i < exceptions.length; i++) { ret[i] = BytecodeHelper.getClassInternalName(exceptions[i]); } return ret; } protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { String methodType = BytecodeHelper.getMethodDescriptor(node.getReturnType(), node.getParameters()); cv = cw.visitMethod(node.getModifiers(), node.getName(), methodType, null, buildExceptions(node.getExceptions())); helper = new BytecodeHelper(cv); if (!node.isAbstract()) { Statement code = node.getCode(); if (isConstructor && (code == null || !firstStatementIsSpecialConstructorCall(node))) { // invokes the super class constructor cv.visitVarInsn(ALOAD, 0); cv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(classNode.getSuperClass()), "<init>", "()V"); } compileStack.init(node.getVariableScope(),node.getParameters(),cv, BytecodeHelper.getTypeDescription(classNode)); super.visitConstructorOrMethod(node, isConstructor); if (!outputReturn || node.isVoidMethod()) { cv.visitInsn(RETURN); } compileStack.clear(); // lets do all the exception blocks for (Iterator iter = exceptionBlocks.iterator(); iter.hasNext();) { Runnable runnable = (Runnable) iter.next(); runnable.run(); } exceptionBlocks.clear(); cv.visitMaxs(0, 0); } } private boolean firstStatementIsSpecialConstructorCall(MethodNode node) { Statement code = node.getFirstStatement(); if (code == null || !(code instanceof ExpressionStatement)) return false; Expression expression = ((ExpressionStatement)code).getExpression(); if (!(expression instanceof ConstructorCallExpression)) return false; ConstructorCallExpression cce = (ConstructorCallExpression) expression; return cce.isSpecialCall(); } public void visitConstructor(ConstructorNode node) { this.constructorNode = node; this.methodNode = null; outputReturn = false; super.visitConstructor(node); } public void visitMethod(MethodNode node) { this.constructorNode = null; this.methodNode = node; outputReturn = false; super.visitMethod(node); } public void visitField(FieldNode fieldNode) { onLineNumber(fieldNode, "visitField: " + fieldNode.getName()); ClassNode t = fieldNode.getType(); cw.visitField( fieldNode.getModifiers(), fieldNode.getName(), BytecodeHelper.getTypeDescription(t), null, //fieldValue, //br all the sudden that one cannot init the field here. init is done in static initilizer and instace intializer. null); visitAnnotations(fieldNode); } public void visitProperty(PropertyNode statement) { // the verifyer created the field and the setter/getter methods, so here is // not really something to do onLineNumber(statement, "visitProperty:" + statement.getField().getName()); this.methodNode = null; } // GroovyCodeVisitor interface //------------------------------------------------------------------------- // Statements //------------------------------------------------------------------------- protected void visitStatement(Statement statement) { String name = statement.getStatementLabel(); if (name!=null) { Label label = compileStack.createLocalLabel(name); cv.visitLabel(label); } } public void visitBlockStatement(BlockStatement block) { onLineNumber(block, "visitBlockStatement"); visitStatement(block); compileStack.pushVariableScope(block.getVariableScope()); super.visitBlockStatement(block); compileStack.pop(); } public void visitForLoop(ForStatement loop) { onLineNumber(loop, "visitForLoop"); visitStatement(loop); compileStack.pushLoop(loop.getVariableScope(),loop.getStatementLabel()); // // Declare the loop counter. Variable variable = compileStack.defineVariable(loop.getVariable(),false); // // Then initialize the iterator and generate the loop control loop.getCollectionExpression().visit(this); asIteratorMethod.call(cv); final int iteratorIdx = compileStack.defineTemporaryVariable("iterator", ClassHelper.make(java.util.Iterator.class),true); Label continueLabel = compileStack.getContinueLabel(); Label breakLabel = compileStack.getBreakLabel(); cv.visitLabel(continueLabel); cv.visitVarInsn(ALOAD, iteratorIdx); iteratorHasNextMethod.call(cv); // note: ifeq tests for ==0, a boolean is 0 if it is false cv.visitJumpInsn(IFEQ, breakLabel); cv.visitVarInsn(ALOAD, iteratorIdx); iteratorNextMethod.call(cv); helper.storeVar(variable); // Generate the loop body loop.getLoopBlock().visit(this); cv.visitJumpInsn(GOTO, continueLabel); cv.visitLabel(breakLabel); compileStack.pop(); } public void visitWhileLoop(WhileStatement loop) { onLineNumber(loop, "visitWhileLoop"); visitStatement(loop); compileStack.pushLoop(loop.getStatementLabel()); Label continueLabel = compileStack.getContinueLabel(); Label breakLabel = compileStack.getBreakLabel(); cv.visitLabel(continueLabel); loop.getBooleanExpression().visit(this); cv.visitJumpInsn(IFEQ, breakLabel); loop.getLoopBlock().visit(this); cv.visitJumpInsn(GOTO, continueLabel); cv.visitLabel(breakLabel); compileStack.pop(); } public void visitDoWhileLoop(DoWhileStatement loop) { onLineNumber(loop, "visitDoWhileLoop"); visitStatement(loop); compileStack.pushLoop(loop.getStatementLabel()); Label breakLabel = compileStack.getBreakLabel(); Label continueLabel = compileStack.getContinueLabel(); cv.visitLabel(continueLabel); loop.getLoopBlock().visit(this); loop.getBooleanExpression().visit(this); cv.visitJumpInsn(IFEQ, continueLabel); cv.visitLabel(breakLabel); compileStack.pop(); } public void visitIfElse(IfStatement ifElse) { onLineNumber(ifElse, "visitIfElse"); visitStatement(ifElse); ifElse.getBooleanExpression().visit(this); Label l0 = new Label(); cv.visitJumpInsn(IFEQ, l0); ifElse.getIfBlock().visit(this); Label l1 = new Label(); cv.visitJumpInsn(GOTO, l1); cv.visitLabel(l0); ifElse.getElseBlock().visit(this); cv.visitLabel(l1); } public void visitTernaryExpression(TernaryExpression expression) { onLineNumber(expression, "visitTernaryExpression"); expression.getBooleanExpression().visit(this); Label l0 = new Label(); cv.visitJumpInsn(IFEQ, l0); expression.getTrueExpression().visit(this); Label l1 = new Label(); cv.visitJumpInsn(GOTO, l1); cv.visitLabel(l0); expression.getFalseExpression().visit(this); cv.visitLabel(l1); } public void visitAssertStatement(AssertStatement statement) { onLineNumber(statement, "visitAssertStatement"); visitStatement(statement); BooleanExpression booleanExpression = statement.getBooleanExpression(); booleanExpression.visit(this); Label l0 = new Label(); cv.visitJumpInsn(IFEQ, l0); // do nothing Label l1 = new Label(); cv.visitJumpInsn(GOTO, l1); cv.visitLabel(l0); // push expression string onto stack String expressionText = booleanExpression.getText(); List list = new ArrayList(); addVariableNames(booleanExpression, list); if (list.isEmpty()) { cv.visitLdcInsn(expressionText); } else { boolean first = true; // lets create a new expression cv.visitTypeInsn(NEW, "java/lang/StringBuffer"); cv.visitInsn(DUP); cv.visitLdcInsn(expressionText + ". Values: "); cv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "(Ljava/lang/String;)V"); int tempIndex = compileStack.defineTemporaryVariable("assert",true); for (Iterator iter = list.iterator(); iter.hasNext();) { String name = (String) iter.next(); String text = name + " = "; if (first) { first = false; } else { text = ", " + text; } cv.visitVarInsn(ALOAD, tempIndex); cv.visitLdcInsn(text); cv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(Ljava/lang/Object;)Ljava/lang/StringBuffer;");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?