📄 interpreter.java
字号:
if (inum == num) { if (inum == 0) { addIcode(Icode_ZERO); // Check for negative zero if (1.0 / num < 0.0) { addToken(Token.NEG); } } else if (inum == 1) { addIcode(Icode_ONE); } else if ((short)inum == inum) { addIcode(Icode_SHORTNUMBER); // write short as uin16 bit pattern addUint16(inum & 0xFFFF); } else { addIcode(Icode_INTNUMBER); addInt(inum); } } else { int index = getDoubleIndex(num); addIndexOp(Token.NUMBER, index); } stackChange(1); } break; case Token.GETVAR: { if (itsData.itsNeedsActivation) Kit.codeBug(); String name = node.getString(); int index = scriptOrFn.getParamOrVarIndex(name); addVarOp(Token.GETVAR, index); stackChange(1); } break; case Token.SETVAR: { if (itsData.itsNeedsActivation) Kit.codeBug(); String name = child.getString(); child = child.getNext(); visitExpression(child, 0); int index = scriptOrFn.getParamOrVarIndex(name); addVarOp(Token.SETVAR, index); } break; case Token.NULL: case Token.THIS: case Token.THISFN: case Token.FALSE: case Token.TRUE: addToken(type); stackChange(1); break; case Token.ENUM_NEXT: case Token.ENUM_ID: addIndexOp(type, getLocalBlockRef(node)); stackChange(1); break; case Token.REGEXP: { int index = node.getExistingIntProp(Node.REGEXP_PROP); addIndexOp(Token.REGEXP, index); stackChange(1); } break; case Token.ARRAYLIT: case Token.OBJECTLIT: visitLiteral(node, child); break; case Token.REF_SPECIAL: visitExpression(child, 0); addStringOp(type, (String)node.getProp(Node.NAME_PROP)); break; case Token.REF_MEMBER: case Token.REF_NS_MEMBER: case Token.REF_NAME: case Token.REF_NS_NAME: { int memberTypeFlags = node.getIntProp(Node.MEMBER_TYPE_PROP, 0); // generate possible target, possible namespace and member int childCount = 0; do { visitExpression(child, 0); ++childCount; child = child.getNext(); } while (child != null); addIndexOp(type, memberTypeFlags); stackChange(1 - childCount); } break; case Token.DOTQUERY: { int queryPC; updateLineNumber(node); visitExpression(child, 0); addIcode(Icode_ENTERDQ); stackChange(-1); queryPC = itsICodeTop; visitExpression(child.getNext(), 0); addBackwardGoto(Icode_LEAVEDQ, queryPC); } break; case Token.DEFAULTNAMESPACE : case Token.ESCXMLATTR : case Token.ESCXMLTEXT : visitExpression(child, 0); addToken(type); break; default: throw badTree(node); } if (savedStackDepth + 1 != itsStackDepth) { Kit.codeBug(); } } private void generateCallFunAndThis(Node left) { // Generate code to place on stack function and thisObj int type = left.getType(); switch (type) { case Token.NAME: { String name = left.getString(); // stack: ... -> ... function thisObj addStringOp(Icode_NAME_AND_THIS, name); stackChange(2); break; } case Token.GETPROP: case Token.GETELEM: { Node target = left.getFirstChild(); visitExpression(target, 0); Node id = target.getNext(); if (type == Token.GETPROP) { String property = id.getString(); // stack: ... target -> ... function thisObj addStringOp(Icode_PROP_AND_THIS, property); stackChange(1); } else { visitExpression(id, 0); // stack: ... target id -> ... function thisObj addIcode(Icode_ELEM_AND_THIS); } break; } default: // Including Token.GETVAR visitExpression(left, 0); // stack: ... value -> ... function thisObj addIcode(Icode_VALUE_AND_THIS); stackChange(1); break; } } private void visitIncDec(Node node, Node child) { int incrDecrMask = node.getExistingIntProp(Node.INCRDECR_PROP); int childType = child.getType(); switch (childType) { case Token.GETVAR : { if (itsData.itsNeedsActivation) Kit.codeBug(); String name = child.getString(); int i = scriptOrFn.getParamOrVarIndex(name); addVarOp(Icode_VAR_INC_DEC, i); addUint8(incrDecrMask); stackChange(1); break; } case Token.NAME : { String name = child.getString(); addStringOp(Icode_NAME_INC_DEC, name); addUint8(incrDecrMask); stackChange(1); break; } case Token.GETPROP : { Node object = child.getFirstChild(); visitExpression(object, 0); String property = object.getNext().getString(); addStringOp(Icode_PROP_INC_DEC, property); addUint8(incrDecrMask); break; } case Token.GETELEM : { Node object = child.getFirstChild(); visitExpression(object, 0); Node index = object.getNext(); visitExpression(index, 0); addIcode(Icode_ELEM_INC_DEC); addUint8(incrDecrMask); stackChange(-1); break; } case Token.GET_REF : { Node ref = child.getFirstChild(); visitExpression(ref, 0); addIcode(Icode_REF_INC_DEC); addUint8(incrDecrMask); break; } default : { throw badTree(node); } } } private void visitLiteral(Node node, Node child) { int type = node.getType(); int count; Object[] propertyIds = null; if (type == Token.ARRAYLIT) { count = 0; for (Node n = child; n != null; n = n.getNext()) { ++count; } } else if (type == Token.OBJECTLIT) { propertyIds = (Object[])node.getProp(Node.OBJECT_IDS_PROP); count = propertyIds.length; } else { throw badTree(node); } addIndexOp(Icode_LITERAL_NEW, count); stackChange(1); while (child != null) { visitExpression(child, 0); addIcode(Icode_LITERAL_SET); stackChange(-1); child = child.getNext(); } if (type == Token.ARRAYLIT) { int[] skipIndexes = (int[])node.getProp(Node.SKIP_INDEXES_PROP); if (skipIndexes == null) { addToken(Token.ARRAYLIT); } else { int index = itsLiteralIds.size(); itsLiteralIds.add(skipIndexes); addIndexOp(Icode_SPARE_ARRAYLIT, index); } } else { int index = itsLiteralIds.size(); itsLiteralIds.add(propertyIds); addIndexOp(Token.OBJECTLIT, index); } } private int getLocalBlockRef(Node node) { Node localBlock = (Node)node.getProp(Node.LOCAL_BLOCK_PROP); return localBlock.getExistingIntProp(Node.LOCAL_PROP); } private int getTargetLabel(Node target) { int label = target.labelId(); if (label != -1) { return label; } label = itsLabelTableTop; if (itsLabelTable == null || label == itsLabelTable.length) { if (itsLabelTable == null) { itsLabelTable = new int[MIN_LABEL_TABLE_SIZE]; }else { int[] tmp = new int[itsLabelTable.length * 2]; System.arraycopy(itsLabelTable, 0, tmp, 0, label); itsLabelTable = tmp; } } itsLabelTableTop = label + 1; itsLabelTable[label] = -1; target.labelId(label); return label; } private void markTargetLabel(Node target) { int label = getTargetLabel(target); if (itsLabelTable[label] != -1) { // Can mark label only once Kit.codeBug(); } itsLabelTable[label] = itsICodeTop; } private void addGoto(Node target, int gotoOp) { int label = getTargetLabel(target); if (!(label < itsLabelTableTop)) Kit.codeBug(); int targetPC = itsLabelTable[label]; if (targetPC != -1) { addBackwardGoto(gotoOp, targetPC); } else { int gotoPC = itsICodeTop; addGotoOp(gotoOp); int top = itsFixupTableTop; if (itsFixupTable == null || top == itsFixupTable.length) { if (itsFixupTable == null) { itsFixupTable = new long[MIN_FIXUP_TABLE_SIZE]; } else { long[] tmp = new long[itsFixupTable.length * 2]; System.arraycopy(itsFixupTable, 0, tmp, 0, top); itsFixupTable = tmp; } } itsFixupTableTop = top + 1; itsFixupTable[top] = ((long)label << 32) | gotoPC; } } private void fixLabelGotos() { for (int i = 0; i < itsFixupTableTop; i++) { long fixup = itsFixupTable[i]; int label = (int)(fixup >> 32); int jumpSource = (int)fixup; int pc = itsLabelTable[label]; if (pc == -1) { // Unlocated label throw Kit.codeBug(); } resolveGoto(jumpSource, pc); } itsFixupTableTop = 0; } private void addBackwardGoto(int gotoOp, int jumpPC) { int fromPC = itsICodeTop; // Ensure that this is a jump backward if (fromPC <= jumpPC) throw Kit.codeBug(); addGotoOp(gotoOp); resolveGoto(fromPC, jumpPC); } private void resolveForwardGoto(int fromPC) { // Ensure that forward jump skips at least self bytecode if (itsICodeTop < fromPC + 3) throw Kit.codeBug(); resolveGoto(fromPC, itsICodeTop); } private void resolveGoto(int fromPC, int jumpPC) { int offset = jumpPC - fromPC; // Ensure that jumps do not overlap if (0 <= offset && offset <= 2) throw Kit.codeBug(); int offsetSite = fromPC + 1; if (offset != (short)offset) { if (itsData.longJumps == null) { itsData.longJumps = new UintMap(); } itsData.longJumps.put(offsetSite, jumpPC); offset = 0; } byte[] array = itsData.itsICode; array[offsetSite] = (byte)(offset >> 8); array[offsetSite + 1] = (byte)offset; } private void addToken(int token) { if (!validTokenCode(token)) throw Kit.codeBug(); addUint8(token); } private void addIcode(int icode) { if (!validIcode(icode)) throw Kit.codeBug(); // Write negative icode as uint8 bits addUint8(icode & 0xFF); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -