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*);