final String getAndResetCurrentComment() { if (sourceString != null) { if (isMarkingComment()) Kit.codeBug(); return sourceString.substring(tokenBeg, tokenEnd); } else { if (!isMarkingComment()) Kit.codeBug(); StringBuilder comment = new StringBuilder(commentPrefix); comment.append(sourceBuffer, commentCursor, getTokenLength() - commentPrefix.length()); commentCursor = -1; return comment.toString(); } }
TokenStream(Parser parser, Reader sourceReader, String sourceString, int lineno) { this.parser = parser; this.lineno = lineno; if (sourceReader != null) { if (sourceString != null) Kit.codeBug(); this.sourceReader = sourceReader; this.sourceBuffer = new char[512]; this.sourceEnd = 0; } else { if (sourceString == null) Kit.codeBug(); this.sourceString = sourceString; this.sourceEnd = sourceString.length(); } this.sourceCursor = this.cursor = 0; }
public int getExistingIntProp(int propType) { PropListItem item = lookupProperty(propType); if (item == null) { Kit.codeBug(); } return item.intValue; }
/** * Generates code to push typed parameters onto the operand stack prior to a direct Java method * call. */ private static int generatePushParam(ClassFileWriter cfw, int paramOffset, Class<?> paramType) { if (!paramType.isPrimitive()) { cfw.addALoad(paramOffset); return 1; } String typeName = paramType.getName(); switch (typeName.charAt(0)) { case 'z': case 'b': case 'c': case 's': case 'i': // load an int value, convert to double. cfw.addILoad(paramOffset); return 1; case 'l': // load a long, convert to double. cfw.addLLoad(paramOffset); return 2; case 'f': // load a float, convert to double. cfw.addFLoad(paramOffset); return 1; case 'd': cfw.addDLoad(paramOffset); return 2; } throw Kit.codeBug(); }
/* 473: */ /* 474: */ private static Node addBeforeCurrent( Node parent, Node previous, Node current, Node toAdd) /* 475: */ { /* 476:562 */ if (previous == null) /* 477: */ { /* 478:563 */ if (current != parent.getFirstChild()) { /* 479:563 */ Kit.codeBug(); /* 480: */ } /* 481:564 */ parent.addChildToFront(toAdd); /* 482: */ } /* 483: */ else /* 484: */ { /* 485:566 */ if (current != previous.getNext()) { /* 486:566 */ Kit.codeBug(); /* 487: */ } /* 488:567 */ parent.addChildAfter(toAdd, previous); /* 489: */ } /* 490:569 */ return toAdd; /* 491: */ }
private void increaseSourceCapacity(int minimalCapacity) { // Call this only when capacity increase is must if (minimalCapacity <= sourceBuffer.length) Kit.codeBug(); int newCapacity = sourceBuffer.length * 2; if (newCapacity < minimalCapacity) { newCapacity = minimalCapacity; } char[] tmp = new char[newCapacity]; System.arraycopy(sourceBuffer, 0, tmp, 0, sourceTop); sourceBuffer = tmp; }
Scriptable[] createRegExpWraps(Context cx, Scriptable scope) { if (idata.itsRegExpLiterals == null) Kit.codeBug(); RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx); int N = idata.itsRegExpLiterals.length; Scriptable[] array = new Scriptable[N]; for (int i = 0; i != N; ++i) { array[i] = rep.wrapRegExp(cx, scope, idata.itsRegExpLiterals[i]); } return array; }
private static final String propToString(int propType) { if (Token.printTrees) { // If Context.printTrees is false, the compiler // can remove all these strings. switch (propType) { case FUNCTION_PROP: return "function"; case LOCAL_PROP: return "local"; case LOCAL_BLOCK_PROP: return "local_block"; case REGEXP_PROP: return "regexp"; case CASEARRAY_PROP: return "casearray"; case TARGETBLOCK_PROP: return "targetblock"; case VARIABLE_PROP: return "variable"; case ISNUMBER_PROP: return "isnumber"; case DIRECTCALL_PROP: return "directcall"; case SPECIALCALL_PROP: return "specialcall"; case SKIP_INDEXES_PROP: return "skip_indexes"; case OBJECT_IDS_PROP: return "object_ids_prop"; case INCRDECR_PROP: return "incrdecr_prop"; case CATCH_SCOPE_PROP: return "catch_scope_prop"; case LABEL_ID_PROP: return "label_id_prop"; case MEMBER_TYPE_PROP: return "member_type_prop"; case NAME_PROP: return "name_prop"; case CONTROL_BLOCK_PROP: return "control_block_prop"; case PARENTHESIZED_PROP: return "parenthesized_prop"; default: Kit.codeBug(); } } return null; }
/** Parser calls the method when it gets / or /= in literal context. */ void readRegExp(int startToken) throws IOException { int start = tokenBeg; stringBufferTop = 0; if (startToken == Token.ASSIGN_DIV) { // Miss-scanned /= addToString('='); } else { if (startToken != Token.DIV) Kit.codeBug(); } boolean inCharSet = false; // true if inside a '['..']' pair int c; while ((c = getChar()) != '/' || inCharSet) { if (c == '\n' || c == EOF_CHAR) { ungetChar(c); tokenEnd = cursor - 1; this.string = new String(stringBuffer, 0, stringBufferTop); parser.reportError("msg.unterminated.re.lit"); return; } if (c == '\\') { addToString(c); c = getChar(); } else if (c == '[') { inCharSet = true; } else if (c == ']') { inCharSet = false; } addToString(c); } int reEnd = stringBufferTop; while (true) { if (matchChar('g')) addToString('g'); else if (matchChar('i')) addToString('i'); else if (matchChar('m')) addToString('m'); else if (matchChar('y')) // FireFox 3 addToString('y'); else break; } tokenEnd = start + stringBufferTop + 2; // include slashes if (isAlpha(peekChar())) { parser.reportError("msg.invalid.re.flag"); } this.string = new String(stringBuffer, 0, reEnd); this.regExpFlags = new String(stringBuffer, reEnd, stringBufferTop - reEnd); }
void addNumber(double n) { addToken(Token.NUMBER); /* encode the number in the source stream. * Save as NUMBER type (char | char char char char) * where type is * 'D' - double, 'S' - short, 'J' - long. * We need to retain float vs. integer type info to keep the * behavior of liveconnect type-guessing the same after * decompilation. (Liveconnect tries to present 1.0 to Java * as a float/double) * OPT: This is no longer true. We could compress the format. * This may not be the most space-efficient encoding; * the chars created below may take up to 3 bytes in * constant pool UTF-8 encoding, so a Double could take * up to 12 bytes. */ long lbits = (long) n; if (lbits != n) { // if it's floating point, save as a Double bit pattern. // (12/15/97 our scanner only returns Double for f.p.) lbits = Double.doubleToLongBits(n); append('D'); append((char) (lbits >> 48)); append((char) (lbits >> 32)); append((char) (lbits >> 16)); append((char) lbits); } else { // we can ignore negative values, bc they're already prefixed // by NEG if (lbits < 0) Kit.codeBug(); // will it fit in a char? // this gives a short encoding for integer values up to 2^16. if (lbits <= Character.MAX_VALUE) { append('S'); append((char) lbits); } else { // Integral, but won't fit in a char. Store as a long. append('J'); append((char) (lbits >> 48)); append((char) (lbits >> 32)); append((char) (lbits >> 16)); append((char) lbits); } } }
// Overridden for better debug printouts @Override public String toString() { String name; switch (tagId) { case ID_NOT_FOUND: name = "NOT_FOUND"; break; case ID_NULL_VALUE: name = "NULL_VALUE"; break; case ID_DOUBLE_MARK: name = "DOUBLE_MARK"; break; default: throw Kit.codeBug(); } return super.toString() + ": " + name; }
/* 492: */ /* 493: */ private static Node replaceCurrent( Node parent, Node previous, Node current, Node replacement) /* 494: */ { /* 495:575 */ if (previous == null) /* 496: */ { /* 497:576 */ if (current != parent.getFirstChild()) { /* 498:576 */ Kit.codeBug(); /* 499: */ } /* 500:577 */ parent.replaceChild(current, replacement); /* 501: */ } /* 502:578 */ else if (previous.next == current) /* 503: */ { /* 504:581 */ parent.replaceChildAfter(previous, replacement); /* 505: */ } /* 506: */ else /* 507: */ { /* 508:583 */ parent.replaceChild(current, replacement); /* 509: */ } /* 510:585 */ return replacement; /* 511: */ }
private boolean fillSourceBuffer() throws IOException { if (sourceString != null) Kit.codeBug(); if (sourceEnd == sourceBuffer.length) { if (lineStart != 0 && !isMarkingComment()) { System.arraycopy(sourceBuffer, lineStart, sourceBuffer, 0, sourceEnd - lineStart); sourceEnd -= lineStart; sourceCursor -= lineStart; lineStart = 0; } else { char[] tmp = new char[sourceBuffer.length * 2]; System.arraycopy(sourceBuffer, 0, tmp, 0, sourceEnd); sourceBuffer = tmp; } } int n = sourceReader.read(sourceBuffer, sourceEnd, sourceBuffer.length - sourceEnd); if (n < 0) { return false; } sourceEnd += n; return true; }
public final void setLoop(Jump loop) { if (!(type == Token.LABEL)) Kit.codeBug(); if (loop == null) Kit.codeBug(); if (jumpNode != null) Kit.codeBug(); // only once jumpNode = loop; }
/* 47: */ /* 48: */ private void transformCompilationUnit_r( ScriptNode tree, Node parent, Scope scope, boolean createScopeObjects, boolean inStrictMode) /* 49: */ { /* 50:104 */ Node node = null; /* 51: */ for (; ; ) /* 52: */ { /* 53:107 */ Node previous = null; /* 54:108 */ if (node == null) /* 55: */ { /* 56:109 */ node = parent.getFirstChild(); /* 57: */ } /* 58: */ else /* 59: */ { /* 60:111 */ previous = node; /* 61:112 */ node = node.getNext(); /* 62: */ } /* 63:114 */ if (node == null) { /* 64: */ break; /* 65: */ } /* 66:118 */ int type = node.getType(); /* 67:119 */ if ((createScopeObjects) && ((type == 129) || (type == 132) || (type == 157)) && ((node instanceof Scope))) /* 68: */ { /* 69:124 */ Scope newScope = (Scope) node; /* 70:125 */ if (newScope.getSymbolTable() != null) /* 71: */ { /* 72:128 */ Node let = new Node(type == 157 ? 158 : 153); /* 73: */ /* 74:130 */ Node innerLet = new Node(153); /* 75:131 */ let.addChildToBack(innerLet); /* 76:132 */ for (String name : newScope.getSymbolTable().keySet()) { /* 77:133 */ innerLet.addChildToBack(Node.newString(39, name)); /* 78: */ } /* 79:135 */ newScope.setSymbolTable(null); /* 80:136 */ Node oldNode = node; /* 81:137 */ node = replaceCurrent(parent, previous, node, let); /* 82:138 */ type = node.getType(); /* 83:139 */ let.addChildToBack(oldNode); /* 84: */ } /* 85: */ } /* 86:143 */ switch (type) /* 87: */ { /* 88: */ case 114: /* 89: */ case 130: /* 90: */ case 132: /* 91:148 */ this.loops.push(node); /* 92:149 */ this.loopEnds.push(((Jump) node).target); /* 93:150 */ break; /* 94: */ case 123: /* 95:154 */ this.loops.push(node); /* 96:155 */ Node leave = node.getNext(); /* 97:156 */ if (leave.getType() != 3) { /* 98:157 */ Kit.codeBug(); /* 99: */ } /* 100:159 */ this.loopEnds.push(leave); /* 101:160 */ break; /* 102: */ case 81: /* 103:165 */ Jump jump = (Jump) node; /* 104:166 */ Node finallytarget = jump.getFinally(); /* 105:167 */ if (finallytarget != null) /* 106: */ { /* 107:168 */ this.hasFinally = true; /* 108:169 */ this.loops.push(node); /* 109:170 */ this.loopEnds.push(finallytarget); /* 110: */ } /* 111: */ break; /* 112: */ case 3: /* 113: */ case 131: /* 114:177 */ if ((!this.loopEnds.isEmpty()) && (this.loopEnds.peek() == node)) /* 115: */ { /* 116:178 */ this.loopEnds.pop(); /* 117:179 */ this.loops.pop(); /* 118: */ } /* 119: */ break; /* 120: */ case 72: /* 121:184 */ ((FunctionNode) tree).addResumptionPoint(node); /* 122:185 */ break; /* 123: */ case 4: /* 124:189 */ boolean isGenerator = (tree.getType() == 109) && (((FunctionNode) tree).isGenerator()); /* 125:191 */ if (isGenerator) { /* 126:192 */ node.putIntProp(20, 1); /* 127: */ } /* 128:201 */ if (this.hasFinally) /* 129: */ { /* 130:203 */ Node unwindBlock = null; /* 131:204 */ for (int i = this.loops.size() - 1; i >= 0; i--) /* 132: */ { /* 133:205 */ Node n = (Node) this.loops.get(i); /* 134:206 */ int elemtype = n.getType(); /* 135:207 */ if ((elemtype == 81) || (elemtype == 123)) /* 136: */ { /* 137: */ Node unwind; /* 138: */ Node unwind; /* 139:209 */ if (elemtype == 81) /* 140: */ { /* 141:210 */ Jump jsrnode = new Jump(135); /* 142:211 */ Node jsrtarget = ((Jump) n).getFinally(); /* 143:212 */ jsrnode.target = jsrtarget; /* 144:213 */ unwind = jsrnode; /* 145: */ } /* 146: */ else /* 147: */ { /* 148:215 */ unwind = new Node(3); /* 149: */ } /* 150:217 */ if (unwindBlock == null) { /* 151:218 */ unwindBlock = new Node(129, node.getLineno()); /* 152: */ } /* 153:221 */ unwindBlock.addChildToBack(unwind); /* 154: */ } /* 155: */ } /* 156:224 */ if (unwindBlock != null) /* 157: */ { /* 158:225 */ Node returnNode = node; /* 159:226 */ Node returnExpr = returnNode.getFirstChild(); /* 160:227 */ node = replaceCurrent(parent, previous, node, unwindBlock); /* 161:228 */ if ((returnExpr == null) || (isGenerator)) /* 162: */ { /* 163:229 */ unwindBlock.addChildToBack(returnNode); continue; /* 164: */ } /* 165:231 */ Node store = new Node(134, returnExpr); /* 166:232 */ unwindBlock.addChildToFront(store); /* 167:233 */ returnNode = new Node(64); /* 168:234 */ unwindBlock.addChildToBack(returnNode); /* 169: */ /* 170:236 */ transformCompilationUnit_r( tree, store, scope, createScopeObjects, inStrictMode); /* 171: */ } /* 172: */ } /* 173:241 */ break; /* 174: */ case 120: /* 175: */ case 121: /* 176:249 */ Jump jump = (Jump) node; /* 177:250 */ Jump jumpStatement = jump.getJumpStatement(); /* 178:251 */ if (jumpStatement == null) { /* 179:251 */ Kit.codeBug(); /* 180: */ } /* 181:253 */ int i = this.loops.size(); /* 182: */ for (; ; ) /* 183: */ { /* 184:254 */ if (i == 0) { /* 185:258 */ throw Kit.codeBug(); /* 186: */ } /* 187:260 */ i--; /* 188:261 */ Node n = (Node) this.loops.get(i); /* 189:262 */ if (n == jumpStatement) { /* 190: */ break; /* 191: */ } /* 192:266 */ int elemtype = n.getType(); /* 193:267 */ if (elemtype == 123) /* 194: */ { /* 195:268 */ Node leave = new Node(3); /* 196:269 */ previous = addBeforeCurrent(parent, previous, node, leave); /* 197: */ } /* 198:271 */ else if (elemtype == 81) /* 199: */ { /* 200:272 */ Jump tryNode = (Jump) n; /* 201:273 */ Jump jsrFinally = new Jump(135); /* 202:274 */ jsrFinally.target = tryNode.getFinally(); /* 203:275 */ previous = addBeforeCurrent(parent, previous, node, jsrFinally); /* 204: */ } /* 205: */ } /* 206:280 */ if (type == 120) { /* 207:281 */ jump.target = jumpStatement.target; /* 208: */ } else { /* 209:283 */ jump.target = jumpStatement.getContinue(); /* 210: */ } /* 211:285 */ jump.setType(5); /* 212: */ /* 213:287 */ break; /* 214: */ case 38: /* 215:291 */ visitCall(node, tree); /* 216:292 */ break; /* 217: */ case 30: /* 218:295 */ visitNew(node, tree); /* 219:296 */ break; /* 220: */ case 153: /* 221: */ case 158: /* 222:300 */ Node child = node.getFirstChild(); /* 223:301 */ if (child.getType() == 153) /* 224: */ { /* 225:304 */ boolean createWith = (tree.getType() != 109) || (((FunctionNode) tree).requiresActivation()); /* 226: */ /* 227:306 */ node = visitLet(createWith, parent, previous, node); /* 228: */ } /* 229:307 */ break; /* 230: */ case 122: /* 231: */ case 154: /* 232:316 */ Node result = new Node(129); /* 233:317 */ for (Node cursor = node.getFirstChild(); cursor != null; ) /* 234: */ { /* 235:320 */ Node n = cursor; /* 236:321 */ cursor = cursor.getNext(); /* 237:322 */ if (n.getType() == 39) /* 238: */ { /* 239:323 */ if (!n.hasChildren()) { /* 240: */ continue; /* 241: */ } /* 242:325 */ Node init = n.getFirstChild(); /* 243:326 */ n.removeChild(init); /* 244:327 */ n.setType(49); /* 245:328 */ n = new Node(type == 154 ? 155 : 8, n, init); /* 246: */ } /* 247:335 */ else if (n.getType() != 158) /* 248: */ { /* 249:336 */ throw Kit.codeBug(); /* 250: */ } /* 251:338 */ Node pop = new Node(133, n, node.getLineno()); /* 252:339 */ result.addChildToBack(pop); /* 253: */ } /* 254:341 */ node = replaceCurrent(parent, previous, node, result); /* 255:342 */ break; /* 256: */ case 137: /* 257:346 */ Scope defining = scope.getDefiningScope(node.getString()); /* 258:347 */ if (defining != null) { /* 259:348 */ node.setScope(defining); /* 260: */ } /* 261:351 */ break; /* 262: */ case 7: /* 263: */ case 32: /* 264:359 */ Node child = node.getFirstChild(); /* 265:360 */ if (type == 7) /* 266: */ { /* 267:361 */ while (child.getType() == 26) { /* 268:362 */ child = child.getFirstChild(); /* 269: */ } /* 270:364 */ if ((child.getType() == 12) || (child.getType() == 13)) /* 271: */ { /* 272:367 */ Node first = child.getFirstChild(); /* 273:368 */ Node last = child.getLastChild(); /* 274:369 */ if ((first.getType() == 39) && (first.getString().equals("undefined"))) { /* 275:371 */ child = last; /* 276:372 */ } else if ((last.getType() == 39) && (last.getString().equals("undefined"))) { /* 277:374 */ child = first; /* 278: */ } /* 279: */ } /* 280: */ } /* 281:377 */ if (child.getType() == 33) { /* 282:378 */ child.setType(34); /* 283: */ } /* 284: */ break; /* 285: */ case 8: /* 286:383 */ if (inStrictMode) { /* 287:384 */ node.setType(73); /* 288: */ } /* 289: */ case 31: /* 290: */ case 39: /* 291: */ case 155: /* 292:392 */ if (!createScopeObjects) /* 293: */ { /* 294: */ Node nameSource; /* 295: */ Node nameSource; /* 296:396 */ if (type == 39) /* 297: */ { /* 298:397 */ nameSource = node; /* 299: */ } /* 300: */ else /* 301: */ { /* 302:399 */ nameSource = node.getFirstChild(); /* 303:400 */ if (nameSource.getType() != 49) /* 304: */ { /* 305:401 */ if (type == 31) { /* 306: */ break label1734; /* 307: */ } /* 308:404 */ throw Kit.codeBug(); /* 309: */ } /* 310: */ } /* 311:407 */ if (nameSource.getScope() == null) /* 312: */ { /* 313:410 */ String name = nameSource.getString(); /* 314:411 */ Scope defining = scope.getDefiningScope(name); /* 315:412 */ if (defining != null) /* 316: */ { /* 317:413 */ nameSource.setScope(defining); /* 318:414 */ if (type == 39) /* 319: */ { /* 320:415 */ node.setType(55); /* 321: */ } /* 322:416 */ else if ((type == 8) || (type == 73)) /* 323: */ { /* 324:418 */ node.setType(56); /* 325:419 */ nameSource.setType(41); /* 326: */ } /* 327:420 */ else if (type == 155) /* 328: */ { /* 329:421 */ node.setType(156); /* 330:422 */ nameSource.setType(41); /* 331: */ } /* 332:423 */ else if (type == 31) /* 333: */ { /* 334:425 */ Node n = new Node(44); /* 335:426 */ node = replaceCurrent(parent, previous, node, n); /* 336: */ } /* 337: */ else /* 338: */ { /* 339:428 */ throw Kit.codeBug(); /* 340: */ } /* 341: */ } /* 342: */ } /* 343: */ } /* 344: */ default: /* 345: */ label1734: /* 346:435 */ transformCompilationUnit_r( tree, node, (node instanceof Scope) ? (Scope) node : scope, createScopeObjects, inStrictMode); /* 347: */ } /* 348: */ } /* 349: */ }
private void toString(ObjToIntMap printIds, StringBuffer sb) { if (Token.printTrees) { sb.append(Token.name(type)); if (this instanceof StringNode) { sb.append(' '); sb.append(getString()); } else if (this instanceof ScriptOrFnNode) { ScriptOrFnNode sof = (ScriptOrFnNode) this; if (this instanceof FunctionNode) { FunctionNode fn = (FunctionNode) this; sb.append(' '); sb.append(fn.getFunctionName()); } sb.append(" [source name: "); sb.append(sof.getSourceName()); sb.append("] [encoded source length: "); sb.append(sof.getEncodedSourceEnd() - sof.getEncodedSourceStart()); sb.append("] [base line: "); sb.append(sof.getBaseLineno()); sb.append("] [end line: "); sb.append(sof.getEndLineno()); sb.append(']'); } else if (this instanceof Jump) { Jump jump = (Jump) this; if (type == Token.BREAK || type == Token.CONTINUE) { sb.append(" [label: "); appendPrintId(jump.getJumpStatement(), printIds, sb); sb.append(']'); } else if (type == Token.TRY) { Node catchNode = jump.target; Node finallyTarget = jump.getFinally(); if (catchNode != null) { sb.append(" [catch: "); appendPrintId(catchNode, printIds, sb); sb.append(']'); } if (finallyTarget != null) { sb.append(" [finally: "); appendPrintId(finallyTarget, printIds, sb); sb.append(']'); } } else if (type == Token.LABEL || type == Token.LOOP || type == Token.SWITCH) { sb.append(" [break: "); appendPrintId(jump.target, printIds, sb); sb.append(']'); if (type == Token.LOOP) { sb.append(" [continue: "); appendPrintId(jump.getContinue(), printIds, sb); sb.append(']'); } } else { sb.append(" [target: "); appendPrintId(jump.target, printIds, sb); sb.append(']'); } } else if (type == Token.NUMBER) { sb.append(' '); sb.append(getDouble()); } else if (type == Token.TARGET) { sb.append(' '); appendPrintId(this, printIds, sb); } if (lineno != -1) { sb.append(' '); sb.append(lineno); } for (PropListItem x = propListHead; x != null; x = x.next) { int type = x.type; sb.append(" ["); sb.append(propToString(type)); sb.append(": "); String value; switch (type) { case TARGETBLOCK_PROP: // can't add this as it recurses value = "target block property"; break; case LOCAL_BLOCK_PROP: // can't add this as it is dull value = "last local block"; break; case ISNUMBER_PROP: switch (x.intValue) { case BOTH: value = "both"; break; case RIGHT: value = "right"; break; case LEFT: value = "left"; break; default: throw Kit.codeBug(); } break; case SPECIALCALL_PROP: switch (x.intValue) { case SPECIALCALL_EVAL: value = "eval"; break; case SPECIALCALL_WITH: value = "with"; break; default: // NON_SPECIALCALL should not be stored throw Kit.codeBug(); } break; default: Object obj = x.objectValue; if (obj != null) { value = obj.toString(); } else { value = String.valueOf(x.intValue); } break; } sb.append(value); sb.append(']'); } } }
/* 354: */ /* 355: */ protected Node visitLet( boolean createWith, Node parent, Node previous, Node scopeNode) /* 356: */ { /* 357:450 */ Node vars = scopeNode.getFirstChild(); /* 358:451 */ Node body = vars.getNext(); /* 359:452 */ scopeNode.removeChild(vars); /* 360:453 */ scopeNode.removeChild(body); /* 361:454 */ boolean isExpression = scopeNode.getType() == 158; /* 362: */ Node result; /* 363:457 */ if (createWith) /* 364: */ { /* 365:458 */ Node result = new Node(isExpression ? 159 : 129); /* 366:459 */ result = replaceCurrent(parent, previous, scopeNode, result); /* 367:460 */ ArrayList<Object> list = new ArrayList(); /* 368:461 */ Node objectLiteral = new Node(66); /* 369:462 */ for (Node v = vars.getFirstChild(); v != null; v = v.getNext()) /* 370: */ { /* 371:463 */ Node current = v; /* 372:464 */ if (current.getType() == 158) /* 373: */ { /* 374:466 */ List<?> destructuringNames = (List) current.getProp(22); /* 375: */ /* 376:468 */ Node c = current.getFirstChild(); /* 377:469 */ if (c.getType() != 153) { /* 378:469 */ throw Kit.codeBug(); /* 379: */ } /* 380:471 */ if (isExpression) { /* 381:472 */ body = new Node(89, c.getNext(), body); /* 382: */ } else { /* 383:474 */ body = new Node(129, new Node(133, c.getNext()), body); /* 384: */ } /* 385:480 */ if (destructuringNames != null) /* 386: */ { /* 387:481 */ list.addAll(destructuringNames); /* 388:482 */ for (int i = 0; i < destructuringNames.size(); i++) { /* 389:483 */ objectLiteral.addChildToBack(new Node(126, Node.newNumber(0.0D))); /* 390: */ } /* 391: */ } /* 392:487 */ current = c.getFirstChild(); /* 393: */ } /* 394:489 */ if (current.getType() != 39) { /* 395:489 */ throw Kit.codeBug(); /* 396: */ } /* 397:490 */ list.add(ScriptRuntime.getIndexObject(current.getString())); /* 398:491 */ Node init = current.getFirstChild(); /* 399:492 */ if (init == null) { /* 400:493 */ init = new Node(126, Node.newNumber(0.0D)); /* 401: */ } /* 402:495 */ objectLiteral.addChildToBack(init); /* 403: */ } /* 404:497 */ objectLiteral.putProp(12, list.toArray()); /* 405:498 */ Node newVars = new Node(2, objectLiteral); /* 406:499 */ result.addChildToBack(newVars); /* 407:500 */ result.addChildToBack(new Node(123, body)); /* 408:501 */ result.addChildToBack(new Node(3)); /* 409: */ } /* 410: */ else /* 411: */ { /* 412:503 */ result = new Node(isExpression ? 89 : 129); /* 413:504 */ result = replaceCurrent(parent, previous, scopeNode, result); /* 414:505 */ Node newVars = new Node(89); /* 415:506 */ for (Node v = vars.getFirstChild(); v != null; v = v.getNext()) /* 416: */ { /* 417:507 */ Node current = v; /* 418:508 */ if (current.getType() == 158) /* 419: */ { /* 420:510 */ Node c = current.getFirstChild(); /* 421:511 */ if (c.getType() != 153) { /* 422:511 */ throw Kit.codeBug(); /* 423: */ } /* 424:513 */ if (isExpression) { /* 425:514 */ body = new Node(89, c.getNext(), body); /* 426: */ } else { /* 427:516 */ body = new Node(129, new Node(133, c.getNext()), body); /* 428: */ } /* 429:521 */ Scope.joinScopes((Scope) current, (Scope) scopeNode); /* 430: */ /* 431:523 */ current = c.getFirstChild(); /* 432: */ } /* 433:525 */ if (current.getType() != 39) { /* 434:525 */ throw Kit.codeBug(); /* 435: */ } /* 436:526 */ Node stringNode = Node.newString(current.getString()); /* 437:527 */ stringNode.setScope((Scope) scopeNode); /* 438:528 */ Node init = current.getFirstChild(); /* 439:529 */ if (init == null) { /* 440:530 */ init = new Node(126, Node.newNumber(0.0D)); /* 441: */ } /* 442:532 */ newVars.addChildToBack(new Node(56, stringNode, init)); /* 443: */ } /* 444:534 */ if (isExpression) /* 445: */ { /* 446:535 */ result.addChildToBack(newVars); /* 447:536 */ scopeNode.setType(89); /* 448:537 */ result.addChildToBack(scopeNode); /* 449:538 */ scopeNode.addChildToBack(body); /* 450:539 */ if ((body instanceof Scope)) /* 451: */ { /* 452:540 */ Scope scopeParent = ((Scope) body).getParentScope(); /* 453:541 */ ((Scope) body).setParentScope((Scope) scopeNode); /* 454:542 */ ((Scope) scopeNode).setParentScope(scopeParent); /* 455: */ } /* 456: */ } /* 457: */ else /* 458: */ { /* 459:545 */ result.addChildToBack(new Node(133, newVars)); /* 460:546 */ scopeNode.setType(129); /* 461:547 */ result.addChildToBack(scopeNode); /* 462:548 */ scopeNode.addChildrenToBack(body); /* 463:549 */ if ((body instanceof Scope)) /* 464: */ { /* 465:550 */ Scope scopeParent = ((Scope) body).getParentScope(); /* 466:551 */ ((Scope) body).setParentScope((Scope) scopeNode); /* 467:552 */ ((Scope) scopeNode).setParentScope(scopeParent); /* 468: */ } /* 469: */ } /* 470: */ } /* 471:556 */ return result; /* 472: */ }
public void labelId(int labelId) { if (type != Token.TARGET) Kit.codeBug(); putIntProp(LABEL_ID_PROP, labelId); }
public boolean hasSideEffects() { switch (type) { case Token.EXPR_VOID: case Token.COMMA: if (last != null) return last.hasSideEffects(); else return true; case Token.HOOK: if (first == null || first.next == null || first.next.next == null) Kit.codeBug(); return first.next.hasSideEffects() && first.next.next.hasSideEffects(); case Token.ERROR: // Avoid cascaded error messages case Token.EXPR_RESULT: case Token.ASSIGN: case Token.ASSIGN_ADD: case Token.ASSIGN_SUB: case Token.ASSIGN_MUL: case Token.ASSIGN_DIV: case Token.ASSIGN_MOD: case Token.ASSIGN_BITOR: case Token.ASSIGN_BITXOR: case Token.ASSIGN_BITAND: case Token.ASSIGN_LSH: case Token.ASSIGN_RSH: case Token.ASSIGN_URSH: case Token.ENTERWITH: case Token.LEAVEWITH: case Token.RETURN: case Token.GOTO: case Token.IFEQ: case Token.IFNE: case Token.NEW: case Token.DELPROP: case Token.SETNAME: case Token.SETPROP: case Token.SETELEM: case Token.CALL: case Token.THROW: case Token.RETHROW: case Token.SETVAR: case Token.CATCH_SCOPE: case Token.RETURN_RESULT: case Token.SET_REF: case Token.DEL_REF: case Token.REF_CALL: case Token.TRY: case Token.SEMI: case Token.INC: case Token.DEC: case Token.EXPORT: case Token.IMPORT: case Token.IF: case Token.ELSE: case Token.SWITCH: case Token.WHILE: case Token.DO: case Token.FOR: case Token.BREAK: case Token.CONTINUE: case Token.VAR: case Token.CONST: case Token.WITH: case Token.CATCH: case Token.FINALLY: case Token.BLOCK: case Token.LABEL: case Token.TARGET: case Token.LOOP: case Token.JSR: case Token.SETPROP_OP: case Token.SETELEM_OP: case Token.LOCAL_BLOCK: case Token.SET_REF_OP: return true; default: return false; } }
/** Can only be called when node has String context. */ public final void setString(String s) { if (s == null) Kit.codeBug(); ((StringNode) this).str = s; }
public final int labelId() { if (type != Token.TARGET) Kit.codeBug(); return getIntProp(LABEL_ID_PROP, -1); }
public final Node getDefault() { if (!(type == Token.SWITCH)) Kit.codeBug(); return target2; }
public final void setJumpStatement(Jump jumpStatement) { if (!(type == Token.BREAK || type == Token.CONTINUE)) Kit.codeBug(); if (jumpStatement == null) Kit.codeBug(); if (this.jumpNode != null) Kit.codeBug(); // only once this.jumpNode = jumpStatement; }
public final void setContinue(Node continueTarget) { if (type != Token.LOOP) Kit.codeBug(); if (continueTarget.type != Token.TARGET) Kit.codeBug(); if (target2 != null) Kit.codeBug(); // only once target2 = continueTarget; }
public final void setDefault(Node defaultTarget) { if (!(type == Token.SWITCH)) Kit.codeBug(); if (defaultTarget.type != Token.TARGET) Kit.codeBug(); if (target2 != null) Kit.codeBug(); // only once target2 = defaultTarget; }
public final Node getFinally() { if (!(type == Token.TRY)) Kit.codeBug(); return target2; }
public final Jump getLoop() { if (!(type == Token.LABEL)) Kit.codeBug(); return jumpNode; }
public final void setFinally(Node finallyTarget) { if (!(type == Token.TRY)) Kit.codeBug(); if (finallyTarget.type != Token.TARGET) Kit.codeBug(); if (target2 != null) Kit.codeBug(); // only once target2 = finallyTarget; }
/** * Find the index of the correct function to call given the set of methods or constructors and the * arguments. If no function can be found to call, return -1. */ static int findFunction(Context cx, MemberBox[] methodsOrCtors, Object[] args) { if (methodsOrCtors.length == 0) { return -1; } else if (methodsOrCtors.length == 1) { MemberBox member = methodsOrCtors[0]; Class<?>[] argTypes = member.argTypes; int alength = argTypes.length; if (member.vararg) { alength--; if (alength > args.length) { return -1; } } else { if (alength != args.length) { return -1; } } for (int j = 0; j != alength; ++j) { if (!NativeJavaObject.canConvert(args[j], argTypes[j])) { if (debug) printDebug("Rejecting (args can't convert) ", member, args); return -1; } } if (debug) printDebug("Found ", member, args); return 0; } int firstBestFit = -1; int[] extraBestFits = null; int extraBestFitsCount = 0; search: for (int i = 0; i < methodsOrCtors.length; i++) { MemberBox member = methodsOrCtors[i]; Class<?>[] argTypes = member.argTypes; int alength = argTypes.length; if (member.vararg) { alength--; if (alength > args.length) { continue search; } } else { if (alength != args.length) { continue search; } } for (int j = 0; j < alength; j++) { if (!NativeJavaObject.canConvert(args[j], argTypes[j])) { if (debug) printDebug("Rejecting (args can't convert) ", member, args); continue search; } } if (firstBestFit < 0) { if (debug) printDebug("Found first applicable ", member, args); firstBestFit = i; } else { // Compare with all currently fit methods. // The loop starts from -1 denoting firstBestFit and proceed // until extraBestFitsCount to avoid extraBestFits allocation // in the most common case of no ambiguity int betterCount = 0; // number of times member was prefered over // best fits int worseCount = 0; // number of times best fits were prefered // over member for (int j = -1; j != extraBestFitsCount; ++j) { int bestFitIndex; if (j == -1) { bestFitIndex = firstBestFit; } else { bestFitIndex = extraBestFits[j]; } MemberBox bestFit = methodsOrCtors[bestFitIndex]; if (cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS) && (bestFit.member().getModifiers() & Modifier.PUBLIC) != (member.member().getModifiers() & Modifier.PUBLIC)) { // When FEATURE_ENHANCED_JAVA_ACCESS gives us access // to non-public members, continue to prefer public // methods in overloading if ((bestFit.member().getModifiers() & Modifier.PUBLIC) == 0) ++betterCount; else ++worseCount; } else { int preference = preferSignature(args, argTypes, member.vararg, bestFit.argTypes, bestFit.vararg); if (preference == PREFERENCE_AMBIGUOUS) { break; } else if (preference == PREFERENCE_FIRST_ARG) { ++betterCount; } else if (preference == PREFERENCE_SECOND_ARG) { ++worseCount; } else { if (preference != PREFERENCE_EQUAL) Kit.codeBug(); // This should not happen in theory // but on some JVMs, Class.getMethods will return all // static methods of the class hierarchy, even if // a derived class's parameters match exactly. // We want to call the derived class's method. if (bestFit.isStatic() && bestFit.getDeclaringClass().isAssignableFrom(member.getDeclaringClass())) { // On some JVMs, Class.getMethods will return all // static methods of the class hierarchy, even if // a derived class's parameters match exactly. // We want to call the derived class's method. if (debug) printDebug("Substituting (overridden static)", member, args); if (j == -1) { firstBestFit = i; } else { extraBestFits[j] = i; } } else { if (debug) printDebug("Ignoring same signature member ", member, args); } continue search; } } } if (betterCount == 1 + extraBestFitsCount) { // member was prefered over all best fits if (debug) printDebug("New first applicable ", member, args); firstBestFit = i; extraBestFitsCount = 0; } else if (worseCount == 1 + extraBestFitsCount) { // all best fits were prefered over member, ignore it if (debug) printDebug("Rejecting (all current bests better) ", member, args); } else { // some ambiguity was present, add member to best fit set if (debug) printDebug("Added to best fit set ", member, args); if (extraBestFits == null) { // Allocate maximum possible array extraBestFits = new int[methodsOrCtors.length - 1]; } extraBestFits[extraBestFitsCount] = i; ++extraBestFitsCount; } } } if (firstBestFit < 0) { // Nothing was found return -1; } else if (extraBestFitsCount == 0) { // single best fit return firstBestFit; } // report remaining ambiguity StringBuffer buf = new StringBuffer(); for (int j = -1; j != extraBestFitsCount; ++j) { int bestFitIndex; if (j == -1) { bestFitIndex = firstBestFit; } else { bestFitIndex = extraBestFits[j]; } buf.append("\n "); buf.append(methodsOrCtors[bestFitIndex].toJavaDeclaration()); } MemberBox firstFitMember = methodsOrCtors[firstBestFit]; String memberName = firstFitMember.getName(); String memberClass = firstFitMember.getDeclaringClass().getName(); if (methodsOrCtors[0].isMethod()) { throw Context.reportRuntimeError3( "msg.constructor.ambiguous", memberName, scriptSignature(args), buf.toString()); } else { throw Context.reportRuntimeError4( "msg.method.ambiguous", memberClass, memberName, scriptSignature(args), buf.toString()); } }
public final Node getContinue() { if (type != Token.LOOP) Kit.codeBug(); return target2; }