Changeset 38635 in webkit


Ignore:
Timestamp:
Nov 20, 2008 3:23:59 PM (15 years ago)
Author:
weinig@apple.com
Message:

2008-11-20 Sam Weinig <sam@webkit.org>

Reviewed by Darin Adler.

Patch for https://bugs.webkit.org/show_bug.cgi?id=22385
<rdar://problem/6390179>
Lazily reparse FunctionBodyNodes on first execution.

  • Saves 57MB on Membuster head.
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::generate): Remove vector shrinking since this is now handled by destroying the ScopeNodeData after generation.
  • parser/Grammar.y: Add alternate NoNode version of the grammar that does not create nodes. This is used to lazily create FunctionBodyNodes on first execution.
  • parser/Lexer.cpp: (JSC::Lexer::setCode): Fix bug where on reparse, the Lexer was confused about what position and length meant. Position is the current position in the original data buffer (important for getting correct line/column information) and length the end offset in the original buffer.
  • parser/Lexer.h: (JSC::Lexer::sourceCode): Positions are relative to the beginning of the buffer.
  • parser/Nodes.cpp: (JSC::ScopeNodeData::ScopeNodeData): Move initialization of ScopeNode data here. (JSC::ScopeNode::ScopeNode): Add constructor that only sets the JSGlobalData for FunctionBodyNode stubs. (JSC::ScopeNode::~ScopeNode): Release m_children now that we don't inherit from BlockNode. (JSC::ScopeNode::releaseNodes): Ditto. (JSC::EvalNode::generateBytecode): Only shrink m_children, as we need to keep around the rest of the data. (JSC::FunctionBodyNode::FunctionBodyNode): Add constructor that only sets the JSGlobalData. (JSC::FunctionBodyNode::create): Ditto. (JSC::FunctionBodyNode::generateBytecode): If we don't have the data, do a reparse to construct it. Then after generation, destroy the data. (JSC::ProgramNode::generateBytecode): After generation, destroy the AST data.
  • parser/Nodes.h: (JSC::ExpressionNode::): Add isFuncExprNode for FunctionConstructor. (JSC::StatementNode::): Add isExprStatementNode for FunctionConstructor. (JSC::ExprStatementNode::): Ditto. (JSC::ExprStatementNode::expr): Add accessor for FunctionConstructor. (JSC::FuncExprNode::): Add isFuncExprNode for FunctionConstructor

(JSC::ScopeNode::adoptData): Adopts a ScopeNodeData.
(JSC::ScopeNode::data): Accessor for ScopeNodeData.
(JSC::ScopeNode::destroyData): Deletes the ScopeNodeData.
(JSC::ScopeNode::setFeatures): Added.
(JSC::ScopeNode::varStack): Added assert.
(JSC::ScopeNode::functionStack): Ditto.
(JSC::ScopeNode::children): Ditto.
(JSC::ScopeNode::neededConstants): Ditto.
Factor m_varStack, m_functionStack, m_children and m_numConstants into ScopeNodeData.

  • parser/Parser.cpp: (JSC::Parser::reparse): Reparse the SourceCode in the FunctionBodyNode and set set up the ScopeNodeData for it.
  • parser/Parser.h:
  • parser/SourceCode.h: (JSC::SourceCode::endOffset): Added for use in the lexer.
  • runtime/FunctionConstructor.cpp: (JSC::getFunctionBody): Assuming a ProgramNode with one FunctionExpression in it, get the FunctionBodyNode. Any issues signifies a parse failure in constructFunction. (JSC::constructFunction): Make parsing functions in the form new Function(""), easier by concatenating the strings together (with some glue) and parsing the function expression as a ProgramNode from which we can receive the FunctionBodyNode. This has the added benefit of not having special parsing code for the arguments and lazily constructing the FunctionBodyNode's AST on first execution.
  • runtime/Identifier.h: (JSC::operator!=): Added.
Location:
trunk/JavaScriptCore
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r38632 r38635  
     12008-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
    1792008-11-20  Sam Weinig  <sam@webkit.org>
    280
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r38511 r38635  
    140140    }
    141141#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     }
    148142   
    149143    m_codeBlock->instructions.shrinkToFit();
  • trunk/JavaScriptCore/parser/Grammar.y

    r38249 r38635  
    284284%%
    285285
     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
    286290Literal:
    287291    NULLTOKEN                           { $$ = createNodeInfo<ExpressionNode*>(new NullNode(GLOBAL_DATA), 0, 1); }
     
    12041208
    12051209FunctionBody:
    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); }
    12211212;
    12221213
     
    12481239;
    12491240 
     1241// Start NoNodes
     1242
     1243Literal_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
     1253Property_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
     1261PropertyList_NoNode:
     1262    Property_NoNode
     1263  | PropertyList_NoNode ',' Property_NoNode
     1264;
     1265
     1266PrimaryExpr_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
     1274PrimaryExprNoBrace_NoNode:
     1275    THISTOKEN
     1276  | Literal_NoNode
     1277  | ArrayLiteral_NoNode
     1278  | IDENT
     1279  | '(' Expr_NoNode ')'
     1280;
     1281
     1282ArrayLiteral_NoNode:
     1283    '[' ElisionOpt_NoNode ']'
     1284  | '[' ElementList_NoNode ']'
     1285  | '[' ElementList_NoNode ',' ElisionOpt_NoNode ']'
     1286;
     1287
     1288ElementList_NoNode:
     1289    ElisionOpt_NoNode AssignmentExpr_NoNode
     1290  | ElementList_NoNode ',' ElisionOpt_NoNode AssignmentExpr_NoNode
     1291;
     1292
     1293ElisionOpt_NoNode:
     1294    /* nothing */
     1295  | Elision_NoNode
     1296;
     1297
     1298Elision_NoNode:
     1299    ','
     1300  | Elision_NoNode ','
     1301;
     1302
     1303MemberExpr_NoNode:
     1304    PrimaryExpr_NoNode
     1305  | FunctionExpr_NoNode
     1306  | MemberExpr_NoNode '[' Expr_NoNode ']'
     1307  | MemberExpr_NoNode '.' IDENT
     1308  | NEW MemberExpr_NoNode Arguments_NoNode
     1309;
     1310
     1311MemberExprNoBF_NoNode:
     1312    PrimaryExprNoBrace_NoNode
     1313  | MemberExprNoBF_NoNode '[' Expr_NoNode ']'
     1314  | MemberExprNoBF_NoNode '.' IDENT
     1315  | NEW MemberExpr_NoNode Arguments_NoNode
     1316;
     1317
     1318NewExpr_NoNode:
     1319    MemberExpr_NoNode
     1320  | NEW NewExpr_NoNode
     1321;
     1322
     1323NewExprNoBF_NoNode:
     1324    MemberExprNoBF_NoNode
     1325  | NEW NewExpr_NoNode
     1326;
     1327
     1328CallExpr_NoNode:
     1329    MemberExpr_NoNode Arguments_NoNode
     1330  | CallExpr_NoNode Arguments_NoNode
     1331  | CallExpr_NoNode '[' Expr_NoNode ']'
     1332  | CallExpr_NoNode '.' IDENT
     1333;
     1334
     1335CallExprNoBF_NoNode:
     1336    MemberExprNoBF_NoNode Arguments_NoNode
     1337  | CallExprNoBF_NoNode Arguments_NoNode
     1338  | CallExprNoBF_NoNode '[' Expr_NoNode ']'
     1339  | CallExprNoBF_NoNode '.' IDENT
     1340;
     1341
     1342Arguments_NoNode:
     1343    '(' ')'
     1344  | '(' ArgumentList_NoNode ')'
     1345;
     1346
     1347ArgumentList_NoNode:
     1348    AssignmentExpr_NoNode
     1349  | ArgumentList_NoNode ',' AssignmentExpr_NoNode
     1350;
     1351
     1352LeftHandSideExpr_NoNode:
     1353    NewExpr_NoNode
     1354  | CallExpr_NoNode
     1355;
     1356
     1357LeftHandSideExprNoBF_NoNode:
     1358    NewExprNoBF_NoNode
     1359  | CallExprNoBF_NoNode
     1360;
     1361
     1362PostfixExpr_NoNode:
     1363    LeftHandSideExpr_NoNode
     1364  | LeftHandSideExpr_NoNode PLUSPLUS
     1365  | LeftHandSideExpr_NoNode MINUSMINUS
     1366;
     1367
     1368PostfixExprNoBF_NoNode:
     1369    LeftHandSideExprNoBF_NoNode
     1370  | LeftHandSideExprNoBF_NoNode PLUSPLUS
     1371  | LeftHandSideExprNoBF_NoNode MINUSMINUS
     1372;
     1373
     1374UnaryExprCommon_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
     1387UnaryExpr_NoNode:
     1388    PostfixExpr_NoNode
     1389  | UnaryExprCommon_NoNode
     1390;
     1391
     1392UnaryExprNoBF_NoNode:
     1393    PostfixExprNoBF_NoNode
     1394  | UnaryExprCommon_NoNode
     1395;
     1396
     1397MultiplicativeExpr_NoNode:
     1398    UnaryExpr_NoNode
     1399  | MultiplicativeExpr_NoNode '*' UnaryExpr_NoNode
     1400  | MultiplicativeExpr_NoNode '/' UnaryExpr_NoNode
     1401  | MultiplicativeExpr_NoNode '%' UnaryExpr_NoNode
     1402;
     1403
     1404MultiplicativeExprNoBF_NoNode:
     1405    UnaryExprNoBF_NoNode
     1406  | MultiplicativeExprNoBF_NoNode '*' UnaryExpr_NoNode
     1407  | MultiplicativeExprNoBF_NoNode '/' UnaryExpr_NoNode
     1408  | MultiplicativeExprNoBF_NoNode '%' UnaryExpr_NoNode
     1409;
     1410
     1411AdditiveExpr_NoNode:
     1412    MultiplicativeExpr_NoNode
     1413  | AdditiveExpr_NoNode '+' MultiplicativeExpr_NoNode
     1414  | AdditiveExpr_NoNode '-' MultiplicativeExpr_NoNode
     1415;
     1416
     1417AdditiveExprNoBF_NoNode:
     1418    MultiplicativeExprNoBF_NoNode
     1419  | AdditiveExprNoBF_NoNode '+' MultiplicativeExpr_NoNode
     1420  | AdditiveExprNoBF_NoNode '-' MultiplicativeExpr_NoNode
     1421;
     1422
     1423ShiftExpr_NoNode:
     1424    AdditiveExpr_NoNode
     1425  | ShiftExpr_NoNode LSHIFT AdditiveExpr_NoNode
     1426  | ShiftExpr_NoNode RSHIFT AdditiveExpr_NoNode
     1427  | ShiftExpr_NoNode URSHIFT AdditiveExpr_NoNode
     1428;
     1429
     1430ShiftExprNoBF_NoNode:
     1431    AdditiveExprNoBF_NoNode
     1432  | ShiftExprNoBF_NoNode LSHIFT AdditiveExpr_NoNode
     1433  | ShiftExprNoBF_NoNode RSHIFT AdditiveExpr_NoNode
     1434  | ShiftExprNoBF_NoNode URSHIFT AdditiveExpr_NoNode
     1435;
     1436
     1437RelationalExpr_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
     1447RelationalExprNoIn_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
     1456RelationalExprNoBF_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
     1466EqualityExpr_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
     1474EqualityExprNoIn_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
     1482EqualityExprNoBF_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
     1490BitwiseANDExpr_NoNode:
     1491    EqualityExpr_NoNode
     1492  | BitwiseANDExpr_NoNode '&' EqualityExpr_NoNode
     1493;
     1494
     1495BitwiseANDExprNoIn_NoNode:
     1496    EqualityExprNoIn_NoNode
     1497  | BitwiseANDExprNoIn_NoNode '&' EqualityExprNoIn_NoNode
     1498;
     1499
     1500BitwiseANDExprNoBF_NoNode:
     1501    EqualityExprNoBF_NoNode
     1502  | BitwiseANDExprNoBF_NoNode '&' EqualityExpr_NoNode
     1503;
     1504
     1505BitwiseXORExpr_NoNode:
     1506    BitwiseANDExpr_NoNode
     1507  | BitwiseXORExpr_NoNode '^' BitwiseANDExpr_NoNode
     1508;
     1509
     1510BitwiseXORExprNoIn_NoNode:
     1511    BitwiseANDExprNoIn_NoNode
     1512  | BitwiseXORExprNoIn_NoNode '^' BitwiseANDExprNoIn_NoNode
     1513;
     1514
     1515BitwiseXORExprNoBF_NoNode:
     1516    BitwiseANDExprNoBF_NoNode
     1517  | BitwiseXORExprNoBF_NoNode '^' BitwiseANDExpr_NoNode
     1518;
     1519
     1520BitwiseORExpr_NoNode:
     1521    BitwiseXORExpr_NoNode
     1522  | BitwiseORExpr_NoNode '|' BitwiseXORExpr_NoNode
     1523;
     1524
     1525BitwiseORExprNoIn_NoNode:
     1526    BitwiseXORExprNoIn_NoNode
     1527  | BitwiseORExprNoIn_NoNode '|' BitwiseXORExprNoIn_NoNode
     1528;
     1529
     1530BitwiseORExprNoBF_NoNode:
     1531    BitwiseXORExprNoBF_NoNode
     1532  | BitwiseORExprNoBF_NoNode '|' BitwiseXORExpr_NoNode
     1533;
     1534
     1535LogicalANDExpr_NoNode:
     1536    BitwiseORExpr_NoNode
     1537  | LogicalANDExpr_NoNode AND BitwiseORExpr_NoNode
     1538;
     1539
     1540LogicalANDExprNoIn_NoNode:
     1541    BitwiseORExprNoIn_NoNode
     1542  | LogicalANDExprNoIn_NoNode AND BitwiseORExprNoIn_NoNode
     1543;
     1544
     1545LogicalANDExprNoBF_NoNode:
     1546    BitwiseORExprNoBF_NoNode
     1547  | LogicalANDExprNoBF_NoNode AND BitwiseORExpr_NoNode
     1548;
     1549
     1550LogicalORExpr_NoNode:
     1551    LogicalANDExpr_NoNode
     1552  | LogicalORExpr_NoNode OR LogicalANDExpr_NoNode
     1553;
     1554
     1555LogicalORExprNoIn_NoNode:
     1556    LogicalANDExprNoIn_NoNode
     1557  | LogicalORExprNoIn_NoNode OR LogicalANDExprNoIn_NoNode
     1558;
     1559
     1560LogicalORExprNoBF_NoNode:
     1561    LogicalANDExprNoBF_NoNode
     1562  | LogicalORExprNoBF_NoNode OR LogicalANDExpr_NoNode
     1563;
     1564
     1565ConditionalExpr_NoNode:
     1566    LogicalORExpr_NoNode
     1567  | LogicalORExpr_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode
     1568;
     1569
     1570ConditionalExprNoIn_NoNode:
     1571    LogicalORExprNoIn_NoNode
     1572  | LogicalORExprNoIn_NoNode '?' AssignmentExprNoIn_NoNode ':' AssignmentExprNoIn_NoNode
     1573;
     1574
     1575ConditionalExprNoBF_NoNode:
     1576    LogicalORExprNoBF_NoNode
     1577  | LogicalORExprNoBF_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode
     1578;
     1579
     1580AssignmentExpr_NoNode:
     1581    ConditionalExpr_NoNode
     1582  | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode
     1583;
     1584
     1585AssignmentExprNoIn_NoNode:
     1586    ConditionalExprNoIn_NoNode
     1587  | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExprNoIn_NoNode
     1588;
     1589
     1590AssignmentExprNoBF_NoNode:
     1591    ConditionalExprNoBF_NoNode
     1592  | LeftHandSideExprNoBF_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode
     1593;
     1594
     1595AssignmentOperator_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
     1610Expr_NoNode:
     1611    AssignmentExpr_NoNode
     1612  | Expr_NoNode ',' AssignmentExpr_NoNode
     1613;
     1614
     1615ExprNoIn_NoNode:
     1616    AssignmentExprNoIn_NoNode
     1617  | ExprNoIn_NoNode ',' AssignmentExprNoIn_NoNode
     1618;
     1619
     1620ExprNoBF_NoNode:
     1621    AssignmentExprNoBF_NoNode
     1622  | ExprNoBF_NoNode ',' AssignmentExpr_NoNode
     1623;
     1624
     1625Statement_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
     1644Block_NoNode:
     1645    OPENBRACE CLOSEBRACE
     1646  | OPENBRACE SourceElements_NoNode CLOSEBRACE
     1647;
     1648
     1649VariableStatement_NoNode:
     1650    VAR VariableDeclarationList_NoNode ';'
     1651  | VAR VariableDeclarationList_NoNode error { AUTO_SEMICOLON; }
     1652;
     1653
     1654VariableDeclarationList_NoNode:
     1655    IDENT
     1656  | IDENT Initializer_NoNode
     1657  | VariableDeclarationList_NoNode ',' IDENT
     1658  | VariableDeclarationList_NoNode ',' IDENT Initializer_NoNode
     1659;
     1660
     1661VariableDeclarationListNoIn_NoNode:
     1662    IDENT
     1663  | IDENT InitializerNoIn_NoNode
     1664  | VariableDeclarationListNoIn_NoNode ',' IDENT
     1665  | VariableDeclarationListNoIn_NoNode ',' IDENT InitializerNoIn_NoNode
     1666;
     1667
     1668ConstStatement_NoNode:
     1669    CONSTTOKEN ConstDeclarationList_NoNode ';'
     1670  | CONSTTOKEN ConstDeclarationList_NoNode error { AUTO_SEMICOLON; }
     1671;
     1672
     1673ConstDeclarationList_NoNode:
     1674    ConstDeclaration_NoNode
     1675  | ConstDeclarationList_NoNode ',' ConstDeclaration_NoNode
     1676;
     1677
     1678ConstDeclaration_NoNode:
     1679    IDENT
     1680  | IDENT Initializer_NoNode
     1681;
     1682
     1683Initializer_NoNode:
     1684    '=' AssignmentExpr_NoNode
     1685;
     1686
     1687InitializerNoIn_NoNode:
     1688    '=' AssignmentExprNoIn_NoNode
     1689;
     1690
     1691EmptyStatement_NoNode:
     1692    ';'
     1693;
     1694
     1695ExprStatement_NoNode:
     1696    ExprNoBF_NoNode ';'
     1697  | ExprNoBF_NoNode error { AUTO_SEMICOLON; }
     1698;
     1699
     1700IfStatement_NoNode:
     1701    IF '(' Expr_NoNode ')' Statement_NoNode %prec IF_WITHOUT_ELSE
     1702  | IF '(' Expr_NoNode ')' Statement_NoNode ELSE Statement_NoNode
     1703;
     1704
     1705IterationStatement_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
     1716ExprOpt_NoNode:
     1717    /* nothing */
     1718  | Expr_NoNode
     1719;
     1720
     1721ExprNoInOpt_NoNode:
     1722    /* nothing */
     1723  | ExprNoIn_NoNode
     1724;
     1725
     1726ContinueStatement_NoNode:
     1727    CONTINUE ';'
     1728  | CONTINUE error { AUTO_SEMICOLON; }
     1729  | CONTINUE IDENT ';'
     1730  | CONTINUE IDENT error { AUTO_SEMICOLON; }
     1731;
     1732
     1733BreakStatement_NoNode:
     1734    BREAK ';'
     1735  | BREAK error { AUTO_SEMICOLON; }
     1736  | BREAK IDENT ';'
     1737  | BREAK IDENT error { AUTO_SEMICOLON; }
     1738;
     1739
     1740ReturnStatement_NoNode:
     1741    RETURN ';'
     1742  | RETURN error { AUTO_SEMICOLON; }
     1743  | RETURN Expr_NoNode ';'
     1744  | RETURN Expr_NoNode error { AUTO_SEMICOLON; }
     1745;
     1746
     1747WithStatement_NoNode:
     1748    WITH '(' Expr_NoNode ')' Statement_NoNode
     1749;
     1750
     1751SwitchStatement_NoNode:
     1752    SWITCH '(' Expr_NoNode ')' CaseBlock_NoNode
     1753;
     1754
     1755CaseBlock_NoNode:
     1756    OPENBRACE CaseClausesOpt_NoNode CLOSEBRACE
     1757  | OPENBRACE CaseClausesOpt_NoNode DefaultClause_NoNode CaseClausesOpt_NoNode CLOSEBRACE
     1758;
     1759
     1760CaseClausesOpt_NoNode:
     1761    /* nothing */
     1762  | CaseClauses_NoNode
     1763;
     1764
     1765CaseClauses_NoNode:
     1766    CaseClause_NoNode
     1767  | CaseClauses_NoNode CaseClause_NoNode
     1768;
     1769
     1770CaseClause_NoNode:
     1771    CASE Expr_NoNode ':'
     1772  | CASE Expr_NoNode ':' SourceElements_NoNode
     1773;
     1774
     1775DefaultClause_NoNode:
     1776    DEFAULT ':'
     1777  | DEFAULT ':' SourceElements_NoNode
     1778;
     1779
     1780LabelledStatement_NoNode:
     1781    IDENT ':' Statement_NoNode;
     1782
     1783ThrowStatement_NoNode:
     1784    THROW Expr_NoNode ';'
     1785  | THROW Expr_NoNode error { AUTO_SEMICOLON; }
     1786;
     1787
     1788TryStatement_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
     1794DebuggerStatement_NoNode:
     1795    DEBUGGER ';'
     1796  | DEBUGGER error { AUTO_SEMICOLON; }
     1797;
     1798
     1799FunctionDeclaration_NoNode:
     1800    FUNCTION IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
     1801  | FUNCTION IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
     1802;
     1803
     1804FunctionExpr_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
     1811FormalParameterList_NoNode:
     1812    IDENT
     1813  | FormalParameterList_NoNode ',' IDENT
     1814;
     1815
     1816FunctionBody_NoNode:
     1817    /* not in spec */
     1818  | SourceElements_NoNode
     1819;
     1820
     1821SourceElements_NoNode:
     1822    SourceElement_NoNode
     1823  | SourceElements_NoNode SourceElement_NoNode
     1824;
     1825
     1826SourceElement_NoNode:
     1827    FunctionDeclaration_NoNode
     1828  | Statement_NoNode
     1829;
     1830
     1831// End NoNodes
     1832
    12501833%%
    12511834
  • trunk/JavaScriptCore/parser/Lexer.cpp

    r38632 r38635  
    9797    m_lastToken = -1;
    9898
    99     m_position = 0;
     99    m_position = source.startOffset();
    100100    m_source = &source;
    101     m_code = source.data();
    102     m_length = source.length();
     101    m_code = source.provider()->data();
     102    m_length = source.endOffset();
    103103    m_skipLF = false;
    104104    m_skipCR = false;
  • trunk/JavaScriptCore/parser/Lexer.h

    r38632 r38635  
    8989
    9090        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); }
    9292
    9393    private:
  • trunk/JavaScriptCore/parser/Nodes.cpp

    r38528 r38635  
    23782378}
    23792379
    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
     2382ScopeNodeData::ScopeNodeData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
     2383    : m_numConstants(numConstants)
    23872384{
    23882385    if (varStack)
     
    23902387    if (funcStack)
    23912388        m_functionStack = *funcStack;
     2389    if (children)
     2390        children->releaseContentsIntoVector(m_children);
     2391}
     2392
     2393// ------------------------------ ScopeNode -----------------------------
     2394
     2395ScopeNode::ScopeNode(JSGlobalData* globalData)
     2396    : StatementNode(globalData)
     2397    , m_features(NoFeatures)
     2398{
    23922399#if ENABLE(OPCODE_SAMPLING)
    23932400    globalData->interpreter->sampler()->notifyOfScope(this);
     
    23952402}
    23962403
     2404ScopeNode::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
     2415ScopeNode::~ScopeNode()
     2416{
     2417    NodeReleaser::releaseAllNodes(this);
     2418}
     2419
     2420void 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
    23972429// ------------------------------ ProgramNode -----------------------------
    23982430
     
    24362468    BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable, m_code.get());
    24372469    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();
    24382474}
    24392475
     
    24442480
    24452481// ------------------------------ FunctionBodyNode -----------------------------
     2482
     2483FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
     2484    : ScopeNode(globalData)
     2485    , m_parameters(0)
     2486    , m_parameterCount(0)
     2487    , m_refCount(0)
     2488{
     2489}
    24462490
    24472491FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
     
    24832527}
    24842528
    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);
     2529FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
     2530{
     2531    return new FunctionBodyNode(globalData);
    24882532}
    24892533
     
    24952539void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
    24962540{
     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
    24972547    ScopeChain scopeChain(scopeChainNode);
    24982548    JSGlobalObject* globalObject = scopeChain.globalObject();
     
    25022552    BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable, m_code.get());
    25032553    generator.generate();
     2554
     2555    destroyData();
    25042556}
    25052557
     
    25382590    BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get());
    25392591    generator.generate();
     2592
     2593    destroyData();
    25402594}
    25412595
  • trunk/JavaScriptCore/parser/Nodes.h

    r38473 r38635  
    171171        virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return false; }
    172172        virtual bool isDotAccessorNode() const JSC_FAST_CALL { return false; }
     173        virtual bool isFuncExprNode() const JSC_FAST_CALL { return false; }
    173174
    174175        virtual ExpressionNode* stripUnaryPlus() { return this; }
     
    192193        virtual bool isEmptyStatement() const JSC_FAST_CALL { return false; }
    193194        virtual bool isReturnNode() const JSC_FAST_CALL { return false; }
     195        virtual bool isExprStatement() const JSC_FAST_CALL { return false; }
    194196
    195197        virtual bool isBlock() const JSC_FAST_CALL { return false; }
     
    17431745        }
    17441746
    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(); }
    17461752
    17471753    private:
     
    20572063    };
    20582064
    2059     class ScopeNode : public BlockNode {
    2060     public:
     2065    struct ScopeNodeData {
    20612066        typedef DeclarationStacks::VarStack VarStack;
    20622067        typedef DeclarationStacks::FunctionStack FunctionStack;
    20632068
     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;
    20642083        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(); }
    20652090
    20662091        const SourceCode& source() const { return m_source; }
     
    20682093        intptr_t sourceID() const { return m_source.provider()->asID(); }
    20692094
     2095        void setFeatures(CodeFeatures features) { m_features = features; }
    20702096        bool usesEval() const { return m_features & EvalFeature; }
    20712097        bool usesArguments() const { return m_features & ArgumentsFeature; }
     
    20742100        bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
    20752101
    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; }
    20782106
    20792107        int neededConstants()
    20802108        {
     2109            ASSERT(m_data);
    20812110            // We may need 2 more constants than the count given by the parser,
    20822111            // because of the various uses of jsUndefined() and jsNull().
    2083             return m_numConstants + 2;
     2112            return m_data->m_numConstants + 2;
    20842113        }
    20852114
     
    20872116        void setSource(const SourceCode& source) { m_source = source; }
    20882117
    2089         VarStack m_varStack;
    2090         FunctionStack m_functionStack;
    2091 
    2092     private:
     2118    private:
     2119        OwnPtr<ScopeNodeData> m_data;
     2120        CodeFeatures m_features;
    20932121        SourceCode m_source;
    2094         CodeFeatures m_features;
    2095         int m_numConstants;
    20962122    };
    20972123
     
    21422168        friend class JIT;
    21432169    public:
     2170        static FunctionBodyNode* create(JSGlobalData*) JSC_FAST_CALL;
    21442171        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();
    21472173
    21482174        const Identifier* parameters() const JSC_FAST_CALL { return m_parameters; }
     
    21942220
    21952221    private:
     2222        FunctionBodyNode(JSGlobalData*) JSC_FAST_CALL;
    21962223        FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
    21972224
     
    22172244        virtual ~FuncExprNode();
    22182245        virtual void releaseNodes(NodeReleaser&);
     2246
     2247        virtual bool isFuncExprNode() const JSC_FAST_CALL { return true; }
    22192248
    22202249        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
  • trunk/JavaScriptCore/parser/Parser.cpp

    r38205 r38635  
    6464}
    6565
     66void 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
    6688void Parser::didFinishParsing(SourceElements* sourceElements, ParserRefCountedData<DeclarationStacks::VarStack>* varStack,
    6789                              ParserRefCountedData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants)
  • trunk/JavaScriptCore/parser/Parser.h

    r38205 r38635  
    5252        template <class ParsedNode> PassRefPtr<ParsedNode> parse(ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
    5353
     54        void reparse(JSGlobalData*, FunctionBodyNode*);
     55
    5456        void didFinishParsing(SourceElements*, ParserRefCountedData<DeclarationStacks::VarStack>*,
    5557                              ParserRefCountedData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants);
  • trunk/JavaScriptCore/parser/SourceCode.h

    r38205 r38635  
    7171        int firstLine() const { return m_firstLine; }
    7272        int startOffset() const { return m_startChar; }
     73        int endOffset() const { return m_endChar; }
    7374        const UChar* data() const { return m_provider->data() + m_startChar; }
    7475        int length() const { return m_endChar - m_startChar; }
  • trunk/JavaScriptCore/runtime/FunctionConstructor.cpp

    r38440 r38635  
    6767}
    6868
     69static 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
    6993// ECMA 15.3.2 The Function Constructor
    7094JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
    7195{
    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) + "})";
    79101    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) + "})";
    84106    }
    85107
    86     // parse the source code
    87108    int errLine;
    88109    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);
    91112
    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)
    96115        return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
    97 
    98     // parse parameter list. throw syntax error on illegal identifiers
    99     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 error
    108             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 error
    124         }
    125         return throwError(exec, SyntaxError, "Syntax error in parameter list");
    126     }
    127     size_t count = parameters.size();
    128     functionBody->finishParsing(parameters.releaseBuffer(), count);
    129116
    130117    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    131118    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());
    138120}
    139121
  • trunk/JavaScriptCore/runtime/Identifier.h

    r38440 r38635  
    6969
    7070        friend bool operator==(const Identifier&, const char*);
     71        friend bool operator!=(const Identifier&, const char*);
    7172   
    7273        static void remove(UString::Rep*);
     
    133134    }
    134135
     136    inline bool operator!=(const Identifier& a, const char* b)
     137    {
     138        return !Identifier::equal(a, b);
     139    }
     140
    135141    IdentifierTable* createIdentifierTable();
    136142    void deleteIdentifierTable(IdentifierTable*);
Note: See TracChangeset for help on using the changeset viewer.