<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[189279] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/189279">189279</a></dd>
<dt>Author</dt> <dd>saambarati1@gmail.com</dd>
<dt>Date</dt> <dd>2015-09-03 12:45:44 -0700 (Thu, 03 Sep 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Block scoped variables should be visible across scripts
https://bugs.webkit.org/show_bug.cgi?id=147813
Reviewed by Filip Pizlo.
Source/JavaScriptCore:
This patch properly implements the global lexical tier described in
http://www.ecma-international.org/ecma-262/6.0/index.html#sec-globaldeclarationinstantiation.
The sepcification mandates that there is a global lexical environment
that wrtaps all program execution. This global lexical environment
holds let/const/class variables defined at the top-level scope
inside a program. These variables can never shadow other program-level
"var"s, global object properties, or other global lexical environment
declarations. Doing so is a SyntaxError.
This patch adds new ResolveTypes that describe the global lexical environment:
GlobalLexicalVar and GlobalLexiclaVarWithInjectionChecks. Resolving to
these means we're doing a load/store from the JSGlobalLexicalEnvironment.
This patch also addes new ResolveTypes: UnresolvedProperty and
UnresolvedPropertyWithVarInjectionChecks. Before, we used GlobalProperty
to encompass this category because if JSScope::abstractAccess didn't
resolve to anything, we could safely assume that this property is
on the global object. Such an assumption is no longer true in ES6.
When we have a resolve_scope/put_to_scope/get_from_scope with this
ResolveType, we try to transition it to either a GlobalProperty
ResolveType or a GlobalLexicalVar resolve type.
JSGlobalLexicalEnvironment is a subclass of JSSegmentedVariableObject.
This means get_from_scopes are direct pointer reads and
put_to_scopes are direct pointer stores.
* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
* bytecode/EvalCodeCache.h:
(JSC::EvalCodeCache::clear):
(JSC::EvalCodeCache::isCacheableScope):
(JSC::EvalCodeCache::isCacheable):
* bytecode/SpeculatedType.h:
* bytecode/UnlinkedCodeBlock.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack):
(JSC::BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration):
(JSC::BytecodeGenerator::emitGetFromScope):
(JSC::BytecodeGenerator::emitPutToScope):
(JSC::BytecodeGenerator::initializeVariable):
(JSC::BytecodeGenerator::emitInstanceOf):
(JSC::BytecodeGenerator::emitPushFunctionNameScope):
(JSC::BytecodeGenerator::pushScopedControlFlowContext):
(JSC::BytecodeGenerator::emitPushCatchScope):
(JSC::BytecodeGenerator::emitPopCatchScope):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::PostfixNode::emitResolve):
(JSC::PrefixNode::emitResolve):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::AssignResolveNode::emitBytecode):
(JSC::EmptyLetExpression::emitBytecode):
(JSC::ForInNode::emitLoopHeader):
(JSC::ForOfNode::emitBytecode):
(JSC::BindingNode::bindValue):
* debugger/DebuggerScope.cpp:
(JSC::DebuggerScope::isGlobalScope):
(JSC::DebuggerScope::isGlobalLexicalEnvironment):
(JSC::DebuggerScope::isClosureScope):
(JSC::DebuggerScope::caughtValue):
(JSC::DebuggerScope::isFunctionOrEvalScope): Deleted.
* debugger/DebuggerScope.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasRegisterPointer):
(JSC::DFG::Node::variablePointer):
(JSC::DFG::Node::hasHeapPrediction):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStoreBarrierInsertionPhase.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileNode):
(JSC::FTL::DFG::LowerDFGToLLVM::compileMultiPutByOffset):
(JSC::FTL::DFG::LowerDFGToLLVM::compileGetGlobalVariable):
(JSC::FTL::DFG::LowerDFGToLLVM::compilePutGlobalVariable):
(JSC::FTL::DFG::LowerDFGToLLVM::compileGetGlobalVar): Deleted.
(JSC::FTL::DFG::LowerDFGToLLVM::compilePutGlobalVar): Deleted.
* inspector/JSJavaScriptCallFrame.cpp:
(Inspector::JSJavaScriptCallFrame::scopeType):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
* jit/JIT.h:
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::emitSlow_op_resolve_scope):
(JSC::JIT::emitLoadWithStructureCheck):
(JSC::JIT::emitGetGlobalProperty):
(JSC::JIT::emitGetVarFromPointer):
(JSC::JIT::emitGetClosureVar):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emitSlow_op_get_from_scope):
(JSC::JIT::emitPutGlobalProperty):
(JSC::JIT::emitPutGlobalVariable):
(JSC::JIT::emit_op_put_to_scope):
(JSC::JIT::emitSlow_op_put_to_scope):
(JSC::JIT::emitGetGlobalVar): Deleted.
(JSC::JIT::emitPutGlobalVar): Deleted.
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::emitSlow_op_resolve_scope):
(JSC::JIT::emitLoadWithStructureCheck):
(JSC::JIT::emitGetGlobalProperty):
(JSC::JIT::emitGetVarFromPointer):
(JSC::JIT::emitGetClosureVar):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emitSlow_op_get_from_scope):
(JSC::JIT::emitPutGlobalProperty):
(JSC::JIT::emitPutGlobalVariable):
(JSC::JIT::emit_op_put_to_scope):
(JSC::JIT::emitSlow_op_put_to_scope):
(JSC::JIT::emitGetGlobalVar): Deleted.
(JSC::JIT::emitPutGlobalVar): Deleted.
* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
(JSC::CommonSlowPaths::tryCachePutToScopeGlobal):
(JSC::CommonSlowPaths::tryCacheGetFromScopeGlobal):
* runtime/Executable.cpp:
(JSC::ProgramExecutable::initializeGlobalProperties):
* runtime/GetPutInfo.h: Added.
(JSC::resolveModeName):
(JSC::resolveTypeName):
(JSC::initializationModeName):
(JSC::makeType):
(JSC::needsVarInjectionChecks):
(JSC::ResolveOp::ResolveOp):
(JSC::GetPutInfo::GetPutInfo):
(JSC::GetPutInfo::resolveType):
(JSC::GetPutInfo::initializationMode):
(JSC::GetPutInfo::resolveMode):
(JSC::GetPutInfo::operand):
* runtime/JSGlobalLexicalEnvironment.cpp: Added.
(JSC::JSGlobalLexicalEnvironment::getOwnPropertySlot):
(JSC::JSGlobalLexicalEnvironment::put):
* runtime/JSGlobalLexicalEnvironment.h: Added.
(JSC::JSGlobalLexicalEnvironment::create):
(JSC::JSGlobalLexicalEnvironment::isEmpty):
(JSC::JSGlobalLexicalEnvironment::createStructure):
(JSC::JSGlobalLexicalEnvironment::JSGlobalLexicalEnvironment):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::put):
(JSC::JSGlobalObject::addGlobalVar):
(JSC::JSGlobalObject::visitChildren):
(JSC::JSGlobalObject::addStaticGlobals):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::addVar):
(JSC::JSGlobalObject::globalScope):
(JSC::JSGlobalObject::globalLexicalEnvironment):
(JSC::JSGlobalObject::hasOwnPropertyForWrite):
(JSC::constructEmptyArray):
(JSC::JSGlobalObject::symbolTableHasProperty): Deleted.
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::globalFuncEval):
(JSC::globalFuncParseInt):
* runtime/JSLexicalEnvironment.h:
(JSC::JSLexicalEnvironment::createStructure):
* runtime/JSObject.h:
(JSC::JSObject::isGlobalObject):
(JSC::JSObject::isErrorInstance):
(JSC::JSObject::isVariableObject): Deleted.
(JSC::JSObject::isStaticScopeObject): Deleted.
(JSC::JSObject::isNameScopeObject): Deleted.
(JSC::JSObject::isActivationObject): Deleted.
* runtime/JSScope.cpp:
(JSC::JSScope::visitChildren):
(JSC::abstractAccess):
(JSC::JSScope::resolve):
(JSC::JSScope::abstractResolve):
(JSC::JSScope::collectVariablesUnderTDZ):
(JSC::isScopeType):
(JSC::JSScope::isVarScope):
(JSC::JSScope::isLexicalScope):
(JSC::JSScope::isCatchScope):
(JSC::JSScope::isFunctionNameScopeObject):
(JSC::JSScope::isGlobalLexicalEnvironment):
(JSC::JSScope::constantScopeForCodeBlock):
(JSC::resolveModeName): Deleted.
(JSC::resolveTypeName): Deleted.
* runtime/JSScope.h:
(JSC::makeType): Deleted.
(JSC::needsVarInjectionChecks): Deleted.
(JSC::ResolveOp::ResolveOp): Deleted.
(JSC::ResolveModeAndType::ResolveModeAndType): Deleted.
(JSC::ResolveModeAndType::mode): Deleted.
(JSC::ResolveModeAndType::type): Deleted.
(JSC::ResolveModeAndType::operand): Deleted.
* runtime/JSSegmentedVariableObject.cpp:
(JSC::JSSegmentedVariableObject::findVariableIndex):
(JSC::JSSegmentedVariableObject::addVariables):
* runtime/JSSegmentedVariableObject.h:
* runtime/JSSymbolTableObject.h:
(JSC::symbolTablePut):
* runtime/JSType.h:
* runtime/PutPropertySlot.h:
(JSC::PutPropertySlot::PutPropertySlot):
(JSC::PutPropertySlot::isCacheablePut):
(JSC::PutPropertySlot::isCacheableSetter):
(JSC::PutPropertySlot::isCacheableCustom):
(JSC::PutPropertySlot::isInitialization):
(JSC::PutPropertySlot::cachedOffset):
* runtime/SymbolTable.h:
* tests/stress/global-lexical-let-no-rhs.js: Added.
(assert):
(foo):
* tests/stress/global-lexical-redeclare-variable.js: Added.
(globalFunction):
(globalClass):
(assert):
(assertExpectations):
(assertProperError):
* tests/stress/global-lexical-redefine-const.js: Added.
* tests/stress/global-lexical-var-injection.js: Added.
(assert):
(baz):
* tests/stress/global-lexical-variable-tdz.js: Added.
* tests/stress/global-lexical-variable-unresolved-property.js: Added.
* tests/stress/global-lexical-variable-with-statement.js: Added.
(assert):
(shouldThrowInvalidConstAssignment):
(makeObj):
* tests/stress/multiple-files-tests: Added.
* tests/stress/multiple-files-tests/global-lexical-redeclare-variable: Added.
* tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fifth.js: Added.
* tests/stress/multiple-files-tests/global-lexical-redeclare-variable/first.js: Added.
* tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fourth.js: Added.
* tests/stress/multiple-files-tests/global-lexical-redeclare-variable/second.js: Added.
* tests/stress/multiple-files-tests/global-lexical-redeclare-variable/sixth.js: Added.
* tests/stress/multiple-files-tests/global-lexical-redeclare-variable/third.js: Added.
* tests/stress/multiple-files-tests/global-lexical-redefine-const: Added.
* tests/stress/multiple-files-tests/global-lexical-redefine-const/first.js: Added.
(assert):
(shouldThrowInvalidConstAssignment):
* tests/stress/multiple-files-tests/global-lexical-redefine-const/second.js: Added.
(foo):
(bar):
(baz):
* tests/stress/multiple-files-tests/global-lexical-variable-tdz: Added.
* tests/stress/multiple-files-tests/global-lexical-variable-tdz/first.js: Added.
(assert):
(shouldThrowTDZ):
(foo):
(bar):
* tests/stress/multiple-files-tests/global-lexical-variable-tdz/second.js: Added.
* tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property: Added.
* tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/first.js: Added.
(assert):
(shouldThrowTDZ):
(foo):
* tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/second.js: Added.
LayoutTests:
* js/dom/const-expected.txt:
* js/dom/const.html:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsdomconstexpectedtxt">trunk/LayoutTests/js/dom/const-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsdomconsthtml">trunk/LayoutTests/js/dom/const.html</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeEvalCodeCacheh">trunk/Source/JavaScriptCore/bytecode/EvalCodeCache.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeSpeculatedTypeh">trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockh">trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerNodesCodegencpp">trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerScopecpp">trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerScopeh">trunk/Source/JavaScriptCore/debugger/DebuggerScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStoreBarrierInsertionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSJavaScriptCallFramecpp">trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccesscpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntDatacpp">trunk/Source/JavaScriptCore/llint/LLIntData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathsh">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathsh">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExecutablecpp">trunk/Source/JavaScriptCore/runtime/Executable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjecth">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionscpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSLexicalEnvironmenth">trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjecth">trunk/Source/JavaScriptCore/runtime/JSObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSScopecpp">trunk/Source/JavaScriptCore/runtime/JSScope.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSScopeh">trunk/Source/JavaScriptCore/runtime/JSScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSSegmentedVariableObjectcpp">trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSSegmentedVariableObjecth">trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSSymbolTableObjecth">trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSTypeh">trunk/Source/JavaScriptCore/runtime/JSType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimePutPropertySloth">trunk/Source/JavaScriptCore/runtime/PutPropertySlot.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolTableh">trunk/Source/JavaScriptCore/runtime/SymbolTable.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreruntimeGetPutInfoh">trunk/Source/JavaScriptCore/runtime/GetPutInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalLexicalEnvironmentcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalLexicalEnvironmenth">trunk/Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressgloballexicalletnorhsjs">trunk/Source/JavaScriptCore/tests/stress/global-lexical-let-no-rhs.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressgloballexicalredeclarevariablejs">trunk/Source/JavaScriptCore/tests/stress/global-lexical-redeclare-variable.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressgloballexicalredefineconstjs">trunk/Source/JavaScriptCore/tests/stress/global-lexical-redefine-const.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressgloballexicalvarinjectionjs">trunk/Source/JavaScriptCore/tests/stress/global-lexical-var-injection.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressgloballexicalvariabletdzjs">trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-tdz.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressgloballexicalvariableunresolvedpropertyjs">trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-unresolved-property.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressgloballexicalvariablewithstatementjs">trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-with-statement.js</a></li>
<li>trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/</li>
<li>trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/</li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablefifthjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fifth.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablefirstjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/first.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablefourthjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fourth.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablesecondjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/second.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablesixthjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/sixth.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablethirdjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/third.js</a></li>
<li>trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redefine-const/</li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredefineconstfirstjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redefine-const/first.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredefineconstsecondjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redefine-const/second.js</a></li>
<li>trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-tdz/</li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalvariabletdzfirstjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-tdz/first.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalvariabletdzsecondjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-tdz/second.js</a></li>
<li>trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/</li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalvariableunresolvedpropertyfirstjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/first.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalvariableunresolvedpropertysecondjs">trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/second.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/LayoutTests/ChangeLog        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2015-09-03 Saam barati <sbarati@apple.com>
+
+ Block scoped variables should be visible across scripts
+ https://bugs.webkit.org/show_bug.cgi?id=147813
+
+ Reviewed by Filip Pizlo.
+
+ * js/dom/const-expected.txt:
+ * js/dom/const.html:
+
</ins><span class="cx"> 2015-09-02 Ryosuke Niwa <rniwa@webkit.org>
</span><span class="cx">
</span><span class="cx"> MutationObserver should accept attributeFilter, attributeOldValue, and characterDataOldValue on their own
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomconstexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/const-expected.txt (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/const-expected.txt        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/LayoutTests/js/dom/const-expected.txt        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -1,10 +1,8 @@
</span><del>-This test checks that const declarations in JavaScript work and are readonly.
</del><ins>+CONSOLE MESSAGE: SyntaxError: Can't create duplicate variable that shadows a global property: 'bodyId'
+This test checks that const variables can't shadow global object properties. Note that this test expects SyntaxErrors in below
</ins><span class="cx">
</span><del>-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
</del><ins>+PASS sentinel is "__s__"
</ins><span class="cx"> PASS bodyId is document.getElementById('bodyId')
</span><del>-PASS ranConstInitialiser is true
</del><span class="cx"> PASS successfullyParsed is true
</span><span class="cx">
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomconsthtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/const.html (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/const.html        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/LayoutTests/js/dom/const.html        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -5,17 +5,28 @@
</span><span class="cx"> <script src="../../resources/js-test-pre.js"></script>
</span><span class="cx"> </head>
</span><span class="cx"> <body id="bodyId">
</span><ins>+
</ins><span class="cx"> <script>
</span><ins>+
</ins><span class="cx"> description(
</span><del>-"This test checks that const declarations in JavaScript work and are readonly."
</del><ins>+ "This test checks that const variables can't shadow global object properties. Note that this test expects SyntaxErrors in below <script>"
</ins><span class="cx"> );
</span><span class="cx">
</span><del>-// Make sure we don't override properties placed on the global object
-var ranConstInitialiser = false;
-const bodyId = (ranConstInitialiser = true, "Const initialiser overwrote existing property");
</del><ins>+let sentinel = "__s__";
+</script>
+
+<script>
+// Make sure we can't override properties placed on the global object
+const bodyId = "lah la lah la lah, I should never execute.";
+sentinel = "bad";
+</script>
+
+<script>
+shouldBe("sentinel", '"__s__"');
</ins><span class="cx"> shouldBe("bodyId", "document.getElementById('bodyId')");
</span><del>-shouldBeTrue("ranConstInitialiser");
</del><ins>+successfullyParsed = true;
</ins><span class="cx"> </script>
</span><ins>+
</ins><span class="cx"> <script src="../../resources/js-test-post.js"></script>
</span><span class="cx"> </body>
</span><span class="cx"> </html>
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -525,6 +525,7 @@
</span><span class="cx"> runtime/JSDateMath.cpp
</span><span class="cx"> runtime/JSEnvironmentRecord.cpp
</span><span class="cx"> runtime/JSFunction.cpp
</span><ins>+ runtime/JSGlobalLexicalEnvironment.cpp
</ins><span class="cx"> runtime/JSGlobalObject.cpp
</span><span class="cx"> runtime/JSGlobalObjectDebuggable.cpp
</span><span class="cx"> runtime/JSGlobalObjectFunctions.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -1,3 +1,300 @@
</span><ins>+2015-09-03 Saam barati <sbarati@apple.com>
+
+ Block scoped variables should be visible across scripts
+ https://bugs.webkit.org/show_bug.cgi?id=147813
+
+ Reviewed by Filip Pizlo.
+
+ This patch properly implements the global lexical tier described in
+ http://www.ecma-international.org/ecma-262/6.0/index.html#sec-globaldeclarationinstantiation.
+ The sepcification mandates that there is a global lexical environment
+ that wrtaps all program execution. This global lexical environment
+ holds let/const/class variables defined at the top-level scope
+ inside a program. These variables can never shadow other program-level
+ "var"s, global object properties, or other global lexical environment
+ declarations. Doing so is a SyntaxError.
+
+ This patch adds new ResolveTypes that describe the global lexical environment:
+ GlobalLexicalVar and GlobalLexiclaVarWithInjectionChecks. Resolving to
+ these means we're doing a load/store from the JSGlobalLexicalEnvironment.
+ This patch also addes new ResolveTypes: UnresolvedProperty and
+ UnresolvedPropertyWithVarInjectionChecks. Before, we used GlobalProperty
+ to encompass this category because if JSScope::abstractAccess didn't
+ resolve to anything, we could safely assume that this property is
+ on the global object. Such an assumption is no longer true in ES6.
+ When we have a resolve_scope/put_to_scope/get_from_scope with this
+ ResolveType, we try to transition it to either a GlobalProperty
+ ResolveType or a GlobalLexicalVar resolve type.
+
+ JSGlobalLexicalEnvironment is a subclass of JSSegmentedVariableObject.
+ This means get_from_scopes are direct pointer reads and
+ put_to_scopes are direct pointer stores.
+
+ * CMakeLists.txt:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ * bytecode/EvalCodeCache.h:
+ (JSC::EvalCodeCache::clear):
+ (JSC::EvalCodeCache::isCacheableScope):
+ (JSC::EvalCodeCache::isCacheable):
+ * bytecode/SpeculatedType.h:
+ * bytecode/UnlinkedCodeBlock.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack):
+ (JSC::BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration):
+ (JSC::BytecodeGenerator::emitGetFromScope):
+ (JSC::BytecodeGenerator::emitPutToScope):
+ (JSC::BytecodeGenerator::initializeVariable):
+ (JSC::BytecodeGenerator::emitInstanceOf):
+ (JSC::BytecodeGenerator::emitPushFunctionNameScope):
+ (JSC::BytecodeGenerator::pushScopedControlFlowContext):
+ (JSC::BytecodeGenerator::emitPushCatchScope):
+ (JSC::BytecodeGenerator::emitPopCatchScope):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::PostfixNode::emitResolve):
+ (JSC::PrefixNode::emitResolve):
+ (JSC::ReadModifyResolveNode::emitBytecode):
+ (JSC::AssignResolveNode::emitBytecode):
+ (JSC::EmptyLetExpression::emitBytecode):
+ (JSC::ForInNode::emitLoopHeader):
+ (JSC::ForOfNode::emitBytecode):
+ (JSC::BindingNode::bindValue):
+ * debugger/DebuggerScope.cpp:
+ (JSC::DebuggerScope::isGlobalScope):
+ (JSC::DebuggerScope::isGlobalLexicalEnvironment):
+ (JSC::DebuggerScope::isClosureScope):
+ (JSC::DebuggerScope::caughtValue):
+ (JSC::DebuggerScope::isFunctionOrEvalScope): Deleted.
+ * debugger/DebuggerScope.h:
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCapabilities.cpp:
+ (JSC::DFG::capabilityLevel):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGDoesGC.cpp:
+ (JSC::DFG::doesGC):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasRegisterPointer):
+ (JSC::DFG::Node::variablePointer):
+ (JSC::DFG::Node::hasHeapPrediction):
+ * dfg/DFGNodeType.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::safeToExecute):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStoreBarrierInsertionPhase.cpp:
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::DFG::LowerDFGToLLVM::compileNode):
+ (JSC::FTL::DFG::LowerDFGToLLVM::compileMultiPutByOffset):
+ (JSC::FTL::DFG::LowerDFGToLLVM::compileGetGlobalVariable):
+ (JSC::FTL::DFG::LowerDFGToLLVM::compilePutGlobalVariable):
+ (JSC::FTL::DFG::LowerDFGToLLVM::compileGetGlobalVar): Deleted.
+ (JSC::FTL::DFG::LowerDFGToLLVM::compilePutGlobalVar): Deleted.
+ * inspector/JSJavaScriptCallFrame.cpp:
+ (Inspector::JSJavaScriptCallFrame::scopeType):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ * jit/JIT.h:
+ * jit/JITOperations.cpp:
+ * jit/JITOperations.h:
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_resolve_scope):
+ (JSC::JIT::emitSlow_op_resolve_scope):
+ (JSC::JIT::emitLoadWithStructureCheck):
+ (JSC::JIT::emitGetGlobalProperty):
+ (JSC::JIT::emitGetVarFromPointer):
+ (JSC::JIT::emitGetClosureVar):
+ (JSC::JIT::emit_op_get_from_scope):
+ (JSC::JIT::emitSlow_op_get_from_scope):
+ (JSC::JIT::emitPutGlobalProperty):
+ (JSC::JIT::emitPutGlobalVariable):
+ (JSC::JIT::emit_op_put_to_scope):
+ (JSC::JIT::emitSlow_op_put_to_scope):
+ (JSC::JIT::emitGetGlobalVar): Deleted.
+ (JSC::JIT::emitPutGlobalVar): Deleted.
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_resolve_scope):
+ (JSC::JIT::emitSlow_op_resolve_scope):
+ (JSC::JIT::emitLoadWithStructureCheck):
+ (JSC::JIT::emitGetGlobalProperty):
+ (JSC::JIT::emitGetVarFromPointer):
+ (JSC::JIT::emitGetClosureVar):
+ (JSC::JIT::emit_op_get_from_scope):
+ (JSC::JIT::emitSlow_op_get_from_scope):
+ (JSC::JIT::emitPutGlobalProperty):
+ (JSC::JIT::emitPutGlobalVariable):
+ (JSC::JIT::emit_op_put_to_scope):
+ (JSC::JIT::emitSlow_op_put_to_scope):
+ (JSC::JIT::emitGetGlobalVar): Deleted.
+ (JSC::JIT::emitPutGlobalVar): Deleted.
+ * llint/LLIntData.cpp:
+ (JSC::LLInt::Data::performAssertions):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LLIntSlowPaths.h:
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * runtime/CommonSlowPaths.cpp:
+ (JSC::SLOW_PATH_DECL):
+ * runtime/CommonSlowPaths.h:
+ (JSC::CommonSlowPaths::tryCachePutToScopeGlobal):
+ (JSC::CommonSlowPaths::tryCacheGetFromScopeGlobal):
+ * runtime/Executable.cpp:
+ (JSC::ProgramExecutable::initializeGlobalProperties):
+ * runtime/GetPutInfo.h: Added.
+ (JSC::resolveModeName):
+ (JSC::resolveTypeName):
+ (JSC::initializationModeName):
+ (JSC::makeType):
+ (JSC::needsVarInjectionChecks):
+ (JSC::ResolveOp::ResolveOp):
+ (JSC::GetPutInfo::GetPutInfo):
+ (JSC::GetPutInfo::resolveType):
+ (JSC::GetPutInfo::initializationMode):
+ (JSC::GetPutInfo::resolveMode):
+ (JSC::GetPutInfo::operand):
+ * runtime/JSGlobalLexicalEnvironment.cpp: Added.
+ (JSC::JSGlobalLexicalEnvironment::getOwnPropertySlot):
+ (JSC::JSGlobalLexicalEnvironment::put):
+ * runtime/JSGlobalLexicalEnvironment.h: Added.
+ (JSC::JSGlobalLexicalEnvironment::create):
+ (JSC::JSGlobalLexicalEnvironment::isEmpty):
+ (JSC::JSGlobalLexicalEnvironment::createStructure):
+ (JSC::JSGlobalLexicalEnvironment::JSGlobalLexicalEnvironment):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init):
+ (JSC::JSGlobalObject::put):
+ (JSC::JSGlobalObject::addGlobalVar):
+ (JSC::JSGlobalObject::visitChildren):
+ (JSC::JSGlobalObject::addStaticGlobals):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::addVar):
+ (JSC::JSGlobalObject::globalScope):
+ (JSC::JSGlobalObject::globalLexicalEnvironment):
+ (JSC::JSGlobalObject::hasOwnPropertyForWrite):
+ (JSC::constructEmptyArray):
+ (JSC::JSGlobalObject::symbolTableHasProperty): Deleted.
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncEval):
+ (JSC::globalFuncParseInt):
+ * runtime/JSLexicalEnvironment.h:
+ (JSC::JSLexicalEnvironment::createStructure):
+ * runtime/JSObject.h:
+ (JSC::JSObject::isGlobalObject):
+ (JSC::JSObject::isErrorInstance):
+ (JSC::JSObject::isVariableObject): Deleted.
+ (JSC::JSObject::isStaticScopeObject): Deleted.
+ (JSC::JSObject::isNameScopeObject): Deleted.
+ (JSC::JSObject::isActivationObject): Deleted.
+ * runtime/JSScope.cpp:
+ (JSC::JSScope::visitChildren):
+ (JSC::abstractAccess):
+ (JSC::JSScope::resolve):
+ (JSC::JSScope::abstractResolve):
+ (JSC::JSScope::collectVariablesUnderTDZ):
+ (JSC::isScopeType):
+ (JSC::JSScope::isVarScope):
+ (JSC::JSScope::isLexicalScope):
+ (JSC::JSScope::isCatchScope):
+ (JSC::JSScope::isFunctionNameScopeObject):
+ (JSC::JSScope::isGlobalLexicalEnvironment):
+ (JSC::JSScope::constantScopeForCodeBlock):
+ (JSC::resolveModeName): Deleted.
+ (JSC::resolveTypeName): Deleted.
+ * runtime/JSScope.h:
+ (JSC::makeType): Deleted.
+ (JSC::needsVarInjectionChecks): Deleted.
+ (JSC::ResolveOp::ResolveOp): Deleted.
+ (JSC::ResolveModeAndType::ResolveModeAndType): Deleted.
+ (JSC::ResolveModeAndType::mode): Deleted.
+ (JSC::ResolveModeAndType::type): Deleted.
+ (JSC::ResolveModeAndType::operand): Deleted.
+ * runtime/JSSegmentedVariableObject.cpp:
+ (JSC::JSSegmentedVariableObject::findVariableIndex):
+ (JSC::JSSegmentedVariableObject::addVariables):
+ * runtime/JSSegmentedVariableObject.h:
+ * runtime/JSSymbolTableObject.h:
+ (JSC::symbolTablePut):
+ * runtime/JSType.h:
+ * runtime/PutPropertySlot.h:
+ (JSC::PutPropertySlot::PutPropertySlot):
+ (JSC::PutPropertySlot::isCacheablePut):
+ (JSC::PutPropertySlot::isCacheableSetter):
+ (JSC::PutPropertySlot::isCacheableCustom):
+ (JSC::PutPropertySlot::isInitialization):
+ (JSC::PutPropertySlot::cachedOffset):
+ * runtime/SymbolTable.h:
+ * tests/stress/global-lexical-let-no-rhs.js: Added.
+ (assert):
+ (foo):
+ * tests/stress/global-lexical-redeclare-variable.js: Added.
+ (globalFunction):
+ (globalClass):
+ (assert):
+ (assertExpectations):
+ (assertProperError):
+ * tests/stress/global-lexical-redefine-const.js: Added.
+ * tests/stress/global-lexical-var-injection.js: Added.
+ (assert):
+ (baz):
+ * tests/stress/global-lexical-variable-tdz.js: Added.
+ * tests/stress/global-lexical-variable-unresolved-property.js: Added.
+ * tests/stress/global-lexical-variable-with-statement.js: Added.
+ (assert):
+ (shouldThrowInvalidConstAssignment):
+ (makeObj):
+ * tests/stress/multiple-files-tests: Added.
+ * tests/stress/multiple-files-tests/global-lexical-redeclare-variable: Added.
+ * tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fifth.js: Added.
+ * tests/stress/multiple-files-tests/global-lexical-redeclare-variable/first.js: Added.
+ * tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fourth.js: Added.
+ * tests/stress/multiple-files-tests/global-lexical-redeclare-variable/second.js: Added.
+ * tests/stress/multiple-files-tests/global-lexical-redeclare-variable/sixth.js: Added.
+ * tests/stress/multiple-files-tests/global-lexical-redeclare-variable/third.js: Added.
+ * tests/stress/multiple-files-tests/global-lexical-redefine-const: Added.
+ * tests/stress/multiple-files-tests/global-lexical-redefine-const/first.js: Added.
+ (assert):
+ (shouldThrowInvalidConstAssignment):
+ * tests/stress/multiple-files-tests/global-lexical-redefine-const/second.js: Added.
+ (foo):
+ (bar):
+ (baz):
+ * tests/stress/multiple-files-tests/global-lexical-variable-tdz: Added.
+ * tests/stress/multiple-files-tests/global-lexical-variable-tdz/first.js: Added.
+ (assert):
+ (shouldThrowTDZ):
+ (foo):
+ (bar):
+ * tests/stress/multiple-files-tests/global-lexical-variable-tdz/second.js: Added.
+ * tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property: Added.
+ * tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/first.js: Added.
+ (assert):
+ (shouldThrowTDZ):
+ (foo):
+ * tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/second.js: Added.
+
</ins><span class="cx"> 2015-09-03 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> RepatchBuffer should be stateless
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -778,6 +778,7 @@
</span><span class="cx"> <ClCompile Include="..\runtime\JSFunction.cpp" />
</span><span class="cx"> <ClCompile Include="..\runtime\JSGlobalObject.cpp" />
</span><span class="cx"> <ClCompile Include="..\runtime\JSGlobalObjectFunctions.cpp" />
</span><ins>+ <ClCompile Include="..\runtime\JSGlobalLexicalEnvironment.cpp" />
</ins><span class="cx"> <ClCompile Include="..\runtime\JSInternalPromise.cpp" />
</span><span class="cx"> <ClCompile Include="..\runtime\JSInternalPromiseConstructor.cpp" />
</span><span class="cx"> <ClCompile Include="..\runtime\JSInternalPromiseDeferred.cpp" />
</span><span class="lines">@@ -1570,6 +1571,7 @@
</span><span class="cx"> <ClInclude Include="..\runtime\GenericOffset.h" />
</span><span class="cx"> <ClInclude Include="..\runtime\GenericTypedArrayView.h" />
</span><span class="cx"> <ClInclude Include="..\runtime\GenericTypedArrayViewInlines.h" />
</span><ins>+ <ClInclude Include="..\runtime\GetPutInfo.h" />
</ins><span class="cx"> <ClInclude Include="..\runtime\GetterSetter.h" />
</span><span class="cx"> <ClInclude Include="..\runtime\Identifier.h" />
</span><span class="cx"> <ClInclude Include="..\runtime\IndexingHeader.h" />
</span><span class="lines">@@ -1629,6 +1631,7 @@
</span><span class="cx"> <ClInclude Include="..\runtime\JSGenericTypedArrayViewPrototypeInlines.h" />
</span><span class="cx"> <ClInclude Include="..\runtime\JSGlobalObject.h" />
</span><span class="cx"> <ClInclude Include="..\runtime\JSGlobalObjectFunctions.h" />
</span><ins>+ <ClInclude Include="..\runtime\JSGlobalLexicalEnvironment.h" />
</ins><span class="cx"> <ClInclude Include="..\runtime\JSJob.h" />
</span><span class="cx"> <ClInclude Include="..\runtime\JSInt16Array.h" />
</span><span class="cx"> <ClInclude Include="..\runtime\JSInt32Array.h" />
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -717,6 +717,9 @@
</span><span class="cx"> <ClCompile Include="..\runtime\JSGlobalObjectFunctions.cpp">
</span><span class="cx"> <Filter>runtime</Filter>
</span><span class="cx"> </ClCompile>
</span><ins>+ <ClCompile Include="..\runtime\JSGlobalLexicalEnvironment.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
</ins><span class="cx"> <ClCompile Include="..\runtime\JSJob.cpp">
</span><span class="cx"> <Filter>runtime</Filter>
</span><span class="cx"> </ClCompile>
</span><span class="lines">@@ -2757,6 +2760,9 @@
</span><span class="cx"> <ClInclude Include="..\runtime\FunctionRareData.h">
</span><span class="cx"> <Filter>runtime</Filter>
</span><span class="cx"> </ClInclude>
</span><ins>+ <ClInclude Include="..\runtime\GetPutInfo.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
</ins><span class="cx"> <ClInclude Include="..\runtime\GetterSetter.h">
</span><span class="cx"> <Filter>runtime</Filter>
</span><span class="cx"> </ClInclude>
</span><span class="lines">@@ -2865,6 +2871,9 @@
</span><span class="cx"> <ClInclude Include="..\runtime\JSGlobalObjectFunctions.h">
</span><span class="cx"> <Filter>runtime</Filter>
</span><span class="cx"> </ClInclude>
</span><ins>+ <ClInclude Include="..\runtime\JSGlobalLexicalEnvironment.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
</ins><span class="cx"> <ClInclude Include="..\runtime\JSJob.h">
</span><span class="cx"> <Filter>runtime</Filter>
</span><span class="cx"> </ClInclude>
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -1033,6 +1033,9 @@
</span><span class="cx">                 70ECA6071AFDBEA200449739 /* TemplateRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */; };
</span><span class="cx">                 70ECA6081AFDBEA200449739 /* TemplateRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6031AFDBEA200449739 /* TemplateRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 70ECA6091AFDBEA200449739 /* TemplateRegistryKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 796465681B952FF0003059EE /* GetPutInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */; };
+                797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 79EE0BFF1B4AFB85000385C9 /* VariableEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79EE0BFD1B4AFB85000385C9 /* VariableEnvironment.cpp */; };
</span><span class="cx">                 79EE0C001B4AFB85000385C9 /* VariableEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 7B0247551B8682DD00542440 /* WASMConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B0247521B8682D500542440 /* WASMConstants.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2855,6 +2858,9 @@
</span><span class="cx">                 70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateRegistry.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 70ECA6031AFDBEA200449739 /* TemplateRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistry.h; sourceTree = "<group>"; };
</span><span class="cx">                 70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistryKey.h; sourceTree = "<group>"; };
</span><ins>+                796465681B952FF0003059EE /* GetPutInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetPutInfo.h; sourceTree = "<group>"; };
+                797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalLexicalEnvironment.cpp; sourceTree = "<group>"; };
+                797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalLexicalEnvironment.h; sourceTree = "<group>"; };
</ins><span class="cx">                 79EE0BFD1B4AFB85000385C9 /* VariableEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableEnvironment.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableEnvironment.h; sourceTree = "<group>"; };
</span><span class="cx">                 7B0247521B8682D500542440 /* WASMConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMConstants.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -4655,6 +4661,7 @@
</span><span class="cx">                                 0FE050131AA9091100D33B33 /* GenericOffset.h */,
</span><span class="cx">                                 0F2B66B217B6B5AB00A7AE3F /* GenericTypedArrayView.h */,
</span><span class="cx">                                 0F2B66B317B6B5AB00A7AE3F /* GenericTypedArrayViewInlines.h */,
</span><ins>+                                796465681B952FF0003059EE /* GetPutInfo.h */,
</ins><span class="cx">                                 BC02E9B80E184545000F9297 /* GetterSetter.cpp */,
</span><span class="cx">                                 BC337BDE0E1AF0B80076918A /* GetterSetter.h */,
</span><span class="cx">                                 933A349D038AE80F008635CE /* Identifier.cpp */,
</span><span class="lines">@@ -4752,6 +4759,8 @@
</span><span class="cx">                                 0F2B66C817B6B5AB00A7AE3F /* JSGenericTypedArrayViewPrototypeInlines.h */,
</span><span class="cx">                                 14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */,
</span><span class="cx">                                 A8E894330CD0603F00367179 /* JSGlobalObject.h */,
</span><ins>+                                797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */,
+                                797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */,
</ins><span class="cx">                                 A59455901824744700CC3843 /* JSGlobalObjectDebuggable.cpp */,
</span><span class="cx">                                 A59455911824744700CC3843 /* JSGlobalObjectDebuggable.h */,
</span><span class="cx">                                 BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */,
</span><span class="lines">@@ -5892,6 +5901,8 @@
</span><span class="cx">                                 A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
</span><span class="cx">                                 0F898F321B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h in Headers */,
</span><span class="cx">                                 86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
</span><ins>+                                7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */,
+                                797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */,
</ins><span class="cx">                                 0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */,
</span><span class="cx">                                 52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */,
</span><span class="cx">                                 FE4D55B81AE716CA0052E459 /* IterationStatus.h in Headers */,
</span><span class="lines">@@ -7348,6 +7359,7 @@
</span><span class="cx">                                 0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */,
</span><span class="cx">                                 147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
</span><span class="cx">                                 0F6B1CC918641DF800845D97 /* ArityCheckFailReturnThunks.cpp in Sources */,
</span><ins>+                                797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */,
</ins><span class="cx">                                 E3794E751B77EB97005543AE /* ModuleAnalyzer.cpp in Sources */,
</span><span class="cx">                                 0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */,
</span><span class="cx">                                 86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> #include "DFGWorklist.h"
</span><span class="cx"> #include "Debugger.h"
</span><span class="cx"> #include "FunctionExecutableDump.h"
</span><ins>+#include "GetPutInfo.h"
</ins><span class="cx"> #include "InlineCallFrame.h"
</span><span class="cx"> #include "Interpreter.h"
</span><span class="cx"> #include "JIT.h"
</span><span class="lines">@@ -1518,20 +1519,18 @@
</span><span class="cx"> int r0 = (++it)->u.operand;
</span><span class="cx"> int scope = (++it)->u.operand;
</span><span class="cx"> int id0 = (++it)->u.operand;
</span><del>- ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand);
</del><ins>+ ResolveType resolveType = static_cast<ResolveType>((++it)->u.operand);
</ins><span class="cx"> int depth = (++it)->u.operand;
</span><ins>+ void* pointer = (++it)->u.pointer;
</ins><span class="cx"> printLocationAndOp(out, exec, location, it, "resolve_scope");
</span><del>- out.printf("%s, %s, %s, %u<%s|%s>, %d", registerName(r0).data(), registerName(scope).data(), idName(id0, identifier(id0)).data(),
- modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
- depth);
- ++it;
</del><ins>+ out.printf("%s, %s, %s, <%s>, %d, %p", registerName(r0).data(), registerName(scope).data(), idName(id0, identifier(id0)).data(), resolveTypeName(resolveType), depth, pointer);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case op_get_from_scope: {
</span><span class="cx"> int r0 = (++it)->u.operand;
</span><span class="cx"> int r1 = (++it)->u.operand;
</span><span class="cx"> int id0 = (++it)->u.operand;
</span><del>- ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand);
</del><ins>+ GetPutInfo getPutInfo = GetPutInfo((++it)->u.operand);
</ins><span class="cx"> ++it; // Structure
</span><span class="cx"> int operand = (++it)->u.operand; // Operand
</span><span class="cx"> printLocationAndOp(out, exec, location, it, "get_from_scope");
</span><span class="lines">@@ -1540,7 +1539,7 @@
</span><span class="cx"> out.print(", anonymous");
</span><span class="cx"> else
</span><span class="cx"> out.print(", ", idName(id0, identifier(id0)));
</span><del>- out.print(", ", modeAndType.operand(), "<", resolveModeName(modeAndType.mode()), "|", resolveTypeName(modeAndType.type()), ">, ", operand);
</del><ins>+ out.print(", ", getPutInfo.operand(), "<", resolveModeName(getPutInfo.resolveMode()), "|", resolveTypeName(getPutInfo.resolveType()), "|", initializationModeName(getPutInfo.initializationMode()), ">, ", operand);
</ins><span class="cx"> dumpValueProfiling(out, it, hasPrintedProfiling);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="lines">@@ -1548,7 +1547,7 @@
</span><span class="cx"> int r0 = (++it)->u.operand;
</span><span class="cx"> int id0 = (++it)->u.operand;
</span><span class="cx"> int r1 = (++it)->u.operand;
</span><del>- ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand);
</del><ins>+ GetPutInfo getPutInfo = GetPutInfo((++it)->u.operand);
</ins><span class="cx"> ++it; // Structure
</span><span class="cx"> int operand = (++it)->u.operand; // Operand
</span><span class="cx"> printLocationAndOp(out, exec, location, it, "put_to_scope");
</span><span class="lines">@@ -1557,7 +1556,7 @@
</span><span class="cx"> out.print(", anonymous");
</span><span class="cx"> else
</span><span class="cx"> out.print(", ", idName(id0, identifier(id0)));
</span><del>- out.print(", ", registerName(r1), ", ", modeAndType.operand(), "<", resolveModeName(modeAndType.mode()), "|", resolveTypeName(modeAndType.type()), ">, <structure>, ", operand);
</del><ins>+ out.print(", ", registerName(r1), ", ", getPutInfo.operand(), "<", resolveModeName(getPutInfo.resolveMode()), "|", resolveTypeName(getPutInfo.resolveType()), "|", initializationModeName(getPutInfo.initializationMode()), ">, <structure>, ", operand);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case op_get_from_arguments: {
</span><span class="lines">@@ -1971,11 +1970,13 @@
</span><span class="cx"> RELEASE_ASSERT(type != LocalClosureVar);
</span><span class="cx"> int localScopeDepth = pc[5].u.operand;
</span><span class="cx">
</span><del>- ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, type);
</del><ins>+ ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, type, NotInitialization);
</ins><span class="cx"> instructions[i + 4].u.operand = op.type;
</span><span class="cx"> instructions[i + 5].u.operand = op.depth;
</span><span class="cx"> if (op.lexicalEnvironment)
</span><span class="cx"> instructions[i + 6].u.symbolTable.set(*vm(), ownerExecutable, op.lexicalEnvironment->symbolTable());
</span><ins>+ else if (JSScope* constantScope = JSScope::constantScopeForCodeBlock(op.type, this))
+ instructions[i + 6].u.jsCell.set(*vm(), ownerExecutable, constantScope);
</ins><span class="cx"> else
</span><span class="cx"> instructions[i + 6].u.pointer = nullptr;
</span><span class="cx"> break;
</span><span class="lines">@@ -1987,22 +1988,23 @@
</span><span class="cx"> profile->m_bytecodeOffset = i;
</span><span class="cx"> instructions[i + opLength - 1] = profile;
</span><span class="cx">
</span><del>- // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
</del><ins>+ // get_from_scope dst, scope, id, GetPutInfo, Structure, Operand
</ins><span class="cx">
</span><span class="cx"> int localScopeDepth = pc[5].u.operand;
</span><span class="cx"> instructions[i + 5].u.pointer = nullptr;
</span><span class="cx">
</span><del>- ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
- if (modeAndType.type() == LocalClosureVar) {
- instructions[i + 4] = ResolveModeAndType(modeAndType.mode(), ClosureVar).operand();
</del><ins>+ GetPutInfo getPutInfo = GetPutInfo(pc[4].u.operand);
+ ASSERT(getPutInfo.initializationMode() == NotInitialization);
+ if (getPutInfo.resolveType() == LocalClosureVar) {
+ instructions[i + 4] = GetPutInfo(getPutInfo.resolveMode(), ClosureVar, getPutInfo.initializationMode()).operand();
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> const Identifier& ident = identifier(pc[3].u.operand);
</span><del>- ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, modeAndType.type());
</del><ins>+ ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, getPutInfo.resolveType(), NotInitialization);
</ins><span class="cx">
</span><del>- instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
- if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks)
</del><ins>+ instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), op.type, getPutInfo.initializationMode()).operand();
+ if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks || op.type == GlobalLexicalVar || op.type == GlobalLexicalVarWithVarInjectionChecks)
</ins><span class="cx"> instructions[i + 5].u.watchpointSet = op.watchpointSet;
</span><span class="cx"> else if (op.structure)
</span><span class="cx"> instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
</span><span class="lines">@@ -2011,9 +2013,9 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case op_put_to_scope: {
</span><del>- // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
- ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
- if (modeAndType.type() == LocalClosureVar) {
</del><ins>+ // put_to_scope scope, id, value, GetPutInfo, Structure, Operand
+ GetPutInfo getPutInfo = GetPutInfo(pc[4].u.operand);
+ if (getPutInfo.resolveType() == LocalClosureVar) {
</ins><span class="cx"> // Only do watching if the property we're putting to is not anonymous.
</span><span class="cx"> if (static_cast<unsigned>(pc[2].u.operand) != UINT_MAX) {
</span><span class="cx"> int symbolTableIndex = pc[5].u.operand;
</span><span class="lines">@@ -2033,10 +2035,10 @@
</span><span class="cx"> const Identifier& ident = identifier(pc[2].u.operand);
</span><span class="cx"> int localScopeDepth = pc[5].u.operand;
</span><span class="cx"> instructions[i + 5].u.pointer = nullptr;
</span><del>- ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Put, modeAndType.type());
</del><ins>+ ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Put, getPutInfo.resolveType(), getPutInfo.initializationMode());
</ins><span class="cx">
</span><del>- instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
- if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks)
</del><ins>+ instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), op.type, getPutInfo.initializationMode()).operand();
+ if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks || op.type == GlobalLexicalVar || op.type == GlobalLexicalVarWithVarInjectionChecks)
</ins><span class="cx"> instructions[i + 5].u.watchpointSet = op.watchpointSet;
</span><span class="cx"> else if (op.type == ClosureVar || op.type == ClosureVarWithVarInjectionChecks) {
</span><span class="cx"> if (op.watchpointSet)
</span><span class="lines">@@ -2067,7 +2069,7 @@
</span><span class="cx"> ResolveType type = static_cast<ResolveType>(pc[5].u.operand);
</span><span class="cx"> // Even though type profiling may be profiling either a Get or a Put, we can always claim a Get because
</span><span class="cx"> // we're abstractly "read"ing from a JSScope.
</span><del>- ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, type);
</del><ins>+ ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, type, NotInitialization);
</ins><span class="cx">
</span><span class="cx"> if (op.type == ClosureVar)
</span><span class="cx"> symbolTable = op.lexicalEnvironment->symbolTable();
</span><span class="lines">@@ -2621,9 +2623,9 @@
</span><span class="cx"> }
</span><span class="cx"> case op_get_from_scope:
</span><span class="cx"> case op_put_to_scope: {
</span><del>- ResolveModeAndType modeAndType =
- ResolveModeAndType(curInstruction[4].u.operand);
- if (modeAndType.type() == GlobalVar || modeAndType.type() == GlobalVarWithVarInjectionChecks || modeAndType.type() == LocalClosureVar)
</del><ins>+ GetPutInfo getPutInfo = GetPutInfo(curInstruction[4].u.operand);
+ if (getPutInfo.resolveType() == GlobalVar || getPutInfo.resolveType() == GlobalVarWithVarInjectionChecks
+ || getPutInfo.resolveType() == LocalClosureVar || getPutInfo.resolveType() == GlobalLexicalVar || getPutInfo.resolveType() == GlobalLexicalVarWithVarInjectionChecks)
</ins><span class="cx"> continue;
</span><span class="cx"> WriteBarrierBase<Structure>& structure = curInstruction[5].u.structure;
</span><span class="cx"> if (!structure || Heap::isMarked(structure.get()))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeEvalCodeCacheh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/EvalCodeCache.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/EvalCodeCache.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/bytecode/EvalCodeCache.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx">
</span><span class="cx"> #include "Executable.h"
</span><span class="cx"> #include "JSGlobalObject.h"
</span><ins>+#include "JSScope.h"
</ins><span class="cx"> #include "Options.h"
</span><span class="cx"> #include "SourceCode.h"
</span><span class="cx"> #include <wtf/HashMap.h>
</span><span class="lines">@@ -74,15 +75,18 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- ALWAYS_INLINE bool isCacheable(bool inStrictContext, const String& evalSource, JSScope* scope) const
</del><ins>+ ALWAYS_INLINE bool isCacheableScope(JSScope* scope)
</ins><span class="cx"> {
</span><ins>+ return scope->isGlobalLexicalEnvironment() || scope->isFunctionNameScopeObject() || scope->isVarScope();
+ }
+
+ ALWAYS_INLINE bool isCacheable(bool inStrictContext, const String& evalSource, JSScope* scope)
+ {
</ins><span class="cx"> // If eval() is called and it has access to a lexical scope, we can't soundly cache it.
</span><span class="cx"> // If the eval() only has access to the "var" scope, then we can cache it.
</span><span class="cx"> return !inStrictContext
</span><span class="cx"> && evalSource.length() < Options::maximumEvalCacheableSourceLength()
</span><del>- && scope->begin()->isVariableObject()
- && !scope->isLexicalScope()
- && !scope->isCatchScope();
</del><ins>+ && isCacheableScope(scope);
</ins><span class="cx"> }
</span><span class="cx"> static const int maxCacheEntries = 64;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeSpeculatedTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -86,7 +86,7 @@
</span><span class="cx"> static const SpeculatedType SpecMisc = 0x30000000; // It's definitely either a boolean, Null, or Undefined.
</span><span class="cx"> static const SpeculatedType SpecHeapTop = 0x3bbfffff; // It can be any of the above, except for SpecInt52.
</span><span class="cx"> static const SpeculatedType SpecEmpty = 0x40000000; // It's definitely an empty value marker.
</span><del>-static const SpeculatedType SpecBytecodeTop = 0x7bbfffff; // It can be any of the above, except for SpecInt52.
</del><ins>+static const SpeculatedType SpecBytecodeTop = 0x7bbfffff; // It can be any of the above, except for SpecInt52. This is (SpecHeapTop | SpecEmpty).
</ins><span class="cx"> static const SpeculatedType SpecFullTop = 0x7fffffff; // It can be any of the above plus anything the DFG chooses.
</span><span class="cx">
</span><span class="cx"> typedef bool (*SpeculatedTypeChecker)(SpeculatedType);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -490,6 +490,9 @@
</span><span class="cx"> void setVariableDeclarations(const VariableEnvironment& environment) { m_varDeclarations = environment; }
</span><span class="cx"> const VariableEnvironment& variableDeclarations() const { return m_varDeclarations; }
</span><span class="cx">
</span><ins>+ void setLexicalDeclarations(const VariableEnvironment& environment) { m_lexicalDeclarations = environment; }
+ const VariableEnvironment& lexicalDeclarations() const { return m_lexicalDeclarations; }
+
</ins><span class="cx"> static void visitChildren(JSCell*, SlotVisitor&);
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="lines">@@ -499,6 +502,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> VariableEnvironment m_varDeclarations;
</span><ins>+ VariableEnvironment m_lexicalDeclarations;
</ins><span class="cx">
</span><span class="cx"> public:
</span><span class="cx"> static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -70,22 +70,25 @@
</span><span class="cx"> if (m_needToInitializeArguments)
</span><span class="cx"> initializeVariable(variable(propertyNames().arguments), m_argumentsRegister);
</span><span class="cx">
</span><del>- // For ModuleCode, we already instantiated the environment for the lexical variables.
- if (m_codeType != ModuleCode)
- pushLexicalScope(m_scopeNode, true);
-
</del><span class="cx"> {
</span><span class="cx"> RefPtr<RegisterID> temp = newTemporary();
</span><del>- RefPtr<RegisterID> globalScope = m_topMostScope;
</del><ins>+ RefPtr<RegisterID> globalScope;
</ins><span class="cx"> for (auto functionPair : m_functionsToInitialize) {
</span><span class="cx"> FunctionMetadataNode* metadata = functionPair.first;
</span><span class="cx"> FunctionVariableType functionType = functionPair.second;
</span><span class="cx"> emitNewFunction(temp.get(), metadata);
</span><span class="cx"> if (functionType == NormalFunctionVariable)
</span><del>- initializeVariable(variable(metadata->ident()) , temp.get());
- else if (functionType == GlobalFunctionVariable)
- emitPutToScope(globalScope.get(), Variable(metadata->ident()), temp.get(), ThrowIfNotFound);
- else
</del><ins>+ initializeVariable(variable(metadata->ident()), temp.get());
+ else if (functionType == GlobalFunctionVariable) {
+ if (!globalScope) {
+ // We know this will resolve to the global object because our parser/global initialization code
+ // doesn't allow let/const/class variables to have the same names as functions.
+ RefPtr<RegisterID> globalObjectScope = emitResolveScope(nullptr, Variable(metadata->ident()));
+ globalScope = newBlockScopeVariable();
+ emitMove(globalScope.get(), globalObjectScope.get());
+ }
+ emitPutToScope(globalScope.get(), Variable(metadata->ident()), temp.get(), ThrowIfNotFound, NotInitialization);
+ } else
</ins><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -172,6 +175,11 @@
</span><span class="cx"> RELEASE_ASSERT(entry.value.isVar());
</span><span class="cx"> }
</span><span class="cx"> codeBlock->setVariableDeclarations(programNode->varDeclarations());
</span><ins>+ codeBlock->setLexicalDeclarations(programNode->lexicalVariables());
+ // Even though this program may have lexical variables that go under TDZ, when linking the get_from_scope/put_to_scope
+ // operations we emit we will have ResolveTypes that implictly do TDZ checks. Therefore, we don't need
+ // additional TDZ checks on top of those. This is why we can omit pushing programNode->lexicalVariables()
+ // to the TDZ stack.
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode, const VariableEnvironment* parentScopeTDZVariables)
</span><span class="lines">@@ -318,7 +326,7 @@
</span><span class="cx"> instructions().append(m_lexicalEnvironmentRegister->index());
</span><span class="cx"> instructions().append(UINT_MAX);
</span><span class="cx"> instructions().append(virtualRegisterForArgument(1 + i).offset());
</span><del>- instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
</del><ins>+ instructions().append(GetPutInfo(ThrowIfNotFound, LocalClosureVar, NotInitialization).operand());
</ins><span class="cx"> instructions().append(symbolTableConstantIndex);
</span><span class="cx"> instructions().append(offset.offset());
</span><span class="cx"> }
</span><span class="lines">@@ -365,7 +373,7 @@
</span><span class="cx"> instructions().append(m_lexicalEnvironmentRegister->index());
</span><span class="cx"> instructions().append(addConstant(ident));
</span><span class="cx"> instructions().append(virtualRegisterForArgument(1 + i).offset());
</span><del>- instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
</del><ins>+ instructions().append(GetPutInfo(ThrowIfNotFound, LocalClosureVar, NotInitialization).operand());
</ins><span class="cx"> instructions().append(symbolTableConstantIndex);
</span><span class="cx"> instructions().append(offset.offset());
</span><span class="cx"> }
</span><span class="lines">@@ -467,6 +475,8 @@
</span><span class="cx"> // because a function's default parameter ExpressionNodes will use temporary registers.
</span><span class="cx"> m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false));
</span><span class="cx"> initializeDefaultParameterValuesAndSetupFunctionScopeStack(parameters, functionNode, functionSymbolTable, symbolTableConstantIndex, captures);
</span><ins>+
+ pushLexicalScope(m_scopeNode, true);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode, const VariableEnvironment* parentScopeTDZVariables)
</span><span class="lines">@@ -504,6 +514,8 @@
</span><span class="cx"> codeBlock->adoptVariables(variables);
</span><span class="cx">
</span><span class="cx"> m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false));
</span><ins>+
+ pushLexicalScope(m_scopeNode, true);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode, const VariableEnvironment* parentScopeTDZVariables)
</span><span class="lines">@@ -725,7 +737,7 @@
</span><span class="cx"> ASSERT(parameters.hasDefaultParameterValues());
</span><span class="cx"> Variable var = variable(valuesToMoveIntoVars[i].first);
</span><span class="cx"> RegisterID* scope = emitResolveScope(nullptr, var);
</span><del>- emitPutToScope(scope, var, valuesToMoveIntoVars[i].second.get(), DoNotThrowIfNotFound);
</del><ins>+ emitPutToScope(scope, var, valuesToMoveIntoVars[i].second.get(), DoNotThrowIfNotFound, NotInitialization);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (!parameters.hasDefaultParameterValues()) {
</span><span class="lines">@@ -1760,7 +1772,7 @@
</span><span class="cx"> SymbolTableEntry entry = symbolTable->get(locker, identifier.impl());
</span><span class="cx"> RELEASE_ASSERT(!entry.isNull());
</span><span class="cx"> RegisterID* transitionValue = pair.first;
</span><del>- emitPutToScope(loopScope, variableForLocalEntry(identifier, entry, loopSymbolTable->index(), true), transitionValue, DoNotThrowIfNotFound);
</del><ins>+ emitPutToScope(loopScope, variableForLocalEntry(identifier, entry, loopSymbolTable->index(), true), transitionValue, DoNotThrowIfNotFound, NotInitialization);
</ins><span class="cx"> transitionValue->deref();
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -1979,12 +1991,12 @@
</span><span class="cx"> case VarKind::Invalid: {
</span><span class="cx"> m_codeBlock->addPropertyAccessInstruction(instructions().size());
</span><span class="cx">
</span><del>- // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
</del><ins>+ // get_from_scope dst, scope, id, GetPutInfo, Structure, Operand
</ins><span class="cx"> UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
</span><span class="cx"> instructions().append(kill(dst));
</span><span class="cx"> instructions().append(scope->index());
</span><span class="cx"> instructions().append(addConstant(variable.ident()));
</span><del>- instructions().append(ResolveModeAndType(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType()).operand());
</del><ins>+ instructions().append(GetPutInfo(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType(), NotInitialization).operand());
</ins><span class="cx"> instructions().append(localScopeDepth());
</span><span class="cx"> instructions().append(variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
</span><span class="cx"> instructions().append(profile);
</span><span class="lines">@@ -1994,7 +2006,7 @@
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Variable& variable, RegisterID* value, ResolveMode resolveMode)
</del><ins>+RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Variable& variable, RegisterID* value, ResolveMode resolveMode, InitializationMode initializationMode)
</ins><span class="cx"> {
</span><span class="cx"> switch (variable.offset().kind()) {
</span><span class="cx"> case VarKind::Stack:
</span><span class="lines">@@ -2012,7 +2024,7 @@
</span><span class="cx"> case VarKind::Invalid: {
</span><span class="cx"> m_codeBlock->addPropertyAccessInstruction(instructions().size());
</span><span class="cx">
</span><del>- // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
</del><ins>+ // put_to_scope scope, id, value, GetPutInfo, Structure, Operand
</ins><span class="cx"> emitOpcode(op_put_to_scope);
</span><span class="cx"> instructions().append(scope->index());
</span><span class="cx"> instructions().append(addConstant(variable.ident()));
</span><span class="lines">@@ -2020,11 +2032,11 @@
</span><span class="cx"> ScopeOffset offset;
</span><span class="cx"> if (variable.offset().isScope()) {
</span><span class="cx"> offset = variable.offset().scopeOffset();
</span><del>- instructions().append(ResolveModeAndType(resolveMode, LocalClosureVar).operand());
</del><ins>+ instructions().append(GetPutInfo(resolveMode, LocalClosureVar, initializationMode).operand());
</ins><span class="cx"> instructions().append(variable.symbolTableConstantIndex());
</span><span class="cx"> } else {
</span><span class="cx"> ASSERT(resolveType() != LocalClosureVar);
</span><del>- instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
</del><ins>+ instructions().append(GetPutInfo(resolveMode, resolveType(), initializationMode).operand());
</ins><span class="cx"> instructions().append(localScopeDepth());
</span><span class="cx"> }
</span><span class="cx"> instructions().append(!!offset ? offset.offset() : 0);
</span><span class="lines">@@ -2038,7 +2050,7 @@
</span><span class="cx"> {
</span><span class="cx"> RELEASE_ASSERT(variable.offset().kind() != VarKind::Invalid);
</span><span class="cx"> RegisterID* scope = emitResolveScope(nullptr, variable);
</span><del>- return emitPutToScope(scope, variable, value, ThrowIfNotFound);
</del><ins>+ return emitPutToScope(scope, variable, value, ThrowIfNotFound, NotInitialization);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
</span><span class="lines">@@ -3277,7 +3289,7 @@
</span><span class="cx"> ASSERT_UNUSED(numVars, m_codeBlock->m_numVars == static_cast<int>(numVars + 1)); // Should have only created one new "var" for the function name scope.
</span><span class="cx"> bool shouldTreatAsLexicalVariable = isStrictMode();
</span><span class="cx"> Variable functionVar = variableForLocalEntry(property, m_symbolTableStack.last().m_symbolTable->get(property.impl()), m_symbolTableStack.last().m_symbolTableConstantIndex, shouldTreatAsLexicalVariable);
</span><del>- emitPutToScope(m_symbolTableStack.last().m_scope, functionVar, callee, ThrowIfNotFound);
</del><ins>+ emitPutToScope(m_symbolTableStack.last().m_scope, functionVar, callee, ThrowIfNotFound, NotInitialization);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void BytecodeGenerator::pushScopedControlFlowContext()
</span><span class="lines">@@ -3303,7 +3315,7 @@
</span><span class="cx"> Variable exceptionVar = variable(property);
</span><span class="cx"> RELEASE_ASSERT(exceptionVar.isResolved());
</span><span class="cx"> RefPtr<RegisterID> scope = emitResolveScope(nullptr, exceptionVar);
</span><del>- emitPutToScope(scope.get(), exceptionVar, exceptionValue, ThrowIfNotFound);
</del><ins>+ emitPutToScope(scope.get(), exceptionVar, exceptionValue, ThrowIfNotFound, NotInitialization);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void BytecodeGenerator::emitPopCatchScope(VariableEnvironment& environment)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -546,7 +546,7 @@
</span><span class="cx"> RegisterID* emitResolveConstantLocal(RegisterID* dst, const Variable&);
</span><span class="cx"> RegisterID* emitResolveScope(RegisterID* dst, const Variable&);
</span><span class="cx"> RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable&, ResolveMode);
</span><del>- RegisterID* emitPutToScope(RegisterID* scope, const Variable&, RegisterID* value, ResolveMode);
</del><ins>+ RegisterID* emitPutToScope(RegisterID* scope, const Variable&, RegisterID* value, ResolveMode, InitializationMode);
</ins><span class="cx"> RegisterID* initializeVariable(const Variable&, RegisterID* value);
</span><span class="cx">
</span><span class="cx"> PassRefPtr<Label> emitLabel(Label*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -1053,7 +1053,7 @@
</span><span class="cx"> }
</span><span class="cx"> RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
</span><span class="cx"> if (!var.isReadOnly()) {
</span><del>- generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
</del><ins>+ generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, NotInitialization);
</ins><span class="cx"> generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1253,7 +1253,7 @@
</span><span class="cx">
</span><span class="cx"> emitIncOrDec(generator, value.get(), m_operator);
</span><span class="cx"> if (!var.isReadOnly()) {
</span><del>- generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
</del><ins>+ generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, NotInitialization);
</ins><span class="cx"> generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
</span><span class="cx"> }
</span><span class="cx"> return generator.moveToDestinationIfNeeded(dst, value.get());
</span><span class="lines">@@ -1777,7 +1777,7 @@
</span><span class="cx"> RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
</span><span class="cx"> RegisterID* returnResult = result.get();
</span><span class="cx"> if (!var.isReadOnly()) {
</span><del>- returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound);
</del><ins>+ returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound, NotInitialization);
</ins><span class="cx"> generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
</span><span class="cx"> }
</span><span class="cx"> return returnResult;
</span><span class="lines">@@ -1834,7 +1834,8 @@
</span><span class="cx"> generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx"> RegisterID* returnResult = result.get();
</span><span class="cx"> if (!isReadOnly) {
</span><del>- returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</del><ins>+ returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound,
+ m_assignmentContext == AssignmentContext::ConstDeclarationStatement || m_assignmentContext == AssignmentContext::DeclarationStatement ? Initialization : NotInitialization);
</ins><span class="cx"> generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2029,7 +2030,7 @@
</span><span class="cx"> } else {
</span><span class="cx"> RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
</span><span class="cx"> RefPtr<RegisterID> value = generator.emitLoad(nullptr, jsUndefined());
</span><del>- generator.emitPutToScope(scope.get(), var, value.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</del><ins>+ generator.emitPutToScope(scope.get(), var, value.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, Initialization);
</ins><span class="cx"> generator.emitProfileType(value.get(), var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2235,7 +2236,7 @@
</span><span class="cx"> generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx"> RegisterID* scope = generator.emitResolveScope(nullptr, var);
</span><span class="cx"> generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>- generator.emitPutToScope(scope, var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</del><ins>+ generator.emitPutToScope(scope, var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, NotInitialization);
</ins><span class="cx"> }
</span><span class="cx"> generator.emitProfileType(propertyName, var, m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
</span><span class="cx"> return;
</span><span class="lines">@@ -2456,7 +2457,7 @@
</span><span class="cx"> generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx"> RegisterID* scope = generator.emitResolveScope(nullptr, var);
</span><span class="cx"> generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>- generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</del><ins>+ generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, NotInitialization);
</ins><span class="cx"> }
</span><span class="cx"> generator.emitProfileType(value, var, m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
</span><span class="cx"> } else if (m_lexpr->isDotAccessorNode()) {
</span><span class="lines">@@ -3330,7 +3331,8 @@
</span><span class="cx"> generator.emitReadOnlyExceptionIfNeeded(var);
</span><span class="cx"> return;
</span><span class="cx"> }
</span><del>- generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</del><ins>+ generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound,
+ m_bindingContext == AssignmentContext::ConstDeclarationStatement || m_bindingContext == AssignmentContext::DeclarationStatement ? Initialization : NotInitialization);
</ins><span class="cx"> generator.emitProfileType(value, var, divotStart(), divotEnd());
</span><span class="cx"> if (m_bindingContext == AssignmentContext::DeclarationStatement || m_bindingContext == AssignmentContext::ConstDeclarationStatement)
</span><span class="cx"> generator.liftTDZCheckIfPossible(var);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -184,12 +184,17 @@
</span><span class="cx"> return m_scope->isGlobalObject();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool DebuggerScope::isFunctionOrEvalScope() const
</del><ins>+bool DebuggerScope::isGlobalLexicalEnvironment() const
</ins><span class="cx"> {
</span><ins>+ return m_scope->isGlobalLexicalEnvironment();
+}
+
+bool DebuggerScope::isClosureScope() const
+{
</ins><span class="cx"> // In the current debugger implementation, every function or eval will create an
</span><span class="cx"> // lexical environment object. Hence, a lexical environment object implies a
</span><span class="cx"> // function or eval scope.
</span><del>- return m_scope->isActivationObject() && !isCatchScope();
</del><ins>+ return m_scope->isVarScope() || m_scope->isLexicalScope();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> JSValue DebuggerScope::caughtValue(ExecState* exec) const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/DebuggerScope.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerScope.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerScope.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -89,7 +89,8 @@
</span><span class="cx"> bool isFunctionNameScope() const;
</span><span class="cx"> bool isWithScope() const;
</span><span class="cx"> bool isGlobalScope() const;
</span><del>- bool isFunctionOrEvalScope() const;
</del><ins>+ bool isClosureScope() const;
+ bool isGlobalLexicalEnvironment() const;
</ins><span class="cx">
</span><span class="cx"> JSValue caughtValue(ExecState*) const;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -2365,9 +2365,12 @@
</span><span class="cx"> case GetGlobalVar:
</span><span class="cx"> forNode(node).makeHeapTop();
</span><span class="cx"> break;
</span><ins>+ case GetGlobalLexicalVariable:
+ forNode(node).makeBytecodeTop();
+ break;
</ins><span class="cx">
</span><span class="cx"> case VarInjectionWatchpoint:
</span><del>- case PutGlobalVar:
</del><ins>+ case PutGlobalVariable:
</ins><span class="cx"> case NotifyWrite:
</span><span class="cx"> break;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -3819,6 +3819,7 @@
</span><span class="cx"> int dst = currentInstruction[1].u.operand;
</span><span class="cx"> ResolveType resolveType = static_cast<ResolveType>(currentInstruction[4].u.operand);
</span><span class="cx"> unsigned depth = currentInstruction[5].u.operand;
</span><ins>+ int scope = currentInstruction[2].u.operand;
</ins><span class="cx">
</span><span class="cx"> // get_from_scope and put_to_scope depend on this watchpoint forcing OSR exit, so they don't add their own watchpoints.
</span><span class="cx"> if (needsVarInjectionChecks(resolveType))
</span><span class="lines">@@ -3829,14 +3830,19 @@
</span><span class="cx"> case GlobalVar:
</span><span class="cx"> case GlobalPropertyWithVarInjectionChecks:
</span><span class="cx"> case GlobalVarWithVarInjectionChecks:
</span><del>- set(VirtualRegister(dst), weakJSConstant(m_inlineStackTop->m_codeBlock->globalObject()));
- if (resolveType == GlobalPropertyWithVarInjectionChecks || resolveType == GlobalVarWithVarInjectionChecks)
- addToGraph(Phantom, getDirect(m_inlineStackTop->remapOperand(VirtualRegister(currentInstruction[2].u.operand))));
</del><ins>+ case GlobalLexicalVar:
+ case GlobalLexicalVarWithVarInjectionChecks: {
+ JSScope* constantScope = JSScope::constantScopeForCodeBlock(resolveType, m_inlineStackTop->m_codeBlock);
+ RELEASE_ASSERT(constantScope);
+ RELEASE_ASSERT(static_cast<JSScope*>(currentInstruction[6].u.pointer) == constantScope);
+ set(VirtualRegister(dst), weakJSConstant(constantScope));
+ addToGraph(Phantom, get(VirtualRegister(scope)));
</ins><span class="cx"> break;
</span><ins>+ }
</ins><span class="cx"> case LocalClosureVar:
</span><span class="cx"> case ClosureVar:
</span><span class="cx"> case ClosureVarWithVarInjectionChecks: {
</span><del>- Node* localBase = get(VirtualRegister(currentInstruction[2].u.operand));
</del><ins>+ Node* localBase = get(VirtualRegister(scope));
</ins><span class="cx"> addToGraph(Phantom, localBase); // OSR exit cannot handle resolve_scope on a DCE'd scope.
</span><span class="cx">
</span><span class="cx"> // We have various forms of constant folding here. This is necessary to avoid
</span><span class="lines">@@ -3860,6 +3866,13 @@
</span><span class="cx"> set(VirtualRegister(dst), localBase);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><ins>+ case UnresolvedProperty:
+ case UnresolvedPropertyWithVarInjectionChecks: {
+ addToGraph(Phantom, get(VirtualRegister(scope)));
+ addToGraph(ForceOSRExit);
+ set(VirtualRegister(dst), addToGraph(JSConstant, OpInfo(m_constantNull)));
+ break;
+ }
</ins><span class="cx"> case Dynamic:
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> break;
</span><span class="lines">@@ -3872,16 +3885,16 @@
</span><span class="cx"> int scope = currentInstruction[2].u.operand;
</span><span class="cx"> unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand];
</span><span class="cx"> UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber];
</span><del>- ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</del><ins>+ ResolveType resolveType = GetPutInfo(currentInstruction[4].u.operand).resolveType();
</ins><span class="cx">
</span><span class="cx"> Structure* structure = 0;
</span><span class="cx"> WatchpointSet* watchpoints = 0;
</span><span class="cx"> uintptr_t operand;
</span><span class="cx"> {
</span><span class="cx"> ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
</span><del>- if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks)
</del><ins>+ if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks)
</ins><span class="cx"> watchpoints = currentInstruction[5].u.watchpointSet;
</span><del>- else
</del><ins>+ else if (resolveType != UnresolvedProperty && resolveType != UnresolvedPropertyWithVarInjectionChecks)
</ins><span class="cx"> structure = currentInstruction[5].u.structure.get();
</span><span class="cx"> operand = reinterpret_cast<uintptr_t>(currentInstruction[6].u.pointer);
</span><span class="cx"> }
</span><span class="lines">@@ -3910,13 +3923,16 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case GlobalVar:
</span><del>- case GlobalVarWithVarInjectionChecks: {
</del><ins>+ case GlobalVarWithVarInjectionChecks:
+ case GlobalLexicalVar:
+ case GlobalLexicalVarWithVarInjectionChecks: {
</ins><span class="cx"> addToGraph(Phantom, get(VirtualRegister(scope)));
</span><span class="cx"> WatchpointSet* watchpointSet;
</span><span class="cx"> ScopeOffset offset;
</span><ins>+ JSSegmentedVariableObject* scopeObject = jsCast<JSSegmentedVariableObject*>(JSScope::constantScopeForCodeBlock(resolveType, m_inlineStackTop->m_codeBlock));
</ins><span class="cx"> {
</span><del>- ConcurrentJITLocker locker(globalObject->symbolTable()->m_lock);
- SymbolTableEntry entry = globalObject->symbolTable()->get(locker, uid);
</del><ins>+ ConcurrentJITLocker locker(scopeObject->symbolTable()->m_lock);
+ SymbolTableEntry entry = scopeObject->symbolTable()->get(locker, uid);
</ins><span class="cx"> watchpointSet = entry.watchpointSet();
</span><span class="cx"> offset = entry.scopeOffset();
</span><span class="cx"> }
</span><span class="lines">@@ -3961,7 +3977,7 @@
</span><span class="cx"> // reading are added, we might access freed memory if we do variableAt().
</span><span class="cx"> WriteBarrier<Unknown>* pointer = bitwise_cast<WriteBarrier<Unknown>*>(operand);
</span><span class="cx">
</span><del>- ASSERT(globalObject->findVariableIndex(pointer) == offset);
</del><ins>+ ASSERT(scopeObject->findVariableIndex(pointer) == offset);
</ins><span class="cx">
</span><span class="cx"> JSValue value = pointer->get();
</span><span class="cx"> if (value) {
</span><span class="lines">@@ -3972,7 +3988,15 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> SpeculatedType prediction = getPrediction();
</span><del>- set(VirtualRegister(dst), addToGraph(GetGlobalVar, OpInfo(operand), OpInfo(prediction)));
</del><ins>+ NodeType nodeType;
+ if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks)
+ nodeType = GetGlobalVar;
+ else
+ nodeType = GetGlobalLexicalVariable;
+ Node* value = addToGraph(nodeType, OpInfo(operand), OpInfo(prediction));
+ if (resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks)
+ addToGraph(CheckNotEmpty, value);
+ set(VirtualRegister(dst), value);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case LocalClosureVar:
</span><span class="lines">@@ -4002,6 +4026,14 @@
</span><span class="cx"> addToGraph(GetClosureVar, OpInfo(operand), OpInfo(prediction), scopeNode));
</span><span class="cx"> break;
</span><span class="cx"> }
</span><ins>+ case UnresolvedProperty:
+ case UnresolvedPropertyWithVarInjectionChecks: {
+ addToGraph(ForceOSRExit);
+ Node* scopeNode = get(VirtualRegister(scope));
+ addToGraph(Phantom, scopeNode);
+ set(VirtualRegister(dst), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
+ break;
+ }
</ins><span class="cx"> case Dynamic:
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> break;
</span><span class="lines">@@ -4015,7 +4047,8 @@
</span><span class="cx"> if (identifierNumber != UINT_MAX)
</span><span class="cx"> identifierNumber = m_inlineStackTop->m_identifierRemap[identifierNumber];
</span><span class="cx"> unsigned value = currentInstruction[3].u.operand;
</span><del>- ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</del><ins>+ GetPutInfo getPutInfo = GetPutInfo(currentInstruction[4].u.operand);
+ ResolveType resolveType = getPutInfo.resolveType();
</ins><span class="cx"> UniquedStringImpl* uid;
</span><span class="cx"> if (identifierNumber != UINT_MAX)
</span><span class="cx"> uid = m_graph.identifiers()[identifierNumber];
</span><span class="lines">@@ -4027,9 +4060,9 @@
</span><span class="cx"> uintptr_t operand;
</span><span class="cx"> {
</span><span class="cx"> ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
</span><del>- if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar)
</del><ins>+ if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar || resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks)
</ins><span class="cx"> watchpoints = currentInstruction[5].u.watchpointSet;
</span><del>- else
</del><ins>+ else if (resolveType != UnresolvedProperty && resolveType != UnresolvedPropertyWithVarInjectionChecks)
</ins><span class="cx"> structure = currentInstruction[5].u.structure.get();
</span><span class="cx"> operand = reinterpret_cast<uintptr_t>(currentInstruction[6].u.pointer);
</span><span class="cx"> }
</span><span class="lines">@@ -4056,14 +4089,23 @@
</span><span class="cx"> addToGraph(Phantom, get(VirtualRegister(scope)));
</span><span class="cx"> break;
</span><span class="cx"> }
</span><ins>+ case GlobalLexicalVar:
+ case GlobalLexicalVarWithVarInjectionChecks:
</ins><span class="cx"> case GlobalVar:
</span><span class="cx"> case GlobalVarWithVarInjectionChecks: {
</span><ins>+ if (getPutInfo.initializationMode() != Initialization && (resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks)) {
+ SpeculatedType prediction = SpecEmpty;
+ Node* value = addToGraph(GetGlobalLexicalVariable, OpInfo(operand), OpInfo(prediction));
+ addToGraph(CheckNotEmpty, value);
+ }
+
+ JSSegmentedVariableObject* scopeObject = jsCast<JSSegmentedVariableObject*>(JSScope::constantScopeForCodeBlock(resolveType, m_inlineStackTop->m_codeBlock));
</ins><span class="cx"> if (watchpoints) {
</span><del>- SymbolTableEntry entry = globalObject->symbolTable()->get(uid);
</del><ins>+ SymbolTableEntry entry = scopeObject->symbolTable()->get(uid);
</ins><span class="cx"> ASSERT_UNUSED(entry, watchpoints == entry.watchpointSet());
</span><span class="cx"> }
</span><span class="cx"> Node* valueNode = get(VirtualRegister(value));
</span><del>- addToGraph(PutGlobalVar, OpInfo(operand), weakJSConstant(globalObject), valueNode);
</del><ins>+ addToGraph(PutGlobalVariable, OpInfo(operand), weakJSConstant(scopeObject), valueNode);
</ins><span class="cx"> if (watchpoints && watchpoints->state() != IsInvalidated) {
</span><span class="cx"> // Must happen after the store. See comment for GetGlobalVar.
</span><span class="cx"> addToGraph(NotifyWrite, OpInfo(watchpoints));
</span><span class="lines">@@ -4086,6 +4128,13 @@
</span><span class="cx"> }
</span><span class="cx"> break;
</span><span class="cx"> }
</span><ins>+ case UnresolvedProperty:
+ case UnresolvedPropertyWithVarInjectionChecks: {
+ addToGraph(ForceOSRExit);
+ Node* scopeNode = get(VirtualRegister(scope));
+ addToGraph(Phantom, scopeNode);
+ break;
+ }
</ins><span class="cx"> case Dynamic:
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -220,7 +220,7 @@
</span><span class="cx"> return CanCompileAndInline;
</span><span class="cx">
</span><span class="cx"> case op_put_to_scope: {
</span><del>- ResolveType resolveType = ResolveModeAndType(pc[4].u.operand).type();
</del><ins>+ ResolveType resolveType = GetPutInfo(pc[4].u.operand).resolveType();
</ins><span class="cx"> // If we're writing to a readonly property we emit a Dynamic put that
</span><span class="cx"> // the DFG can't currently handle.
</span><span class="cx"> if (resolveType == Dynamic)
</span><span class="lines">@@ -230,7 +230,7 @@
</span><span class="cx">
</span><span class="cx"> case op_resolve_scope: {
</span><span class="cx"> // We don't compile 'catch' or 'with', so there's no point in compiling variable resolution within them.
</span><del>- ResolveType resolveType = ResolveModeAndType(pc[4].u.operand).type();
</del><ins>+ ResolveType resolveType = static_cast<ResolveType>(pc[4].u.operand);
</ins><span class="cx"> if (resolveType == Dynamic)
</span><span class="cx"> return CannotCompile;
</span><span class="cx"> return CanCompileAndInline;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -841,11 +841,12 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case GetGlobalVar:
</span><ins>+ case GetGlobalLexicalVariable:
</ins><span class="cx"> read(AbstractHeap(Absolute, node->variablePointer()));
</span><span class="cx"> def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->variablePointer())), LazyNode(node));
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- case PutGlobalVar:
</del><ins>+ case PutGlobalVariable:
</ins><span class="cx"> write(AbstractHeap(Absolute, node->variablePointer()));
</span><span class="cx"> def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->variablePointer())), LazyNode(node->child2().node()));
</span><span class="cx"> return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -105,7 +105,8 @@
</span><span class="cx"> case GetClosureVar:
</span><span class="cx"> case PutClosureVar:
</span><span class="cx"> case GetGlobalVar:
</span><del>- case PutGlobalVar:
</del><ins>+ case GetGlobalLexicalVariable:
+ case PutGlobalVariable:
</ins><span class="cx"> case VarInjectionWatchpoint:
</span><span class="cx"> case CheckCell:
</span><span class="cx"> case CheckNotEmpty:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -1191,7 +1191,7 @@
</span><span class="cx"> DFG_CRASH(m_graph, node, "Unexpected node during fixup");
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- case PutGlobalVar: {
</del><ins>+ case PutGlobalVariable: {
</ins><span class="cx"> fixEdge<CellUse>(node->child1());
</span><span class="cx"> speculateForBarrier(node->child2());
</span><span class="cx"> break;
</span><span class="lines">@@ -1336,6 +1336,7 @@
</span><span class="cx"> case PhantomLocal:
</span><span class="cx"> case GetLocalUnlinked:
</span><span class="cx"> case GetGlobalVar:
</span><ins>+ case GetGlobalLexicalVariable:
</ins><span class="cx"> case NotifyWrite:
</span><span class="cx"> case VarInjectionWatchpoint:
</span><span class="cx"> case Call:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -186,7 +186,7 @@
</span><span class="cx"> // @# - a NodeIndex referencing a prior node in the graph.
</span><span class="cx"> // arg# - an argument number.
</span><span class="cx"> // id# - the index in the CodeBlock of an identifier { if codeBlock is passed to dump(), the string representation is displayed }.
</span><del>- // var# - the index of a var on the global object, used by GetGlobalVar/PutGlobalVar operations.
</del><ins>+ // var# - the index of a var on the global object, used by GetGlobalVar/GetGlobalLexicalVariable/PutGlobalVariable operations.
</ins><span class="cx"> out.printf("% 4d:<%c%u:", (int)node->index(), mustGenerate ? '!' : ' ', refCount);
</span><span class="cx"> if (node->hasResult() && node->hasVirtualRegister() && node->virtualRegister().isValid())
</span><span class="cx"> out.print(node->virtualRegister());
</span><span class="lines">@@ -222,7 +222,7 @@
</span><span class="cx"> if (node->hasDirectArgumentsOffset())
</span><span class="cx"> out.print(comma, node->capturedArgumentsOffset());
</span><span class="cx"> if (node->hasRegisterPointer())
</span><del>- out.print(comma, "global", globalObjectFor(node->origin.semantic)->findVariableIndex(node->variablePointer()), "(", RawPointer(node->variablePointer()), ")");
</del><ins>+ out.print(comma, "global", "(", RawPointer(node->variablePointer()), ")");
</ins><span class="cx"> if (node->hasIdentifier())
</span><span class="cx"> out.print(comma, "id", node->identifierNumber(), "{", identifiers()[node->identifierNumber()], "}");
</span><span class="cx"> if (node->hasPromotedLocationDescriptor())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -989,7 +989,7 @@
</span><span class="cx">
</span><span class="cx"> bool hasRegisterPointer()
</span><span class="cx"> {
</span><del>- return op() == GetGlobalVar || op() == PutGlobalVar;
</del><ins>+ return op() == GetGlobalVar || op() == GetGlobalLexicalVariable || op() == PutGlobalVariable;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> WriteBarrier<Unknown>* variablePointer()
</span><span class="lines">@@ -1262,6 +1262,7 @@
</span><span class="cx"> case RegExpExec:
</span><span class="cx"> case RegExpTest:
</span><span class="cx"> case GetGlobalVar:
</span><ins>+ case GetGlobalLexicalVariable:
</ins><span class="cx"> return true;
</span><span class="cx"> default:
</span><span class="cx"> return false;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -207,7 +207,8 @@
</span><span class="cx"> macro(GetClosureVar, NodeResultJS) \
</span><span class="cx"> macro(PutClosureVar, NodeMustGenerate) \
</span><span class="cx"> macro(GetGlobalVar, NodeResultJS) \
</span><del>- macro(PutGlobalVar, NodeMustGenerate) \
</del><ins>+ macro(GetGlobalLexicalVariable, NodeResultJS) \
+ macro(PutGlobalVariable, NodeMustGenerate) \
</ins><span class="cx"> macro(NotifyWrite, NodeMustGenerate) \
</span><span class="cx"> macro(VarInjectionWatchpoint, NodeMustGenerate) \
</span><span class="cx"> macro(CheckCell, NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -200,6 +200,7 @@
</span><span class="cx"> case CallForwardVarargs:
</span><span class="cx"> case ConstructForwardVarargs:
</span><span class="cx"> case GetGlobalVar:
</span><ins>+ case GetGlobalLexicalVariable:
</ins><span class="cx"> case GetClosureVar:
</span><span class="cx"> case GetFromArguments: {
</span><span class="cx"> changed |= setPrediction(node->getHeapPrediction());
</span><span class="lines">@@ -660,7 +661,7 @@
</span><span class="cx"> case VarInjectionWatchpoint:
</span><span class="cx"> case Phantom:
</span><span class="cx"> case Check:
</span><del>- case PutGlobalVar:
</del><ins>+ case PutGlobalVariable:
</ins><span class="cx"> case CheckWatchdogTimer:
</span><span class="cx"> case Unreachable:
</span><span class="cx"> case LoopHint:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -196,7 +196,8 @@
</span><span class="cx"> case GetClosureVar:
</span><span class="cx"> case PutClosureVar:
</span><span class="cx"> case GetGlobalVar:
</span><del>- case PutGlobalVar:
</del><ins>+ case GetGlobalLexicalVariable:
+ case PutGlobalVariable:
</ins><span class="cx"> case VarInjectionWatchpoint:
</span><span class="cx"> case CheckCell:
</span><span class="cx"> case CheckBadCell:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -4110,6 +4110,7 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case GetGlobalLexicalVariable:
</ins><span class="cx"> case GetGlobalVar: {
</span><span class="cx"> GPRTemporary resultPayload(this);
</span><span class="cx"> GPRTemporary resultTag(this);
</span><span class="lines">@@ -4122,7 +4123,7 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case PutGlobalVar: {
</del><ins>+ case PutGlobalVariable: {
</ins><span class="cx"> JSValueOperand value(this, node->child2());
</span><span class="cx">
</span><span class="cx"> // FIXME: if we happen to have a spare register - and _ONLY_ if we happen to have
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -4105,6 +4105,7 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case GetGlobalLexicalVariable:
</ins><span class="cx"> case GetGlobalVar: {
</span><span class="cx"> GPRTemporary result(this);
</span><span class="cx">
</span><span class="lines">@@ -4114,7 +4115,7 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case PutGlobalVar: {
</del><ins>+ case PutGlobalVariable: {
</ins><span class="cx"> JSValueOperand value(this, node->child2());
</span><span class="cx">
</span><span class="cx"> m_jit.store64(value.gpr(), node->variablePointer());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStoreBarrierInsertionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -273,7 +273,7 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case PutGlobalVar: {
</del><ins>+ case PutGlobalVariable: {
</ins><span class="cx"> considerBarrier(m_node->child1(), m_node->child2());
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -77,7 +77,8 @@
</span><span class="cx"> case GetSetter:
</span><span class="cx"> case PutByOffset:
</span><span class="cx"> case GetGlobalVar:
</span><del>- case PutGlobalVar:
</del><ins>+ case GetGlobalLexicalVariable:
+ case PutGlobalVariable:
</ins><span class="cx"> case ValueAdd:
</span><span class="cx"> case StrCat:
</span><span class="cx"> case ArithAdd:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -665,10 +665,11 @@
</span><span class="cx"> compileMultiPutByOffset();
</span><span class="cx"> break;
</span><span class="cx"> case GetGlobalVar:
</span><del>- compileGetGlobalVar();
</del><ins>+ case GetGlobalLexicalVariable:
+ compileGetGlobalVariable();
</ins><span class="cx"> break;
</span><del>- case PutGlobalVar:
- compilePutGlobalVar();
</del><ins>+ case PutGlobalVariable:
+ compilePutGlobalVariable();
</ins><span class="cx"> break;
</span><span class="cx"> case NotifyWrite:
</span><span class="cx"> compileNotifyWrite();
</span><span class="lines">@@ -4056,12 +4057,12 @@
</span><span class="cx"> m_out.appendTo(continuation, lastNext);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void compileGetGlobalVar()
</del><ins>+ void compileGetGlobalVariable()
</ins><span class="cx"> {
</span><span class="cx"> setJSValue(m_out.load64(m_out.absolute(m_node->variablePointer())));
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void compilePutGlobalVar()
</del><ins>+ void compilePutGlobalVariable()
</ins><span class="cx"> {
</span><span class="cx"> m_out.store64(
</span><span class="cx"> lowJSValue(m_node->child2()), m_out.absolute(m_node->variablePointer()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSJavaScriptCallFramecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -99,8 +99,8 @@
</span><span class="cx"> for (DebuggerScope::iterator iter = scopeChain->begin(); iter != end; ++iter) {
</span><span class="cx"> DebuggerScope* scope = iter.get();
</span><span class="cx">
</span><del>- if (!foundLocalScope && scope->isFunctionOrEvalScope()) {
- // First function scope is the local scope, each successive one is a closure.
</del><ins>+ if (!foundLocalScope && scope->isClosureScope()) {
+ // First closure scope is the local scope, each successive one is a true closure.
</ins><span class="cx"> if (!index)
</span><span class="cx"> return jsNumber(JSJavaScriptCallFrame::LOCAL_SCOPE);
</span><span class="cx"> foundLocalScope = true;
</span><span class="lines">@@ -113,11 +113,16 @@
</span><span class="cx"> return jsNumber(JSJavaScriptCallFrame::FUNCTION_NAME_SCOPE);
</span><span class="cx"> if (scope->isWithScope())
</span><span class="cx"> return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE);
</span><ins>+ if (scope->isGlobalLexicalEnvironment()) {
+ // FIXME: We need a way to better describe this scope.
+ // It's currently best described as a "closure" scope.
+ return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
+ }
</ins><span class="cx"> if (scope->isGlobalScope()) {
</span><span class="cx"> ASSERT(++iter == end);
</span><span class="cx"> return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE);
</span><span class="cx"> }
</span><del>- ASSERT(scope->isFunctionOrEvalScope());
</del><ins>+ ASSERT(scope->isClosureScope());
</ins><span class="cx"> return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -757,7 +757,7 @@
</span><span class="cx"> {
</span><span class="cx"> SamplingScope samplingScope(this);
</span><span class="cx">
</span><del>- JSScope* scope = thisObj->globalObject();
</del><ins>+ JSScope* scope = thisObj->globalObject()->globalScope();
</ins><span class="cx"> VM& vm = *scope->vm();
</span><span class="cx">
</span><span class="cx"> ASSERT(!vm.exception());
</span><span class="lines">@@ -1142,7 +1142,6 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> }
</span><del>- ASSERT(!variableObject->isNameScopeObject());
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> JSObject* compileError = eval->prepareForExecution(callFrame, nullptr, scope, CodeForCall);
</span><span class="lines">@@ -1150,6 +1149,28 @@
</span><span class="cx"> return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
</span><span class="cx"> EvalCodeBlock* codeBlock = eval->codeBlock();
</span><span class="cx">
</span><ins>+ // We can't declare a "var"/"function" that overwrites a global "let"/"const"/"class" in a sloppy-mode eval.
+ if (variableObject->isGlobalObject() && !eval->isStrictMode() && (numVariables || numFunctions)) {
+ JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalObject*>(variableObject)->globalLexicalEnvironment();
+ for (unsigned i = 0; i < numVariables; ++i) {
+ const Identifier& ident = codeBlock->variable(i);
+ PropertySlot slot(globalLexicalEnvironment);
+ if (JSGlobalLexicalEnvironment::getOwnPropertySlot(globalLexicalEnvironment, callFrame, ident, slot)) {
+ return checkedReturn(callFrame->vm().throwException(callFrame,
+ createTypeError(callFrame, makeString("Can't create duplicate global variable in eval: '", String(ident.impl()), "'"))));
+ }
+ }
+
+ for (int i = 0; i < numFunctions; ++i) {
+ FunctionExecutable* function = codeBlock->functionDecl(i);
+ PropertySlot slot(globalLexicalEnvironment);
+ if (JSGlobalLexicalEnvironment::getOwnPropertySlot(globalLexicalEnvironment, callFrame, function->name(), slot)) {
+ return checkedReturn(callFrame->vm().throwException(callFrame,
+ createTypeError(callFrame, makeString("Can't create duplicate global variable in eval: '", String(function->name().impl()), "'"))));
+ }
+ }
+ }
+
</ins><span class="cx"> if (numVariables || numFunctions) {
</span><span class="cx"> BatchedTransitionOptimizer optimizer(vm, variableObject);
</span><span class="cx"> if (variableObject->next())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -670,11 +670,15 @@
</span><span class="cx"> void emitResolveClosure(int dst, int scope, bool needsVarInjectionChecks, unsigned depth);
</span><span class="cx"> void emitLoadWithStructureCheck(int scope, Structure** structureSlot);
</span><span class="cx"> void emitGetGlobalProperty(uintptr_t* operandSlot);
</span><del>- void emitGetGlobalVar(uintptr_t operand);
</del><ins>+#if USE(JSVALUE64)
+ void emitGetVarFromPointer(uintptr_t operand, GPRReg);
+#else
+ void emitGetVarFromPointer(uintptr_t operand, GPRReg tag, GPRReg payload);
+#endif
</ins><span class="cx"> void emitGetClosureVar(int scope, uintptr_t operand);
</span><span class="cx"> void emitPutGlobalProperty(uintptr_t* operandSlot, int value);
</span><span class="cx"> void emitNotifyWrite(WatchpointSet*);
</span><del>- void emitPutGlobalVar(uintptr_t operand, int value, WatchpointSet*);
</del><ins>+ void emitPutGlobalVariable(uintptr_t operand, int value, WatchpointSet*);
</ins><span class="cx"> void emitPutClosureVar(int scope, uintptr_t operand, int value, WatchpointSet*);
</span><span class="cx">
</span><span class="cx"> void emitInitRegister(int dst);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -1928,15 +1928,6 @@
</span><span class="cx"> return reinterpret_cast<char*>(result);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-EncodedJSValue JIT_OPERATION operationResolveScope(ExecState* exec, int32_t scopeReg, int32_t identifierIndex)
-{
- VM& vm = exec->vm();
- NativeCallFrameTracer tracer(&vm, exec);
- const Identifier& ident = exec->codeBlock()->identifier(identifierIndex);
- JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
- return JSValue::encode(JSScope::resolve(exec, scope, ident));
-}
-
</del><span class="cx"> EncodedJSValue JIT_OPERATION operationGetFromScope(ExecState* exec, Instruction* bytecodePC)
</span><span class="cx"> {
</span><span class="cx"> VM& vm = exec->vm();
</span><span class="lines">@@ -1946,29 +1937,30 @@
</span><span class="cx">
</span><span class="cx"> const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
</span><span class="cx"> JSObject* scope = jsCast<JSObject*>(exec->uncheckedR(pc[2].u.operand).jsValue());
</span><del>- ResolveModeAndType modeAndType(pc[4].u.operand);
</del><ins>+ GetPutInfo getPutInfo(pc[4].u.operand);
</ins><span class="cx">
</span><span class="cx"> PropertySlot slot(scope);
</span><span class="cx"> if (!scope->getPropertySlot(exec, ident, slot)) {
</span><del>- if (modeAndType.mode() == ThrowIfNotFound)
</del><ins>+ if (getPutInfo.resolveMode() == ThrowIfNotFound)
</ins><span class="cx"> vm.throwException(exec, createUndefinedVariableError(exec, ident));
</span><span class="cx"> return JSValue::encode(jsUndefined());
</span><span class="cx"> }
</span><span class="cx">
</span><del>- // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
- if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure(vm)->propertyAccessesAreCacheable()) {
- if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
- Structure* structure = scope->structure(vm);
- {
- ConcurrentJITLocker locker(codeBlock->m_lock);
- pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), structure);
- pc[6].u.operand = slot.cachedOffset();
- }
- structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
</del><ins>+ JSValue result = JSValue();
+ if (jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)) {
+ // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
+ result = slot.getValue(exec, ident);
+ if (result == jsTDZValue()) {
+ exec->vm().throwException(exec, createTDZError(exec));
+ return JSValue::encode(jsUndefined());
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- return JSValue::encode(slot.getValue(exec, ident));
</del><ins>+ CommonSlowPaths::tryCacheGetFromScopeGlobal(exec, vm, pc, scope, slot, ident);
+
+ if (!result)
+ result = slot.getValue(exec, ident);
+ return JSValue::encode(result);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void JIT_OPERATION operationPutToScope(ExecState* exec, Instruction* bytecodePC)
</span><span class="lines">@@ -1981,26 +1973,40 @@
</span><span class="cx"> const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
</span><span class="cx"> JSObject* scope = jsCast<JSObject*>(exec->uncheckedR(pc[1].u.operand).jsValue());
</span><span class="cx"> JSValue value = exec->r(pc[3].u.operand).jsValue();
</span><del>- ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
- if (modeAndType.type() == LocalClosureVar) {
</del><ins>+ GetPutInfo getPutInfo = GetPutInfo(pc[4].u.operand);
+ if (getPutInfo.resolveType() == LocalClosureVar) {
</ins><span class="cx"> JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
</span><span class="cx"> environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
</span><span class="cx"> if (WatchpointSet* set = pc[5].u.watchpointSet)
</span><span class="cx"> set->touch("Executed op_put_scope<LocalClosureVar>");
</span><span class="cx"> return;
</span><span class="cx"> }
</span><del>- if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident)) {
</del><ins>+
+ bool hasProperty = scope->hasProperty(exec, ident);
+ if (hasProperty
+ && jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)
+ && getPutInfo.initializationMode() != Initialization) {
+ // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
+ PropertySlot slot(scope);
+ JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot);
+ if (slot.getValue(exec, ident) == jsTDZValue()) {
+ exec->vm().throwException(exec, createTDZError(exec));
+ return;
+ }
+ }
+
+ if (getPutInfo.resolveMode() == ThrowIfNotFound && !hasProperty) {
</ins><span class="cx"> exec->vm().throwException(exec, createUndefinedVariableError(exec, ident));
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- PutPropertySlot slot(scope, codeBlock->isStrictMode());
</del><ins>+ PutPropertySlot slot(scope, codeBlock->isStrictMode(), PutPropertySlot::UnknownContext, getPutInfo.initializationMode() == Initialization);
</ins><span class="cx"> scope->methodTable()->put(scope, exec, ident, value, slot);
</span><span class="cx">
</span><span class="cx"> if (exec->vm().exception())
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
</del><ins>+ CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, getPutInfo, slot, ident);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void JIT_OPERATION operationThrow(ExecState* exec, EncodedJSValue encodedExceptionValue)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -334,7 +334,6 @@
</span><span class="cx"> char* JIT_OPERATION operationSwitchCharWithUnknownKeyType(ExecState*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;
</span><span class="cx"> char* JIT_OPERATION operationSwitchImmWithUnknownKeyType(ExecState*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;
</span><span class="cx"> char* JIT_OPERATION operationSwitchStringWithUnknownKeyType(ExecState*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;
</span><del>-EncodedJSValue JIT_OPERATION operationResolveScope(ExecState*, int32_t scope, int32_t identifierIndex) WTF_INTERNAL;
</del><span class="cx"> EncodedJSValue JIT_OPERATION operationGetFromScope(ExecState*, Instruction* bytecodePC) WTF_INTERNAL;
</span><span class="cx"> void JIT_OPERATION operationPutToScope(ExecState*, Instruction* bytecodePC) WTF_INTERNAL;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx"> #include "SamplingTool.h"
</span><span class="cx"> #include "ScopedArguments.h"
</span><span class="cx"> #include "ScopedArgumentsTable.h"
</span><ins>+#include "SlowPathCall.h"
</ins><span class="cx"> #include <wtf/StringPrintStream.h>
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -695,14 +696,22 @@
</span><span class="cx"> case GlobalVar:
</span><span class="cx"> case GlobalPropertyWithVarInjectionChecks:
</span><span class="cx"> case GlobalVarWithVarInjectionChecks:
</span><ins>+ case GlobalLexicalVar:
+ case GlobalLexicalVarWithVarInjectionChecks: {
+ JSScope* constantScope = JSScope::constantScopeForCodeBlock(resolveType, m_codeBlock);
+ RELEASE_ASSERT(constantScope);
+ RELEASE_ASSERT(static_cast<JSScope*>(currentInstruction[6].u.pointer) == constantScope);
</ins><span class="cx"> emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><del>- move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
</del><ins>+ move(TrustedImmPtr(constantScope), regT0);
</ins><span class="cx"> emitPutVirtualRegister(dst);
</span><span class="cx"> break;
</span><ins>+ }
</ins><span class="cx"> case ClosureVar:
</span><span class="cx"> case ClosureVarWithVarInjectionChecks:
</span><span class="cx"> emitResolveClosure(dst, scope, needsVarInjectionChecks(resolveType), depth);
</span><span class="cx"> break;
</span><ins>+ case UnresolvedProperty:
+ case UnresolvedPropertyWithVarInjectionChecks:
</ins><span class="cx"> case Dynamic:
</span><span class="cx"> addSlowCase(jump());
</span><span class="cx"> break;
</span><span class="lines">@@ -713,16 +722,13 @@
</span><span class="cx">
</span><span class="cx"> void JIT::emitSlow_op_resolve_scope(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
</span><span class="cx"> {
</span><del>- int dst = currentInstruction[1].u.operand;
</del><span class="cx"> ResolveType resolveType = static_cast<ResolveType>(currentInstruction[4].u.operand);
</span><del>-
- if (resolveType == GlobalProperty || resolveType == GlobalVar || resolveType == ClosureVar)
</del><ins>+ if (resolveType == GlobalProperty || resolveType == GlobalVar || resolveType == ClosureVar || resolveType == GlobalLexicalVar)
</ins><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> linkSlowCase(iter);
</span><del>- int32_t scope = currentInstruction[2].u.operand;
- int32_t identifierIndex = currentInstruction[3].u.operand;
- callOperation(operationResolveScope, dst, scope, identifierIndex);
</del><ins>+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_resolve_scope);
+ slowPathCall.call();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void JIT::emitLoadWithStructureCheck(int scope, Structure** structureSlot)
</span><span class="lines">@@ -740,9 +746,9 @@
</span><span class="cx"> compileGetDirectOffset(regT0, regT0, regT1, regT2, KnownNotFinal);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void JIT::emitGetGlobalVar(uintptr_t operand)
</del><ins>+void JIT::emitGetVarFromPointer(uintptr_t operand, GPRReg reg)
</ins><span class="cx"> {
</span><del>- loadPtr(reinterpret_cast<void*>(operand), regT0);
</del><ins>+ loadPtr(reinterpret_cast<void*>(operand), reg);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void JIT::emitGetClosureVar(int scope, uintptr_t operand)
</span><span class="lines">@@ -755,7 +761,7 @@
</span><span class="cx"> {
</span><span class="cx"> int dst = currentInstruction[1].u.operand;
</span><span class="cx"> int scope = currentInstruction[2].u.operand;
</span><del>- ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</del><ins>+ ResolveType resolveType = GetPutInfo(currentInstruction[4].u.operand).resolveType();
</ins><span class="cx"> Structure** structureSlot = currentInstruction[5].u.structure.slot();
</span><span class="cx"> uintptr_t* operandSlot = reinterpret_cast<uintptr_t*>(&currentInstruction[6].u.pointer);
</span><span class="cx">
</span><span class="lines">@@ -767,14 +773,20 @@
</span><span class="cx"> break;
</span><span class="cx"> case GlobalVar:
</span><span class="cx"> case GlobalVarWithVarInjectionChecks:
</span><ins>+ case GlobalLexicalVar:
+ case GlobalLexicalVarWithVarInjectionChecks:
</ins><span class="cx"> emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><del>- emitGetGlobalVar(*operandSlot);
</del><ins>+ emitGetVarFromPointer(*operandSlot, regT0);
+ if (resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks) // TDZ check.
+ addSlowCase(branchTest64(Zero, regT0));
</ins><span class="cx"> break;
</span><span class="cx"> case ClosureVar:
</span><span class="cx"> case ClosureVarWithVarInjectionChecks:
</span><span class="cx"> emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><span class="cx"> emitGetClosureVar(scope, *operandSlot);
</span><span class="cx"> break;
</span><ins>+ case UnresolvedProperty:
+ case UnresolvedPropertyWithVarInjectionChecks:
</ins><span class="cx"> case Dynamic:
</span><span class="cx"> addSlowCase(jump());
</span><span class="cx"> break;
</span><span class="lines">@@ -788,14 +800,19 @@
</span><span class="cx"> void JIT::emitSlow_op_get_from_scope(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
</span><span class="cx"> {
</span><span class="cx"> int dst = currentInstruction[1].u.operand;
</span><del>- ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</del><ins>+ ResolveType resolveType = GetPutInfo(currentInstruction[4].u.operand).resolveType();
</ins><span class="cx">
</span><span class="cx"> if (resolveType == GlobalVar || resolveType == ClosureVar)
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> if (resolveType == GlobalProperty || resolveType == GlobalPropertyWithVarInjectionChecks)
</span><span class="cx"> linkSlowCase(iter);
</span><ins>+
+ if (resolveType == GlobalLexicalVarWithVarInjectionChecks) // Var injections check.
+ linkSlowCase(iter);
+
</ins><span class="cx"> linkSlowCase(iter);
</span><ins>+
</ins><span class="cx"> callOperation(WithProfile, operationGetFromScope, dst, currentInstruction);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -809,7 +826,7 @@
</span><span class="cx"> storePtr(regT2, BaseIndex(regT0, regT1, TimesEight, (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue)));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void JIT::emitPutGlobalVar(uintptr_t operand, int value, WatchpointSet* set)
</del><ins>+void JIT::emitPutGlobalVariable(uintptr_t operand, int value, WatchpointSet* set)
</ins><span class="cx"> {
</span><span class="cx"> emitGetVirtualRegister(value, regT0);
</span><span class="cx"> emitNotifyWrite(set);
</span><span class="lines">@@ -828,7 +845,8 @@
</span><span class="cx"> {
</span><span class="cx"> int scope = currentInstruction[1].u.operand;
</span><span class="cx"> int value = currentInstruction[3].u.operand;
</span><del>- ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</del><ins>+ GetPutInfo getPutInfo = GetPutInfo(currentInstruction[4].u.operand);
+ ResolveType resolveType = getPutInfo.resolveType();
</ins><span class="cx"> Structure** structureSlot = currentInstruction[5].u.structure.slot();
</span><span class="cx"> uintptr_t* operandSlot = reinterpret_cast<uintptr_t*>(&currentInstruction[6].u.pointer);
</span><span class="cx">
</span><span class="lines">@@ -841,10 +859,21 @@
</span><span class="cx"> break;
</span><span class="cx"> case GlobalVar:
</span><span class="cx"> case GlobalVarWithVarInjectionChecks:
</span><del>- emitWriteBarrier(m_codeBlock->globalObject(), value, ShouldFilterValue);
</del><ins>+ case GlobalLexicalVar:
+ case GlobalLexicalVarWithVarInjectionChecks: {
+ JSScope* constantScope = JSScope::constantScopeForCodeBlock(resolveType, m_codeBlock);
+ RELEASE_ASSERT(constantScope);
+ emitWriteBarrier(constantScope, value, ShouldFilterValue);
</ins><span class="cx"> emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><del>- emitPutGlobalVar(*operandSlot, value, currentInstruction[5].u.watchpointSet);
</del><ins>+ if (getPutInfo.initializationMode() != Initialization && (resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks)) {
+ // We need to do a TDZ check here because we can't always prove we need to emit TDZ checks statically.
+ emitGetVarFromPointer(*operandSlot, regT0);
+ addSlowCase(branchTest64(Zero, regT0));
+ }
+
+ emitPutGlobalVariable(*operandSlot, value, currentInstruction[5].u.watchpointSet);
</ins><span class="cx"> break;
</span><ins>+ }
</ins><span class="cx"> case LocalClosureVar:
</span><span class="cx"> case ClosureVar:
</span><span class="cx"> case ClosureVarWithVarInjectionChecks:
</span><span class="lines">@@ -852,6 +881,8 @@
</span><span class="cx"> emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><span class="cx"> emitPutClosureVar(scope, *operandSlot, value, currentInstruction[5].u.watchpointSet);
</span><span class="cx"> break;
</span><ins>+ case UnresolvedProperty:
+ case UnresolvedPropertyWithVarInjectionChecks:
</ins><span class="cx"> case Dynamic:
</span><span class="cx"> addSlowCase(jump());
</span><span class="cx"> break;
</span><span class="lines">@@ -860,15 +891,20 @@
</span><span class="cx">
</span><span class="cx"> void JIT::emitSlow_op_put_to_scope(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
</span><span class="cx"> {
</span><del>- ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</del><ins>+ GetPutInfo getPutInfo = GetPutInfo(currentInstruction[4].u.operand);
+ ResolveType resolveType = getPutInfo.resolveType();
</ins><span class="cx"> unsigned linkCount = 0;
</span><del>- if (resolveType != GlobalVar && resolveType != ClosureVar && resolveType != LocalClosureVar)
</del><ins>+ if (resolveType != GlobalVar && resolveType != ClosureVar && resolveType != LocalClosureVar && resolveType != GlobalLexicalVar)
</ins><span class="cx"> linkCount++;
</span><del>- if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar)
</del><ins>+ if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks
+ || resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks
+ || resolveType == LocalClosureVar)
</ins><span class="cx"> && currentInstruction[5].u.watchpointSet->state() != IsInvalidated)
</span><span class="cx"> linkCount++;
</span><span class="cx"> if (resolveType == GlobalProperty || resolveType == GlobalPropertyWithVarInjectionChecks)
</span><span class="cx"> linkCount++;
</span><ins>+ if (getPutInfo.initializationMode() != Initialization && (resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks)) // TDZ check.
+ linkCount++;
</ins><span class="cx"> if (!linkCount)
</span><span class="cx"> return;
</span><span class="cx"> while (linkCount--)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> #include "RepatchBuffer.h"
</span><span class="cx"> #include "ResultType.h"
</span><span class="cx"> #include "SamplingTool.h"
</span><ins>+#include "SlowPathCall.h"
</ins><span class="cx"> #include <wtf/StringPrintStream.h>
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -724,17 +725,25 @@
</span><span class="cx"> switch (resolveType) {
</span><span class="cx"> case GlobalProperty:
</span><span class="cx"> case GlobalVar:
</span><ins>+ case GlobalLexicalVar:
</ins><span class="cx"> case GlobalPropertyWithVarInjectionChecks:
</span><del>- case GlobalVarWithVarInjectionChecks:
</del><ins>+ case GlobalVarWithVarInjectionChecks:
+ case GlobalLexicalVarWithVarInjectionChecks: {
+ JSScope* constantScope = JSScope::constantScopeForCodeBlock(resolveType, m_codeBlock);
+ RELEASE_ASSERT(constantScope);
+ RELEASE_ASSERT(static_cast<JSScope*>(currentInstruction[6].u.pointer) == constantScope);
</ins><span class="cx"> emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><span class="cx"> move(TrustedImm32(JSValue::CellTag), regT1);
</span><del>- move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
</del><ins>+ move(TrustedImmPtr(constantScope), regT0);
</ins><span class="cx"> emitStore(dst, regT1, regT0);
</span><span class="cx"> break;
</span><ins>+ }
</ins><span class="cx"> case ClosureVar:
</span><span class="cx"> case ClosureVarWithVarInjectionChecks:
</span><span class="cx"> emitResolveClosure(dst, scope, needsVarInjectionChecks(resolveType), depth);
</span><span class="cx"> break;
</span><ins>+ case UnresolvedProperty:
+ case UnresolvedPropertyWithVarInjectionChecks:
</ins><span class="cx"> case Dynamic:
</span><span class="cx"> addSlowCase(jump());
</span><span class="cx"> break;
</span><span class="lines">@@ -745,16 +754,14 @@
</span><span class="cx">
</span><span class="cx"> void JIT::emitSlow_op_resolve_scope(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
</span><span class="cx"> {
</span><del>- int dst = currentInstruction[1].u.operand;
</del><span class="cx"> ResolveType resolveType = static_cast<ResolveType>(currentInstruction[4].u.operand);
</span><span class="cx">
</span><del>- if (resolveType == GlobalProperty || resolveType == GlobalVar || resolveType == ClosureVar)
</del><ins>+ if (resolveType == GlobalProperty || resolveType == GlobalVar || resolveType == ClosureVar || resolveType == GlobalLexicalVar)
</ins><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> linkSlowCase(iter);
</span><del>- int32_t scope = currentInstruction[2].u.operand;
- int32_t identifierIndex = currentInstruction[3].u.operand;
- callOperation(operationResolveScope, dst, scope, identifierIndex);
</del><ins>+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_resolve_scope);
+ slowPathCall.call();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void JIT::emitLoadWithStructureCheck(int scope, Structure** structureSlot)
</span><span class="lines">@@ -771,10 +778,10 @@
</span><span class="cx"> compileGetDirectOffset(regT2, regT1, regT0, regT3, KnownNotFinal);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void JIT::emitGetGlobalVar(uintptr_t operand)
</del><ins>+void JIT::emitGetVarFromPointer(uintptr_t operand, GPRReg tag, GPRReg payload)
</ins><span class="cx"> {
</span><del>- load32(reinterpret_cast<char*>(operand) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag), regT1);
- load32(reinterpret_cast<char*>(operand) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload), regT0);
</del><ins>+ load32(reinterpret_cast<char*>(operand) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag), tag);
+ load32(reinterpret_cast<char*>(operand) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload), payload);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void JIT::emitGetClosureVar(int scope, uintptr_t operand)
</span><span class="lines">@@ -788,7 +795,7 @@
</span><span class="cx"> {
</span><span class="cx"> int dst = currentInstruction[1].u.operand;
</span><span class="cx"> int scope = currentInstruction[2].u.operand;
</span><del>- ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</del><ins>+ ResolveType resolveType = GetPutInfo(currentInstruction[4].u.operand).resolveType();
</ins><span class="cx"> Structure** structureSlot = currentInstruction[5].u.structure.slot();
</span><span class="cx"> uintptr_t* operandSlot = reinterpret_cast<uintptr_t*>(&currentInstruction[6].u.pointer);
</span><span class="cx">
</span><span class="lines">@@ -800,14 +807,20 @@
</span><span class="cx"> break;
</span><span class="cx"> case GlobalVar:
</span><span class="cx"> case GlobalVarWithVarInjectionChecks:
</span><ins>+ case GlobalLexicalVar:
+ case GlobalLexicalVarWithVarInjectionChecks:
</ins><span class="cx"> emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><del>- emitGetGlobalVar(*operandSlot);
</del><ins>+ emitGetVarFromPointer(*operandSlot, regT1, regT0);
+ if (resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks) // TDZ check.
+ addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag)));
</ins><span class="cx"> break;
</span><span class="cx"> case ClosureVar:
</span><span class="cx"> case ClosureVarWithVarInjectionChecks:
</span><span class="cx"> emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><span class="cx"> emitGetClosureVar(scope, *operandSlot);
</span><span class="cx"> break;
</span><ins>+ case UnresolvedProperty:
+ case UnresolvedPropertyWithVarInjectionChecks:
</ins><span class="cx"> case Dynamic:
</span><span class="cx"> addSlowCase(jump());
</span><span class="cx"> break;
</span><span class="lines">@@ -821,11 +834,14 @@
</span><span class="cx"> void JIT::emitSlow_op_get_from_scope(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
</span><span class="cx"> {
</span><span class="cx"> int dst = currentInstruction[1].u.operand;
</span><del>- ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</del><ins>+ ResolveType resolveType = GetPutInfo(currentInstruction[4].u.operand).resolveType();
</ins><span class="cx">
</span><span class="cx"> if (resolveType == GlobalVar || resolveType == ClosureVar)
</span><span class="cx"> return;
</span><span class="cx">
</span><ins>+ if (resolveType == GlobalLexicalVarWithVarInjectionChecks) // Var Injections check.
+ linkSlowCase(iter);
+
</ins><span class="cx"> linkSlowCase(iter);
</span><span class="cx"> callOperation(WithProfile, operationGetFromScope, dst, currentInstruction);
</span><span class="cx"> }
</span><span class="lines">@@ -841,7 +857,7 @@
</span><span class="cx"> store32(regT2, BaseIndex(regT0, regT1, TimesEight, (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void JIT::emitPutGlobalVar(uintptr_t operand, int value, WatchpointSet* set)
</del><ins>+void JIT::emitPutGlobalVariable(uintptr_t operand, int value, WatchpointSet* set)
</ins><span class="cx"> {
</span><span class="cx"> emitLoad(value, regT1, regT0);
</span><span class="cx"> emitNotifyWrite(set);
</span><span class="lines">@@ -862,7 +878,8 @@
</span><span class="cx"> {
</span><span class="cx"> int scope = currentInstruction[1].u.operand;
</span><span class="cx"> int value = currentInstruction[3].u.operand;
</span><del>- ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</del><ins>+ GetPutInfo getPutInfo = GetPutInfo(currentInstruction[4].u.operand);
+ ResolveType resolveType = getPutInfo.resolveType();
</ins><span class="cx"> Structure** structureSlot = currentInstruction[5].u.structure.slot();
</span><span class="cx"> uintptr_t* operandSlot = reinterpret_cast<uintptr_t*>(&currentInstruction[6].u.pointer);
</span><span class="cx">
</span><span class="lines">@@ -875,10 +892,20 @@
</span><span class="cx"> break;
</span><span class="cx"> case GlobalVar:
</span><span class="cx"> case GlobalVarWithVarInjectionChecks:
</span><del>- emitWriteBarrier(m_codeBlock->globalObject(), value, ShouldFilterValue);
</del><ins>+ case GlobalLexicalVar:
+ case GlobalLexicalVarWithVarInjectionChecks: {
+ JSScope* constantScope = JSScope::constantScopeForCodeBlock(resolveType, m_codeBlock);
+ RELEASE_ASSERT(constantScope);
+ emitWriteBarrier(constantScope, value, ShouldFilterValue);
</ins><span class="cx"> emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><del>- emitPutGlobalVar(*operandSlot, value, currentInstruction[5].u.watchpointSet);
</del><ins>+ if (getPutInfo.initializationMode() != Initialization && (resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks)) {
+ // We need to do a TDZ check here because we can't always prove we need to emit TDZ checks statically.
+ emitGetVarFromPointer(*operandSlot, regT1, regT0);
+ addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag)));
+ }
+ emitPutGlobalVariable(*operandSlot, value, currentInstruction[5].u.watchpointSet);
</ins><span class="cx"> break;
</span><ins>+ }
</ins><span class="cx"> case LocalClosureVar:
</span><span class="cx"> case ClosureVar:
</span><span class="cx"> case ClosureVarWithVarInjectionChecks:
</span><span class="lines">@@ -886,6 +913,8 @@
</span><span class="cx"> emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><span class="cx"> emitPutClosureVar(scope, *operandSlot, value, currentInstruction[5].u.watchpointSet);
</span><span class="cx"> break;
</span><ins>+ case UnresolvedProperty:
+ case UnresolvedPropertyWithVarInjectionChecks:
</ins><span class="cx"> case Dynamic:
</span><span class="cx"> addSlowCase(jump());
</span><span class="cx"> break;
</span><span class="lines">@@ -894,13 +923,17 @@
</span><span class="cx">
</span><span class="cx"> void JIT::emitSlow_op_put_to_scope(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
</span><span class="cx"> {
</span><del>- ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</del><ins>+ GetPutInfo getPutInfo = GetPutInfo(currentInstruction[4].u.operand);
+ ResolveType resolveType = getPutInfo.resolveType();
</ins><span class="cx"> unsigned linkCount = 0;
</span><del>- if (resolveType != GlobalVar && resolveType != ClosureVar && resolveType != LocalClosureVar)
</del><ins>+ if (resolveType != GlobalVar && resolveType != ClosureVar && resolveType != LocalClosureVar && resolveType != GlobalLexicalVar)
</ins><span class="cx"> linkCount++;
</span><del>- if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar)
</del><ins>+ if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar
+ || resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks)
</ins><span class="cx"> && currentInstruction[5].u.watchpointSet->state() != IsInvalidated)
</span><span class="cx"> linkCount++;
</span><ins>+ if (getPutInfo.initializationMode() != Initialization && (resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks)) // TDZ check.
+ linkCount++;
</ins><span class="cx"> if (!linkCount)
</span><span class="cx"> return;
</span><span class="cx"> while (linkCount--)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntData.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -145,14 +145,19 @@
</span><span class="cx">
</span><span class="cx"> static_assert(GlobalProperty == 0, "LLInt assumes GlobalProperty ResultType is == 0");
</span><span class="cx"> static_assert(GlobalVar == 1, "LLInt assumes GlobalVar ResultType is == 1");
</span><del>- static_assert(ClosureVar == 2, "LLInt assumes ClosureVar ResultType is == 2");
- static_assert(LocalClosureVar == 3, "LLInt assumes LocalClosureVar ResultType is == 3");
- static_assert(GlobalPropertyWithVarInjectionChecks == 4, "LLInt assumes GlobalPropertyWithVarInjectionChecks ResultType is == 4");
- static_assert(GlobalVarWithVarInjectionChecks == 5, "LLInt assumes GlobalVarWithVarInjectionChecks ResultType is == 5");
- static_assert(ClosureVarWithVarInjectionChecks == 6, "LLInt assumes ClosureVarWithVarInjectionChecks ResultType is == 6");
- static_assert(Dynamic == 7, "LLInt assumes Dynamic ResultType is == 7");
</del><ins>+ static_assert(GlobalLexicalVar == 2, "LLInt assumes GlobalLexicalVar ResultType is == 2");
+ static_assert(ClosureVar == 3, "LLInt assumes ClosureVar ResultType is == 3");
+ static_assert(LocalClosureVar == 4, "LLInt assumes LocalClosureVar ResultType is == 4");
+ static_assert(GlobalPropertyWithVarInjectionChecks == 5, "LLInt assumes GlobalPropertyWithVarInjectionChecks ResultType is == 5");
+ static_assert(GlobalVarWithVarInjectionChecks == 6, "LLInt assumes GlobalVarWithVarInjectionChecks ResultType is == 6");
+ static_assert(GlobalLexicalVarWithVarInjectionChecks == 7, "LLInt assumes GlobalLexicalVarWithVarInjectionChecks ResultType is == 7");
+ static_assert(ClosureVarWithVarInjectionChecks == 8, "LLInt assumes ClosureVarWithVarInjectionChecks ResultType is == 8");
+
+ static_assert(InitializationMode::Initialization == 0, "LLInt assumes that InitializationMode::Initialization is 0");
</ins><span class="cx">
</span><del>- ASSERT(ResolveModeAndType::mask == 0xffff);
</del><ins>+ ASSERT(GetPutInfo::typeBits == 0x3ff);
+ ASSERT(GetPutInfo::initializationShift == 10);
+ ASSERT(GetPutInfo::initializationBits == 0xffc00);
</ins><span class="cx">
</span><span class="cx"> ASSERT(MarkedBlock::blockMask == ~static_cast<decltype(MarkedBlock::blockMask)>(0x3fff));
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -1358,44 +1358,34 @@
</span><span class="cx"> LLINT_END_IMPL();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-LLINT_SLOW_PATH_DECL(slow_path_resolve_scope)
-{
- LLINT_BEGIN();
- const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
- JSScope* scope = LLINT_OP(2).Register::scope();
- LLINT_RETURN(JSScope::resolve(exec, scope, ident));
-}
-
</del><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
</span><span class="cx"> {
</span><span class="cx"> LLINT_BEGIN();
</span><span class="cx">
</span><span class="cx"> const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
</span><span class="cx"> JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
</span><del>- ResolveModeAndType modeAndType(pc[4].u.operand);
</del><ins>+ GetPutInfo getPutInfo(pc[4].u.operand);
</ins><span class="cx">
</span><span class="cx"> PropertySlot slot(scope);
</span><span class="cx"> if (!scope->getPropertySlot(exec, ident, slot)) {
</span><del>- if (modeAndType.mode() == ThrowIfNotFound)
</del><ins>+ if (getPutInfo.resolveMode() == ThrowIfNotFound)
</ins><span class="cx"> LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
</span><span class="cx"> LLINT_RETURN(jsUndefined());
</span><span class="cx"> }
</span><span class="cx">
</span><del>- // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
- if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
- if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
- CodeBlock* codeBlock = exec->codeBlock();
- Structure* structure = scope->structure(vm);
- {
- ConcurrentJITLocker locker(codeBlock->m_lock);
- pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), structure);
- pc[6].u.operand = slot.cachedOffset();
- }
- structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
- }
</del><ins>+ JSValue result = JSValue();
+ if (jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)) {
+ // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
+ result = slot.getValue(exec, ident);
+ if (result == jsTDZValue())
+ LLINT_THROW(createTDZError(exec));
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- LLINT_RETURN(slot.getValue(exec, ident));
</del><ins>+ CommonSlowPaths::tryCacheGetFromScopeGlobal(exec, vm, pc, scope, slot, ident);
+
+ if (!result)
+ result = slot.getValue(exec, ident);
+ LLINT_RETURN(result);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
</span><span class="lines">@@ -1406,8 +1396,8 @@
</span><span class="cx"> const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
</span><span class="cx"> JSObject* scope = jsCast<JSObject*>(LLINT_OP(1).jsValue());
</span><span class="cx"> JSValue value = LLINT_OP_C(3).jsValue();
</span><del>- ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
- if (modeAndType.type() == LocalClosureVar) {
</del><ins>+ GetPutInfo getPutInfo = GetPutInfo(pc[4].u.operand);
+ if (getPutInfo.resolveType() == LocalClosureVar) {
</ins><span class="cx"> JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
</span><span class="cx"> environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
</span><span class="cx">
</span><span class="lines">@@ -1419,13 +1409,24 @@
</span><span class="cx"> LLINT_END();
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident))
</del><ins>+ bool hasProperty = scope->hasProperty(exec, ident);
+ if (hasProperty
+ && jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)
+ && getPutInfo.initializationMode() != Initialization) {
+ // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
+ PropertySlot slot(scope);
+ JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot);
+ if (slot.getValue(exec, ident) == jsTDZValue())
+ LLINT_THROW(createTDZError(exec));
+ }
+
+ if (getPutInfo.resolveMode() == ThrowIfNotFound && !hasProperty)
</ins><span class="cx"> LLINT_THROW(createUndefinedVariableError(exec, ident));
</span><span class="cx">
</span><del>- PutPropertySlot slot(scope, codeBlock->isStrictMode());
</del><ins>+ PutPropertySlot slot(scope, codeBlock->isStrictMode(), PutPropertySlot::UnknownContext, getPutInfo.initializationMode() == Initialization);
</ins><span class="cx"> scope->methodTable()->put(scope, exec, ident, value, slot);
</span><span class="cx">
</span><del>- CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
</del><ins>+ CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, getPutInfo, slot, ident);
</ins><span class="cx">
</span><span class="cx"> LLINT_END();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -114,7 +114,6 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_will_call);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_did_call);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_handle_exception);
</span><del>-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve_scope);
</del><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope);
</span><span class="cx"> extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM*, ProtoCallFrame*) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -190,14 +190,18 @@
</span><span class="cx"> # ResolveType
</span><span class="cx"> const GlobalProperty = 0
</span><span class="cx"> const GlobalVar = 1
</span><del>-const ClosureVar = 2
-const LocalClosureVar = 3
-const GlobalPropertyWithVarInjectionChecks = 4
-const GlobalVarWithVarInjectionChecks = 5
-const ClosureVarWithVarInjectionChecks = 6
-const Dynamic = 7
</del><ins>+const GlobalLexicalVar = 2
+const ClosureVar = 3
+const LocalClosureVar = 4
+const GlobalPropertyWithVarInjectionChecks = 5
+const GlobalVarWithVarInjectionChecks = 6
+const GlobalLexicalVarWithVarInjectionChecks = 7
+const ClosureVarWithVarInjectionChecks = 8
</ins><span class="cx">
</span><del>-const ResolveModeMask = 0xffff
</del><ins>+const ResolveTypeMask = 0x3ff
+const InitializationModeMask = 0xffc00
+const InitializationModeShift = 10
+const Initialization = 0
</ins><span class="cx">
</span><span class="cx"> const MarkedBlockSize = 16 * 1024
</span><span class="cx"> const MarkedBlockMask = ~(MarkedBlockSize - 1)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -596,14 +596,14 @@
</span><span class="cx"> end
</span><span class="cx"> end
</span><span class="cx">
</span><del>-macro writeBarrierOnGlobalObject(valueOperand)
</del><ins>+macro writeBarrierOnGlobal(valueOperand, loadHelper)
</ins><span class="cx"> if GGC
</span><span class="cx"> loadisFromInstruction(valueOperand, t1)
</span><span class="cx"> loadConstantOrVariableTag(t1, t0)
</span><span class="cx"> bineq t0, CellTag, .writeBarrierDone
</span><ins>+
+ loadHelper(t3)
</ins><span class="cx">
</span><del>- loadp CodeBlock[cfr], t3
- loadp CodeBlock::m_globalObject[t3], t3
</del><span class="cx"> skipIfIsRememberedOrInEden(t3, t1, t2,
</span><span class="cx"> macro(gcData)
</span><span class="cx"> btbnz gcData, .writeBarrierDone
</span><span class="lines">@@ -619,6 +619,23 @@
</span><span class="cx"> end
</span><span class="cx"> end
</span><span class="cx">
</span><ins>+macro writeBarrierOnGlobalObject(valueOperand)
+ writeBarrierOnGlobal(valueOperand,
+ macro(registerToStoreGlobal)
+ loadp CodeBlock[cfr], registerToStoreGlobal
+ loadp CodeBlock::m_globalObject[registerToStoreGlobal], registerToStoreGlobal
+ end)
+end
+
+macro writeBarrierOnGlobalLexicalEnvironment(valueOperand)
+ writeBarrierOnGlobal(valueOperand,
+ macro(registerToStoreGlobal)
+ loadp CodeBlock[cfr], registerToStoreGlobal
+ loadp CodeBlock::m_globalObject[registerToStoreGlobal], registerToStoreGlobal
+ loadp JSGlobalObject::m_globalLexicalEnvironment[registerToStoreGlobal], registerToStoreGlobal
+ end)
+end
+
</ins><span class="cx"> macro valueProfile(tag, payload, operand, scratch)
</span><span class="cx"> loadp operand[PC], scratch
</span><span class="cx"> storei tag, ValueProfile::m_buckets + TagOffset[scratch]
</span><span class="lines">@@ -2037,9 +2054,8 @@
</span><span class="cx"> end
</span><span class="cx">
</span><span class="cx">
</span><del>-macro getGlobalObject(dst)
- loadp CodeBlock[cfr], t0
- loadp CodeBlock::m_globalObject[t0], t0
</del><ins>+macro getConstantScope(dst)
+ loadpFromInstruction(6, t0)
</ins><span class="cx"> loadisFromInstruction(dst, t1)
</span><span class="cx"> storei CellTag, TagOffset[cfr, t1, 8]
</span><span class="cx"> storei t0, PayloadOffset[cfr, t1, 8]
</span><span class="lines">@@ -2078,14 +2094,19 @@
</span><span class="cx">
</span><span class="cx"> #rGlobalProperty:
</span><span class="cx"> bineq t0, GlobalProperty, .rGlobalVar
</span><del>- getGlobalObject(1)
</del><ins>+ getConstantScope(1)
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx"> .rGlobalVar:
</span><del>- bineq t0, GlobalVar, .rClosureVar
- getGlobalObject(1)
</del><ins>+ bineq t0, GlobalVar, .rGlobalLexicalVar
+ getConstantScope(1)
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><ins>+.rGlobalLexicalVar:
+ bineq t0, GlobalLexicalVar, .rClosureVar
+ getConstantScope(1)
+ dispatch(7)
+
</ins><span class="cx"> .rClosureVar:
</span><span class="cx"> bineq t0, ClosureVar, .rGlobalPropertyWithVarInjectionChecks
</span><span class="cx"> resolveScope()
</span><span class="lines">@@ -2094,15 +2115,21 @@
</span><span class="cx"> .rGlobalPropertyWithVarInjectionChecks:
</span><span class="cx"> bineq t0, GlobalPropertyWithVarInjectionChecks, .rGlobalVarWithVarInjectionChecks
</span><span class="cx"> varInjectionCheck(.rDynamic)
</span><del>- getGlobalObject(1)
</del><ins>+ getConstantScope(1)
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx"> .rGlobalVarWithVarInjectionChecks:
</span><del>- bineq t0, GlobalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
</del><ins>+ bineq t0, GlobalVarWithVarInjectionChecks, .rGlobalLexicalVarWithVarInjectionChecks
</ins><span class="cx"> varInjectionCheck(.rDynamic)
</span><del>- getGlobalObject(1)
</del><ins>+ getConstantScope(1)
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><ins>+.rGlobalLexicalVarWithVarInjectionChecks:
+ bineq t0, GlobalLexicalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
+ varInjectionCheck(.rDynamic)
+ getConstantScope(1)
+ dispatch(7)
+
</ins><span class="cx"> .rClosureVarWithVarInjectionChecks:
</span><span class="cx"> bineq t0, ClosureVarWithVarInjectionChecks, .rDynamic
</span><span class="cx"> varInjectionCheck(.rDynamic)
</span><span class="lines">@@ -2110,7 +2137,7 @@
</span><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx"> .rDynamic:
</span><del>- callSlowPath(_llint_slow_path_resolve_scope)
</del><ins>+ callSlowPath(_slow_path_resolve_scope)
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -2130,10 +2157,11 @@
</span><span class="cx"> storei t2, PayloadOffset[cfr, t0, 8]
</span><span class="cx"> end
</span><span class="cx">
</span><del>-macro getGlobalVar()
</del><ins>+macro getGlobalVar(tdzCheckIfNecessary)
</ins><span class="cx"> loadpFromInstruction(6, t0)
</span><span class="cx"> loadp TagOffset[t0], t1
</span><span class="cx"> loadp PayloadOffset[t0], t2
</span><ins>+ tdzCheckIfNecessary(t1)
</ins><span class="cx"> valueProfile(t1, t2, 28, t0)
</span><span class="cx"> loadisFromInstruction(1, t0)
</span><span class="cx"> storei t1, TagOffset[cfr, t0, 8]
</span><span class="lines">@@ -2153,7 +2181,7 @@
</span><span class="cx"> _llint_op_get_from_scope:
</span><span class="cx"> traceExecution()
</span><span class="cx"> loadisFromInstruction(4, t0)
</span><del>- andi ResolveModeMask, t0
</del><ins>+ andi ResolveTypeMask, t0
</ins><span class="cx">
</span><span class="cx"> #gGlobalProperty:
</span><span class="cx"> bineq t0, GlobalProperty, .gGlobalVar
</span><span class="lines">@@ -2162,10 +2190,18 @@
</span><span class="cx"> dispatch(8)
</span><span class="cx">
</span><span class="cx"> .gGlobalVar:
</span><del>- bineq t0, GlobalVar, .gClosureVar
- getGlobalVar()
</del><ins>+ bineq t0, GlobalVar, .gGlobalLexicalVar
+ getGlobalVar(macro(t) end)
</ins><span class="cx"> dispatch(8)
</span><span class="cx">
</span><ins>+.gGlobalLexicalVar:
+ bineq t0, GlobalLexicalVar, .gClosureVar
+ getGlobalVar(
+ macro(tag)
+ bieq tag, EmptyValueTag, .gDynamic
+ end)
+ dispatch(8)
+
</ins><span class="cx"> .gClosureVar:
</span><span class="cx"> bineq t0, ClosureVar, .gGlobalPropertyWithVarInjectionChecks
</span><span class="cx"> loadVariable(2, t2, t1, t0)
</span><span class="lines">@@ -2179,11 +2215,20 @@
</span><span class="cx"> dispatch(8)
</span><span class="cx">
</span><span class="cx"> .gGlobalVarWithVarInjectionChecks:
</span><del>- bineq t0, GlobalVarWithVarInjectionChecks, .gClosureVarWithVarInjectionChecks
</del><ins>+ bineq t0, GlobalVarWithVarInjectionChecks, .gGlobalLexicalVarWithVarInjectionChecks
</ins><span class="cx"> varInjectionCheck(.gDynamic)
</span><del>- getGlobalVar()
</del><ins>+ getGlobalVar(macro(t) end)
</ins><span class="cx"> dispatch(8)
</span><span class="cx">
</span><ins>+.gGlobalLexicalVarWithVarInjectionChecks:
+ bineq t0, GlobalLexicalVarWithVarInjectionChecks, .gClosureVarWithVarInjectionChecks
+ varInjectionCheck(.gDynamic)
+ getGlobalVar(
+ macro(tag)
+ bieq tag, EmptyValueTag, .gDynamic
+ end)
+ dispatch(8)
+
</ins><span class="cx"> .gClosureVarWithVarInjectionChecks:
</span><span class="cx"> bineq t0, ClosureVarWithVarInjectionChecks, .gDynamic
</span><span class="cx"> varInjectionCheck(.gDynamic)
</span><span class="lines">@@ -2203,7 +2248,7 @@
</span><span class="cx"> storePropertyAtVariableOffset(t1, t0, t2, t3)
</span><span class="cx"> end
</span><span class="cx">
</span><del>-macro putGlobalVar()
</del><ins>+macro putGlobalVariable()
</ins><span class="cx"> loadisFromInstruction(3, t0)
</span><span class="cx"> loadConstantOrVariable(t0, t1, t2)
</span><span class="cx"> loadpFromInstruction(5, t3)
</span><span class="lines">@@ -2237,7 +2282,7 @@
</span><span class="cx"> _llint_op_put_to_scope:
</span><span class="cx"> traceExecution()
</span><span class="cx"> loadisFromInstruction(4, t0)
</span><del>- andi ResolveModeMask, t0
</del><ins>+ andi ResolveTypeMask, t0
</ins><span class="cx">
</span><span class="cx"> #pLocalClosureVar:
</span><span class="cx"> bineq t0, LocalClosureVar, .pGlobalProperty
</span><span class="lines">@@ -2254,11 +2299,17 @@
</span><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx"> .pGlobalVar:
</span><del>- bineq t0, GlobalVar, .pClosureVar
</del><ins>+ bineq t0, GlobalVar, .pGlobalLexicalVar
</ins><span class="cx"> writeBarrierOnGlobalObject(3)
</span><del>- putGlobalVar()
</del><ins>+ putGlobalVariable()
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><ins>+.pGlobalLexicalVar:
+ bineq t0, GlobalLexicalVar, .pClosureVar
+ writeBarrierOnGlobalLexicalEnvironment(3)
+ putGlobalVariable()
+ dispatch(7)
+
</ins><span class="cx"> .pClosureVar:
</span><span class="cx"> bineq t0, ClosureVar, .pGlobalPropertyWithVarInjectionChecks
</span><span class="cx"> writeBarrierOnOperands(1, 3)
</span><span class="lines">@@ -2274,12 +2325,19 @@
</span><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx"> .pGlobalVarWithVarInjectionChecks:
</span><del>- bineq t0, GlobalVarWithVarInjectionChecks, .pClosureVarWithVarInjectionChecks
</del><ins>+ bineq t0, GlobalVarWithVarInjectionChecks, .pGlobalLexicalVarWithVarInjectionChecks
</ins><span class="cx"> writeBarrierOnGlobalObject(3)
</span><span class="cx"> varInjectionCheck(.pDynamic)
</span><del>- putGlobalVar()
</del><ins>+ putGlobalVariable()
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><ins>+.pGlobalLexicalVarWithVarInjectionChecks:
+ bineq t0, GlobalLexicalVarWithVarInjectionChecks, .pClosureVarWithVarInjectionChecks
+ writeBarrierOnGlobalLexicalEnvironment(3)
+ varInjectionCheck(.pDynamic)
+ putGlobalVariable()
+ dispatch(7)
+
</ins><span class="cx"> .pClosureVarWithVarInjectionChecks:
</span><span class="cx"> bineq t0, ClosureVarWithVarInjectionChecks, .pDynamic
</span><span class="cx"> writeBarrierOnOperands(1, 3)
</span><span class="lines">@@ -2381,4 +2439,4 @@
</span><span class="cx"> loadisFromInstruction(1, t1)
</span><span class="cx"> storei CellTag, TagOffset[cfr, t1, 8]
</span><span class="cx"> storei t0, PayloadOffset[cfr, t1, 8]
</span><del>- dispatch(2)
</del><span class="cx">\ No newline at end of file
</span><ins>+ dispatch(2)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -466,14 +466,13 @@
</span><span class="cx"> end
</span><span class="cx"> end
</span><span class="cx">
</span><del>-macro writeBarrierOnGlobalObject(valueOperand)
</del><ins>+macro writeBarrierOnGlobal(valueOperand, loadHelper)
</ins><span class="cx"> if GGC
</span><span class="cx"> loadisFromInstruction(valueOperand, t1)
</span><span class="cx"> loadConstantOrVariableCell(t1, t0, .writeBarrierDone)
</span><span class="cx"> btpz t0, .writeBarrierDone
</span><span class="cx">
</span><del>- loadp CodeBlock[cfr], t3
- loadp CodeBlock::m_globalObject[t3], t3
</del><ins>+ loadHelper(t3)
</ins><span class="cx"> skipIfIsRememberedOrInEden(t3, t1, t2,
</span><span class="cx"> macro(gcData)
</span><span class="cx"> btbnz gcData, .writeBarrierDone
</span><span class="lines">@@ -486,6 +485,23 @@
</span><span class="cx"> end
</span><span class="cx"> end
</span><span class="cx">
</span><ins>+macro writeBarrierOnGlobalObject(valueOperand)
+ writeBarrierOnGlobal(valueOperand,
+ macro(registerToStoreGlobal)
+ loadp CodeBlock[cfr], registerToStoreGlobal
+ loadp CodeBlock::m_globalObject[registerToStoreGlobal], registerToStoreGlobal
+ end)
+end
+
+macro writeBarrierOnGlobalLexicalEnvironment(valueOperand)
+ writeBarrierOnGlobal(valueOperand,
+ macro(registerToStoreGlobal)
+ loadp CodeBlock[cfr], registerToStoreGlobal
+ loadp CodeBlock::m_globalObject[registerToStoreGlobal], registerToStoreGlobal
+ loadp JSGlobalObject::m_globalLexicalEnvironment[registerToStoreGlobal], registerToStoreGlobal
+ end)
+end
+
</ins><span class="cx"> macro valueProfile(value, operand, scratch)
</span><span class="cx"> loadpFromInstruction(operand, scratch)
</span><span class="cx"> storeq value, ValueProfile::m_buckets[scratch]
</span><span class="lines">@@ -1910,10 +1926,8 @@
</span><span class="cx"> jmp _llint_throw_from_slow_path_trampoline
</span><span class="cx"> end
</span><span class="cx">
</span><del>-
-macro getGlobalObject(dst)
- loadp CodeBlock[cfr], t0
- loadp CodeBlock::m_globalObject[t0], t0
</del><ins>+macro getConstantScope(dst)
+ loadpFromInstruction(6, t0)
</ins><span class="cx"> loadisFromInstruction(dst, t1)
</span><span class="cx"> storeq t0, [cfr, t1, 8]
</span><span class="cx"> end
</span><span class="lines">@@ -1948,14 +1962,19 @@
</span><span class="cx">
</span><span class="cx"> #rGlobalProperty:
</span><span class="cx"> bineq t0, GlobalProperty, .rGlobalVar
</span><del>- getGlobalObject(1)
</del><ins>+ getConstantScope(1)
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx"> .rGlobalVar:
</span><del>- bineq t0, GlobalVar, .rClosureVar
- getGlobalObject(1)
</del><ins>+ bineq t0, GlobalVar, .rGlobalLexicalVar
+ getConstantScope(1)
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><ins>+.rGlobalLexicalVar:
+ bineq t0, GlobalLexicalVar, .rClosureVar
+ getConstantScope(1)
+ dispatch(7)
+
</ins><span class="cx"> .rClosureVar:
</span><span class="cx"> bineq t0, ClosureVar, .rGlobalPropertyWithVarInjectionChecks
</span><span class="cx"> resolveScope()
</span><span class="lines">@@ -1964,15 +1983,21 @@
</span><span class="cx"> .rGlobalPropertyWithVarInjectionChecks:
</span><span class="cx"> bineq t0, GlobalPropertyWithVarInjectionChecks, .rGlobalVarWithVarInjectionChecks
</span><span class="cx"> varInjectionCheck(.rDynamic)
</span><del>- getGlobalObject(1)
</del><ins>+ getConstantScope(1)
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx"> .rGlobalVarWithVarInjectionChecks:
</span><del>- bineq t0, GlobalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
</del><ins>+ bineq t0, GlobalVarWithVarInjectionChecks, .rGlobalLexicalVarWithVarInjectionChecks
</ins><span class="cx"> varInjectionCheck(.rDynamic)
</span><del>- getGlobalObject(1)
</del><ins>+ getConstantScope(1)
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><ins>+.rGlobalLexicalVarWithVarInjectionChecks:
+ bineq t0, GlobalLexicalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
+ varInjectionCheck(.rDynamic)
+ getConstantScope(1)
+ dispatch(7)
+
</ins><span class="cx"> .rClosureVarWithVarInjectionChecks:
</span><span class="cx"> bineq t0, ClosureVarWithVarInjectionChecks, .rDynamic
</span><span class="cx"> varInjectionCheck(.rDynamic)
</span><span class="lines">@@ -1980,7 +2005,7 @@
</span><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx"> .rDynamic:
</span><del>- callSlowPath(_llint_slow_path_resolve_scope)
</del><ins>+ callSlowPath(_slow_path_resolve_scope)
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -2000,9 +2025,10 @@
</span><span class="cx"> storeq t2, [cfr, t0, 8]
</span><span class="cx"> end
</span><span class="cx">
</span><del>-macro getGlobalVar()
</del><ins>+macro getGlobalVar(tdzCheckIfNecessary)
</ins><span class="cx"> loadpFromInstruction(6, t0)
</span><span class="cx"> loadq [t0], t0
</span><ins>+ tdzCheckIfNecessary(t0)
</ins><span class="cx"> valueProfile(t0, 7, t1)
</span><span class="cx"> loadisFromInstruction(1, t1)
</span><span class="cx"> storeq t0, [cfr, t1, 8]
</span><span class="lines">@@ -2019,7 +2045,7 @@
</span><span class="cx"> _llint_op_get_from_scope:
</span><span class="cx"> traceExecution()
</span><span class="cx"> loadisFromInstruction(4, t0)
</span><del>- andi ResolveModeMask, t0
</del><ins>+ andi ResolveTypeMask, t0
</ins><span class="cx">
</span><span class="cx"> #gGlobalProperty:
</span><span class="cx"> bineq t0, GlobalProperty, .gGlobalVar
</span><span class="lines">@@ -2028,10 +2054,18 @@
</span><span class="cx"> dispatch(8)
</span><span class="cx">
</span><span class="cx"> .gGlobalVar:
</span><del>- bineq t0, GlobalVar, .gClosureVar
- getGlobalVar()
</del><ins>+ bineq t0, GlobalVar, .gGlobalLexicalVar
+ getGlobalVar(macro(v) end)
</ins><span class="cx"> dispatch(8)
</span><span class="cx">
</span><ins>+.gGlobalLexicalVar:
+ bineq t0, GlobalLexicalVar, .gClosureVar
+ getGlobalVar(
+ macro (value)
+ bqeq value, ValueEmpty, .gDynamic
+ end)
+ dispatch(8)
+
</ins><span class="cx"> .gClosureVar:
</span><span class="cx"> bineq t0, ClosureVar, .gGlobalPropertyWithVarInjectionChecks
</span><span class="cx"> loadVariable(2, t0)
</span><span class="lines">@@ -2045,11 +2079,20 @@
</span><span class="cx"> dispatch(8)
</span><span class="cx">
</span><span class="cx"> .gGlobalVarWithVarInjectionChecks:
</span><del>- bineq t0, GlobalVarWithVarInjectionChecks, .gClosureVarWithVarInjectionChecks
</del><ins>+ bineq t0, GlobalVarWithVarInjectionChecks, .gGlobalLexicalVarWithVarInjectionChecks
</ins><span class="cx"> varInjectionCheck(.gDynamic)
</span><del>- getGlobalVar()
</del><ins>+ getGlobalVar(macro(v) end)
</ins><span class="cx"> dispatch(8)
</span><span class="cx">
</span><ins>+.gGlobalLexicalVarWithVarInjectionChecks:
+ bineq t0, GlobalLexicalVarWithVarInjectionChecks, .gClosureVarWithVarInjectionChecks
+ varInjectionCheck(.gDynamic)
+ getGlobalVar(
+ macro (value)
+ bqeq value, ValueEmpty, .gDynamic
+ end)
+ dispatch(8)
+
</ins><span class="cx"> .gClosureVarWithVarInjectionChecks:
</span><span class="cx"> bineq t0, ClosureVarWithVarInjectionChecks, .gDynamic
</span><span class="cx"> varInjectionCheck(.gDynamic)
</span><span class="lines">@@ -2069,7 +2112,7 @@
</span><span class="cx"> storePropertyAtVariableOffset(t1, t0, t2)
</span><span class="cx"> end
</span><span class="cx">
</span><del>-macro putGlobalVar()
</del><ins>+macro putGlobalVariable()
</ins><span class="cx"> loadisFromInstruction(3, t0)
</span><span class="cx"> loadConstantOrVariable(t0, t1)
</span><span class="cx"> loadpFromInstruction(5, t2)
</span><span class="lines">@@ -2096,11 +2139,22 @@
</span><span class="cx"> storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
</span><span class="cx"> end
</span><span class="cx">
</span><ins>+macro checkTDZInGlobalPutToScopeIfNecessary()
+ loadisFromInstruction(4, t0)
+ andi InitializationModeMask, t0
+ rshifti InitializationModeShift, t0
+ bieq t0, Initialization, .noNeedForTDZCheck
+ loadpFromInstruction(6, t0)
+ loadq [t0], t0
+ bqeq t0, ValueEmpty, .pDynamic
+.noNeedForTDZCheck:
+end
</ins><span class="cx">
</span><ins>+
</ins><span class="cx"> _llint_op_put_to_scope:
</span><span class="cx"> traceExecution()
</span><span class="cx"> loadisFromInstruction(4, t0)
</span><del>- andi ResolveModeMask, t0
</del><ins>+ andi ResolveTypeMask, t0
</ins><span class="cx">
</span><span class="cx"> #pLocalClosureVar:
</span><span class="cx"> bineq t0, LocalClosureVar, .pGlobalProperty
</span><span class="lines">@@ -2117,11 +2171,18 @@
</span><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx"> .pGlobalVar:
</span><del>- bineq t0, GlobalVar, .pClosureVar
</del><ins>+ bineq t0, GlobalVar, .pGlobalLexicalVar
</ins><span class="cx"> writeBarrierOnGlobalObject(3)
</span><del>- putGlobalVar()
</del><ins>+ putGlobalVariable()
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><ins>+.pGlobalLexicalVar:
+ bineq t0, GlobalLexicalVar, .pClosureVar
+ writeBarrierOnGlobalLexicalEnvironment(3)
+ checkTDZInGlobalPutToScopeIfNecessary()
+ putGlobalVariable()
+ dispatch(7)
+
</ins><span class="cx"> .pClosureVar:
</span><span class="cx"> bineq t0, ClosureVar, .pGlobalPropertyWithVarInjectionChecks
</span><span class="cx"> writeBarrierOnOperands(1, 3)
</span><span class="lines">@@ -2137,12 +2198,20 @@
</span><span class="cx"> dispatch(7)
</span><span class="cx">
</span><span class="cx"> .pGlobalVarWithVarInjectionChecks:
</span><del>- bineq t0, GlobalVarWithVarInjectionChecks, .pClosureVarWithVarInjectionChecks
</del><ins>+ bineq t0, GlobalVarWithVarInjectionChecks, .pGlobalLexicalVarWithVarInjectionChecks
</ins><span class="cx"> writeBarrierOnGlobalObject(3)
</span><span class="cx"> varInjectionCheck(.pDynamic)
</span><del>- putGlobalVar()
</del><ins>+ putGlobalVariable()
</ins><span class="cx"> dispatch(7)
</span><span class="cx">
</span><ins>+.pGlobalLexicalVarWithVarInjectionChecks:
+ bineq t0, GlobalLexicalVarWithVarInjectionChecks, .pClosureVarWithVarInjectionChecks
+ writeBarrierOnGlobalLexicalEnvironment(3)
+ varInjectionCheck(.pDynamic)
+ checkTDZInGlobalPutToScopeIfNecessary()
+ putGlobalVariable()
+ dispatch(7)
+
</ins><span class="cx"> .pClosureVarWithVarInjectionChecks:
</span><span class="cx"> bineq t0, ClosureVarWithVarInjectionChecks, .pDynamic
</span><span class="cx"> writeBarrierOnOperands(1, 3)
</span><span class="lines">@@ -2233,4 +2302,4 @@
</span><span class="cx"> loadp JSArrowFunction::m_boundThis[t0], t0
</span><span class="cx"> loadisFromInstruction(1, t1)
</span><span class="cx"> storeq t0, [cfr, t1, 8]
</span><del>- dispatch(2)
</del><span class="cx">\ No newline at end of file
</span><ins>+ dispatch(2)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -660,4 +660,34 @@
</span><span class="cx"> RETURN(JSWithScope::create(exec, newScope, currentScope));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+SLOW_PATH_DECL(slow_path_resolve_scope)
+{
+ BEGIN();
+ const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
+ JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
+ JSValue resolvedScope = JSScope::resolve(exec, scope, ident);
+
+ ResolveType resolveType = static_cast<ResolveType>(pc[4].u.operand);
+ if (resolveType == UnresolvedProperty || resolveType == UnresolvedPropertyWithVarInjectionChecks) {
+ if (JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsDynamicCast<JSGlobalLexicalEnvironment*>(resolvedScope)) {
+ if (resolveType == UnresolvedProperty)
+ pc[4].u.operand = GlobalLexicalVar;
+ else
+ pc[4].u.operand = GlobalLexicalVarWithVarInjectionChecks;
+ pc[6].u.pointer = globalLexicalEnvironment;
+ } else if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(resolvedScope)) {
+ if (globalObject->hasProperty(exec, ident)) {
+ if (resolveType == UnresolvedProperty)
+ pc[4].u.operand = GlobalProperty;
+ else
+ pc[4].u.operand = GlobalPropertyWithVarInjectionChecks;
+
+ pc[6].u.pointer = globalObject;
+ }
+ }
+ }
+
+ RETURN(resolvedScope);
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -90,29 +90,81 @@
</span><span class="cx">
</span><span class="cx"> inline void tryCachePutToScopeGlobal(
</span><span class="cx"> ExecState* exec, CodeBlock* codeBlock, Instruction* pc, JSObject* scope,
</span><del>- ResolveModeAndType modeAndType, PutPropertySlot& slot)
</del><ins>+ GetPutInfo getPutInfo, PutPropertySlot& slot, const Identifier& ident)
</ins><span class="cx"> {
</span><span class="cx"> // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
</span><span class="cx">
</span><del>- if (modeAndType.type() != GlobalProperty && modeAndType.type() != GlobalPropertyWithVarInjectionChecks)
</del><ins>+ ResolveType resolveType = getPutInfo.resolveType();
+ if (resolveType != GlobalProperty && resolveType != GlobalPropertyWithVarInjectionChecks
+ && resolveType != UnresolvedProperty && resolveType != UnresolvedPropertyWithVarInjectionChecks)
</ins><span class="cx"> return;
</span><del>-
- if (!slot.isCacheablePut()
- || slot.base() != scope
- || !scope->structure()->propertyAccessesAreCacheable())
- return;
-
- if (slot.type() == PutPropertySlot::NewProperty) {
- // Don't cache if we've done a transition. We want to detect the first replace so that we
- // can invalidate the watchpoint.
- return;
</del><ins>+
+ if (resolveType == UnresolvedProperty || resolveType == UnresolvedPropertyWithVarInjectionChecks) {
+ if (JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)) {
+ ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalLexicalVar : GlobalLexicalVarWithVarInjectionChecks;
+ pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
+ SymbolTableEntry entry = globalLexicalEnvironment->symbolTable()->get(ident.impl());
+ ASSERT(!entry.isNull());
+ pc[5].u.watchpointSet = entry.watchpointSet();
+ pc[6].u.pointer = static_cast<void*>(globalLexicalEnvironment->variableAt(entry.scopeOffset()).slot());
+ } else if (jsDynamicCast<JSGlobalObject*>(scope)) {
+ ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalProperty : GlobalPropertyWithVarInjectionChecks;
+ pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
+
+ if (!slot.isCacheablePut()
+ || slot.base() != scope
+ || !scope->structure()->propertyAccessesAreCacheable())
+ return;
+
+ if (slot.type() == PutPropertySlot::NewProperty) {
+ // Don't cache if we've done a transition. We want to detect the first replace so that we
+ // can invalidate the watchpoint.
+ return;
+ }
+
+ scope->structure()->didCachePropertyReplacement(exec->vm(), slot.cachedOffset());
+
+ ConcurrentJITLocker locker(codeBlock->m_lock);
+ pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
+ pc[6].u.operand = slot.cachedOffset();
+ }
</ins><span class="cx"> }
</span><del>-
- scope->structure()->didCachePropertyReplacement(exec->vm(), slot.cachedOffset());
</del><ins>+}
</ins><span class="cx">
</span><del>- ConcurrentJITLocker locker(codeBlock->m_lock);
- pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
- pc[6].u.operand = slot.cachedOffset();
</del><ins>+inline void tryCacheGetFromScopeGlobal(
+ ExecState* exec, VM& vm, Instruction* pc, JSObject* scope, PropertySlot& slot, const Identifier& ident)
+{
+ GetPutInfo getPutInfo(pc[4].u.operand);
+ ResolveType resolveType = getPutInfo.resolveType();
+
+ if (resolveType == UnresolvedProperty || resolveType == UnresolvedPropertyWithVarInjectionChecks) {
+ if (JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)) {
+ ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalLexicalVar : GlobalLexicalVarWithVarInjectionChecks;
+ pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
+ SymbolTableEntry entry = globalLexicalEnvironment->symbolTable()->get(ident.impl());
+ ASSERT(!entry.isNull());
+ pc[5].u.watchpointSet = entry.watchpointSet();
+ pc[6].u.pointer = static_cast<void*>(globalLexicalEnvironment->variableAt(entry.scopeOffset()).slot());
+ } else if (jsDynamicCast<JSGlobalObject*>(scope)) {
+ ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalProperty : GlobalPropertyWithVarInjectionChecks;
+ resolveType = newResolveType; // Allow bottom caching mechanism to kick in.
+ pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
+ }
+ }
+
+ // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
+ if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
+ if (resolveType == GlobalProperty || resolveType == GlobalPropertyWithVarInjectionChecks) {
+ CodeBlock* codeBlock = exec->codeBlock();
+ Structure* structure = scope->structure(vm);
+ {
+ ConcurrentJITLocker locker(codeBlock->m_lock);
+ pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), structure);
+ pc[6].u.operand = slot.cachedOffset();
+ }
+ structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
+ }
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } // namespace CommonSlowPaths
</span><span class="lines">@@ -235,6 +287,7 @@
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_profile_type_clear_log);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_create_lexical_environment);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_push_with_scope);
</span><ins>+SLOW_PATH_HIDDEN_DECL(slow_path_resolve_scope);
</ins><span class="cx">
</span><span class="cx"> } // namespace JSC
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Executable.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Executable.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/Executable.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -539,6 +539,40 @@
</span><span class="cx"> if (exception)
</span><span class="cx"> return exception;
</span><span class="cx">
</span><ins>+ JSGlobalLexicalEnvironment* globalLexicalEnvironment = globalObject->globalLexicalEnvironment();
+ const VariableEnvironment& variableDeclarations = unlinkedCodeBlock->variableDeclarations();
+ const VariableEnvironment& lexicalDeclarations = unlinkedCodeBlock->lexicalDeclarations();
+ // The ES6 spec says that no vars/global properties/let/const can be duplicated in the global scope.
+ // This carried out section 15.1.8 of the ES6 spec: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-globaldeclarationinstantiation
+ {
+ ExecState* exec = globalObject->globalExec();
+ // Check for intersection of "var" and "let"/"const"/"class"
+ for (auto& entry : lexicalDeclarations) {
+ if (variableDeclarations.contains(entry.key))
+ return createSyntaxError(exec, makeString("Can't create duplicate variable: '", String(entry.key.get()), "'"));
+ }
+
+ // Check if any new "let"/"const"/"class" will shadow any pre-existing global property names, or "var"/"let"/"const" variables.
+ // It's an error to introduce a shadow.
+ for (auto& entry : lexicalDeclarations) {
+ if (globalObject->hasProperty(exec, entry.key.get()))
+ return createSyntaxError(exec, makeString("Can't create duplicate variable that shadows a global property: '", String(entry.key.get()), "'"));
+
+ if (globalLexicalEnvironment->hasProperty(exec, entry.key.get()))
+ return createSyntaxError(exec, makeString("Can't create duplicate variable: '", String(entry.key.get()), "'"));
+ }
+
+ // Check if any new "var"s will shadow any previous "let"/"const"/"class" names.
+ // It's an error to introduce a shadow.
+ if (!globalLexicalEnvironment->isEmpty()) {
+ for (auto& entry : variableDeclarations) {
+ if (globalLexicalEnvironment->hasProperty(exec, entry.key.get()))
+ return createSyntaxError(exec, makeString("Can't create duplicate variable: '", String(entry.key.get()), "'"));
+ }
+ }
+ }
+
+
</ins><span class="cx"> m_unlinkedProgramCodeBlock.set(vm, this, unlinkedCodeBlock);
</span><span class="cx">
</span><span class="cx"> BatchedTransitionOptimizer optimizer(vm, globalObject);
</span><span class="lines">@@ -554,11 +588,25 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- const VariableEnvironment& variableDeclarations = unlinkedCodeBlock->variableDeclarations();
</del><span class="cx"> for (auto& entry : variableDeclarations) {
</span><span class="cx"> ASSERT(entry.value.isVar());
</span><span class="cx"> globalObject->addVar(callFrame, Identifier::fromUid(&vm, entry.key.get()));
</span><span class="cx"> }
</span><ins>+
+ {
+ JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalLexicalEnvironment*>(globalObject->globalScope());
+ SymbolTable* symbolTable = globalLexicalEnvironment->symbolTable();
+ ConcurrentJITLocker locker(symbolTable->m_lock);
+ for (auto& entry : lexicalDeclarations) {
+ ScopeOffset offset = symbolTable->takeNextScopeOffset(locker);
+ SymbolTableEntry newEntry(VarOffset(offset), entry.value.isConst() ? ReadOnly : 0);
+ newEntry.prepareToWatch();
+ symbolTable->add(locker, entry.key.get(), newEntry);
+
+ ScopeOffset offsetForAssert = globalLexicalEnvironment->addVariables(1, jsTDZValue());
+ RELEASE_ASSERT(offsetForAssert == offset);
+ }
+ }
</ins><span class="cx"> return 0;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeGetPutInfoh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/GetPutInfo.h (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/GetPutInfo.h         (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/GetPutInfo.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,215 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GetPutInfo_h
+#define GetPutInfo_h
+
+namespace JSC {
+
+class Structure;
+class WatchpointSet;
+class JSLexicalEnvironment;
+
+enum ResolveMode {
+ ThrowIfNotFound,
+ DoNotThrowIfNotFound
+};
+
+enum ResolveType {
+ // Lexical scope guaranteed a certain type of variable access.
+ GlobalProperty,
+ GlobalVar,
+ GlobalLexicalVar,
+ ClosureVar,
+ LocalClosureVar,
+
+ // Ditto, but at least one intervening scope used non-strict eval, which
+ // can inject an intercepting var delcaration at runtime.
+ GlobalPropertyWithVarInjectionChecks,
+ GlobalVarWithVarInjectionChecks,
+ GlobalLexicalVarWithVarInjectionChecks,
+ ClosureVarWithVarInjectionChecks,
+
+ // We haven't found which scope this belongs to, and we also
+ // haven't ruled out the possibility of it being cached. Ideally,
+ // we want to transition this to GlobalVar/GlobalLexicalVar/GlobalProperty <with/without injection>
+ UnresolvedProperty,
+ UnresolvedPropertyWithVarInjectionChecks,
+
+ // Lexical scope didn't prove anything -- probably because of a 'with' scope.
+ Dynamic
+};
+
+enum InitializationMode {
+ Initialization, // "let x = 20;"
+ NotInitialization // "x = 20;"
+};
+
+ALWAYS_INLINE const char* resolveModeName(ResolveMode resolveMode)
+{
+ static const char* const names[] = {
+ "ThrowIfNotFound",
+ "DoNotThrowIfNotFound"
+ };
+ return names[resolveMode];
+}
+
+ALWAYS_INLINE const char* resolveTypeName(ResolveType type)
+{
+ static const char* const names[] = {
+ "GlobalProperty",
+ "GlobalVar",
+ "GlobalLexicalVar",
+ "ClosureVar",
+ "LocalClosureVar",
+ "GlobalPropertyWithVarInjectionChecks",
+ "GlobalVarWithVarInjectionChecks",
+ "GlobalLexicalVarWithVarInjectionChecks",
+ "ClosureVarWithVarInjectionChecks",
+ "UnresolvedProperty",
+ "UnresolvedPropertyWithVarInjectionChecks",
+ "Dynamic"
+ };
+ return names[type];
+}
+
+ALWAYS_INLINE const char* initializationModeName(InitializationMode initializationMode)
+{
+ static const char* const names[] = {
+ "Initialization",
+ "NotInitialization"
+ };
+ return names[initializationMode];
+}
+
+
+ALWAYS_INLINE ResolveType makeType(ResolveType type, bool needsVarInjectionChecks)
+{
+ if (!needsVarInjectionChecks)
+ return type;
+
+ switch (type) {
+ case GlobalProperty:
+ return GlobalPropertyWithVarInjectionChecks;
+ case GlobalVar:
+ return GlobalVarWithVarInjectionChecks;
+ case GlobalLexicalVar:
+ return GlobalLexicalVarWithVarInjectionChecks;
+ case ClosureVar:
+ case LocalClosureVar:
+ return ClosureVarWithVarInjectionChecks;
+ case UnresolvedProperty:
+ return UnresolvedPropertyWithVarInjectionChecks;
+ case GlobalPropertyWithVarInjectionChecks:
+ case GlobalVarWithVarInjectionChecks:
+ case GlobalLexicalVarWithVarInjectionChecks:
+ case ClosureVarWithVarInjectionChecks:
+ case UnresolvedPropertyWithVarInjectionChecks:
+ case Dynamic:
+ return type;
+ }
+
+ RELEASE_ASSERT_NOT_REACHED();
+ return type;
+}
+
+ALWAYS_INLINE bool needsVarInjectionChecks(ResolveType type)
+{
+ switch (type) {
+ case GlobalProperty:
+ case GlobalVar:
+ case GlobalLexicalVar:
+ case ClosureVar:
+ case LocalClosureVar:
+ case UnresolvedProperty:
+ return false;
+ case GlobalPropertyWithVarInjectionChecks:
+ case GlobalVarWithVarInjectionChecks:
+ case GlobalLexicalVarWithVarInjectionChecks:
+ case ClosureVarWithVarInjectionChecks:
+ case UnresolvedPropertyWithVarInjectionChecks:
+ case Dynamic:
+ return true;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return true;
+ }
+}
+
+struct ResolveOp {
+ ResolveOp(ResolveType type, size_t depth, Structure* structure, JSLexicalEnvironment* lexicalEnvironment, WatchpointSet* watchpointSet, uintptr_t operand)
+ : type(type)
+ , depth(depth)
+ , structure(structure)
+ , lexicalEnvironment(lexicalEnvironment)
+ , watchpointSet(watchpointSet)
+ , operand(operand)
+ {
+ }
+
+ ResolveType type;
+ size_t depth;
+ Structure* structure;
+ JSLexicalEnvironment* lexicalEnvironment;
+ WatchpointSet* watchpointSet;
+ uintptr_t operand;
+};
+
+class GetPutInfo {
+ typedef unsigned Operand;
+public:
+ // Give each field 10 bits for simplicity.
+ static_assert(sizeof(Operand) * 8 > 30, "Not enough bits for GetPutInfo");
+ static const unsigned modeShift = 20;
+ static const unsigned initializationShift = 10;
+ static const unsigned typeBits = (1 << initializationShift) - 1;
+ static const unsigned initializationBits = ((1 << modeShift) - 1) & ~typeBits;
+ static const unsigned modeBits = ((1 << 30) - 1) & ~initializationBits & ~typeBits;
+ static_assert((modeBits & initializationBits & typeBits) == 0x0, "There should be no intersection between ResolveMode ResolveType and InitializationMode");
+
+ GetPutInfo(ResolveMode resolveMode, ResolveType resolveType, InitializationMode initializationMode)
+ : m_operand((resolveMode << modeShift) | (initializationMode << initializationShift) | resolveType)
+ {
+ }
+
+ explicit GetPutInfo(unsigned operand)
+ : m_operand(operand)
+ {
+ }
+
+ ResolveType resolveType() const { return static_cast<ResolveType>(m_operand & typeBits); }
+ InitializationMode initializationMode() const { return static_cast<InitializationMode>((m_operand & initializationBits) >> initializationShift); }
+ ResolveMode resolveMode() const { return static_cast<ResolveMode>((m_operand & modeBits) >> modeShift); }
+ unsigned operand() { return m_operand; }
+
+private:
+ Operand m_operand;
+};
+
+enum GetOrPut { Get, Put };
+
+} // namespace JSC
+
+#endif // GetPutInfo_h
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalLexicalEnvironmentcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.cpp (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.cpp         (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSGlobalLexicalEnvironment.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSGlobalLexicalEnvironment::s_info = { "JSGlobalLexicalEnvironment", &Base::s_info, 0, CREATE_METHOD_TABLE(JSGlobalLexicalEnvironment) };
+
+bool JSGlobalLexicalEnvironment::getOwnPropertySlot(JSObject* object, ExecState*, PropertyName propertyName, PropertySlot& slot)
+{
+ JSGlobalLexicalEnvironment* thisObject = jsCast<JSGlobalLexicalEnvironment*>(object);
+ return symbolTableGet(thisObject, propertyName, slot);
+}
+
+void JSGlobalLexicalEnvironment::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
+{
+ JSGlobalLexicalEnvironment* thisObject = jsCast<JSGlobalLexicalEnvironment*>(cell);
+ ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
+ bool alwaysThrowWhenAssigningToConstProperty = true;
+ bool ignoreConstAssignmentError = slot.isInitialization();
+ symbolTablePut(thisObject, exec, propertyName, value, alwaysThrowWhenAssigningToConstProperty, ignoreConstAssignmentError);
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalLexicalEnvironmenth"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.h (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.h         (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSGlobalLexicalEnvironment_h
+#define JSGlobalLexicalEnvironment_h
+
+#include "JSSegmentedVariableObject.h"
+
+namespace JSC {
+
+class JSGlobalLexicalEnvironment : public JSSegmentedVariableObject {
+
+public:
+ typedef JSSegmentedVariableObject Base;
+
+ static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+
+ static JSGlobalLexicalEnvironment* create(VM& vm, Structure* structure, JSScope* parentScope)
+ {
+ JSGlobalLexicalEnvironment* result =
+ new (NotNull, allocateCell<JSGlobalLexicalEnvironment>(vm.heap)) JSGlobalLexicalEnvironment(vm, structure, parentScope);
+ result->finishCreation(vm);
+ result->symbolTable()->setScopeType(SymbolTable::ScopeType::GlobalLexicalScope);
+ return result;
+ }
+
+ static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+ static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+
+ bool isEmpty() const { return !symbolTable()->size(); }
+
+ DECLARE_INFO;
+
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
+ {
+ return Structure::create(vm, globalObject, jsNull(), TypeInfo(ClosureObjectType, StructureFlags), info());
+ }
+
+protected:
+ JSGlobalLexicalEnvironment(VM& vm, Structure* structure, JSScope* scope)
+ : Base(vm, structure, scope)
+ {
+ }
+};
+
+} // namespace JSC
+
+#endif // JSGlobalLexicalEnvironment_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -262,8 +262,9 @@
</span><span class="cx"> m_functionPrototype.set(vm, this, FunctionPrototype::create(vm, FunctionPrototype::createStructure(vm, this, jsNull()))); // The real prototype will be set once ObjectPrototype is created.
</span><span class="cx"> m_calleeStructure.set(vm, this, JSCallee::createStructure(vm, this, jsNull()));
</span><span class="cx">
</span><ins>+ m_globalLexicalEnvironment.set(vm, this, JSGlobalLexicalEnvironment::create(vm, JSGlobalLexicalEnvironment::createStructure(vm, this), this));
</ins><span class="cx"> // Need to create the callee structure (above) before creating the callee.
</span><del>- m_globalCallee.set(vm, this, JSCallee::create(vm, this, this));
</del><ins>+ m_globalCallee.set(vm, this, JSCallee::create(vm, this, globalScope()));
</ins><span class="cx"> exec->setCallee(m_globalCallee.get());
</span><span class="cx">
</span><span class="cx"> m_functionStructure.set(vm, this, JSFunction::createStructure(vm, this, m_functionPrototype.get()));
</span><span class="lines">@@ -552,7 +553,7 @@
</span><span class="cx"> JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell);
</span><span class="cx"> ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
</span><span class="cx">
</span><del>- if (symbolTablePut(thisObject, exec, propertyName, value, slot.isStrictMode()))
</del><ins>+ if (symbolTablePut(thisObject, exec, propertyName, value, slot.isStrictMode(), false))
</ins><span class="cx"> return;
</span><span class="cx"> Base::put(thisObject, exec, propertyName, value, slot);
</span><span class="cx"> }
</span><span class="lines">@@ -579,7 +580,7 @@
</span><span class="cx"> newEntry.prepareToWatch();
</span><span class="cx"> symbolTable()->add(locker, ident.impl(), newEntry);
</span><span class="cx">
</span><del>- ScopeOffset offsetForAssert = addVariables(1);
</del><ins>+ ScopeOffset offsetForAssert = addVariables(1, jsUndefined());
</ins><span class="cx"> RELEASE_ASSERT(offsetForAssert == offset);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -754,6 +755,7 @@
</span><span class="cx">
</span><span class="cx"> visitor.append(&thisObject->m_globalThis);
</span><span class="cx">
</span><ins>+ visitor.append(&thisObject->m_globalLexicalEnvironment);
</ins><span class="cx"> visitor.append(&thisObject->m_globalCallee);
</span><span class="cx"> visitor.append(&thisObject->m_regExpConstructor);
</span><span class="cx"> visitor.append(&thisObject->m_errorConstructor);
</span><span class="lines">@@ -855,7 +857,7 @@
</span><span class="cx">
</span><span class="cx"> void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
</span><span class="cx"> {
</span><del>- ScopeOffset startOffset = addVariables(count);
</del><ins>+ ScopeOffset startOffset = addVariables(count, jsUndefined());
</ins><span class="cx">
</span><span class="cx"> for (int i = 0; i < count; ++i) {
</span><span class="cx"> GlobalPropertyInfo& global = globals[i];
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include "JSArray.h"
</span><span class="cx"> #include "JSArrayBufferPrototype.h"
</span><span class="cx"> #include "JSClassRef.h"
</span><ins>+#include "JSGlobalLexicalEnvironment.h"
</ins><span class="cx"> #include "JSProxy.h"
</span><span class="cx"> #include "JSSegmentedVariableObject.h"
</span><span class="cx"> #include "JSWeakObjectMapRefInternal.h"
</span><span class="lines">@@ -193,6 +194,7 @@
</span><span class="cx">
</span><span class="cx"> WriteBarrier<JSObject> m_globalThis;
</span><span class="cx">
</span><ins>+ WriteBarrier<JSGlobalLexicalEnvironment> m_globalLexicalEnvironment;
</ins><span class="cx"> WriteBarrier<JSObject> m_globalCallee;
</span><span class="cx"> WriteBarrier<RegExpConstructor> m_regExpConstructor;
</span><span class="cx"> WriteBarrier<ErrorConstructor> m_errorConstructor;
</span><span class="lines">@@ -385,10 +387,6 @@
</span><span class="cx"> JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, PropertyName, JSObject* setterFunc, unsigned attributes);
</span><span class="cx"> JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
</span><span class="cx">
</span><del>- // We use this in the code generator as we perform symbol table
- // lookups prior to initializing the properties
- bool symbolTableHasProperty(PropertyName);
-
</del><span class="cx"> void addVar(ExecState* exec, const Identifier& propertyName)
</span><span class="cx"> {
</span><span class="cx"> if (!hasProperty(exec, propertyName))
</span><span class="lines">@@ -396,6 +394,9 @@
</span><span class="cx"> }
</span><span class="cx"> void addFunction(ExecState*, const Identifier&);
</span><span class="cx">
</span><ins>+ JSScope* globalScope() { return m_globalLexicalEnvironment.get(); }
+ JSGlobalLexicalEnvironment* globalLexicalEnvironment() { return m_globalLexicalEnvironment.get(); }
+
</ins><span class="cx"> // The following accessors return pristine values, even if a script
</span><span class="cx"> // replaces the global object's associated property.
</span><span class="cx">
</span><span class="lines">@@ -693,12 +694,6 @@
</span><span class="cx"> return symbolTableGet(this, propertyName, slot, slotIsWriteable);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName)
-{
- SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
- return !entry.isNull();
-}
-
</del><span class="cx"> inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0)
</span><span class="cx"> {
</span><span class="cx"> return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), initialLength >= MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -585,7 +585,7 @@
</span><span class="cx"> if (!eval)
</span><span class="cx"> return JSValue::encode(jsUndefined());
</span><span class="cx">
</span><del>- return JSValue::encode(exec->interpreter()->execute(eval, exec, calleeGlobalObject->globalThis(), calleeGlobalObject));
</del><ins>+ return JSValue::encode(exec->interpreter()->execute(eval, exec, calleeGlobalObject->globalThis(), calleeGlobalObject->globalScope()));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSLexicalEnvironmenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -75,7 +75,7 @@
</span><span class="cx">
</span><span class="cx"> DECLARE_INFO;
</span><span class="cx">
</span><del>- static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) { return Structure::create(vm, globalObject, jsNull(), TypeInfo(ActivationObjectType, StructureFlags), info()); }
</del><ins>+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) { return Structure::create(vm, globalObject, jsNull(), TypeInfo(ClosureObjectType, StructureFlags), info()); }
</ins><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> bool symbolTableGet(PropertyName, PropertySlot&);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -597,10 +597,6 @@
</span><span class="cx"> JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
</span><span class="cx">
</span><span class="cx"> bool isGlobalObject() const;
</span><del>- bool isVariableObject() const;
- bool isStaticScopeObject() const;
- bool isNameScopeObject() const;
- bool isActivationObject() const;
</del><span class="cx"> bool isErrorInstance() const;
</span><span class="cx"> bool isWithScope() const;
</span><span class="cx">
</span><span class="lines">@@ -1012,27 +1008,6 @@
</span><span class="cx"> return type() == GlobalObjectType;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline bool JSObject::isVariableObject() const
-{
- return type() == GlobalObjectType || type() == ActivationObjectType;
-}
-
-inline bool JSObject::isStaticScopeObject() const
-{
- JSType type = this->type();
- return type == NameScopeObjectType || type == ActivationObjectType;
-}
-
-inline bool JSObject::isNameScopeObject() const
-{
- return type() == NameScopeObjectType;
-}
-
-inline bool JSObject::isActivationObject() const
-{
- return type() == ActivationObjectType;
-}
-
</del><span class="cx"> inline bool JSObject::isErrorInstance() const
</span><span class="cx"> {
</span><span class="cx"> return type() == ErrorInstanceType;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSScope.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSScope.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/JSScope.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -44,7 +44,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Returns true if we found enough information to terminate optimization.
</span><del>-static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, size_t depth, bool& needsVarInjectionChecks, ResolveOp& op)
</del><ins>+static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, size_t depth, bool& needsVarInjectionChecks, ResolveOp& op, InitializationMode initializationMode)
</ins><span class="cx"> {
</span><span class="cx"> if (JSLexicalEnvironment* lexicalEnvironment = jsDynamicCast<JSLexicalEnvironment*>(scope)) {
</span><span class="cx"> if (ident == exec->propertyNames().arguments) {
</span><span class="lines">@@ -70,6 +70,33 @@
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ if (JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)) {
+ SymbolTableEntry entry = globalLexicalEnvironment->symbolTable()->get(ident.impl());
+ if (!entry.isNull()) {
+ if (getOrPut == Put && entry.isReadOnly() && initializationMode != Initialization) {
+ // We know the property will be at global lexical environment, but we don't know how to cache it.
+ op = ResolveOp(Dynamic, 0, 0, 0, 0, 0);
+ return true;
+ }
+
+ // We can try to force const Initialization to always go down the fast path. It is provably impossible to construct
+ // a program that needs a var injection check here. You can convince yourself of this as follows:
+ // Any other let/const/class would be a duplicate of this in the global scope, so we would never get here in that situation.
+ // Also, if we had an eval in the global scope that defined a const, it would also be a duplicate of this const, and so it would
+ // also throw an error. Therefore, we're *the only* thing that can assign to this "const" slot for the first (and only) time. Also,
+ // we will never have a Dynamic ResolveType here because if we were inside a "with" statement, that would mean the "const" definition
+ // isn't a global, it would be a local to the "with" block.
+ // We still need to make the slow path correct for when we need to fire a watchpoint.
+ ResolveType resolveType = initializationMode == Initialization ? GlobalLexicalVar : makeType(GlobalLexicalVar, needsVarInjectionChecks);
+ op = ResolveOp(
+ resolveType, depth, 0, 0, entry.watchpointSet(),
+ reinterpret_cast<uintptr_t>(globalLexicalEnvironment->variableAt(entry.scopeOffset()).slot()));
+ return true;
+ }
+
+ return false;
+ }
+
</ins><span class="cx"> if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(scope)) {
</span><span class="cx"> SymbolTableEntry entry = globalObject->symbolTable()->get(ident.impl());
</span><span class="cx"> if (!entry.isNull()) {
</span><span class="lines">@@ -92,7 +119,7 @@
</span><span class="cx"> || (globalObject->structure()->hasReadOnlyOrGetterSetterPropertiesExcludingProto() && getOrPut == Put)) {
</span><span class="cx"> // We know the property will be at global scope, but we don't know how to cache it.
</span><span class="cx"> ASSERT(!scope->next());
</span><del>- op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, 0, 0, 0, 0);
</del><ins>+ op = ResolveOp(makeType(UnresolvedProperty, needsVarInjectionChecks), 0, 0, 0, 0, 0);
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -161,7 +188,7 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-ResolveOp JSScope::abstractResolve(ExecState* exec, size_t depthOffset, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, ResolveType unlinkedType)
</del><ins>+ResolveOp JSScope::abstractResolve(ExecState* exec, size_t depthOffset, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, ResolveType unlinkedType, InitializationMode initializationMode)
</ins><span class="cx"> {
</span><span class="cx"> ResolveOp op(Dynamic, 0, 0, 0, 0, 0);
</span><span class="cx"> if (unlinkedType == Dynamic)
</span><span class="lines">@@ -170,7 +197,7 @@
</span><span class="cx"> bool needsVarInjectionChecks = JSC::needsVarInjectionChecks(unlinkedType);
</span><span class="cx"> size_t depth = depthOffset;
</span><span class="cx"> for (; scope; scope = scope->next()) {
</span><del>- if (abstractAccess(exec, scope, ident, getOrPut, depth, needsVarInjectionChecks, op))
</del><ins>+ if (abstractAccess(exec, scope, ident, getOrPut, depth, needsVarInjectionChecks, op, initializationMode))
</ins><span class="cx"> break;
</span><span class="cx"> ++depth;
</span><span class="cx"> }
</span><span class="lines">@@ -181,63 +208,68 @@
</span><span class="cx"> void JSScope::collectVariablesUnderTDZ(JSScope* scope, VariableEnvironment& result)
</span><span class="cx"> {
</span><span class="cx"> for (; scope; scope = scope->next()) {
</span><del>- if (!scope->isLexicalScope())
</del><ins>+ if (!scope->isLexicalScope() && !scope->isGlobalLexicalEnvironment())
</ins><span class="cx"> continue;
</span><del>- SymbolTable* symbolTable = jsCast<JSLexicalEnvironment*>(scope)->symbolTable();
- ASSERT(symbolTable->scopeType() == SymbolTable::ScopeType::LexicalScope);
</del><ins>+ SymbolTable* symbolTable = jsCast<JSSymbolTableObject*>(scope)->symbolTable();
+ ASSERT(symbolTable->scopeType() == SymbolTable::ScopeType::LexicalScope || symbolTable->scopeType() == SymbolTable::ScopeType::GlobalLexicalScope);
</ins><span class="cx"> ConcurrentJITLocker locker(symbolTable->m_lock);
</span><span class="cx"> for (auto end = symbolTable->end(locker), iter = symbolTable->begin(locker); iter != end; ++iter)
</span><span class="cx"> result.add(iter->key);
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool JSScope::isLexicalScope()
</del><ins>+template <typename EnvironmentType, SymbolTable::ScopeType scopeType>
+inline static bool isScopeType(JSScope* scope)
</ins><span class="cx"> {
</span><del>- JSLexicalEnvironment* lexicalEnvironment = jsDynamicCast<JSLexicalEnvironment*>(this);
- if (!lexicalEnvironment) // Global object does not hold any lexical variables so we can ignore it.
</del><ins>+ EnvironmentType* environment = jsDynamicCast<EnvironmentType*>(scope);
+ if (!environment)
</ins><span class="cx"> return false;
</span><span class="cx">
</span><del>- return lexicalEnvironment->symbolTable()->scopeType() == SymbolTable::ScopeType::LexicalScope;
</del><ins>+ return environment->symbolTable()->scopeType() == scopeType;
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+bool JSScope::isVarScope()
+{
+ return isScopeType<JSLexicalEnvironment, SymbolTable::ScopeType::VarScope>(this);
+}
+
+bool JSScope::isLexicalScope()
+{
+ return isScopeType<JSLexicalEnvironment, SymbolTable::ScopeType::LexicalScope>(this);
+}
+
</ins><span class="cx"> bool JSScope::isCatchScope()
</span><span class="cx"> {
</span><del>- JSLexicalEnvironment* lexicalEnvironment = jsDynamicCast<JSLexicalEnvironment*>(this);
- if (!lexicalEnvironment)
- return false;
- return lexicalEnvironment->symbolTable()->scopeType() == SymbolTable::ScopeType::CatchScope;
</del><ins>+ return isScopeType<JSLexicalEnvironment, SymbolTable::ScopeType::CatchScope>(this);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool JSScope::isFunctionNameScopeObject()
</span><span class="cx"> {
</span><del>- JSLexicalEnvironment* lexicalEnvironment = jsDynamicCast<JSLexicalEnvironment*>(this);
- if (!lexicalEnvironment)
- return false;
- return lexicalEnvironment->symbolTable()->scopeType() == SymbolTable::ScopeType::FunctionNameScope;
</del><ins>+ return isScopeType<JSLexicalEnvironment, SymbolTable::ScopeType::FunctionNameScope>(this);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-const char* resolveModeName(ResolveMode mode)
</del><ins>+bool JSScope::isGlobalLexicalEnvironment()
</ins><span class="cx"> {
</span><del>- static const char* const names[] = {
- "ThrowIfNotFound",
- "DoNotThrowIfNotFound"
- };
- return names[mode];
</del><ins>+ return isScopeType<JSGlobalLexicalEnvironment, SymbolTable::ScopeType::GlobalLexicalScope>(this);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-const char* resolveTypeName(ResolveType type)
</del><ins>+JSScope* JSScope::constantScopeForCodeBlock(ResolveType type, CodeBlock* codeBlock)
</ins><span class="cx"> {
</span><del>- static const char* const names[] = {
- "GlobalProperty",
- "GlobalVar",
- "ClosureVar",
- "LocalClosureVar",
- "GlobalPropertyWithVarInjectionChecks",
- "GlobalVarWithVarInjectionChecks",
- "ClosureVarWithVarInjectionChecks",
- "Dynamic"
- };
- return names[type];
</del><ins>+ switch (type) {
+ case GlobalProperty:
+ case GlobalVar:
+ case GlobalPropertyWithVarInjectionChecks:
+ case GlobalVarWithVarInjectionChecks:
+ return codeBlock->globalObject();
+ case GlobalLexicalVarWithVarInjectionChecks:
+ case GlobalLexicalVar:
+ return codeBlock->globalObject()->globalLexicalEnvironment();
+ default:
+ return nullptr;
+ }
+
+ RELEASE_ASSERT_NOT_REACHED();
+ return nullptr;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSScope.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSScope.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/JSScope.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved.
</del><ins>+ * Copyright (C) 2012-2015 Apple Inc. All Rights Reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #ifndef JSScope_h
</span><span class="cx"> #define JSScope_h
</span><span class="cx">
</span><ins>+#include "GetPutInfo.h"
</ins><span class="cx"> #include "JSObject.h"
</span><span class="cx"> #include "VariableEnvironment.h"
</span><span class="cx">
</span><span class="lines">@@ -34,119 +35,6 @@
</span><span class="cx"> class ScopeChainIterator;
</span><span class="cx"> class WatchpointSet;
</span><span class="cx">
</span><del>-enum ResolveMode {
- ThrowIfNotFound,
- DoNotThrowIfNotFound
-};
-
-enum ResolveType {
- // Lexical scope guaranteed a certain type of variable access.
- GlobalProperty,
- GlobalVar,
- ClosureVar,
- LocalClosureVar,
-
- // Ditto, but at least one intervening scope used non-strict eval, which
- // can inject an intercepting var delcaration at runtime.
- GlobalPropertyWithVarInjectionChecks,
- GlobalVarWithVarInjectionChecks,
- ClosureVarWithVarInjectionChecks,
-
- // Lexical scope didn't prove anything -- probably because of a 'with' scope.
- Dynamic
-};
-
-const char* resolveModeName(ResolveMode mode);
-const char* resolveTypeName(ResolveType type);
-
-inline ResolveType makeType(ResolveType type, bool needsVarInjectionChecks)
-{
- if (!needsVarInjectionChecks)
- return type;
-
- switch (type) {
- case GlobalProperty:
- return GlobalPropertyWithVarInjectionChecks;
- case GlobalVar:
- return GlobalVarWithVarInjectionChecks;
- case ClosureVar:
- case LocalClosureVar:
- return ClosureVarWithVarInjectionChecks;
- case GlobalPropertyWithVarInjectionChecks:
- case GlobalVarWithVarInjectionChecks:
- case ClosureVarWithVarInjectionChecks:
- case Dynamic:
- return type;
- }
-
- RELEASE_ASSERT_NOT_REACHED();
- return type;
-}
-
-inline bool needsVarInjectionChecks(ResolveType type)
-{
- switch (type) {
- case GlobalProperty:
- case GlobalVar:
- case ClosureVar:
- case LocalClosureVar:
- return false;
- case GlobalPropertyWithVarInjectionChecks:
- case GlobalVarWithVarInjectionChecks:
- case ClosureVarWithVarInjectionChecks:
- case Dynamic:
- return true;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- return true;
- }
-}
-
-struct ResolveOp {
- ResolveOp(ResolveType type, size_t depth, Structure* structure, JSLexicalEnvironment* lexicalEnvironment, WatchpointSet* watchpointSet, uintptr_t operand)
- : type(type)
- , depth(depth)
- , structure(structure)
- , lexicalEnvironment(lexicalEnvironment)
- , watchpointSet(watchpointSet)
- , operand(operand)
- {
- }
-
- ResolveType type;
- size_t depth;
- Structure* structure;
- JSLexicalEnvironment* lexicalEnvironment;
- WatchpointSet* watchpointSet;
- uintptr_t operand;
-};
-
-class ResolveModeAndType {
- typedef unsigned Operand;
-public:
- static const size_t shift = sizeof(Operand) * 8 / 2;
- static const unsigned mask = (1 << shift) - 1;
-
- ResolveModeAndType(ResolveMode resolveMode, ResolveType resolveType)
- : m_operand((resolveMode << shift) | resolveType)
- {
- }
-
- explicit ResolveModeAndType(unsigned operand)
- : m_operand(operand)
- {
- }
-
- ResolveMode mode() { return static_cast<ResolveMode>(m_operand >> shift); }
- ResolveType type() { return static_cast<ResolveType>(m_operand & mask); }
- unsigned operand() { return m_operand; }
-
-private:
- Operand m_operand;
-};
-
-enum GetOrPut { Get, Put };
-
</del><span class="cx"> class JSScope : public JSNonFinalObject {
</span><span class="cx"> public:
</span><span class="cx"> typedef JSNonFinalObject Base;
</span><span class="lines">@@ -158,13 +46,18 @@
</span><span class="cx"> static JSObject* objectAtScope(JSScope*);
</span><span class="cx">
</span><span class="cx"> static JSValue resolve(ExecState*, JSScope*, const Identifier&);
</span><del>- static ResolveOp abstractResolve(ExecState*, size_t depthOffset, JSScope*, const Identifier&, GetOrPut, ResolveType);
</del><ins>+ static ResolveOp abstractResolve(ExecState*, size_t depthOffset, JSScope*, const Identifier&, GetOrPut, ResolveType, InitializationMode);
</ins><span class="cx">
</span><ins>+ static bool hasConstantScope(ResolveType);
+ static JSScope* constantScopeForCodeBlock(ResolveType, CodeBlock*);
+
</ins><span class="cx"> static void collectVariablesUnderTDZ(JSScope*, VariableEnvironment& result);
</span><span class="cx">
</span><span class="cx"> static void visitChildren(JSCell*, SlotVisitor&);
</span><span class="cx">
</span><ins>+ bool isVarScope();
</ins><span class="cx"> bool isLexicalScope();
</span><ins>+ bool isGlobalLexicalEnvironment();
</ins><span class="cx"> bool isCatchScope();
</span><span class="cx"> bool isFunctionNameScopeObject();
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSSegmentedVariableObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -46,7 +46,7 @@
</span><span class="cx"> return ScopeOffset();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-ScopeOffset JSSegmentedVariableObject::addVariables(unsigned numberOfVariablesToAdd)
</del><ins>+ScopeOffset JSSegmentedVariableObject::addVariables(unsigned numberOfVariablesToAdd, JSValue initialValue)
</ins><span class="cx"> {
</span><span class="cx"> ConcurrentJITLocker locker(m_lock);
</span><span class="cx">
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx"> m_variables.grow(oldSize + numberOfVariablesToAdd);
</span><span class="cx">
</span><span class="cx"> for (size_t i = numberOfVariablesToAdd; i--;)
</span><del>- m_variables[oldSize + i].setWithoutWriteBarrier(jsUndefined());
</del><ins>+ m_variables[oldSize + i].setWithoutWriteBarrier(initialValue);
</ins><span class="cx">
</span><span class="cx"> return ScopeOffset(oldSize);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSSegmentedVariableObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx">
</span><span class="cx"> // Adds numberOfRegistersToAdd registers, initializes them to Undefined, and returns
</span><span class="cx"> // the index of the first one added.
</span><del>- JS_EXPORT_PRIVATE ScopeOffset addVariables(unsigned numberOfVariablesToAdd);
</del><ins>+ JS_EXPORT_PRIVATE ScopeOffset addVariables(unsigned numberOfVariablesToAdd, JSValue);
</ins><span class="cx">
</span><span class="cx"> JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSSymbolTableObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -127,7 +127,7 @@
</span><span class="cx"> template<typename SymbolTableObjectType>
</span><span class="cx"> inline bool symbolTablePut(
</span><span class="cx"> SymbolTableObjectType* object, ExecState* exec, PropertyName propertyName, JSValue value,
</span><del>- bool shouldThrow)
</del><ins>+ bool shouldThrowReadOnlyError, bool ignoreReadOnlyErrors)
</ins><span class="cx"> {
</span><span class="cx"> VM& vm = exec->vm();
</span><span class="cx"> ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
</span><span class="lines">@@ -145,8 +145,8 @@
</span><span class="cx"> bool wasFat;
</span><span class="cx"> SymbolTableEntry::Fast fastEntry = iter->value.getFast(wasFat);
</span><span class="cx"> ASSERT(!fastEntry.isNull());
</span><del>- if (fastEntry.isReadOnly()) {
- if (shouldThrow)
</del><ins>+ if (fastEntry.isReadOnly() && !ignoreReadOnlyErrors) {
+ if (shouldThrowReadOnlyError)
</ins><span class="cx"> throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
</span><span class="cx"> return true;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSType.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSType.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/JSType.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -75,12 +75,10 @@
</span><span class="cx"> Float64ArrayType,
</span><span class="cx"> DataViewType,
</span><span class="cx">
</span><del>- NameScopeObjectType,
-
</del><span class="cx"> GlobalObjectType,
</span><del>- ActivationObjectType,
</del><ins>+ ClosureObjectType,
</ins><span class="cx">
</span><del>- LastJSCObjectType = ActivationObjectType,
</del><ins>+ LastJSCObjectType = ClosureObjectType,
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> COMPILE_ASSERT(sizeof(JSType) == sizeof(uint8_t), sizeof_jstype_is_one_byte);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimePutPropertySloth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/PutPropertySlot.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/PutPropertySlot.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/PutPropertySlot.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -1,6 +1,5 @@
</span><del>-// -*- mode: c++; c-basic-offset: 4 -*-
</del><span class="cx"> /*
</span><del>- * Copyright (C) 2008 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008-2015 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -43,12 +42,13 @@
</span><span class="cx"> enum Context { UnknownContext, PutById, PutByIdEval };
</span><span class="cx"> typedef void (*PutValueFunc)(ExecState*, JSObject* base, EncodedJSValue thisObject, EncodedJSValue value);
</span><span class="cx">
</span><del>- PutPropertySlot(JSValue thisValue, bool isStrictMode = false, Context context = UnknownContext)
</del><ins>+ PutPropertySlot(JSValue thisValue, bool isStrictMode = false, Context context = UnknownContext, bool isInitialization = false)
</ins><span class="cx"> : m_type(Uncachable)
</span><span class="cx"> , m_base(0)
</span><span class="cx"> , m_thisValue(thisValue)
</span><span class="cx"> , m_offset(invalidOffset)
</span><span class="cx"> , m_isStrictMode(isStrictMode)
</span><ins>+ , m_isInitialization(isInitialization)
</ins><span class="cx"> , m_context(context)
</span><span class="cx"> , m_putFunction(nullptr)
</span><span class="cx"> {
</span><span class="lines">@@ -99,6 +99,7 @@
</span><span class="cx"> bool isCacheablePut() const { return m_type == NewProperty || m_type == ExistingProperty; }
</span><span class="cx"> bool isCacheableSetter() const { return m_type == SetterProperty; }
</span><span class="cx"> bool isCacheableCustom() const { return m_type == CustomProperty; }
</span><ins>+ bool isInitialization() const { return m_isInitialization; }
</ins><span class="cx">
</span><span class="cx"> PropertyOffset cachedOffset() const
</span><span class="cx"> {
</span><span class="lines">@@ -111,6 +112,7 @@
</span><span class="cx"> JSValue m_thisValue;
</span><span class="cx"> PropertyOffset m_offset;
</span><span class="cx"> bool m_isStrictMode;
</span><ins>+ bool m_isInitialization;
</ins><span class="cx"> uint8_t m_context;
</span><span class="cx"> PutValueFunc m_putFunction;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.h (189278 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2015-09-03 19:41:42 UTC (rev 189278)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -651,6 +651,7 @@
</span><span class="cx">
</span><span class="cx"> enum ScopeType {
</span><span class="cx"> VarScope,
</span><ins>+ GlobalLexicalScope,
</ins><span class="cx"> LexicalScope,
</span><span class="cx"> CatchScope,
</span><span class="cx"> FunctionNameScope
</span><span class="lines">@@ -685,7 +686,7 @@
</span><span class="cx"> std::unique_ptr<TypeProfilingRareData> m_typeProfilingRareData;
</span><span class="cx">
</span><span class="cx"> bool m_usesNonStrictEval : 1;
</span><del>- unsigned m_scopeType : 2; // ScopeType
</del><ins>+ unsigned m_scopeType : 3; // ScopeType
</ins><span class="cx">
</span><span class="cx"> WriteBarrier<ScopedArgumentsTable> m_arguments;
</span><span class="cx"> WriteBarrier<InferredValue> m_singletonScope;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressgloballexicalletnorhsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/global-lexical-let-no-rhs.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/global-lexical-let-no-rhs.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/global-lexical-let-no-rhs.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+function assert(cond) {
+ if (!cond)
+ throw new Error("broke assertion");
+}
+noInline(assert);
+
+let x;
+function foo() {
+ return x;
+}
+for (var i = 0; i < 1000; i++) {
+ assert(x === undefined);
+ assert(foo() === undefined);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressgloballexicalredeclarevariablejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/global-lexical-redeclare-variable.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/global-lexical-redeclare-variable.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/global-lexical-redeclare-variable.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+let globalLet = "let";
+function globalFunction() { }
+class globalClass { }
+const globalConst = 20;
+var globalVar = 21;
+this.globalProperty = 22;
+
+let sentinel = "__s__";
+
+function assert(b) {
+ if (!b)
+ throw new Error("bad assertion");
+}
+
+function assertExpectations() {
+ assert(sentinel === "__s__");
+}
+
+
+let errorCount = 0;
+function assertProperError(e) {
+ if (e instanceof SyntaxError && e.message.indexOf("Can't create duplicate variable") !== -1) {
+ errorCount++;
+ } else {
+ assert(false);
+ }
+
+}
+
+assertExpectations();
+
+try {
+ load("./multiple-files-tests/global-lexical-redeclare-variable/first.js");
+} catch(e) {
+ assertProperError(e);
+}
+assertExpectations();
+
+try {
+ load("./multiple-files-tests/global-lexical-redeclare-variable/second.js");
+} catch(e) {
+ assertProperError(e);
+}
+assertExpectations();
+
+try {
+ load("./multiple-files-tests/global-lexical-redeclare-variable/third.js");
+} catch(e) {
+ assertProperError(e);
+}
+assertExpectations();
+
+try {
+ load("./multiple-files-tests/global-lexical-redeclare-variable/fourth.js");
+} catch(e) {
+ assertProperError(e);
+}
+assertExpectations();
+
+try {
+ load("./multiple-files-tests/global-lexical-redeclare-variable/fifth.js");
+} catch(e) {
+ assertProperError(e);
+}
+assertExpectations();
+
+try {
+ load("./multiple-files-tests/global-lexical-redeclare-variable/sixth.js");
+} catch(e) {
+ assertProperError(e);
+}
+assertExpectations();
+
+assert(errorCount === 6);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressgloballexicalredefineconstjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/global-lexical-redefine-const.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/global-lexical-redefine-const.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/global-lexical-redefine-const.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+load("./multiple-files-tests/global-lexical-redefine-const/first.js");
+load("./multiple-files-tests/global-lexical-redefine-const/second.js");
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressgloballexicalvarinjectionjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/global-lexical-var-injection.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/global-lexical-var-injection.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/global-lexical-var-injection.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+function assert(cond) {
+ if (!cond)
+ throw new Error("broke assertion");
+}
+noInline(assert);
+
+let foo = "foo";
+const bar = "bar";
+
+for (let i = 0; i < 1000; i++) {
+ assert(foo === "foo");
+ assert(bar === "bar");
+}
+
+eval("var INJECTION = 20");
+
+for (let i = 0; i < 100; i++) {
+ assert(foo === "foo");
+ assert(bar === "bar");
+ assert(INJECTION === 20);
+ let threw = false;
+ try {
+ eval("var foo;");
+ } catch(e) {
+ threw = true;
+ assert(e.message.indexOf("Can't create duplicate global variable in eval") !== -1);
+ }
+ assert(threw);
+ threw = false;
+ try {
+ eval("var bar;");
+ } catch(e) {
+ threw = true;
+ assert(e.message.indexOf("Can't create duplicate global variable in eval") !== -1);
+ }
+ assert(threw);
+
+ assert(foo === "foo");
+ assert(bar === "bar");
+ assert(INJECTION === 20);
+}
+
+
+var flag = false;
+function baz() {
+ if (flag) eval("var foo = 20;");
+ return foo;
+}
+
+for (var i = 0; i < 1000; i++) {
+ assert(baz() === "foo");
+ assert(baz() === foo);
+}
+flag = true;
+for (var i = 0; i < 1000; i++) {
+ assert(baz() === 20);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressgloballexicalvariabletdzjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-tdz.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-tdz.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-tdz.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+load("./multiple-files-tests/global-lexical-variable-tdz/first.js");
+load("./multiple-files-tests/global-lexical-variable-tdz/second.js");
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressgloballexicalvariableunresolvedpropertyjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-unresolved-property.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-unresolved-property.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-unresolved-property.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+load("./multiple-files-tests/global-lexical-variable-unresolved-property/first.js");
+load("./multiple-files-tests/global-lexical-variable-unresolved-property/second.js");
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressgloballexicalvariablewithstatementjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-with-statement.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-with-statement.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/global-lexical-variable-with-statement.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+function assert(cond) {
+ if (!cond)
+ throw new Error("broke assertion");
+}
+noInline(assert);
+function shouldThrowInvalidConstAssignment(f) {
+ var threw = false;
+ try {
+ f();
+ } catch(e) {
+ if (e.name.indexOf("TypeError") !== -1 && e.message.indexOf("readonly") !== -1)
+ threw = true;
+ }
+ assert(threw);
+}
+noInline(shouldThrowInvalidConstAssignment);
+
+
+function makeObj() {
+ return {foo: 20};
+}
+noInline(makeObj);
+
+let foo = "foo";
+const bar = "bar";
+
+for (var i = 0; i < 100; i++) {
+ with (makeObj()) {
+ assert(foo === 20);
+ assert(bar === "bar");
+ shouldThrowInvalidConstAssignment(function() { bar = 20; });
+ }
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablefifthjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fifth.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fifth.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fifth.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+let globalVar = "bad";
+sentinel = "bad";
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablefirstjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/first.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/first.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/first.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+let globalLet = "bad";
+sentinel = "bad";
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablefourthjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fourth.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fourth.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/fourth.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+let globalConst = "bad";
+sentinel = "bad";
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablesecondjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/second.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/second.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/second.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+let globalFunction = "bad";
+sentinel = "bad";
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablesixthjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/sixth.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/sixth.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/sixth.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+let globalProperty = "bad";
+sentinel = "bad";
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredeclarevariablethirdjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/third.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/third.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redeclare-variable/third.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+let globalClass = "bad";
+sentinel = "bad";
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredefineconstfirstjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redefine-const/first.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redefine-const/first.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redefine-const/first.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+function assert(cond) {
+ if (!cond)
+ throw new Error("broke assertion");
+}
+noInline(assert);
+function shouldThrowInvalidConstAssignment(f) {
+ var threw = false;
+ try {
+ f();
+ } catch(e) {
+ if (e.name.indexOf("TypeError") !== -1 && e.message.indexOf("readonly") !== -1)
+ threw = true;
+ }
+ assert(threw);
+}
+noInline(shouldThrowInvalidConstAssignment);
+
+
+const constValue = "const";
+const {a: destructureObj} = {a: 20};
+const [destructureArr] = [40];
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalredefineconstsecondjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redefine-const/second.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redefine-const/second.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-redefine-const/second.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+function foo() {
+ constValue = 20;
+}
+
+function bar() {
+ destructureObj = 100;
+}
+
+function baz() {
+ destructureArr = 100;
+}
+
+for (var i = 0; i < 1000; i++) {
+ shouldThrowInvalidConstAssignment(foo);
+ assert(constValue === "const");
+
+ shouldThrowInvalidConstAssignment(bar);
+ assert(destructureObj === 20);
+
+ shouldThrowInvalidConstAssignment(baz);
+ assert(destructureArr === 40);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalvariabletdzfirstjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-tdz/first.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-tdz/first.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-tdz/first.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+function assert(cond) {
+ if (!cond)
+ throw new Error("broke assertion");
+}
+noInline(assert);
+
+function shouldThrowTDZ(func) {
+ var hasThrown = false;
+ try {
+ func();
+ } catch(e) {
+ if (e.name.indexOf("ReferenceError") !== -1)
+ hasThrown = true;
+ }
+ assert(hasThrown);
+}
+noInline(shouldThrowTDZ);
+
+
+
+
+function foo() {
+ return lexicalVariableNotYetDefined;
+}
+
+function bar() {
+ lexicalVariableNotYetDefinedSecond = 300;
+ return lexicalVariableNotYetDefinedSecond;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalvariabletdzsecondjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-tdz/second.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-tdz/second.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-tdz/second.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+
+for (var i = 0; i < 1000; i++)
+ shouldThrowTDZ(foo);
+
+let lexicalVariableNotYetDefined = 100;
+assert(foo() === lexicalVariableNotYetDefined);
+
+
+for (var i = 0; i < 1000; i++)
+ shouldThrowTDZ(bar);
+let lexicalVariableNotYetDefinedSecond = 200;
+assert(bar() === 300);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalvariableunresolvedpropertyfirstjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/first.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/first.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/first.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+function assert(cond) {
+ if (!cond)
+ throw new Error("broke assertion");
+}
+noInline(assert);
+
+function shouldThrowTDZ(func) {
+ var hasThrown = false;
+ try {
+ func();
+ } catch(e) {
+ if (e.name.indexOf("ReferenceError") !== -1)
+ hasThrown = true;
+ }
+ assert(hasThrown);
+}
+noInline(shouldThrowTDZ);
+
+
+let b = false;
+function foo() {
+ if (b)
+ return x;
+}
+foo(); // Link as UnresolvedProperty.
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiplefilestestsgloballexicalvariableunresolvedpropertysecondjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/second.js (0 => 189279)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/second.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multiple-files-tests/global-lexical-variable-unresolved-property/second.js        2015-09-03 19:45:44 UTC (rev 189279)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+b = true;
+let x = "x";
+for (var i = 0; i < 1000; i++) {
+ assert(foo() === "x");
+ assert(x === "x");
+}
+
+x = 20;
+x = 40;
+for (var i = 0; i < 1000; i++) {
+ assert(foo() === 40);
+ assert(x === 40);
+}
+
</ins></span></pre>
</div>
</div>
</body>
</html>