Title: [214547] trunk
Revision
214547
Author
jfbast...@apple.com
Date
2017-03-29 10:44:59 -0700 (Wed, 29 Mar 2017)

Log Message

WebAssembly: add shell-only Memory mode helper
https://bugs.webkit.org/show_bug.cgi?id=170227

Reviewed by Mark Lam.

JSTests:

* wasm/assert.js: fix a prior debug thing I forgot to remove
* wasm/function-tests/memory-section-and-import.js: the assert
issue was hiding a failure in error message here
* wasm/js-api/element.js: the assert issue was hiding a failure in
error message here
(badInstantiation.test):
(badInstantiation):
* wasm/js-api/extension-MemoryMode.js: Added.
(const.validateMode.what.switch):
(testMemoryNoMax):
(testMemory):
(testInstanceNoMemory):
(testInstanceNoMax):
(testInstance):
* wasm/js-api/test_memory.js: the assert issue was hiding a
failure in error message here
(test):

Source/_javascript_Core:

* jsc.cpp:
(GlobalObject::finishCreation):
(functionWebAssemblyMemoryMode):
* wasm/WasmMemory.h:
* wasm/js/JSWebAssemblyInstance.h:
* wasm/js/JSWebAssemblyMemory.h:

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (214546 => 214547)


--- trunk/JSTests/ChangeLog	2017-03-29 17:40:21 UTC (rev 214546)
+++ trunk/JSTests/ChangeLog	2017-03-29 17:44:59 UTC (rev 214547)
@@ -1,3 +1,28 @@
+2017-03-29  JF Bastien  <jfbast...@apple.com>
+
+        WebAssembly: add shell-only Memory mode helper
+        https://bugs.webkit.org/show_bug.cgi?id=170227
+
+        Reviewed by Mark Lam.
+
+        * wasm/assert.js: fix a prior debug thing I forgot to remove
+        * wasm/function-tests/memory-section-and-import.js: the assert
+        issue was hiding a failure in error message here
+        * wasm/js-api/element.js: the assert issue was hiding a failure in
+        error message here
+        (badInstantiation.test):
+        (badInstantiation):
+        * wasm/js-api/extension-MemoryMode.js: Added.
+        (const.validateMode.what.switch):
+        (testMemoryNoMax):
+        (testMemory):
+        (testInstanceNoMemory):
+        (testInstanceNoMax):
+        (testInstance):
+        * wasm/js-api/test_memory.js: the assert issue was hiding a
+        failure in error message here
+        (test):
+
 2017-03-28  Keith Miller  <keith_mil...@apple.com>
 
         WebAssembly: Make WebAssembly.instantiate/compile truly asynchronous

Modified: trunk/JSTests/wasm/assert.js (214546 => 214547)


--- trunk/JSTests/wasm/assert.js	2017-03-29 17:40:21 UTC (rev 214546)
+++ trunk/JSTests/wasm/assert.js	2017-03-29 17:44:59 UTC (rev 214547)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,6 +45,8 @@
 export const isString = (v, msg) => isA(v, "string", msg);
 export const notNumber = (v, msg) => isNotA(v, "number", msg);
 export const isNumber = (v, msg) => isA(v, "number", msg);
+export const notFunction = (v, msg) => isNotA(v, "function", msg);
+export const isFunction = (v, msg) => isA(v, "function", msg);
 
 export const hasObjectProperty = (o, p, msg) => {
     isObject(o, msg);
@@ -127,7 +129,6 @@
                 if (cleanMessage === message)
                     return e;
             }
-            return e;
         }
         _fail(`Expected to throw a ${type.name} with message "${message}", got ${e.name} with message "${e.message}"`);
     }

Modified: trunk/JSTests/wasm/function-tests/memory-section-and-import.js (214546 => 214547)


--- trunk/JSTests/wasm/function-tests/memory-section-and-import.js	2017-03-29 17:40:21 UTC (rev 214546)
+++ trunk/JSTests/wasm/function-tests/memory-section-and-import.js	2017-03-29 17:44:59 UTC (rev 214547)
@@ -28,4 +28,4 @@
       .Code().End();
 
 const i0 = instantiate(builder0);
-assert.throws(() => instantiate(builder1, { imp: { memory: i0.exports.memory } }), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 34 / 40: Memory section cannot exist if an Import has a memory`);
+assert.throws(() => instantiate(builder1, { imp: { memory: i0.exports.memory } }), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 35 / 41: Memory section cannot exist if an Import has a memory`);

Modified: trunk/JSTests/wasm/js-api/element.js (214546 => 214547)


--- trunk/JSTests/wasm/js-api/element.js	2017-03-29 17:40:21 UTC (rev 214546)
+++ trunk/JSTests/wasm/js-api/element.js	2017-03-29 17:44:59 UTC (rev 214547)
@@ -181,7 +181,7 @@
             if (j === i)
                 assert.eq(table.get(j)(i*2), i*2 + 42);
             else
-                assert.throws(() => table.get(j)(i*2), TypeError, "table.get(j) is not a function.");
+                assert.throws(() => table.get(j)(i*2), TypeError, "table.get(j) is not a function. (In 'table.get(j)(i*2)', 'table.get(j)' is null)");
         }
     }
     for (let i = 0; i < 19; i++)

Added: trunk/JSTests/wasm/js-api/extension-MemoryMode.js (0 => 214547)


--- trunk/JSTests/wasm/js-api/extension-MemoryMode.js	                        (rev 0)
+++ trunk/JSTests/wasm/js-api/extension-MemoryMode.js	2017-03-29 17:44:59 UTC (rev 214547)
@@ -0,0 +1,102 @@
+import Builder from '../Builder.js';
+import * as assert from '../assert.js';
+
+const iterations = 32;
+
+// This API isn't part of WebAssembly's official spec. It is use for testing within the shell.
+
+const version = 0x01;
+const emptyModuleArray = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, version, 0x00, 0x00, 0x00);
+
+assert.isFunction(WebAssemblyMemoryMode);
+
+const message = `WebAssemblyMemoryMode expects either a WebAssembly.Memory or WebAssembly.Instance`;
+assert.throws(() => WebAssemblyMemoryMode(null), TypeError, message);
+assert.throws(() => WebAssemblyMemoryMode(undefined), TypeError, message);
+assert.throws(() => WebAssemblyMemoryMode(1), TypeError, message);
+assert.throws(() => WebAssemblyMemoryMode(""), TypeError, message);
+assert.throws(() => WebAssemblyMemoryMode({}), TypeError, message);
+assert.throws(() => WebAssemblyMemoryMode(new WebAssembly.Module(emptyModuleArray)), TypeError, message);
+assert.throws(() => WebAssemblyMemoryMode(new WebAssembly.Table({initial: 1, element: "anyfunc"})), TypeError, message);
+
+const validateMode = what => {
+    const mode = WebAssemblyMemoryMode(what);
+    switch (mode) {
+    case "Signaling":
+        break;
+    case "BoundsChecking":
+        break;
+    default:
+        throw new Error(`Unexpected WebAssembly.Memory mode '${mode}'`);
+    }
+    return what;
+}
+
+const instantiate = builder => {
+    const bin = builder.WebAssembly();
+    const module = new WebAssembly.Module(bin.get());
+    return new WebAssembly.Instance(module);
+};
+
+(function testMemoryNoMax() {
+    let memories = [];
+    for (let i = 0; i != iterations; ++i)
+        memories.push(validateMode(new WebAssembly.Memory({ initial: i })));
+    return memories;
+})();
+
+fullGC();
+
+(function testMemory() {
+    let memories = [];
+    for (let i = 0; i != iterations; ++i)
+        memories.push(validateMode(new WebAssembly.Memory({ initial: i, maximum: i })));
+    return memories;
+})();
+
+fullGC();
+
+(function testInstanceNoMemory() {
+    let instances = [];
+    for (let i = 0; i != iterations; ++i) {
+        const builder = (new Builder())
+              .Type().End()
+              .Function().End()
+              .Code().End();
+        const instance = instantiate(builder);
+        // No-memory instances should never be Signaling: it would be wasteful.
+        assert.eq(WebAssemblyMemoryMode(instance), "BoundsChecking");
+        instances.push(instance);
+    }
+    return instances;
+})();
+
+fullGC();
+
+(function testInstanceNoMax() {
+    let instances = [];
+    for (let i = 0; i != iterations; ++i) {
+        // Note: not exported! The internal API can still access.
+        const builder = (new Builder())
+              .Type().End()
+              .Function().End()
+              .Memory().InitialMaxPages(i).End()
+              .Code().End();
+        instances.push(validateMode(instantiate(builder)));
+    }
+})();
+
+fullGC();
+
+(function testInstance() {
+    let instances = [];
+    for (let i = 0; i != iterations; ++i) {
+        // Note: not exported! The internal API can still access.
+        const builder = (new Builder())
+              .Type().End()
+              .Function().End()
+              .Memory().InitialMaxPages(i, i).End()
+              .Code().End();
+        instances.push(validateMode(instantiate(builder)));
+    }
+})();

Modified: trunk/JSTests/wasm/js-api/test_memory.js (214546 => 214547)


--- trunk/JSTests/wasm/js-api/test_memory.js	2017-03-29 17:40:21 UTC (rev 214546)
+++ trunk/JSTests/wasm/js-api/test_memory.js	2017-03-29 17:44:59 UTC (rev 214547)
@@ -317,14 +317,14 @@
     const bin = builder.WebAssembly().get();
     const module = new WebAssembly.Module(bin);
 
-    assert.throws(() => new WebAssembly.Instance(module, 20), TypeError, `second argument to WebAssembly.Instance must be undefined or an Object (evaluating 'new WebAssembly.Instance(module, 20)')`);
-    assert.throws(() => new WebAssembly.Instance(module, {}), TypeError, `import must be an object (evaluating 'new WebAssembly.Instance(module, {})')`);
-    assert.throws(() => new WebAssembly.Instance(module, {imp: { } }), WebAssembly.LinkError, `Memory import is not an instance of WebAssembly.Memory (evaluating 'new WebAssembly.Instance(module, {imp: { } })')`);
-    assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: 20 } }), WebAssembly.LinkError, `Memory import is not an instance of WebAssembly.Memory (evaluating 'new WebAssembly.Instance(module, {imp: { memory: 20 } })')`);
-    assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: [] } }), WebAssembly.LinkError, `Memory import is not an instance of WebAssembly.Memory (evaluating 'new WebAssembly.Instance(module, {imp: { memory: [] } })')`);
-    assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 19, maximum: 25}) } }), WebAssembly.LinkError, `Memory import provided an 'initial' that is too small (evaluating 'new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 19, maximum: 25}) } })')`);
-    assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20}) } }), WebAssembly.LinkError, `Memory import did not have a 'maximum' but the module requires that it does (evaluating 'new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20}) } })')`);
-    assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20, maximum: 26}) } }), WebAssembly.LinkError, `Memory imports 'maximum' is larger than the module's expected 'maximum' (evaluating 'new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20, maximum: 26}) } })')`);
+    assert.throws(() => new WebAssembly.Instance(module, 20), TypeError, `second argument to WebAssembly.Instance must be undefined or an Object`);
+    assert.throws(() => new WebAssembly.Instance(module, {}), TypeError, `import must be an object`);
+    assert.throws(() => new WebAssembly.Instance(module, {imp: { } }), WebAssembly.LinkError, `Memory import is not an instance of WebAssembly.Memory`);
+    assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: 20 } }), WebAssembly.LinkError, `Memory import is not an instance of WebAssembly.Memory`);
+    assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: [] } }), WebAssembly.LinkError, `Memory import is not an instance of WebAssembly.Memory`);
+    assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 19, maximum: 25}) } }), WebAssembly.LinkError, `Memory import provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
+    assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20}) } }), WebAssembly.LinkError, `Memory import did not have a 'maximum' but the module requires that it does`);
+    assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20, maximum: 26}) } }), WebAssembly.LinkError, `Memory import provided a 'maximum' that is larger than the module's declared 'maximum' import memory size`);
 });
 
 test(function() {
@@ -354,8 +354,8 @@
         assert.throws(() => new WebAssembly.Instance(module, instanceObj), WebAssembly.LinkError, expectedError);
     }
 
-    testMemImportError({imp: { memory: new WebAssembly.Memory({initial: 19, maximum: 25}) } }, "Memory import provided an 'initial' that is too small (evaluating 'new WebAssembly.Instance(module, instanceObj)')");
-    testMemImportError({imp: { memory: new WebAssembly.Memory({initial: 19}) } }, "Memory import provided an 'initial' that is too small (evaluating 'new WebAssembly.Instance(module, instanceObj)')");
+    testMemImportError({imp: { memory: new WebAssembly.Memory({initial: 19, maximum: 25}) } }, `Memory import provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
+    testMemImportError({imp: { memory: new WebAssembly.Memory({initial: 19}) } }, `Memory import provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
 
     // This should not throw.
     new WebAssembly.Instance(module, {imp: {memory: new WebAssembly.Memory({initial:20})}});

Modified: trunk/Source/_javascript_Core/ChangeLog (214546 => 214547)


--- trunk/Source/_javascript_Core/ChangeLog	2017-03-29 17:40:21 UTC (rev 214546)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-03-29 17:44:59 UTC (rev 214547)
@@ -1,3 +1,17 @@
+2017-03-29  JF Bastien  <jfbast...@apple.com>
+
+        WebAssembly: add shell-only Memory mode helper
+        https://bugs.webkit.org/show_bug.cgi?id=170227
+
+        Reviewed by Mark Lam.
+
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionWebAssemblyMemoryMode):
+        * wasm/WasmMemory.h:
+        * wasm/js/JSWebAssemblyInstance.h:
+        * wasm/js/JSWebAssemblyMemory.h:
+
 2017-03-29  Keith Miller  <keith_mil...@apple.com>
 
         WebAssembly: pack OpcodeOrigin to fit in a pointer

Modified: trunk/Source/_javascript_Core/jsc.cpp (214546 => 214547)


--- trunk/Source/_javascript_Core/jsc.cpp	2017-03-29 17:40:21 UTC (rev 214546)
+++ trunk/Source/_javascript_Core/jsc.cpp	2017-03-29 17:44:59 UTC (rev 214547)
@@ -57,6 +57,8 @@
 #include "JSString.h"
 #include "JSTypedArrays.h"
 #include "JSWebAssemblyCallee.h"
+#include "JSWebAssemblyInstance.h"
+#include "JSWebAssemblyMemory.h"
 #include "LLIntData.h"
 #include "LLIntThunks.h"
 #include "ObjectConstructor.h"
@@ -1084,6 +1086,7 @@
 
 #if ENABLE(WEBASSEMBLY)
 static EncodedJSValue JSC_HOST_CALL functionTestWasmModuleFunctions(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionWebAssemblyMemoryMode(ExecState*);
 #endif
 
 #if ENABLE(SAMPLING_FLAGS)
@@ -1358,6 +1361,7 @@
 
 #if ENABLE(WEBASSEMBLY)
         addFunction(vm, "testWasmModuleFunctions", functionTestWasmModuleFunctions, 0);
+        addFunction(vm, "WebAssemblyMemoryMode", functionWebAssemblyMemoryMode, 1);
 #endif
 
         if (!arguments.isEmpty()) {
@@ -3246,6 +3250,24 @@
     return encodedJSUndefined();
 }
 
+static EncodedJSValue JSC_HOST_CALL functionWebAssemblyMemoryMode(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+    
+    if (!Options::useWebAssembly())
+        return throwVMTypeError(exec, scope, ASCIILiteral("WebAssemblyMemoryMode should only be called if the useWebAssembly option is set"));
+
+    if (JSObject* object = exec->argument(0).getObject()) {
+        if (auto* memory = jsDynamicCast<JSWebAssemblyMemory*>(vm, object))
+            return JSValue::encode(jsString(&vm, makeString(memory->memory().mode())));
+        if (auto* instance = jsDynamicCast<JSWebAssemblyInstance*>(vm, object))
+            return JSValue::encode(jsString(&vm, makeString(instance->memoryMode())));
+    }
+
+    return throwVMTypeError(exec, scope, ASCIILiteral("WebAssemblyMemoryMode expects either a WebAssembly.Memory or WebAssembly.Instance"));
+}
+
 #endif // ENABLE(WEBASSEBLY)
 
 // Use SEH for Release builds only to get rid of the crash report dialog

Modified: trunk/Source/_javascript_Core/wasm/WasmMemory.h (214546 => 214547)


--- trunk/Source/_javascript_Core/wasm/WasmMemory.h	2017-03-29 17:40:21 UTC (rev 214546)
+++ trunk/Source/_javascript_Core/wasm/WasmMemory.h	2017-03-29 17:44:59 UTC (rev 214547)
@@ -51,7 +51,7 @@
     NumberOfMemoryModes
 };
 static constexpr size_t NumberOfMemoryModes = static_cast<size_t>(MemoryMode::NumberOfMemoryModes);
-const char* makeString(MemoryMode);
+JS_EXPORT_PRIVATE const char* makeString(MemoryMode);
 
 class Memory : public RefCounted<Memory> {
     WTF_MAKE_NONCOPYABLE(Memory);

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h (214546 => 214547)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h	2017-03-29 17:40:21 UTC (rev 214546)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h	2017-03-29 17:44:59 UTC (rev 214547)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -51,7 +51,7 @@
     static JSWebAssemblyInstance* create(VM&, ExecState*, JSWebAssemblyModule*, JSObject* importObject, Structure*);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 
-    DECLARE_INFO;
+    DECLARE_EXPORT_INFO;
 
     JSWebAssemblyCodeBlock* codeBlock() const { return m_codeBlock.get(); }
     bool initialized() const { return codeBlock() && codeBlock()->initialized(); }

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.h (214546 => 214547)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.h	2017-03-29 17:40:21 UTC (rev 214546)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.h	2017-03-29 17:44:59 UTC (rev 214547)
@@ -44,7 +44,7 @@
     static JSWebAssemblyMemory* create(VM&, Structure*, Ref<Wasm::Memory>&&);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 
-    DECLARE_INFO;
+    DECLARE_EXPORT_INFO;
 
     Wasm::Memory& memory() { return m_memory.get(); }
     JSArrayBuffer* buffer(VM& vm, JSGlobalObject*);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to