SymbolTable* SymbolTable::clone(VM& vm)
{
    SymbolTable* result = SymbolTable::create(vm);
    
    result->m_parameterCountIncludingThis = m_parameterCountIncludingThis;
    result->m_usesNonStrictEval = m_usesNonStrictEval;
    result->m_captureStart = m_captureStart;
    result->m_captureEnd = m_captureEnd;
    
    Map::iterator iter = m_map.begin();
    Map::iterator end = m_map.end();
    for (; iter != end; ++iter) {
        result->m_map.add(
            iter->key,
            SymbolTableEntry(iter->value.getIndex(), iter->value.getAttributes()));
    }
    
    if (m_slowArguments) {
        result->m_slowArguments = std::make_unique<SlowArgument[]>(parameterCount());
        for (unsigned i = parameterCount(); i--;)
            result->m_slowArguments[i] = m_slowArguments[i];
    }
    
    return result;
}
    Storage storageForGeneratorLocal(unsigned index)
    {
        // We assign a symbol to a register. There is one-on-one corresponding between a register and a symbol.
        // By doing so, we allocate the specific storage to save the given register.
        // This allow us not to save all the live registers even if the registers are not overwritten from the previous resuming time.
        // It means that, the register can be retrieved even if the immediate previous op_save does not save it.

        if (m_storages.size() <= index)
            m_storages.resize(index + 1);
        if (Optional<Storage> storage = m_storages[index])
            return *storage;

        Identifier identifier = Identifier::fromUid(PrivateName());
        unsigned identifierIndex = m_codeBlock->numberOfIdentifiers();
        m_codeBlock->addIdentifier(identifier);
        ScopeOffset scopeOffset = m_generatorFrameSymbolTable->takeNextScopeOffset(NoLockingNecessary);
        m_generatorFrameSymbolTable->set(NoLockingNecessary, identifier.impl(), SymbolTableEntry(VarOffset(scopeOffset)));

        Storage storage = {
            identifier,
            identifierIndex,
            scopeOffset
        };
        m_storages[index] = storage;
        return storage;
    }
示例#3
0
SymbolTable* SymbolTable::cloneCapturedNames(VM& vm)
{
    SymbolTable* result = SymbolTable::create(vm);
    
    result->m_parameterCountIncludingThis = m_parameterCountIncludingThis;
    result->m_usesNonStrictEval = m_usesNonStrictEval;
    result->m_captureStart = m_captureStart;
    result->m_captureEnd = m_captureEnd;

    for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
        if (!isCaptured(iter->value.getIndex()))
            continue;
        result->m_map.add(
            iter->key,
            SymbolTableEntry(iter->value.getIndex(), iter->value.getAttributes()));
    }
    
    if (m_slowArguments) {
        result->m_slowArguments = std::make_unique<SlowArgument[]>(parameterCount());
        for (unsigned i = parameterCount(); i--;)
            result->m_slowArguments[i] = m_slowArguments[i];
    }

    if (m_uniqueIDMap && result->m_uniqueIDMap) {

        {
            auto iter = m_uniqueIDMap->begin();
            auto end = m_uniqueIDMap->end();
            for (; iter != end; ++iter)
                result->m_uniqueIDMap->set(iter->key, iter->value);
        }

        {
            auto iter = m_registerToVariableMap->begin();
            auto end = m_registerToVariableMap->end();
            for (; iter != end; ++iter)
                result->m_registerToVariableMap->set(iter->key, iter->value);
        }

        {
            auto iter = m_uniqueTypeSetMap->begin();
            auto end = m_uniqueTypeSetMap->end();
            for (; iter != end; ++iter)
                result->m_uniqueTypeSetMap->set(iter->key, iter->value);
        }
    }

    
    return result;
}
示例#4
0
SymbolTable* SymbolTable::cloneScopePart(VM& vm)
{
    SymbolTable* result = SymbolTable::create(vm);
    
    result->m_usesNonStrictEval = m_usesNonStrictEval;
    result->m_nestedLexicalScope = m_nestedLexicalScope;
    result->m_scopeType = m_scopeType;

    for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
        if (!iter->value.varOffset().isScope())
            continue;
        result->m_map.add(
            iter->key,
            SymbolTableEntry(iter->value.varOffset(), iter->value.getAttributes()));
    }
    
    result->m_maxScopeOffset = m_maxScopeOffset;
    
    if (ScopedArgumentsTable* arguments = this->arguments())
        result->m_arguments.set(vm, result, arguments);
    
    if (m_typeProfilingRareData) {
        result->m_typeProfilingRareData = std::make_unique<TypeProfilingRareData>();

        {
            auto iter = m_typeProfilingRareData->m_uniqueIDMap.begin();
            auto end = m_typeProfilingRareData->m_uniqueIDMap.end();
            for (; iter != end; ++iter)
                result->m_typeProfilingRareData->m_uniqueIDMap.set(iter->key, iter->value);
        }

        {
            auto iter = m_typeProfilingRareData->m_offsetToVariableMap.begin();
            auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
            for (; iter != end; ++iter)
                result->m_typeProfilingRareData->m_offsetToVariableMap.set(iter->key, iter->value);
        }

        {
            auto iter = m_typeProfilingRareData->m_uniqueTypeSetMap.begin();
            auto end = m_typeProfilingRareData->m_uniqueTypeSetMap.end();
            for (; iter != end; ++iter)
                result->m_typeProfilingRareData->m_uniqueTypeSetMap.set(iter->key, iter->value);
        }
    }
    
    return result;
}
static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyModule(ExecState* state)
{
    VM& vm = state->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSValue val = state->argument(0);

    // If the given bytes argument is not a BufferSource, a TypeError exception is thrown.
    JSArrayBuffer* arrayBuffer = val.getObject() ? jsDynamicCast<JSArrayBuffer*>(val.getObject()) : nullptr;
    JSArrayBufferView* arrayBufferView = val.getObject() ? jsDynamicCast<JSArrayBufferView*>(val.getObject()) : nullptr;
    if (!(arrayBuffer || arrayBufferView))
        return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("first argument to WebAssembly.Module must be an ArrayBufferView or an ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val))));

    if (arrayBufferView ? arrayBufferView->isNeutered() : arrayBuffer->impl()->isNeutered())
        return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("underlying TypedArray has been detatched from the ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val))));

    size_t byteOffset = arrayBufferView ? arrayBufferView->byteOffset() : 0;
    size_t byteSize = arrayBufferView ? arrayBufferView->length() : arrayBuffer->impl()->byteLength();
    const auto* base = arrayBufferView ? static_cast<uint8_t*>(arrayBufferView->vector()) : static_cast<uint8_t*>(arrayBuffer->impl()->data());

    Wasm::Plan plan(&vm, base + byteOffset, byteSize);
    // On failure, a new WebAssembly.CompileError is thrown.
    plan.run();
    if (plan.failed())
        return JSValue::encode(throwException(state, scope, createWebAssemblyCompileError(state, plan.errorMessage())));

    // On success, a new WebAssembly.Module object is returned with [[Module]] set to the validated Ast.module.
    auto* structure = InternalFunction::createSubclassStructure(state, state->newTarget(), asInternalFunction(state->jsCallee())->globalObject()->WebAssemblyModuleStructure());
    RETURN_IF_EXCEPTION(scope, { });

    // The export symbol table is the same for all Instances of a Module.
    SymbolTable* exportSymbolTable = SymbolTable::create(vm);
    for (auto& exp : plan.exports()) {
        auto offset = exportSymbolTable->takeNextScopeOffset(NoLockingNecessary);
        exportSymbolTable->set(NoLockingNecessary, exp.field.impl(), SymbolTableEntry(VarOffset(offset)));
    }

    // Only wasm-internal functions have a callee, stubs to JS do not.
    unsigned calleeCount = plan.internalFunctionCount();
    JSWebAssemblyModule* result = JSWebAssemblyModule::create(vm, structure, plan.takeModuleInformation(), plan.takeCallLinkInfos(), plan.takeWasmToJSStubs(), plan.takeFunctionIndexSpace(), exportSymbolTable, calleeCount);
    plan.initializeCallees(state->jsCallee()->globalObject(), 
        [&] (unsigned calleeIndex, JSWebAssemblyCallee* jsEntrypointCallee, JSWebAssemblyCallee* wasmEntrypointCallee) {
            result->setJSEntrypointCallee(vm, calleeIndex, jsEntrypointCallee);
            result->setWasmEntrypointCallee(vm, calleeIndex, wasmEntrypointCallee);
        });
    return JSValue::encode(result);
}
JSValue WebAssemblyModuleConstructor::createModule(ExecState* state, Structure* structure)
{
    VM& vm = state->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    size_t byteOffset;
    size_t byteSize;
    uint8_t* base = getWasmBufferFromValue(state, state->argument(0), byteOffset, byteSize);
    RETURN_IF_EXCEPTION(scope, { });

    Wasm::Plan plan(&vm, base + byteOffset, byteSize);
    // On failure, a new WebAssembly.CompileError is thrown.
    plan.run();
    if (plan.failed())
        return throwException(state, scope, createJSWebAssemblyCompileError(state, vm, plan.errorMessage()));

    // On success, a new WebAssembly.Module object is returned with [[Module]] set to the validated Ast.module.

    // The export symbol table is the same for all Instances of a Module.
    SymbolTable* exportSymbolTable = SymbolTable::create(vm);
    for (auto& exp : plan.exports()) {
        auto offset = exportSymbolTable->takeNextScopeOffset(NoLockingNecessary);
        exportSymbolTable->set(NoLockingNecessary, exp.field.impl(), SymbolTableEntry(VarOffset(offset)));
    }

    // Only wasm-internal functions have a callee, stubs to JS do not.
    unsigned calleeCount = plan.internalFunctionCount();
    JSWebAssemblyModule* result = JSWebAssemblyModule::create(vm, structure, plan.takeModuleInformation(), plan.takeCallLinkInfos(), plan.takeWasmExitStubs(), exportSymbolTable, calleeCount);
    plan.initializeCallees(state->jsCallee()->globalObject(), 
        [&] (unsigned calleeIndex, JSWebAssemblyCallee* jsEntrypointCallee, JSWebAssemblyCallee* wasmEntrypointCallee) {
            result->setJSEntrypointCallee(vm, calleeIndex, jsEntrypointCallee);
            result->setWasmEntrypointCallee(vm, calleeIndex, wasmEntrypointCallee);
        });

    return result;
}