Changeset 230697 in webkit


Ignore:
Timestamp:
Apr 16, 2018 7:38:59 PM (6 years ago)
Author:
Yusuke Suzuki
Message:

[WebAssembly][Modules] Prototype wasm import
https://bugs.webkit.org/show_bug.cgi?id=184600

Reviewed by JF Bastien.

JSTests:

Add wasm and wat files since module loader want to load wasm files from FS.
Currently, importing the other modules from wasm is not supported.

  • wasm.yaml:
  • wasm/modules/constant.wasm: Added.
  • wasm/modules/constant.wat: Added.
  • wasm/modules/js-wasm-function-namespace.js: Added.

(assert.throws):

  • wasm/modules/js-wasm-function.js: Added.

(assert.throws):

  • wasm/modules/js-wasm-global-namespace.js: Added.

(assert.throws):

  • wasm/modules/js-wasm-global.js: Added.

(assert.throws):

  • wasm/modules/js-wasm-memory-namespace.js: Added.

(assert.throws):

  • wasm/modules/js-wasm-memory.js: Added.

(assert.throws):

  • wasm/modules/js-wasm-start.js: Added.

(then):

  • wasm/modules/js-wasm-table-namespace.js: Added.

(assert.throws):

  • wasm/modules/js-wasm-table.js: Added.

(assert.throws):

  • wasm/modules/memory.wasm: Added.
  • wasm/modules/memory.wat: Added.
  • wasm/modules/start.wasm: Added.
  • wasm/modules/start.wat: Added.
  • wasm/modules/sum.wasm: Added.
  • wasm/modules/sum.wat: Added.
  • wasm/modules/table.wasm: Added.
  • wasm/modules/table.wat: Added.

Source/JavaScriptCore:

This patch is an initial attempt to implement Wasm loading in module pipeline.
Currently,

  1. We only support Wasm loading in the JSC shell. Once loading mechanism is specified in whatwg HTML, we should integrate this into WebCore.
  1. We only support exporting values from Wasm. Wasm module cannot import anything from the other modules now.

When loading a file, JSC shell checks wasm magic. If the wasm magic is found, JSC shell
loads the file with WebAssemblySourceProvider. It is wrapped into JSSourceCode and
module loader pipeline just handles it as the same to JS. When parsing a module, we
checks the type of JSSourceCode. If the source code is Wasm source code, we create a
WebAssemblyModuleRecord instead of JSModuleRecord. Our module pipeline handles
AbstractModuleRecord and Wasm module is instantiated, linked, and evaluated.

  • builtins/ModuleLoaderPrototype.js:

(globalPrivate.newRegistryEntry):
(requestInstantiate):
(link):

  • jsc.cpp:

(convertShebangToJSComment):
(fillBufferWithContentsOfFile):
(fetchModuleFromLocalFileSystem):
(GlobalObject::moduleLoaderFetch):

  • parser/SourceProvider.h:

(JSC::WebAssemblySourceProvider::create):
(JSC::WebAssemblySourceProvider::WebAssemblySourceProvider):

  • runtime/AbstractModuleRecord.cpp:

(JSC::AbstractModuleRecord::hostResolveImportedModule):
(JSC::AbstractModuleRecord::link):
(JSC::AbstractModuleRecord::evaluate):
(JSC::identifierToJSValue): Deleted.

  • runtime/AbstractModuleRecord.h:
  • runtime/JSModuleLoader.cpp:

(JSC::JSModuleLoader::evaluate):

  • runtime/JSModuleRecord.cpp:

(JSC::JSModuleRecord::link):
(JSC::JSModuleRecord::instantiateDeclarations):

  • runtime/JSModuleRecord.h:
  • runtime/ModuleLoaderPrototype.cpp:

(JSC::moduleLoaderPrototypeParseModule):
(JSC::moduleLoaderPrototypeRequestedModules):
(JSC::moduleLoaderPrototypeModuleDeclarationInstantiation):

  • wasm/js/JSWebAssemblyHelpers.h:

(JSC::getWasmBufferFromValue):
(JSC::createSourceBufferFromValue):

  • wasm/js/JSWebAssemblyInstance.cpp:

(JSC::JSWebAssemblyInstance::finalizeCreation):
(JSC::JSWebAssemblyInstance::createPrivateModuleKey):
(JSC::JSWebAssemblyInstance::create):

  • wasm/js/JSWebAssemblyInstance.h:
  • wasm/js/WebAssemblyInstanceConstructor.cpp:

(JSC::constructJSWebAssemblyInstance):

  • wasm/js/WebAssemblyModuleRecord.cpp:

(JSC::WebAssemblyModuleRecord::prepareLink):
(JSC::WebAssemblyModuleRecord::link):

  • wasm/js/WebAssemblyModuleRecord.h:
  • wasm/js/WebAssemblyPrototype.cpp:

(JSC::resolve):
(JSC::instantiate):
(JSC::compileAndInstantiate):
(JSC::WebAssemblyPrototype::instantiate):
(JSC::webAssemblyInstantiateFunc):
(JSC::webAssemblyValidateFunc):

  • wasm/js/WebAssemblyPrototype.h:
Location:
trunk
Files:
20 added
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r230662 r230697  
     12018-04-16  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [WebAssembly][Modules] Prototype wasm import
     4        https://bugs.webkit.org/show_bug.cgi?id=184600
     5
     6        Reviewed by JF Bastien.
     7
     8        Add wasm and wat files since module loader want to load wasm files from FS.
     9        Currently, importing the other modules from wasm is not supported.
     10
     11        * wasm.yaml:
     12        * wasm/modules/constant.wasm: Added.
     13        * wasm/modules/constant.wat: Added.
     14        * wasm/modules/js-wasm-function-namespace.js: Added.
     15        (assert.throws):
     16        * wasm/modules/js-wasm-function.js: Added.
     17        (assert.throws):
     18        * wasm/modules/js-wasm-global-namespace.js: Added.
     19        (assert.throws):
     20        * wasm/modules/js-wasm-global.js: Added.
     21        (assert.throws):
     22        * wasm/modules/js-wasm-memory-namespace.js: Added.
     23        (assert.throws):
     24        * wasm/modules/js-wasm-memory.js: Added.
     25        (assert.throws):
     26        * wasm/modules/js-wasm-start.js: Added.
     27        (then):
     28        * wasm/modules/js-wasm-table-namespace.js: Added.
     29        (assert.throws):
     30        * wasm/modules/js-wasm-table.js: Added.
     31        (assert.throws):
     32        * wasm/modules/memory.wasm: Added.
     33        * wasm/modules/memory.wat: Added.
     34        * wasm/modules/start.wasm: Added.
     35        * wasm/modules/start.wat: Added.
     36        * wasm/modules/sum.wasm: Added.
     37        * wasm/modules/sum.wat: Added.
     38        * wasm/modules/table.wasm: Added.
     39        * wasm/modules/table.wat: Added.
     40
    1412018-04-14  Filip Pizlo  <fpizlo@apple.com>
    242
  • trunk/JSTests/wasm.yaml

    r220894 r230697  
    3737  cmd: runWebAssemblyLowExecutableMemory unless parseRunCommands
    3838- path: wasm/regress/
     39  cmd: runWebAssembly unless parseRunCommands
     40- path: wasm/modules/
    3941  cmd: runWebAssembly unless parseRunCommands
    4042
  • trunk/Source/JavaScriptCore/ChangeLog

    r230662 r230697  
     12018-04-16  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [WebAssembly][Modules] Prototype wasm import
     4        https://bugs.webkit.org/show_bug.cgi?id=184600
     5
     6        Reviewed by JF Bastien.
     7
     8        This patch is an initial attempt to implement Wasm loading in module pipeline.
     9        Currently,
     10
     11        1. We only support Wasm loading in the JSC shell. Once loading mechanism is specified
     12           in whatwg HTML, we should integrate this into WebCore.
     13
     14        2. We only support exporting values from Wasm. Wasm module cannot import anything from
     15           the other modules now.
     16
     17        When loading a file, JSC shell checks wasm magic. If the wasm magic is found, JSC shell
     18        loads the file with WebAssemblySourceProvider. It is wrapped into JSSourceCode and
     19        module loader pipeline just handles it as the same to JS. When parsing a module, we
     20        checks the type of JSSourceCode. If the source code is Wasm source code, we create a
     21        WebAssemblyModuleRecord instead of JSModuleRecord. Our module pipeline handles
     22        AbstractModuleRecord and Wasm module is instantiated, linked, and evaluated.
     23
     24        * builtins/ModuleLoaderPrototype.js:
     25        (globalPrivate.newRegistryEntry):
     26        (requestInstantiate):
     27        (link):
     28        * jsc.cpp:
     29        (convertShebangToJSComment):
     30        (fillBufferWithContentsOfFile):
     31        (fetchModuleFromLocalFileSystem):
     32        (GlobalObject::moduleLoaderFetch):
     33        * parser/SourceProvider.h:
     34        (JSC::WebAssemblySourceProvider::create):
     35        (JSC::WebAssemblySourceProvider::WebAssemblySourceProvider):
     36        * runtime/AbstractModuleRecord.cpp:
     37        (JSC::AbstractModuleRecord::hostResolveImportedModule):
     38        (JSC::AbstractModuleRecord::link):
     39        (JSC::AbstractModuleRecord::evaluate):
     40        (JSC::identifierToJSValue): Deleted.
     41        * runtime/AbstractModuleRecord.h:
     42        * runtime/JSModuleLoader.cpp:
     43        (JSC::JSModuleLoader::evaluate):
     44        * runtime/JSModuleRecord.cpp:
     45        (JSC::JSModuleRecord::link):
     46        (JSC::JSModuleRecord::instantiateDeclarations):
     47        * runtime/JSModuleRecord.h:
     48        * runtime/ModuleLoaderPrototype.cpp:
     49        (JSC::moduleLoaderPrototypeParseModule):
     50        (JSC::moduleLoaderPrototypeRequestedModules):
     51        (JSC::moduleLoaderPrototypeModuleDeclarationInstantiation):
     52        * wasm/js/JSWebAssemblyHelpers.h:
     53        (JSC::getWasmBufferFromValue):
     54        (JSC::createSourceBufferFromValue):
     55        * wasm/js/JSWebAssemblyInstance.cpp:
     56        (JSC::JSWebAssemblyInstance::finalizeCreation):
     57        (JSC::JSWebAssemblyInstance::createPrivateModuleKey):
     58        (JSC::JSWebAssemblyInstance::create):
     59        * wasm/js/JSWebAssemblyInstance.h:
     60        * wasm/js/WebAssemblyInstanceConstructor.cpp:
     61        (JSC::constructJSWebAssemblyInstance):
     62        * wasm/js/WebAssemblyModuleRecord.cpp:
     63        (JSC::WebAssemblyModuleRecord::prepareLink):
     64        (JSC::WebAssemblyModuleRecord::link):
     65        * wasm/js/WebAssemblyModuleRecord.h:
     66        * wasm/js/WebAssemblyPrototype.cpp:
     67        (JSC::resolve):
     68        (JSC::instantiate):
     69        (JSC::compileAndInstantiate):
     70        (JSC::WebAssemblyPrototype::instantiate):
     71        (JSC::webAssemblyInstantiateFunc):
     72        (JSC::webAssemblyValidateFunc):
     73        * wasm/js/WebAssemblyPrototype.h:
     74
    1752018-04-14  Filip Pizlo  <fpizlo@apple.com>
    276
  • trunk/Source/JavaScriptCore/builtins/ModuleLoaderPrototype.js

    r230459 r230697  
    9696        satisfy: @undefined,
    9797        dependencies: [], // To keep the module order, we store the module keys in the array.
    98         dependenciesMap: @undefined,
    9998        module: @undefined, // JSModuleRecord
    10099        linkError: @undefined,
     
    198197
    199198        var key = entry.key;
    200         var moduleRecord = this.parseModule(key, source);
    201         var dependenciesMap = moduleRecord.dependenciesMap;
    202         var requestedModules = this.requestedModules(moduleRecord);
    203         var dependencies = @newArrayWithSize(requestedModules.length);
    204         for (var i = 0, length = requestedModules.length; i < length; ++i) {
    205             var depName = requestedModules[i];
    206             var depKey = this.resolveSync(depName, key, fetcher);
    207             var depEntry = this.ensureRegistered(depKey);
    208             @putByValDirect(dependencies, i, depEntry);
    209             dependenciesMap.@set(depName, depEntry);
    210         }
    211         entry.dependencies = dependencies;
    212         entry.dependenciesMap = dependenciesMap;
    213         entry.module = moduleRecord;
    214         @setStateToMax(entry, @ModuleSatisfy);
    215         return entry;
     199        return this.parseModule(key, source).then((moduleRecord) => {
     200            var dependenciesMap = moduleRecord.dependenciesMap;
     201            var requestedModules = this.requestedModules(moduleRecord);
     202            var dependencies = @newArrayWithSize(requestedModules.length);
     203            for (var i = 0, length = requestedModules.length; i < length; ++i) {
     204                var depName = requestedModules[i];
     205                var depKey = this.resolveSync(depName, key, fetcher);
     206                var depEntry = this.ensureRegistered(depKey);
     207                @putByValDirect(dependencies, i, depEntry);
     208                dependenciesMap.@set(depName, depEntry);
     209            }
     210            entry.dependencies = dependencies;
     211            entry.module = moduleRecord;
     212            @setStateToMax(entry, @ModuleSatisfy);
     213            return entry;
     214        });
    216215    });
    217216    return instantiatePromise;
     
    289288            this.link(dependencies[i], fetcher);
    290289
    291         this.moduleDeclarationInstantiation(entry.module, entry.key, fetcher);
     290        this.moduleDeclarationInstantiation(entry.module, fetcher);
    292291    } catch (error) {
    293292        entry.linkSucceeded = false;
  • trunk/Source/JavaScriptCore/jsc.cpp

    r229605 r230697  
    187187}
    188188
    189 static bool fillBufferWithContentsOfFile(const String& fileName, Vector<char>& buffer);
     189template<typename Vector>
     190static bool fillBufferWithContentsOfFile(const String& fileName, Vector& buffer);
    190191static RefPtr<Uint8Array> fillBufferWithContentsOfFile(const String& fileName);
    191192
     
    845846}
    846847
    847 static void convertShebangToJSComment(Vector<char>& buffer)
     848template<typename Vector>
     849static void convertShebangToJSComment(Vector& buffer)
    848850{
    849851    if (buffer.size() >= 2) {
     
    883885}
    884886
    885 static bool fillBufferWithContentsOfFile(FILE* file, Vector<char>& buffer)
     887template<typename Vector>
     888static bool fillBufferWithContentsOfFile(FILE* file, Vector& buffer)
    886889{
    887890    // We might have injected "use strict"; at the top.
     
    921924}
    922925
    923 static bool fetchModuleFromLocalFileSystem(const String& fileName, Vector<char>& buffer)
     926template<typename Vector>
     927static bool fetchModuleFromLocalFileSystem(const String& fileName, Vector& buffer)
    924928{
    925929    // We assume that fileName is always an absolute path.
     
    972976
    973977    // Here, now we consider moduleKey as the fileName.
    974     Vector<char> utf8;
    975     if (!fetchModuleFromLocalFileSystem(moduleKey, utf8)) {
     978    Vector<uint8_t> buffer;
     979    if (!fetchModuleFromLocalFileSystem(moduleKey, buffer)) {
    976980        auto result = deferred->reject(exec, createError(exec, makeString("Could not open file '", moduleKey, "'.")));
    977981        scope.releaseAssertNoException();
     
    979983    }
    980984
    981     auto result = deferred->resolve(exec, JSSourceCode::create(vm, makeSource(stringFromUTF(utf8), SourceOrigin { moduleKey }, moduleKey, TextPosition(), SourceProviderSourceType::Module)));
     985#if ENABLE(WEBASSEMBLY)
     986    // FileSystem does not have mime-type header. The JSC shell recognizes WebAssembly's magic header.
     987    if (buffer.size() >= 4) {
     988        if (buffer[0] == '\0' && buffer[1] == 'a' && buffer[2] == 's' && buffer[3] == 'm') {
     989            auto result = deferred->resolve(exec, JSSourceCode::create(vm, SourceCode(WebAssemblySourceProvider::create(WTFMove(buffer), SourceOrigin { moduleKey }, moduleKey))));
     990            scope.releaseAssertNoException();
     991            return result;
     992        }
     993    }
     994#endif
     995
     996    auto result = deferred->resolve(exec, JSSourceCode::create(vm, makeSource(stringFromUTF(buffer), SourceOrigin { moduleKey }, moduleKey, TextPosition(), SourceProviderSourceType::Module)));
    982997    scope.releaseAssertNoException();
    983998    return result;
  • trunk/Source/JavaScriptCore/parser/SourceProvider.h

    r210149 r230697  
    121121    class WebAssemblySourceProvider : public SourceProvider {
    122122    public:
    123         static Ref<WebAssemblySourceProvider> create(const Vector<uint8_t>& data, const SourceOrigin& sourceOrigin, const String& url)
     123        static Ref<WebAssemblySourceProvider> create(Vector<uint8_t>&& data, const SourceOrigin& sourceOrigin, const String& url)
    124124        {
    125             return adoptRef(*new WebAssemblySourceProvider(data, sourceOrigin, url));
     125            return adoptRef(*new WebAssemblySourceProvider(WTFMove(data), sourceOrigin, url));
    126126        }
    127127
     
    142142
    143143    private:
    144         WebAssemblySourceProvider(const Vector<uint8_t>& data, const SourceOrigin& sourceOrigin, const String& url)
     144        WebAssemblySourceProvider(Vector<uint8_t>&& data, const SourceOrigin& sourceOrigin, const String& url)
    145145            : SourceProvider(sourceOrigin, url, TextPosition(), SourceProviderSourceType::WebAssembly)
    146146            , m_source("[WebAssembly source]")
    147             , m_data(data)
     147            , m_data(WTFMove(data))
    148148        {
    149149        }
  • trunk/Source/JavaScriptCore/runtime/AbstractModuleRecord.cpp

    r223894 r230697  
    3333#include "JSModuleEnvironment.h"
    3434#include "JSModuleNamespaceObject.h"
     35#include "JSModuleRecord.h"
    3536#include "UnlinkedModuleProgramCodeBlock.h"
     37#include "WebAssemblyModuleRecord.h"
    3638
    3739namespace JSC {
     
    138140}
    139141
    140 static JSValue identifierToJSValue(ExecState* exec, const Identifier& identifier)
    141 {
    142     VM& vm = exec->vm();
    143     if (identifier.isSymbol())
    144         return Symbol::create(vm, static_cast<SymbolImpl&>(*identifier.impl()));
    145     return jsString(&vm, identifier.impl());
    146 }
    147 
    148142AbstractModuleRecord* AbstractModuleRecord::hostResolveImportedModule(ExecState* exec, const Identifier& moduleName)
    149143{
    150144    VM& vm = exec->vm();
    151145    auto scope = DECLARE_THROW_SCOPE(vm);
    152     JSValue moduleNameValue = identifierToJSValue(exec, moduleName);
     146    JSValue moduleNameValue = identifierToJSValue(vm, moduleName);
    153147    JSValue entry = m_dependenciesMap->JSMap::get(exec, moduleNameValue);
    154148    RETURN_IF_EXCEPTION(scope, nullptr);
     
    776770}
    777771
     772void AbstractModuleRecord::link(ExecState* exec, JSValue scriptFetcher)
     773{
     774    VM& vm = exec->vm();
     775    if (auto* jsModuleRecord = jsDynamicCast<JSModuleRecord*>(vm, this))
     776        return jsModuleRecord->link(exec, scriptFetcher);
     777#if ENABLE(WEBASSEMBLY)
     778    if (auto* wasmModuleRecord = jsDynamicCast<WebAssemblyModuleRecord*>(vm, this))
     779        return wasmModuleRecord->link(exec, scriptFetcher);
     780#endif
     781    RELEASE_ASSERT_NOT_REACHED();
     782}
     783
     784JS_EXPORT_PRIVATE JSValue AbstractModuleRecord::evaluate(ExecState* exec)
     785{
     786    VM& vm = exec->vm();
     787    if (auto* jsModuleRecord = jsDynamicCast<JSModuleRecord*>(vm, this))
     788        return jsModuleRecord->evaluate(exec);
     789#if ENABLE(WEBASSEMBLY)
     790    if (auto* wasmModuleRecord = jsDynamicCast<WebAssemblyModuleRecord*>(vm, this))
     791        return wasmModuleRecord->evaluate(exec);
     792#endif
     793    RELEASE_ASSERT_NOT_REACHED();
     794    return jsUndefined();
     795}
     796
    778797static String printableName(const RefPtr<UniquedStringImpl>& uid)
    779798{
  • trunk/Source/JavaScriptCore/runtime/AbstractModuleRecord.h

    r218794 r230697  
    120120    }
    121121
     122    void link(ExecState*, JSValue scriptFetcher);
     123    JS_EXPORT_PRIVATE JSValue evaluate(ExecState*);
     124
    122125protected:
    123126    AbstractModuleRecord(VM&, Structure*, const Identifier&);
  • trunk/Source/JavaScriptCore/runtime/JSModuleLoader.cpp

    r224309 r230697  
    276276        return globalObject->globalObjectMethodTable()->moduleLoaderEvaluate(globalObject, exec, this, key, moduleRecordValue, scriptFetcher);
    277277
    278     JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(exec->vm(), moduleRecordValue);
    279     if (!moduleRecord)
    280         return jsUndefined();
    281     return moduleRecord->evaluate(exec);
     278    if (auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(exec->vm(), moduleRecordValue))
     279        return moduleRecord->evaluate(exec);
     280    return jsUndefined();
    282281}
    283282
  • trunk/Source/JavaScriptCore/runtime/JSModuleRecord.cpp

    r225799 r230697  
    7979}
    8080
    81 void JSModuleRecord::link(ExecState* exec, JSValue key, JSValue scriptFetcher)
     81void JSModuleRecord::link(ExecState* exec, JSValue scriptFetcher)
    8282{
    8383    VM& vm = exec->vm();
     
    9090        return;
    9191    }
    92     instantiateDeclarations(exec, executable, key, scriptFetcher);
     92    instantiateDeclarations(exec, executable, scriptFetcher);
    9393    RETURN_IF_EXCEPTION(scope, void());
    9494    m_moduleProgramExecutable.set(vm, this, executable);
    9595}
    9696
    97 void JSModuleRecord::instantiateDeclarations(ExecState* exec, ModuleProgramExecutable* moduleProgramExecutable, JSValue key, JSValue scriptFetcher)
     97void JSModuleRecord::instantiateDeclarations(ExecState* exec, ModuleProgramExecutable* moduleProgramExecutable, JSValue scriptFetcher)
    9898{
    9999    VM& vm = exec->vm();
     
    209209
    210210    {
    211         JSObject* metaProperties = exec->lexicalGlobalObject()->moduleLoader()->createImportMetaProperties(exec, key, this, scriptFetcher);
     211        JSObject* metaProperties = exec->lexicalGlobalObject()->moduleLoader()->createImportMetaProperties(exec, identifierToJSValue(vm, moduleKey()), this, scriptFetcher);
    212212        RETURN_IF_EXCEPTION(scope, void());
    213213        bool putResult = false;
  • trunk/Source/JavaScriptCore/runtime/JSModuleRecord.h

    r229413 r230697  
    4646    static JSModuleRecord* create(ExecState*, VM&, Structure*, const Identifier&, const SourceCode&, const VariableEnvironment&, const VariableEnvironment&);
    4747
    48     void link(ExecState*, JSValue key, JSValue scriptFetcher);
     48    void link(ExecState*, JSValue scriptFetcher);
    4949    JS_EXPORT_PRIVATE JSValue evaluate(ExecState*);
    5050
     
    6161    static void destroy(JSCell*);
    6262
    63     void instantiateDeclarations(ExecState*, ModuleProgramExecutable*, JSValue key, JSValue scriptFetcher);
     63    void instantiateDeclarations(ExecState*, ModuleProgramExecutable*, JSValue scriptFetcher);
    6464
    6565    SourceCode m_sourceCode;
  • trunk/Source/JavaScriptCore/runtime/ModuleLoaderPrototype.cpp

    r223777 r230697  
    4646#include "Parser.h"
    4747#include "ParserError.h"
     48#include "WebAssemblyPrototype.h"
    4849
    4950namespace JSC {
     
    7778    requestSatisfy                 JSBuiltin                                           DontEnum|Function 3
    7879    link                           JSBuiltin                                           DontEnum|Function 2
    79     moduleDeclarationInstantiation moduleLoaderPrototypeModuleDeclarationInstantiation DontEnum|Function 3
     80    moduleDeclarationInstantiation moduleLoaderPrototypeModuleDeclarationInstantiation DontEnum|Function 2
    8081    moduleEvaluation               JSBuiltin                                           DontEnum|Function 2
    8182    evaluate                       moduleLoaderPrototypeEvaluate                       DontEnum|Function 3
     
    104105{
    105106    VM& vm = exec->vm();
    106     auto scope = DECLARE_THROW_SCOPE(vm);
     107    auto scope = DECLARE_CATCH_SCOPE(vm);
     108
     109    JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::create(exec, exec->lexicalGlobalObject());
     110    scope.releaseAssertNoException();
     111
     112    auto reject = [&] {
     113        JSValue exception = scope.exception();
     114        scope.clearException();
     115        return JSValue::encode(deferred->reject(exec, exception));
     116    };
    107117
    108118    const Identifier moduleKey = exec->argument(0).toPropertyKey(exec);
    109     RETURN_IF_EXCEPTION(scope, encodedJSValue());
    110 
    111     auto* jsSourceCode = jsDynamicCast<JSSourceCode*>(vm, exec->argument(1));
    112     if (!jsSourceCode)
    113         return throwVMTypeError(exec, scope);
     119    if (UNLIKELY(scope.exception()))
     120        return reject();
     121
     122    JSValue source = exec->argument(1);
     123    auto* jsSourceCode = jsCast<JSSourceCode*>(source);
    114124    SourceCode sourceCode = jsSourceCode->sourceCode();
     125
     126#if ENABLE(WEBASSEMBLY)
     127    if (sourceCode.provider()->sourceType() == SourceProviderSourceType::WebAssembly)
     128        return JSValue::encode(WebAssemblyPrototype::instantiate(exec, deferred, moduleKey, jsSourceCode));
     129#endif
    115130
    116131    CodeProfiling profile(sourceCode);
     
    120135        &vm, sourceCode, Identifier(), JSParserBuiltinMode::NotBuiltin,
    121136        JSParserStrictMode::Strict, JSParserScriptMode::Module, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error);
    122 
    123     if (error.isValid()) {
    124         throwVMError(exec, scope, error.toErrorObject(exec->lexicalGlobalObject(), sourceCode));
    125         return JSValue::encode(jsUndefined());
    126     }
     137    if (error.isValid())
     138        return JSValue::encode(deferred->reject(exec, error.toErrorObject(exec->lexicalGlobalObject(), sourceCode)));
    127139    ASSERT(moduleProgramNode);
    128140
    129141    ModuleAnalyzer moduleAnalyzer(exec, moduleKey, sourceCode, moduleProgramNode->varDeclarations(), moduleProgramNode->lexicalVariables());
    130     RETURN_IF_EXCEPTION(scope, encodedJSValue());
    131     JSModuleRecord* moduleRecord = moduleAnalyzer.analyze(*moduleProgramNode);
    132 
    133     return JSValue::encode(moduleRecord);
     142    if (UNLIKELY(scope.exception()))
     143        return reject();
     144
     145    return JSValue::encode(deferred->resolve(exec, moduleAnalyzer.analyze(*moduleProgramNode)));
    134146}
    135147
     
    138150    VM& vm = exec->vm();
    139151    auto scope = DECLARE_THROW_SCOPE(vm);
    140     JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(vm, exec->argument(0));
     152    auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(vm, exec->argument(0));
    141153    if (!moduleRecord) {
    142154        scope.release();
     
    158170    VM& vm = exec->vm();
    159171    auto scope = DECLARE_THROW_SCOPE(vm);
    160     JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(vm, exec->argument(0));
     172    auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(vm, exec->argument(0));
    161173    if (!moduleRecord)
    162174        return JSValue::encode(jsUndefined());
     
    165177        dataLog("Loader [link] ", moduleRecord->moduleKey(), "\n");
    166178
    167     moduleRecord->link(exec, exec->argument(1), exec->argument(2));
     179    moduleRecord->link(exec, exec->argument(1));
    168180    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    169181
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h

    r230119 r230697  
    3030#include "JSArrayBuffer.h"
    3131#include "JSCJSValue.h"
     32#include "JSSourceCode.h"
    3233#include "WebAssemblyFunction.h"
    3334#include "WebAssemblyWrapperFunction.h"
     
    5051}
    5152
    52 ALWAYS_INLINE std::pair<uint8_t*, size_t> getWasmBufferFromValue(ExecState* exec, JSValue value)
     53ALWAYS_INLINE std::pair<const uint8_t*, size_t> getWasmBufferFromValue(ExecState* exec, JSValue value)
    5354{
    5455    VM& vm = exec->vm();
    5556    auto throwScope = DECLARE_THROW_SCOPE(vm);
     57
     58    if (auto* source = jsDynamicCast<JSSourceCode*>(vm, value)) {
     59        auto* provider = static_cast<WebAssemblySourceProvider*>(source->sourceCode().provider());
     60        return { provider->data().data(), provider->data().size() };
     61    }
     62
    5663    // If the given bytes argument is not a BufferSource, a TypeError exception is thrown.
    5764    JSArrayBuffer* arrayBuffer = value.getObject() ? jsDynamicCast<JSArrayBuffer*>(vm, value.getObject()) : nullptr;
     
    7784{
    7885    auto throwScope = DECLARE_THROW_SCOPE(vm);
    79     uint8_t* data;
     86    const uint8_t* data;
    8087    size_t byteSize;
    8188    std::tie(data, byteSize) = getWasmBufferFromValue(exec, value);
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp

    r230096 r230697  
    9292}
    9393
    94 void JSWebAssemblyInstance::finalizeCreation(VM& vm, ExecState* exec, Ref<Wasm::CodeBlock>&& wasmCodeBlock)
     94void JSWebAssemblyInstance::finalizeCreation(VM& vm, ExecState* exec, Ref<Wasm::CodeBlock>&& wasmCodeBlock, ModuleRunMode moduleRunMode)
    9595{
    9696    m_instance->finalizeCreation(this, wasmCodeBlock.copyRef());
     
    128128
    129129    auto* moduleRecord = jsCast<WebAssemblyModuleRecord*>(m_moduleNamespaceObject->moduleRecord());
    130     moduleRecord->link(exec, m_module.get(), this);
    131     RETURN_IF_EXCEPTION(scope, void());
    132 
    133     JSValue startResult = moduleRecord->evaluate(exec);
    134     UNUSED_PARAM(startResult);
    135     RETURN_IF_EXCEPTION(scope, void());
    136 }
    137 
    138 JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, ExecState* exec, JSWebAssemblyModule* jsModule, JSObject* importObject, Structure* instanceStructure, Ref<Wasm::Module>&& module)
     130    moduleRecord->prepareLink(vm, this);
     131
     132    if (moduleRunMode == ModuleRunMode::Run) {
     133        moduleRecord->link(exec, jsNull());
     134        RETURN_IF_EXCEPTION(scope, void());
     135
     136        JSValue startResult = moduleRecord->evaluate(exec);
     137        UNUSED_PARAM(startResult);
     138        RETURN_IF_EXCEPTION(scope, void());
     139    }
     140}
     141
     142Identifier JSWebAssemblyInstance::createPrivateModuleKey()
     143{
     144    return Identifier::fromUid(PrivateName(PrivateName::Description, "WebAssemblyInstance"));
     145}
     146
     147JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, ExecState* exec, const Identifier& moduleKey, JSWebAssemblyModule* jsModule, JSObject* importObject, Structure* instanceStructure, Ref<Wasm::Module>&& module)
    139148{
    140149    auto throwScope = DECLARE_THROW_SCOPE(vm);
     
    159168        return exception(createTypeError(exec, ASCIILiteral("can't make WebAssembly.Instance because there is no imports Object and the WebAssembly.Module requires imports")));
    160169
    161     Identifier moduleKey = Identifier::fromUid(PrivateName(PrivateName::Description, "WebAssemblyInstance"));
    162170    WebAssemblyModuleRecord* moduleRecord = WebAssemblyModuleRecord::create(exec, vm, globalObject->webAssemblyModuleRecordStructure(), moduleKey, moduleInformation);
    163171    RETURN_IF_EXCEPTION(throwScope, nullptr);
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h

    r229413 r230697  
    5151    typedef JSDestructibleObject Base;
    5252
    53     static JSWebAssemblyInstance* create(VM&, ExecState*, JSWebAssemblyModule*, JSObject* importObject, Structure*, Ref<Wasm::Module>&&);
     53    static Identifier createPrivateModuleKey();
     54
     55    static JSWebAssemblyInstance* create(VM&, ExecState*, const Identifier& moduleKey, JSWebAssemblyModule*, JSObject* importObject, Structure*, Ref<Wasm::Module>&&);
    5456    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    5557
    5658    DECLARE_EXPORT_INFO;
    5759
    58     void finalizeCreation(VM&, ExecState*, Ref<Wasm::CodeBlock>&&);
     60    enum class ModuleRunMode { Run, None };
     61    void finalizeCreation(VM&, ExecState*, Ref<Wasm::CodeBlock>&&, ModuleRunMode);
    5962   
    6063    Wasm::Instance& instance() { return m_instance.get(); }
     
    7780    }
    7881
     82    JSWebAssemblyModule* module() const { return m_module.get(); }
     83
    7984    static size_t offsetOfPoisonedInstance() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_instance); }
    8085    static size_t offsetOfPoisonedCallee() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_callee); }
     
    9095
    9196private:
    92     JSWebAssemblyModule* module() const { return m_module.get(); }
    93 
    9497    PoisonedRef<JSWebAssemblyInstancePoison, Wasm::Instance> m_instance;
    9598
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp

    r224810 r230697  
    7878    RETURN_IF_EXCEPTION(scope, { });
    7979
    80     JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, exec, module, importObject, instanceStructure, Ref<Wasm::Module>(module->module()));
     80    JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, exec, JSWebAssemblyInstance::createPrivateModuleKey(), module, importObject, instanceStructure, Ref<Wasm::Module>(module->module()));
    8181    RETURN_IF_EXCEPTION(scope, { });
    8282
    83     instance->finalizeCreation(vm, exec, module->module().compileSync(&vm.wasmContext, instance->memoryMode(), &Wasm::createJSToWasmWrapper, &Wasm::wasmToJSException));
     83    instance->finalizeCreation(vm, exec, module->module().compileSync(&vm.wasmContext, instance->memoryMode(), &Wasm::createJSToWasmWrapper, &Wasm::wasmToJSException), JSWebAssemblyInstance::ModuleRunMode::Run);
    8484    RETURN_IF_EXCEPTION(scope, { });
    8585    return JSValue::encode(instance);
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp

    r230096 r230697  
    8787}
    8888
    89 void WebAssemblyModuleRecord::link(ExecState* exec, JSWebAssemblyModule* module, JSWebAssemblyInstance* instance)
     89void WebAssemblyModuleRecord::prepareLink(VM& vm, JSWebAssemblyInstance* instance)
     90{
     91    RELEASE_ASSERT(!m_instance);
     92    m_instance.set(vm, this, instance);
     93}
     94
     95void WebAssemblyModuleRecord::link(ExecState* exec, JSValue)
    9096{
    9197    VM& vm = exec->vm();
     
    94100    auto* globalObject = exec->lexicalGlobalObject();
    95101
    96     Wasm::CodeBlock* codeBlock = instance->instance().codeBlock();
     102    RELEASE_ASSERT(m_instance);
     103
     104    Wasm::CodeBlock* codeBlock = m_instance->instance().codeBlock();
     105    JSWebAssemblyModule* module = m_instance->module();
    97106    const Wasm::ModuleInformation& moduleInformation = module->moduleInformation();
    98107
     
    111120            if (exp.kindIndex < functionImportCount) {
    112121                unsigned functionIndex = exp.kindIndex;
    113                 JSObject* functionImport = instance->instance().importFunction<JSWebAssemblyInstance::PoisonedBarrier<JSObject>>(functionIndex)->get();
     122                JSObject* functionImport = m_instance->instance().importFunction<JSWebAssemblyInstance::PoisonedBarrier<JSObject>>(functionIndex)->get();
    114123                if (isWebAssemblyHostFunction(vm, functionImport))
    115124                    exportedValue = functionImport;
    116125                else {
    117126                    Wasm::SignatureIndex signatureIndex = module->signatureIndexFromFunctionIndexSpace(functionIndex);
    118                     exportedValue = WebAssemblyWrapperFunction::create(vm, globalObject, functionImport, functionIndex, instance, signatureIndex);
     127                    exportedValue = WebAssemblyWrapperFunction::create(vm, globalObject, functionImport, functionIndex, m_instance.get(), signatureIndex);
    119128                }
    120129            } else {
     
    127136                Wasm::SignatureIndex signatureIndex = module->signatureIndexFromFunctionIndexSpace(exp.kindIndex);
    128137                const Wasm::Signature& signature = Wasm::SignatureInformation::get(signatureIndex);
    129                 WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature.argumentCount(), String::fromUTF8(exp.field), instance, embedderEntrypointCallee, entrypointLoadLocation, signatureIndex);
     138                WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature.argumentCount(), String::fromUTF8(exp.field), m_instance.get(), embedderEntrypointCallee, entrypointLoadLocation, signatureIndex);
    130139                exportedValue = function;
    131140            }
     
    134143        case Wasm::ExternalKind::Table: {
    135144            // This should be guaranteed by module verification.
    136             RELEASE_ASSERT(instance->table());
     145            RELEASE_ASSERT(m_instance->table());
    137146            ASSERT(exp.kindIndex == 0);
    138147
    139             exportedValue = instance->table();
     148            exportedValue = m_instance->table();
    140149            break;
    141150        }
     
    143152            ASSERT(exp.kindIndex == 0);
    144153
    145             exportedValue = instance->memory();
     154            exportedValue = m_instance->memory();
    146155            break;
    147156        }
     
    153162            switch (global.type) {
    154163            case Wasm::I32:
    155                 exportedValue = JSValue(instance->instance().loadI32Global(exp.kindIndex));
     164                exportedValue = JSValue(m_instance->instance().loadI32Global(exp.kindIndex));
    156165                break;
    157166
     
    161170
    162171            case Wasm::F32:
    163                 exportedValue = JSValue(instance->instance().loadF32Global(exp.kindIndex));
     172                exportedValue = JSValue(m_instance->instance().loadF32Global(exp.kindIndex));
    164173                break;
    165174
    166175            case Wasm::F64:
    167                 exportedValue = JSValue(instance->instance().loadF64Global(exp.kindIndex));
     176                exportedValue = JSValue(m_instance->instance().loadF64Global(exp.kindIndex));
    168177                break;
    169178
     
    192201        ASSERT(signature.returnType() == Wasm::Void);
    193202        if (startFunctionIndexSpace < codeBlock->functionImportCount()) {
    194             JSObject* startFunction = instance->instance().importFunction<JSWebAssemblyInstance::PoisonedBarrier<JSObject>>(startFunctionIndexSpace)->get();
     203            JSObject* startFunction = m_instance->instance().importFunction<JSWebAssemblyInstance::PoisonedBarrier<JSObject>>(startFunctionIndexSpace)->get();
    195204            m_startFunction.set(vm, this, startFunction);
    196205        } else {
    197206            Wasm::Callee& embedderEntrypointCallee = codeBlock->embedderEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace);
    198207            Wasm::WasmToWasmImportableFunction::LoadLocation entrypointLoadLocation = codeBlock->entrypointLoadLocationFromFunctionIndexSpace(startFunctionIndexSpace);
    199             WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature.argumentCount(), "start", instance, embedderEntrypointCallee, entrypointLoadLocation, signatureIndex);
     208            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature.argumentCount(), "start", m_instance.get(), embedderEntrypointCallee, entrypointLoadLocation, signatureIndex);
    200209            m_startFunction.set(vm, this, function);
    201210        }
    202211    }
    203 
    204     RELEASE_ASSERT(!m_instance);
    205     m_instance.set(vm, this, instance);
    206212    m_moduleEnvironment.set(vm, this, moduleEnvironment);
    207213}
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.h

    r229413 r230697  
    4949    static WebAssemblyModuleRecord* create(ExecState*, VM&, Structure*, const Identifier&, const Wasm::ModuleInformation&);
    5050
    51     void link(ExecState*, JSWebAssemblyModule*, JSWebAssemblyInstance*);
     51    void prepareLink(VM&, JSWebAssemblyInstance*);
     52    void link(ExecState*, JSValue scriptFetcher);
    5253    JS_EXPORT_PRIVATE JSValue evaluate(ExecState*);
    5354
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp

    r230119 r230697  
    3333#include "FunctionPrototype.h"
    3434#include "JSCInlines.h"
     35#include "JSModuleNamespaceObject.h"
    3536#include "JSPromiseDeferred.h"
    3637#include "JSToWasm.h"
     
    121122}
    122123
    123 enum class Resolve { WithInstance, WithModuleAndInstance };
    124 static void resolve(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyInstance* instance, JSWebAssemblyModule* module, Ref<Wasm::CodeBlock>&& codeBlock, Resolve resolveKind)
     124enum class Resolve { WithInstance, WithModuleRecord, WithModuleAndInstance };
     125static void resolve(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyInstance* instance, JSWebAssemblyModule* module, Ref<Wasm::CodeBlock>&& codeBlock, Resolve resolveKind, JSWebAssemblyInstance::ModuleRunMode moduleRunMode)
    125126{
    126127    auto scope = DECLARE_CATCH_SCOPE(vm);
    127     instance->finalizeCreation(vm, exec, WTFMove(codeBlock));
     128    instance->finalizeCreation(vm, exec, WTFMove(codeBlock), moduleRunMode);
    128129    RETURN_IF_EXCEPTION(scope, reject(exec, scope, promise));
    129130
    130131    if (resolveKind == Resolve::WithInstance)
    131132        promise->resolve(exec, instance);
    132     else {
     133    else if (resolveKind == Resolve::WithModuleRecord) {
     134        auto* moduleRecord = instance->moduleNamespaceObject()->moduleRecord();
     135        if (Options::dumpModuleRecord())
     136            moduleRecord->dump();
     137        promise->resolve(exec, moduleRecord);
     138    } else {
    133139        JSObject* result = constructEmptyObject(exec);
    134140        result->putDirect(vm, Identifier::fromString(&vm, ASCIILiteral("module")), module);
     
    139145}
    140146
    141 static void instantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyModule* module, JSObject* importObject, Resolve resolveKind)
     147static void instantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyModule* module, JSObject* importObject, const Identifier& moduleKey, Resolve resolveKind, JSWebAssemblyInstance::ModuleRunMode moduleRunMode)
    142148{
    143149    auto scope = DECLARE_CATCH_SCOPE(vm);
    144150    // In order to avoid potentially recompiling a module. We first gather all the import/memory information prior to compiling code.
    145     JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, exec, module, importObject, exec->lexicalGlobalObject()->WebAssemblyInstanceStructure(), Ref<Wasm::Module>(module->module()));
     151    JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, exec, moduleKey, module, importObject, exec->lexicalGlobalObject()->WebAssemblyInstanceStructure(), Ref<Wasm::Module>(module->module()));
    146152    RETURN_IF_EXCEPTION(scope, reject(exec, scope, promise));
    147153
     
    151157    vm.promiseDeferredTimer->addPendingPromise(promise, WTFMove(dependencies));
    152158    // Note: This completion task may or may not get called immediately.
    153     module->module().compileAsync(&vm.wasmContext, instance->memoryMode(), createSharedTask<Wasm::CodeBlock::CallbackType>([promise, instance, module, resolveKind, &vm] (Ref<Wasm::CodeBlock>&& refCodeBlock) mutable {
     159    module->module().compileAsync(&vm.wasmContext, instance->memoryMode(), createSharedTask<Wasm::CodeBlock::CallbackType>([promise, instance, module, resolveKind, moduleRunMode, &vm] (Ref<Wasm::CodeBlock>&& refCodeBlock) mutable {
    154160        RefPtr<Wasm::CodeBlock> codeBlock = WTFMove(refCodeBlock);
    155         vm.promiseDeferredTimer->scheduleWorkSoon(promise, [promise, instance, module, resolveKind, &vm, codeBlock = WTFMove(codeBlock)] () mutable {
     161        vm.promiseDeferredTimer->scheduleWorkSoon(promise, [promise, instance, module, resolveKind, moduleRunMode, &vm, codeBlock = WTFMove(codeBlock)] () mutable {
    156162            ExecState* exec = instance->globalObject()->globalExec();
    157             resolve(vm, exec, promise, instance, module, codeBlock.releaseNonNull(), resolveKind);
     163            resolve(vm, exec, promise, instance, module, codeBlock.releaseNonNull(), resolveKind, moduleRunMode);
    158164        });
    159165    }), &Wasm::createJSToWasmWrapper, &Wasm::wasmToJSException);
    160166}
    161167
    162 static void compileAndInstantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSValue buffer, JSObject* importObject)
     168static void compileAndInstantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, const Identifier& moduleKey, JSValue buffer, JSObject* importObject, Resolve resolveKind, JSWebAssemblyInstance::ModuleRunMode moduleRunMode)
    163169{
    164170    auto scope = DECLARE_CATCH_SCOPE(vm);
     
    166172    auto* globalObject = exec->lexicalGlobalObject();
    167173
     174    JSCell* moduleKeyCell = identifierToJSValue(vm, moduleKey).asCell();
    168175    Vector<Strong<JSCell>> dependencies;
    169176    dependencies.append(Strong<JSCell>(vm, importObject));
     177    dependencies.append(Strong<JSCell>(vm, moduleKeyCell));
    170178    vm.promiseDeferredTimer->addPendingPromise(promise, WTFMove(dependencies));
    171179
     
    173181    RETURN_IF_EXCEPTION(scope, reject(exec, scope, promise));
    174182
    175     Wasm::Module::validateAsync(&vm.wasmContext, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([promise, importObject, globalObject, &vm] (Wasm::Module::ValidationResult&& result) mutable {
    176         vm.promiseDeferredTimer->scheduleWorkSoon(promise, [promise, importObject, globalObject, result = WTFMove(result), &vm] () mutable {
     183    Wasm::Module::validateAsync(&vm.wasmContext, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([promise, importObject, moduleKeyCell, globalObject, resolveKind, moduleRunMode, &vm] (Wasm::Module::ValidationResult&& result) mutable {
     184        vm.promiseDeferredTimer->scheduleWorkSoon(promise, [promise, importObject, moduleKeyCell, globalObject, result = WTFMove(result), resolveKind, moduleRunMode, &vm] () mutable {
    177185            auto scope = DECLARE_CATCH_SCOPE(vm);
    178186            ExecState* exec = globalObject->globalExec();
     
    181189                return reject(exec, scope, promise);
    182190
    183             instantiate(vm, exec, promise, module, importObject, Resolve::WithModuleAndInstance);
     191            const Identifier moduleKey = JSValue(moduleKeyCell).toPropertyKey(exec);
     192            if (UNLIKELY(scope.exception()))
     193                return reject(exec, scope, promise);
     194
     195            instantiate(vm, exec, promise, module, importObject, moduleKey, resolveKind, moduleRunMode);
    184196        });
    185197    }));
     198}
     199
     200JSValue WebAssemblyPrototype::instantiate(ExecState* exec, JSPromiseDeferred* promise, const Identifier& moduleKey, JSValue argument)
     201{
     202    VM& vm = exec->vm();
     203    compileAndInstantiate(vm, exec, promise, moduleKey, argument, nullptr, Resolve::WithModuleRecord, JSWebAssemblyInstance::ModuleRunMode::None);
     204    return promise->promise();
    186205}
    187206
     
    207226            JSValue firstArgument = exec->argument(0);
    208227            if (auto* module = jsDynamicCast<JSWebAssemblyModule*>(vm, firstArgument))
    209                 instantiate(vm, exec, promise, module, importObject, Resolve::WithInstance);
     228                instantiate(vm, exec, promise, module, importObject, JSWebAssemblyInstance::createPrivateModuleKey(), Resolve::WithInstance, JSWebAssemblyInstance::ModuleRunMode::Run);
    210229            else
    211                 compileAndInstantiate(vm, exec, promise, firstArgument, importObject);
     230                compileAndInstantiate(vm, exec, promise, JSWebAssemblyInstance::createPrivateModuleKey(), firstArgument, importObject, Resolve::WithModuleAndInstance, JSWebAssemblyInstance::ModuleRunMode::Run);
    212231        }
    213232
     
    221240    auto scope = DECLARE_THROW_SCOPE(vm);
    222241
    223     uint8_t* base;
     242    const uint8_t* base;
    224243    size_t byteSize;
    225244    std::tie(base, byteSize) = getWasmBufferFromValue(exec, exec->argument(0));
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.h

    r229413 r230697  
    4343    DECLARE_INFO;
    4444
     45    static JSValue instantiate(ExecState*, JSPromiseDeferred*, const Identifier&, JSValue);
     46
    4547protected:
    4648    void finishCreation(VM&);
Note: See TracChangeset for help on using the changeset viewer.