Changeset 38047 in webkit for trunk/JavaScriptCore/kjs/nodes.cpp


Ignore:
Timestamp:
Oct 31, 2008, 12:59:08 PM (17 years ago)
Author:
[email protected]
Message:

2008-10-30 Geoffrey Garen <[email protected]>

Reviewed by Oliver Hunt.


Fixed a small bit of https://bugs.webkit.org/show_bug.cgi?id=21962
AST uses way too much memory


Removed a word from StatementNode by nixing LabelStack and turning it
into a compile-time data structure managed by CodeGenerator.


v8 tests and SunSpider, run by Gavin, report no change.


  • VM/CodeGenerator.cpp: (JSC::CodeGenerator::CodeGenerator): (JSC::CodeGenerator::newLabelScope): (JSC::CodeGenerator::breakTarget): (JSC::CodeGenerator::continueTarget):
  • VM/CodeGenerator.h: Nixed the JumpContext system because it depended on a LabelStack in the AST, and it was a little cumbersome on the client side. Replaced with LabelScope, which tracks all break / continue information in the CodeGenerator, just like we track LabelIDs and other stacks of compile-time data.
  • kjs/LabelScope.h: Added. (JSC::LabelScope::): (JSC::LabelScope::LabelScope): (JSC::LabelScope::ref): (JSC::LabelScope::deref): (JSC::LabelScope::refCount): (JSC::LabelScope::breakTarget): (JSC::LabelScope::continueTarget): (JSC::LabelScope::type): (JSC::LabelScope::name): (JSC::LabelScope::scopeDepth): Simple abstraction for holding everything you might want to know about a break-able / continue-able scope.
  • kjs/LabelStack.cpp: Removed.
  • kjs/LabelStack.h: Removed.
  • kjs/grammar.y: No need to push labels at parse time -- we don't store LabelStacks in the AST anymore.
  • kjs/nodes.cpp: (JSC::DoWhileNode::emitCode): (JSC::WhileNode::emitCode): (JSC::ForNode::emitCode): (JSC::ForInNode::emitCode): (JSC::ContinueNode::emitCode): (JSC::BreakNode::emitCode): (JSC::SwitchNode::emitCode): (JSC::LabelNode::emitCode):
  • kjs/nodes.h: (JSC::StatementNode::): (JSC::LabelNode::): Use LabelScope where we used to use JumpContext. Simplified a bunch of code. Touched up label-related error messages a bit.
  • kjs/nodes2string.cpp: (JSC::LabelNode::streamTo): Updated for rename.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r38040 r38047  
    3131#include "JSGlobalObject.h"
    3232#include "JSStaticScopeObject.h"
     33#include "LabelScope.h"
    3334#include "Parser.h"
    3435#include "PropertyNameArray.h"
     
    11751176RegisterID* DoWhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    11761177{
     1178    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
     1179
    11771180    RefPtr<LabelID> topOfLoop = generator.newLabel();
    11781181    generator.emitLabel(topOfLoop.get());
     
    11821185    if (!m_statement->isBlock())
    11831186        generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
    1184 
    1185     RefPtr<LabelID> continueTarget = generator.newLabel();
    1186     RefPtr<LabelID> breakTarget = generator.newLabel();
    1187 
    1188     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
     1187       
    11891188    RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
    1190     generator.popJumpContext();
    1191 
    1192     generator.emitLabel(continueTarget.get());
     1189
     1190    generator.emitLabel(scope->continueTarget());
    11931191    generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
    11941192    RegisterID* cond = generator.emitNode(m_expr.get());
    11951193    generator.emitJumpIfTrue(cond, topOfLoop.get());
    11961194
    1197     generator.emitLabel(breakTarget.get());
     1195    generator.emitLabel(scope->breakTarget());
    11981196    return result.get();
    11991197}
     
    12031201RegisterID* WhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    12041202{
     1203    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
     1204
     1205    generator.emitJump(scope->continueTarget());
     1206
    12051207    RefPtr<LabelID> topOfLoop = generator.newLabel();
    1206     RefPtr<LabelID> continueTarget = generator.newLabel();
    1207     RefPtr<LabelID> breakTarget = generator.newLabel();
    1208 
    1209     generator.emitJump(continueTarget.get());
    12101208    generator.emitLabel(topOfLoop.get());
    12111209
     
    12131211        generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
    12141212 
    1215     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
    12161213    generator.emitNode(dst, m_statement.get());
    1217     generator.popJumpContext();
    1218 
    1219     generator.emitLabel(continueTarget.get());
     1214
     1215    generator.emitLabel(scope->continueTarget());
    12201216    generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
    12211217    RegisterID* cond = generator.emitNode(m_expr.get());
    12221218    generator.emitJumpIfTrue(cond, topOfLoop.get());
    12231219
    1224     generator.emitLabel(breakTarget.get());
     1220    generator.emitLabel(scope->breakTarget());
    12251221   
    12261222    // FIXME: This should return the last statement executed so that it can be returned as a Completion
     
    12351231        dst = 0;
    12361232
     1233    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
     1234
    12371235    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
    12381236
     
    12401238        generator.emitNode(ignoredResult(), m_expr1.get());
    12411239
     1240    RefPtr<LabelID> condition = generator.newLabel();
     1241    generator.emitJump(condition.get());
     1242
    12421243    RefPtr<LabelID> topOfLoop = generator.newLabel();
    1243     RefPtr<LabelID> beforeCondition = generator.newLabel();
    1244     RefPtr<LabelID> continueTarget = generator.newLabel();
    1245     RefPtr<LabelID> breakTarget = generator.newLabel();
    1246     generator.emitJump(beforeCondition.get());
    1247 
    12481244    generator.emitLabel(topOfLoop.get());
    1249     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
     1245
    12501246    if (!m_statement->isBlock())
    12511247        generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
    12521248    RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
    1253     generator.popJumpContext();
    1254     generator.emitLabel(continueTarget.get());
     1249
     1250    generator.emitLabel(scope->continueTarget());
    12551251    if (m_expr3)
    12561252        generator.emitNode(ignoredResult(), m_expr3.get());
    12571253
    1258     generator.emitLabel(beforeCondition.get());
     1254    generator.emitLabel(condition.get());
    12591255    if (m_expr2) {
    12601256        RegisterID* cond = generator.emitNode(m_expr2.get());
    12611257        generator.emitJumpIfTrue(cond, topOfLoop.get());
    1262     } else {
     1258    } else
    12631259        generator.emitJump(topOfLoop.get());
    1264     }
    1265 
    1266     generator.emitLabel(breakTarget.get());
    1267    
     1260
     1261    generator.emitLabel(scope->breakTarget());
    12681262    return result.get();
    12691263}
     
    12991293RegisterID* ForInNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    13001294{
     1295    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
     1296
    13011297    if (!m_lexpr->isLocation())
    13021298        return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference.");
    1303     RefPtr<LabelID> loopStart = generator.newLabel();
     1299
    13041300    RefPtr<LabelID> continueTarget = generator.newLabel();
    1305     RefPtr<LabelID> breakTarget = generator.newLabel();
    13061301
    13071302    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
     
    13111306    RegisterID* forInBase = generator.emitNode(m_expr.get());
    13121307    RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
    1313     generator.emitJump(continueTarget.get());
     1308    generator.emitJump(scope->continueTarget());
     1309
     1310    RefPtr<LabelID> loopStart = generator.newLabel();
    13141311    generator.emitLabel(loopStart.get());
     1312
    13151313    RegisterID* propertyName;
    13161314    if (m_lexpr->isResolveNode()) {
     
    13461344    }   
    13471345
    1348     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
    13491346    if (!m_statement->isBlock())
    13501347        generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
    13511348    generator.emitNode(dst, m_statement.get());
    1352     generator.popJumpContext();
    1353 
    1354     generator.emitLabel(continueTarget.get());
     1349
     1350    generator.emitLabel(scope->continueTarget());
    13551351    generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
    1356     generator.emitLabel(breakTarget.get());
     1352    generator.emitLabel(scope->breakTarget());
    13571353    return dst;
    13581354}
     
    13631359RegisterID* ContinueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    13641360{
    1365     if (!generator.inContinueContext())
    1366         return emitThrowError(generator, SyntaxError, "Invalid continue statement.");
    1367 
    1368     JumpContext* targetContext = generator.jumpContextForContinue(m_ident);
    1369 
    1370     if (!targetContext) {
    1371         if (m_ident.isEmpty())
    1372             return emitThrowError(generator, SyntaxError, "Invalid continue statement.");
    1373         else
    1374             return emitThrowError(generator, SyntaxError, "Label %s not found.", m_ident);
    1375     }
    1376 
    1377     if (!targetContext->continueTarget)
    1378         return emitThrowError(generator, SyntaxError, "Invalid continue statement.");       
    1379 
    1380     generator.emitJumpScopes(targetContext->continueTarget, targetContext->scopeDepth);
    1381    
     1361    LabelScope* scope = generator.continueTarget(m_ident);
     1362
     1363    if (!scope)
     1364        return m_ident.isEmpty()
     1365            ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
     1366            : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
     1367
     1368    generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
    13821369    return dst;
    13831370}
     
    13881375RegisterID* BreakNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    13891376{
    1390     if (!generator.inJumpContext())
    1391         return emitThrowError(generator, SyntaxError, "Invalid break statement.");
     1377    LabelScope* scope = generator.breakTarget(m_ident);
    13921378   
    1393     JumpContext* targetContext = generator.jumpContextForBreak(m_ident);
    1394    
    1395     if (!targetContext) {
    1396         if (m_ident.isEmpty())
    1397             return emitThrowError(generator, SyntaxError, "Invalid break statement.");
    1398         else
    1399             return emitThrowError(generator, SyntaxError, "Label %s not found.", m_ident);
    1400     }
    1401 
    1402     ASSERT(targetContext->breakTarget);
    1403 
    1404     generator.emitJumpScopes(targetContext->breakTarget, targetContext->scopeDepth);
    1405 
     1379    if (!scope)
     1380        return m_ident.isEmpty()
     1381            ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
     1382            : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
     1383
     1384    generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
    14061385    return dst;
    14071386}
     
    15841563RegisterID* SwitchNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    15851564{
    1586     RefPtr<LabelID> breakTarget = generator.newLabel();
     1565    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
    15871566
    15881567    RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
    1589     generator.pushJumpContext(&m_labelStack, 0, breakTarget.get(), true);
    15901568    RegisterID* r1 = m_block->emitCodeForBlock(generator, r0.get(), dst);
    1591     generator.popJumpContext();
    1592 
    1593     generator.emitLabel(breakTarget.get());
    1594 
     1569
     1570    generator.emitLabel(scope->breakTarget());
    15951571    return r1;
    15961572}
     
    16001576RegisterID* LabelNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    16011577{
    1602     if (generator.jumpContextForBreak(m_label))
    1603         return emitThrowError(generator, SyntaxError, "Duplicated label %s found.", m_label);
    1604 
    1605     RefPtr<LabelID> l0 = generator.newLabel();
    1606     m_labelStack.push(m_label);
    1607     generator.pushJumpContext(&m_labelStack, 0, l0.get(), false);
    1608    
     1578    if (generator.breakTarget(m_name))
     1579        return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
     1580
     1581    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
    16091582    RegisterID* r0 = generator.emitNode(dst, m_statement.get());
    1610    
    1611     generator.popJumpContext();
    1612     m_labelStack.pop();
    1613    
    1614     generator.emitLabel(l0.get());
     1583
     1584    generator.emitLabel(scope->breakTarget());
    16151585    return r0;
    16161586}
Note: See TracChangeset for help on using the changeset viewer.