Ignore:
Timestamp:
Oct 2, 2014, 1:35:58 PM (11 years ago)
Author:
[email protected]
Message:

Do all closed variable access through the local lexical object
https://bugs.webkit.org/show_bug.cgi?id=136869

Reviewed by Filip Pizlo.

This patch makes all reads and writes from captured registers
go through the lexical record, and by doing so removes the
need for record tearoff.

To keep the patch simple we still number variables as though
they are local stack allocated registers, but ::local() will
fail. When local fails we perform a generic resolve, and in
that resolve we now use a ResolveScopeInfo struct to pass
around information about whether a lookup is a statically
known captured variable, and its location in the activation.
To ensure correct behaviour during codeblock linking we also
add a LocalClosureVariable resolution type.

To ensure correct semantics for the Arguments object, we now
have to eagerly create the Arguments object for any function
that uses both the Arguments object and requires a lexical
record.

  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::initializeCapturedVariable):

During the entry to a function we are not yet in a position
to allocate temporaries so we directly use the lexical
environment register.

(JSC::BytecodeGenerator::resolveCallee):
(JSC::BytecodeGenerator::emitMove):
(JSC::BytecodeGenerator::local):
(JSC::BytecodeGenerator::constLocal):
(JSC::BytecodeGenerator::emitResolveScope):
(JSC::BytecodeGenerator::emitResolveConstantLocal):

The two resolve scope operations could technically skip
the op_resolve_scope, and simply perform

op_mov dst, recordRegister

but for now it seemed best to maintain the same basic
behaviour.

(JSC::BytecodeGenerator::emitGetFromScope):
(JSC::BytecodeGenerator::emitPutToScope):
(JSC::BytecodeGenerator::createArgumentsIfNecessary):

If we have an environment we've already created Arguments
so no need to check again.

(JSC::BytecodeGenerator::emitReturn):

Don't need to emit tearoff_environment

  • bytecompiler/BytecodeGenerator.h:

(JSC::Local::Local):
(JSC::Local::operator bool):
(JSC::Local::get):
(JSC::Local::isReadOnly):
(JSC::Local::isSpecial):
(JSC::ResolveScopeInfo::ResolveScopeInfo):
(JSC::ResolveScopeInfo::isLocal):
(JSC::ResolveScopeInfo::localIndex):
(JSC::BytecodeGenerator::shouldCreateArgumentsEagerly):
(JSC::Local::isCaptured): Deleted.
(JSC::Local::captureMode): Deleted.

  • bytecompiler/NodesCodegen.cpp:

(JSC::ResolveNode::emitBytecode):
(JSC::EvalFunctionCallNode::emitBytecode):
(JSC::FunctionCallResolveNode::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::BindingNode::bindValue):

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::capabilityLevel):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::tryGetRegisters):

  • dfg/DFGNodeType.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • interpreter/Interpreter.cpp:

(JSC::unwindCallFrame):

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):

  • jit/JIT.h:
  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_captured_mov): Deleted.
(JSC::JIT::emit_op_tear_off_lexical_environment): Deleted.
(JSC::JIT::emitSlow_op_captured_mov): Deleted.

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_captured_mov): Deleted.
(JSC::JIT::emit_op_tear_off_lexical_environment): Deleted.

  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emit_op_put_to_scope):
(JSC::JIT::emitSlow_op_put_to_scope):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emit_op_put_to_scope):
(JSC::JIT::emitSlow_op_put_to_scope):

  • llint/LLIntData.cpp:

(JSC::LLInt::Data::performAssertions):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • llint/LLIntSlowPaths.h:
  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/Arguments.cpp:

(JSC::Arguments::tearOff):

  • runtime/Arguments.h:

(JSC::Arguments::argument):

  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL): Deleted.

  • runtime/CommonSlowPaths.h:
  • runtime/JSLexicalEnvironment.cpp:

(JSC::JSLexicalEnvironment::visitChildren):
(JSC::JSLexicalEnvironment::symbolTableGet):
(JSC::JSLexicalEnvironment::symbolTablePut):
(JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
(JSC::JSLexicalEnvironment::getOwnPropertySlot):
(JSC::JSLexicalEnvironment::argumentsGetter):

  • runtime/JSLexicalEnvironment.h:

(JSC::JSLexicalEnvironment::create):
(JSC::JSLexicalEnvironment::JSLexicalEnvironment):
(JSC::JSLexicalEnvironment::tearOff): Deleted.
(JSC::JSLexicalEnvironment::isTornOff): Deleted.

  • runtime/JSScope.cpp:

(JSC::resolveTypeName):

  • runtime/JSScope.h:

(JSC::makeType):
(JSC::needsVarInjectionChecks):

  • runtime/WriteBarrier.h:

(JSC::WriteBarrier<Unknown>::WriteBarrier):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r173125 r174226  
    169169    JSTextPosition divot = m_start + m_ident.length();
    170170    generator.emitExpressionInfo(divot, m_start, divot);
    171     RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident);
     171    ResolveScopeInfo resolveScopeInfo;
     172    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident, resolveScopeInfo);
    172173    RegisterID* finalDest = generator.finalDestination(dst);
    173     RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), m_ident, ThrowIfNotFound);
     174    RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo);
    174175    if (generator.vm()->typeProfiler()) {
    175         generator.emitProfileType(finalDest, ProfileTypeBytecodeGetFromScope, &m_ident);
     176        generator.emitProfileType(finalDest, resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
    176177        generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
    177178    }
     
    490491    JSTextPosition newDivot = divotStart() + 4;
    491492    generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
    492     generator.emitResolveScope(callArguments.thisRegister(), generator.propertyNames().eval);
    493     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), generator.propertyNames().eval, ThrowIfNotFound);
     493    ResolveScopeInfo resolveScopeInfo;
     494    generator.emitResolveScope(callArguments.thisRegister(), generator.propertyNames().eval, resolveScopeInfo);
     495    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), generator.propertyNames().eval, ThrowIfNotFound, resolveScopeInfo);
    494496    return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
    495497}
     
    538540    JSTextPosition newDivot = divotStart() + m_ident.length();
    539541    generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
    540     generator.emitResolveScope(callArguments.thisRegister(), m_ident);
    541     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound);
     542    ResolveScopeInfo resolveScopeInfo;
     543    generator.emitResolveScope(callArguments.thisRegister(), m_ident, resolveScopeInfo);
     544    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound, resolveScopeInfo);
    542545    RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
    543546    if (generator.vm()->typeProfiler()) {
     
    803806            generator.emitReadOnlyExceptionIfNeeded();
    804807            localReg = generator.emitMove(generator.tempDestination(dst), localReg);
    805         } else if (local.isCaptured() || generator.vm()->typeProfiler()) {
     808        } else if (generator.vm()->typeProfiler()) {
    806809            RefPtr<RegisterID> tempDst = generator.finalDestination(dst);
    807810            ASSERT(dst != localReg);
     
    819822
    820823    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    821     RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), ident);
    822     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound);
     824    ResolveScopeInfo resolveScopeInfo;
     825    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), ident, resolveScopeInfo);
     826    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo);
    823827    RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
    824     generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
     828    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo);
    825829    if (generator.vm()->typeProfiler()) {
    826         generator.emitProfileType(value.get(), ProfileTypeBytecodePutToScope, &ident);
     830        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
    827831        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
    828832    }
     
    904908
    905909    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    906     RefPtr<RegisterID> base = generator.emitResolveScope(generator.tempDestination(dst), m_ident);
     910    ResolveScopeInfo resolveScopeInfo;
     911    RefPtr<RegisterID> base = generator.emitResolveScope(generator.tempDestination(dst), m_ident, resolveScopeInfo);
    907912    return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
    908913}
     
    961966    }
    962967
    963     RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident);
    964     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound);
     968    ResolveScopeInfo resolveScopeInfo;
     969    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident, resolveScopeInfo);
     970    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo);
    965971    if (dst == generator.ignoredResult())
    966972        return 0;
     
    993999            generator.emitReadOnlyExceptionIfNeeded();
    9941000            localReg = generator.emitMove(generator.tempDestination(dst), localReg);
    995         } else if (local.isCaptured() || generator.vm()->typeProfiler()) {
     1001        } else if (generator.vm()->typeProfiler()) {
    9961002            RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
    9971003            generator.emitMove(tempDst.get(), localReg);
     
    10071013
    10081014    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    1009     RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), ident);
    1010     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound);
     1015    ResolveScopeInfo resolveScopeInfo;
     1016    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), ident, resolveScopeInfo);
     1017    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo);
    10111018    emitIncOrDec(generator, value.get(), m_operator);
    1012     generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
     1019    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo);
    10131020    if (generator.vm()->typeProfiler()) {
    1014         generator.emitProfileType(value.get(), ProfileTypeBytecodePutToScope, &ident);
     1021        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
    10151022        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
    10161023    }
     
    15061513        }
    15071514       
    1508         if (local.isCaptured()
    1509             || generator.vm()->typeProfiler()
     1515        if (generator.vm()->typeProfiler()
    15101516            || generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
    15111517            RefPtr<RegisterID> result = generator.newTemporary();
     
    15251531
    15261532    generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
    1527     RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
    1528     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound);
     1533    ResolveScopeInfo resolveScopeInfo;
     1534    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo);
     1535    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo);
    15291536    RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
    1530     RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound);
     1537    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound, resolveScopeInfo);
    15311538    if (generator.vm()->typeProfiler()) {
    1532         generator.emitProfileType(result.get(), ProfileTypeBytecodePutToScope, &m_ident);
     1539        generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
    15331540        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
    15341541    }
     
    15451552            return generator.emitNode(dst, m_right);
    15461553        }
    1547         if (local.isCaptured() || generator.vm()->typeProfiler()) {
     1554        if (local.isSpecial() || generator.vm()->typeProfiler()) {
    15481555            RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
    15491556            generator.emitNode(tempDst.get(), m_right);
     
    15611568    if (generator.isStrictMode())
    15621569        generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    1563     RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
     1570    ResolveScopeInfo resolveScopeInfo;
     1571    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo);
    15641572    if (dst == generator.ignoredResult())
    15651573        dst = 0;
    15661574    RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
    15671575    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    1568     RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
     1576    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
    15691577    if (generator.vm()->typeProfiler()) {
    1570         generator.emitProfileType(result.get(), ProfileTypeBytecodePutToScope, &m_ident);
     1578        generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
    15711579        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
    15721580    }
     
    16771685
    16781686        // FIXME: Maybe call emitExpressionInfo here.
    1679         if (local.isCaptured() || generator.vm()->typeProfiler()) {
     1687        if (local.isSpecial() || generator.vm()->typeProfiler()) {
    16801688            RefPtr<RegisterID> tempDst = generator.newTemporary();
    16811689            generator.emitNode(tempDst.get(), m_init);
     
    16911699        return generator.emitInitGlobalConst(m_ident, value.get());
    16921700
    1693     if (generator.codeType() != EvalCode)
     1701    if (generator.codeType() != EvalCode) {
     1702
     1703        ResolveScopeInfo resolveScopeInfo;
     1704        if (RefPtr<RegisterID> scope = generator.emitResolveConstantLocal(generator.newTemporary(), m_ident, resolveScopeInfo))
     1705            return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo);
     1706
    16941707        return value.get();
     1708    }
    16951709
    16961710    // FIXME: This will result in incorrect assignment if m_ident exists in an intervening with scope.
    1697     RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
    1698     return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound);
     1711    ResolveScopeInfo resolveScopeInfo;
     1712    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo);
     1713    return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo);
    16991714}
    17001715
     
    17931808        generator.emitProfileType(local.get(), ProfileTypeBytecodeHasGlobalID, nullptr);
    17941809    else {
    1795         RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
    1796         RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound);
    1797         generator.emitProfileType(value.get(), ProfileTypeBytecodeGetFromScope, &m_ident);
     1810        ResolveScopeInfo resolveScopeInfo;
     1811        RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo);
     1812        RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo);
     1813        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
    17981814    }
    17991815
     
    19561972        const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
    19571973        Local local = generator.local(ident);
    1958         if (local.isCaptured())
    1959             return nullptr;
    19601974        return local.get();
    19611975    }
     
    19701984        const Identifier& ident = simpleBinding->boundProperty();
    19711985        Local local = generator.local(ident);
    1972         if (local.isCaptured())
     1986        if (local.isSpecial())
    19731987            return nullptr;
    19741988        return local.get();
     
    19882002            if (generator.isStrictMode())
    19892003                generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    1990             RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident);
     2004            ResolveScopeInfo resolveScopeInfo;
     2005            RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident, resolveScopeInfo);
    19912006            generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    1992             generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
     2007            generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
    19932008        }
    19942009        return;
     
    20222037        const Identifier& ident = simpleBinding->boundProperty();
    20232038        Local local = generator.local(ident);
    2024         if (!local.get() || local.isCaptured()) {
     2039        if (!local.get() || local.isSpecial()) {
    20252040            assignNode->bindings()->bindValue(generator, propertyName);
    20262041            return;
     
    21842199                if (generator.isStrictMode())
    21852200                    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    2186                 RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident);
     2201                ResolveScopeInfo resolveScopeInfo;
     2202                RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident, resolveScopeInfo);
    21872203                generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    2188                 generator.emitPutToScope(scope, ident, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
     2204                generator.emitPutToScope(scope, ident, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
    21892205            }
    21902206        } else if (m_lexpr->isDotAccessorNode()) {
     
    28232839    if (generator.isStrictMode())
    28242840        generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
    2825     RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), m_boundProperty);
     2841    ResolveScopeInfo resolveScopeInfo;
     2842    RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), m_boundProperty, resolveScopeInfo);
    28262843    generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
    2827     generator.emitPutToScope(scope, m_boundProperty, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
     2844    generator.emitPutToScope(scope, m_boundProperty, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
    28282845    if (generator.vm()->typeProfiler()) {
    2829         generator.emitProfileType(value, ProfileTypeBytecodePutToScope, &m_boundProperty);
     2846        generator.emitProfileType(value, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_boundProperty);
    28302847        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
    28312848    }
Note: See TracChangeset for help on using the changeset viewer.