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

📄 codegen.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        if (isGenerator) {            // generate the user visible method which when invoked will            // return a generator object            generateGenerator();        }    }    // This creates a the user-facing function that returns a NativeGenerator    // object.    private void generateGenerator()    {        cfw.startMethod(codegen.getBodyMethodName(scriptOrFn),                        codegen.getBodyMethodSignature(scriptOrFn),                        (short)(ClassFileWriter.ACC_STATIC                                | ClassFileWriter.ACC_PRIVATE));        initBodyGeneration();        argsLocal = firstFreeLocal++;        localsMax = firstFreeLocal;        // get top level scope        if (fnCurrent != null && !inDirectCallFunction            && (!compilerEnv.isUseDynamicScope()                || fnCurrent.fnode.getIgnoreDynamicScope()))        {            // Unless we're either in a direct call or using dynamic scope,            // use the enclosing scope of the function as our variable object.            cfw.addALoad(funObjLocal);            cfw.addInvoke(ByteCode.INVOKEINTERFACE,                          "org/mozilla/javascript/Scriptable",                          "getParentScope",                          "()Lorg/mozilla/javascript/Scriptable;");            cfw.addAStore(variableObjectLocal);        }        // generators are forced to have an activation record        cfw.addALoad(funObjLocal);        cfw.addALoad(variableObjectLocal);        cfw.addALoad(argsLocal);        addScriptRuntimeInvoke("createFunctionActivation",                               "(Lorg/mozilla/javascript/NativeFunction;"                               +"Lorg/mozilla/javascript/Scriptable;"                               +"[Ljava/lang/Object;"                               +")Lorg/mozilla/javascript/Scriptable;");        cfw.addAStore(variableObjectLocal);        // create a function object        cfw.add(ByteCode.NEW, codegen.mainClassName);        // Call function constructor        cfw.add(ByteCode.DUP);        cfw.addALoad(variableObjectLocal);        cfw.addALoad(contextLocal);           // load 'cx'        cfw.addPush(scriptOrFnIndex);        cfw.addInvoke(ByteCode.INVOKESPECIAL, codegen.mainClassName,                      "<init>", Codegen.FUNCTION_CONSTRUCTOR_SIGNATURE);        // Init mainScript field        cfw.add(ByteCode.DUP);        if (isTopLevel) Kit.codeBug();  // Only functions can be generators        cfw.add(ByteCode.ALOAD_0);        cfw.add(ByteCode.GETFIELD,                codegen.mainClassName,                Codegen.DIRECT_CALL_PARENT_FIELD,                codegen.mainClassSignature);        cfw.add(ByteCode.PUTFIELD,                codegen.mainClassName,                Codegen.DIRECT_CALL_PARENT_FIELD,                codegen.mainClassSignature);        generateNestedFunctionInits();                // create the NativeGenerator object that we return        cfw.addALoad(variableObjectLocal);        cfw.addALoad(thisObjLocal);        cfw.addLoadConstant(maxLocals);        cfw.addLoadConstant(maxStack);        addOptRuntimeInvoke("createNativeGenerator",                               "(Lorg/mozilla/javascript/NativeFunction;"                               +"Lorg/mozilla/javascript/Scriptable;"                               +"Lorg/mozilla/javascript/Scriptable;II"                               +")Lorg/mozilla/javascript/Scriptable;");        cfw.add(ByteCode.ARETURN);        cfw.stopMethod((short)(localsMax + 1));    }    private void generateNestedFunctionInits()    {        int functionCount = scriptOrFn.getFunctionCount();        for (int i = 0; i != functionCount; i++) {            OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn, i);            if (ofn.fnode.getFunctionType()                    == FunctionNode.FUNCTION_STATEMENT)            {                visitFunction(ofn, FunctionNode.FUNCTION_STATEMENT);            }        }    }    private void initBodyGeneration()    {        isTopLevel = (scriptOrFn == codegen.scriptOrFnNodes[0]);        varRegisters = null;        if (scriptOrFn.getType() == Token.FUNCTION) {            fnCurrent = OptFunctionNode.get(scriptOrFn);            hasVarsInRegs = !fnCurrent.fnode.requiresActivation();            if (hasVarsInRegs) {                int n = fnCurrent.fnode.getParamAndVarCount();                if (n != 0) {                    varRegisters = new short[n];                }            }            inDirectCallFunction = fnCurrent.isTargetOfDirectCall();            if (inDirectCallFunction && !hasVarsInRegs) Codegen.badTree();        } else {            fnCurrent = null;            hasVarsInRegs = false;            inDirectCallFunction = false;        }        locals = new int[MAX_LOCALS];        funObjLocal = 0;        contextLocal = 1;        variableObjectLocal = 2;        thisObjLocal = 3;        localsMax = (short) 4;  // number of parms + "this"        firstFreeLocal = 4;        popvLocal = -1;        argsLocal = -1;        itsZeroArgArray = -1;        itsOneArgArray = -1;        scriptRegexpLocal = -1;        epilogueLabel = -1;        enterAreaStartLabel = -1;        generatorStateLocal = -1;    }    /**     * Generate the prologue for a function or script.     */    private void generatePrologue()    {        if (inDirectCallFunction) {            int directParameterCount = scriptOrFn.getParamCount();            // 0 is reserved for function Object 'this'            // 1 is reserved for context            // 2 is reserved for parentScope            // 3 is reserved for script 'this'            if (firstFreeLocal != 4) Kit.codeBug();            for (int i = 0; i != directParameterCount; ++i) {                varRegisters[i] = firstFreeLocal;                // 3 is 1 for Object parm and 2 for double parm                firstFreeLocal += 3;            }            if (!fnCurrent.getParameterNumberContext()) {                // make sure that all parameters are objects                itsForcedObjectParameters = true;                for (int i = 0; i != directParameterCount; ++i) {                    short reg = varRegisters[i];                    cfw.addALoad(reg);                    cfw.add(ByteCode.GETSTATIC,                            "java/lang/Void",                            "TYPE",                            "Ljava/lang/Class;");                    int isObjectLabel = cfw.acquireLabel();                    cfw.add(ByteCode.IF_ACMPNE, isObjectLabel);                    cfw.addDLoad(reg + 1);                    addDoubleWrap();                    cfw.addAStore(reg);                    cfw.markLabel(isObjectLabel);                }            }        }        if (fnCurrent != null && !inDirectCallFunction            && (!compilerEnv.isUseDynamicScope()                || fnCurrent.fnode.getIgnoreDynamicScope()))        {            // Unless we're either in a direct call or using dynamic scope,            // use the enclosing scope of the function as our variable object.            cfw.addALoad(funObjLocal);            cfw.addInvoke(ByteCode.INVOKEINTERFACE,                          "org/mozilla/javascript/Scriptable",                          "getParentScope",                          "()Lorg/mozilla/javascript/Scriptable;");            cfw.addAStore(variableObjectLocal);        }        // reserve 'args[]'        argsLocal = firstFreeLocal++;        localsMax = firstFreeLocal;        // Generate Generator specific prelude        if (isGenerator) {            // reserve 'args[]'            operationLocal = firstFreeLocal++;            localsMax = firstFreeLocal;            // Local 3 is a reference to a GeneratorState object. The rest            // of codegen expects local 3 to be a reference to the thisObj.            // So move the value in local 3 to generatorStateLocal, and load            // the saved thisObj from the GeneratorState object.            cfw.addALoad(thisObjLocal);            generatorStateLocal = firstFreeLocal++;            localsMax = firstFreeLocal;            cfw.add(ByteCode.CHECKCAST, OptRuntime.GeneratorState.CLASS_NAME);            cfw.add(ByteCode.DUP);            cfw.addAStore(generatorStateLocal);            cfw.add(ByteCode.GETFIELD,                    OptRuntime.GeneratorState.CLASS_NAME,                    OptRuntime.GeneratorState.thisObj_NAME,                    OptRuntime.GeneratorState.thisObj_TYPE);            cfw.addAStore(thisObjLocal);                        if (epilogueLabel == -1) {                epilogueLabel = cfw.acquireLabel();            }            ArrayList targets = ((FunctionNode)scriptOrFn).getResumptionPoints();            if (targets != null) {                // get resumption point                generateGetGeneratorResumptionPoint();                  // generate dispatch table                generatorSwitch = cfw.addTableSwitch(0,                    targets.size() + GENERATOR_START);                generateCheckForThrowOrClose(-1, false, GENERATOR_START);            }        }        if (fnCurrent == null) {            // See comments in case Token.REGEXP            if (scriptOrFn.getRegexpCount() != 0) {                scriptRegexpLocal = getNewWordLocal();                codegen.pushRegExpArray(cfw, scriptOrFn, contextLocal,                                        variableObjectLocal);                cfw.addAStore(scriptRegexpLocal);            }        }        if (compilerEnv.isGenerateObserverCount())            saveCurrentCodeOffset();        if (hasVarsInRegs) {            // No need to create activation. Pad arguments if need be.            int parmCount = scriptOrFn.getParamCount();            if (parmCount > 0 && !inDirectCallFunction) {                // Set up args array                // check length of arguments, pad if need be                cfw.addALoad(argsLocal);                cfw.add(ByteCode.ARRAYLENGTH);                cfw.addPush(parmCount);                int label = cfw.acquireLabel();                cfw.add(ByteCode.IF_ICMPGE, label);                cfw.addALoad(argsLocal);                cfw.addPush(parmCount);                addScriptRuntimeInvoke("padArguments",                                       "([Ljava/lang/Object;I"                                       +")[Ljava/lang/Object;");                cfw.addAStore(argsLocal);                cfw.markLabel(label);            }            int paramCount = fnCurrent.fnode.getParamCount();            int varCount = fnCurrent.fnode.getParamAndVarCount();            boolean [] constDeclarations = fnCurrent.fnode.getParamAndVarConst();            // REMIND - only need to initialize the vars that don't get a value            // before the next call and are used in the function            short firstUndefVar = -1;            for (int i = 0; i != varCount; ++i) {                short reg = -1;                if (i < paramCount) {                    if (!inDirectCallFunction) {                        reg = getNewWordLocal();                        cfw.addALoad(argsLocal);                        cfw.addPush(i);                        cfw.add(ByteCode.AALOAD);                        cfw.addAStore(reg);                    }                } else if (fnCurrent.isNumberVar(i)) {                    reg = getNewWordPairLocal(constDeclarations[i]);                    cfw.addPush(0.0);                    cfw.addDStore(reg);                } else {                    reg = getNewWordLocal(constDeclarations[i]);                    if (firstUndefVar == -1) {                        Codegen.pushUndefined(cfw);                        firstUndefVar = reg;                    } else {                        cfw.addALoad(firstUndefVar);                    }                    cfw.addAStore(reg);                }                if (reg >= 0) {                    if (constDeclarations[i]) {                        cfw.addPush(0);                        cfw.addIStore(reg + (fnCurrent.isNumberVar(i) ? 2 : 1));                    }                    varRegisters[i] = reg;                }                // Add debug table entry if we're generating debug info                if (compilerEnv.isGenerateDebugInfo()) {                    String name = fnCurrent.fnode.getParamOrVarName(i);                    String type = fnCurrent.isNumberVar(i)                                      ? "D" : "Ljava/lang/Object;";                    int startPC = cfw.getCurrentCodeOffset();                    if (reg < 0) {                        reg = varRegisters[i];                    }                    cfw.addVariableDescriptor(name, type, startPC, reg);                }            }            // Skip creating activation object.            return;        }        // skip creating activation object for the body of a generator. The        // activation record required by a generator has already been created        // in generateGenerator().        if (isGenerator)            return;        String debugVariableName;        if (fnCurrent != null) {            debugVariableName = "activation";            cfw.addALoad(funObjLocal);            cfw.addALoad(variableObjectLocal);            cfw.addALoad(argsLocal);            addScriptRuntimeInvoke("createFunctionActivation",                                   "(Lorg/mozilla/javascript/NativeFunction;"                                   +"Lorg/mozilla/javascript/Scrip

⌨️ 快捷键说明

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