Changeset 230697 in webkit
- Timestamp:
- Apr 16, 2018 7:38:59 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 20 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r230662 r230697 1 2018-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 1 41 2018-04-14 Filip Pizlo <fpizlo@apple.com> 2 42 -
trunk/JSTests/wasm.yaml
r220894 r230697 37 37 cmd: runWebAssemblyLowExecutableMemory unless parseRunCommands 38 38 - path: wasm/regress/ 39 cmd: runWebAssembly unless parseRunCommands 40 - path: wasm/modules/ 39 41 cmd: runWebAssembly unless parseRunCommands 40 42 -
trunk/Source/JavaScriptCore/ChangeLog
r230662 r230697 1 2018-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 1 75 2018-04-14 Filip Pizlo <fpizlo@apple.com> 2 76 -
trunk/Source/JavaScriptCore/builtins/ModuleLoaderPrototype.js
r230459 r230697 96 96 satisfy: @undefined, 97 97 dependencies: [], // To keep the module order, we store the module keys in the array. 98 dependenciesMap: @undefined,99 98 module: @undefined, // JSModuleRecord 100 99 linkError: @undefined, … … 198 197 199 198 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 }); 216 215 }); 217 216 return instantiatePromise; … … 289 288 this.link(dependencies[i], fetcher); 290 289 291 this.moduleDeclarationInstantiation(entry.module, entry.key,fetcher);290 this.moduleDeclarationInstantiation(entry.module, fetcher); 292 291 } catch (error) { 293 292 entry.linkSucceeded = false; -
trunk/Source/JavaScriptCore/jsc.cpp
r229605 r230697 187 187 } 188 188 189 static bool fillBufferWithContentsOfFile(const String& fileName, Vector<char>& buffer); 189 template<typename Vector> 190 static bool fillBufferWithContentsOfFile(const String& fileName, Vector& buffer); 190 191 static RefPtr<Uint8Array> fillBufferWithContentsOfFile(const String& fileName); 191 192 … … 845 846 } 846 847 847 static void convertShebangToJSComment(Vector<char>& buffer) 848 template<typename Vector> 849 static void convertShebangToJSComment(Vector& buffer) 848 850 { 849 851 if (buffer.size() >= 2) { … … 883 885 } 884 886 885 static bool fillBufferWithContentsOfFile(FILE* file, Vector<char>& buffer) 887 template<typename Vector> 888 static bool fillBufferWithContentsOfFile(FILE* file, Vector& buffer) 886 889 { 887 890 // We might have injected "use strict"; at the top. … … 921 924 } 922 925 923 static bool fetchModuleFromLocalFileSystem(const String& fileName, Vector<char>& buffer) 926 template<typename Vector> 927 static bool fetchModuleFromLocalFileSystem(const String& fileName, Vector& buffer) 924 928 { 925 929 // We assume that fileName is always an absolute path. … … 972 976 973 977 // 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)) { 976 980 auto result = deferred->reject(exec, createError(exec, makeString("Could not open file '", moduleKey, "'."))); 977 981 scope.releaseAssertNoException(); … … 979 983 } 980 984 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))); 982 997 scope.releaseAssertNoException(); 983 998 return result; -
trunk/Source/JavaScriptCore/parser/SourceProvider.h
r210149 r230697 121 121 class WebAssemblySourceProvider : public SourceProvider { 122 122 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) 124 124 { 125 return adoptRef(*new WebAssemblySourceProvider( data, sourceOrigin, url));125 return adoptRef(*new WebAssemblySourceProvider(WTFMove(data), sourceOrigin, url)); 126 126 } 127 127 … … 142 142 143 143 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) 145 145 : SourceProvider(sourceOrigin, url, TextPosition(), SourceProviderSourceType::WebAssembly) 146 146 , m_source("[WebAssembly source]") 147 , m_data( data)147 , m_data(WTFMove(data)) 148 148 { 149 149 } -
trunk/Source/JavaScriptCore/runtime/AbstractModuleRecord.cpp
r223894 r230697 33 33 #include "JSModuleEnvironment.h" 34 34 #include "JSModuleNamespaceObject.h" 35 #include "JSModuleRecord.h" 35 36 #include "UnlinkedModuleProgramCodeBlock.h" 37 #include "WebAssemblyModuleRecord.h" 36 38 37 39 namespace JSC { … … 138 140 } 139 141 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 148 142 AbstractModuleRecord* AbstractModuleRecord::hostResolveImportedModule(ExecState* exec, const Identifier& moduleName) 149 143 { 150 144 VM& vm = exec->vm(); 151 145 auto scope = DECLARE_THROW_SCOPE(vm); 152 JSValue moduleNameValue = identifierToJSValue( exec, moduleName);146 JSValue moduleNameValue = identifierToJSValue(vm, moduleName); 153 147 JSValue entry = m_dependenciesMap->JSMap::get(exec, moduleNameValue); 154 148 RETURN_IF_EXCEPTION(scope, nullptr); … … 776 770 } 777 771 772 void 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 784 JS_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 778 797 static String printableName(const RefPtr<UniquedStringImpl>& uid) 779 798 { -
trunk/Source/JavaScriptCore/runtime/AbstractModuleRecord.h
r218794 r230697 120 120 } 121 121 122 void link(ExecState*, JSValue scriptFetcher); 123 JS_EXPORT_PRIVATE JSValue evaluate(ExecState*); 124 122 125 protected: 123 126 AbstractModuleRecord(VM&, Structure*, const Identifier&); -
trunk/Source/JavaScriptCore/runtime/JSModuleLoader.cpp
r224309 r230697 276 276 return globalObject->globalObjectMethodTable()->moduleLoaderEvaluate(globalObject, exec, this, key, moduleRecordValue, scriptFetcher); 277 277 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(); 282 281 } 283 282 -
trunk/Source/JavaScriptCore/runtime/JSModuleRecord.cpp
r225799 r230697 79 79 } 80 80 81 void JSModuleRecord::link(ExecState* exec, JSValue key, JSValuescriptFetcher)81 void JSModuleRecord::link(ExecState* exec, JSValue scriptFetcher) 82 82 { 83 83 VM& vm = exec->vm(); … … 90 90 return; 91 91 } 92 instantiateDeclarations(exec, executable, key,scriptFetcher);92 instantiateDeclarations(exec, executable, scriptFetcher); 93 93 RETURN_IF_EXCEPTION(scope, void()); 94 94 m_moduleProgramExecutable.set(vm, this, executable); 95 95 } 96 96 97 void JSModuleRecord::instantiateDeclarations(ExecState* exec, ModuleProgramExecutable* moduleProgramExecutable, JSValue key, JSValuescriptFetcher)97 void JSModuleRecord::instantiateDeclarations(ExecState* exec, ModuleProgramExecutable* moduleProgramExecutable, JSValue scriptFetcher) 98 98 { 99 99 VM& vm = exec->vm(); … … 209 209 210 210 { 211 JSObject* metaProperties = exec->lexicalGlobalObject()->moduleLoader()->createImportMetaProperties(exec, key, this, scriptFetcher);211 JSObject* metaProperties = exec->lexicalGlobalObject()->moduleLoader()->createImportMetaProperties(exec, identifierToJSValue(vm, moduleKey()), this, scriptFetcher); 212 212 RETURN_IF_EXCEPTION(scope, void()); 213 213 bool putResult = false; -
trunk/Source/JavaScriptCore/runtime/JSModuleRecord.h
r229413 r230697 46 46 static JSModuleRecord* create(ExecState*, VM&, Structure*, const Identifier&, const SourceCode&, const VariableEnvironment&, const VariableEnvironment&); 47 47 48 void link(ExecState*, JSValue key, JSValuescriptFetcher);48 void link(ExecState*, JSValue scriptFetcher); 49 49 JS_EXPORT_PRIVATE JSValue evaluate(ExecState*); 50 50 … … 61 61 static void destroy(JSCell*); 62 62 63 void instantiateDeclarations(ExecState*, ModuleProgramExecutable*, JSValue key, JSValuescriptFetcher);63 void instantiateDeclarations(ExecState*, ModuleProgramExecutable*, JSValue scriptFetcher); 64 64 65 65 SourceCode m_sourceCode; -
trunk/Source/JavaScriptCore/runtime/ModuleLoaderPrototype.cpp
r223777 r230697 46 46 #include "Parser.h" 47 47 #include "ParserError.h" 48 #include "WebAssemblyPrototype.h" 48 49 49 50 namespace JSC { … … 77 78 requestSatisfy JSBuiltin DontEnum|Function 3 78 79 link JSBuiltin DontEnum|Function 2 79 moduleDeclarationInstantiation moduleLoaderPrototypeModuleDeclarationInstantiation DontEnum|Function 380 moduleDeclarationInstantiation moduleLoaderPrototypeModuleDeclarationInstantiation DontEnum|Function 2 80 81 moduleEvaluation JSBuiltin DontEnum|Function 2 81 82 evaluate moduleLoaderPrototypeEvaluate DontEnum|Function 3 … … 104 105 { 105 106 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 }; 107 117 108 118 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); 114 124 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 115 130 116 131 CodeProfiling profile(sourceCode); … … 120 135 &vm, sourceCode, Identifier(), JSParserBuiltinMode::NotBuiltin, 121 136 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))); 127 139 ASSERT(moduleProgramNode); 128 140 129 141 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))); 134 146 } 135 147 … … 138 150 VM& vm = exec->vm(); 139 151 auto scope = DECLARE_THROW_SCOPE(vm); 140 JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(vm, exec->argument(0));152 auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(vm, exec->argument(0)); 141 153 if (!moduleRecord) { 142 154 scope.release(); … … 158 170 VM& vm = exec->vm(); 159 171 auto scope = DECLARE_THROW_SCOPE(vm); 160 JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(vm, exec->argument(0));172 auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(vm, exec->argument(0)); 161 173 if (!moduleRecord) 162 174 return JSValue::encode(jsUndefined()); … … 165 177 dataLog("Loader [link] ", moduleRecord->moduleKey(), "\n"); 166 178 167 moduleRecord->link(exec, exec->argument(1) , exec->argument(2));179 moduleRecord->link(exec, exec->argument(1)); 168 180 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 169 181 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h
r230119 r230697 30 30 #include "JSArrayBuffer.h" 31 31 #include "JSCJSValue.h" 32 #include "JSSourceCode.h" 32 33 #include "WebAssemblyFunction.h" 33 34 #include "WebAssemblyWrapperFunction.h" … … 50 51 } 51 52 52 ALWAYS_INLINE std::pair< uint8_t*, size_t> getWasmBufferFromValue(ExecState* exec, JSValue value)53 ALWAYS_INLINE std::pair<const uint8_t*, size_t> getWasmBufferFromValue(ExecState* exec, JSValue value) 53 54 { 54 55 VM& vm = exec->vm(); 55 56 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 56 63 // If the given bytes argument is not a BufferSource, a TypeError exception is thrown. 57 64 JSArrayBuffer* arrayBuffer = value.getObject() ? jsDynamicCast<JSArrayBuffer*>(vm, value.getObject()) : nullptr; … … 77 84 { 78 85 auto throwScope = DECLARE_THROW_SCOPE(vm); 79 uint8_t* data;86 const uint8_t* data; 80 87 size_t byteSize; 81 88 std::tie(data, byteSize) = getWasmBufferFromValue(exec, value); -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
r230096 r230697 92 92 } 93 93 94 void JSWebAssemblyInstance::finalizeCreation(VM& vm, ExecState* exec, Ref<Wasm::CodeBlock>&& wasmCodeBlock )94 void JSWebAssemblyInstance::finalizeCreation(VM& vm, ExecState* exec, Ref<Wasm::CodeBlock>&& wasmCodeBlock, ModuleRunMode moduleRunMode) 95 95 { 96 96 m_instance->finalizeCreation(this, wasmCodeBlock.copyRef()); … … 128 128 129 129 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 142 Identifier JSWebAssemblyInstance::createPrivateModuleKey() 143 { 144 return Identifier::fromUid(PrivateName(PrivateName::Description, "WebAssemblyInstance")); 145 } 146 147 JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, ExecState* exec, const Identifier& moduleKey, JSWebAssemblyModule* jsModule, JSObject* importObject, Structure* instanceStructure, Ref<Wasm::Module>&& module) 139 148 { 140 149 auto throwScope = DECLARE_THROW_SCOPE(vm); … … 159 168 return exception(createTypeError(exec, ASCIILiteral("can't make WebAssembly.Instance because there is no imports Object and the WebAssembly.Module requires imports"))); 160 169 161 Identifier moduleKey = Identifier::fromUid(PrivateName(PrivateName::Description, "WebAssemblyInstance"));162 170 WebAssemblyModuleRecord* moduleRecord = WebAssemblyModuleRecord::create(exec, vm, globalObject->webAssemblyModuleRecordStructure(), moduleKey, moduleInformation); 163 171 RETURN_IF_EXCEPTION(throwScope, nullptr); -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h
r229413 r230697 51 51 typedef JSDestructibleObject Base; 52 52 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>&&); 54 56 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 55 57 56 58 DECLARE_EXPORT_INFO; 57 59 58 void finalizeCreation(VM&, ExecState*, Ref<Wasm::CodeBlock>&&); 60 enum class ModuleRunMode { Run, None }; 61 void finalizeCreation(VM&, ExecState*, Ref<Wasm::CodeBlock>&&, ModuleRunMode); 59 62 60 63 Wasm::Instance& instance() { return m_instance.get(); } … … 77 80 } 78 81 82 JSWebAssemblyModule* module() const { return m_module.get(); } 83 79 84 static size_t offsetOfPoisonedInstance() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_instance); } 80 85 static size_t offsetOfPoisonedCallee() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_callee); } … … 90 95 91 96 private: 92 JSWebAssemblyModule* module() const { return m_module.get(); }93 94 97 PoisonedRef<JSWebAssemblyInstancePoison, Wasm::Instance> m_instance; 95 98 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp
r224810 r230697 78 78 RETURN_IF_EXCEPTION(scope, { }); 79 79 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())); 81 81 RETURN_IF_EXCEPTION(scope, { }); 82 82 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); 84 84 RETURN_IF_EXCEPTION(scope, { }); 85 85 return JSValue::encode(instance); -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
r230096 r230697 87 87 } 88 88 89 void WebAssemblyModuleRecord::link(ExecState* exec, JSWebAssemblyModule* module, JSWebAssemblyInstance* instance) 89 void WebAssemblyModuleRecord::prepareLink(VM& vm, JSWebAssemblyInstance* instance) 90 { 91 RELEASE_ASSERT(!m_instance); 92 m_instance.set(vm, this, instance); 93 } 94 95 void WebAssemblyModuleRecord::link(ExecState* exec, JSValue) 90 96 { 91 97 VM& vm = exec->vm(); … … 94 100 auto* globalObject = exec->lexicalGlobalObject(); 95 101 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(); 97 106 const Wasm::ModuleInformation& moduleInformation = module->moduleInformation(); 98 107 … … 111 120 if (exp.kindIndex < functionImportCount) { 112 121 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(); 114 123 if (isWebAssemblyHostFunction(vm, functionImport)) 115 124 exportedValue = functionImport; 116 125 else { 117 126 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); 119 128 } 120 129 } else { … … 127 136 Wasm::SignatureIndex signatureIndex = module->signatureIndexFromFunctionIndexSpace(exp.kindIndex); 128 137 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); 130 139 exportedValue = function; 131 140 } … … 134 143 case Wasm::ExternalKind::Table: { 135 144 // This should be guaranteed by module verification. 136 RELEASE_ASSERT( instance->table());145 RELEASE_ASSERT(m_instance->table()); 137 146 ASSERT(exp.kindIndex == 0); 138 147 139 exportedValue = instance->table();148 exportedValue = m_instance->table(); 140 149 break; 141 150 } … … 143 152 ASSERT(exp.kindIndex == 0); 144 153 145 exportedValue = instance->memory();154 exportedValue = m_instance->memory(); 146 155 break; 147 156 } … … 153 162 switch (global.type) { 154 163 case Wasm::I32: 155 exportedValue = JSValue( instance->instance().loadI32Global(exp.kindIndex));164 exportedValue = JSValue(m_instance->instance().loadI32Global(exp.kindIndex)); 156 165 break; 157 166 … … 161 170 162 171 case Wasm::F32: 163 exportedValue = JSValue( instance->instance().loadF32Global(exp.kindIndex));172 exportedValue = JSValue(m_instance->instance().loadF32Global(exp.kindIndex)); 164 173 break; 165 174 166 175 case Wasm::F64: 167 exportedValue = JSValue( instance->instance().loadF64Global(exp.kindIndex));176 exportedValue = JSValue(m_instance->instance().loadF64Global(exp.kindIndex)); 168 177 break; 169 178 … … 192 201 ASSERT(signature.returnType() == Wasm::Void); 193 202 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(); 195 204 m_startFunction.set(vm, this, startFunction); 196 205 } else { 197 206 Wasm::Callee& embedderEntrypointCallee = codeBlock->embedderEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace); 198 207 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); 200 209 m_startFunction.set(vm, this, function); 201 210 } 202 211 } 203 204 RELEASE_ASSERT(!m_instance);205 m_instance.set(vm, this, instance);206 212 m_moduleEnvironment.set(vm, this, moduleEnvironment); 207 213 } -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.h
r229413 r230697 49 49 static WebAssemblyModuleRecord* create(ExecState*, VM&, Structure*, const Identifier&, const Wasm::ModuleInformation&); 50 50 51 void link(ExecState*, JSWebAssemblyModule*, JSWebAssemblyInstance*); 51 void prepareLink(VM&, JSWebAssemblyInstance*); 52 void link(ExecState*, JSValue scriptFetcher); 52 53 JS_EXPORT_PRIVATE JSValue evaluate(ExecState*); 53 54 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp
r230119 r230697 33 33 #include "FunctionPrototype.h" 34 34 #include "JSCInlines.h" 35 #include "JSModuleNamespaceObject.h" 35 36 #include "JSPromiseDeferred.h" 36 37 #include "JSToWasm.h" … … 121 122 } 122 123 123 enum class Resolve { WithInstance, WithModule AndInstance };124 static void resolve(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyInstance* instance, JSWebAssemblyModule* module, Ref<Wasm::CodeBlock>&& codeBlock, Resolve resolveKind )124 enum class Resolve { WithInstance, WithModuleRecord, WithModuleAndInstance }; 125 static void resolve(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyInstance* instance, JSWebAssemblyModule* module, Ref<Wasm::CodeBlock>&& codeBlock, Resolve resolveKind, JSWebAssemblyInstance::ModuleRunMode moduleRunMode) 125 126 { 126 127 auto scope = DECLARE_CATCH_SCOPE(vm); 127 instance->finalizeCreation(vm, exec, WTFMove(codeBlock) );128 instance->finalizeCreation(vm, exec, WTFMove(codeBlock), moduleRunMode); 128 129 RETURN_IF_EXCEPTION(scope, reject(exec, scope, promise)); 129 130 130 131 if (resolveKind == Resolve::WithInstance) 131 132 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 { 133 139 JSObject* result = constructEmptyObject(exec); 134 140 result->putDirect(vm, Identifier::fromString(&vm, ASCIILiteral("module")), module); … … 139 145 } 140 146 141 static void instantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyModule* module, JSObject* importObject, Resolve resolveKind)147 static void instantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyModule* module, JSObject* importObject, const Identifier& moduleKey, Resolve resolveKind, JSWebAssemblyInstance::ModuleRunMode moduleRunMode) 142 148 { 143 149 auto scope = DECLARE_CATCH_SCOPE(vm); 144 150 // 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())); 146 152 RETURN_IF_EXCEPTION(scope, reject(exec, scope, promise)); 147 153 … … 151 157 vm.promiseDeferredTimer->addPendingPromise(promise, WTFMove(dependencies)); 152 158 // 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 { 154 160 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 { 156 162 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); 158 164 }); 159 165 }), &Wasm::createJSToWasmWrapper, &Wasm::wasmToJSException); 160 166 } 161 167 162 static void compileAndInstantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSValue buffer, JSObject* importObject)168 static void compileAndInstantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, const Identifier& moduleKey, JSValue buffer, JSObject* importObject, Resolve resolveKind, JSWebAssemblyInstance::ModuleRunMode moduleRunMode) 163 169 { 164 170 auto scope = DECLARE_CATCH_SCOPE(vm); … … 166 172 auto* globalObject = exec->lexicalGlobalObject(); 167 173 174 JSCell* moduleKeyCell = identifierToJSValue(vm, moduleKey).asCell(); 168 175 Vector<Strong<JSCell>> dependencies; 169 176 dependencies.append(Strong<JSCell>(vm, importObject)); 177 dependencies.append(Strong<JSCell>(vm, moduleKeyCell)); 170 178 vm.promiseDeferredTimer->addPendingPromise(promise, WTFMove(dependencies)); 171 179 … … 173 181 RETURN_IF_EXCEPTION(scope, reject(exec, scope, promise)); 174 182 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 { 177 185 auto scope = DECLARE_CATCH_SCOPE(vm); 178 186 ExecState* exec = globalObject->globalExec(); … … 181 189 return reject(exec, scope, promise); 182 190 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); 184 196 }); 185 197 })); 198 } 199 200 JSValue 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(); 186 205 } 187 206 … … 207 226 JSValue firstArgument = exec->argument(0); 208 227 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); 210 229 else 211 compileAndInstantiate(vm, exec, promise, firstArgument, importObject);230 compileAndInstantiate(vm, exec, promise, JSWebAssemblyInstance::createPrivateModuleKey(), firstArgument, importObject, Resolve::WithModuleAndInstance, JSWebAssemblyInstance::ModuleRunMode::Run); 212 231 } 213 232 … … 221 240 auto scope = DECLARE_THROW_SCOPE(vm); 222 241 223 uint8_t* base;242 const uint8_t* base; 224 243 size_t byteSize; 225 244 std::tie(base, byteSize) = getWasmBufferFromValue(exec, exec->argument(0)); -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.h
r229413 r230697 43 43 DECLARE_INFO; 44 44 45 static JSValue instantiate(ExecState*, JSPromiseDeferred*, const Identifier&, JSValue); 46 45 47 protected: 46 48 void finishCreation(VM&);
Note: See TracChangeset
for help on using the changeset viewer.