Changeset 187515 in webkit


Ignore:
Timestamp:
Jul 28, 2015, 2:39:34 PM (10 years ago)
Author:
[email protected]
Message:

Implement catch scope using lexical scoping constructs introduced with "let" scoping patch
https://bugs.webkit.org/show_bug.cgi?id=146979

Reviewed by Geoffrey Garen.

Now that BytecodeGenerator has a notion of local scope depth,
we can easily implement a catch scope that doesn't claim that
all variables are dynamically scoped. This means that functions
that use try/catch can have local variable resolution. This also
means that all functions that use try/catch don't have all
their variables marked as being captured.

Catch scopes now behave like a "let" scope (sans the TDZ logic) with a
single variable. Catch scopes are now just JSLexicalEnvironments and the
symbol table backing the catch scope knows that it corresponds to a catch scope.

(JSC::CodeBlock::dumpBytecode):

  • bytecode/EvalCodeCache.h:

(JSC::EvalCodeCache::isCacheable):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack):
(JSC::BytecodeGenerator::emitLoadGlobalObject):
(JSC::BytecodeGenerator::pushLexicalScope):
(JSC::BytecodeGenerator::pushLexicalScopeInternal):
(JSC::BytecodeGenerator::popLexicalScope):
(JSC::BytecodeGenerator::popLexicalScopeInternal):
(JSC::BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration):
(JSC::BytecodeGenerator::variable):
(JSC::BytecodeGenerator::resolveType):
(JSC::BytecodeGenerator::emitResolveScope):
(JSC::BytecodeGenerator::emitPopScope):
(JSC::BytecodeGenerator::emitPopWithScope):
(JSC::BytecodeGenerator::emitDebugHook):
(JSC::BytecodeGenerator::popScopedControlFlowContext):
(JSC::BytecodeGenerator::emitPushCatchScope):
(JSC::BytecodeGenerator::emitPopCatchScope):
(JSC::BytecodeGenerator::beginSwitch):
(JSC::BytecodeGenerator::emitPopWithOrCatchScope): Deleted.

  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::lastOpcodeID):

  • bytecompiler/NodesCodegen.cpp:

(JSC::AssignResolveNode::emitBytecode):
(JSC::WithNode::emitBytecode):
(JSC::TryNode::emitBytecode):

  • debugger/DebuggerScope.cpp:

(JSC::DebuggerScope::isCatchScope):
(JSC::DebuggerScope::isFunctionNameScope):
(JSC::DebuggerScope::isFunctionOrEvalScope):
(JSC::DebuggerScope::caughtValue):

  • debugger/DebuggerScope.h:
  • inspector/ScriptDebugServer.cpp:

(Inspector::ScriptDebugServer::exceptionOrCaughtValue):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::execute):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_push_name_scope):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_push_name_scope):

  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createContinueStatement):
(JSC::ASTBuilder::createTryStatement):

  • parser/NodeConstructors.h:

(JSC::ThrowNode::ThrowNode):
(JSC::TryNode::TryNode):
(JSC::FunctionParameters::FunctionParameters):

  • parser/Nodes.h:
  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseTryStatement):

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createBreakStatement):
(JSC::SyntaxChecker::createContinueStatement):
(JSC::SyntaxChecker::createTryStatement):
(JSC::SyntaxChecker::createSwitchStatement):
(JSC::SyntaxChecker::createWhileStatement):
(JSC::SyntaxChecker::createWithStatement):

  • runtime/JSCatchScope.cpp:
  • runtime/JSCatchScope.h:

(JSC::JSCatchScope::JSCatchScope): Deleted.
(JSC::JSCatchScope::create): Deleted.
(JSC::JSCatchScope::createStructure): Deleted.

  • runtime/JSFunctionNameScope.h:

(JSC::JSFunctionNameScope::JSFunctionNameScope):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::withScopeStructure):
(JSC::JSGlobalObject::strictEvalActivationStructure):
(JSC::JSGlobalObject::activationStructure):
(JSC::JSGlobalObject::functionNameScopeStructure):
(JSC::JSGlobalObject::directArgumentsStructure):
(JSC::JSGlobalObject::scopedArgumentsStructure):
(JSC::JSGlobalObject::catchScopeStructure): Deleted.

  • runtime/JSNameScope.cpp:

(JSC::JSNameScope::create):
(JSC::JSNameScope::toThis):

  • runtime/JSNameScope.h:
  • runtime/JSObject.cpp:

(JSC::JSObject::toThis):
(JSC::JSObject::isFunctionNameScopeObject):
(JSC::JSObject::isCatchScopeObject): Deleted.

  • runtime/JSObject.h:
  • runtime/JSScope.cpp:

(JSC::JSScope::collectVariablesUnderTDZ):
(JSC::JSScope::isLexicalScope):
(JSC::JSScope::isCatchScope):
(JSC::resolveModeName):

  • runtime/JSScope.h:
  • runtime/SymbolTable.cpp:

(JSC::SymbolTable::SymbolTable):
(JSC::SymbolTable::cloneScopePart):

  • runtime/SymbolTable.h:
  • tests/stress/const-semantics.js:

(.):

Location:
trunk/Source/JavaScriptCore
Files:
2 deleted
35 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r187483 r187515  
    491491    runtime/JSCJSValue.cpp
    492492    runtime/JSCallee.cpp
    493     runtime/JSCatchScope.cpp
    494493    runtime/JSCell.cpp
    495494    runtime/JSConsole.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r187513 r187515  
     12015-07-28  Saam barati  <[email protected]>
     2
     3        Implement catch scope using lexical scoping constructs introduced with "let" scoping patch
     4        https://bugs.webkit.org/show_bug.cgi?id=146979
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Now that BytecodeGenerator has a notion of local scope depth,
     9        we can easily implement a catch scope that doesn't claim that
     10        all variables are dynamically scoped. This means that functions
     11        that use try/catch can have local variable resolution. This also
     12        means that all functions that use try/catch don't have all
     13        their variables marked as being captured.
     14
     15        Catch scopes now behave like a "let" scope (sans the TDZ logic) with a
     16        single variable. Catch scopes are now just JSLexicalEnvironments and the
     17        symbol table backing the catch scope knows that it corresponds to a catch scope.
     18
     19        * CMakeLists.txt:
     20        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
     21        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
     22        * JavaScriptCore.xcodeproj/project.pbxproj:
     23        * bytecode/CodeBlock.cpp:
     24        (JSC::CodeBlock::dumpBytecode):
     25        * bytecode/EvalCodeCache.h:
     26        (JSC::EvalCodeCache::isCacheable):
     27        * bytecompiler/BytecodeGenerator.cpp:
     28        (JSC::BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack):
     29        (JSC::BytecodeGenerator::emitLoadGlobalObject):
     30        (JSC::BytecodeGenerator::pushLexicalScope):
     31        (JSC::BytecodeGenerator::pushLexicalScopeInternal):
     32        (JSC::BytecodeGenerator::popLexicalScope):
     33        (JSC::BytecodeGenerator::popLexicalScopeInternal):
     34        (JSC::BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration):
     35        (JSC::BytecodeGenerator::variable):
     36        (JSC::BytecodeGenerator::resolveType):
     37        (JSC::BytecodeGenerator::emitResolveScope):
     38        (JSC::BytecodeGenerator::emitPopScope):
     39        (JSC::BytecodeGenerator::emitPopWithScope):
     40        (JSC::BytecodeGenerator::emitDebugHook):
     41        (JSC::BytecodeGenerator::popScopedControlFlowContext):
     42        (JSC::BytecodeGenerator::emitPushCatchScope):
     43        (JSC::BytecodeGenerator::emitPopCatchScope):
     44        (JSC::BytecodeGenerator::beginSwitch):
     45        (JSC::BytecodeGenerator::emitPopWithOrCatchScope): Deleted.
     46        * bytecompiler/BytecodeGenerator.h:
     47        (JSC::BytecodeGenerator::lastOpcodeID):
     48        * bytecompiler/NodesCodegen.cpp:
     49        (JSC::AssignResolveNode::emitBytecode):
     50        (JSC::WithNode::emitBytecode):
     51        (JSC::TryNode::emitBytecode):
     52        * debugger/DebuggerScope.cpp:
     53        (JSC::DebuggerScope::isCatchScope):
     54        (JSC::DebuggerScope::isFunctionNameScope):
     55        (JSC::DebuggerScope::isFunctionOrEvalScope):
     56        (JSC::DebuggerScope::caughtValue):
     57        * debugger/DebuggerScope.h:
     58        * inspector/ScriptDebugServer.cpp:
     59        (Inspector::ScriptDebugServer::exceptionOrCaughtValue):
     60        * interpreter/Interpreter.cpp:
     61        (JSC::Interpreter::execute):
     62        * jit/JITOpcodes.cpp:
     63        (JSC::JIT::emit_op_push_name_scope):
     64        * jit/JITOpcodes32_64.cpp:
     65        (JSC::JIT::emit_op_push_name_scope):
     66        * jit/JITOperations.cpp:
     67        * jit/JITOperations.h:
     68        * parser/ASTBuilder.h:
     69        (JSC::ASTBuilder::createContinueStatement):
     70        (JSC::ASTBuilder::createTryStatement):
     71        * parser/NodeConstructors.h:
     72        (JSC::ThrowNode::ThrowNode):
     73        (JSC::TryNode::TryNode):
     74        (JSC::FunctionParameters::FunctionParameters):
     75        * parser/Nodes.h:
     76        * parser/Parser.cpp:
     77        (JSC::Parser<LexerType>::parseTryStatement):
     78        * parser/SyntaxChecker.h:
     79        (JSC::SyntaxChecker::createBreakStatement):
     80        (JSC::SyntaxChecker::createContinueStatement):
     81        (JSC::SyntaxChecker::createTryStatement):
     82        (JSC::SyntaxChecker::createSwitchStatement):
     83        (JSC::SyntaxChecker::createWhileStatement):
     84        (JSC::SyntaxChecker::createWithStatement):
     85        * runtime/JSCatchScope.cpp:
     86        * runtime/JSCatchScope.h:
     87        (JSC::JSCatchScope::JSCatchScope): Deleted.
     88        (JSC::JSCatchScope::create): Deleted.
     89        (JSC::JSCatchScope::createStructure): Deleted.
     90        * runtime/JSFunctionNameScope.h:
     91        (JSC::JSFunctionNameScope::JSFunctionNameScope):
     92        * runtime/JSGlobalObject.cpp:
     93        (JSC::JSGlobalObject::init):
     94        (JSC::JSGlobalObject::visitChildren):
     95        * runtime/JSGlobalObject.h:
     96        (JSC::JSGlobalObject::withScopeStructure):
     97        (JSC::JSGlobalObject::strictEvalActivationStructure):
     98        (JSC::JSGlobalObject::activationStructure):
     99        (JSC::JSGlobalObject::functionNameScopeStructure):
     100        (JSC::JSGlobalObject::directArgumentsStructure):
     101        (JSC::JSGlobalObject::scopedArgumentsStructure):
     102        (JSC::JSGlobalObject::catchScopeStructure): Deleted.
     103        * runtime/JSNameScope.cpp:
     104        (JSC::JSNameScope::create):
     105        (JSC::JSNameScope::toThis):
     106        * runtime/JSNameScope.h:
     107        * runtime/JSObject.cpp:
     108        (JSC::JSObject::toThis):
     109        (JSC::JSObject::isFunctionNameScopeObject):
     110        (JSC::JSObject::isCatchScopeObject): Deleted.
     111        * runtime/JSObject.h:
     112        * runtime/JSScope.cpp:
     113        (JSC::JSScope::collectVariablesUnderTDZ):
     114        (JSC::JSScope::isLexicalScope):
     115        (JSC::JSScope::isCatchScope):
     116        (JSC::resolveModeName):
     117        * runtime/JSScope.h:
     118        * runtime/SymbolTable.cpp:
     119        (JSC::SymbolTable::SymbolTable):
     120        (JSC::SymbolTable::cloneScopePart):
     121        * runtime/SymbolTable.h:
     122        * tests/stress/const-semantics.js:
     123        (.):
     124
    11252015-07-28  Filip Pizlo  <[email protected]>
    2126
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r187483 r187515  
    746746    <ClCompile Include="..\runtime\JSCJSValue.cpp" />
    747747    <ClCompile Include="..\runtime\JSCallee.cpp" />
    748     <ClCompile Include="..\runtime\JSCatchScope.cpp" />
    749748    <ClCompile Include="..\runtime\JSCell.cpp" />
    750749    <ClCompile Include="..\runtime\JSConsole.cpp" />
     
    15581557    <ClInclude Include="..\runtime\JSCJSValueInlines.h" />
    15591558    <ClInclude Include="..\runtime\JSCallee.h" />
    1560     <ClInclude Include="..\runtime\JSCatchScope.h" />
    15611559    <ClInclude Include="..\runtime\JSCell.h" />
    15621560    <ClInclude Include="..\runtime\JSConsole.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r187483 r187515  
    17721772    <ClCompile Include="..\ftl\FTLJSCallBase.cpp" />
    17731773    <ClCompile Include="..\ftl\FTLJSCallVarargs.cpp" />
    1774     <ClCompile Include="..\runtime\JSCatchScope.cpp" />
    17751774    <ClCompile Include="..\runtime\JSFunctionNameScope.cpp" />
    17761775    <ClCompile Include="..\jit\ExecutableAllocatorFixedVMPool.cpp">
     
    42734272    <ClInclude Include="..\ftl\FTLJSCallBase.h" />
    42744273    <ClInclude Include="..\ftl\FTLJSCallVarargs.h" />
    4275     <ClInclude Include="..\runtime\JSCatchScope.h" />
    42764274    <ClInclude Include="..\runtime\JSFunctionNameScope.h" />
    42774275    <ClInclude Include="..\runtime\MathCommon.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r187483 r187515  
    611611                0FD8A32B17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD8A32317D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp */; };
    612612                0FD8A32C17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD8A32417D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
    613                 0FD949821A97DB9600E28966 /* JSCatchScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD9497E1A97DB9600E28966 /* JSCatchScope.cpp */; };
    614                 0FD949831A97DB9600E28966 /* JSCatchScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD9497F1A97DB9600E28966 /* JSCatchScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
    615613                0FD949841A97DB9600E28966 /* JSFunctionNameScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD949801A97DB9600E28966 /* JSFunctionNameScope.cpp */; };
    616614                0FD949851A97DB9600E28966 /* JSFunctionNameScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD949811A97DB9600E28966 /* JSFunctionNameScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    23732371                0FD8A32317D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGToFTLForOSREntryDeferredCompilationCallback.cpp; path = dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp; sourceTree = "<group>"; };
    23742372                0FD8A32417D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGToFTLForOSREntryDeferredCompilationCallback.h; path = dfg/DFGToFTLForOSREntryDeferredCompilationCallback.h; sourceTree = "<group>"; };
    2375                 0FD9497E1A97DB9600E28966 /* JSCatchScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCatchScope.cpp; sourceTree = "<group>"; };
    2376                 0FD9497F1A97DB9600E28966 /* JSCatchScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCatchScope.h; sourceTree = "<group>"; };
    23772373                0FD949801A97DB9600E28966 /* JSFunctionNameScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFunctionNameScope.cpp; sourceTree = "<group>"; };
    23782374                0FD949811A97DB9600E28966 /* JSFunctionNameScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFunctionNameScope.h; sourceTree = "<group>"; };
     
    45314527                                657CF45619BF6662004ACBF2 /* JSCallee.cpp */,
    45324528                                657CF45719BF6662004ACBF2 /* JSCallee.h */,
    4533                                 0FD9497E1A97DB9600E28966 /* JSCatchScope.cpp */,
    4534                                 0FD9497F1A97DB9600E28966 /* JSCatchScope.h */,
    45354529                                BC7F8FBA0E19D1EF008632C0 /* JSCell.cpp */,
    45364530                                BC1167D80E19BCC9008066DD /* JSCell.h */,
     
    62936287                                A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */,
    62946288                                A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
    6295                                 0FD949831A97DB9600E28966 /* JSCatchScope.h in Headers */,
    62966289                                A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
    62976290                                1442566215EDE98D0066A49B /* JSWithScope.h in Headers */,
     
    74367429                                14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */,
    74377430                                70DC3E091B2DF2C700054299 /* IteratorPrototype.cpp in Sources */,
    7438                                 0FD949821A97DB9600E28966 /* JSCatchScope.cpp in Sources */,
    74397431                                A72028B61797601E0098028C /* JSCTestRunnerUtils.cpp in Sources */,
    74407432                                0F2B66EB17B6B5AB00A7AE3F /* JSDataView.cpp in Sources */,
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r187033 r187515  
    14581458            JSNameScope::Type scopeType = (JSNameScope::Type)(++it)->u.operand;
    14591459            printLocationAndOp(out, exec, location, it, "push_name_scope");
    1460             out.printf("%s, %s, %s, %s", registerName(dst).data(), registerName(r1).data(), constantName(k0).data(), (scopeType == JSNameScope::FunctionNameScope) ? "functionScope" : ((scopeType == JSNameScope::CatchScope) ? "catchScope" : "unknownScopeType"));
     1460            out.printf("%s, %s, %s, %s", registerName(dst).data(), registerName(r1).data(), constantName(k0).data(), (scopeType == JSNameScope::FunctionNameScope) ? "functionScope" : "unknownScopeType");
    14611461            break;
    14621462        }
  • trunk/Source/JavaScriptCore/bytecode/EvalCodeCache.h

    r186860 r187515  
    8282                && evalSource.length() < Options::maximumEvalCacheableSourceLength()
    8383                && scope->begin()->isVariableObject()
    84                 && !scope->isLexicalScope();
     84                && !scope->isLexicalScope()
     85                && !scope->isCatchScope();
    8586        }
    8687        static const int maxCacheEntries = 64;
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r187437 r187515  
    579579       
    580580        // This implements step 25 of section 9.2.12.
    581         pushLexicalScopeInternal(environment, true, nullptr);
     581        pushLexicalScopeInternal(environment, true, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope);
    582582
    583583        RefPtr<RegisterID> temp = newTemporary();
     
    13581358}
    13591359
    1360 void BytecodeGenerator::pushLexicalScopeInternal(VariableEnvironment& environment, bool canOptimizeTDZChecks, RegisterID** constantSymbolTableResult)
     1360void BytecodeGenerator::pushLexicalScope(VariableEnvironmentNode* node, bool canOptimizeTDZChecks, RegisterID** constantSymbolTableResult)
     1361{
     1362    VariableEnvironment& environment = node->lexicalVariables();
     1363    pushLexicalScopeInternal(environment, canOptimizeTDZChecks, constantSymbolTableResult, TDZRequirement::UnderTDZ, ScopeType::LetConstScope);
     1364}
     1365
     1366void BytecodeGenerator::pushLexicalScopeInternal(VariableEnvironment& environment, bool canOptimizeTDZChecks, RegisterID** constantSymbolTableResult, TDZRequirement tdzRequirement, ScopeType scopeType)
    13611367{
    13621368    if (!environment.size())
     
    13671373
    13681374    Strong<SymbolTable> symbolTable(*m_vm, SymbolTable::create(*m_vm));
    1369     symbolTable->setDoesCorrespondToLexicalScope();
     1375    switch (scopeType) {
     1376    case ScopeType::CatchScope:
     1377        symbolTable->setScopeType(SymbolTable::ScopeType::CatchScope);
     1378        break;
     1379    case ScopeType::LetConstScope:
     1380        symbolTable->setScopeType(SymbolTable::ScopeType::LexicalScope);
     1381        break;
     1382    }
     1383
    13701384    bool hasCapturedVariables = false;
    13711385    {
    13721386        ConcurrentJITLocker locker(symbolTable->m_lock);
    1373         for (auto entry : environment) {
     1387        for (auto& entry : environment) {
    13741388            ASSERT(entry.value.isLet() || entry.value.isConst());
    13751389            ASSERT(!entry.value.isVar());
     
    14091423        instructions().append(scopeRegister()->index());
    14101424        instructions().append(constantSymbolTable->index());
    1411         instructions().append(addConstantValue(jsTDZValue())->index());
     1425        instructions().append(addConstantValue(tdzRequirement == TDZRequirement::UnderTDZ ? jsTDZValue() : jsUndefined())->index());
    14121426
    14131427        emitMove(scopeRegister(), newScope);
     
    14171431
    14181432    m_symbolTableStack.append(SymbolTableStackEntry{ symbolTable, newScope, false, symbolTableConstantIndex });
    1419     m_TDZStack.append(std::make_pair(environment, canOptimizeTDZChecks));
    1420     // Prefill stack variables with the TDZ empty value.
    1421     // Scope variables will be initialized to the TDZ empty value when JSLexicalEnvironment is allocated.
    1422     for (auto entry : environment) {
    1423         SymbolTableEntry symbolTableEntry = symbolTable->get(entry.key.get());
    1424         ASSERT(!symbolTableEntry.isNull());
    1425         VarOffset offset = symbolTableEntry.varOffset();
    1426         if (offset.isScope()) {
    1427             ASSERT(newScope);
    1428             continue;
    1429         }
    1430         ASSERT(offset.isStack());
    1431         emitMoveEmptyValue(&registerFor(offset.stackOffset()));
    1432     }
    1433 }
    1434 
    1435 void BytecodeGenerator::pushLexicalScope(VariableEnvironmentNode* node, bool canOptimizeTDZChecks, RegisterID** constantSymbolTableResult)
     1433    if (tdzRequirement == TDZRequirement::UnderTDZ)
     1434        m_TDZStack.append(std::make_pair(environment, canOptimizeTDZChecks));
     1435
     1436    if (tdzRequirement == TDZRequirement::UnderTDZ) {
     1437        // Prefill stack variables with the TDZ empty value.
     1438        // Scope variables will be initialized to the TDZ empty value when JSLexicalEnvironment is allocated.
     1439        for (auto& entry : environment) {
     1440            SymbolTableEntry symbolTableEntry = symbolTable->get(entry.key.get());
     1441            ASSERT(!symbolTableEntry.isNull());
     1442            VarOffset offset = symbolTableEntry.varOffset();
     1443            if (offset.isScope()) {
     1444                ASSERT(newScope);
     1445                continue;
     1446            }
     1447            ASSERT(offset.isStack());
     1448            emitMoveEmptyValue(&registerFor(offset.stackOffset()));
     1449        }
     1450    }
     1451}
     1452
     1453void BytecodeGenerator::popLexicalScope(VariableEnvironmentNode* node)
    14361454{
    14371455    VariableEnvironment& environment = node->lexicalVariables();
    1438     pushLexicalScopeInternal(environment, canOptimizeTDZChecks, constantSymbolTableResult);
    1439 }
    1440 
    1441 void BytecodeGenerator::popLexicalScope(VariableEnvironmentNode* node)
    1442 {
    1443     VariableEnvironment& environment = node->lexicalVariables();
     1456    popLexicalScopeInternal(environment, TDZRequirement::UnderTDZ);
     1457}
     1458
     1459void BytecodeGenerator::popLexicalScopeInternal(VariableEnvironment& environment, TDZRequirement tdzRequirement)
     1460{
    14441461    if (!environment.size())
    14451462        return;
     
    14521469    ConcurrentJITLocker locker(symbolTable->m_lock);
    14531470    bool hasCapturedVariables = false;
    1454     for (auto entry : environment) {
     1471    for (auto& entry : environment) {
    14551472        if (entry.value.isCaptured()) {
    14561473            hasCapturedVariables = true;
     
    14721489    }
    14731490
    1474     m_TDZStack.removeLast();
     1491    if (tdzRequirement == TDZRequirement::UnderTDZ)
     1492        m_TDZStack.removeLast();
    14751493}
    14761494
     
    15771595    for (unsigned i = m_symbolTableStack.size(); i--; ) {
    15781596        SymbolTableStackEntry& stackEntry = m_symbolTableStack[i];
    1579         if (stackEntry.m_isWithOrCatch)
     1597        if (stackEntry.m_isWithScope)
    15801598            return Variable(property);
    15811599        Strong<SymbolTable>& symbolTable = stackEntry.m_symbolTable;
     
    15841602            continue;
    15851603       
    1586         return variableForLocalEntry(property, symbolTableEntry, stackEntry.m_symbolTableConstantIndex, symbolTable->correspondsToLexicalScope());
     1604        return variableForLocalEntry(property, symbolTableEntry, stackEntry.m_symbolTableConstantIndex, symbolTable->scopeType() == SymbolTable::ScopeType::LexicalScope);
    15871605    }
    15881606
     
    16621680{
    16631681    for (unsigned i = m_symbolTableStack.size(); i--; ) {
    1664         if (m_symbolTableStack[i].m_isWithOrCatch)
     1682        if (m_symbolTableStack[i].m_isWithScope)
    16651683            return Dynamic;
    16661684    }
     
    16891707        for (unsigned i = m_symbolTableStack.size(); i--; ) {
    16901708            SymbolTableStackEntry& stackEntry = m_symbolTableStack[i];
    1691             // We should not resolve a variable to VarKind::Scope if a "with" or "catch" scope lies in between the current
     1709            // We should not resolve a variable to VarKind::Scope if a "with" scope lies in between the current
    16921710            // scope and the resolved scope.
    1693             RELEASE_ASSERT(!stackEntry.m_isWithOrCatch);
     1711            RELEASE_ASSERT(!stackEntry.m_isWithScope);
    16941712
    16951713            if (stackEntry.m_symbolTable->get(variable.ident().impl()).isNull())
     
    25682586}
    25692587
    2570 void BytecodeGenerator::emitPopWithOrCatchScope(RegisterID* srcDst)
     2588void BytecodeGenerator::emitPopWithScope(RegisterID* srcDst)
    25712589{
    25722590    emitPopScope(srcDst, srcDst);
    25732591    popScopedControlFlowContext();
    25742592    SymbolTableStackEntry stackEntry = m_symbolTableStack.takeLast();
    2575     RELEASE_ASSERT(stackEntry.m_isWithOrCatch);
     2593    RELEASE_ASSERT(stackEntry.m_isWithScope);
    25762594}
    25772595
     
    30083026}
    30093027
    3010 void BytecodeGenerator::emitPushCatchScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes)
    3011 {
    3012     pushScopedControlFlowContext();
    3013 
    3014     emitOpcode(op_push_name_scope);
    3015     instructions().append(dst->index());
    3016     instructions().append(value->index());
    3017     instructions().append(addConstantValue(SymbolTable::createNameScopeTable(*vm(), property, attributes))->index());
    3018     instructions().append(JSNameScope::CatchScope);
    3019 
    3020     m_symbolTableStack.append(SymbolTableStackEntry{ Strong<SymbolTable>(), nullptr, true, 0 });
     3028void BytecodeGenerator::emitPushCatchScope(const Identifier& property, RegisterID* exceptionValue, VariableEnvironment& environment)
     3029{
     3030    RELEASE_ASSERT(environment.contains(property.impl()));
     3031    pushLexicalScopeInternal(environment, true, nullptr, TDZRequirement::NotUnderTDZ, ScopeType::CatchScope);
     3032    Variable exceptionVar = variable(property);
     3033    RELEASE_ASSERT(exceptionVar.isResolved());
     3034    RefPtr<RegisterID> scope = emitResolveScope(nullptr, exceptionVar);
     3035    emitPutToScope(scope.get(), exceptionVar, exceptionValue, ThrowIfNotFound);
     3036}
     3037
     3038void BytecodeGenerator::emitPopCatchScope(VariableEnvironment& environment)
     3039{
     3040    popLexicalScopeInternal(environment, TDZRequirement::NotUnderTDZ);
    30213041}
    30223042
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r187351 r187515  
    582582
    583583        void emitPushFunctionNameScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes);
    584         void emitPushCatchScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes);
     584        void emitPushCatchScope(const Identifier& property, RegisterID* exceptionValue, VariableEnvironment&);
     585        void emitPopCatchScope(VariableEnvironment&);
    585586
    586587        void emitGetScope();
    587588        RegisterID* emitPushWithScope(RegisterID* dst, RegisterID* scope);
    588589        void emitPopScope(RegisterID* dst, RegisterID* scope);
    589         void emitPopWithOrCatchScope(RegisterID* srcDst);
     590        void emitPopWithScope(RegisterID* srcDst);
    590591        RegisterID* emitGetParentScope(RegisterID* dst, RegisterID* scope);
    591592
     
    623624
    624625    private:
    625         void pushLexicalScopeInternal(VariableEnvironment&, bool canOptimizeTDZChecks, RegisterID** constantSymbolTableResult);
     626        enum class TDZRequirement { UnderTDZ, NotUnderTDZ };
     627        enum class ScopeType { CatchScope, LetConstScope };
     628        void pushLexicalScopeInternal(VariableEnvironment&, bool canOptimizeTDZChecks, RegisterID** constantSymbolTableResult, TDZRequirement, ScopeType);
     629        void popLexicalScopeInternal(VariableEnvironment&, TDZRequirement);
    626630    public:
    627631        void pushLexicalScope(VariableEnvironmentNode*, bool canOptimizeTDZChecks, RegisterID** constantSymbolTableResult = nullptr);
     
    739743            Strong<SymbolTable> m_symbolTable;
    740744            RegisterID* m_scope;
    741             bool m_isWithOrCatch;
     745            bool m_isWithScope;
    742746            int m_symbolTableConstantIndex;
    743747        };
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r187351 r187515  
    18591859
    18601860        if (var.isReadOnly() && m_assignmentContext != AssignmentContext::ConstDeclarationStatement) {
     1861            result = generator.emitNode(dst, m_right); // Execute side effects first.
    18611862            generator.emitReadOnlyExceptionIfNeeded(var);
    1862             result = generator.emitNode(dst, m_right);
    18631863        } else if (var.isSpecial() || generator.vm()->typeProfiler()) {
    18641864            RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
     
    18891889    RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
    18901890    if (var.isReadOnly() && m_assignmentContext != AssignmentContext::ConstDeclarationStatement) {
     1891        RegisterID* result = generator.emitNode(dst, m_right); // Execute side effects first.
    18911892        bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
    18921893        if (threwException)
    1893             return generator.emitNode(dst, m_right);
     1894            return result;
    18941895    }
    18951896    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     
    26842685    generator.emitPushWithScope(generator.scopeRegister(), scope.get());
    26852686    generator.emitNode(dst, m_statement);
    2686     generator.emitPopWithOrCatchScope(generator.scopeRegister());
     2687    generator.emitPopWithScope(generator.scopeRegister());
    26872688}
    26882689
     
    29342935        }
    29352936
    2936         generator.emitPushCatchScope(generator.scopeRegister(), m_thrownValueIdent, thrownValueRegister.get(), DontDelete);
     2937        generator.emitPushCatchScope(m_thrownValueIdent, thrownValueRegister.get(), m_catchEnvironment);
    29372938        generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
    29382939        generator.emitNode(dst, m_catchBlock);
    2939         generator.emitPopWithOrCatchScope(generator.scopeRegister());
     2940        generator.emitPopCatchScope(m_catchEnvironment);
    29402941        generator.emitLabel(catchEndLabel.get());
    29412942    }
  • trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp

    r186860 r187515  
    168168bool DebuggerScope::isCatchScope() const
    169169{
    170     return m_scope->isCatchScopeObject();
     170    return m_scope->isCatchScope();
    171171}
    172172
     
    191191    // lexical environment object. Hence, a lexical environment object implies a
    192192    // function or eval scope.
    193     return m_scope->isActivationObject();
    194 }
    195 
    196 JSValue DebuggerScope::caughtValue() const
     193    return m_scope->isActivationObject() && !isCatchScope();
     194}
     195
     196JSValue DebuggerScope::caughtValue(ExecState* exec) const
    197197{
    198198    ASSERT(isCatchScope());
    199     return reinterpret_cast<JSNameScope*>(m_scope.get())->value();
     199    JSLexicalEnvironment* catchEnvironment = jsCast<JSLexicalEnvironment*>(m_scope.get());
     200    SymbolTable* catchSymbolTable = catchEnvironment->symbolTable();
     201    RELEASE_ASSERT(catchSymbolTable->size() == 1);
     202    PropertyName errorName(catchSymbolTable->begin(catchSymbolTable->m_lock)->key.get());
     203    PropertySlot slot(m_scope.get());
     204    bool success = catchEnvironment->getOwnPropertySlot(catchEnvironment, exec, errorName, slot);
     205    RELEASE_ASSERT(success && slot.isValue());
     206    return slot.getValue(exec, errorName);
    200207}
    201208
  • trunk/Source/JavaScriptCore/debugger/DebuggerScope.h

    r182747 r187515  
    9292    bool isFunctionOrEvalScope() const;
    9393
    94     JSValue caughtValue() const;
     94    JSValue caughtValue(ExecState*) const;
    9595
    9696private:
  • trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp

    r185608 r187515  
    341341        DebuggerScope* scope = debuggerCallFrame->scope();
    342342        if (scope->isCatchScope())
    343             return Deprecated::ScriptValue(state->vm(), scope->caughtValue());
     343            return Deprecated::ScriptValue(state->vm(), scope->caughtValue(state));
    344344        debuggerCallFrame = debuggerCallFrame->callerFrame();
    345345    }
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r187142 r187515  
    11411141            }
    11421142            if (JSLexicalEnvironment* lexicalEnvironment = jsDynamicCast<JSLexicalEnvironment*>(node)) {
    1143                 if (!lexicalEnvironment->symbolTable()->correspondsToLexicalScope()) {
     1143                if (lexicalEnvironment->symbolTable()->scopeType() == SymbolTable::ScopeType::VarScope) {
    11441144                    variableObject = node;
    11451145                    break;
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r186860 r187515  
    498498    int dst = currentInstruction[1].u.operand;
    499499    emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
    500     if (currentInstruction[4].u.operand == JSNameScope::CatchScope) {
    501         callOperation(operationPushCatchScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT0);
    502         return;
    503     }
    504 
    505500    RELEASE_ASSERT(currentInstruction[4].u.operand == JSNameScope::FunctionNameScope);
    506501    callOperation(operationPushFunctionNameScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT0);
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r186860 r187515  
    805805    int dst = currentInstruction[1].u.operand;
    806806    emitLoad(currentInstruction[2].u.operand, regT1, regT0);
    807     if (currentInstruction[4].u.operand == JSNameScope::CatchScope) {
    808         callOperation(operationPushCatchScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT1, regT0);
    809         return;
    810     }
    811 
    812807    RELEASE_ASSERT(currentInstruction[4].u.operand == JSNameScope::FunctionNameScope);
    813808    callOperation(operationPushFunctionNameScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT1, regT0);
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r187505 r187515  
    4545#include "JITToDFGDeferredCompilationCallback.h"
    4646#include "JSCInlines.h"
    47 #include "JSCatchScope.h"
    4847#include "JSFunctionNameScope.h"
    4948#include "JSGlobalObjectFunctions.h"
     
    13651364#endif
    13661365
    1367 void JIT_OPERATION operationPushCatchScope(ExecState* exec, int32_t dst, SymbolTable* symbolTable, EncodedJSValue encodedValue)
    1368 {
    1369     pushNameScope<JSCatchScope>(exec, dst, symbolTable, encodedValue);
    1370 }
    1371 
    13721366void JIT_OPERATION operationPushFunctionNameScope(ExecState* exec, int32_t dst, SymbolTable* symbolTable, EncodedJSValue encodedValue)
    13731367{
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r187505 r187515  
    305305void JIT_OPERATION operationPutGetterSetter(ExecState*, JSCell*, Identifier*, JSCell*, JSCell*) WTF_INTERNAL;
    306306#endif
    307 void JIT_OPERATION operationPushCatchScope(ExecState*, int32_t, SymbolTable*, EncodedJSValue) WTF_INTERNAL;
    308307void JIT_OPERATION operationPushFunctionNameScope(ExecState*, int32_t, SymbolTable*, EncodedJSValue) WTF_INTERNAL;
    309308void JIT_OPERATION operationPushWithScope(ExecState*, int32_t, EncodedJSValue) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/parser/ASTBuilder.h

    r187351 r187515  
    556556    }
    557557
    558     StatementNode* createTryStatement(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
    559     {
    560         TryNode* result = new (m_parserArena) TryNode(location, tryBlock, *ident, catchBlock, finallyBlock);
     558    StatementNode* createTryStatement(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine, VariableEnvironment& catchEnvironment)
     559    {
     560        TryNode* result = new (m_parserArena) TryNode(location, tryBlock, *ident, catchBlock, catchEnvironment, finallyBlock);
    561561        if (catchBlock)
    562562            usesCatch();
  • trunk/Source/JavaScriptCore/parser/NodeConstructors.h

    r187108 r187515  
    819819    }
    820820
    821     inline TryNode::TryNode(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier& thrownValueIdent, StatementNode* catchBlock, StatementNode* finallyBlock)
     821    inline TryNode::TryNode(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier& thrownValueIdent, StatementNode* catchBlock, VariableEnvironment& catchEnvironment, StatementNode* finallyBlock)
    822822        : StatementNode(location)
    823823        , m_tryBlock(tryBlock)
     
    826826        , m_finallyBlock(finallyBlock)
    827827    {
     828        m_catchEnvironment.swap(catchEnvironment);
    828829    }
    829830
  • trunk/Source/JavaScriptCore/parser/Nodes.h

    r187351 r187515  
    15141514    class TryNode : public StatementNode {
    15151515    public:
    1516         TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
     1516        TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, VariableEnvironment& catchEnvironment, StatementNode* finallyBlock);
    15171517
    15181518    private:
     
    15231523        StatementNode* m_catchBlock;
    15241524        StatementNode* m_finallyBlock;
     1525        VariableEnvironment m_catchEnvironment;
    15251526    };
    15261527
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r187351 r187515  
    12621262    failIfFalse(tryBlock, "Cannot parse the body of try block");
    12631263    int lastLine = m_lastTokenEndPosition.line;
    1264    
     1264    VariableEnvironment catchEnvironment;
    12651265    if (match(CATCH)) {
    1266         currentScope()->setNeedsFullActivation();
    12671266        next();
    12681267       
     
    12751274        next();
    12761275        AutoPopScopeRef catchScope(this, pushScope());
    1277         failIfTrueIfStrict(declareVariable(ident) & DeclarationResult::InvalidStrictMode, "Cannot declare a catch variable named '", ident->impl(), "' in strict mode");
    1278         catchScope->preventAllVariableDeclarations();
     1276        catchScope->setIsLexicalScope();
     1277        catchScope->preventVarDeclarations();
     1278        failIfTrueIfStrict(catchScope->declareLexicalVariable(ident, false) & DeclarationResult::InvalidStrictMode, "Cannot declare a catch variable named '", ident->impl(), "' in strict mode");
    12791279        handleProductionOrFail(CLOSEPAREN, ")", "end", "'catch' target");
    12801280        matchOrFail(OPENBRACE, "Expected exception handler to be a block statement");
    12811281        catchBlock = parseBlockStatement(context);
    12821282        failIfFalse(catchBlock, "Unable to parse 'catch' block");
     1283        catchEnvironment = catchScope->finalizeLexicalEnvironment();
     1284        RELEASE_ASSERT(catchEnvironment.size() == 1 && catchEnvironment.contains(ident->impl()));
    12831285        popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo);
    12841286    }
     
    12911293    }
    12921294    failIfFalse(catchBlock || finallyBlock, "Try statements must have at least a catch or finally block");
    1293     return context.createTryStatement(location, tryBlock, ident, catchBlock, finallyBlock, firstLine, lastLine);
     1295    return context.createTryStatement(location, tryBlock, ident, catchBlock, finallyBlock, firstLine, lastLine, catchEnvironment);
    12941296}
    12951297
  • trunk/Source/JavaScriptCore/parser/SyntaxChecker.h

    r187351 r187515  
    243243    int createContinueStatement(const JSTokenLocation&, int, int) { return StatementResult; }
    244244    int createContinueStatement(const JSTokenLocation&, const Identifier*, int, int) { return StatementResult; }
    245     int createTryStatement(const JSTokenLocation&, int, const Identifier*, int, int, int, int) { return StatementResult; }
     245    int createTryStatement(const JSTokenLocation&, int, const Identifier*, int, int, int, int, VariableEnvironment&) { return StatementResult; }
    246246    int createSwitchStatement(const JSTokenLocation&, int, int, int, int, int, int, VariableEnvironment&) { return StatementResult; }
    247247    int createWhileStatement(const JSTokenLocation&, int, int, int, int) { return StatementResult; }
  • trunk/Source/JavaScriptCore/runtime/JSFunctionNameScope.h

    r180514 r187515  
    3939   
    4040    JSFunctionNameScope(VM& vm, JSGlobalObject* globalObject, JSScope* next, SymbolTable* symbolTable)
    41         : Base(vm, globalObject->catchScopeStructure(), next, symbolTable)
     41        : Base(vm, globalObject->functionNameScopeStructure(), next, symbolTable)
    4242    {
    4343    }
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r187483 r187515  
    6565#include "JSCallbackFunction.h"
    6666#include "JSCallbackObject.h"
    67 #include "JSCatchScope.h"
    6867#include "JSConsole.h"
    6968#include "JSDataView.h"
     
    303302    m_typedArrays[toIndex(TypeDataView)].structure.set(vm, this, JSDataView::createStructure(vm, this, m_typedArrays[toIndex(TypeDataView)].prototype.get()));
    304303   
    305     m_catchScopeStructure.set(vm, this, JSCatchScope::createStructure(vm, this, jsNull()));
    306304    m_functionNameScopeStructure.set(vm, this, JSFunctionNameScope::createStructure(vm, this, jsNull()));
    307305    m_lexicalEnvironmentStructure.set(vm, this, JSLexicalEnvironment::createStructure(vm, this));
     
    774772    visitor.append(&thisObject->m_strictEvalActivationStructure);
    775773    visitor.append(&thisObject->m_lexicalEnvironmentStructure);
    776     visitor.append(&thisObject->m_catchScopeStructure);
    777774    visitor.append(&thisObject->m_functionNameScopeStructure);
    778775    visitor.append(&thisObject->m_directArgumentsStructure);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r187483 r187515  
    212212    WriteBarrier<Structure> m_strictEvalActivationStructure;
    213213    WriteBarrier<Structure> m_lexicalEnvironmentStructure;
    214     WriteBarrier<Structure> m_catchScopeStructure;
    215214    WriteBarrier<Structure> m_functionNameScopeStructure;
    216215    WriteBarrier<Structure> m_directArgumentsStructure;
     
    424423    Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); }
    425424    Structure* activationStructure() const { return m_lexicalEnvironmentStructure.get(); }
    426     Structure* catchScopeStructure() const { return m_catchScopeStructure.get(); }
    427425    Structure* functionNameScopeStructure() const { return m_functionNameScopeStructure.get(); }
    428426    Structure* directArgumentsStructure() const { return m_directArgumentsStructure.get(); }
  • trunk/Source/JavaScriptCore/runtime/JSNameScope.cpp

    r181993 r187515  
    2929#include "Error.h"
    3030#include "JSCInlines.h"
    31 #include "JSCatchScope.h"
    3231#include "JSFunctionNameScope.h"
    3332
     
    3837JSNameScope* JSNameScope::create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value, Type type)
    3938{
    40     switch (type) {
    41     case CatchScope:
    42         return JSCatchScope::create(vm, globalObject, currentScope, symbolTable, value);
    43     case FunctionNameScope:
    44         return JSFunctionNameScope::create(vm, globalObject, currentScope, symbolTable, value);
    45     }
    46     RELEASE_ASSERT_NOT_REACHED();
    47     return nullptr;
     39    RELEASE_ASSERT(type == FunctionNameScope);
     40    return JSFunctionNameScope::create(vm, globalObject, currentScope, symbolTable, value);
    4841}
    4942
  • trunk/Source/JavaScriptCore/runtime/JSNameScope.h

    r182747 r187515  
    3939
    4040    enum Type {
    41         CatchScope,
    4241        FunctionNameScope
    4342    };
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r187464 r187515  
    3636#include "GetterSetter.h"
    3737#include "IndexingHeaderInlines.h"
    38 #include "JSCatchScope.h"
    3938#include "JSFunction.h"
    4039#include "JSFunctionNameScope.h"
     
    16011600{
    16021601    return jsCast<JSObject*>(cell);
    1603 }
    1604 
    1605 bool JSObject::isCatchScopeObject() const
    1606 {
    1607     return inherits(JSCatchScope::info());
    16081602}
    16091603
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r186776 r187515  
    602602    bool isStaticScopeObject() const;
    603603    bool isNameScopeObject() const;
    604     bool isCatchScopeObject() const;
    605604    bool isFunctionNameScopeObject() const;
    606605    bool isActivationObject() const;
  • trunk/Source/JavaScriptCore/runtime/JSScope.cpp

    r186860 r187515  
    194194            continue;
    195195        SymbolTable* symbolTable = jsCast<JSLexicalEnvironment*>(scope)->symbolTable();
    196         ASSERT(symbolTable->correspondsToLexicalScope());
     196        ASSERT(symbolTable->scopeType() == SymbolTable::ScopeType::LexicalScope);
    197197        ConcurrentJITLocker locker(symbolTable->m_lock);
    198198        for (auto end = symbolTable->end(locker), iter = symbolTable->begin(locker); iter != end; ++iter)
     
    207207        return false;
    208208
    209     return lexicalEnvironment->symbolTable()->correspondsToLexicalScope();
    210 }
     209    return lexicalEnvironment->symbolTable()->scopeType() == SymbolTable::ScopeType::LexicalScope;
     210}
     211
     212bool JSScope::isCatchScope()
     213{
     214    JSLexicalEnvironment* lexicalEnvironment = jsDynamicCast<JSLexicalEnvironment*>(this);
     215    if (!lexicalEnvironment)
     216        return false;
     217    return lexicalEnvironment->symbolTable()->scopeType() == SymbolTable::ScopeType::CatchScope;
     218}
     219
    211220
    212221const char* resolveModeName(ResolveMode mode)
  • trunk/Source/JavaScriptCore/runtime/JSScope.h

    r186860 r187515  
    166166
    167167    bool isLexicalScope();
     168    bool isCatchScope();
    168169
    169170    ScopeChainIterator begin();
  • trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp

    r186860 r187515  
    8585    : JSCell(vm, vm.symbolTableStructure.get())
    8686    , m_usesNonStrictEval(false)
    87     , m_correspondsToLexicalScope(false)
     87    , m_scopeType(VarScope)
    8888{
    8989}
     
    143143   
    144144    result->m_usesNonStrictEval = m_usesNonStrictEval;
    145     result->m_correspondsToLexicalScope = m_correspondsToLexicalScope;
     145    result->m_scopeType = m_scopeType;
    146146
    147147    for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
  • trunk/Source/JavaScriptCore/runtime/SymbolTable.h

    r186860 r187515  
    649649    bool usesNonStrictEval() { return m_usesNonStrictEval; }
    650650    void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
    651     ALWAYS_INLINE bool correspondsToLexicalScope() { return m_correspondsToLexicalScope; }
    652     void setDoesCorrespondToLexicalScope() { m_correspondsToLexicalScope = true; }
     651
     652    enum ScopeType {
     653        VarScope,
     654        LexicalScope,
     655        CatchScope
     656    };
     657    void setScopeType(ScopeType type) { m_scopeType = type; }
     658    ScopeType scopeType() const { return static_cast<ScopeType>(m_scopeType); }
    653659
    654660    SymbolTable* cloneScopePart(VM&);
     
    679685
    680686    bool m_usesNonStrictEval : 1;
    681     bool m_correspondsToLexicalScope : 1;
     687    unsigned m_scopeType : 2; // ScopeType
    682688   
    683689    WriteBarrier<ScopedArgumentsTable> m_arguments;
  • trunk/Source/JavaScriptCore/tests/stress/const-semantics.js

    r187460 r187515  
    189189        const x = 20;
    190190        shouldThrowInvalidConstAssignment(function() { x = 20; });
     191        assert(x === 20);
    191192        shouldThrowInvalidConstAssignment(function() { x += 20; });
     193        assert(x === 20);
    192194        shouldThrowInvalidConstAssignment(function() { x -= 20; });
     195        assert(x === 20);
    193196        shouldThrowInvalidConstAssignment(function() { x *= 20; });
     197        assert(x === 20);
    194198        shouldThrowInvalidConstAssignment(function() { x /= 20; });
     199        assert(x === 20);
    195200        shouldThrowInvalidConstAssignment(function() { x >>= 20; });
     201        assert(x === 20);
    196202        shouldThrowInvalidConstAssignment(function() { x <<= 20; });
     203        assert(x === 20);
    197204        shouldThrowInvalidConstAssignment(function() { x ^= 20; });
     205        assert(x === 20);
    198206        shouldThrowInvalidConstAssignment(function() { x++; });
     207        assert(x === 20);
    199208        shouldThrowInvalidConstAssignment(function() { x--; });
     209        assert(x === 20);
    200210        shouldThrowInvalidConstAssignment(function() { ++x; });
     211        assert(x === 20);
    201212        shouldThrowInvalidConstAssignment(function() { --x; });
     213        assert(x === 20);
    202214    }
    203215    function jaz() {
Note: See TracChangeset for help on using the changeset viewer.