⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asmclassgenerator.java

📁 大名鼎鼎的java动态脚本语言。已经通过了sun的认证
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        leftHandExpression = wasLeft;        return;    }    private void throwException(String s) {        throw new RuntimeParserException(s, currentASTNode);    }    public void visitPrefixExpression(PrefixExpression expression) {        switch (expression.getOperation().getType()) {            case Types.PLUS_PLUS :                evaluatePrefixMethod("next", expression.getExpression());                break;            case Types.MINUS_MINUS :                evaluatePrefixMethod("previous", expression.getExpression());                break;        }    }    public void visitClosureExpression(ClosureExpression expression) {        ClassNode innerClass = createClosureClass(expression);        addInnerClass(innerClass);        String innerClassinternalName = BytecodeHelper.getClassInternalName(innerClass);        passingClosureParams = true;        List constructors = innerClass.getDeclaredConstructors();        ConstructorNode node = (ConstructorNode) constructors.get(0);        Parameter[] localVariableParams = node.getParameters();        cv.visitTypeInsn(NEW, innerClassinternalName);        cv.visitInsn(DUP);        if (isStaticMethod() || classNode.isStaticClass()) {            visitClassExpression(new ClassExpression(classNode));        } else {            cv.visitVarInsn(ALOAD, 0);        }        // now lets load the various parameters we're passing        // we start at index 1 because the first variable we pass        // is the owner instance and at this point it is already         // on the stack        for (int i = 1; i < localVariableParams.length; i++) {            Parameter param = localVariableParams[i];            String name = param.getName();            if (compileStack.getScope().isReferencedClassVariable(name)) {                visitFieldExpression(new FieldExpression(classNode.getField(name)));            } else {                 Variable v = compileStack.getVariable(name,classNode.getSuperClass()!=ClassHelper.CLOSURE_TYPE);                if (v==null) {                    // variable is not on stack because we are                    // inside a nested Closure and this variable                    // was not used before                    // then load it from the Closure field                    FieldNode field = classNode.getField(name);                    cv.visitVarInsn(ALOAD, 0);                    cv.visitFieldInsn(GETFIELD, internalClassName, name, BytecodeHelper.getTypeDescription(field.getType()));                    // and define it                    // Note:                    // we can simply define it here and don't have to                    // be afraid about name problems because a second                    // variable with that name is not allowed inside the closure                    param.setClosureSharedVariable(false);                    v = compileStack.defineVariable(param,true);                    param.setClosureSharedVariable(true);                    v.setHolder(true);                }                 cv.visitVarInsn(ALOAD, v.getIndex());            }        }        passingClosureParams = false;        // we may need to pass in some other constructors        //cv.visitMethodInsn(INVOKESPECIAL, innerClassinternalName, "<init>", prototype + ")V");        cv.visitMethodInsn(            INVOKESPECIAL,            innerClassinternalName,            "<init>",            BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, localVariableParams));    }    /**     * Loads either this object or if we're inside a closure then load the top level owner     */    protected void loadThisOrOwner() {        if (isInnerClass()) {            visitFieldExpression(new FieldExpression(classNode.getField("owner")));        }        else {            cv.visitVarInsn(ALOAD, 0);        }    }    public void visitRegexExpression(RegexExpression expression) {        expression.getRegex().visit(this);        regexPattern.call(cv);    }    /**     * Generate byte code for constants     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#14152">Class field types</a>     */    public void visitConstantExpression(ConstantExpression expression) {        Object value = expression.getValue();        helper.loadConstant(value);    }    public void visitSpreadExpression(SpreadExpression expression) {        Expression subExpression = expression.getExpression();        subExpression.visit(this);        spreadList.call(cv);    }    public void visitSpreadMapExpression(SpreadMapExpression expression) {        Expression subExpression = expression.getExpression();        subExpression.visit(this);        spreadMap.call(cv);    }    public void visitMethodPointerExpression(MethodPointerExpression expression) {        Expression subExpression = expression.getExpression();        subExpression.visit(this);        helper.loadConstant(expression.getMethodName());        getMethodPointer.call(cv);    }    public void visitNegationExpression(NegationExpression expression) {        Expression subExpression = expression.getExpression();        subExpression.visit(this);        negation.call(cv);    }    public void visitBitwiseNegExpression(BitwiseNegExpression expression) {        Expression subExpression = expression.getExpression();        subExpression.visit(this);        bitNegation.call(cv);    }    public void visitCastExpression(CastExpression expression) {        ClassNode type = expression.getType();        visitAndAutoboxBoolean(expression.getExpression());        doConvertAndCast(type, expression.getExpression(), expression.isIgnoringAutoboxing(),false);    }    public void visitNotExpression(NotExpression expression) {        Expression subExpression = expression.getExpression();        subExpression.visit(this);        // This is not the best way to do this. Javac does it by reversing the        // underlying expressions but that proved        // fairly complicated for not much gain. Instead we'll just use a        // utility function for now.        if (isComparisonExpression(expression.getExpression())) {            notBoolean.call(cv);        }        else {            notObject.call(cv);        }    }    /**     * return a primitive boolean value of the BooleanExpresion.     * @param expression     */    public void visitBooleanExpression(BooleanExpression expression) {        compileStack.pushBooleanExpression();        expression.getExpression().visit(this);        if (!isComparisonExpression(expression.getExpression())) {// comment out for optimization when boolean values are not autoboxed for eg. function calls.//           Class typeClass = expression.getExpression().getTypeClass();//           if (typeClass != null && typeClass != boolean.class) {                asBool.call(cv); // to return a primitive boolean//            }        }        compileStack.pop();    }    private void prepareMethodcallObjectAndName(Expression objectExpression, boolean objectExpressionIsMethodName, String method) {        if (objectExpressionIsMethodName) {            VariableExpression.THIS_EXPRESSION.visit(this);            objectExpression.visit(this);        } else {            objectExpression.visit(this);            cv.visitLdcInsn(method);            }    }    public void visitMethodCallExpression(MethodCallExpression call) {        onLineNumber(call, "visitMethodCallExpression: \"" + call.getMethod() + "\":");        this.leftHandExpression = false;        Expression arguments = call.getArguments();        /*         * if (arguments instanceof TupleExpression) { TupleExpression         * tupleExpression = (TupleExpression) arguments; int size =         * tupleExpression.getExpressions().size(); if (size == 0) { arguments =         * ConstantExpression.EMPTY_ARRAY; } }         */        boolean superMethodCall = MethodCallExpression.isSuperMethodCall(call);        String method = call.getMethod();        // are we a local variable        if (isThisExpression(call.getObjectExpression()) && isFieldOrVariable(method) && ! classNode.hasPossibleMethod(method, arguments)) {            /*             * if (arguments instanceof TupleExpression) { TupleExpression             * tupleExpression = (TupleExpression) arguments; int size =             * tupleExpression.getExpressions().size(); if (size == 1) {             * arguments = (Expression)             * tupleExpression.getExpressions().get(0); } }             */                        // lets invoke the closure method            visitVariableExpression(new VariableExpression(method));            arguments.visit(this);            invokeClosureMethod.call(cv);        } else {            if (superMethodCall) {                MethodNode superMethodNode = findSuperMethod(call);                                cv.visitVarInsn(ALOAD, 0);                                loadArguments(superMethodNode.getParameters(), arguments);                                String descriptor = BytecodeHelper.getMethodDescriptor(superMethodNode.getReturnType(), superMethodNode.getParameters());                cv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(superMethodNode.getDeclaringClass()), method, descriptor);                // as long as we want to work with objects where possible, we may have to                // box the value here. This can be removed when we know the return type                 // and save it in the MethodCallExpression. By default it returns Object                // so boxing is always save.                helper.box(superMethodNode.getReturnType());            }            else {                Expression objectExpression = call.getObjectExpression();                boolean objectExpressionIsMethodName = false;                if (method.equals("call")) {                    if (objectExpression instanceof GStringExpression) {                        objectExpressionIsMethodName=true;                        objectExpression = new CastExpression(ClassHelper.STRING_TYPE, objectExpression);                    } else if (objectExpression instanceof ConstantExpression) {                        Object value = ((ConstantExpression) objectExpression).getValue();                        if ( value != null && value instanceof String) objectExpressionIsMethodName=true;                    }                }                                if (emptyArguments(arguments) && !call.isSafe() && !call.isSpreadSafe()) {                    prepareMethodcallObjectAndName(objectExpression, objectExpressionIsMethodName,method);                    invokeNoArgumentsMethod.call(cv);                } else {                    if (argumentsUseStack(arguments)) {                                                arguments.visit(this);                                                int paramIdx = compileStack.defineTemporaryVariable(method + "_arg",true);                                                prepareMethodcallObjectAndName(objectExpression, objectExpressionIsMethodName,method);                                                cv.visitVarInsn(ALOAD, paramIdx);                        compileStack.removeVar(paramIdx);                    } else {                        prepareMethodcallObjectAndName(objectExpression, objectExpressionIsMethodName,method);                        arguments.visit(this);                    }                                        if (call.isSpreadSafe()) {                        invokeMethodSpreadSafeMethod.call(cv);                    }                    else if (call.isSafe()) {                        invokeMethodSafeMethod.call(cv);                    }                    else {                        invokeMethodMethod.call(cv);                    }                }            }        }    }    /**     * Loads and coerces the argument values for the given method call     */    protected void loadArguments(Parameter[] parameters, Expression expression) {        TupleExpression argListExp = (TupleExpression) expression;        List arguments = argListExp.getExpressions();        for (int i = 0, size = arguments.size(); i < size; i++) {            Expression argExp = argListExp.getExpression(i);            Parameter param = parameters[i];            visitAndAutoboxBoolean(argExp);            ClassNode type = param.getType();            ClassNode expType = getExpressionType(argExp);            if (!type.equals(expType)) {                doConvertAndCast(type);            }        }    }    /**     * Attempts to find the method of the given name in a super class     */    protected MethodNode findSuperMethod(MethodCallExpression call) {        String methodName = call.getMethod();        TupleExpression argExpr = (TupleExpression) call.getArguments();        int argCount = argExpr.getExpressions().size();        ClassNode superClassNode = classNode.getSuperClass();        if (superClassNode != null) {            List methods = superClassNode.getMethods(methodName);            for (Iterator iter = methods.iterator(); iter.hasNext(); ) {                MethodNode method = (MethodNode) iter.next();                if (method.getParameters().length == argCount) {                    return method;                }            }        }        throwException("No such method: " + methodName + " for class: " + classNode.getName());        return null; // should not come her

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -