public Object compile(CompilerEnvirons compilerEnv, ScriptNode tree, String encodedSource, boolean returnFunction) { this.compilerEnv = compilerEnv; CodeGenerator cgen = new CodeGenerator(); itsData = cgen.compile(compilerEnv, tree, encodedSource, returnFunction); return itsData; }
private void addBackwardGoto(int gotoOp, int jumpPC) { int fromPC = iCodeTop; // Ensure that this is a jump backward if (fromPC <= jumpPC) throw Kit.codeBug(); addGotoOp(gotoOp); resolveGoto(fromPC, jumpPC); }
private void addIndexPrefix(int index) { if (index < 0) Kit.codeBug(); if (index < 6) { addIcode(Icode_REG_IND_C0 - index); } else if (index <= 0xFF) { addIcode(Icode_REG_IND1); addUint8(index); } else if (index <= 0xFFFF) { addIcode(Icode_REG_IND2); addUint16(index); } else { addIcode(Icode_REG_IND4); addInt(index); } }
private void addIndexOp(int op, int index) { addIndexPrefix(index); if (Icode.validIcode(op)) { addIcode(op); } else { addToken(op); } }
addIndexOp(Icode_CLOSURE_EXPR, fnIndex); stackChange(1); int localIndex = getLocalBlockRef(node); addIndexOp(Token.LOCAL_LOAD, localIndex); stackChange(1); visitExpression(child, 0); addIcode(Icode_POP); stackChange(-1); child = child.getNext(); visitExpression(child, contextFlags & ECF_TAIL); stackChange(1); break; visitExpression(child, 0); } else { generateCallFunAndThis(child); visitExpression(child, 0); ++argCount; addIndexOp(Icode_CALLSPECIAL, argCount); addUint8(callType); addUint8(type == Token.NEW ? 1 : 0); addUint16(lineNumber & 0xFFFF); } else {
addIndexOp(Icode_CLOSURE_STMT, fnIndex); } else { if (fnType != FunctionNode.FUNCTION_STATEMENT) { addIndexOp(Icode_CLOSURE_EXPR, fnIndex); stackChange(1); addIcode(Icode_POP_RESULT); stackChange(-1); case Token.EMPTY: case Token.WITH: updateLineNumber(node); case Token.SCRIPT: visitStatement(child, initialStackDepth); child = child.getNext(); visitExpression(child, 0); addToken(Token.ENTERWITH); stackChange(-1); break; addToken(Token.LEAVEWITH); break; int local = allocLocal(); node.putIntProp(Node.LOCAL_PROP, local); updateLineNumber(node); while (child != null) {
if (itsData.itsNeedsActivation) Kit.codeBug(); int i = scriptOrFn.getIndexForNameNode(child); addVarOp(Icode_VAR_INC_DEC, i); addUint8(incrDecrMask); stackChange(1); break; addStringOp(Icode_NAME_INC_DEC, name); addUint8(incrDecrMask); stackChange(1); break; visitExpression(object, 0); String property = object.getNext().getString(); addStringOp(Icode_PROP_INC_DEC, property); addUint8(incrDecrMask); break; visitExpression(object, 0); Node index = object.getNext(); visitExpression(index, 0); addIcode(Icode_ELEM_INC_DEC); addUint8(incrDecrMask); stackChange(-1); break; visitExpression(ref, 0); addIcode(Icode_REF_INC_DEC); addUint8(incrDecrMask);
count = propertyIds.length; } else { throw badTree(node); addIndexOp(Icode_LITERAL_NEW, count); stackChange(2); while (child != null) { int childType = child.getType(); if (childType == Token.GET) { visitExpression(child.getFirstChild(), 0); addIcode(Icode_LITERAL_GETTER); } else if (childType == Token.SET) { visitExpression(child.getFirstChild(), 0); addIcode(Icode_LITERAL_SETTER); } else { visitExpression(child, 0); addIcode(Icode_LITERAL_SET); stackChange(-1); child = child.getNext(); int[] skipIndexes = (int[])node.getProp(Node.SKIP_INDEXES_PROP); if (skipIndexes == null) { addToken(Token.ARRAYLIT); } else { int index = literalIds.size(); literalIds.add(skipIndexes); addIndexOp(Icode_SPARE_ARRAYLIT, index);
String name = left.getString(); addStringOp(Icode_NAME_AND_THIS, name); stackChange(2); break; case Token.GETELEM: { Node target = left.getFirstChild(); visitExpression(target, 0); Node id = target.getNext(); if (type == Token.GETPROP) { String property = id.getString(); addStringOp(Icode_PROP_AND_THIS, property); stackChange(1); } else { visitExpression(id, 0); addIcode(Icode_ELEM_AND_THIS); visitExpression(left, 0); addIcode(Icode_VALUE_AND_THIS); stackChange(1); break;
private void addStringOp(int op, String str) { addStringPrefix(str); if (Icode.validIcode(op)) { addIcode(op); } else { addToken(op); } }
private void addVarOp(int op, int varIndex) { switch (op) { case Token.SETCONSTVAR: if (varIndex < 128) { addIcode(Icode_SETCONSTVAR1); addUint8(varIndex); return; } addIndexOp(Icode_SETCONSTVAR, varIndex); return; case Token.GETVAR: case Token.SETVAR: if (varIndex < 128) { addIcode(op == Token.GETVAR ? Icode_GETVAR1 : Icode_SETVAR1); addUint8(varIndex); return; } // fallthrough case Icode_VAR_INC_DEC: addIndexOp(op, varIndex); return; } throw Kit.codeBug(); }
private void addGoto(Node target, int gotoOp) { int label = getTargetLabel(target); if (!(label < labelTableTop)) Kit.codeBug(); int targetPC = labelTable[label]; if (targetPC != -1) { addBackwardGoto(gotoOp, targetPC); } else { int gotoPC = iCodeTop; addGotoOp(gotoOp); int top = fixupTableTop; if (fixupTable == null || top == fixupTable.length) { if (fixupTable == null) { fixupTable = new long[MIN_FIXUP_TABLE_SIZE]; } else { long[] tmp = new long[fixupTable.length * 2]; System.arraycopy(fixupTable, 0, tmp, 0, top); fixupTable = tmp; } } fixupTableTop = top + 1; fixupTable[top] = ((long)label << 32) | gotoPC; } }
private void generateFunctionICode() { itsInFunctionFlag = true; FunctionNode theFunction = (FunctionNode)scriptOrFn; itsData.itsFunctionType = theFunction.getFunctionType(); itsData.itsNeedsActivation = theFunction.requiresActivation(); if (theFunction.getFunctionName() != null) { itsData.itsName = theFunction.getName(); } if (!theFunction.getIgnoreDynamicScope()) { if (compilerEnv.isUseDynamicScope()) { itsData.useDynamicScope = true; } } if (theFunction.isGenerator()) { addIcode(Icode_GENERATOR); addUint16(theFunction.getBaseLineno() & 0xFFFF); } generateICodeFromTree(theFunction.getLastChild()); }
private void generateNestedFunctions() { int functionCount = scriptOrFn.getFunctionCount(); if (functionCount == 0) return; InterpreterData[] array = new InterpreterData[functionCount]; for (int i = 0; i != functionCount; i++) { FunctionNode fn = scriptOrFn.getFunctionNode(i); CodeGenerator gen = new CodeGenerator(); gen.compilerEnv = compilerEnv; gen.scriptOrFn = fn; gen.itsData = new InterpreterData(itsData); gen.generateFunctionICode(); array[i] = gen.itsData; } itsData.itsNestedFunctions = array; }
private void addStringPrefix(String str) { int index = strings.get(str, -1); if (index == -1) { index = strings.size(); strings.put(str, index); } if (index < 4) { addIcode(Icode_REG_STR_C0 - index); } else if (index <= 0xFF) { addIcode(Icode_REG_STR1); addUint8(index); } else if (index <= 0xFFFF) { addIcode(Icode_REG_STR2); addUint16(index); } else { addIcode(Icode_REG_STR4); addInt(index); } }