Пример #1
0
void Arguments::tearOff(CallFrame* callFrame)
{
    if (isTornOff())
        return;

    if (!m_numArguments)
        return;

    // Must be called for the same call frame from which it was created.
    ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == m_registers);
    
    m_registerArray = std::make_unique<WriteBarrier<Unknown>[]>(m_numArguments);
    m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1;

    // If we have a captured argument that logically aliases activation storage,
    // but we optimize away the activation, the argument needs to tear off into
    // our storage. The simplest way to do this is to revert it to Normal status.
    if (m_slowArgumentData && !m_activation) {
        for (size_t i = 0; i < m_numArguments; ++i) {
            if (m_slowArgumentData->slowArguments[i].status != SlowArgument::Captured)
                continue;
            m_slowArgumentData->slowArguments[i].status = SlowArgument::Normal;
            m_slowArgumentData->slowArguments[i].index = CallFrame::argumentOffset(i);
        }
    }

    for (size_t i = 0; i < m_numArguments; ++i)
        trySetArgument(callFrame->vm(), i, callFrame->argumentAfterCapture(i));
}
Пример #2
0
void Arguments::didTearOffActivation(ExecState* exec, JSActivation* activation)
{
    RELEASE_ASSERT(activation);
    if (isTornOff())
        return;

    if (!m_numArguments)
        return;
    
    m_activation.set(exec->vm(), this, activation);
    tearOff(exec);
}
inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertyDescriptor& descriptor)
{
    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
    if (entry.isNull())
        return false;

    // Defend against the inspector asking for a var after it has been optimized out.
    if (isTornOff() && !isValid(entry))
        return false;

    descriptor.setDescriptor(registerAt(entry.getIndex()).get(), entry.getAttributes());
    return true;
}
inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertySlot& slot)
{
    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
    if (entry.isNull())
        return false;

    // Defend against the inspector asking for a var after it has been optimized out.
    if (isTornOff() && !isValid(entry))
        return false;

    slot.setValue(this, DontEnum, registerAt(entry.getIndex()).get());
    return true;
}
Пример #5
0
void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
{
    if (isTornOff())
        return;
    
    if (!d->numArguments)
        return;
    
    d->registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[d->numArguments]);
    d->registers = d->registerArray.get() + CallFrame::offsetFor(d->numArguments + 1);

    tearOffForInlineCallFrame(
        callFrame->globalData(), callFrame->registers() + inlineCallFrame->stackOffset,
        inlineCallFrame);
}
Пример #6
0
void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
{
    RELEASE_ASSERT(!inlineCallFrame->baselineCodeBlock()->needsActivation());
    if (isTornOff())
        return;
    
    if (!m_numArguments)
        return;

    m_registers = &registerArray() - CallFrame::offsetFor(1) - 1;

    for (size_t i = 0; i < m_numArguments; ++i) {
        ValueRecovery& recovery = inlineCallFrame->arguments[i + 1];
        trySetArgument(callFrame->vm(), i, recovery.recover(callFrame));
    }
}
Пример #7
0
void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
{
    if (isTornOff())
        return;
    
    if (!m_numArguments)
        return;
    
    m_registerArray = std::make_unique<WriteBarrier<Unknown>[]>(m_numArguments);
    m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1;

    for (size_t i = 0; i < m_numArguments; ++i) {
        ValueRecovery& recovery = inlineCallFrame->arguments[i + 1];
        trySetArgument(callFrame->vm(), i, recovery.recover(callFrame));
    }
}
Пример #8
0
void Arguments::tearOff(CallFrame* callFrame)
{
    if (isTornOff())
        return;

    if (!m_numArguments)
        return;

    // Must be called for the same call frame from which it was created.
    ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == m_registers);
    
    allocateRegisterArray(callFrame->vm());
    m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1;

    for (size_t i = 0; i < m_numArguments; ++i) {
        if (m_slowArgumentData && m_slowArgumentData->slowArguments()[i].status == SlowArgument::Captured)
            continue;
        trySetArgument(callFrame->vm(), i, callFrame->argumentAfterCapture(i));
    }
}
inline bool JSActivation::symbolTablePut(ExecState* exec, PropertyName propertyName, JSValue value, bool shouldThrow)
{
    VM& vm = exec->vm();
    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
    
    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
    if (entry.isNull())
        return false;
    if (entry.isReadOnly()) {
        if (shouldThrow)
            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
        return true;
    }

    // Defend against the inspector asking for a var after it has been optimized out.
    if (isTornOff() && !isValid(entry))
        return false;

    registerAt(entry.getIndex()).set(vm, this, value);
    return true;
}
Пример #10
0
void Arguments::tearOff(CallFrame* callFrame)
{
    if (isTornOff())
        return;

    if (!d->numArguments)
        return;

    // Must be called for the same call frame from which it was created.
    ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == d->registers);
    
    d->registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[d->numArguments]);
    d->registers = d->registerArray.get() + CallFrame::offsetFor(d->numArguments + 1);

    if (!callFrame->isInlineCallFrame()) {
        for (size_t i = 0; i < d->numArguments; ++i)
            argument(i).set(callFrame->globalData(), this, callFrame->argument(i));
        return;
    }

    tearOffForInlineCallFrame(
        callFrame->globalData(), callFrame->registers(), callFrame->inlineCallFrame());
}