- a/Source/JavaScriptCore/ChangeLog +14 lines
Lines 1-3 a/Source/JavaScriptCore/ChangeLog_sec1
1
2015-07-18  Commit Queue  <commit-queue@webkit.org>
2
3
        Unreviewed, rolling out r186996.
4
        https://bugs.webkit.org/show_bug.cgi?id=147070
5
6
        Broke JSC tests (Requested by smfr on #webkit).
7
8
        Reverted changeset:
9
10
        "lexical scoping is broken with respect to "break" and
11
        "continue""
12
        https://bugs.webkit.org/show_bug.cgi?id=147063
13
        http://trac.webkit.org/changeset/186996
14
1
2015-07-18  Saam barati  <saambarati1@gmail.com>
15
2015-07-18  Saam barati  <saambarati1@gmail.com>
2
16
3
        lexical scoping is broken with respect to "break" and "continue"
17
        lexical scoping is broken with respect to "break" and "continue"
- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp -51 / +42 lines
Lines 522-529 BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec1
522
        instructions().append(0);
522
        instructions().append(0);
523
    }
523
    }
524
524
525
    if (m_lexicalEnvironmentRegister)
526
        pushScopedControlFlowContext();
527
    m_symbolTableStack.append(SymbolTableStackEntry{ Strong<SymbolTable>(*m_vm, m_symbolTable), m_lexicalEnvironmentRegister, false, symbolTableConstantIndex });
525
    m_symbolTableStack.append(SymbolTableStackEntry{ Strong<SymbolTable>(*m_vm, m_symbolTable), m_lexicalEnvironmentRegister, false, symbolTableConstantIndex });
528
    m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false));
526
    m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false));
529
}
527
}
Lines 629-635 LabelScopePtr BytecodeGenerator::newLabelScope(LabelScope::Type type, const Iden a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec2
629
        m_labelScopes.removeLast();
627
        m_labelScopes.removeLast();
630
628
631
    // Allocate new label scope.
629
    // Allocate new label scope.
632
    LabelScope scope(type, name, labelScopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
630
    LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
633
    m_labelScopes.append(scope);
631
    m_labelScopes.append(scope);
634
    return LabelScopePtr(m_labelScopes, m_labelScopes.size() - 1);
632
    return LabelScopePtr(m_labelScopes, m_labelScopes.size() - 1);
635
}
633
}
Lines 1212-1218 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTy a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec3
1212
    // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
1210
    // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
1213
    emitOpcode(op_profile_type);
1211
    emitOpcode(op_profile_type);
1214
    instructions().append(registerToProfile->index());
1212
    instructions().append(registerToProfile->index());
1215
    instructions().append(localScopeDepth());
1213
    instructions().append(currentScopeDepth());
1216
    instructions().append(flag);
1214
    instructions().append(flag);
1217
    instructions().append(identifier ? addConstant(*identifier) : 0);
1215
    instructions().append(identifier ? addConstant(*identifier) : 0);
1218
    instructions().append(resolveType());
1216
    instructions().append(resolveType());
Lines 1320-1327 void BytecodeGenerator::pushLexicalScope(VariableEnvironmentNode* node, bool can a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec4
1320
        instructions().append(addConstantValue(jsTDZValue())->index());
1318
        instructions().append(addConstantValue(jsTDZValue())->index());
1321
1319
1322
        emitMove(scopeRegister(), newScope);
1320
        emitMove(scopeRegister(), newScope);
1323
1324
        pushScopedControlFlowContext();
1325
    }
1321
    }
1326
1322
1327
    m_symbolTableStack.append(SymbolTableStackEntry{ symbolTable, newScope, false, symbolTableConstantIndex });
1323
    m_symbolTableStack.append(SymbolTableStackEntry{ symbolTable, newScope, false, symbolTableConstantIndex });
Lines 1369-1376 void BytecodeGenerator::popLexicalScope(VariableEnvironmentNode* node) a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec5
1369
1365
1370
    if (hasCapturedVariables) {
1366
    if (hasCapturedVariables) {
1371
        RELEASE_ASSERT(stackEntry.m_scope);
1367
        RELEASE_ASSERT(stackEntry.m_scope);
1372
        emitPopScope(scopeRegister(), stackEntry.m_scope);
1368
        RefPtr<RegisterID> parentScope = emitGetParentScope(newTemporary(), scopeRegister());
1373
        popScopedControlFlowContext();
1369
        emitMove(scopeRegister(), parentScope.get());
1374
        stackEntry.m_scope->deref();
1370
        stackEntry.m_scope->deref();
1375
    }
1371
    }
1376
1372
Lines 1427-1433 void BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration(VariableEnvir a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec6
1427
    // as the previous scope because the loop body is compiled under
1423
    // as the previous scope because the loop body is compiled under
1428
    // the assumption that the scope's register index is constant even
1424
    // the assumption that the scope's register index is constant even
1429
    // though the value in that register will change on each loop iteration.
1425
    // though the value in that register will change on each loop iteration.
1430
    RefPtr<RegisterID> parentScope = emitGetParentScope(newTemporary(), loopScope);
1426
    RefPtr<RegisterID> parentScope = emitGetParentScope(newTemporary(), scopeRegister());
1431
    emitMove(scopeRegister(), parentScope.get());
1427
    emitMove(scopeRegister(), parentScope.get());
1432
1428
1433
    emitOpcode(op_create_lexical_environment);
1429
    emitOpcode(op_create_lexical_environment);
Lines 1576-1586 void BytecodeGenerator::emitCheckHasInstance(RegisterID* dst, RegisterID* value, a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec7
1576
// will start with this ResolveType and compute the least upper bound including intercepting scopes.
1572
// will start with this ResolveType and compute the least upper bound including intercepting scopes.
1577
ResolveType BytecodeGenerator::resolveType()
1573
ResolveType BytecodeGenerator::resolveType()
1578
{
1574
{
1579
    for (unsigned i = m_symbolTableStack.size(); i--; ) {
1575
    if (m_localScopeDepth)
1580
        if (m_symbolTableStack[i].m_isWithOrCatch)
1576
        return Dynamic;
1581
            return Dynamic;
1582
    }
1583
1584
    if (m_symbolTable && m_symbolTable->usesNonStrictEval())
1577
    if (m_symbolTable && m_symbolTable->usesNonStrictEval())
1585
        return GlobalPropertyWithVarInjectionChecks;
1578
        return GlobalPropertyWithVarInjectionChecks;
1586
    return GlobalProperty;
1579
    return GlobalProperty;
Lines 1639-1645 RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Variable& a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec8
1639
        instructions().append(scopeRegister()->index());
1632
        instructions().append(scopeRegister()->index());
1640
        instructions().append(addConstant(variable.ident()));
1633
        instructions().append(addConstant(variable.ident()));
1641
        instructions().append(resolveType());
1634
        instructions().append(resolveType());
1642
        instructions().append(localScopeDepth());
1635
        instructions().append(currentScopeDepth());
1643
        instructions().append(0);
1636
        instructions().append(0);
1644
        return dst;
1637
        return dst;
1645
    }
1638
    }
Lines 1673-1679 RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* sco a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec9
1673
        instructions().append(scope->index());
1666
        instructions().append(scope->index());
1674
        instructions().append(addConstant(variable.ident()));
1667
        instructions().append(addConstant(variable.ident()));
1675
        instructions().append(ResolveModeAndType(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType()).operand());
1668
        instructions().append(ResolveModeAndType(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType()).operand());
1676
        instructions().append(localScopeDepth());
1669
        instructions().append(currentScopeDepth());
1677
        instructions().append(variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
1670
        instructions().append(variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
1678
        instructions().append(profile);
1671
        instructions().append(profile);
1679
        return dst;
1672
        return dst;
Lines 1713-1719 RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Variable& a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec10
1713
        } else {
1706
        } else {
1714
            ASSERT(resolveType() != LocalClosureVar);
1707
            ASSERT(resolveType() != LocalClosureVar);
1715
            instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
1708
            instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
1716
            instructions().append(localScopeDepth());
1709
            instructions().append(currentScopeDepth());
1717
        }
1710
        }
1718
        instructions().append(!!offset ? offset.offset() : 0);
1711
        instructions().append(!!offset ? offset.offset() : 0);
1719
        return value;
1712
        return value;
Lines 2481-2487 void BytecodeGenerator::emitGetScope() a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec11
2481
2474
2482
RegisterID* BytecodeGenerator::emitPushWithScope(RegisterID* dst, RegisterID* scope)
2475
RegisterID* BytecodeGenerator::emitPushWithScope(RegisterID* dst, RegisterID* scope)
2483
{
2476
{
2484
    pushScopedControlFlowContext();
2477
    ControlFlowContext context;
2478
    context.isFinallyBlock = false;
2479
    m_scopeContextStack.append(context);
2480
    m_localScopeDepth++;
2485
2481
2486
    RegisterID* result = emitUnaryOp(op_push_with_scope, dst, scope);
2482
    RegisterID* result = emitUnaryOp(op_push_with_scope, dst, scope);
2487
    m_symbolTableStack.append(SymbolTableStackEntry{ Strong<SymbolTable>(), nullptr, true, 0 });
2483
    m_symbolTableStack.append(SymbolTableStackEntry{ Strong<SymbolTable>(), nullptr, true, 0 });
Lines 2496-2511 RegisterID* BytecodeGenerator::emitGetParentScope(RegisterID* dst, RegisterID* s a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec12
2496
    return dst;
2492
    return dst;
2497
}
2493
}
2498
2494
2499
void BytecodeGenerator::emitPopScope(RegisterID* dst, RegisterID* scope)
2495
void BytecodeGenerator::emitPopScope(RegisterID* srcDst)
2500
{
2496
{
2501
    RefPtr<RegisterID> parentScope = emitGetParentScope(newTemporary(), scope);
2497
    ASSERT(m_scopeContextStack.size());
2502
    emitMove(dst, parentScope.get());
2498
    ASSERT(!m_scopeContextStack.last().isFinallyBlock);
2503
}
2504
2499
2505
void BytecodeGenerator::emitPopWithOrCatchScope(RegisterID* srcDst)
2500
    RefPtr<RegisterID> parentScope = emitGetParentScope(newTemporary(), srcDst);
2506
{
2501
    emitMove(srcDst, parentScope.get());
2507
    emitPopScope(srcDst, srcDst);
2502
2508
    popScopedControlFlowContext();
2503
    m_scopeContextStack.removeLast();
2504
    m_localScopeDepth--;
2509
    SymbolTableStackEntry stackEntry = m_symbolTableStack.takeLast();
2505
    SymbolTableStackEntry stackEntry = m_symbolTableStack.takeLast();
2510
    RELEASE_ASSERT(stackEntry.m_isWithOrCatch);
2506
    RELEASE_ASSERT(stackEntry.m_isWithOrCatch);
2511
}
2507
}
Lines 2819-2827 void BytecodeGenerator::emitComplexPopScopes(RegisterID* scope, ControlFlowConte a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec13
2819
2815
2820
void BytecodeGenerator::emitPopScopes(RegisterID* scope, int targetScopeDepth)
2816
void BytecodeGenerator::emitPopScopes(RegisterID* scope, int targetScopeDepth)
2821
{
2817
{
2822
    ASSERT(labelScopeDepth() - targetScopeDepth >= 0);
2818
    ASSERT(scopeDepth() - targetScopeDepth >= 0);
2823
2819
2824
    size_t scopeDelta = labelScopeDepth() - targetScopeDepth;
2820
    size_t scopeDelta = scopeDepth() - targetScopeDepth;
2825
    ASSERT(scopeDelta <= m_scopeContextStack.size());
2821
    ASSERT(scopeDelta <= m_scopeContextStack.size());
2826
    if (!scopeDelta)
2822
    if (!scopeDelta)
2827
        return;
2823
        return;
Lines 2880-2889 void BytecodeGenerator::popTryAndEmitCatch(TryData* tryData, RegisterID* excepti a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec14
2880
2876
2881
int BytecodeGenerator::calculateTargetScopeDepthForExceptionHandler() const
2877
int BytecodeGenerator::calculateTargetScopeDepthForExceptionHandler() const
2882
{
2878
{
2883
    int depth = localScopeDepth();
2879
    int depth = m_localScopeDepth;
2880
2881
    for (unsigned i = m_symbolTableStack.size(); i--; ) {
2882
        RegisterID* scope = m_symbolTableStack[i].m_scope;
2883
        if (scope)
2884
            depth++;
2885
    }
2884
2886
2885
    // Currently, we're maintaing compatibility with how things are done and letting the exception handling
2887
    // Currently, we're maintaing compatibility with how things are done and letting the exception handling
2886
    // code take into consideration the base activation of the function. There is no reason we shouldn't
2888
    // code take into consideration the base activation of the function. There is no reason we shouldn't 
2887
    // be able to calculate the exact depth here and let the exception handler not worry if there is a base
2889
    // be able to calculate the exact depth here and let the exception handler not worry if there is a base
2888
    // activation or not.
2890
    // activation or not.
2889
    if (m_lexicalEnvironmentRegister)
2891
    if (m_lexicalEnvironmentRegister)
Lines 2893-2906 int BytecodeGenerator::calculateTargetScopeDepthForExceptionHandler() const a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec15
2893
    return depth;
2895
    return depth;
2894
}
2896
}
2895
2897
2896
int BytecodeGenerator::localScopeDepth() const
2898
int BytecodeGenerator::currentScopeDepth() const
2897
{
2899
{
2898
    return m_localScopeDepth;
2900
    // This is the current number of JSScope descendents that would be allocated
2899
}
2901
    // in this function/program if this code were running.
2900
2902
    int depth = 0;
2901
int BytecodeGenerator::labelScopeDepth() const
2903
    for (unsigned i = m_symbolTableStack.size(); i--; ) {
2902
{ 
2904
        if (m_symbolTableStack[i].m_scope || m_symbolTableStack[i].m_isWithOrCatch)
2903
    return localScopeDepth() + m_finallyDepth;
2905
            depth++;
2906
    }
2907
    return depth;
2904
}
2908
}
2905
2909
2906
void BytecodeGenerator::emitThrowReferenceError(const String& message)
2910
void BytecodeGenerator::emitThrowReferenceError(const String& message)
Lines 2926-2950 void BytecodeGenerator::emitPushFunctionNameScope(RegisterID* dst, const Identif a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec16
2926
    instructions().append(JSNameScope::FunctionNameScope);
2930
    instructions().append(JSNameScope::FunctionNameScope);
2927
}
2931
}
2928
2932
2929
void BytecodeGenerator::pushScopedControlFlowContext()
2933
void BytecodeGenerator::emitPushCatchScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes)
2930
{
2934
{
2931
    ControlFlowContext context;
2935
    ControlFlowContext context;
2932
    context.isFinallyBlock = false;
2936
    context.isFinallyBlock = false;
2933
    m_scopeContextStack.append(context);
2937
    m_scopeContextStack.append(context);
2934
    m_localScopeDepth++;
2938
    m_localScopeDepth++;
2935
}
2936
2937
void BytecodeGenerator::popScopedControlFlowContext()
2938
{
2939
    ASSERT(m_scopeContextStack.size());
2940
    ASSERT(!m_scopeContextStack.last().isFinallyBlock);
2941
    m_scopeContextStack.removeLast();
2942
    m_localScopeDepth--;
2943
}
2944
2945
void BytecodeGenerator::emitPushCatchScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes)
2946
{
2947
    pushScopedControlFlowContext();
2948
2939
2949
    emitOpcode(op_push_name_scope);
2940
    emitOpcode(op_push_name_scope);
2950
    instructions().append(dst->index());
2941
    instructions().append(dst->index());
- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h -6 / +3 lines
Lines 585-596 namespace JSC { a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h_sec1
585
585
586
        void emitGetScope();
586
        void emitGetScope();
587
        RegisterID* emitPushWithScope(RegisterID* dst, RegisterID* scope);
587
        RegisterID* emitPushWithScope(RegisterID* dst, RegisterID* scope);
588
        void emitPopScope(RegisterID* dst, RegisterID* scope);
588
        void emitPopScope(RegisterID* srcDst);
589
        void emitPopWithOrCatchScope(RegisterID* srcDst);
590
        RegisterID* emitGetParentScope(RegisterID* dst, RegisterID* scope);
589
        RegisterID* emitGetParentScope(RegisterID* dst, RegisterID* scope);
591
590
592
        void emitDebugHook(DebugHookID, unsigned line, unsigned charOffset, unsigned lineStart);
591
        void emitDebugHook(DebugHookID, unsigned line, unsigned charOffset, unsigned lineStart);
593
592
593
        int scopeDepth() { return m_localScopeDepth + m_finallyDepth; }
594
        bool hasFinaliser() { return m_finallyDepth != 0; }
594
        bool hasFinaliser() { return m_finallyDepth != 0; }
595
595
596
        void pushFinallyContext(StatementNode* finallyBlock);
596
        void pushFinallyContext(StatementNode* finallyBlock);
Lines 624-630 namespace JSC { a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h_sec2
624
        void pushLexicalScope(VariableEnvironmentNode*, bool canOptimizeTDZChecks, RegisterID** constantSymbolTableResult = nullptr);
624
        void pushLexicalScope(VariableEnvironmentNode*, bool canOptimizeTDZChecks, RegisterID** constantSymbolTableResult = nullptr);
625
        void popLexicalScope(VariableEnvironmentNode*);
625
        void popLexicalScope(VariableEnvironmentNode*);
626
        void prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode*, RegisterID* loopSymbolTable);
626
        void prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode*, RegisterID* loopSymbolTable);
627
        int labelScopeDepth() const;
628
627
629
    private:
628
    private:
630
        void reclaimFreeRegisters();
629
        void reclaimFreeRegisters();
Lines 762-770 namespace JSC { a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h_sec3
762
        const CodeType m_codeType;
761
        const CodeType m_codeType;
763
762
764
        int calculateTargetScopeDepthForExceptionHandler() const;
763
        int calculateTargetScopeDepthForExceptionHandler() const;
765
        int localScopeDepth() const;
764
        int currentScopeDepth() const;
766
        void pushScopedControlFlowContext();
767
        void popScopedControlFlowContext();
768
765
769
        Vector<ControlFlowContext, 0, UnsafeVectorOverflow> m_scopeContextStack;
766
        Vector<ControlFlowContext, 0, UnsafeVectorOverflow> m_scopeContextStack;
770
        Vector<SwitchInfo> m_switchContextStack;
767
        Vector<SwitchInfo> m_switchContextStack;
- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp -5 / +5 lines
Lines 2627-2633 Label* ContinueNode::trivialTarget(BytecodeGenerator& generator) a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp_sec1
2627
    LabelScopePtr scope = generator.continueTarget(m_ident);
2627
    LabelScopePtr scope = generator.continueTarget(m_ident);
2628
    ASSERT(scope);
2628
    ASSERT(scope);
2629
2629
2630
    if (generator.labelScopeDepth() != scope->scopeDepth())
2630
    if (generator.scopeDepth() != scope->scopeDepth())
2631
        return 0;
2631
        return 0;
2632
2632
2633
    return scope->continueTarget();
2633
    return scope->continueTarget();
Lines 2656-2662 Label* BreakNode::trivialTarget(BytecodeGenerator& generator) a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp_sec2
2656
    LabelScopePtr scope = generator.breakTarget(m_ident);
2656
    LabelScopePtr scope = generator.breakTarget(m_ident);
2657
    ASSERT(scope);
2657
    ASSERT(scope);
2658
2658
2659
    if (generator.labelScopeDepth() != scope->scopeDepth())
2659
    if (generator.scopeDepth() != scope->scopeDepth())
2660
        return 0;
2660
        return 0;
2661
2661
2662
    return scope->breakTarget();
2662
    return scope->breakTarget();
Lines 2690-2696 void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp_sec3
2690
        generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, nullptr);
2690
        generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, nullptr);
2691
        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
2691
        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
2692
    }
2692
    }
2693
    if (generator.labelScopeDepth()) {
2693
    if (generator.scopeDepth()) {
2694
        returnRegister = generator.emitMove(generator.newTemporary(), returnRegister.get());
2694
        returnRegister = generator.emitMove(generator.newTemporary(), returnRegister.get());
2695
        generator.emitPopScopes(generator.scopeRegister(), 0);
2695
        generator.emitPopScopes(generator.scopeRegister(), 0);
2696
    }
2696
    }
Lines 2714-2720 void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp_sec4
2714
    generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
2714
    generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
2715
    generator.emitPushWithScope(generator.scopeRegister(), scope.get());
2715
    generator.emitPushWithScope(generator.scopeRegister(), scope.get());
2716
    generator.emitNode(dst, m_statement);
2716
    generator.emitNode(dst, m_statement);
2717
    generator.emitPopWithOrCatchScope(generator.scopeRegister());
2717
    generator.emitPopScope(generator.scopeRegister());
2718
}
2718
}
2719
2719
2720
// ------------------------------ CaseClauseNode --------------------------------
2720
// ------------------------------ CaseClauseNode --------------------------------
Lines 2967-2973 void TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp_sec5
2967
        generator.emitPushCatchScope(generator.scopeRegister(), m_thrownValueIdent, thrownValueRegister.get(), DontDelete);
2967
        generator.emitPushCatchScope(generator.scopeRegister(), m_thrownValueIdent, thrownValueRegister.get(), DontDelete);
2968
        generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
2968
        generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
2969
        generator.emitNode(dst, m_catchBlock);
2969
        generator.emitNode(dst, m_catchBlock);
2970
        generator.emitPopWithOrCatchScope(generator.scopeRegister());
2970
        generator.emitPopScope(generator.scopeRegister());
2971
        generator.emitLabel(catchEndLabel.get());
2971
        generator.emitLabel(catchEndLabel.get());
2972
    }
2972
    }
2973
2973
- a/Source/JavaScriptCore/tests/stress/lexical-scoping-break-continue.js -216 lines
Lines 1-216 a/Source/JavaScriptCore/tests/stress/lexical-scoping-break-continue.js_sec1
1
function assert(b) {
2
    if (!b)
3
        throw new Error("bad assertion");
4
}
5
noInline(assert);
6
7
;(function() {
8
    function test1() {
9
        let x = 20;
10
        function foo() {
11
            label: {
12
                let y = 21;
13
                let capY = function () { return y; }
14
                assert(x === 20);
15
                break label;
16
            }
17
            assert(x === 20);
18
        }
19
        foo();
20
    }
21
22
    function test2() {
23
        let x = 20;
24
        function capX() { return x; }
25
        function foo() {
26
            label1: {
27
                label2: {
28
                    let y = 21;
29
                    let capY = function () { return y; }
30
                    break label2;
31
                }
32
                assert(x === 20);
33
            }
34
            assert(x === 20);
35
36
            label1: {
37
                label2: {
38
                    let y = 21;
39
                    let capY = function () { return y; }
40
                    assert(x === 20);
41
                    assert(y === 21);
42
                    break label1;
43
                }
44
            }
45
            assert(x === 20);
46
47
            label1: {
48
                let y = 21;
49
                let capY = function () { return y; }
50
                label2: {
51
                    let y = 21;
52
                    let capY = function () { return y; }
53
                    assert(x === 20);
54
                    assert(y === 21);
55
                    break label1;
56
                }
57
            }
58
            assert(x === 20);
59
        }
60
        foo()
61
    }
62
63
    function test3() {
64
        let x = 20;
65
        function capX() { return x; }
66
        function foo() {
67
            loop1: for (var i = 0; i++ < 1000; ) {
68
                //assert(x === 20);
69
                loop2: for (var j = 0; j++ < 1000; ) {
70
                    let y = 21;
71
                    let capY = function() { return y; }
72
                    assert(x === 20);
73
                    assert(y === 21);
74
                    continue loop1;
75
                    //break loop1;
76
                }
77
            }
78
            assert(x === 20);
79
        }
80
        foo()
81
    }
82
83
    function test4() {
84
        let x = 20;
85
        function capX() { return x; }
86
        function foo() {
87
            loop1: for (var i = 0; i++ < 1000; ) {
88
                loop2: for (var j = 0; j++ < 1000; ) {
89
                    let y = 21;
90
                    let capY = function() { return y; }
91
                    assert(x === 20);
92
                    assert(y === 21);
93
                    break loop1;
94
                }
95
            }
96
            assert(x === 20);
97
        }
98
        foo()
99
    }
100
101
    function test5() {
102
        let x = 20;
103
        function capX() { return x; }
104
        function foo() {
105
            loop1: for (var i = 0; i++ < 1000; ) {
106
                let y = 21;
107
                let capY = function() { return y; }
108
                loop2: for (var j = 0; j++ < 1000; ) {
109
                    let y = 21;
110
                    let capY = function() { return y; }
111
                    assert(x === 20);
112
                    assert(y === 21);
113
                    break loop1;
114
                }
115
            }
116
            assert(x === 20);
117
        }
118
        foo()
119
    }
120
121
    function test6() {
122
        let x = 20;
123
        function capX() { return x; }
124
        function foo() {
125
            loop1: for (var i = 0; i++ < 1000; ) {
126
                assert(x === 20);
127
                let y = 21;
128
                let capY = function() { return y; }
129
                loop2: for (var j = 0; j++ < 1000; ) {
130
                    let y = 21;
131
                    let capY = function() { return y; }
132
                    assert(x === 20);
133
                    assert(y === 21);
134
                    try {
135
                        throw new Error();            
136
                    } catch(e) {
137
                    } finally {
138
                        assert(x === 20);
139
                        continue loop1;    
140
                    }
141
                }
142
            }
143
            assert(x === 20);
144
        }
145
        foo()
146
    }
147
148
    function test7() {
149
        let x = 20;
150
        function capX() { return x; }
151
        function foo() {
152
            loop1: for (var i = 0; i++ < 1000; ) {
153
                assert(x === 20);
154
                let y = 21;
155
                let capY = function() { return y; }
156
                loop2: for (var j = 0; j++ < 1000; ) {
157
                    let y = 21;
158
                    let capY = function() { return y; }
159
                    assert(x === 20);
160
                    assert(y === 21);
161
                    try {
162
                        throw new Error();            
163
                    } catch(e) {
164
                        continue loop1;
165
                    } finally {
166
                        let x = 40;
167
                        let capX = function() { return x; }
168
                        assert(x === 40);
169
                    }
170
                }
171
            }
172
            assert(x === 20);
173
        }
174
        foo()
175
    }
176
177
    function test8() {
178
        let x = 20;
179
        function capX() { return x; }
180
        function foo() {
181
            loop1: for (var i = 0; i++ < 1000; ) {
182
                assert(x === 20);
183
                let y = 21;
184
                let capY = function() { return y; }
185
                loop2: for (var j = 0; j++ < 1000; ) {
186
                    let y = 21;
187
                    let capY = function() { return y; }
188
                    assert(x === 20);
189
                    assert(y === 21);
190
                    try {
191
                        throw new Error();            
192
                    } catch(e) {
193
                        break loop1;
194
                    } finally {
195
                        let x = 40;
196
                        let capX = function() { return x; }
197
                        assert(x === 40);
198
                    }
199
                }
200
            }
201
            assert(x === 20);
202
        }
203
        foo()
204
    }
205
206
    for (var i = 0; i < 1000; i++) {
207
        test1();
208
        test2();
209
        test3();
210
        test4();
211
        test5();
212
        test6();
213
        test7();
214
        test8();
215
    }
216
})();

Return to Bug 147070