Heap variables shouldn't end up in the stack frame
https://bugs.webkit.org/show_bug.cgi?id=141174

Reviewed by Geoffrey Garen.
Source/JavaScriptCore:

        
This is a major change to how JavaScriptCore handles declared variables (i.e. "var"). It removes
any ambiguity about whether a variable should be in the heap or on the stack. A variable will no
longer move between heap and stack during its lifetime. This enables a bunch of optimizations and
simplifications:
        
- Accesses to variables no longer need checks or indirections to determine where the variable is
  at that moment in time. For example, loading a closure variable now takes just one load instead
  of two. Loading an argument by index now takes a bounds check and a load in the fastest case
  (when no arguments object allocation is required) while previously that same operation required
  a "did I allocate arguments yet" check, a bounds check, and then the load.
        
- Reasoning about the allocation of an activation or arguments object now follows the same simple
  logic as the allocation of any other kind of object. Previously, those objects were lazily
  allocated - so an allocation instruction wasn't the actual allocation site, since it might not
  allocate anything at all. This made the implementation of traditional escape analyses really
  awkward, and ultimately it meant that we missed important cases. Now, we can reason about the
  arguments object using the usual SSA tricks which allows for more comprehensive removal.
        
- The allocations of arguments objects, functions, and activations are now much faster. While
  this patch generally expands our ability to eliminate arguments object allocations, an earlier
  version of the patch - which lacked that functionality - was a progression on some arguments-
  and closure-happy benchmarks because although no allocations were eliminated, all allocations
  were faster.
        
- There is no tear-off. The runtime no loner needs to know about where on the stack a frame keeps
  its arguments objects or activations. The runtime doesn't have to do things to the arguments
  objects and activations that a frame allocated, when the frame is unwound. We always had horrid
  bugs in that code, so it's good to see it go. This removes *a ton* of machinery from the DFG,
  FTL, CodeBlock, and other places. All of the things having to do with "captured variables" is
  now gone. This also enables implementing block-scoping. Without this change, block-scope
  support would require telling CodeBlock and all of the rest of the runtime about all of the
  variables that store currently-live scopes. That would have been so disastrously hard that it
  might as well be impossible. With this change, it's fair game for the bytecode generator to
  simply allocate whatever activations it wants, wherever it wants, and to keep them live for
  however long it wants. This all works, because after bytecode generation, an activation is just
  an object and variables that refer to it are just normal variables.
        
- SymbolTable can now tell you explicitly where a variable lives. The answer is in the form of a
  VarOffset object, which has methods like isStack(), isScope(), etc. VirtualRegister is never
  used for offsets of non-stack variables anymore. We now have shiny new objects for other kinds
  of offsets - ScopeOffset for offsets into scopes, and DirectArgumentsOffset for offsets into
  an arguments object.
        
- Functions that create activations can now tier-up into the FTL. Previously they couldn't. Also,
  using activations used to prevent inlining; now functions that use activations can be inlined
  just fine.
        
This is a >1% speed-up on Octane. This is a >2% speed-up on CompressionBench. This is a tiny
speed-up on AsmBench (~0.4% or something). This looks like it might be a speed-up on SunSpider.
It's only a slow-down on very short-running microbenchmarks we had previously written for our old
style of tear-off-based arguments optimization. Those benchmarks are not part of any major suite.
        
The easiest way of understanding this change is to start by looking at the changes in runtime/,
and then the changes in bytecompiler/, and then sort of work your way up the compiler tiers.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/AbortReason.h:
* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::BaseIndex::withOffset):
* bytecode/ByValInfo.h:
(JSC::hasOptimizableIndexingForJSType):
(JSC::hasOptimizableIndexing):
(JSC::jitArrayModeForJSType):
(JSC::jitArrayModePermitsPut):
(JSC::jitArrayModeForStructure):
* bytecode/BytecodeKills.h: Added.
(JSC::BytecodeKills::BytecodeKills):
(JSC::BytecodeKills::operandIsKilled):
(JSC::BytecodeKills::forEachOperandKilledAt):
(JSC::BytecodeKills::KillSet::KillSet):
(JSC::BytecodeKills::KillSet::add):
(JSC::BytecodeKills::KillSet::forEachLocal):
(JSC::BytecodeKills::KillSet::contains):
* bytecode/BytecodeList.json:
* bytecode/BytecodeLivenessAnalysis.cpp:
(JSC::isValidRegisterForLiveness):
(JSC::stepOverInstruction):
(JSC::BytecodeLivenessAnalysis::runLivenessFixpoint):
(JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset):
(JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset):
(JSC::BytecodeLivenessAnalysis::computeFullLiveness):
(JSC::BytecodeLivenessAnalysis::computeKills):
(JSC::indexForOperand): Deleted.
(JSC::BytecodeLivenessAnalysis::getLivenessInfoForNonCapturedVarsAtBytecodeOffset): Deleted.
(JSC::getLivenessInfo): Deleted.
* bytecode/BytecodeLivenessAnalysis.h:
* bytecode/BytecodeLivenessAnalysisInlines.h:
(JSC::operandIsAlwaysLive):
(JSC::operandThatIsNotAlwaysLiveIsLive):
(JSC::operandIsLive):
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::nameForRegister):
(JSC::CodeBlock::validate):
(JSC::CodeBlock::isCaptured): Deleted.
(JSC::CodeBlock::framePointerOffsetToGetActivationRegisters): Deleted.
(JSC::CodeBlock::machineSlowArguments): Deleted.
* bytecode/CodeBlock.h:
(JSC::unmodifiedArgumentsRegister): Deleted.
(JSC::CodeBlock::setArgumentsRegister): Deleted.
(JSC::CodeBlock::argumentsRegister): Deleted.
(JSC::CodeBlock::uncheckedArgumentsRegister): Deleted.
(JSC::CodeBlock::usesArguments): Deleted.
(JSC::CodeBlock::captureCount): Deleted.
(JSC::CodeBlock::captureStart): Deleted.
(JSC::CodeBlock::captureEnd): Deleted.
(JSC::CodeBlock::argumentIndexAfterCapture): Deleted.
(JSC::CodeBlock::hasSlowArguments): Deleted.
(JSC::ExecState::argumentAfterCapture): Deleted.
* bytecode/CodeOrigin.h:
* bytecode/DataFormat.h:
(JSC::dataFormatToString):
* bytecode/FullBytecodeLiveness.h:
(JSC::FullBytecodeLiveness::getLiveness):
(JSC::FullBytecodeLiveness::operandIsLive):
(JSC::FullBytecodeLiveness::FullBytecodeLiveness): Deleted.
(JSC::FullBytecodeLiveness::getOut): Deleted.
* bytecode/Instruction.h:
(JSC::Instruction::Instruction):
* bytecode/Operands.h:
(JSC::Operands::virtualRegisterForIndex):
* bytecode/SpeculatedType.cpp:
(JSC::dumpSpeculation):
(JSC::speculationToAbbreviatedString):
(JSC::speculationFromClassInfo):
* bytecode/SpeculatedType.h:
(JSC::isDirectArgumentsSpeculation):
(JSC::isScopedArgumentsSpeculation):
(JSC::isActionableMutableArraySpeculation):
(JSC::isActionableArraySpeculation):
(JSC::isArgumentsSpeculation): Deleted.
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::setArgumentsRegister): Deleted.
(JSC::UnlinkedCodeBlock::usesArguments): Deleted.
(JSC::UnlinkedCodeBlock::argumentsRegister): Deleted.
* bytecode/ValueRecovery.cpp:
(JSC::ValueRecovery::dumpInContext):
* bytecode/ValueRecovery.h:
(JSC::ValueRecovery::directArgumentsThatWereNotCreated):
(JSC::ValueRecovery::outOfBandArgumentsThatWereNotCreated):
(JSC::ValueRecovery::nodeID):
(JSC::ValueRecovery::argumentsThatWereNotCreated): Deleted.
* bytecode/VirtualRegister.h:
(JSC::VirtualRegister::operator==):
(JSC::VirtualRegister::operator!=):
(JSC::VirtualRegister::operator<):
(JSC::VirtualRegister::operator>):
(JSC::VirtualRegister::operator<=):
(JSC::VirtualRegister::operator>=):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::initializeNextParameter):
(JSC::BytecodeGenerator::visibleNameForParameter):
(JSC::BytecodeGenerator::emitMove):
(JSC::BytecodeGenerator::variable):
(JSC::BytecodeGenerator::createVariable):
(JSC::BytecodeGenerator::emitResolveScope):
(JSC::BytecodeGenerator::emitGetFromScope):
(JSC::BytecodeGenerator::emitPutToScope):
(JSC::BytecodeGenerator::initializeVariable):
(JSC::BytecodeGenerator::emitInstanceOf):
(JSC::BytecodeGenerator::emitNewFunction):
(JSC::BytecodeGenerator::emitNewFunctionInternal):
(JSC::BytecodeGenerator::emitCall):
(JSC::BytecodeGenerator::emitReturn):
(JSC::BytecodeGenerator::emitConstruct):
(JSC::BytecodeGenerator::isArgumentNumber):
(JSC::BytecodeGenerator::emitEnumeration):
(JSC::BytecodeGenerator::addVar): Deleted.
(JSC::BytecodeGenerator::emitInitLazyRegister): Deleted.
(JSC::BytecodeGenerator::initializeCapturedVariable): Deleted.
(JSC::BytecodeGenerator::resolveCallee): Deleted.
(JSC::BytecodeGenerator::addCallee): Deleted.
(JSC::BytecodeGenerator::addParameter): Deleted.
(JSC::BytecodeGenerator::willResolveToArgumentsRegister): Deleted.
(JSC::BytecodeGenerator::uncheckedLocalArgumentsRegister): Deleted.
(JSC::BytecodeGenerator::createLazyRegisterIfNecessary): Deleted.
(JSC::BytecodeGenerator::isCaptured): Deleted.
(JSC::BytecodeGenerator::local): Deleted.
(JSC::BytecodeGenerator::constLocal): Deleted.
(JSC::BytecodeGenerator::emitResolveConstantLocal): Deleted.
(JSC::BytecodeGenerator::emitGetArgumentsLength): Deleted.
(JSC::BytecodeGenerator::emitGetArgumentByVal): Deleted.
(JSC::BytecodeGenerator::emitLazyNewFunction): Deleted.
(JSC::BytecodeGenerator::createArgumentsIfNecessary): Deleted.
* bytecompiler/BytecodeGenerator.h:
(JSC::Variable::Variable):
(JSC::Variable::isResolved):
(JSC::Variable::ident):
(JSC::Variable::offset):
(JSC::Variable::isLocal):
(JSC::Variable::local):
(JSC::Variable::isSpecial):
(JSC::BytecodeGenerator::argumentsRegister):
(JSC::BytecodeGenerator::emitNode):
(JSC::BytecodeGenerator::registerFor):
(JSC::Local::Local): Deleted.
(JSC::Local::operator bool): Deleted.
(JSC::Local::get): Deleted.
(JSC::Local::isSpecial): Deleted.
(JSC::ResolveScopeInfo::ResolveScopeInfo): Deleted.
(JSC::ResolveScopeInfo::isLocal): Deleted.
(JSC::ResolveScopeInfo::localIndex): Deleted.
(JSC::BytecodeGenerator::hasSafeLocalArgumentsRegister): Deleted.
(JSC::BytecodeGenerator::captureMode): Deleted.
(JSC::BytecodeGenerator::shouldTearOffArgumentsEagerly): Deleted.
(JSC::BytecodeGenerator::shouldCreateArgumentsEagerly): Deleted.
(JSC::BytecodeGenerator::hasWatchableVariable): Deleted.
(JSC::BytecodeGenerator::watchableVariableIdentifier): Deleted.
* bytecompiler/NodesCodegen.cpp:
(JSC::ResolveNode::isPure):
(JSC::ResolveNode::emitBytecode):
(JSC::BracketAccessorNode::emitBytecode):
(JSC::DotAccessorNode::emitBytecode):
(JSC::EvalFunctionCallNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::CallFunctionCallDotNode::emitBytecode):
(JSC::ApplyFunctionCallDotNode::emitBytecode):
(JSC::PostfixNode::emitResolve):
(JSC::DeleteResolveNode::emitBytecode):
(JSC::TypeOfResolveNode::emitBytecode):
(JSC::PrefixNode::emitResolve):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::AssignResolveNode::emitBytecode):
(JSC::ConstDeclNode::emitCodeSingle):
(JSC::EmptyVarExpression::emitBytecode):
(JSC::ForInNode::tryGetBoundLocal):
(JSC::ForInNode::emitLoopHeader):
(JSC::ForOfNode::emitBytecode):
(JSC::ArrayPatternNode::emitDirectBinding):
(JSC::BindingNode::bindValue):
(JSC::getArgumentByVal): Deleted.
* dfg/DFGAbstractHeap.h:
* dfg/DFGAbstractInterpreter.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberWorld):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberCapturedVars): Deleted.
* dfg/DFGAbstractValue.h:
* dfg/DFGArgumentPosition.h:
(JSC::DFG::ArgumentPosition::addVariable):
* dfg/DFGArgumentsEliminationPhase.cpp: Added.
(JSC::DFG::performArgumentsElimination):
* dfg/DFGArgumentsEliminationPhase.h: Added.
* dfg/DFGArgumentsSimplificationPhase.cpp: Removed.
* dfg/DFGArgumentsSimplificationPhase.h: Removed.
* dfg/DFGArgumentsUtilities.cpp: Added.
(JSC::DFG::argumentsInvolveStackSlot):
(JSC::DFG::emitCodeToGetArgumentsArrayLength):
* dfg/DFGArgumentsUtilities.h: Added.
* dfg/DFGArrayMode.cpp:
(JSC::DFG::ArrayMode::refine):
(JSC::DFG::ArrayMode::alreadyChecked):
(JSC::DFG::arrayTypeToString):
* dfg/DFGArrayMode.h:
(JSC::DFG::ArrayMode::canCSEStorage):
(JSC::DFG::ArrayMode::modeForPut):
* dfg/DFGAvailabilityMap.cpp:
(JSC::DFG::AvailabilityMap::prune):
* dfg/DFGAvailabilityMap.h:
(JSC::DFG::AvailabilityMap::closeOverNodes):
(JSC::DFG::AvailabilityMap::closeStartingWithLocal):
* dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::propagate):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::newVariableAccessData):
(JSC::DFG::ByteCodeParser::getLocal):
(JSC::DFG::ByteCodeParser::setLocal):
(JSC::DFG::ByteCodeParser::getArgument):
(JSC::DFG::ByteCodeParser::setArgument):
(JSC::DFG::ByteCodeParser::flushDirect):
(JSC::DFG::ByteCodeParser::flush):
(JSC::DFG::ByteCodeParser::noticeArgumentsUse):
(JSC::DFG::ByteCodeParser::handleVarargsCall):
(JSC::DFG::ByteCodeParser::attemptToInlineCall):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
(JSC::DFG::ByteCodeParser::parseCodeBlock):
* dfg/DFGCPSRethreadingPhase.cpp:
(JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
(JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
* dfg/DFGCSEPhase.cpp:
* dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h: Added.
(JSC::DFG::CallCreateDirectArgumentsSlowPathGenerator::CallCreateDirectArgumentsSlowPathGenerator):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::isSupportedForInlining):
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGCommon.h:
* dfg/DFGCommonData.h:
(JSC::DFG::CommonData::CommonData):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDCEPhase.cpp:
(JSC::DFG::DCEPhase::cleanVariables):
* dfg/DFGDisassembler.h:
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGFlushFormat.cpp:
(WTF::printInternal):
* dfg/DFGFlushFormat.h:
(JSC::DFG::resultFor):
(JSC::DFG::useKindFor):
(JSC::DFG::dataFormatFor):
* dfg/DFGForAllKills.h: Added.
(JSC::DFG::forAllLiveNodesAtTail):
(JSC::DFG::forAllDirectlyKilledOperands):
(JSC::DFG::forAllKilledOperands):
(JSC::DFG::forAllKilledNodesAtNodeIndex):
(JSC::DFG::forAllKillsInBlock):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::Graph):
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::substituteGetLocal):
(JSC::DFG::Graph::livenessFor):
(JSC::DFG::Graph::killsFor):
(JSC::DFG::Graph::tryGetConstantClosureVar):
(JSC::DFG::Graph::tryGetRegisters): Deleted.
* dfg/DFGGraph.h:
(JSC::DFG::Graph::symbolTableFor):
(JSC::DFG::Graph::uses):
(JSC::DFG::Graph::bytecodeRegisterForArgument): Deleted.
(JSC::DFG::Graph::capturedVarsFor): Deleted.
(JSC::DFG::Graph::usesArguments): Deleted.
(JSC::DFG::Graph::argumentsRegisterFor): Deleted.
(JSC::DFG::Graph::machineArgumentsRegisterFor): Deleted.
(JSC::DFG::Graph::uncheckedArgumentsRegisterFor): Deleted.
* dfg/DFGHeapLocation.cpp:
(WTF::printInternal):
* dfg/DFGHeapLocation.h:
* dfg/DFGInPlaceAbstractState.cpp:
(JSC::DFG::InPlaceAbstractState::initialize):
(JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGMayExit.cpp:
(JSC::DFG::mayExit):
* dfg/DFGMinifiedID.h:
* dfg/DFGMinifiedNode.cpp:
(JSC::DFG::MinifiedNode::fromNode):
* dfg/DFGMinifiedNode.h:
(JSC::DFG::belongsInMinifiedGraph):
(JSC::DFG::MinifiedNode::hasInlineCallFrame):
(JSC::DFG::MinifiedNode::inlineCallFrame):
* dfg/DFGNode.cpp:
(JSC::DFG::Node::convertToIdentityOn):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasConstant):
(JSC::DFG::Node::constant):
(JSC::DFG::Node::hasScopeOffset):
(JSC::DFG::Node::scopeOffset):
(JSC::DFG::Node::hasDirectArgumentsOffset):
(JSC::DFG::Node::capturedArgumentsOffset):
(JSC::DFG::Node::variablePointer):
(JSC::DFG::Node::hasCallVarargsData):
(JSC::DFG::Node::hasLoadVarargsData):
(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::hasCellOperand):
(JSC::DFG::Node::objectMaterializationData):
(JSC::DFG::Node::isPhantomAllocation):
(JSC::DFG::Node::willHaveCodeGenOrOSR):
(JSC::DFG::Node::shouldSpeculateDirectArguments):
(JSC::DFG::Node::shouldSpeculateScopedArguments):
(JSC::DFG::Node::isPhantomArguments): Deleted.
(JSC::DFG::Node::hasVarNumber): Deleted.
(JSC::DFG::Node::varNumber): Deleted.
(JSC::DFG::Node::registerPointer): Deleted.
(JSC::DFG::Node::shouldSpeculateArguments): Deleted.
* dfg/DFGNodeType.h:
* dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
(JSC::DFG::OSRAvailabilityAnalysisPhase::run):
(JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
* dfg/DFGOSRExitCompiler.cpp:
(JSC::DFG::OSRExitCompiler::emitRestoreArguments):
* dfg/DFGOSRExitCompiler.h:
(JSC::DFG::OSRExitCompiler::badIndex): Deleted.
(JSC::DFG::OSRExitCompiler::initializePoisoned): Deleted.
(JSC::DFG::OSRExitCompiler::poisonIndex): Deleted.
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::reifyInlinedCallFrames):
(JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator): Deleted.
(JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator): Deleted.
(JSC::DFG::ArgumentsRecoveryGenerator::generateFor): Deleted.
* dfg/DFGOSRExitCompilerCommon.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGPreciseLocalClobberize.h:
(JSC::DFG::PreciseLocalClobberizeAdaptor::read):
(JSC::DFG::PreciseLocalClobberizeAdaptor::write):
(JSC::DFG::PreciseLocalClobberizeAdaptor::def):
(JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
(JSC::DFG::preciseLocalClobberize):
(JSC::DFG::PreciseLocalClobberizeAdaptor::writeTop): Deleted.
(JSC::DFG::forEachLocalReadByUnwind): Deleted.
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::run):
(JSC::DFG::PredictionPropagationPhase::propagate):
(JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
(JSC::DFG::PredictionPropagationPhase::propagateThroughArgumentPositions):
* dfg/DFGPromoteHeapAccess.h:
(JSC::DFG::promoteHeapAccess):
* dfg/DFGPromotedHeapLocation.cpp:
(WTF::printInternal):
* dfg/DFGPromotedHeapLocation.h:
* dfg/DFGSSAConversionPhase.cpp:
(JSC::DFG::SSAConversionPhase::run):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
(JSC::DFG::SpeculativeJIT::emitGetLength):
(JSC::DFG::SpeculativeJIT::emitGetCallee):
(JSC::DFG::SpeculativeJIT::emitGetArgumentStart):
(JSC::DFG::SpeculativeJIT::checkArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnDirectArguments):
(JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
(JSC::DFG::SpeculativeJIT::compileGetArrayLength):
(JSC::DFG::SpeculativeJIT::compileNewFunction):
(JSC::DFG::SpeculativeJIT::compileForwardVarargs):
(JSC::DFG::SpeculativeJIT::compileCreateActivation):
(JSC::DFG::SpeculativeJIT::compileCreateDirectArguments):
(JSC::DFG::SpeculativeJIT::compileGetFromArguments):
(JSC::DFG::SpeculativeJIT::compilePutToArguments):
(JSC::DFG::SpeculativeJIT::compileCreateScopedArguments):
(JSC::DFG::SpeculativeJIT::compileCreateClonedArguments):
(JSC::DFG::SpeculativeJIT::emitAllocateArguments): Deleted.
(JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): Deleted.
(JSC::DFG::SpeculativeJIT::compileGetArgumentsLength): Deleted.
(JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck): Deleted.
(JSC::DFG::SpeculativeJIT::compileNewFunctionExpression): Deleted.
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
(JSC::DFG::SpeculativeJIT::emitAllocateJSObjectWithKnownSize):
(JSC::DFG::SpeculativeJIT::emitAllocateJSObject):
(JSC::DFG::SpeculativeJIT::framePointerOffsetToGetActivationRegisters): Deleted.
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStackLayoutPhase.cpp:
(JSC::DFG::StackLayoutPhase::run):
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
* dfg/DFGStructureRegistrationPhase.cpp:
(JSC::DFG::StructureRegistrationPhase::run):
* dfg/DFGUnificationPhase.cpp:
(JSC::DFG::UnificationPhase::run):
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validateCPS):
* dfg/DFGValueSource.cpp:
(JSC::DFG::ValueSource::dump):
* dfg/DFGValueSource.h:
(JSC::DFG::dataFormatToValueSourceKind):
(JSC::DFG::valueSourceKindToDataFormat):
(JSC::DFG::ValueSource::ValueSource):
(JSC::DFG::ValueSource::forFlushFormat):
(JSC::DFG::ValueSource::valueRecovery):
* dfg/DFGVarargsForwardingPhase.cpp: Added.
(JSC::DFG::performVarargsForwarding):
* dfg/DFGVarargsForwardingPhase.h: Added.
* dfg/DFGVariableAccessData.cpp:
(JSC::DFG::VariableAccessData::VariableAccessData):
(JSC::DFG::VariableAccessData::flushFormat):
(JSC::DFG::VariableAccessData::mergeIsCaptured): Deleted.
* dfg/DFGVariableAccessData.h:
(JSC::DFG::VariableAccessData::shouldNeverUnbox):
(JSC::DFG::VariableAccessData::shouldUseDoubleFormat):
(JSC::DFG::VariableAccessData::isCaptured): Deleted.
(JSC::DFG::VariableAccessData::mergeIsArgumentsAlias): Deleted.
(JSC::DFG::VariableAccessData::isArgumentsAlias): Deleted.
* dfg/DFGVariableAccessDataDump.cpp:
(JSC::DFG::VariableAccessDataDump::dump):
* dfg/DFGVariableAccessDataDump.h:
* dfg/DFGVariableEventStream.cpp:
(JSC::DFG::VariableEventStream::tryToSetConstantRecovery):
* dfg/DFGVariableEventStream.h:
* ftl/FTLAbstractHeap.cpp:
(JSC::FTL::AbstractHeap::dump):
(JSC::FTL::AbstractField::dump):
(JSC::FTL::IndexedAbstractHeap::dump):
(JSC::FTL::NumberedAbstractHeap::dump):
(JSC::FTL::AbsoluteAbstractHeap::dump):
* ftl/FTLAbstractHeap.h:
* ftl/FTLAbstractHeapRepository.cpp:
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLCompile.cpp:
(JSC::FTL::mmAllocateDataSection):
* ftl/FTLExitArgument.cpp:
(JSC::FTL::ExitArgument::dump):
* ftl/FTLExitPropertyValue.cpp:
(JSC::FTL::ExitPropertyValue::withLocalsOffset):
* ftl/FTLExitPropertyValue.h:
* ftl/FTLExitTimeObjectMaterialization.cpp:
(JSC::FTL::ExitTimeObjectMaterialization::ExitTimeObjectMaterialization):
(JSC::FTL::ExitTimeObjectMaterialization::accountForLocalsOffset):
* ftl/FTLExitTimeObjectMaterialization.h:
(JSC::FTL::ExitTimeObjectMaterialization::origin):
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::withLocalsOffset):
(JSC::FTL::ExitValue::valueFormat):
(JSC::FTL::ExitValue::dumpInContext):
* ftl/FTLExitValue.h:
(JSC::FTL::ExitValue::isArgument):
(JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated): Deleted.
(JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated): Deleted.
(JSC::FTL::ExitValue::valueFormat): Deleted.
* ftl/FTLInlineCacheSize.cpp:
(JSC::FTL::sizeOfCallForwardVarargs):
(JSC::FTL::sizeOfConstructForwardVarargs):
(JSC::FTL::sizeOfICFor):
* ftl/FTLInlineCacheSize.h:
* ftl/FTLIntrinsicRepository.h:
* ftl/FTLJSCallVarargs.cpp:
(JSC::FTL::JSCallVarargs::JSCallVarargs):
(JSC::FTL::JSCallVarargs::emit):
* ftl/FTLJSCallVarargs.h:
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::lower):
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compilePutStack):
(JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
(JSC::FTL::LowerDFGToLLVM::compileGetByVal):
(JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
(JSC::FTL::LowerDFGToLLVM::compilePutByVal):
(JSC::FTL::LowerDFGToLLVM::compileArrayPush):
(JSC::FTL::LowerDFGToLLVM::compileArrayPop):
(JSC::FTL::LowerDFGToLLVM::compileCreateActivation):
(JSC::FTL::LowerDFGToLLVM::compileNewFunction):
(JSC::FTL::LowerDFGToLLVM::compileCreateDirectArguments):
(JSC::FTL::LowerDFGToLLVM::compileCreateScopedArguments):
(JSC::FTL::LowerDFGToLLVM::compileCreateClonedArguments):
(JSC::FTL::LowerDFGToLLVM::compileStringCharAt):
(JSC::FTL::LowerDFGToLLVM::compileStringCharCodeAt):
(JSC::FTL::LowerDFGToLLVM::compileGetGlobalVar):
(JSC::FTL::LowerDFGToLLVM::compilePutGlobalVar):
(JSC::FTL::LowerDFGToLLVM::compileGetArgumentCount):
(JSC::FTL::LowerDFGToLLVM::compileGetClosureVar):
(JSC::FTL::LowerDFGToLLVM::compilePutClosureVar):
(JSC::FTL::LowerDFGToLLVM::compileGetFromArguments):
(JSC::FTL::LowerDFGToLLVM::compilePutToArguments):
(JSC::FTL::LowerDFGToLLVM::compileCallOrConstructVarargs):
(JSC::FTL::LowerDFGToLLVM::compileForwardVarargs):
(JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorPname):
(JSC::FTL::LowerDFGToLLVM::ArgumentsLength::ArgumentsLength):
(JSC::FTL::LowerDFGToLLVM::getArgumentsLength):
(JSC::FTL::LowerDFGToLLVM::getCurrentCallee):
(JSC::FTL::LowerDFGToLLVM::getArgumentsStart):
(JSC::FTL::LowerDFGToLLVM::baseIndex):
(JSC::FTL::LowerDFGToLLVM::allocateObject):
(JSC::FTL::LowerDFGToLLVM::allocateVariableSizedObject):
(JSC::FTL::LowerDFGToLLVM::isArrayType):
(JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
(JSC::FTL::LowerDFGToLLVM::buildExitArguments):
(JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
(JSC::FTL::LowerDFGToLLVM::exitValueForNode):
(JSC::FTL::LowerDFGToLLVM::loadStructure):
(JSC::FTL::LowerDFGToLLVM::compilePhantomArguments): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileGetClosureRegisters): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileCheckArgumentsNotCreated): Deleted.
(JSC::FTL::LowerDFGToLLVM::checkArgumentsNotCreated): Deleted.
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileRecovery):
(JSC::FTL::compileStub):
* ftl/FTLOperations.cpp:
(JSC::FTL::operationMaterializeObjectInOSR):
* ftl/FTLOutput.h:
(JSC::FTL::Output::aShr):
(JSC::FTL::Output::lShr):
(JSC::FTL::Output::zeroExtPtr):
* heap/CopyToken.h:
* interpreter/CallFrame.h:
(JSC::ExecState::getArgumentUnsafe):
* interpreter/Interpreter.cpp:
(JSC::sizeOfVarargs):
(JSC::sizeFrameForVarargs):
(JSC::loadVarargs):
(JSC::unwindCallFrame):
* interpreter/Interpreter.h:
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::Frame::createArguments):
(JSC::StackVisitor::Frame::existingArguments): Deleted.
* interpreter/StackVisitor.h:
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::storeValue):
(JSC::AssemblyHelpers::loadValue):
(JSC::AssemblyHelpers::storeTrustedValue):
(JSC::AssemblyHelpers::branchIfNotCell):
(JSC::AssemblyHelpers::branchIsEmpty):
(JSC::AssemblyHelpers::argumentsStart):
(JSC::AssemblyHelpers::baselineArgumentsRegisterFor): Deleted.
(JSC::AssemblyHelpers::offsetOfLocals): Deleted.
(JSC::AssemblyHelpers::offsetOfArguments): Deleted.
* jit/CCallHelpers.h:
(JSC::CCallHelpers::setupArgument):
* jit/GPRInfo.h:
(JSC::JSValueRegs::withTwoAvailableRegs):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITCall.cpp:
(JSC::JIT::compileSetupVarargsFrame):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileSetupVarargsFrame):
* jit/JITInlines.h:
(JSC::JIT::callOperation):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_create_lexical_environment):
(JSC::JIT::emit_op_new_func):
(JSC::JIT::emit_op_create_direct_arguments):
(JSC::JIT::emit_op_create_scoped_arguments):
(JSC::JIT::emit_op_create_out_of_band_arguments):
(JSC::JIT::emit_op_tear_off_arguments): Deleted.
(JSC::JIT::emit_op_create_arguments): Deleted.
(JSC::JIT::emit_op_init_lazy_reg): Deleted.
(JSC::JIT::emit_op_get_arguments_length): Deleted.
(JSC::JIT::emitSlow_op_get_arguments_length): Deleted.
(JSC::JIT::emit_op_get_argument_by_val): Deleted.
(JSC::JIT::emitSlow_op_get_argument_by_val): Deleted.
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_create_lexical_environment):
(JSC::JIT::emit_op_tear_off_arguments): Deleted.
(JSC::JIT::emit_op_create_arguments): Deleted.
(JSC::JIT::emit_op_init_lazy_reg): Deleted.
(JSC::JIT::emit_op_get_arguments_length): Deleted.
(JSC::JIT::emitSlow_op_get_arguments_length): Deleted.
(JSC::JIT::emit_op_get_argument_by_val): Deleted.
(JSC::JIT::emitSlow_op_get_argument_by_val): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitGetClosureVar):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emit_op_get_from_arguments):
(JSC::JIT::emit_op_put_to_arguments):
(JSC::JIT::emit_op_init_global_const):
(JSC::JIT::privateCompileGetByVal):
(JSC::JIT::emitDirectArgumentsGetByVal):
(JSC::JIT::emitScopedArgumentsGetByVal):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emitGetClosureVar):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emit_op_get_from_arguments):
(JSC::JIT::emit_op_put_to_arguments):
(JSC::JIT::emit_op_init_global_const):
* jit/SetupVarargsFrame.cpp:
(JSC::emitSetupVarargsFrameFastCase):
* llint/LLIntOffsetsExtractor.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* parser/Nodes.h:
(JSC::ScopeNode::captures):
* runtime/Arguments.cpp: Removed.
* runtime/Arguments.h: Removed.
* runtime/ArgumentsMode.h: Added.
* runtime/DirectArgumentsOffset.cpp: Added.
(JSC::DirectArgumentsOffset::dump):
* runtime/DirectArgumentsOffset.h: Added.
(JSC::DirectArgumentsOffset::DirectArgumentsOffset):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/ConstantMode.cpp: Added.
(WTF::printInternal):
* runtime/ConstantMode.h:
(JSC::modeForIsConstant):
* runtime/DirectArguments.cpp: Added.
(JSC::DirectArguments::DirectArguments):
(JSC::DirectArguments::createUninitialized):
(JSC::DirectArguments::create):
(JSC::DirectArguments::createByCopying):
(JSC::DirectArguments::visitChildren):
(JSC::DirectArguments::copyBackingStore):
(JSC::DirectArguments::createStructure):
(JSC::DirectArguments::overrideThings):
(JSC::DirectArguments::overrideThingsIfNecessary):
(JSC::DirectArguments::overrideArgument):
(JSC::DirectArguments::copyToArguments):
(JSC::DirectArguments::overridesSize):
* runtime/DirectArguments.h: Added.
(JSC::DirectArguments::internalLength):
(JSC::DirectArguments::length):
(JSC::DirectArguments::canAccessIndexQuickly):
(JSC::DirectArguments::getIndexQuickly):
(JSC::DirectArguments::setIndexQuickly):
(JSC::DirectArguments::callee):
(JSC::DirectArguments::argument):
(JSC::DirectArguments::overrodeThings):
(JSC::DirectArguments::offsetOfCallee):
(JSC::DirectArguments::offsetOfLength):
(JSC::DirectArguments::offsetOfMinCapacity):
(JSC::DirectArguments::offsetOfOverrides):
(JSC::DirectArguments::storageOffset):
(JSC::DirectArguments::offsetOfSlot):
(JSC::DirectArguments::allocationSize):
(JSC::DirectArguments::storage):
* runtime/FunctionPrototype.cpp:
* runtime/GenericArguments.h: Added.
(JSC::GenericArguments::GenericArguments):
* runtime/GenericArgumentsInlines.h: Added.
(JSC::GenericArguments<Type>::getOwnPropertySlot):
(JSC::GenericArguments<Type>::getOwnPropertySlotByIndex):
(JSC::GenericArguments<Type>::getOwnPropertyNames):
(JSC::GenericArguments<Type>::put):
(JSC::GenericArguments<Type>::putByIndex):
(JSC::GenericArguments<Type>::deleteProperty):
(JSC::GenericArguments<Type>::deletePropertyByIndex):
(JSC::GenericArguments<Type>::defineOwnProperty):
(JSC::GenericArguments<Type>::copyToArguments):
* runtime/GenericOffset.h: Added.
(JSC::GenericOffset::GenericOffset):
(JSC::GenericOffset::operator!):
(JSC::GenericOffset::offsetUnchecked):
(JSC::GenericOffset::offset):
(JSC::GenericOffset::operator==):
(JSC::GenericOffset::operator!=):
(JSC::GenericOffset::operator<):
(JSC::GenericOffset::operator>):
(JSC::GenericOffset::operator<=):
(JSC::GenericOffset::operator>=):
(JSC::GenericOffset::operator+):
(JSC::GenericOffset::operator-):
(JSC::GenericOffset::operator+=):
(JSC::GenericOffset::operator-=):
* runtime/JSArgumentsIterator.cpp:
(JSC::JSArgumentsIterator::finishCreation):
(JSC::argumentsFuncIterator):
* runtime/JSArgumentsIterator.h:
(JSC::JSArgumentsIterator::create):
(JSC::JSArgumentsIterator::next):
* runtime/JSEnvironmentRecord.cpp:
(JSC::JSEnvironmentRecord::visitChildren):
* runtime/JSEnvironmentRecord.h:
(JSC::JSEnvironmentRecord::variables):
(JSC::JSEnvironmentRecord::isValid):
(JSC::JSEnvironmentRecord::variableAt):
(JSC::JSEnvironmentRecord::offsetOfVariables):
(JSC::JSEnvironmentRecord::offsetOfVariable):
(JSC::JSEnvironmentRecord::allocationSizeForScopeSize):
(JSC::JSEnvironmentRecord::allocationSize):
(JSC::JSEnvironmentRecord::JSEnvironmentRecord):
(JSC::JSEnvironmentRecord::finishCreationUninitialized):
(JSC::JSEnvironmentRecord::finishCreation):
(JSC::JSEnvironmentRecord::registers): Deleted.
(JSC::JSEnvironmentRecord::registerAt): Deleted.
(JSC::JSEnvironmentRecord::addressOfRegisters): Deleted.
(JSC::JSEnvironmentRecord::offsetOfRegisters): Deleted.
* runtime/JSFunction.cpp:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::addGlobalVar):
(JSC::JSGlobalObject::addFunction):
(JSC::JSGlobalObject::visitChildren):
(JSC::JSGlobalObject::addStaticGlobals):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::directArgumentsStructure):
(JSC::JSGlobalObject::scopedArgumentsStructure):
(JSC::JSGlobalObject::outOfBandArgumentsStructure):
(JSC::JSGlobalObject::argumentsStructure): Deleted.
* runtime/JSLexicalEnvironment.cpp:
(JSC::JSLexicalEnvironment::symbolTableGet):
(JSC::JSLexicalEnvironment::symbolTablePut):
(JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
(JSC::JSLexicalEnvironment::symbolTablePutWithAttributes):
(JSC::JSLexicalEnvironment::visitChildren): Deleted.
* runtime/JSLexicalEnvironment.h:
(JSC::JSLexicalEnvironment::create):
(JSC::JSLexicalEnvironment::JSLexicalEnvironment):
(JSC::JSLexicalEnvironment::registersOffset): Deleted.
(JSC::JSLexicalEnvironment::storageOffset): Deleted.
(JSC::JSLexicalEnvironment::storage): Deleted.
(JSC::JSLexicalEnvironment::allocationSize): Deleted.
(JSC::JSLexicalEnvironment::isValidIndex): Deleted.
(JSC::JSLexicalEnvironment::isValid): Deleted.
(JSC::JSLexicalEnvironment::registerAt): Deleted.
* runtime/JSNameScope.cpp:
(JSC::JSNameScope::visitChildren): Deleted.
* runtime/JSNameScope.h:
(JSC::JSNameScope::create):
(JSC::JSNameScope::value):
(JSC::JSNameScope::finishCreation):
(JSC::JSNameScope::JSNameScope):
* runtime/JSScope.cpp:
(JSC::abstractAccess):
* runtime/JSSegmentedVariableObject.cpp:
(JSC::JSSegmentedVariableObject::findVariableIndex):
(JSC::JSSegmentedVariableObject::addVariables):
(JSC::JSSegmentedVariableObject::visitChildren):
(JSC::JSSegmentedVariableObject::findRegisterIndex): Deleted.
(JSC::JSSegmentedVariableObject::addRegisters): Deleted.
* runtime/JSSegmentedVariableObject.h:
(JSC::JSSegmentedVariableObject::variableAt):
(JSC::JSSegmentedVariableObject::assertVariableIsInThisObject):
(JSC::JSSegmentedVariableObject::registerAt): Deleted.
(JSC::JSSegmentedVariableObject::assertRegisterIsInThisObject): Deleted.
* runtime/JSSymbolTableObject.h:
(JSC::JSSymbolTableObject::offsetOfSymbolTable):
(JSC::symbolTableGet):
(JSC::symbolTablePut):
(JSC::symbolTablePutWithAttributes):
* runtime/JSType.h:
* runtime/Options.h:
* runtime/ClonedArguments.cpp: Added.
(JSC::ClonedArguments::ClonedArguments):
(JSC::ClonedArguments::createEmpty):
(JSC::ClonedArguments::createWithInlineFrame):
(JSC::ClonedArguments::createWithMachineFrame):
(JSC::ClonedArguments::createByCopyingFrom):
(JSC::ClonedArguments::createStructure):
(JSC::ClonedArguments::getOwnPropertySlot):
(JSC::ClonedArguments::getOwnPropertyNames):
(JSC::ClonedArguments::put):
(JSC::ClonedArguments::deleteProperty):
(JSC::ClonedArguments::defineOwnProperty):
(JSC::ClonedArguments::materializeSpecials):
(JSC::ClonedArguments::materializeSpecialsIfNecessary):
* runtime/ClonedArguments.h: Added.
(JSC::ClonedArguments::specialsMaterialized):
* runtime/ScopeOffset.cpp: Added.
(JSC::ScopeOffset::dump):
* runtime/ScopeOffset.h: Added.
(JSC::ScopeOffset::ScopeOffset):
* runtime/ScopedArguments.cpp: Added.
(JSC::ScopedArguments::ScopedArguments):
(JSC::ScopedArguments::finishCreation):
(JSC::ScopedArguments::createUninitialized):
(JSC::ScopedArguments::create):
(JSC::ScopedArguments::createByCopying):
(JSC::ScopedArguments::createByCopyingFrom):
(JSC::ScopedArguments::visitChildren):
(JSC::ScopedArguments::createStructure):
(JSC::ScopedArguments::overrideThings):
(JSC::ScopedArguments::overrideThingsIfNecessary):
(JSC::ScopedArguments::overrideArgument):
(JSC::ScopedArguments::copyToArguments):
* runtime/ScopedArguments.h: Added.
(JSC::ScopedArguments::internalLength):
(JSC::ScopedArguments::length):
(JSC::ScopedArguments::canAccessIndexQuickly):
(JSC::ScopedArguments::getIndexQuickly):
(JSC::ScopedArguments::setIndexQuickly):
(JSC::ScopedArguments::callee):
(JSC::ScopedArguments::overrodeThings):
(JSC::ScopedArguments::offsetOfOverrodeThings):
(JSC::ScopedArguments::offsetOfTotalLength):
(JSC::ScopedArguments::offsetOfTable):
(JSC::ScopedArguments::offsetOfScope):
(JSC::ScopedArguments::overflowStorageOffset):
(JSC::ScopedArguments::allocationSize):
(JSC::ScopedArguments::overflowStorage):
* runtime/ScopedArgumentsTable.cpp: Added.
(JSC::ScopedArgumentsTable::ScopedArgumentsTable):
(JSC::ScopedArgumentsTable::~ScopedArgumentsTable):
(JSC::ScopedArgumentsTable::destroy):
(JSC::ScopedArgumentsTable::create):
(JSC::ScopedArgumentsTable::clone):
(JSC::ScopedArgumentsTable::setLength):
(JSC::ScopedArgumentsTable::set):
(JSC::ScopedArgumentsTable::createStructure):
* runtime/ScopedArgumentsTable.h: Added.
(JSC::ScopedArgumentsTable::length):
(JSC::ScopedArgumentsTable::get):
(JSC::ScopedArgumentsTable::lock):
(JSC::ScopedArgumentsTable::offsetOfLength):
(JSC::ScopedArgumentsTable::offsetOfArguments):
(JSC::ScopedArgumentsTable::at):
* runtime/SymbolTable.cpp:
(JSC::SymbolTableEntry::prepareToWatch):
(JSC::SymbolTable::SymbolTable):
(JSC::SymbolTable::visitChildren):
(JSC::SymbolTable::localToEntry):
(JSC::SymbolTable::entryFor):
(JSC::SymbolTable::cloneScopePart):
(JSC::SymbolTable::prepareForTypeProfiling):
(JSC::SymbolTable::uniqueIDForOffset):
(JSC::SymbolTable::globalTypeSetForOffset):
(JSC::SymbolTable::cloneCapturedNames): Deleted.
(JSC::SymbolTable::uniqueIDForRegister): Deleted.
(JSC::SymbolTable::globalTypeSetForRegister): Deleted.
* runtime/SymbolTable.h:
(JSC::SymbolTableEntry::varOffsetFromBits):
(JSC::SymbolTableEntry::scopeOffsetFromBits):
(JSC::SymbolTableEntry::Fast::varOffset):
(JSC::SymbolTableEntry::Fast::scopeOffset):
(JSC::SymbolTableEntry::Fast::isDontEnum):
(JSC::SymbolTableEntry::Fast::getAttributes):
(JSC::SymbolTableEntry::SymbolTableEntry):
(JSC::SymbolTableEntry::varOffset):
(JSC::SymbolTableEntry::isWatchable):
(JSC::SymbolTableEntry::scopeOffset):
(JSC::SymbolTableEntry::setAttributes):
(JSC::SymbolTableEntry::constantMode):
(JSC::SymbolTableEntry::isDontEnum):
(JSC::SymbolTableEntry::disableWatching):
(JSC::SymbolTableEntry::pack):
(JSC::SymbolTableEntry::isValidVarOffset):
(JSC::SymbolTable::createNameScopeTable):
(JSC::SymbolTable::maxScopeOffset):
(JSC::SymbolTable::didUseScopeOffset):
(JSC::SymbolTable::didUseVarOffset):
(JSC::SymbolTable::scopeSize):
(JSC::SymbolTable::nextScopeOffset):
(JSC::SymbolTable::takeNextScopeOffset):
(JSC::SymbolTable::add):
(JSC::SymbolTable::set):
(JSC::SymbolTable::argumentsLength):
(JSC::SymbolTable::setArgumentsLength):
(JSC::SymbolTable::argumentOffset):
(JSC::SymbolTable::setArgumentOffset):
(JSC::SymbolTable::arguments):
(JSC::SlowArgument::SlowArgument): Deleted.
(JSC::SymbolTableEntry::Fast::getIndex): Deleted.
(JSC::SymbolTableEntry::getIndex): Deleted.
(JSC::SymbolTableEntry::isValidIndex): Deleted.
(JSC::SymbolTable::captureStart): Deleted.
(JSC::SymbolTable::setCaptureStart): Deleted.
(JSC::SymbolTable::captureEnd): Deleted.
(JSC::SymbolTable::setCaptureEnd): Deleted.
(JSC::SymbolTable::captureCount): Deleted.
(JSC::SymbolTable::isCaptured): Deleted.
(JSC::SymbolTable::parameterCount): Deleted.
(JSC::SymbolTable::parameterCountIncludingThis): Deleted.
(JSC::SymbolTable::setParameterCountIncludingThis): Deleted.
(JSC::SymbolTable::slowArguments): Deleted.
(JSC::SymbolTable::setSlowArguments): Deleted.
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* runtime/VarOffset.cpp: Added.
(JSC::VarOffset::dump):
(WTF::printInternal):
* runtime/VarOffset.h: Added.
(JSC::VarOffset::VarOffset):
(JSC::VarOffset::assemble):
(JSC::VarOffset::isValid):
(JSC::VarOffset::operator!):
(JSC::VarOffset::kind):
(JSC::VarOffset::isStack):
(JSC::VarOffset::isScope):
(JSC::VarOffset::isDirectArgument):
(JSC::VarOffset::stackOffsetUnchecked):
(JSC::VarOffset::scopeOffsetUnchecked):
(JSC::VarOffset::capturedArgumentsOffsetUnchecked):
(JSC::VarOffset::stackOffset):
(JSC::VarOffset::scopeOffset):
(JSC::VarOffset::capturedArgumentsOffset):
(JSC::VarOffset::rawOffset):
(JSC::VarOffset::checkSanity):
(JSC::VarOffset::operator==):
(JSC::VarOffset::operator!=):
(JSC::VarOffset::hash):
(JSC::VarOffset::isHashTableDeletedValue):
(JSC::VarOffsetHash::hash):
(JSC::VarOffsetHash::equal):
* tests/stress/arguments-exit-strict-mode.js: Added.
* tests/stress/arguments-exit.js: Added.
* tests/stress/arguments-inlined-exit-strict-mode-fixed.js: Added.
* tests/stress/arguments-inlined-exit-strict-mode.js: Added.
* tests/stress/arguments-inlined-exit.js: Added.
* tests/stress/arguments-interference.js: Added.
* tests/stress/arguments-interference-cfg.js: Added.
* tests/stress/dead-get-closure-var.js: Added.
* tests/stress/get-declared-unpassed-argument-in-direct-arguments.js: Added.
* tests/stress/get-declared-unpassed-argument-in-scoped-arguments.js: Added.
* tests/stress/varargs-closure-inlined-exit-strict-mode.js: Added.
* tests/stress/varargs-closure-inlined-exit.js: Added.
* tests/stress/varargs-exit.js: Added.
* tests/stress/varargs-inlined-exit.js: Added.
* tests/stress/varargs-inlined-simple-exit-aliasing-weird-reversed-args.js: Added.
* tests/stress/varargs-inlined-simple-exit-aliasing-weird.js: Added.
* tests/stress/varargs-inlined-simple-exit-aliasing.js: Added.
* tests/stress/varargs-inlined-simple-exit.js: Added.
* tests/stress/varargs-too-few-arguments.js: Added.
* tests/stress/varargs-varargs-closure-inlined-exit.js: Added.
* tests/stress/varargs-varargs-inlined-exit-strict-mode.js: Added.
* tests/stress/varargs-varargs-inlined-exit.js: Added.

Source/WTF:


* wtf/FastBitVector.h:
(WTF::FastBitVector::resize): Small change: don't resize if you don't have to resize.

LayoutTests:


* js/function-apply-aliased-expected.txt:
* js/function-dot-arguments-expected.txt:
* js/regress/arguments-expected.txt: Added.
* js/regress/arguments-named-and-reflective-expected.txt: Added.
* js/regress/arguments-named-and-reflective.html: Added.
* js/regress/arguments-strict-mode-expected.txt: Added.
* js/regress/arguments-strict-mode.html: Added.
* js/regress/arguments.html: Added.
* js/regress/script-tests/arguments-named-and-reflective.js: Added.
* js/regress/script-tests/arguments-strict-mode.js: Added.
* js/regress/script-tests/arguments.js: Added.
* js/regress/script-tests/try-catch-get-by-val-cloned-arguments.js: Added.
* js/regress/script-tests/try-catch-get-by-val-direct-arguments.js: Added.
* js/regress/script-tests/try-catch-get-by-val-scoped-arguments.js: Added.
* js/regress/script-tests/varargs-call.js: Added.
* js/regress/script-tests/varargs-construct-inline.js: Added.
* js/regress/script-tests/varargs-construct.js: Added.
* js/regress/script-tests/varargs-inline.js: Added.
* js/regress/script-tests/varargs-strict-mode.js: Added.
* js/regress/script-tests/varargs.js: Added.
* js/regress/try-catch-get-by-val-cloned-arguments-expected.txt: Added.
* js/regress/try-catch-get-by-val-cloned-arguments.html: Added.
* js/regress/try-catch-get-by-val-direct-arguments-expected.txt: Added.
* js/regress/try-catch-get-by-val-direct-arguments.html: Added.
* js/regress/try-catch-get-by-val-scoped-arguments-expected.txt: Added.
* js/regress/try-catch-get-by-val-scoped-arguments.html: Added.
* js/regress/varargs-call-expected.txt: Added.
* js/regress/varargs-call.html: Added.
* js/regress/varargs-construct-expected.txt: Added.
* js/regress/varargs-construct-inline-expected.txt: Added.
* js/regress/varargs-construct-inline.html: Added.
* js/regress/varargs-construct.html: Added.
* js/regress/varargs-expected.txt: Added.
* js/regress/varargs-inline-expected.txt: Added.
* js/regress/varargs-inline.html: Added.
* js/regress/varargs-strict-mode-expected.txt: Added.
* js/regress/varargs-strict-mode.html: Added.
* js/regress/varargs.html: Added.
* js/script-tests/function-apply-aliased.js:
* js/script-tests/function-dot-arguments.js:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@181993 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index e68e162..ac5e37e 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -64,6 +64,20 @@
     SamplingRegion samplingRegion("Bytecode Generation");
     
     m_codeBlock->setThisRegister(m_thisRegister.virtualRegister());
+    
+    // If we have declared a variable named "arguments" and we are using arguments then we should
+    // perform that assignment now.
+    if (m_needToInitializeArguments)
+        initializeVariable(variable(propertyNames().arguments), m_argumentsRegister);
+    
+    {
+        RefPtr<RegisterID> temp = newTemporary();
+        for (FunctionBodyNode* functionBody : m_functionsToInitialize) {
+            emitNewFunction(temp.get(), functionBody);
+            initializeVariable(variable(functionBody->ident()), temp.get());
+        }
+    }
+    
     for (size_t i = 0; i < m_deconstructedParameters.size(); i++) {
         auto& entry = m_deconstructedParameters[i];
         entry.second->bindValue(*this, entry.first.get());
@@ -119,38 +133,13 @@
     m_codeBlock->shrinkToFit();
 
     if (m_codeBlock->symbolTable() && !m_codeBlock->vm()->typeProfiler())
-        m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneCapturedNames(*m_codeBlock->vm()));
+        m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneScopePart(*m_codeBlock->vm()));
 
     if (m_expressionTooDeep)
         return ParserError(ParserError::OutOfMemory);
     return ParserError(ParserError::ErrorNone);
 }
 
-RegisterID* BytecodeGenerator::addVar(
-    const Identifier& ident, ConstantMode constantMode, WatchMode watchMode)
-{
-    ASSERT(static_cast<size_t>(m_codeBlock->m_numVars) == m_calleeRegisters.size());
-    
-    ConcurrentJITLocker locker(symbolTable().m_lock);
-    int index = virtualRegisterForLocal(m_calleeRegisters.size()).offset();
-    SymbolTableEntry newEntry(index, constantMode == IsConstant ? ReadOnly : 0);
-    SymbolTable::Map::AddResult result = symbolTable().add(locker, ident.impl(), newEntry);
-
-    if (!result.isNewEntry)
-        return &registerFor(result.iterator->value.getIndex());
-    
-    if (watchMode == IsWatchable) {
-        while (m_watchableVariables.size() < static_cast<size_t>(m_codeBlock->m_numVars))
-            m_watchableVariables.append(Identifier());
-        m_watchableVariables.append(ident);
-    }
-    
-    RegisterID* regID = addVar();
-    ASSERT(watchMode == NotWatchable || static_cast<size_t>(m_codeBlock->m_numVars) == m_watchableVariables.size());
-    
-    return regID;
-}
-
 BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
     : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
     , m_shouldEmitProfileHooks(Options::forceProfilerBytecodeGeneration() || profilerMode == ProfilerOn)
@@ -192,7 +181,7 @@
 {
     if (m_isBuiltinFunction)
         m_shouldEmitDebugHooks = false;
-
+    
     m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
     Vector<Identifier> boundParameterProperties;
     FunctionParameters& parameters = *functionNode->parameters();
@@ -203,12 +192,35 @@
         pattern->collectBoundIdentifiers(boundParameterProperties);
         continue;
     }
-    m_symbolTable->setParameterCountIncludingThis(functionNode->parameters()->size() + 1);
+
+    bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain();
+    bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
+    bool needsArguments = functionNode->usesArguments() || codeBlock->usesEval();
+    
+    auto captures = [&] (StringImpl* uid) -> bool {
+        if (shouldCaptureAllOfTheThings)
+            return true;
+        if (!shouldCaptureSomeOfTheThings)
+            return false;
+        if (needsArguments && uid == propertyNames().arguments.impl()) {
+            // Actually, we only need to capture the arguments object when we "need full activation"
+            // because of name scopes. But historically we did it this way, so for now we just preserve
+            // the old behavior.
+            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=143072
+            return true;
+        }
+        return functionNode->captures(uid);
+    };
+    auto varKind = [&] (StringImpl* uid) -> VarKind {
+        return captures(uid) ? VarKind::Scope : VarKind::Stack;
+    };
 
     emitOpcode(op_enter);
 
     allocateAndEmitScope();
     
+    m_calleeRegister.setIndex(JSStack::Callee);
+    
     if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())
         && functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode())) {
         // When we do this, we should make our local scope stack know about the function name symbol
@@ -217,191 +229,245 @@
         // Also, we could create the scope once per JSFunction instance that needs it. That wouldn't
         // be any more correct, but it would be more performant.
         // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141887
-        RegisterID calleeRegister;
-        calleeRegister.setIndex(JSStack::Callee);
-        emitPushFunctionNameScope(m_scopeRegister, functionNode->ident(), &calleeRegister, ReadOnly | DontDelete);
+        emitPushFunctionNameScope(m_scopeRegister, functionNode->ident(), &m_calleeRegister, ReadOnly | DontDelete);
     }
 
-    if (m_codeBlock->needsFullScopeChain() || m_shouldEmitDebugHooks) {
+    if (shouldCaptureSomeOfTheThings) {
         m_lexicalEnvironmentRegister = addVar();
         m_codeBlock->setActivationRegister(m_lexicalEnvironmentRegister->virtualRegister());
         emitOpcode(op_create_lexical_environment);
         instructions().append(m_lexicalEnvironmentRegister->index());
         instructions().append(scopeRegister()->index());
+        emitOpcode(op_mov);
+        instructions().append(scopeRegister()->index());
+        instructions().append(m_lexicalEnvironmentRegister->index());
     }
-    RegisterID* localArgumentsRegister = nullptr;
-    RegisterID* scratch = addVar();
-    m_symbolTable->setCaptureStart(virtualRegisterForLocal(m_codeBlock->m_numVars).offset());
-
-    if (functionNode->usesArguments() || codeBlock->usesEval()) { // May reify arguments object.
-        RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
-        RegisterID* argumentsRegister = addVar(propertyNames().arguments, IsVariable, NotWatchable); // Can be changed by assigning to 'arguments'.
-
-        localArgumentsRegister = argumentsRegister;
-
-        // We can save a little space by hard-coding the knowledge that the two
-        // 'arguments' values are stored in consecutive registers, and storing
-        // only the index of the assignable one.
-        codeBlock->setArgumentsRegister(argumentsRegister->virtualRegister());
-        ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->virtualRegister() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister()));
-
-        emitInitLazyRegister(argumentsRegister);
-        emitInitLazyRegister(unmodifiedArgumentsRegister);
-        
-        if (shouldCreateArgumentsEagerly() || shouldTearOffArgumentsEagerly()) {
-            emitOpcode(op_create_arguments);
-            instructions().append(argumentsRegister->index());
-            instructions().append(m_codeBlock->activationRegister().offset());
-
-            if (m_codeBlock->hasActivationRegister()) {
-                RegisterID* argumentsRegister = &registerFor(m_codeBlock->argumentsRegister().offset());
-                initializeCapturedVariable(argumentsRegister, propertyNames().arguments, argumentsRegister);
-                RegisterID* uncheckedArgumentsRegister = &registerFor(JSC::unmodifiedArgumentsRegister(m_codeBlock->argumentsRegister()).offset());
-                initializeCapturedVariable(uncheckedArgumentsRegister, propertyNames().arguments, uncheckedArgumentsRegister);
-                if (functionNode->modifiesArguments()) {
-                    emitOpcode(op_mov);
-                    instructions().append(argumentsRegister->index());
-                    instructions().append(addConstantValue(jsUndefined())->index());
-                    emitOpcode(op_mov);
-                    instructions().append(uncheckedArgumentsRegister->index());
-                    instructions().append(addConstantValue(jsUndefined())->index());
-                    localArgumentsRegister = nullptr;
-                }
-            }
-        }
+    
+    // Make sure the code block knows about all of our parameters, and make sure that parameters
+    // needing deconstruction are noted.
+    m_parameters.grow(parameters.size() + 1); // reserve space for "this"
+    m_thisRegister.setIndex(initializeNextParameter()->index()); // this
+    for (unsigned i = 0; i < parameters.size(); ++i) {
+        auto pattern = parameters.at(i);
+        RegisterID* reg = initializeNextParameter();
+        if (!pattern->isBindingNode())
+            m_deconstructedParameters.append(std::make_pair(reg, pattern));
     }
-
-    bool shouldCaptureAllTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
-
+    
+    // Figure out some interesting facts about our arguments.
     bool capturesAnyArgumentByName = false;
-    Vector<RegisterID*, 0, UnsafeVectorOverflow> capturedArguments;
-    if (functionNode->hasCapturedVariables() || shouldCaptureAllTheThings) {
+    if (functionNode->hasCapturedVariables()) {
         FunctionParameters& parameters = *functionNode->parameters();
-        capturedArguments.resize(parameters.size());
         for (size_t i = 0; i < parameters.size(); ++i) {
-            capturedArguments[i] = 0;
             auto pattern = parameters.at(i);
             if (!pattern->isBindingNode())
                 continue;
             const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
-            if (!functionNode->captures(ident) && !shouldCaptureAllTheThings)
-                continue;
-            capturesAnyArgumentByName = true;
-            capturedArguments[i] = addVar(ident, IsVariable, IsWatchable);
+            capturesAnyArgumentByName |= captures(ident.impl());
         }
     }
 
-    if (capturesAnyArgumentByName && !shouldTearOffArgumentsEagerly()) {
-        size_t parameterCount = m_symbolTable->parameterCount();
-        auto slowArguments = std::make_unique<SlowArgument[]>(parameterCount);
-        for (size_t i = 0; i < parameterCount; ++i) {
-            if (!capturedArguments[i]) {
-                ASSERT(slowArguments[i].status == SlowArgument::Normal);
-                slowArguments[i].index = CallFrame::argumentOffset(i);
-                continue;
-            }
-            slowArguments[i].status = SlowArgument::Captured;
-            slowArguments[i].index = capturedArguments[i]->index();
-        }
-        m_symbolTable->setSlowArguments(WTF::move(slowArguments));
-    }
-
-    RegisterID* calleeRegister = resolveCallee(functionNode); // May push to the scope chain and/or add a captured var.
-
-    const DeclarationStacks::FunctionStack& functionStack = functionNode->functionStack();
-    const DeclarationStacks::VarStack& varStack = functionNode->varStack();
-    IdentifierSet test;
-
-    // Captured variables and functions go first so that activations don't have
-    // to step over the non-captured locals to mark them.
-    if (functionNode->hasCapturedVariables() || shouldCaptureAllTheThings) {
-        for (size_t i = 0; i < boundParameterProperties.size(); i++) {
-            const Identifier& ident = boundParameterProperties[i];
-            if (functionNode->captures(ident) || shouldCaptureAllTheThings)
-                addVar(ident, IsVariable, IsWatchable);
-        }
-        for (size_t i = 0; i < functionStack.size(); ++i) {
-            FunctionBodyNode* function = functionStack[i];
-            const Identifier& ident = function->ident();
-            if (functionNode->captures(ident) || shouldCaptureAllTheThings) {
-                m_functions.add(ident.impl());
-                emitNewFunction(scratch, function);
-                initializeCapturedVariable(addVar(ident, IsVariable, IsWatchable), ident, scratch);
-            }
-        }
-        for (size_t i = 0; i < varStack.size(); ++i) {
-            const Identifier& ident = varStack[i].first;
-            if (functionNode->captures(ident) || shouldCaptureAllTheThings)
-                addVar(ident, (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, IsWatchable);
-        }
-    }
-
-    m_symbolTable->setCaptureEnd(virtualRegisterForLocal(codeBlock->m_numVars).offset());
-
-    bool canLazilyCreateFunctions = !functionNode->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks && !m_vm->typeProfiler() && !m_vm->controlFlowProfiler();
-    m_firstLazyFunction = codeBlock->m_numVars;
-    if (!shouldCaptureAllTheThings) {
-        for (size_t i = 0; i < functionStack.size(); ++i) {
-            FunctionBodyNode* function = functionStack[i];
-            const Identifier& ident = function->ident();
-            if (!functionNode->captures(ident)) {
-                m_functions.add(ident.impl());
-                RefPtr<RegisterID> reg = addVar(ident, IsVariable, NotWatchable);
-                // Don't lazily create functions that override the name 'arguments'
-                // as this would complicate lazy instantiation of actual arguments.
-                if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
-                    emitNewFunction(reg.get(), function);
-                else {
-                    emitInitLazyRegister(reg.get());
-                    m_lazyFunctions.set(reg->virtualRegister().toLocal(), function);
-                }
-            }
-        }
-        m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction;
-        for (size_t i = 0; i < boundParameterProperties.size(); i++) {
-            const Identifier& ident = boundParameterProperties[i];
-            if (!functionNode->captures(ident))
-                addVar(ident, IsVariable, IsWatchable);
-        }
-        for (size_t i = 0; i < varStack.size(); ++i) {
-            const Identifier& ident = varStack[i].first;
-            if (!functionNode->captures(ident))
-                addVar(ident, (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, NotWatchable);
-        }
-    }
-
-    if (m_symbolTable->captureCount())
-        emitOpcode(op_touch_entry);
+    if (capturesAnyArgumentByName)
+        ASSERT(m_lexicalEnvironmentRegister);
     
-    m_parameters.grow(parameters.size() + 1); // reserve space for "this"
-
-    // Add "this" as a parameter
-    int nextParameterIndex = CallFrame::thisArgumentOffset();
-    m_thisRegister.setIndex(nextParameterIndex++);
-    m_codeBlock->addParameter();
-
-    for (size_t i = 0; i < parameters.size(); ++i, ++nextParameterIndex) {
-        int index = nextParameterIndex;
-        auto pattern = parameters.at(i);
-        if (!pattern->isBindingNode()) {
-            m_codeBlock->addParameter();
-            RegisterID& parameter = registerFor(index);
-            parameter.setIndex(index);
-            m_deconstructedParameters.append(std::make_pair(&parameter, pattern));
-            continue;
-        }
-        auto simpleParameter = static_cast<const BindingNode*>(pattern);
-        if (capturedArguments.size() && capturedArguments[i] && !m_functions.contains(simpleParameter->boundProperty().impl())) {
-            ASSERT((functionNode->hasCapturedVariables() && functionNode->captures(simpleParameter->boundProperty())) || shouldCaptureAllTheThings);
-            index = capturedArguments[i]->index();
-            RegisterID original(nextParameterIndex);
-            initializeCapturedVariable(capturedArguments[i], simpleParameter->boundProperty(), &original);
-        }
-        addParameter(simpleParameter->boundProperty(), index);
+    // Need to know what our functions are called. Parameters have some goofy behaviors when it
+    // comes to functions of the same name.
+    for (FunctionBodyNode* function : functionNode->functionStack())
+        m_functions.add(function->ident().impl());
+    
+    if (needsArguments) {
+        // Create the arguments object now. We may put the arguments object into the activation if
+        // it is captured. Either way, we create two arguments object variables: one is our
+        // private variable that is immutable, and another that is the user-visible variable. The
+        // immutable one is only used here, or during formal parameter resolutions if we opt for
+        // DirectArguments.
+        
+        m_argumentsRegister = addVar();
+        m_argumentsRegister->ref();
     }
-
-    // We declare the callee's name last because it should lose to a var, function, and/or parameter declaration.
-    addCallee(functionNode, calleeRegister);
+    
+    if (needsArguments && !codeBlock->isStrictMode()) {
+        // If we captured any formal parameter by name, then we use ScopedArguments. Otherwise we
+        // use DirectArguments. With ScopedArguments, we lift all of our arguments into the
+        // activation.
+        
+        if (capturesAnyArgumentByName) {
+            m_symbolTable->setArgumentsLength(vm, parameters.size());
+            
+            // For each parameter, we have two possibilities:
+            // Either it's a binding node with no function overlap, in which case it gets a name
+            // in the symbol table - or it just gets space reserved in the symbol table. Either
+            // way we lift the value into the scope.
+            for (unsigned i = 0; i < parameters.size(); ++i) {
+                ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
+                m_symbolTable->setArgumentOffset(vm, i, offset);
+                if (StringImpl* name = visibleNameForParameter(parameters.at(i))) {
+                    VarOffset varOffset(offset);
+                    SymbolTableEntry entry(varOffset);
+                    // Stores to these variables via the ScopedArguments object will not do
+                    // notifyWrite(), since that would be cumbersome. Also, watching formal
+                    // parameters when "arguments" is in play is unlikely to be super profitable.
+                    // So, we just disable it.
+                    entry.disableWatching();
+                    m_symbolTable->set(name, entry);
+                }
+                emitOpcode(op_put_to_scope);
+                instructions().append(m_lexicalEnvironmentRegister->index());
+                instructions().append(UINT_MAX);
+                instructions().append(virtualRegisterForArgument(1 + i).offset());
+                instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
+                instructions().append(0);
+                instructions().append(offset.offset());
+            }
+            
+            // This creates a scoped arguments object and copies the overflow arguments into the
+            // scope. It's the equivalent of calling ScopedArguments::createByCopying().
+            emitOpcode(op_create_scoped_arguments);
+            instructions().append(m_argumentsRegister->index());
+            instructions().append(m_lexicalEnvironmentRegister->index());
+        } else {
+            // We're going to put all parameters into the DirectArguments object. First ensure
+            // that the symbol table knows that this is happening.
+            for (unsigned i = 0; i < parameters.size(); ++i) {
+                if (StringImpl* name = visibleNameForParameter(parameters.at(i)))
+                    m_symbolTable->set(name, SymbolTableEntry(VarOffset(DirectArgumentsOffset(i))));
+            }
+            
+            emitOpcode(op_create_direct_arguments);
+            instructions().append(m_argumentsRegister->index());
+        }
+    } else {
+        // Create the formal parameters the normal way. Any of them could be captured, or not. If
+        // captured, lift them into the scope.
+        for (unsigned i = 0; i < parameters.size(); ++i) {
+            StringImpl* name = visibleNameForParameter(parameters.at(i));
+            if (!name)
+                continue;
+            
+            if (!captures(name)) {
+                // This is the easy case - just tell the symbol table about the argument. It will
+                // be accessed directly.
+                m_symbolTable->set(name, SymbolTableEntry(VarOffset(virtualRegisterForArgument(1 + i))));
+                continue;
+            }
+            
+            ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
+            const Identifier& ident =
+                static_cast<const BindingNode*>(parameters.at(i))->boundProperty();
+            m_symbolTable->set(name, SymbolTableEntry(VarOffset(offset)));
+            
+            emitOpcode(op_put_to_scope);
+            instructions().append(m_lexicalEnvironmentRegister->index());
+            instructions().append(addConstant(ident));
+            instructions().append(virtualRegisterForArgument(1 + i).offset());
+            instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
+            instructions().append(0);
+            instructions().append(offset.offset());
+        }
+    }
+    
+    if (needsArguments && codeBlock->isStrictMode()) {
+        // Allocate an out-of-bands arguments object.
+        emitOpcode(op_create_out_of_band_arguments);
+        instructions().append(m_argumentsRegister->index());
+    }
+    
+    // Now declare all variables.
+    for (const Identifier& ident : boundParameterProperties)
+        createVariable(ident, varKind(ident.impl()), IsVariable);
+    for (FunctionBodyNode* function : functionNode->functionStack()) {
+        const Identifier& ident = function->ident();
+        createVariable(ident, varKind(ident.impl()), IsVariable);
+        m_functionsToInitialize.append(function);
+    }
+    for (auto& entry : functionNode->varStack()) {
+        ConstantMode constantMode = modeForIsConstant(entry.second & DeclarationStacks::IsConstant);
+        // Variables named "arguments" are never const.
+        if (entry.first == propertyNames().arguments)
+            constantMode = IsVariable;
+        createVariable(entry.first, varKind(entry.first.impl()), constantMode, IgnoreExisting);
+    }
+    
+    // There are some variables that need to be preinitialized to something other than Undefined:
+    //
+    // - "arguments": unless it's used as a function or parameter, this should refer to the
+    //   arguments object.
+    //
+    // - callee: unless it's used as a var, function, or parameter, this should refer to the
+    //   callee (i.e. our function).
+    //
+    // - functions: these always override everything else.
+    //
+    // The most logical way to do all of this is to initialize none of the variables until now,
+    // and then initialize them in BytecodeGenerator::generate() in such an order that the rules
+    // for how these things override each other end up holding. We would initialize the callee
+    // first, then "arguments", then all arguments, then the functions.
+    //
+    // But some arguments are already initialized by default, since if they aren't captured and we
+    // don't have "arguments" then we just point the symbol table at the stack slot of those
+    // arguments. We end up initializing the rest of the arguments that have an uncomplicated
+    // binding (i.e. don't involve deconstruction) above when figuring out how to lay them out,
+    // because that's just the simplest thing. This means that when we initialize them, we have to
+    // watch out for the things that override arguments (namely, functions).
+    //
+    // We also initialize callee here as well, just because it's so weird. We know whether we want
+    // to do this because we can just check if it's in the symbol table.
+    if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())
+        && !functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode())
+        && m_symbolTable->get(functionNode->ident().impl()).isNull()) {
+        if (captures(functionNode->ident().impl())) {
+            ScopeOffset offset;
+            {
+                ConcurrentJITLocker locker(m_symbolTable->m_lock);
+                offset = m_symbolTable->takeNextScopeOffset(locker);
+                m_symbolTable->add(
+                    locker, functionNode->ident().impl(),
+                    SymbolTableEntry(VarOffset(offset), ReadOnly));
+            }
+            
+            emitOpcode(op_put_to_scope);
+            instructions().append(m_lexicalEnvironmentRegister->index());
+            instructions().append(addConstant(functionNode->ident()));
+            instructions().append(m_calleeRegister.index());
+            instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
+            instructions().append(0);
+            instructions().append(offset.offset());
+        } else {
+            m_symbolTable->add(
+                functionNode->ident().impl(),
+                SymbolTableEntry(VarOffset(m_calleeRegister.virtualRegister()), ReadOnly));
+        }
+    }
+    
+    // This is our final act of weirdness. "arguments" is overridden by everything except the
+    // callee. We add it to the symbol table if it's not already there and it's not an argument.
+    if (needsArguments) {
+        // If "arguments" is overridden by a function or deconstructed parameter name, then it's
+        // OK for us to call createVariable() because it won't change anything. It's also OK for
+        // us to them tell BytecodeGenerator::generate() to write to it because it will do so
+        // before it initializes functions and deconstructed parameters. But if "arguments" is
+        // overridden by a "simple" function parameter, then we have to bail: createVariable()
+        // would assert and BytecodeGenerator::generate() would write the "arguments" after the
+        // argument value had already been properly initialized.
+        
+        bool haveParameterNamedArguments = false;
+        for (unsigned i = 0; i < parameters.size(); ++i) {
+            StringImpl* name = visibleNameForParameter(parameters.at(i));
+            if (name == propertyNames().arguments.impl()) {
+                haveParameterNamedArguments = true;
+                break;
+            }
+        }
+        
+        if (!haveParameterNamedArguments) {
+            createVariable(
+                propertyNames().arguments, varKind(propertyNames().arguments.impl()), IsVariable);
+            m_needToInitializeArguments = true;
+        }
+    }
+    
+    if (m_symbolTable->scopeSize())
+        emitOpcode(op_touch_entry);
 
     if (isConstructor()) {
         if (constructorKind() == ConstructorKind::Derived) {
@@ -419,7 +485,6 @@
         instructions().append(0);
         instructions().append(0);
     }
-    m_localArgumentsRegister = localArgumentsRegister;
 }
 
 BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
@@ -458,108 +523,23 @@
 {
 }
 
-RegisterID* BytecodeGenerator::emitInitLazyRegister(RegisterID* reg)
+RegisterID* BytecodeGenerator::initializeNextParameter()
 {
-    emitOpcode(op_init_lazy_reg);
-    instructions().append(reg->index());
-    ASSERT(!hasWatchableVariable(reg->index()));
-    return reg;
-}
-
-RegisterID* BytecodeGenerator::initializeCapturedVariable(RegisterID* dst, const Identifier& propertyName, RegisterID* value)
-{
-
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
-    emitOpcode(op_put_to_scope);
-    instructions().append(m_lexicalEnvironmentRegister->index());
-    instructions().append(addConstant(propertyName));
-    instructions().append(value->index());
-    instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
-    int operand = registerFor(dst->index()).index();
-    bool isWatchableVariable = hasWatchableVariable(operand);
-    ASSERT(!isWatchableVariable || watchableVariableIdentifier(operand) == propertyName);
-    instructions().append(isWatchableVariable);
-    instructions().append(dst->index());
-    return dst;
-}
-
-RegisterID* BytecodeGenerator::resolveCallee(FunctionNode* functionNode)
-{
-    if (!functionNameIsInScope(functionNode->ident(), functionNode->functionMode()))
-        return 0;
-
-    if (functionNameScopeIsDynamic(m_codeBlock->usesEval(), m_codeBlock->isStrictMode()))
-        return 0;
-
-    m_calleeRegister.setIndex(JSStack::Callee);
-    if (functionNode->captures(functionNode->ident()))
-        return initializeCapturedVariable(addVar(), functionNode->ident(), &m_calleeRegister);
-
-    return &m_calleeRegister;
-}
-
-void BytecodeGenerator::addCallee(FunctionNode* functionNode, RegisterID* calleeRegister)
-{
-    if (!calleeRegister)
-        return;
-
-    symbolTable().add(functionNode->ident().impl(), SymbolTableEntry(calleeRegister->index(), ReadOnly));
-}
-
-void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex)
-{
-    // Parameters overwrite var declarations, but not function declarations.
-    StringImpl* rep = ident.impl();
-    if (!m_functions.contains(rep)) {
-        symbolTable().set(rep, parameterIndex);
-        RegisterID& parameter = registerFor(parameterIndex);
-        parameter.setIndex(parameterIndex);
-    }
-
-    // To maintain the calling convention, we have to allocate unique space for
-    // each parameter, even if the parameter doesn't make it into the symbol table.
+    VirtualRegister reg = virtualRegisterForArgument(m_codeBlock->numParameters());
+    RegisterID& parameter = registerFor(reg);
+    parameter.setIndex(reg.offset());
     m_codeBlock->addParameter();
+    return &parameter;
 }
 
-bool BytecodeGenerator::willResolveToArgumentsRegister(const Identifier& ident)
+StringImpl* BytecodeGenerator::visibleNameForParameter(DeconstructionPatternNode* pattern)
 {
-    if (ident != propertyNames().arguments)
-        return false;
-    
-    if (!shouldOptimizeLocals())
-        return false;
-    
-    SymbolTableEntry entry = symbolTable().get(ident.impl());
-    if (entry.isNull())
-        return false;
-
-    if (m_localArgumentsRegister && isCaptured(m_localArgumentsRegister->index()) && m_lexicalEnvironmentRegister)
-        return false;
-
-    if (m_codeBlock->usesArguments() && m_codeType == FunctionCode && m_localArgumentsRegister)
-        return true;
-    
-    return false;
-}
-
-RegisterID* BytecodeGenerator::uncheckedLocalArgumentsRegister()
-{
-    ASSERT(willResolveToArgumentsRegister(propertyNames().arguments));
-    ASSERT(m_localArgumentsRegister);
-    return m_localArgumentsRegister;
-}
-
-RegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg)
-{
-    if (!reg->virtualRegister().isLocal())
-        return reg;
-
-    int localVariableNumber = reg->virtualRegister().toLocal();
-
-    if (m_lastLazyFunction <= localVariableNumber || localVariableNumber < m_firstLazyFunction)
-        return reg;
-    emitLazyNewFunction(reg, m_lazyFunctions.get(localVariableNumber));
-    return reg;
+    if (pattern->isBindingNode()) {
+        const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
+        if (!m_functions.contains(ident.impl()))
+            return ident.impl();
+    }
+    return nullptr;
 }
 
 RegisterID* BytecodeGenerator::newRegister()
@@ -964,7 +944,7 @@
     StringImpl* rep = ident.impl();
     return m_identifierMap.contains(rep);
 }
-    
+
 unsigned BytecodeGenerator::addConstant(const Identifier& ident)
 {
     StringImpl* rep = ident.impl();
@@ -1015,7 +995,6 @@
 RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
 {
     m_staticPropertyAnalyzer.mov(dst->index(), src->index());
-    ASSERT(dst->virtualRegister() == m_codeBlock->argumentsRegister() || !isCaptured(dst->index()));
     emitOpcode(op_mov);
     instructions().append(dst->index());
     instructions().append(src->index());
@@ -1197,51 +1176,96 @@
     return m_globalObjectRegister;
 }
 
-bool BytecodeGenerator::isCaptured(int operand)
+Variable BytecodeGenerator::variable(const Identifier& property)
 {
-    return m_symbolTable && m_symbolTable->isCaptured(operand);
-}
-
-Local BytecodeGenerator::local(const Identifier& property)
-{
-    if (property == propertyNames().thisIdentifier)
-        return Local(thisRegister(), ReadOnly, Local::SpecialLocal);
-    bool isArguments = property == propertyNames().arguments;
-    if (isArguments)
-        createArgumentsIfNecessary();
-
+    if (property == propertyNames().thisIdentifier) {
+        return Variable(
+            property, VarOffset(thisRegister()->virtualRegister()), thisRegister(),
+            ReadOnly, Variable::SpecialVariable);
+    }
+    
     if (!shouldOptimizeLocals())
-        return Local();
-
+        return Variable(property);
+    
     SymbolTableEntry entry = symbolTable().get(property.impl());
     if (entry.isNull())
-        return Local();
-
-
-    RegisterID* local = createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
-
-    if (isCaptured(local->index()) && m_lexicalEnvironmentRegister)
-        return Local();
-
-    return Local(local, entry.getAttributes(), isArguments ? Local::SpecialLocal : Local::NormalLocal);
+        return Variable(property);
+    
+    if (entry.varOffset().isScope() && m_localScopeDepth) {
+        // FIXME: We should be able to statically resolve through our local scopes.
+        // https://bugs.webkit.org/show_bug.cgi?id=141885
+        return Variable(property);
+    }
+    
+    return variableForLocalEntry(property, entry);
 }
 
-Local BytecodeGenerator::constLocal(const Identifier& property)
+Variable BytecodeGenerator::variablePerSymbolTable(const Identifier& property)
 {
-    if (m_codeType != FunctionCode)
-        return Local();
-
     SymbolTableEntry entry = symbolTable().get(property.impl());
     if (entry.isNull())
-        return Local();
+        return Variable(property);
+    
+    return variableForLocalEntry(property, entry);
+}
 
-    RegisterID* local = createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
+Variable BytecodeGenerator::variableForLocalEntry(
+    const Identifier& property, const SymbolTableEntry& entry)
+{
+    VarOffset offset = entry.varOffset();
+    
+    RegisterID* local;
+    if (offset.isStack())
+        local = &registerFor(offset.stackOffset());
+    else
+        local = nullptr;
+    
+    return Variable(property, offset, local, entry.getAttributes(), Variable::NormalVariable);
+}
 
-    bool isArguments = property == propertyNames().arguments;
-    if (isCaptured(local->index()) && m_lexicalEnvironmentRegister)
-        return Local();
+void BytecodeGenerator::createVariable(
+    const Identifier& property, VarKind varKind, ConstantMode constantMode,
+    ExistingVariableMode existingVariableMode)
+{
+    ASSERT(property != propertyNames().thisIdentifier);
+    
+    ConcurrentJITLocker locker(symbolTable().m_lock);
+    SymbolTableEntry entry = symbolTable().get(locker, property.impl());
+    
+    if (!entry.isNull()) {
+        if (existingVariableMode == IgnoreExisting)
+            return;
+        
+        // Do some checks to ensure that the variable we're being asked to create is sufficiently
+        // compatible with the one we have already created.
 
-    return Local(local, entry.getAttributes(), isArguments ? Local::SpecialLocal : Local::NormalLocal);
+        VarOffset offset = entry.varOffset();
+        
+        // We can't change our minds about whether it's captured.
+        if (offset.kind() != varKind || constantMode != entry.constantMode()) {
+            dataLog(
+                "Trying to add variable called ", property, " as ", varKind, "/", constantMode,
+                " but it was already added as ", offset, "/", entry.constantMode(), ".\n");
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+
+        return;
+    }
+    
+    VarOffset varOffset;
+    if (varKind == VarKind::Scope)
+        varOffset = VarOffset(symbolTable().takeNextScopeOffset(locker));
+    else {
+        ASSERT(varKind == VarKind::Stack);
+        varOffset = VarOffset(virtualRegisterForLocal(m_calleeRegisters.size()));
+    }
+    SymbolTableEntry newEntry(varOffset, constantMode == IsConstant ? ReadOnly : 0);
+    symbolTable().add(locker, property.impl(), newEntry);
+    
+    if (varKind == VarKind::Stack) {
+        RegisterID* local = addVar();
+        RELEASE_ASSERT(local->index() == varOffset.stackOffset().offset());
+    }
 }
 
 void BytecodeGenerator::emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target)
@@ -1265,88 +1289,147 @@
     return GlobalProperty;
 }
 
-RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Identifier& identifier, ResolveScopeInfo& info)
+RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Variable& variable)
 {
-    if (m_symbolTable && m_codeType == FunctionCode && !m_localScopeDepth) {
-        SymbolTableEntry entry = m_symbolTable->get(identifier.impl());
-        if (!entry.isNull()) {
-            info = ResolveScopeInfo(entry.getIndex());
-            return scopeRegister();
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        return nullptr;
+        
+    case VarKind::DirectArgument:
+        return argumentsRegister();
+        
+    case VarKind::Scope:
+        // This always refers to the activation that *we* allocated, and not the current scope that code
+        // lives in. Note that this will change once we have proper support for block scoping. Once that
+        // changes, it will be correct for this code to return scopeRegister(). The only reason why we
+        // don't do that already is that m_lexicalEnvironment is required by ConstDeclNode. ConstDeclNode
+        // requires weird things because it is a shameful pile of nonsense, but block scoping would make
+        // that code sensible and obviate the need for us to do bad things.
+        return m_lexicalEnvironmentRegister;
+        
+    case VarKind::Invalid:
+        // Indicates non-local resolution.
+        
+        ASSERT(!m_symbolTable || !m_symbolTable->contains(variable.ident().impl()) || resolveType() == Dynamic);
+        
+        m_codeBlock->addPropertyAccessInstruction(instructions().size());
+        
+        // resolve_scope dst, id, ResolveType, depth
+        emitOpcode(op_resolve_scope);
+        dst = tempDestination(dst);
+        instructions().append(kill(dst));
+        instructions().append(scopeRegister()->index());
+        instructions().append(addConstant(variable.ident()));
+        instructions().append(resolveType());
+        instructions().append(0);
+        instructions().append(0);
+        return dst;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable& variable, ResolveMode resolveMode)
+{
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        return emitMove(dst, variable.local());
+        
+    case VarKind::DirectArgument: {
+        UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_arguments);
+        instructions().append(kill(dst));
+        instructions().append(scope->index());
+        instructions().append(variable.offset().capturedArgumentsOffset().offset());
+        instructions().append(profile);
+        return dst;
+    }
+        
+    case VarKind::Scope:
+    case VarKind::Invalid: {
+        m_codeBlock->addPropertyAccessInstruction(instructions().size());
+        
+        // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
+        UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
+        instructions().append(kill(dst));
+        instructions().append(scope->index());
+        instructions().append(addConstant(variable.ident()));
+        instructions().append(ResolveModeAndType(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType()).operand());
+        instructions().append(0);
+        instructions().append(variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
+        instructions().append(profile);
+        return dst;
+    } }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Variable& variable, RegisterID* value, ResolveMode resolveMode)
+{
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        emitMove(variable.local(), value);
+        return value;
+        
+    case VarKind::DirectArgument:
+        emitOpcode(op_put_to_arguments);
+        instructions().append(scope->index());
+        instructions().append(variable.offset().capturedArgumentsOffset().offset());
+        instructions().append(value->index());
+        return value;
+        
+    case VarKind::Scope:
+    case VarKind::Invalid: {
+        m_codeBlock->addPropertyAccessInstruction(instructions().size());
+        
+        // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
+        emitOpcode(op_put_to_scope);
+        instructions().append(scope->index());
+        instructions().append(addConstant(variable.ident()));
+        instructions().append(value->index());
+        ScopeOffset offset;
+        if (variable.offset().isScope()) {
+            offset = variable.offset().scopeOffset();
+            instructions().append(ResolveModeAndType(resolveMode, LocalClosureVar).operand());
+        } else {
+            ASSERT(resolveType() != LocalClosureVar);
+            instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
         }
+        instructions().append(0);
+        instructions().append(!!offset ? offset.offset() : 0);
+        return value;
+    } }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+RegisterID* BytecodeGenerator::initializeVariable(const Variable& variable, RegisterID* value)
+{
+    RegisterID* scope;
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        scope = nullptr;
+        break;
+        
+    case VarKind::DirectArgument:
+        scope = argumentsRegister();
+        break;
+        
+    case VarKind::Scope:
+        scope = scopeRegister();
+        break;
+        
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        scope = nullptr;
+        break;
     }
 
-    ASSERT(!m_symbolTable || !m_symbolTable->contains(identifier.impl()) || resolveType() == Dynamic);
-
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
-
-    // resolve_scope dst, id, ResolveType, depth
-    emitOpcode(op_resolve_scope);
-    dst = tempDestination(dst);
-    instructions().append(kill(dst));
-    instructions().append(scopeRegister()->index());
-    instructions().append(addConstant(identifier));
-    instructions().append(resolveType());
-    instructions().append(0);
-    instructions().append(0);
-    return dst;
-}
-
-
-RegisterID* BytecodeGenerator::emitResolveConstantLocal(RegisterID* dst, const Identifier& identifier, ResolveScopeInfo& info)
-{
-    if (!m_symbolTable || m_codeType != FunctionCode)
-        return nullptr;
-
-    SymbolTableEntry entry = m_symbolTable->get(identifier.impl());
-    if (entry.isNull())
-        return nullptr;
-    info = ResolveScopeInfo(entry.getIndex());
-    return emitMove(dst, m_lexicalEnvironmentRegister);
-
-}
-
-RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier& identifier, ResolveMode resolveMode, const ResolveScopeInfo& info)
-{
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
-
-    // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
-    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
-    instructions().append(kill(dst));
-    instructions().append(scope->index());
-    instructions().append(addConstant(identifier));
-    instructions().append(ResolveModeAndType(resolveMode, info.isLocal() ? LocalClosureVar : resolveType()).operand());
-    instructions().append(0);
-    instructions().append(info.localIndex());
-    instructions().append(profile);
-    return dst;
-}
-
-RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Identifier& identifier, RegisterID* value, ResolveMode resolveMode, const ResolveScopeInfo& info)
-{
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
-
-    // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
-    emitOpcode(op_put_to_scope);
-    instructions().append(scope->index());
-    instructions().append(addConstant(identifier));
-    instructions().append(value->index());
-    if (info.isLocal()) {
-        instructions().append(ResolveModeAndType(resolveMode, LocalClosureVar).operand());
-        int operand = registerFor(info.localIndex()).index();
-        bool isWatchableVariable = hasWatchableVariable(operand);
-        ASSERT(!isWatchableVariable || watchableVariableIdentifier(operand) == identifier);
-        instructions().append(isWatchableVariable);
-    } else {
-        ASSERT(resolveType() != LocalClosureVar);
-        instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
-        instructions().append(false);
-    }
-    instructions().append(info.localIndex());
-    return value;
+    return emitPutToScope(scope, variable, value, ThrowIfNotFound);
 }
 
 RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
-{ 
+{
     emitOpcode(op_instanceof);
     instructions().append(dst->index());
     instructions().append(value->index());
@@ -1381,16 +1464,6 @@
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitGetArgumentsLength(RegisterID* dst, RegisterID* base)
-{
-    emitOpcode(op_get_arguments_length);
-    instructions().append(dst->index());
-    ASSERT(base->virtualRegister() == m_codeBlock->argumentsRegister());
-    instructions().append(base->index());
-    instructions().append(addConstant(propertyNames().length));
-    return dst;
-}
-
 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
 {
     unsigned propertyIndex = addConstant(property);
@@ -1454,20 +1527,6 @@
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
-{
-    UnlinkedArrayProfile arrayProfile = newArrayProfile();
-    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_argument_by_val);
-    instructions().append(kill(dst));
-    ASSERT(base->virtualRegister() == m_codeBlock->argumentsRegister());
-    instructions().append(base->index());
-    instructions().append(property->index());
-    instructions().append(m_codeBlock->activationRegister().offset());
-    instructions().append(arrayProfile);
-    instructions().append(profile);
-    return dst;
-}
-
 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
 {
     for (size_t i = m_forInContextStack.size(); i > 0; i--) {
@@ -1652,24 +1711,15 @@
 
 RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
 {
-    return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(function)), false);
+    return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(function)));
 }
 
-RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function)
-{
-    FunctionOffsetMap::AddResult ptr = m_functionOffsets.add(function, 0);
-    if (ptr.isNewEntry)
-        ptr.iterator->value = m_codeBlock->addFunctionDecl(makeFunction(function));
-    return emitNewFunctionInternal(dst, ptr.iterator->value, true);
-}
-
-RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index, bool doNullCheck)
+RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index)
 {
     emitOpcode(op_new_func);
     instructions().append(dst->index());
     instructions().append(scopeRegister()->index());
     instructions().append(index);
-    instructions().append(doNullCheck);
     return dst;
 }
 
@@ -1711,23 +1761,6 @@
     return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd);
 }
 
-void BytecodeGenerator::createArgumentsIfNecessary()
-{
-    if (m_codeType != FunctionCode)
-        return;
-    
-    if (!m_codeBlock->usesArguments())
-        return;
-
-    if (shouldTearOffArgumentsEagerly() || shouldCreateArgumentsEagerly())
-        return;
-
-    emitOpcode(op_create_arguments);
-    instructions().append(m_codeBlock->argumentsRegister().offset());
-    ASSERT(!hasWatchableVariable(m_codeBlock->argumentsRegister().offset()));
-    instructions().append(m_codeBlock->activationRegister().offset());
-}
-
 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
 {
     return emitCall(op_call_eval, dst, func, NoExpectedFunction, callArguments, divot, divotStart, divotEnd);
@@ -1824,10 +1857,7 @@
             RELEASE_ASSERT(!n->m_next);
             auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
             RefPtr<RegisterID> argumentRegister;
-            if (expression->isResolveNode() && willResolveToArgumentsRegister(static_cast<ResolveNode*>(expression)->identifier()) && !symbolTable().slowArguments())
-                argumentRegister = uncheckedLocalArgumentsRegister();
-            else
-                argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
+            argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
             RefPtr<RegisterID> thisRegister = emitMove(newTemporary(), callArguments.thisRegister());
             return emitCallVarargs(dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
         }
@@ -1916,20 +1946,6 @@
 
 RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
 {
-    if (m_codeBlock->usesArguments() && m_codeBlock->numParameters() != 1 && !isStrictMode()) {
-        RefPtr<RegisterID> scratchRegister;
-        int argumentsIndex = unmodifiedArgumentsRegister(m_codeBlock->argumentsRegister()).offset();
-        if (m_lexicalEnvironmentRegister && m_codeType == FunctionCode) {
-            scratchRegister = newTemporary();
-            ResolveScopeInfo scopeInfo(unmodifiedArgumentsRegister(m_codeBlock->argumentsRegister()).offset());
-            emitGetFromScope(scratchRegister.get(), scopeRegister(), propertyNames().arguments, ThrowIfNotFound, scopeInfo);
-            argumentsIndex = scratchRegister->index();
-        }
-        emitOpcode(op_tear_off_arguments);
-        instructions().append(argumentsIndex);
-        instructions().append(m_lexicalEnvironmentRegister ? m_lexicalEnvironmentRegister->index() : emitLoad(0, JSValue())->index());
-    }
-
     if (isConstructor()) {
         bool derived = constructorKind() == ConstructorKind::Derived;
         if (derived && src->index() == m_thisRegister.index())
@@ -1978,10 +1994,7 @@
             RELEASE_ASSERT(!n->m_next);
             auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
             RefPtr<RegisterID> argumentRegister;
-            if (expression->isResolveNode() && willResolveToArgumentsRegister(static_cast<ResolveNode*>(expression)->identifier()) && !symbolTable().slowArguments())
-                argumentRegister = uncheckedLocalArgumentsRegister();
-            else
-                argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
+            argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
             return emitConstructVarargs(dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
         }
         
@@ -2543,9 +2556,9 @@
 
 bool BytecodeGenerator::isArgumentNumber(const Identifier& ident, int argumentNumber)
 {
-    RegisterID* registerID = local(ident).get();
-    if (!registerID || registerID->index() >= 0)
-         return 0;
+    RegisterID* registerID = variable(ident).local();
+    if (!registerID)
+        return false;
     return registerID->index() == CallFrame::argumentOffset(argumentNumber);
 }
 
@@ -2560,31 +2573,6 @@
     
 void BytecodeGenerator::emitEnumeration(ThrowableExpressionData* node, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack)
 {
-    if (subjectNode->isResolveNode()
-        && willResolveToArgumentsRegister(static_cast<ResolveNode*>(subjectNode)->identifier())
-        && !symbolTable().slowArguments()) {
-        RefPtr<RegisterID> index = emitLoad(newTemporary(), jsNumber(0));
-
-        LabelScopePtr scope = newLabelScope(LabelScope::Loop);
-        RefPtr<RegisterID> value = emitLoad(newTemporary(), jsUndefined());
-        
-        RefPtr<Label> loopCondition = newLabel();
-        RefPtr<Label> loopStart = newLabel();
-        emitJump(loopCondition.get());
-        emitLabel(loopStart.get());
-        emitLoopHint();
-        emitGetArgumentByVal(value.get(), uncheckedLocalArgumentsRegister(), index.get());
-        callBack(*this, value.get());
-    
-        emitLabel(scope->continueTarget());
-        emitInc(index.get());
-        emitLabel(loopCondition.get());
-        RefPtr<RegisterID> length = emitGetArgumentsLength(newTemporary(), uncheckedLocalArgumentsRegister());
-        emitJumpIfTrue(emitEqualityOp(op_less, newTemporary(), index.get(), length.get()), loopStart.get());
-        emitLabel(scope->breakTarget());
-        return;
-    }
-
     LabelScopePtr scope = newLabelScope(LabelScope::Loop);
     RefPtr<RegisterID> subject = newTemporary();
     emitNode(subject.get(), subjectNode);
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index 190b436..1c99aca 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012-2015 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
  * Copyright (C) 2012 Igalia, S.L.
  *
@@ -178,61 +178,55 @@
         TryData* tryData;
     };
 
-    enum CaptureMode {
-        NotCaptured,
-        IsCaptured
-    };
-
-    class Local {
+    class Variable {
     public:
-        Local()
-            : m_local(0)
+        enum VariableKind { NormalVariable, SpecialVariable };
+
+        Variable()
+            : m_offset()
+            , m_local(nullptr)
             , m_attributes(0)
-            , m_kind(NormalLocal)
+            , m_kind(NormalVariable)
+        {
+        }
+        
+        Variable(const Identifier& ident)
+            : m_ident(ident)
+            , m_local(nullptr)
+            , m_attributes(0)
+            , m_kind(NormalVariable) // This is somewhat meaningless here for this kind of Variable.
         {
         }
 
-        enum LocalKind { NormalLocal, SpecialLocal };
-
-        Local(RegisterID* local, unsigned attributes, LocalKind kind)
-            : m_local(local)
+        Variable(const Identifier& ident, VarOffset offset, RegisterID* local, unsigned attributes, VariableKind kind)
+            : m_ident(ident)
+            , m_offset(offset)
+            , m_local(local)
             , m_attributes(attributes)
             , m_kind(kind)
         {
         }
 
-        operator bool() const { return m_local; }
-
-        RegisterID* get() const { return m_local; }
+        // If it's unset, then it is a non-locally-scoped variable. If it is set, then it could be
+        // a stack variable, a scoped variable in the local scope, or a variable captured in the
+        // direct arguments object.
+        bool isResolved() const { return !!m_offset; }
+        
+        const Identifier& ident() const { return m_ident; }
+        
+        VarOffset offset() const { return m_offset; }
+        bool isLocal() const { return m_offset.isStack(); }
+        RegisterID* local() const { return m_local; }
 
         bool isReadOnly() const { return m_attributes & ReadOnly; }
-        bool isSpecial() const { return m_kind != NormalLocal; }
+        bool isSpecial() const { return m_kind != NormalVariable; }
 
     private:
+        Identifier m_ident;
+        VarOffset m_offset;
         RegisterID* m_local;
         unsigned m_attributes;
-        LocalKind m_kind;
-    };
-
-    struct ResolveScopeInfo {
-        ResolveScopeInfo()
-            : m_localIndex(0)
-            , m_resolveScopeKind(NonLocalScope)
-        {
-        }
-
-        ResolveScopeInfo(int index)
-            : m_localIndex(index)
-            , m_resolveScopeKind(LocalScope)
-        {
-        }
-
-        bool isLocal() const { return m_resolveScopeKind == LocalScope; }
-        int localIndex() const { return m_localIndex; }
-
-    private:
-        int m_localIndex;
-        enum { LocalScope, NonLocalScope } m_resolveScopeKind;
+        VariableKind m_kind;
     };
 
     struct TryRange {
@@ -282,19 +276,17 @@
 
         void setIsNumericCompareFunction(bool isNumericCompareFunction);
 
-        bool willResolveToArgumentsRegister(const Identifier&);
-
-        bool hasSafeLocalArgumentsRegister() { return m_localArgumentsRegister; }
-        RegisterID* uncheckedLocalArgumentsRegister();
-
-        bool isCaptured(int operand);
-        CaptureMode captureMode(int operand) { return isCaptured(operand) ? IsCaptured : NotCaptured; }
+        Variable variable(const Identifier&);
         
-        Local local(const Identifier&);
-        Local constLocal(const Identifier&);
-
+        // Ignores the possibility of intervening scopes.
+        Variable variablePerSymbolTable(const Identifier&);
+        
+        enum ExistingVariableMode { VerifyExisting, IgnoreExisting };
+        void createVariable(const Identifier&, VarKind, ConstantMode, ExistingVariableMode = VerifyExisting); // Creates the variable, or asserts that the already-created variable is sufficiently compatible.
+        
         // Returns the register storing "this"
         RegisterID* thisRegister() { return &m_thisRegister; }
+        RegisterID* argumentsRegister() { return m_argumentsRegister; }
         RegisterID* newTarget() { return m_newTargetRegister; }
 
         RegisterID* scopeRegister() { return m_scopeRegister; }
@@ -353,8 +345,6 @@
         {
             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
             ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
-            // Should never store directly into a captured variable.
-            ASSERT(!dst || dst == ignoredResult() || !isCaptured(dst->index()));
             if (!m_vm->isSafeToRecurse()) {
                 emitThrowExpressionTooDeepException();
                 return;
@@ -371,8 +361,6 @@
         {
             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
             ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
-            // Should never store directly into a captured variable.
-            ASSERT(!dst || dst == ignoredResult() || !isCaptured(dst->index()));
             if (!m_vm->isSafeToRecurse())
                 return emitThrowExpressionTooDeepException();
             return n->emitBytecode(*this, dst);
@@ -463,8 +451,7 @@
         RegisterID* emitNewArray(RegisterID* dst, ElementNode*, unsigned length); // stops at first elision
 
         RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode*);
-        RegisterID* emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* body);
-        RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index, bool shouldNullCheck);
+        RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index);
         RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
         RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier& name);
         RegisterID* emitNewRegExp(RegisterID* dst, RegExp*);
@@ -483,7 +470,6 @@
         RegisterID* emitInitGlobalConst(const Identifier&, RegisterID* value);
 
         RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
-        RegisterID* emitGetArgumentsLength(RegisterID* dst, RegisterID* base);
         RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
         RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType);
         RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
@@ -510,14 +496,11 @@
         void emitToPrimitive(RegisterID* dst, RegisterID* src);
 
         ResolveType resolveType();
-        RegisterID* emitResolveConstantLocal(RegisterID* dst, const Identifier&, ResolveScopeInfo&);
-        // Calls tempDestination(dst), so it's safe to pass nullptr. It's also redundant to call
-        // tempDestination(dst) on the thing you pass as the destination. The reason why this
-        // calls tempDestination() for you is that it may not need a spare register. It may return
-        // scopeRegister() directly. So, you cannot rely on this storing to dst.
-        RegisterID* emitResolveScope(RegisterID* dst, const Identifier&, ResolveScopeInfo&);
-        RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&, ResolveMode, const ResolveScopeInfo&);
-        RegisterID* emitPutToScope(RegisterID* scope, const Identifier&, RegisterID* value, ResolveMode, const ResolveScopeInfo&);
+        RegisterID* emitResolveConstantLocal(RegisterID* dst, const Variable&);
+        RegisterID* emitResolveScope(RegisterID* dst, const Variable&);
+        RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable&, ResolveMode);
+        RegisterID* emitPutToScope(RegisterID* scope, const Variable&, RegisterID* value, ResolveMode);
+        RegisterID* initializeVariable(const Variable&, RegisterID* value);
 
         PassRefPtr<Label> emitLabel(Label*);
         void emitLoopHint();
@@ -597,6 +580,8 @@
         OpcodeID lastOpcodeID() const { return m_lastOpcodeID; }
 
     private:
+        Variable variableForLocalEntry(const Identifier&, const SymbolTableEntry&);
+
         void emitOpcode(OpcodeID);
         UnlinkedArrayAllocationProfile newArrayAllocationProfile();
         UnlinkedObjectAllocationProfile newObjectAllocationProfile();
@@ -629,11 +614,7 @@
 
         RegisterID* newRegister();
 
-        // Adds a var slot and maps it to the name ident in symbolTable().
-        enum WatchMode { IsWatchable, NotWatchable };
-        RegisterID* addVar(const Identifier&, ConstantMode, WatchMode);
-
-        // Adds an anonymous var slot. To give this slot a name, add it to symbolTable().
+        // Adds an anonymous local var slot. To give this slot a name, add it to symbolTable().
         RegisterID* addVar()
         {
             ++m_codeBlock->m_numVars;
@@ -643,23 +624,20 @@
             return result;
         }
 
-        // Returns the index of the added var.
-        void addParameter(const Identifier&, int parameterIndex);
-        RegisterID* resolveCallee(FunctionNode*);
-        void addCallee(FunctionNode*, RegisterID*);
-
-        void preserveLastVar();
-
-        RegisterID& registerFor(int index)
+        // Initializes the stack form the parameter; does nothing for the symbol table.
+        RegisterID* initializeNextParameter();
+        StringImpl* visibleNameForParameter(DeconstructionPatternNode*);
+        
+        RegisterID& registerFor(VirtualRegister reg)
         {
-            if (operandIsLocal(index))
-                return m_calleeRegisters[VirtualRegister(index).toLocal()];
+            if (reg.isLocal())
+                return m_calleeRegisters[reg.toLocal()];
 
-            if (index == JSStack::Callee)
+            if (reg.offset() == JSStack::Callee)
                 return m_calleeRegister;
 
             ASSERT(m_parameters.size());
-            return m_parameters[VirtualRegister(index).toArgument()];
+            return m_parameters[reg.toArgument()];
         }
 
         bool hasConstant(const Identifier&) const;
@@ -675,11 +653,8 @@
             return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), body, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction);
         }
 
-        RegisterID* emitInitLazyRegister(RegisterID*);
-        
         RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
         RegisterID* emitCallVarargs(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
-        RegisterID* initializeCapturedVariable(RegisterID* dst, const Identifier&, RegisterID*);
 
     public:
         JSString* addStringConstant(const Identifier&);
@@ -713,44 +688,8 @@
             return true;
         }
 
-        bool shouldTearOffArgumentsEagerly()
-        {
-            return m_codeType == FunctionCode && isStrictMode() && m_scopeNode->modifiesParameter();
-        }
-
-        bool shouldCreateArgumentsEagerly()
-        {
-            if (m_codeType != FunctionCode)
-                return false;
-            return m_lexicalEnvironmentRegister && m_codeBlock->usesArguments();
-        }
-
         RegisterID* emitThrowExpressionTooDeepException();
 
-        void createArgumentsIfNecessary();
-        RegisterID* createLazyRegisterIfNecessary(RegisterID*);
-        
-        bool hasWatchableVariable(int operand) const
-        {
-            VirtualRegister reg(operand);
-            if (!reg.isLocal())
-                return false;
-            if (static_cast<size_t>(reg.toLocal()) >= m_watchableVariables.size())
-                return false;
-            const Identifier& ident = m_watchableVariables[reg.toLocal()];
-            if (ident.isNull())
-                return false;
-            ASSERT(hasConstant(ident)); // Should have already been added.
-            return true;
-        }
-        
-        const Identifier& watchableVariableIdentifier(int operand) const
-        {
-            ASSERT(hasWatchableVariable(operand));
-            VirtualRegister reg(operand);
-            return m_watchableVariables[reg.toLocal()];
-        }
-
     private:
         Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow> m_instructions;
 
@@ -769,13 +708,12 @@
         RegisterID m_thisRegister;
         RegisterID m_calleeRegister;
         RegisterID* m_scopeRegister { nullptr };
+        RegisterID* m_argumentsRegister { nullptr };
         RegisterID* m_lexicalEnvironmentRegister { nullptr };
         RegisterID* m_emptyValueRegister { nullptr };
         RegisterID* m_globalObjectRegister { nullptr };
-        RegisterID* m_localArgumentsRegister { nullptr };
         RegisterID* m_newTargetRegister { nullptr };
 
-        Vector<Identifier, 16> m_watchableVariables;
         SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
         SegmentedVector<RegisterID, 32> m_calleeRegisters;
         SegmentedVector<RegisterID, 32> m_parameters;
@@ -790,15 +728,14 @@
         Vector<std::unique_ptr<ForInContext>> m_forInContextStack;
         Vector<TryContext> m_tryContextStack;
         Vector<std::pair<RefPtr<RegisterID>, const DeconstructionPatternNode*>> m_deconstructedParameters;
+        Vector<FunctionBodyNode*> m_functionsToInitialize;
+        bool m_needToInitializeArguments { false };
         
         Vector<TryRange> m_tryRanges;
         SegmentedVector<TryData, 8> m_tryData;
 
         int m_nextConstantOffset { 0 };
 
-        int m_firstLazyFunction { 0 };
-        int m_lastLazyFunction { 0 };
-        HashMap<unsigned int, FunctionBodyNode*, WTF::IntHash<unsigned int>, WTF::UnsignedWithZeroKeyHashTraits<unsigned int>> m_lazyFunctions;
         typedef HashMap<FunctionBodyNode*, unsigned> FunctionOffsetMap;
         FunctionOffsetMap m_functionOffsets;
         
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 02e447a..b5c3727 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -1,7 +1,7 @@
 /*
 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
-*  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
+*  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013, 2015 Apple Inc. All rights reserved.
 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
 *  Copyright (C) 2007 Maks Orlovich
 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
@@ -187,29 +187,29 @@
 
 bool ResolveNode::isPure(BytecodeGenerator& generator) const
 {
-    return generator.local(m_ident).get();
+    return generator.variable(m_ident).offset().isStack();
 }
 
 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(m_ident)) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
         if (dst == generator.ignoredResult())
-            return 0;
+            return nullptr;
         if (generator.vm()->typeProfiler()) {
-            generator.emitProfileType(local.get(), ProfileTypeBytecodeHasGlobalID, nullptr);
+            generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
             generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
         }
-        return generator.moveToDestinationIfNeeded(dst, local.get());
+        return generator.moveToDestinationIfNeeded(dst, local);
     }
     
     JSTextPosition divot = m_start + m_ident.length();
     generator.emitExpressionInfo(divot, m_start, divot);
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, m_ident, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
     RegisterID* finalDest = generator.finalDestination(dst);
-    RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo);
+    RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), var, ThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(finalDest, resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
+        generator.emitProfileType(finalDest, var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
         generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
     }
     return result;
@@ -439,14 +439,6 @@
         return generator.emitGetByVal(generator.finalDestination(dst), emitSuperBaseForCallee(generator), generator.emitNode(m_subscript));
     }
 
-    if (m_base->isResolveNode() 
-        && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(m_base)->identifier())
-        && !generator.symbolTable().slowArguments()) {
-        RefPtr<RegisterID> property = generator.emitNode(m_subscript);
-        generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-        return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedLocalArgumentsRegister(), property.get());
-    }
-
     RegisterID* ret;
     RegisterID* finalDest = generator.finalDestination(dst);
 
@@ -472,17 +464,6 @@
 
 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (m_ident == generator.propertyNames().length) {
-        if (!m_base->isResolveNode())
-            goto nonArgumentsPath;
-        ResolveNode* resolveNode = static_cast<ResolveNode*>(m_base);
-        if (!generator.willResolveToArgumentsRegister(resolveNode->identifier()))
-            goto nonArgumentsPath;
-        generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-        return generator.emitGetArgumentsLength(generator.finalDestination(dst), generator.uncheckedLocalArgumentsRegister());
-    }
-
-nonArgumentsPath:
     RefPtr<RegisterID> base = m_base->isSuperNode() ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     RegisterID* finalDest = generator.finalDestination(dst);
@@ -547,8 +528,9 @@
 
 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(generator.propertyNames().eval)) {
-        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local.get());
+    Variable var = generator.variable(generator.propertyNames().eval);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
         CallArguments callArguments(generator, m_args);
         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
         return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
@@ -558,11 +540,10 @@
     CallArguments callArguments(generator, m_args);
     JSTextPosition newDivot = divotStart() + 4;
     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
-    ResolveScopeInfo resolveScopeInfo;
     generator.moveToDestinationIfNeeded(
         callArguments.thisRegister(),
-        generator.emitResolveScope(callArguments.thisRegister(), generator.propertyNames().eval, resolveScopeInfo));
-    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), generator.propertyNames().eval, ThrowIfNotFound, resolveScopeInfo);
+        generator.emitResolveScope(callArguments.thisRegister(), var));
+    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
 }
 
@@ -596,8 +577,9 @@
 {
     ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
 
-    if (Local local = generator.local(m_ident)) {
-        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local.get());
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
         RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
         CallArguments callArguments(generator, m_args);
         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
@@ -617,11 +599,10 @@
 
     JSTextPosition newDivot = divotStart() + m_ident.length();
     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
-    ResolveScopeInfo resolveScopeInfo;
     generator.moveToDestinationIfNeeded(
         callArguments.thisRegister(),
-        generator.emitResolveScope(callArguments.thisRegister(), m_ident, resolveScopeInfo));
-    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound, resolveScopeInfo);
+        generator.emitResolveScope(callArguments.thisRegister(), var));
+    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
     RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
     if (generator.vm()->typeProfiler()) {
         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
@@ -675,17 +656,6 @@
     return ret;
 }
 
-static RegisterID* getArgumentByVal(BytecodeGenerator& generator, ExpressionNode* base, RegisterID* property, RegisterID* dst, JSTextPosition divot, JSTextPosition divotStart, JSTextPosition divotEnd)
-{
-    if (base->isResolveNode()
-        && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(base)->identifier())
-        && !generator.symbolTable().slowArguments()) {
-        generator.emitExpressionInfo(divot, divotStart, divotEnd);
-        return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedLocalArgumentsRegister(), property);
-    }
-    return nullptr;
-}
-
 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     RefPtr<Label> realCall = generator.newLabel();
@@ -706,15 +676,10 @@
                 profileHookRegister = generator.newTemporary();
             SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
             ExpressionNode* subject = spread->expression();
-            RefPtr<RegisterID> thisRegister = getArgumentByVal(generator, subject, generator.emitLoad(0, jsNumber(0)), 0, spread->divot(), spread->divotStart(), spread->divotEnd());
             RefPtr<RegisterID> argumentsRegister;
-            if (thisRegister)
-                argumentsRegister = generator.uncheckedLocalArgumentsRegister();
-            else {
-                argumentsRegister = generator.emitNode(subject);
-                generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
-                thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
-            }
+            argumentsRegister = generator.emitNode(subject);
+            generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
+            RefPtr<RegisterID> thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
             generator.emitCallVarargs(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, profileHookRegister.get(), divot(), divotStart(), divotEnd());
         } else if (m_args->m_listNode && m_args->m_listNode->m_expr) {
             ArgumentListNode* oldList = m_args->m_listNode;
@@ -836,10 +801,7 @@
         RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
         RefPtr<RegisterID> argsRegister;
         ArgumentListNode* args = m_args->m_listNode->m_next;
-        if (args->m_expr->isResolveNode() && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(args->m_expr)->identifier()) && !generator.symbolTable().slowArguments())
-            argsRegister = generator.uncheckedLocalArgumentsRegister();
-        else
-            argsRegister = generator.emitNode(args->m_expr);
+        argsRegister = generator.emitNode(args->m_expr);
 
         // Function.prototype.apply ignores extra arguments, but we still
         // need to evaluate them for side effects.
@@ -888,11 +850,12 @@
     ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
     const Identifier& ident = resolve->identifier();
 
-    if (Local local = generator.local(ident)) {
-        RefPtr<RegisterID> localReg = local.get();
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(ident);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> localReg = local;
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
-            localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
+            localReg = generator.emitMove(generator.tempDestination(dst), local);
         } else if (generator.vm()->typeProfiler()) {
             RefPtr<RegisterID> tempDst = generator.finalDestination(dst);
             ASSERT(dst != localReg);
@@ -909,13 +872,12 @@
     }
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, ident, resolveScopeInfo);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
     RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
-    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo);
+    generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
+        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     }
 
@@ -991,12 +953,12 @@
 
 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (generator.local(m_ident).get())
+    Variable var = generator.variable(m_ident);
+    if (var.local())
         return generator.emitLoad(generator.finalDestination(dst), false);
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> base = generator.emitResolveScope(dst, m_ident, resolveScopeInfo);
+    RefPtr<RegisterID> base = generator.emitResolveScope(dst, var);
     return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
 }
 
@@ -1047,19 +1009,19 @@
     return generator.emitLoad(dst, jsUndefined());
 }
 
-// ------------------------------ TypeOfValueNode -----------------------------------
+// ------------------------------ TypeOfResolveNode -----------------------------------
 
 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(m_ident)) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
         if (dst == generator.ignoredResult())
             return 0;
-        return generator.emitTypeOf(generator.finalDestination(dst), local.get());
+        return generator.emitTypeOf(generator.finalDestination(dst), local);
     }
 
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, m_ident, resolveScopeInfo);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
     if (dst == generator.ignoredResult())
         return 0;
     return generator.emitTypeOf(generator.finalDestination(dst, scope.get()), value.get());
@@ -1085,9 +1047,10 @@
     ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
     const Identifier& ident = resolve->identifier();
 
-    if (Local local = generator.local(ident)) {
-        RefPtr<RegisterID> localReg = local.get();
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(ident);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> localReg = local;
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
             localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
         } else if (generator.vm()->typeProfiler()) {
@@ -1104,13 +1067,12 @@
     }
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, ident, resolveScopeInfo);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
     emitIncOrDec(generator, value.get(), m_operator);
-    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo);
+    generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
+        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     }
     return generator.moveToDestinationIfNeeded(dst, value.get());
@@ -1602,37 +1564,37 @@
 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     JSTextPosition newDivot = divotStart() + m_ident.length();
-    if (Local local = generator.local(m_ident)) {
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
-            return emitReadModifyAssignment(generator, generator.finalDestination(dst), local.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+            return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
         }
         
         if (generator.vm()->typeProfiler()
             || generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
             RefPtr<RegisterID> result = generator.newTemporary();
-            generator.emitMove(result.get(), local.get());
+            generator.emitMove(result.get(), local);
             emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
-            generator.emitMove(local.get(), result.get());
-            generator.invalidateForInContextForLocal(local.get());
+            generator.emitMove(local, result.get());
+            generator.invalidateForInContextForLocal(local);
             if (generator.vm()->typeProfiler())
                 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
             return generator.moveToDestinationIfNeeded(dst, result.get());
         }
         
-        RegisterID* result = emitReadModifyAssignment(generator, local.get(), local.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
-        generator.invalidateForInContextForLocal(local.get());
+        RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+        generator.invalidateForInContextForLocal(local);
         return generator.moveToDestinationIfNeeded(dst, result);
     }
 
     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
     RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
-    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound, resolveScopeInfo);
+    RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
+        generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     }
     return returnResult;
@@ -1642,36 +1604,36 @@
 
 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(m_ident)) {
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
             return generator.emitNode(dst, m_right);
         }
-        if (local.isSpecial() || generator.vm()->typeProfiler()) {
+        if (var.isSpecial() || generator.vm()->typeProfiler()) {
             RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
             generator.emitNode(tempDst.get(), m_right);
-            generator.emitMove(local.get(), tempDst.get());
-            generator.invalidateForInContextForLocal(local.get());
+            generator.emitMove(local, tempDst.get());
+            generator.invalidateForInContextForLocal(local);
             if (generator.vm()->typeProfiler())
                 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
             return generator.moveToDestinationIfNeeded(dst, tempDst.get());
         }
-        RegisterID* result = generator.emitNode(local.get(), m_right);
-        generator.invalidateForInContextForLocal(local.get());
+        RegisterID* result = generator.emitNode(local, m_right);
+        generator.invalidateForInContextForLocal(local);
         return generator.moveToDestinationIfNeeded(dst, result);
     }
 
     if (generator.isStrictMode())
         generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
     if (dst == generator.ignoredResult())
         dst = 0;
     RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
+    RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
+        generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     } 
     return returnResult;
@@ -1780,18 +1742,19 @@
 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
 {
     // FIXME: This code does not match the behavior of const in Firefox.
-    if (Local local = generator.constLocal(m_ident)) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
         if (!m_init)
-            return local.get();
+            return local;
 
         // FIXME: Maybe call emitExpressionInfo here.
-        if (local.isSpecial() || generator.vm()->typeProfiler()) {
+        if (var.isSpecial() || generator.vm()->typeProfiler()) {
             RefPtr<RegisterID> tempDst = generator.newTemporary();
             generator.emitNode(tempDst.get(), m_init);
-            return generator.emitMove(local.get(), tempDst.get());
+            return generator.emitMove(local, tempDst.get());
         }
         
-        return generator.emitNode(local.get(), m_init);
+        return generator.emitNode(local, m_init);
     }
 
     RefPtr<RegisterID> value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
@@ -1800,18 +1763,23 @@
         return generator.emitInitGlobalConst(m_ident, value.get());
 
     if (generator.codeType() != EvalCode) {
-
-        ResolveScopeInfo resolveScopeInfo;
-        if (RefPtr<RegisterID> scope = generator.emitResolveConstantLocal(generator.newTemporary(), m_ident, resolveScopeInfo))
-            return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo);
-
-        return value.get();
+        // Do a special kind of resolution. If anything fails, then don't perform the assignment. This is
+        // pretty shady - particularly how negligent it is with inteleaving scopes - but it's the
+        // behavior that JSC has had for a long time.
+        
+        ASSERT(generator.codeType() == FunctinCode);
+        
+        var = generator.variablePerSymbolTable(m_ident);
+        if (!var.isResolved())
+            return value.get();
+        
+        RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), var);
+        return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
     }
 
     // FIXME: This will result in incorrect assignment if m_ident exists in an intervening with scope.
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
-    return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+    return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
 }
 
 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
@@ -1903,13 +1871,13 @@
     if (!generator.vm()->typeProfiler())
         return nullptr;
 
-    if (Local local = generator.local(m_ident))
-        generator.emitProfileType(local.get(), ProfileTypeBytecodeHasGlobalID, nullptr);
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local())
+        generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
     else {
-        ResolveScopeInfo resolveScopeInfo;
-        RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
-        RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo);
-        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
+        RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+        RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
+        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
     }
 
     generator.emitTypeProfilerExpressionInfo(position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
@@ -2079,8 +2047,7 @@
 {
     if (m_lexpr->isResolveNode()) {
         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
-        Local local = generator.local(ident);
-        return local.get();
+        return generator.variable(ident).local();
     }
 
     if (m_lexpr->isDeconstructionNode()) {
@@ -2091,10 +2058,10 @@
 
         auto simpleBinding = static_cast<BindingNode*>(binding);
         const Identifier& ident = simpleBinding->boundProperty();
-        Local local = generator.local(ident);
-        if (local.isSpecial())
+        Variable var = generator.variable(ident);
+        if (var.isSpecial())
             return nullptr;
-        return local.get();
+        return var.local();
     }
 
     return nullptr;
@@ -2104,18 +2071,17 @@
 {
     if (m_lexpr->isResolveNode()) {
         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
-        Local local = generator.local(ident);
-        if (local.get())
-            generator.emitMove(local.get(), propertyName);
+        Variable var = generator.variable(ident);
+        if (RegisterID* local = var.local())
+            generator.emitMove(local, propertyName);
         else {
             if (generator.isStrictMode())
                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-            ResolveScopeInfo resolveScopeInfo;
-            RegisterID* scope = generator.emitResolveScope(nullptr, ident, resolveScopeInfo);
+            RegisterID* scope = generator.emitResolveScope(nullptr, var);
             generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-            generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
+            generator.emitPutToScope(scope, var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
             if (generator.vm()->typeProfiler())
-                generator.emitProfileType(propertyName, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
+                generator.emitProfileType(propertyName, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
         }
         if (generator.vm()->typeProfiler())
             generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
@@ -2156,12 +2122,12 @@
 
         auto simpleBinding = static_cast<BindingNode*>(binding);
         const Identifier& ident = simpleBinding->boundProperty();
-        Local local = generator.local(ident);
-        if (!local.get() || local.isSpecial()) {
+        Variable var = generator.variable(ident);
+        if (!var.local() || var.isSpecial()) {
             assignNode->bindings()->bindValue(generator, propertyName);
             return;
         }
-        generator.emitMove(local.get(), propertyName);
+        generator.emitMove(var.local(), propertyName);
         if (generator.vm()->typeProfiler())
             generator.emitTypeProfilerExpressionInfo(simpleBinding->divotStart(), simpleBinding->divotEnd());
         return;
@@ -2329,17 +2295,17 @@
     {
         if (m_lexpr->isResolveNode()) {
             const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
-            if (Local local = generator.local(ident))
-                generator.emitMove(local.get(), value);
+            Variable var = generator.variable(ident);
+            if (RegisterID* local = var.local())
+                generator.emitMove(local, value);
             else {
                 if (generator.isStrictMode())
                     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-                ResolveScopeInfo resolveScopeInfo;
-                RegisterID* scope = generator.emitResolveScope(nullptr, ident, resolveScopeInfo);
+                RegisterID* scope = generator.emitResolveScope(nullptr, var);
                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-                generator.emitPutToScope(scope, ident, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
+                generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
                 if (generator.vm()->typeProfiler())
-                    generator.emitProfileType(value, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
+                    generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
             }
             if (generator.vm()->typeProfiler())
                 generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
@@ -2964,24 +2930,6 @@
 
 RegisterID* ArrayPatternNode::emitDirectBinding(BytecodeGenerator& generator, RegisterID* dst, ExpressionNode* rhs)
 {
-    if (rhs->isResolveNode()
-        && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(rhs)->identifier())
-        && generator.hasSafeLocalArgumentsRegister()&& !generator.symbolTable().slowArguments()) {
-        for (size_t i = 0; i < m_targetPatterns.size(); i++) {
-            auto target = m_targetPatterns[i];
-            if (!target)
-                continue;
-            
-            RefPtr<RegisterID> temp = generator.newTemporary();
-            generator.emitLoad(temp.get(), jsNumber(i));
-            generator.emitGetArgumentByVal(temp.get(), generator.uncheckedLocalArgumentsRegister(), temp.get());
-            target->bindValue(generator, temp.get());
-        }
-        if (dst == generator.ignoredResult() || !dst)
-            return generator.emitLoad(generator.finalDestination(dst), jsUndefined());
-        Local local = generator.local(generator.vm()->propertyNames->arguments);
-        return generator.moveToDestinationIfNeeded(dst, local.get());
-    }
     if (!rhs->isSimpleArray())
         return 0;
 
@@ -3069,24 +3017,24 @@
 
 void BindingNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const
 {
-    if (Local local = generator.local(m_boundProperty)) {
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(m_boundProperty);
+    if (RegisterID* local = var.local()) {
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
             return;
         }
-        generator.emitMove(local.get(), value);
+        generator.emitMove(local, value);
         if (generator.vm()->typeProfiler())
             generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
         return;
     }
     if (generator.isStrictMode())
         generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
-    ResolveScopeInfo resolveScopeInfo;
-    RegisterID* scope = generator.emitResolveScope(nullptr, m_boundProperty, resolveScopeInfo);
+    RegisterID* scope = generator.emitResolveScope(nullptr, var);
     generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
-    generator.emitPutToScope(scope, m_boundProperty, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
+    generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(value, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_boundProperty);
+        generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_boundProperty);
         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     }
     return;