Пример #1
0
EncodedJSValue JSC_HOST_CALL webAssemblyValidateFunc(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    size_t byteOffset;
    size_t byteSize;
    uint8_t* base = getWasmBufferFromValue(exec, exec->argument(0), byteOffset, byteSize);
    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    Wasm::Plan plan(&vm, base + byteOffset, byteSize);
    // FIXME: We might want to throw an OOM exception here if we detect that something will OOM.
    // https://bugs.webkit.org/show_bug.cgi?id=166015
    return JSValue::encode(jsBoolean(plan.parseAndValidateModule()));
}
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;
}