Changeset 38635 in webkit
- Timestamp:
- Nov 20, 2008 3:23:59 PM (15 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r38632 r38635 1 2008-11-20 Sam Weinig <sam@webkit.org> 2 3 Reviewed by Darin Adler. 4 5 Patch for https://bugs.webkit.org/show_bug.cgi?id=22385 6 <rdar://problem/6390179> 7 Lazily reparse FunctionBodyNodes on first execution. 8 9 - Saves 57MB on Membuster head. 10 11 * bytecompiler/BytecodeGenerator.cpp: 12 (JSC::BytecodeGenerator::generate): Remove vector shrinking since this is now 13 handled by destroying the ScopeNodeData after generation. 14 15 * parser/Grammar.y: Add alternate NoNode version of the grammar 16 that does not create nodes. This is used to lazily create FunctionBodyNodes 17 on first execution. 18 19 * parser/Lexer.cpp: 20 (JSC::Lexer::setCode): Fix bug where on reparse, the Lexer was confused about 21 what position and length meant. Position is the current position in the original 22 data buffer (important for getting correct line/column information) and length 23 the end offset in the original buffer. 24 * parser/Lexer.h: 25 (JSC::Lexer::sourceCode): Positions are relative to the beginning of the buffer. 26 27 * parser/Nodes.cpp: 28 (JSC::ScopeNodeData::ScopeNodeData): Move initialization of ScopeNode data here. 29 (JSC::ScopeNode::ScopeNode): Add constructor that only sets the JSGlobalData 30 for FunctionBodyNode stubs. 31 (JSC::ScopeNode::~ScopeNode): Release m_children now that we don't inherit from 32 BlockNode. 33 (JSC::ScopeNode::releaseNodes): Ditto. 34 (JSC::EvalNode::generateBytecode): Only shrink m_children, as we need to keep around 35 the rest of the data. 36 (JSC::FunctionBodyNode::FunctionBodyNode): Add constructor that only sets the 37 JSGlobalData. 38 (JSC::FunctionBodyNode::create): Ditto. 39 (JSC::FunctionBodyNode::generateBytecode): If we don't have the data, do a reparse 40 to construct it. Then after generation, destroy the data. 41 (JSC::ProgramNode::generateBytecode): After generation, destroy the AST data. 42 * parser/Nodes.h: 43 (JSC::ExpressionNode::): Add isFuncExprNode for FunctionConstructor. 44 (JSC::StatementNode::): Add isExprStatementNode for FunctionConstructor. 45 (JSC::ExprStatementNode::): Ditto. 46 (JSC::ExprStatementNode::expr): Add accessor for FunctionConstructor. 47 (JSC::FuncExprNode::): Add isFuncExprNode for FunctionConstructor 48 49 (JSC::ScopeNode::adoptData): Adopts a ScopeNodeData. 50 (JSC::ScopeNode::data): Accessor for ScopeNodeData. 51 (JSC::ScopeNode::destroyData): Deletes the ScopeNodeData. 52 (JSC::ScopeNode::setFeatures): Added. 53 (JSC::ScopeNode::varStack): Added assert. 54 (JSC::ScopeNode::functionStack): Ditto. 55 (JSC::ScopeNode::children): Ditto. 56 (JSC::ScopeNode::neededConstants): Ditto. 57 Factor m_varStack, m_functionStack, m_children and m_numConstants into ScopeNodeData. 58 59 * parser/Parser.cpp: 60 (JSC::Parser::reparse): Reparse the SourceCode in the FunctionBodyNode and set 61 set up the ScopeNodeData for it. 62 * parser/Parser.h: 63 64 * parser/SourceCode.h: 65 (JSC::SourceCode::endOffset): Added for use in the lexer. 66 67 * runtime/FunctionConstructor.cpp: 68 (JSC::getFunctionBody): Assuming a ProgramNode with one FunctionExpression in it, 69 get the FunctionBodyNode. Any issues signifies a parse failure in constructFunction. 70 (JSC::constructFunction): Make parsing functions in the form new Function(""), easier 71 by concatenating the strings together (with some glue) and parsing the function expression 72 as a ProgramNode from which we can receive the FunctionBodyNode. This has the added benefit 73 of not having special parsing code for the arguments and lazily constructing the 74 FunctionBodyNode's AST on first execution. 75 76 * runtime/Identifier.h: 77 (JSC::operator!=): Added. 78 1 79 2008-11-20 Sam Weinig <sam@webkit.org> 2 80 -
trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r38511 r38635 140 140 } 141 141 #endif 142 143 m_scopeNode->children().shrinkCapacity(0);144 if (m_codeType != EvalCode) { // eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time.145 m_scopeNode->varStack().shrinkCapacity(0);146 m_scopeNode->functionStack().shrinkCapacity(0);147 }148 142 149 143 m_codeBlock->instructions.shrinkToFit(); -
trunk/JavaScriptCore/parser/Grammar.y
r38249 r38635 284 284 %% 285 285 286 // FIXME: There are currently two versions of the grammar in this file, the normal one, and the NoNodes version used for 287 // lazy recompilation of FunctionBodyNodes. We should move to generating the two versions from a script to avoid bugs. 288 // In the mean time, make sure to make any changes to the grammar in both versions. 289 286 290 Literal: 287 291 NULLTOKEN { $$ = createNodeInfo<ExpressionNode*>(new NullNode(GLOBAL_DATA), 0, 1); } … … 1204 1208 1205 1209 FunctionBody: 1206 /* not in spec */ { $$ = FunctionBodyNode::create(GLOBAL_DATA, 0, 0, 0, NoFeatures, 0); } 1207 | SourceElements { $$ = FunctionBodyNode::create(GLOBAL_DATA, $1.m_node, $1.m_varDeclarations ? &$1.m_varDeclarations->data : 0, 1208 $1.m_funcDeclarations ? &$1.m_funcDeclarations->data : 0, 1209 $1.m_features, $1.m_numConstants); 1210 // As in mergeDeclarationLists() we have to ref/deref to safely get rid of 1211 // the declaration lists. 1212 if ($1.m_varDeclarations) { 1213 $1.m_varDeclarations->ref(); 1214 $1.m_varDeclarations->deref(); 1215 } 1216 if ($1.m_funcDeclarations) { 1217 $1.m_funcDeclarations->ref(); 1218 $1.m_funcDeclarations->deref(); 1219 } 1220 } 1210 /* not in spec */ { $$ = FunctionBodyNode::create(GLOBAL_DATA); } 1211 | SourceElements_NoNode { $$ = FunctionBodyNode::create(GLOBAL_DATA); } 1221 1212 ; 1222 1213 … … 1248 1239 ; 1249 1240 1241 // Start NoNodes 1242 1243 Literal_NoNode: 1244 NULLTOKEN 1245 | TRUETOKEN 1246 | FALSETOKEN 1247 | NUMBER 1248 | STRING 1249 | '/' /* regexp */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; } 1250 | DIVEQUAL /* regexp with /= */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; } 1251 ; 1252 1253 Property_NoNode: 1254 IDENT ':' AssignmentExpr_NoNode 1255 | STRING ':' AssignmentExpr_NoNode 1256 | NUMBER ':' AssignmentExpr_NoNode 1257 | IDENT IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; } 1258 | IDENT IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; } 1259 ; 1260 1261 PropertyList_NoNode: 1262 Property_NoNode 1263 | PropertyList_NoNode ',' Property_NoNode 1264 ; 1265 1266 PrimaryExpr_NoNode: 1267 PrimaryExprNoBrace_NoNode 1268 | OPENBRACE CLOSEBRACE 1269 | OPENBRACE PropertyList_NoNode CLOSEBRACE 1270 /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */ 1271 | OPENBRACE PropertyList_NoNode ',' CLOSEBRACE 1272 ; 1273 1274 PrimaryExprNoBrace_NoNode: 1275 THISTOKEN 1276 | Literal_NoNode 1277 | ArrayLiteral_NoNode 1278 | IDENT 1279 | '(' Expr_NoNode ')' 1280 ; 1281 1282 ArrayLiteral_NoNode: 1283 '[' ElisionOpt_NoNode ']' 1284 | '[' ElementList_NoNode ']' 1285 | '[' ElementList_NoNode ',' ElisionOpt_NoNode ']' 1286 ; 1287 1288 ElementList_NoNode: 1289 ElisionOpt_NoNode AssignmentExpr_NoNode 1290 | ElementList_NoNode ',' ElisionOpt_NoNode AssignmentExpr_NoNode 1291 ; 1292 1293 ElisionOpt_NoNode: 1294 /* nothing */ 1295 | Elision_NoNode 1296 ; 1297 1298 Elision_NoNode: 1299 ',' 1300 | Elision_NoNode ',' 1301 ; 1302 1303 MemberExpr_NoNode: 1304 PrimaryExpr_NoNode 1305 | FunctionExpr_NoNode 1306 | MemberExpr_NoNode '[' Expr_NoNode ']' 1307 | MemberExpr_NoNode '.' IDENT 1308 | NEW MemberExpr_NoNode Arguments_NoNode 1309 ; 1310 1311 MemberExprNoBF_NoNode: 1312 PrimaryExprNoBrace_NoNode 1313 | MemberExprNoBF_NoNode '[' Expr_NoNode ']' 1314 | MemberExprNoBF_NoNode '.' IDENT 1315 | NEW MemberExpr_NoNode Arguments_NoNode 1316 ; 1317 1318 NewExpr_NoNode: 1319 MemberExpr_NoNode 1320 | NEW NewExpr_NoNode 1321 ; 1322 1323 NewExprNoBF_NoNode: 1324 MemberExprNoBF_NoNode 1325 | NEW NewExpr_NoNode 1326 ; 1327 1328 CallExpr_NoNode: 1329 MemberExpr_NoNode Arguments_NoNode 1330 | CallExpr_NoNode Arguments_NoNode 1331 | CallExpr_NoNode '[' Expr_NoNode ']' 1332 | CallExpr_NoNode '.' IDENT 1333 ; 1334 1335 CallExprNoBF_NoNode: 1336 MemberExprNoBF_NoNode Arguments_NoNode 1337 | CallExprNoBF_NoNode Arguments_NoNode 1338 | CallExprNoBF_NoNode '[' Expr_NoNode ']' 1339 | CallExprNoBF_NoNode '.' IDENT 1340 ; 1341 1342 Arguments_NoNode: 1343 '(' ')' 1344 | '(' ArgumentList_NoNode ')' 1345 ; 1346 1347 ArgumentList_NoNode: 1348 AssignmentExpr_NoNode 1349 | ArgumentList_NoNode ',' AssignmentExpr_NoNode 1350 ; 1351 1352 LeftHandSideExpr_NoNode: 1353 NewExpr_NoNode 1354 | CallExpr_NoNode 1355 ; 1356 1357 LeftHandSideExprNoBF_NoNode: 1358 NewExprNoBF_NoNode 1359 | CallExprNoBF_NoNode 1360 ; 1361 1362 PostfixExpr_NoNode: 1363 LeftHandSideExpr_NoNode 1364 | LeftHandSideExpr_NoNode PLUSPLUS 1365 | LeftHandSideExpr_NoNode MINUSMINUS 1366 ; 1367 1368 PostfixExprNoBF_NoNode: 1369 LeftHandSideExprNoBF_NoNode 1370 | LeftHandSideExprNoBF_NoNode PLUSPLUS 1371 | LeftHandSideExprNoBF_NoNode MINUSMINUS 1372 ; 1373 1374 UnaryExprCommon_NoNode: 1375 DELETETOKEN UnaryExpr_NoNode 1376 | VOIDTOKEN UnaryExpr_NoNode 1377 | TYPEOF UnaryExpr_NoNode 1378 | PLUSPLUS UnaryExpr_NoNode 1379 | AUTOPLUSPLUS UnaryExpr_NoNode 1380 | MINUSMINUS UnaryExpr_NoNode 1381 | AUTOMINUSMINUS UnaryExpr_NoNode 1382 | '+' UnaryExpr_NoNode 1383 | '-' UnaryExpr_NoNode 1384 | '~' UnaryExpr_NoNode 1385 | '!' UnaryExpr_NoNode 1386 1387 UnaryExpr_NoNode: 1388 PostfixExpr_NoNode 1389 | UnaryExprCommon_NoNode 1390 ; 1391 1392 UnaryExprNoBF_NoNode: 1393 PostfixExprNoBF_NoNode 1394 | UnaryExprCommon_NoNode 1395 ; 1396 1397 MultiplicativeExpr_NoNode: 1398 UnaryExpr_NoNode 1399 | MultiplicativeExpr_NoNode '*' UnaryExpr_NoNode 1400 | MultiplicativeExpr_NoNode '/' UnaryExpr_NoNode 1401 | MultiplicativeExpr_NoNode '%' UnaryExpr_NoNode 1402 ; 1403 1404 MultiplicativeExprNoBF_NoNode: 1405 UnaryExprNoBF_NoNode 1406 | MultiplicativeExprNoBF_NoNode '*' UnaryExpr_NoNode 1407 | MultiplicativeExprNoBF_NoNode '/' UnaryExpr_NoNode 1408 | MultiplicativeExprNoBF_NoNode '%' UnaryExpr_NoNode 1409 ; 1410 1411 AdditiveExpr_NoNode: 1412 MultiplicativeExpr_NoNode 1413 | AdditiveExpr_NoNode '+' MultiplicativeExpr_NoNode 1414 | AdditiveExpr_NoNode '-' MultiplicativeExpr_NoNode 1415 ; 1416 1417 AdditiveExprNoBF_NoNode: 1418 MultiplicativeExprNoBF_NoNode 1419 | AdditiveExprNoBF_NoNode '+' MultiplicativeExpr_NoNode 1420 | AdditiveExprNoBF_NoNode '-' MultiplicativeExpr_NoNode 1421 ; 1422 1423 ShiftExpr_NoNode: 1424 AdditiveExpr_NoNode 1425 | ShiftExpr_NoNode LSHIFT AdditiveExpr_NoNode 1426 | ShiftExpr_NoNode RSHIFT AdditiveExpr_NoNode 1427 | ShiftExpr_NoNode URSHIFT AdditiveExpr_NoNode 1428 ; 1429 1430 ShiftExprNoBF_NoNode: 1431 AdditiveExprNoBF_NoNode 1432 | ShiftExprNoBF_NoNode LSHIFT AdditiveExpr_NoNode 1433 | ShiftExprNoBF_NoNode RSHIFT AdditiveExpr_NoNode 1434 | ShiftExprNoBF_NoNode URSHIFT AdditiveExpr_NoNode 1435 ; 1436 1437 RelationalExpr_NoNode: 1438 ShiftExpr_NoNode 1439 | RelationalExpr_NoNode '<' ShiftExpr_NoNode 1440 | RelationalExpr_NoNode '>' ShiftExpr_NoNode 1441 | RelationalExpr_NoNode LE ShiftExpr_NoNode 1442 | RelationalExpr_NoNode GE ShiftExpr_NoNode 1443 | RelationalExpr_NoNode INSTANCEOF ShiftExpr_NoNode 1444 | RelationalExpr_NoNode INTOKEN ShiftExpr_NoNode 1445 ; 1446 1447 RelationalExprNoIn_NoNode: 1448 ShiftExpr_NoNode 1449 | RelationalExprNoIn_NoNode '<' ShiftExpr_NoNode 1450 | RelationalExprNoIn_NoNode '>' ShiftExpr_NoNode 1451 | RelationalExprNoIn_NoNode LE ShiftExpr_NoNode 1452 | RelationalExprNoIn_NoNode GE ShiftExpr_NoNode 1453 | RelationalExprNoIn_NoNode INSTANCEOF ShiftExpr_NoNode 1454 ; 1455 1456 RelationalExprNoBF_NoNode: 1457 ShiftExprNoBF_NoNode 1458 | RelationalExprNoBF_NoNode '<' ShiftExpr_NoNode 1459 | RelationalExprNoBF_NoNode '>' ShiftExpr_NoNode 1460 | RelationalExprNoBF_NoNode LE ShiftExpr_NoNode 1461 | RelationalExprNoBF_NoNode GE ShiftExpr_NoNode 1462 | RelationalExprNoBF_NoNode INSTANCEOF ShiftExpr_NoNode 1463 | RelationalExprNoBF_NoNode INTOKEN ShiftExpr_NoNode 1464 ; 1465 1466 EqualityExpr_NoNode: 1467 RelationalExpr_NoNode 1468 | EqualityExpr_NoNode EQEQ RelationalExpr_NoNode 1469 | EqualityExpr_NoNode NE RelationalExpr_NoNode 1470 | EqualityExpr_NoNode STREQ RelationalExpr_NoNode 1471 | EqualityExpr_NoNode STRNEQ RelationalExpr_NoNode 1472 ; 1473 1474 EqualityExprNoIn_NoNode: 1475 RelationalExprNoIn_NoNode 1476 | EqualityExprNoIn_NoNode EQEQ RelationalExprNoIn_NoNode 1477 | EqualityExprNoIn_NoNode NE RelationalExprNoIn_NoNode 1478 | EqualityExprNoIn_NoNode STREQ RelationalExprNoIn_NoNode 1479 | EqualityExprNoIn_NoNode STRNEQ RelationalExprNoIn_NoNode 1480 ; 1481 1482 EqualityExprNoBF_NoNode: 1483 RelationalExprNoBF_NoNode 1484 | EqualityExprNoBF_NoNode EQEQ RelationalExpr_NoNode 1485 | EqualityExprNoBF_NoNode NE RelationalExpr_NoNode 1486 | EqualityExprNoBF_NoNode STREQ RelationalExpr_NoNode 1487 | EqualityExprNoBF_NoNode STRNEQ RelationalExpr_NoNode 1488 ; 1489 1490 BitwiseANDExpr_NoNode: 1491 EqualityExpr_NoNode 1492 | BitwiseANDExpr_NoNode '&' EqualityExpr_NoNode 1493 ; 1494 1495 BitwiseANDExprNoIn_NoNode: 1496 EqualityExprNoIn_NoNode 1497 | BitwiseANDExprNoIn_NoNode '&' EqualityExprNoIn_NoNode 1498 ; 1499 1500 BitwiseANDExprNoBF_NoNode: 1501 EqualityExprNoBF_NoNode 1502 | BitwiseANDExprNoBF_NoNode '&' EqualityExpr_NoNode 1503 ; 1504 1505 BitwiseXORExpr_NoNode: 1506 BitwiseANDExpr_NoNode 1507 | BitwiseXORExpr_NoNode '^' BitwiseANDExpr_NoNode 1508 ; 1509 1510 BitwiseXORExprNoIn_NoNode: 1511 BitwiseANDExprNoIn_NoNode 1512 | BitwiseXORExprNoIn_NoNode '^' BitwiseANDExprNoIn_NoNode 1513 ; 1514 1515 BitwiseXORExprNoBF_NoNode: 1516 BitwiseANDExprNoBF_NoNode 1517 | BitwiseXORExprNoBF_NoNode '^' BitwiseANDExpr_NoNode 1518 ; 1519 1520 BitwiseORExpr_NoNode: 1521 BitwiseXORExpr_NoNode 1522 | BitwiseORExpr_NoNode '|' BitwiseXORExpr_NoNode 1523 ; 1524 1525 BitwiseORExprNoIn_NoNode: 1526 BitwiseXORExprNoIn_NoNode 1527 | BitwiseORExprNoIn_NoNode '|' BitwiseXORExprNoIn_NoNode 1528 ; 1529 1530 BitwiseORExprNoBF_NoNode: 1531 BitwiseXORExprNoBF_NoNode 1532 | BitwiseORExprNoBF_NoNode '|' BitwiseXORExpr_NoNode 1533 ; 1534 1535 LogicalANDExpr_NoNode: 1536 BitwiseORExpr_NoNode 1537 | LogicalANDExpr_NoNode AND BitwiseORExpr_NoNode 1538 ; 1539 1540 LogicalANDExprNoIn_NoNode: 1541 BitwiseORExprNoIn_NoNode 1542 | LogicalANDExprNoIn_NoNode AND BitwiseORExprNoIn_NoNode 1543 ; 1544 1545 LogicalANDExprNoBF_NoNode: 1546 BitwiseORExprNoBF_NoNode 1547 | LogicalANDExprNoBF_NoNode AND BitwiseORExpr_NoNode 1548 ; 1549 1550 LogicalORExpr_NoNode: 1551 LogicalANDExpr_NoNode 1552 | LogicalORExpr_NoNode OR LogicalANDExpr_NoNode 1553 ; 1554 1555 LogicalORExprNoIn_NoNode: 1556 LogicalANDExprNoIn_NoNode 1557 | LogicalORExprNoIn_NoNode OR LogicalANDExprNoIn_NoNode 1558 ; 1559 1560 LogicalORExprNoBF_NoNode: 1561 LogicalANDExprNoBF_NoNode 1562 | LogicalORExprNoBF_NoNode OR LogicalANDExpr_NoNode 1563 ; 1564 1565 ConditionalExpr_NoNode: 1566 LogicalORExpr_NoNode 1567 | LogicalORExpr_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode 1568 ; 1569 1570 ConditionalExprNoIn_NoNode: 1571 LogicalORExprNoIn_NoNode 1572 | LogicalORExprNoIn_NoNode '?' AssignmentExprNoIn_NoNode ':' AssignmentExprNoIn_NoNode 1573 ; 1574 1575 ConditionalExprNoBF_NoNode: 1576 LogicalORExprNoBF_NoNode 1577 | LogicalORExprNoBF_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode 1578 ; 1579 1580 AssignmentExpr_NoNode: 1581 ConditionalExpr_NoNode 1582 | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode 1583 ; 1584 1585 AssignmentExprNoIn_NoNode: 1586 ConditionalExprNoIn_NoNode 1587 | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExprNoIn_NoNode 1588 ; 1589 1590 AssignmentExprNoBF_NoNode: 1591 ConditionalExprNoBF_NoNode 1592 | LeftHandSideExprNoBF_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode 1593 ; 1594 1595 AssignmentOperator_NoNode: 1596 '=' 1597 | PLUSEQUAL 1598 | MINUSEQUAL 1599 | MULTEQUAL 1600 | DIVEQUAL 1601 | LSHIFTEQUAL 1602 | RSHIFTEQUAL 1603 | URSHIFTEQUAL 1604 | ANDEQUAL 1605 | XOREQUAL 1606 | OREQUAL 1607 | MODEQUAL 1608 ; 1609 1610 Expr_NoNode: 1611 AssignmentExpr_NoNode 1612 | Expr_NoNode ',' AssignmentExpr_NoNode 1613 ; 1614 1615 ExprNoIn_NoNode: 1616 AssignmentExprNoIn_NoNode 1617 | ExprNoIn_NoNode ',' AssignmentExprNoIn_NoNode 1618 ; 1619 1620 ExprNoBF_NoNode: 1621 AssignmentExprNoBF_NoNode 1622 | ExprNoBF_NoNode ',' AssignmentExpr_NoNode 1623 ; 1624 1625 Statement_NoNode: 1626 Block_NoNode 1627 | VariableStatement_NoNode 1628 | ConstStatement_NoNode 1629 | EmptyStatement_NoNode 1630 | ExprStatement_NoNode 1631 | IfStatement_NoNode 1632 | IterationStatement_NoNode 1633 | ContinueStatement_NoNode 1634 | BreakStatement_NoNode 1635 | ReturnStatement_NoNode 1636 | WithStatement_NoNode 1637 | SwitchStatement_NoNode 1638 | LabelledStatement_NoNode 1639 | ThrowStatement_NoNode 1640 | TryStatement_NoNode 1641 | DebuggerStatement_NoNode 1642 ; 1643 1644 Block_NoNode: 1645 OPENBRACE CLOSEBRACE 1646 | OPENBRACE SourceElements_NoNode CLOSEBRACE 1647 ; 1648 1649 VariableStatement_NoNode: 1650 VAR VariableDeclarationList_NoNode ';' 1651 | VAR VariableDeclarationList_NoNode error { AUTO_SEMICOLON; } 1652 ; 1653 1654 VariableDeclarationList_NoNode: 1655 IDENT 1656 | IDENT Initializer_NoNode 1657 | VariableDeclarationList_NoNode ',' IDENT 1658 | VariableDeclarationList_NoNode ',' IDENT Initializer_NoNode 1659 ; 1660 1661 VariableDeclarationListNoIn_NoNode: 1662 IDENT 1663 | IDENT InitializerNoIn_NoNode 1664 | VariableDeclarationListNoIn_NoNode ',' IDENT 1665 | VariableDeclarationListNoIn_NoNode ',' IDENT InitializerNoIn_NoNode 1666 ; 1667 1668 ConstStatement_NoNode: 1669 CONSTTOKEN ConstDeclarationList_NoNode ';' 1670 | CONSTTOKEN ConstDeclarationList_NoNode error { AUTO_SEMICOLON; } 1671 ; 1672 1673 ConstDeclarationList_NoNode: 1674 ConstDeclaration_NoNode 1675 | ConstDeclarationList_NoNode ',' ConstDeclaration_NoNode 1676 ; 1677 1678 ConstDeclaration_NoNode: 1679 IDENT 1680 | IDENT Initializer_NoNode 1681 ; 1682 1683 Initializer_NoNode: 1684 '=' AssignmentExpr_NoNode 1685 ; 1686 1687 InitializerNoIn_NoNode: 1688 '=' AssignmentExprNoIn_NoNode 1689 ; 1690 1691 EmptyStatement_NoNode: 1692 ';' 1693 ; 1694 1695 ExprStatement_NoNode: 1696 ExprNoBF_NoNode ';' 1697 | ExprNoBF_NoNode error { AUTO_SEMICOLON; } 1698 ; 1699 1700 IfStatement_NoNode: 1701 IF '(' Expr_NoNode ')' Statement_NoNode %prec IF_WITHOUT_ELSE 1702 | IF '(' Expr_NoNode ')' Statement_NoNode ELSE Statement_NoNode 1703 ; 1704 1705 IterationStatement_NoNode: 1706 DO Statement_NoNode WHILE '(' Expr_NoNode ')' ';' 1707 | DO Statement_NoNode WHILE '(' Expr_NoNode ')' error // Always performs automatic semicolon insertion 1708 | WHILE '(' Expr_NoNode ')' Statement_NoNode 1709 | FOR '(' ExprNoInOpt_NoNode ';' ExprOpt_NoNode ';' ExprOpt_NoNode ')' Statement_NoNode 1710 | FOR '(' VAR VariableDeclarationListNoIn_NoNode ';' ExprOpt_NoNode ';' ExprOpt_NoNode ')' Statement_NoNode 1711 | FOR '(' LeftHandSideExpr_NoNode INTOKEN Expr_NoNode ')' Statement_NoNode 1712 | FOR '(' VAR IDENT INTOKEN Expr_NoNode ')' Statement_NoNode 1713 | FOR '(' VAR IDENT InitializerNoIn_NoNode INTOKEN Expr_NoNode ')' Statement_NoNode 1714 ; 1715 1716 ExprOpt_NoNode: 1717 /* nothing */ 1718 | Expr_NoNode 1719 ; 1720 1721 ExprNoInOpt_NoNode: 1722 /* nothing */ 1723 | ExprNoIn_NoNode 1724 ; 1725 1726 ContinueStatement_NoNode: 1727 CONTINUE ';' 1728 | CONTINUE error { AUTO_SEMICOLON; } 1729 | CONTINUE IDENT ';' 1730 | CONTINUE IDENT error { AUTO_SEMICOLON; } 1731 ; 1732 1733 BreakStatement_NoNode: 1734 BREAK ';' 1735 | BREAK error { AUTO_SEMICOLON; } 1736 | BREAK IDENT ';' 1737 | BREAK IDENT error { AUTO_SEMICOLON; } 1738 ; 1739 1740 ReturnStatement_NoNode: 1741 RETURN ';' 1742 | RETURN error { AUTO_SEMICOLON; } 1743 | RETURN Expr_NoNode ';' 1744 | RETURN Expr_NoNode error { AUTO_SEMICOLON; } 1745 ; 1746 1747 WithStatement_NoNode: 1748 WITH '(' Expr_NoNode ')' Statement_NoNode 1749 ; 1750 1751 SwitchStatement_NoNode: 1752 SWITCH '(' Expr_NoNode ')' CaseBlock_NoNode 1753 ; 1754 1755 CaseBlock_NoNode: 1756 OPENBRACE CaseClausesOpt_NoNode CLOSEBRACE 1757 | OPENBRACE CaseClausesOpt_NoNode DefaultClause_NoNode CaseClausesOpt_NoNode CLOSEBRACE 1758 ; 1759 1760 CaseClausesOpt_NoNode: 1761 /* nothing */ 1762 | CaseClauses_NoNode 1763 ; 1764 1765 CaseClauses_NoNode: 1766 CaseClause_NoNode 1767 | CaseClauses_NoNode CaseClause_NoNode 1768 ; 1769 1770 CaseClause_NoNode: 1771 CASE Expr_NoNode ':' 1772 | CASE Expr_NoNode ':' SourceElements_NoNode 1773 ; 1774 1775 DefaultClause_NoNode: 1776 DEFAULT ':' 1777 | DEFAULT ':' SourceElements_NoNode 1778 ; 1779 1780 LabelledStatement_NoNode: 1781 IDENT ':' Statement_NoNode; 1782 1783 ThrowStatement_NoNode: 1784 THROW Expr_NoNode ';' 1785 | THROW Expr_NoNode error { AUTO_SEMICOLON; } 1786 ; 1787 1788 TryStatement_NoNode: 1789 TRY Block_NoNode FINALLY Block_NoNode 1790 | TRY Block_NoNode CATCH '(' IDENT ')' Block_NoNode 1791 | TRY Block_NoNode CATCH '(' IDENT ')' Block_NoNode FINALLY Block_NoNode 1792 ; 1793 1794 DebuggerStatement_NoNode: 1795 DEBUGGER ';' 1796 | DEBUGGER error { AUTO_SEMICOLON; } 1797 ; 1798 1799 FunctionDeclaration_NoNode: 1800 FUNCTION IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE 1801 | FUNCTION IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE 1802 ; 1803 1804 FunctionExpr_NoNode: 1805 FUNCTION '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE 1806 | FUNCTION '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE 1807 | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE 1808 | FUNCTION IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE 1809 ; 1810 1811 FormalParameterList_NoNode: 1812 IDENT 1813 | FormalParameterList_NoNode ',' IDENT 1814 ; 1815 1816 FunctionBody_NoNode: 1817 /* not in spec */ 1818 | SourceElements_NoNode 1819 ; 1820 1821 SourceElements_NoNode: 1822 SourceElement_NoNode 1823 | SourceElements_NoNode SourceElement_NoNode 1824 ; 1825 1826 SourceElement_NoNode: 1827 FunctionDeclaration_NoNode 1828 | Statement_NoNode 1829 ; 1830 1831 // End NoNodes 1832 1250 1833 %% 1251 1834 -
trunk/JavaScriptCore/parser/Lexer.cpp
r38632 r38635 97 97 m_lastToken = -1; 98 98 99 m_position = 0;99 m_position = source.startOffset(); 100 100 m_source = &source; 101 m_code = source. data();102 m_length = source. length();101 m_code = source.provider()->data(); 102 m_length = source.endOffset(); 103 103 m_skipLF = false; 104 104 m_skipCR = false; -
trunk/JavaScriptCore/parser/Lexer.h
r38632 r38635 89 89 90 90 void clear(); 91 SourceCode sourceCode(int openBrace, int closeBrace, int firstLine) { return SourceCode(m_source->provider(), m_source->startOffset() + openBrace + 1, m_source->startOffset() +closeBrace, firstLine); }91 SourceCode sourceCode(int openBrace, int closeBrace, int firstLine) { return SourceCode(m_source->provider(), openBrace + 1, closeBrace, firstLine); } 92 92 93 93 private: -
trunk/JavaScriptCore/parser/Nodes.cpp
r38528 r38635 2378 2378 } 2379 2379 2380 // ------------------------------ ScopeNode ----------------------------- 2381 2382 ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants) 2383 : BlockNode(globalData, children) 2384 , m_source(source) 2385 , m_features(features) 2386 , m_numConstants(numConstants) 2380 // -----------------------------ScopeNodeData --------------------------- 2381 2382 ScopeNodeData::ScopeNodeData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants) 2383 : m_numConstants(numConstants) 2387 2384 { 2388 2385 if (varStack) … … 2390 2387 if (funcStack) 2391 2388 m_functionStack = *funcStack; 2389 if (children) 2390 children->releaseContentsIntoVector(m_children); 2391 } 2392 2393 // ------------------------------ ScopeNode ----------------------------- 2394 2395 ScopeNode::ScopeNode(JSGlobalData* globalData) 2396 : StatementNode(globalData) 2397 , m_features(NoFeatures) 2398 { 2392 2399 #if ENABLE(OPCODE_SAMPLING) 2393 2400 globalData->interpreter->sampler()->notifyOfScope(this); … … 2395 2402 } 2396 2403 2404 ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants) 2405 : StatementNode(globalData) 2406 , m_data(new ScopeNodeData(children, varStack, funcStack, numConstants)) 2407 , m_features(features) 2408 , m_source(source) 2409 { 2410 #if ENABLE(OPCODE_SAMPLING) 2411 globalData->interpreter->sampler()->notifyOfScope(this); 2412 #endif 2413 } 2414 2415 ScopeNode::~ScopeNode() 2416 { 2417 NodeReleaser::releaseAllNodes(this); 2418 } 2419 2420 void ScopeNode::releaseNodes(NodeReleaser& releaser) 2421 { 2422 if (!m_data) 2423 return; 2424 size_t size = m_data->m_children.size(); 2425 for (size_t i = 0; i < size; ++i) 2426 releaser.release(m_data->m_children[i]); 2427 } 2428 2397 2429 // ------------------------------ ProgramNode ----------------------------- 2398 2430 … … 2436 2468 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable, m_code.get()); 2437 2469 generator.generate(); 2470 2471 // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time, 2472 // so the entire ScopeNodeData cannot be destoyed. 2473 children().clear(); 2438 2474 } 2439 2475 … … 2444 2480 2445 2481 // ------------------------------ FunctionBodyNode ----------------------------- 2482 2483 FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData) 2484 : ScopeNode(globalData) 2485 , m_parameters(0) 2486 , m_parameterCount(0) 2487 , m_refCount(0) 2488 { 2489 } 2446 2490 2447 2491 FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants) … … 2483 2527 } 2484 2528 2485 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData , SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)2486 { 2487 return new FunctionBodyNode(globalData , children, varStack, funcStack, SourceCode(), features, numConstants);2529 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData) 2530 { 2531 return new FunctionBodyNode(globalData); 2488 2532 } 2489 2533 … … 2495 2539 void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode) 2496 2540 { 2541 // This branch is only necessary since you can still create a non-stub FunctionBodyNode by 2542 // calling Parser::parse<FunctionBodyNode>(). 2543 if (!data()) 2544 scopeChainNode->globalData->parser->reparse(scopeChainNode->globalData, this); 2545 ASSERT(data()); 2546 2497 2547 ScopeChain scopeChain(scopeChainNode); 2498 2548 JSGlobalObject* globalObject = scopeChain.globalObject(); … … 2502 2552 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable, m_code.get()); 2503 2553 generator.generate(); 2554 2555 destroyData(); 2504 2556 } 2505 2557 … … 2538 2590 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get()); 2539 2591 generator.generate(); 2592 2593 destroyData(); 2540 2594 } 2541 2595 -
trunk/JavaScriptCore/parser/Nodes.h
r38473 r38635 171 171 virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return false; } 172 172 virtual bool isDotAccessorNode() const JSC_FAST_CALL { return false; } 173 virtual bool isFuncExprNode() const JSC_FAST_CALL { return false; } 173 174 174 175 virtual ExpressionNode* stripUnaryPlus() { return this; } … … 192 193 virtual bool isEmptyStatement() const JSC_FAST_CALL { return false; } 193 194 virtual bool isReturnNode() const JSC_FAST_CALL { return false; } 195 virtual bool isExprStatement() const JSC_FAST_CALL { return false; } 194 196 195 197 virtual bool isBlock() const JSC_FAST_CALL { return false; } … … 1743 1745 } 1744 1746 1745 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL; 1747 virtual bool isExprStatement() const JSC_FAST_CALL { return true; } 1748 1749 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL; 1750 1751 ExpressionNode* expr() const { return m_expr.get(); } 1746 1752 1747 1753 private: … … 2057 2063 }; 2058 2064 2059 class ScopeNode : public BlockNode { 2060 public: 2065 struct ScopeNodeData { 2061 2066 typedef DeclarationStacks::VarStack VarStack; 2062 2067 typedef DeclarationStacks::FunctionStack FunctionStack; 2063 2068 2069 ScopeNodeData(SourceElements*, VarStack*, FunctionStack*, int numConstants); 2070 2071 VarStack m_varStack; 2072 FunctionStack m_functionStack; 2073 int m_numConstants; 2074 StatementVector m_children; 2075 }; 2076 2077 class ScopeNode : public StatementNode { 2078 public: 2079 typedef DeclarationStacks::VarStack VarStack; 2080 typedef DeclarationStacks::FunctionStack FunctionStack; 2081 2082 ScopeNode(JSGlobalData*) JSC_FAST_CALL; 2064 2083 ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL; 2084 virtual ~ScopeNode(); 2085 virtual void releaseNodes(NodeReleaser&); 2086 2087 void adoptData(std::auto_ptr<ScopeNodeData> data) { m_data.adopt(data); } 2088 ScopeNodeData* data() const { return m_data.get(); } 2089 void destroyData() { m_data.clear(); } 2065 2090 2066 2091 const SourceCode& source() const { return m_source; } … … 2068 2093 intptr_t sourceID() const { return m_source.provider()->asID(); } 2069 2094 2095 void setFeatures(CodeFeatures features) { m_features = features; } 2070 2096 bool usesEval() const { return m_features & EvalFeature; } 2071 2097 bool usesArguments() const { return m_features & ArgumentsFeature; } … … 2074 2100 bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); } 2075 2101 2076 VarStack& varStack() { return m_varStack; } 2077 FunctionStack& functionStack() { return m_functionStack; } 2102 VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; } 2103 FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; } 2104 2105 StatementVector& children() { ASSERT(m_data); return m_data->m_children; } 2078 2106 2079 2107 int neededConstants() 2080 2108 { 2109 ASSERT(m_data); 2081 2110 // We may need 2 more constants than the count given by the parser, 2082 2111 // because of the various uses of jsUndefined() and jsNull(). 2083 return m_ numConstants + 2;2112 return m_data->m_numConstants + 2; 2084 2113 } 2085 2114 … … 2087 2116 void setSource(const SourceCode& source) { m_source = source; } 2088 2117 2089 VarStack m_varStack; 2090 FunctionStack m_functionStack; 2091 2092 private: 2118 private: 2119 OwnPtr<ScopeNodeData> m_data; 2120 CodeFeatures m_features; 2093 2121 SourceCode m_source; 2094 CodeFeatures m_features;2095 int m_numConstants;2096 2122 }; 2097 2123 … … 2142 2168 friend class JIT; 2143 2169 public: 2170 static FunctionBodyNode* create(JSGlobalData*) JSC_FAST_CALL; 2144 2171 static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL; 2145 static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL; 2146 ~FunctionBodyNode(); 2172 virtual ~FunctionBodyNode(); 2147 2173 2148 2174 const Identifier* parameters() const JSC_FAST_CALL { return m_parameters; } … … 2194 2220 2195 2221 private: 2222 FunctionBodyNode(JSGlobalData*) JSC_FAST_CALL; 2196 2223 FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL; 2197 2224 … … 2217 2244 virtual ~FuncExprNode(); 2218 2245 virtual void releaseNodes(NodeReleaser&); 2246 2247 virtual bool isFuncExprNode() const JSC_FAST_CALL { return true; } 2219 2248 2220 2249 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL; -
trunk/JavaScriptCore/parser/Parser.cpp
r38205 r38635 64 64 } 65 65 66 void Parser::reparse(JSGlobalData* globalData, FunctionBodyNode* functionBodyNode) 67 { 68 ASSERT(!functionBodyNode->data()); 69 70 m_source = &functionBodyNode->source(); 71 parse(globalData, 0, 0); 72 ASSERT(m_sourceElements); 73 functionBodyNode->adoptData(auto_ptr<ScopeNodeData>(new ScopeNodeData(m_sourceElements.get(), 74 m_varDeclarations ? &m_varDeclarations->data : 0, 75 m_funcDeclarations ? &m_funcDeclarations->data : 0, 76 m_numConstants))); 77 bool usesArguments = functionBodyNode->usesArguments(); 78 functionBodyNode->setFeatures(m_features); 79 if (usesArguments && !functionBodyNode->usesArguments()) 80 functionBodyNode->setUsesArguments(); 81 82 m_source = 0; 83 m_sourceElements = 0; 84 m_varDeclarations = 0; 85 m_funcDeclarations = 0; 86 } 87 66 88 void Parser::didFinishParsing(SourceElements* sourceElements, ParserRefCountedData<DeclarationStacks::VarStack>* varStack, 67 89 ParserRefCountedData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants) -
trunk/JavaScriptCore/parser/Parser.h
r38205 r38635 52 52 template <class ParsedNode> PassRefPtr<ParsedNode> parse(ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0); 53 53 54 void reparse(JSGlobalData*, FunctionBodyNode*); 55 54 56 void didFinishParsing(SourceElements*, ParserRefCountedData<DeclarationStacks::VarStack>*, 55 57 ParserRefCountedData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants); -
trunk/JavaScriptCore/parser/SourceCode.h
r38205 r38635 71 71 int firstLine() const { return m_firstLine; } 72 72 int startOffset() const { return m_startChar; } 73 int endOffset() const { return m_endChar; } 73 74 const UChar* data() const { return m_provider->data() + m_startChar; } 74 75 int length() const { return m_endChar - m_startChar; } -
trunk/JavaScriptCore/runtime/FunctionConstructor.cpp
r38440 r38635 67 67 } 68 68 69 static FunctionBodyNode* functionBody(ProgramNode* program) 70 { 71 if (!program) 72 return 0; 73 74 StatementVector& children = program->children(); 75 if (children.size() != 1) 76 return 0; 77 78 ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(children[0].get()); 79 ASSERT(exprStatement->isExprStatement()); 80 if (!exprStatement || !exprStatement->isExprStatement()) 81 return 0; 82 83 FuncExprNode* funcExpr = static_cast<FuncExprNode*>(exprStatement->expr()); 84 ASSERT(funcExpr->isFuncExprNode()); 85 if (!funcExpr || !funcExpr->isFuncExprNode()) 86 return 0; 87 88 FunctionBodyNode* body = funcExpr->body(); 89 ASSERT(body); 90 return body; 91 } 92 69 93 // ECMA 15.3.2 The Function Constructor 70 94 JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber) 71 95 { 72 UString p(""); 73 UString body; 74 int argsSize = args.size(); 75 if (argsSize == 0) 76 body = ""; 77 else if (argsSize == 1) 78 body = args.at(exec, 0)->toString(exec); 96 UString program; 97 if (args.isEmpty()) 98 program = "(function(){})"; 99 else if (args.size() == 1) 100 program = "(function(){" + args.at(exec, 0)->toString(exec) + "})"; 79 101 else { 80 p =args.at(exec, 0)->toString(exec);81 for ( int k = 1; k < argsSize - 1; k++)82 p += "," + args.at(exec, k)->toString(exec);83 body = args.at(exec, argsSize - 1)->toString(exec);102 program = "(function(" + args.at(exec, 0)->toString(exec); 103 for (size_t i = 1; i < args.size() - 1; i++) 104 program += "," + args.at(exec, i)->toString(exec); 105 program += "){" + args.at(exec, args.size() - 1)->toString(exec) + "})"; 84 106 } 85 107 86 // parse the source code87 108 int errLine; 88 109 UString errMsg; 89 SourceCode source = makeSource( body, sourceURL, lineNumber);90 RefPtr< FunctionBodyNode> functionBody = exec->globalData().parser->parse<FunctionBodyNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);110 SourceCode source = makeSource(program, sourceURL, lineNumber); 111 RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); 91 112 92 // No program node == syntax error - throw a syntax error 93 if (!functionBody) 94 // We can't return a Completion(Throw) here, so just set the exception 95 // and return it 113 FunctionBodyNode* body = functionBody(programNode.get()); 114 if (!body) 96 115 return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()); 97 98 // parse parameter list. throw syntax error on illegal identifiers99 int len = p.size();100 const UChar* c = p.data();101 int i = 0;102 UString param;103 Vector<Identifier> parameters;104 while (i < len) {105 while (*c == ' ' && i < len)106 c++, i++;107 if (Lexer::isIdentStart(c[0])) { // else error108 param = UString(c, 1);109 c++, i++;110 while (i < len && (Lexer::isIdentPart(c[0]))) {111 param.append(*c);112 c++, i++;113 }114 while (i < len && *c == ' ')115 c++, i++;116 if (i == len) {117 parameters.append(Identifier(exec, param));118 break;119 } else if (*c == ',') {120 parameters.append(Identifier(exec, param));121 c++, i++;122 continue;123 } // else error124 }125 return throwError(exec, SyntaxError, "Syntax error in parameter list");126 }127 size_t count = parameters.size();128 functionBody->finishParsing(parameters.releaseBuffer(), count);129 116 130 117 JSGlobalObject* globalObject = exec->lexicalGlobalObject(); 131 118 ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue()); 132 JSFunction* function = new (exec) JSFunction(exec, functionName, functionBody.get(), scopeChain.node()); 133 134 JSObject* prototype = constructEmptyObject(exec); 135 prototype->putDirect(exec->propertyNames().constructor, function, DontEnum); 136 function->putDirect(exec->propertyNames().prototype, prototype, DontDelete); 137 return function; 119 return new (exec) JSFunction(exec, functionName, body, scopeChain.node()); 138 120 } 139 121 -
trunk/JavaScriptCore/runtime/Identifier.h
r38440 r38635 69 69 70 70 friend bool operator==(const Identifier&, const char*); 71 friend bool operator!=(const Identifier&, const char*); 71 72 72 73 static void remove(UString::Rep*); … … 133 134 } 134 135 136 inline bool operator!=(const Identifier& a, const char* b) 137 { 138 return !Identifier::equal(a, b); 139 } 140 135 141 IdentifierTable* createIdentifierTable(); 136 142 void deleteIdentifierTable(IdentifierTable*);
Note: See TracChangeset
for help on using the changeset viewer.