📄 irfactory.java
字号:
{ setRequiresActivation(); Node result = new Node(Token.BLOCK, lineno); result.addChildToBack(new Node(Token.ENTERWITH, obj)); Node bodyNode = new Node(Token.WITH, body, lineno); result.addChildrenToBack(bodyNode); result.addChildToBack(new Node(Token.LEAVEWITH)); return result; } /** * DOTQUERY */ public Node createDotQuery (Node obj, Node body, int lineno) { setRequiresActivation(); Node result = new Node(Token.DOTQUERY, obj, body, lineno); return result; } Node createArrayLiteral(ObjArray elems, int skipCount, int destructuringLen) { int length = elems.size(); int[] skipIndexes = null; if (skipCount != 0) { skipIndexes = new int[skipCount]; } Node array = new Node(Token.ARRAYLIT); for (int i = 0, j = 0; i != length; ++i) { Node elem = (Node)elems.get(i); if (elem != null) { array.addChildToBack(elem); } else { skipIndexes[j] = i; ++j; } } if (skipCount != 0) { array.putProp(Node.SKIP_INDEXES_PROP, skipIndexes); } array.putIntProp(Node.DESTRUCTURING_ARRAY_LENGTH, destructuringLen); return array; } /** * Object Literals * <BR> createObjectLiteral rewrites its argument as object * creation plus object property entries, so later compiler * stages don't need to know about object literals. */ Node createObjectLiteral(ObjArray elems) { int size = elems.size() / 2; Node object = new Node(Token.OBJECTLIT); Object[] properties; if (size == 0) { properties = ScriptRuntime.emptyArgs; } else { properties = new Object[size]; for (int i = 0; i != size; ++i) { properties[i] = elems.get(2 * i); Node value = (Node)elems.get(2 * i + 1); object.addChildToBack(value); } } object.putProp(Node.OBJECT_IDS_PROP, properties); return object; } /** * Regular expressions */ Node createRegExp(int regexpIndex) { Node n = new Node(Token.REGEXP); n.putIntProp(Node.REGEXP_PROP, regexpIndex); return n; } /** * If statement */ Node createIf(Node cond, Node ifTrue, Node ifFalse, int lineno) { int condStatus = isAlwaysDefinedBoolean(cond); if (condStatus == ALWAYS_TRUE_BOOLEAN) { return ifTrue; } else if (condStatus == ALWAYS_FALSE_BOOLEAN) { if (ifFalse != null) { return ifFalse; } // Replace if (false) xxx by empty block return new Node(Token.BLOCK, lineno); } Node result = new Node(Token.BLOCK, lineno); Node ifNotTarget = Node.newTarget(); Node.Jump IFNE = new Node.Jump(Token.IFNE, cond); IFNE.target = ifNotTarget; result.addChildToBack(IFNE); result.addChildrenToBack(ifTrue); if (ifFalse != null) { Node endTarget = Node.newTarget(); result.addChildToBack(makeJump(Token.GOTO, endTarget)); result.addChildToBack(ifNotTarget); result.addChildrenToBack(ifFalse); result.addChildToBack(endTarget); } else { result.addChildToBack(ifNotTarget); } return result; } Node createCondExpr(Node cond, Node ifTrue, Node ifFalse) { int condStatus = isAlwaysDefinedBoolean(cond); if (condStatus == ALWAYS_TRUE_BOOLEAN) { return ifTrue; } else if (condStatus == ALWAYS_FALSE_BOOLEAN) { return ifFalse; } return new Node(Token.HOOK, cond, ifTrue, ifFalse); } /** * Unary */ Node createUnary(int nodeType, Node child) { int childType = child.getType(); switch (nodeType) { case Token.DELPROP: { Node n; if (childType == Token.NAME) { // Transform Delete(Name "a") // to Delete(Bind("a"), String("a")) child.setType(Token.BINDNAME); Node left = child; Node right = Node.newString(child.getString()); n = new Node(nodeType, left, right); } else if (childType == Token.GETPROP || childType == Token.GETELEM) { Node left = child.getFirstChild(); Node right = child.getLastChild(); child.removeChild(left); child.removeChild(right); n = new Node(nodeType, left, right); } else if (childType == Token.GET_REF) { Node ref = child.getFirstChild(); child.removeChild(ref); n = new Node(Token.DEL_REF, ref); } else { n = new Node(Token.TRUE); } return n; } case Token.TYPEOF: if (childType == Token.NAME) { child.setType(Token.TYPEOFNAME); return child; } break; case Token.BITNOT: if (childType == Token.NUMBER) { int value = ScriptRuntime.toInt32(child.getDouble()); child.setDouble(~value); return child; } break; case Token.NEG: if (childType == Token.NUMBER) { child.setDouble(-child.getDouble()); return child; } break; case Token.NOT: { int status = isAlwaysDefinedBoolean(child); if (status != 0) { int type; if (status == ALWAYS_TRUE_BOOLEAN) { type = Token.FALSE; } else { type = Token.TRUE; } if (childType == Token.TRUE || childType == Token.FALSE) { child.setType(type); return child; } return new Node(type); } break; } } return new Node(nodeType, child); } Node createYield(Node child, int lineno) { if (!parser.insideFunction()) { parser.reportError("msg.bad.yield"); } setRequiresActivation(); setIsGenerator(); if (child != null) return new Node(Token.YIELD, child, lineno); else return new Node(Token.YIELD, lineno); } Node createCallOrNew(int nodeType, Node child) { int type = Node.NON_SPECIALCALL; if (child.getType() == Token.NAME) { String name = child.getString(); if (name.equals("eval")) { type = Node.SPECIALCALL_EVAL; } else if (name.equals("With")) { type = Node.SPECIALCALL_WITH; } } else if (child.getType() == Token.GETPROP) { String name = child.getLastChild().getString(); if (name.equals("eval")) { type = Node.SPECIALCALL_EVAL; } } Node node = new Node(nodeType, child); if (type != Node.NON_SPECIALCALL) { // Calls to these functions require activation objects. setRequiresActivation(); node.putIntProp(Node.SPECIALCALL_PROP, type); } return node; } Node createIncDec(int nodeType, boolean post, Node child) { child = makeReference(child); if (child == null) { String msg; if (nodeType == Token.DEC) { msg = "msg.bad.decr"; } else { msg = "msg.bad.incr"; } parser.reportError(msg); return null; } int childType = child.getType(); switch (childType) { case Token.NAME: case Token.GETPROP: case Token.GETELEM: case Token.GET_REF: { Node n = new Node(nodeType, child); int incrDecrMask = 0; if (nodeType == Token.DEC) { incrDecrMask |= Node.DECR_FLAG; } if (post) { incrDecrMask |= Node.POST_FLAG; } n.putIntProp(Node.INCRDECR_PROP, incrDecrMask); return n; } } throw Kit.codeBug(); } Node createPropertyGet(Node target, String namespace, String name, int memberTypeFlags) { if (namespace == null && memberTypeFlags == 0) { if (target == null) { return createName(name); } checkActivationName(name, Token.GETPROP); if (ScriptRuntime.isSpecialProperty(name)) { Node ref = new Node(Token.REF_SPECIAL, target); ref.putProp(Node.NAME_PROP, name); return new Node(Token.GET_REF, ref); } return new Node(Token.GETPROP, target, createString(name)); } Node elem = createString(name); memberTypeFlags |= Node.PROPERTY_FLAG; return createMemberRefGet(target, namespace, elem, memberTypeFlags); } Node createElementGet(Node target, String namespace, Node elem, int memberTypeFlags) { // OPT: could optimize to createPropertyGet // iff elem is string that can not be number if (namespace == null && memberTypeFlags == 0) { // stand-alone [aaa] as primary expression is array literal // declaration and should not come here! if (target == null) throw Kit.codeBug(); return new Node(Token.GETELEM, target, elem); } return createMemberRefGet(target, namespace, elem, memberTypeFlags); } private Node createMemberRefGet(Node target, String namespace, Node elem, int memberTypeFlags) { Node nsNode = null; if (namespace != null) { // See 11.1.2 in ECMA 357 if (namespace.equals("*")) { nsNode = new Node(Token.NULL); } else { nsNode = createName(namespace); } } Node ref; if (target == null) { if (namespace == null) { ref = new Node(Token.REF_NAME, elem); } else { ref = new Node(Token.REF_NS_NAME, nsNode, elem); } } else { if (namespace == null) { ref = new Node(Token.REF_MEMBER, target, elem); } else { ref = new Node(Token.REF_NS_MEMBER, target, nsNode, elem); } } if (memberTypeFlags != 0) { ref.putIntProp(Node.MEMBER_TYPE_PROP, memberTypeFlags); } return new Node(Token.GET_REF, ref); } /** * Binary */ Node createBinary(int nodeType, Node left, Node right) { switch (nodeType) { case Token.ADD: // numerical addition and string concatenation if (left.type == Token.STRING) { String s2; if (right.type == Token.STRING) { s2 = right.getString(); } else if (right.type == Token.NUMBER) { s2 = ScriptRuntime.numberToString(right.getDouble(), 10); } else { break; } String s1 = left.getString(); left.setString(s1.concat(s2)); return left; } else if (left.type == Token.NUMBER) { if (right.type == Token.NUMBER) { left.setDouble(left.getDouble() + right.getDouble()); return left; } else if (right.type == Token.STRING) { String s1, s2; s1 = ScriptRuntime.numberToString(left.getDouble(), 10); s2 = right.getString(); right.setString(s1.concat(s2)); return right; } } // can't do anything if we don't know both types - since // 0 + object is supposed to call toString on the object and do // string concantenation rather than addition break; case Token.SUB: // numerical subtraction if (left.type == Token.NUMBER) { double ld = left.getDouble(); if (right.type == Token.NUMBER) { //both numbers left.setDouble(ld - right.getDouble()); return left; } else if (ld == 0.0) { // first 0: 0-x -> -x return new Node(Token.NEG, right); } } else if (right.type == Token.NUMBER) { if (right.getDouble() == 0.0) { //second 0: x - 0 -> +x // can not make simply x because x - 0 must be number return new Node(Token.POS, left); } } break; case Token.MUL: // numerical multiplication if (left.type == Token.NUMBER) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -