Changeset 207929 in webkit
- Timestamp:
- Oct 26, 2016 7:18:51 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r207906 r207929 1 2016-10-26 JF Bastien <jfbastien@apple.com> 2 3 WebAssembly API: implement Instance 4 5 As described in: https://github.com/WebAssembly/design/blob/master/JS.md#webassemblyinstance-objects 6 7 - Take ownership of Wasm::Plan's compilation result when successfully creating a JSWebAssemblyModule object. 8 - Construct a basic Instance with a Module. 9 - Handle second argument (importObject) of WebAssembly.Instance. 10 - Add reference text from the spec to WebAssembly.Module's code. 11 - Expose and test an empty 'exports' ModuleNamespaceObject on WebAssembly.Instance. 12 13 The implementation isn't complete yet: it relies on further work for which I've filed bugs. 14 15 WebAssembly API: implement Instance 16 https://bugs.webkit.org/show_bug.cgi?id=163998 17 18 Reviewed by Keith Miller. 19 20 * wasm/js-api/test_Instance.js: Added. 21 (EmptyModule): use the Builder, create the simplest Module possible, and create an Instance from it 22 * wasm/js-api/test_basic_api.js: 23 (const.c.in.constructorProperties.switch): basic tests of the API 24 1 25 2016-10-26 Mark Lam <mark.lam@apple.com> 2 26 -
trunk/JSTests/wasm/js-api/test_basic_api.js
r207825 r207929 3 3 4 4 const version = 0xC; 5 const emptyModule = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, version, 0x00, 0x00, 0x00); 5 const emptyModuleArray = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, version, 0x00, 0x00, 0x00); 6 const invalidConstructorInputs = [undefined, null, "", 1, {}, []]; 7 const invalidInstanceImports = [null, "", 1]; 6 8 7 9 const checkOwnPropertyDescriptor = (obj, prop, expect) => { … … 50 52 switch (c) { 51 53 case "Module": 52 for (const invalid of [undefined, "", 1, {}, []])54 for (const invalid of invalidConstructorInputs) 53 55 assert.throws(() => new WebAssembly[c](invalid), TypeError, `first argument to WebAssembly.Module must be an ArrayBufferView or an ArrayBuffer (evaluating 'new WebAssembly[c](invalid)')`); 54 56 for (const buffer of [new ArrayBuffer(), new DataView(new ArrayBuffer()), new Int8Array(), new Uint8Array(), new Uint8ClampedArray(), new Int16Array(), new Uint16Array(), new Int32Array(), new Uint32Array(), new Float32Array(), new Float64Array()]) 55 57 // FIXME the following should be WebAssembly.CompileError. https://bugs.webkit.org/show_bug.cgi?id=163768 56 58 assert.throws(() => new WebAssembly[c](buffer), Error, `Module is 0 bytes, expected at least 8 bytes (evaluating 'new WebAssembly[c](buffer)')`); 57 assert.instanceof(new WebAssembly[c](emptyModule ), WebAssembly.Module);59 assert.instanceof(new WebAssembly[c](emptyModuleArray), WebAssembly.Module); 58 60 // FIXME test neutered TypedArray and TypedArrayView. https://bugs.webkit.org/show_bug.cgi?id=163899 59 61 break; 60 62 case "Instance": 61 // FIXME Implement and test these APIs further. For now they just throw. https://bugs.webkit.org/show_bug.cgi?id=159775 62 assert.throws(() => new WebAssembly[c](), Error, `WebAssembly doesn't yet implement the ${c} constructor property`); 63 for (const invalid of invalidConstructorInputs) 64 assert.throws(() => new WebAssembly[c](invalid), TypeError, `first argument to WebAssembly.Instance must be a WebAssembly.Module (evaluating 'new WebAssembly[c](invalid)')`); 65 const instance = new WebAssembly[c](new WebAssembly.Module(emptyModuleArray)); 66 assert.instanceof(instance, WebAssembly.Instance); 67 for (const invalid of invalidInstanceImports) 68 assert.throws(() => new WebAssembly[c](new WebAssembly.Module(emptyModuleArray), invalid), TypeError, `second argument to WebAssembly.Instance must be undefined or an Object (evaluating 'new WebAssembly[c](new WebAssembly.Module(emptyModuleArray), invalid)')`); 69 assert.notUndef(instance.exports); 70 checkOwnPropertyDescriptor(instance, "exports", { typeofvalue: "object", writable: true, configurable: true, enumerable: true }); 71 assert.isUndef(instance.exports.__proto__); 72 assert.eq(Reflect.isExtensible(instance.exports), false); 73 assert.eq(Symbol.iterator in instance.exports, true); 74 assert.eq(Symbol.toStringTag in instance.exports, true); 63 75 break; 64 76 case "Memory": -
trunk/Source/JavaScriptCore/ChangeLog
r207928 r207929 1 2016-10-26 JF Bastien <jfbastien@apple.com> 2 3 WebAssembly API: implement Instance 4 5 As described in: https://github.com/WebAssembly/design/blob/master/JS.md#webassemblyinstance-objects 6 7 - Take ownership of Wasm::Plan's compilation result when successfully creating a JSWebAssemblyModule object. 8 - Construct a basic Instance with a Module. 9 - Handle second argument (importObject) of WebAssembly.Instance. 10 - Add reference text from the spec to WebAssembly.Module's code. 11 - Expose and test an empty 'exports' ModuleNamespaceObject on WebAssembly.Instance. 12 13 The implementation isn't complete yet: it relies on further work for which I've filed bugs. 14 15 WebAssembly API: implement Instance 16 https://bugs.webkit.org/show_bug.cgi?id=163998 17 18 Reviewed by Keith Miller. 19 20 * wasm/WasmPlan.h: 21 (JSC::Wasm::Plan::getFunctions): allow transfering state out 22 (JSC::Wasm::Plan::getMemory): allow transfering state out 23 * wasm/js/JSWebAssemblyInstance.cpp: 24 (JSC::JSWebAssemblyInstance::create): 25 (JSC::JSWebAssemblyInstance::finishCreation): set the ModuleNamespaceObject, and expose it as "exports" 26 (JSC::JSWebAssemblyInstance::visitChildren): visit the ModuleNamespaceObject child 27 * wasm/js/JSWebAssemblyInstance.h: 28 * wasm/js/JSWebAssemblyModule.cpp: 29 (JSC::JSWebAssemblyModule::create): 30 (JSC::JSWebAssemblyModule::JSWebAssemblyModule): move in the compiled functions and the memory 31 * wasm/js/JSWebAssemblyModule.h: 32 * wasm/js/WebAssemblyInstanceConstructor.cpp: 33 (JSC::constructJSWebAssemblyInstance): take the Module, extract the Plan's results, and create the (empty for now) ModuleNamespaceObject 34 * wasm/js/WebAssemblyModuleConstructor.cpp: 35 (JSC::constructJSWebAssemblyModule): add a few comments from the spec, and pass out the Plan's results 36 1 37 2016-10-26 Brian Burg <bburg@apple.com> 2 38 -
trunk/Source/JavaScriptCore/wasm/WasmPlan.h
r207825 r207929 39 39 class Plan { 40 40 public: 41 typedef Vector<std::unique_ptr<FunctionCompilation>> CompiledFunctions; 42 41 43 JS_EXPORT_PRIVATE Plan(VM&, Vector<uint8_t>); 42 44 JS_EXPORT_PRIVATE Plan(VM&, const uint8_t*, size_t); … … 64 66 return m_memory.get(); 65 67 } 68 69 CompiledFunctions* getFunctions() 70 { 71 RELEASE_ASSERT(!failed()); 72 return &m_result; 73 } 74 std::unique_ptr<Memory>* getMemory() 75 { 76 RELEASE_ASSERT(!failed()); 77 return &m_memory; 78 } 66 79 67 80 private: 68 Vector<std::unique_ptr<FunctionCompilation>>m_result;81 CompiledFunctions m_result; 69 82 std::unique_ptr<Memory> m_memory; 70 83 bool m_failed { true }; -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
r207650 r207929 30 30 31 31 #include "JSCInlines.h" 32 #include "JSModuleNamespaceObject.h" 32 33 33 34 namespace JSC { 34 35 35 JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, Structure* structure )36 JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, Structure* structure, JSModuleNamespaceObject* moduleNamespaceObject) 36 37 { 37 38 auto* instance = new (NotNull, allocateCell<JSWebAssemblyInstance>(vm.heap)) JSWebAssemblyInstance(vm, structure); 38 instance->finishCreation(vm );39 instance->finishCreation(vm, moduleNamespaceObject); 39 40 return instance; 40 41 } … … 50 51 } 51 52 52 void JSWebAssemblyInstance::finishCreation(VM& vm )53 void JSWebAssemblyInstance::finishCreation(VM& vm, JSModuleNamespaceObject* moduleNamespaceObject) 53 54 { 54 55 Base::finishCreation(vm); 56 m_moduleNamespaceObject.set(vm, this, moduleNamespaceObject); 57 putDirectWithoutTransition(vm, Identifier::fromString(&vm, "exports"), m_moduleNamespaceObject.get(), None); 55 58 ASSERT(inherits(info())); 56 59 } … … 67 70 68 71 Base::visitChildren(thisObject, visitor); 72 visitor.append(&thisObject->m_moduleNamespaceObject); 69 73 } 70 74 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h
r207650 r207929 32 32 33 33 namespace JSC { 34 35 class JSModuleNamespaceObject; 34 36 35 37 class JSWebAssemblyInstance : public JSDestructibleObject { … … 37 39 typedef JSDestructibleObject Base; 38 40 39 static JSWebAssemblyInstance* create(VM&, Structure* );41 static JSWebAssemblyInstance* create(VM&, Structure*, JSModuleNamespaceObject*); 40 42 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 41 43 … … 44 46 protected: 45 47 JSWebAssemblyInstance(VM&, Structure*); 46 void finishCreation(VM& );48 void finishCreation(VM&, JSModuleNamespaceObject*); 47 49 static void destroy(JSCell*); 48 50 static void visitChildren(JSCell*, SlotVisitor&); 51 52 private: 53 WriteBarrier<JSModuleNamespaceObject> m_moduleNamespaceObject; 49 54 }; 50 55 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp
r207650 r207929 30 30 31 31 #include "JSCInlines.h" 32 #include "WasmFormat.h" 33 #include "WasmMemory.h" 34 #include <wtf/StdLibExtras.h> 32 35 33 36 namespace JSC { 34 37 35 JSWebAssemblyModule* JSWebAssemblyModule::create(VM& vm, Structure* structure )38 JSWebAssemblyModule* JSWebAssemblyModule::create(VM& vm, Structure* structure, Vector<std::unique_ptr<Wasm::FunctionCompilation>>* compiledFunctions, std::unique_ptr<Wasm::Memory>* memory) 36 39 { 37 auto* instance = new (NotNull, allocateCell<JSWebAssemblyModule>(vm.heap)) JSWebAssemblyModule(vm, structure );40 auto* instance = new (NotNull, allocateCell<JSWebAssemblyModule>(vm.heap)) JSWebAssemblyModule(vm, structure, compiledFunctions, memory); 38 41 instance->finishCreation(vm); 39 42 return instance; … … 45 48 } 46 49 47 JSWebAssemblyModule::JSWebAssemblyModule(VM& vm, Structure* structure )50 JSWebAssemblyModule::JSWebAssemblyModule(VM& vm, Structure* structure, Vector<std::unique_ptr<Wasm::FunctionCompilation>>* compiledFunctions, std::unique_ptr<Wasm::Memory>* memory) 48 51 : Base(vm, structure) 52 , m_compiledFunctions(WTFMove(*compiledFunctions)) 53 , m_memory(WTFMove(*memory)) 49 54 { 50 55 } -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h
r207650 r207929 33 33 namespace JSC { 34 34 35 namespace Wasm { 36 struct FunctionCompilation; 37 class Memory; 38 } 39 35 40 class JSWebAssemblyModule : public JSDestructibleObject { 36 41 public: 37 42 typedef JSDestructibleObject Base; 38 43 39 static JSWebAssemblyModule* create(VM&, Structure* );44 static JSWebAssemblyModule* create(VM&, Structure*, Vector<std::unique_ptr<Wasm::FunctionCompilation>>*, std::unique_ptr<Wasm::Memory>*); 40 45 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 41 46 … … 43 48 44 49 protected: 45 JSWebAssemblyModule(VM&, Structure* );50 JSWebAssemblyModule(VM&, Structure*, Vector<std::unique_ptr<Wasm::FunctionCompilation>>*, std::unique_ptr<Wasm::Memory>*); 46 51 void finishCreation(VM&); 47 52 static void destroy(JSCell*); 48 53 static void visitChildren(JSCell*, SlotVisitor&); 54 55 private: 56 Vector<std::unique_ptr<Wasm::FunctionCompilation>> m_compiledFunctions; 57 std::unique_ptr<Wasm::Memory> m_memory; 49 58 }; 50 59 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp
r207825 r207929 31 31 #include "FunctionPrototype.h" 32 32 #include "JSCInlines.h" 33 #include "JSModuleNamespaceObject.h" 34 #include "JSModuleRecord.h" 35 #include "JSWebAssemblyInstance.h" 36 #include "JSWebAssemblyModule.h" 33 37 #include "WebAssemblyInstancePrototype.h" 34 38 … … 46 50 static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyInstance(ExecState* state) 47 51 { 48 VM& vm = state->vm();52 auto& vm = state->vm(); 49 53 auto scope = DECLARE_THROW_SCOPE(vm); 50 return JSValue::encode(throwException(state, scope, createError(state, ASCIILiteral("WebAssembly doesn't yet implement the Instance constructor property")))); 54 auto* globalObject = state->lexicalGlobalObject(); 55 56 // If moduleObject is not a WebAssembly.Module instance, a TypeError is thrown. 57 JSWebAssemblyModule* module = jsDynamicCast<JSWebAssemblyModule*>(state->argument(0)); 58 if (!module) 59 return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("first argument to WebAssembly.Instance must be a WebAssembly.Module"), defaultSourceAppender, runtimeTypeForValue(state->argument(0))))); 60 61 // If the importObject parameter is not undefined and Type(importObject) is not Object, a TypeError is thrown. 62 JSValue importArgument = state->argument(1); 63 JSObject* importObject = importArgument.getObject(); 64 if (!importArgument.isUndefined() && !importObject) 65 return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("second argument to WebAssembly.Instance must be undefined or an Object"), defaultSourceAppender, runtimeTypeForValue(importArgument)))); 66 67 // FIXME use the importObject. https://bugs.webkit.org/show_bug.cgi?id=164039 68 // If the list of module.imports is not empty and Type(importObject) is not Object, a TypeError is thrown. 69 70 // FIXME String things from https://bugs.webkit.org/show_bug.cgi?id=164023 71 // Let exports be a list of (string, JS value) pairs that is mapped from each external value e in instance.exports as follows: 72 IdentifierSet instanceExports; 73 for (const auto& name : instanceExports) { 74 // FIXME validate according to Module.Instance spec. 75 (void)name; 76 } 77 Identifier moduleKey; 78 SourceCode sourceCode; 79 VariableEnvironment declaredVariables; 80 VariableEnvironment lexicalVariables; 81 auto* moduleRecord = JSModuleRecord::create(state, vm, globalObject->moduleRecordStructure(), moduleKey, sourceCode, declaredVariables, lexicalVariables); 82 auto* moduleNamespaceObject = JSModuleNamespaceObject::create(state, globalObject, globalObject->moduleNamespaceObjectStructure(), moduleRecord, instanceExports); 83 84 auto* structure = InternalFunction::createSubclassStructure(state, state->newTarget(), globalObject->WebAssemblyInstanceStructure()); 85 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 86 87 return JSValue::encode(JSWebAssemblyInstance::create(vm, structure, moduleNamespaceObject)); 51 88 } 52 89 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp
r207825 r207929 55 55 auto scope = DECLARE_THROW_SCOPE(vm); 56 56 JSValue val = state->argument(0); 57 58 // If the given bytes argument is not a BufferSource, a TypeError exception is thrown. 57 59 JSArrayBuffer* arrayBuffer = val.getObject() ? jsDynamicCast<JSArrayBuffer*>(val.getObject()) : nullptr; 58 60 JSArrayBufferView* arrayBufferView = val.getObject() ? jsDynamicCast<JSArrayBufferView*>(val.getObject()) : nullptr; … … 68 70 69 71 Wasm::Plan plan(vm, base + byteOffset, byteSize); 72 // On failure, a new WebAssembly.CompileError is thrown. 70 73 if (plan.failed()) 71 74 return JSValue::encode(throwException(state, scope, createWebAssemblyCompileError(state, plan.errorMessage()))); 72 75 73 // FIXME take content from Plan.76 // The spec string values inside Ast.module are decoded as UTF8 as described in Web.md. FIXME https://bugs.webkit.org/show_bug.cgi?id=164023 74 77 78 // On success, a new WebAssembly.Module object is returned with [[Module]] set to the validated Ast.module. 75 79 auto* structure = InternalFunction::createSubclassStructure(state, state->newTarget(), asInternalFunction(state->callee())->globalObject()->WebAssemblyModuleStructure()); 76 80 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 77 return JSValue::encode(JSWebAssemblyModule::create(vm, structure)); 81 82 return JSValue::encode(JSWebAssemblyModule::create(vm, structure, plan.getFunctions(), plan.getMemory())); 78 83 } 79 84
Note: See TracChangeset
for help on using the changeset viewer.