Diff
Modified: trunk/JSTests/ChangeLog (214483 => 214484)
--- trunk/JSTests/ChangeLog 2017-03-28 18:29:40 UTC (rev 214483)
+++ trunk/JSTests/ChangeLog 2017-03-28 18:41:53 UTC (rev 214484)
@@ -1,3 +1,17 @@
+2017-03-28 JF Bastien <[email protected]>
+
+ WebAssembly: implement Module imports/exports
+ https://bugs.webkit.org/show_bug.cgi?id=166982
+
+ Reviewed by Saam Barati.
+
+ * wasm/js-api/Module.exports.js: Added.
+ (assert.throws.WebAssembly.Module.prototype.exports):
+ (assert.eq):
+ * wasm/js-api/Module.imports.js: Added.
+ (assert.throws.WebAssembly.Module.prototype.imports):
+ (assert.eq):
+
2017-03-27 JF Bastien <[email protected]>
WebAssembly: misc memory testing
Added: trunk/JSTests/wasm/js-api/Module.exports.js (0 => 214484)
--- trunk/JSTests/wasm/js-api/Module.exports.js (rev 0)
+++ trunk/JSTests/wasm/js-api/Module.exports.js 2017-03-28 18:41:53 UTC (rev 214484)
@@ -0,0 +1,42 @@
+import Builder from '../Builder.js';
+import * as assert from '../assert.js';
+
+assert.throws(() => WebAssembly.Module.prototype.exports(undefined, ""), TypeError, `WebAssembly.Module.prototype.exports called with non WebAssembly.Module |this| value`);
+
+{
+ const m = new WebAssembly.Module((new Builder()).WebAssembly().get());
+ assert.isArray(m.exports);
+ assert.eq(m.exports.length, 0);
+ assert.truthy(m.exports !== m.exports);
+}
+
+{
+ const m = new WebAssembly.Module(
+ (new Builder())
+ .Type().End()
+ .Function().End()
+ .Table()
+ .Table({initial: 20, maximum: 30, element: "anyfunc"})
+ .End()
+ .Memory().InitialMaxPages(1, 1).End()
+ .Global().I32(42, "immutable").End()
+ .Export()
+ .Function("func")
+ .Table("tab", 0)
+ .Memory("mem", 0)
+ .Global("glob", 0)
+ .End()
+ .Code()
+ .Function("func", { params: [] }).Return().End()
+ .End()
+ .WebAssembly().get());
+ assert.eq(m.exports.length, 4);
+ assert.eq(m.exports[0].name, "func");
+ assert.eq(m.exports[0].kind, "function");
+ assert.eq(m.exports[1].name, "tab");
+ assert.eq(m.exports[1].kind, "table");
+ assert.eq(m.exports[2].name, "mem");
+ assert.eq(m.exports[2].kind, "memory");
+ assert.eq(m.exports[3].name, "glob");
+ assert.eq(m.exports[3].kind, "global");
+}
Added: trunk/JSTests/wasm/js-api/Module.imports.js (0 => 214484)
--- trunk/JSTests/wasm/js-api/Module.imports.js (rev 0)
+++ trunk/JSTests/wasm/js-api/Module.imports.js 2017-03-28 18:41:53 UTC (rev 214484)
@@ -0,0 +1,37 @@
+import Builder from '../Builder.js';
+import * as assert from '../assert.js';
+
+assert.throws(() => WebAssembly.Module.prototype.imports(undefined, ""), TypeError, `WebAssembly.Module.prototype.imports called with non WebAssembly.Module |this| value`);
+
+{
+ const m = new WebAssembly.Module((new Builder()).WebAssembly().get());
+ assert.isArray(m.imports);
+ assert.eq(m.imports.length, 0);
+ assert.truthy(m.exports !== m.exports);
+}
+
+{
+ const m = new WebAssembly.Module(
+ (new Builder())
+ .Type().End()
+ .Import()
+ .Function("fooFunction", "barFunction", { params: [] })
+ .Table("fooTable", "barTable", {initial: 20, element: "anyfunc"})
+ .Memory("fooMemory", "barMemory", {initial: 20})
+ .Global().I32("fooGlobal", "barGlobal", "immutable").End()
+ .End()
+ .WebAssembly().get());
+ assert.eq(m.imports.length, 4);
+ assert.eq(m.imports[0].module, "fooFunction");
+ assert.eq(m.imports[0].name, "barFunction");
+ assert.eq(m.imports[0].kind, "function");
+ assert.eq(m.imports[1].module, "fooTable");
+ assert.eq(m.imports[1].name, "barTable");
+ assert.eq(m.imports[1].kind, "table");
+ assert.eq(m.imports[2].module, "fooMemory");
+ assert.eq(m.imports[2].name, "barMemory");
+ assert.eq(m.imports[2].kind, "memory");
+ assert.eq(m.imports[3].module, "fooGlobal");
+ assert.eq(m.imports[3].name, "barGlobal");
+ assert.eq(m.imports[3].kind, "global");
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (214483 => 214484)
--- trunk/Source/_javascript_Core/ChangeLog 2017-03-28 18:29:40 UTC (rev 214483)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-03-28 18:41:53 UTC (rev 214484)
@@ -1,3 +1,20 @@
+2017-03-28 JF Bastien <[email protected]>
+
+ WebAssembly: implement Module imports/exports
+ https://bugs.webkit.org/show_bug.cgi?id=166982
+
+ Reviewed by Saam Barati.
+
+ As defined in: https://github.com/WebAssembly/design/commit/18cbacb90cd3584dd5c9aa3d392e4e55f66af6ab
+
+ * wasm/WasmFormat.h:
+ (JSC::Wasm::makeString): use uppercase instead, it was only used
+ for diagnostic but is now used for the expected JS property's
+ capitalization
+ * wasm/js/WebAssemblyModulePrototype.cpp:
+ (JSC::webAssemblyModuleProtoImports):
+ (JSC::webAssemblyModuleProtoExports):
+
2017-03-27 JF Bastien <[email protected]>
WebAssembly: JSWebAssemblyCodeBlock.h belongs in _javascript_Core/wasm/js not _javascript_Core/wasm
Modified: trunk/Source/_javascript_Core/wasm/WasmFormat.h (214483 => 214484)
--- trunk/Source/_javascript_Core/wasm/WasmFormat.h 2017-03-28 18:29:40 UTC (rev 214483)
+++ trunk/Source/_javascript_Core/wasm/WasmFormat.h 2017-03-28 18:41:53 UTC (rev 214484)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-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
@@ -92,10 +92,10 @@
static inline const char* makeString(ExternalKind kind)
{
switch (kind) {
- case ExternalKind::Function: return "Function";
- case ExternalKind::Table: return "Table";
- case ExternalKind::Memory: return "Memory";
- case ExternalKind::Global: return "Global";
+ case ExternalKind::Function: return "function";
+ case ExternalKind::Table: return "table";
+ case ExternalKind::Memory: return "memory";
+ case ExternalKind::Global: return "global";
}
RELEASE_ASSERT_NOT_REACHED();
return "?";
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModulePrototype.cpp (214483 => 214484)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModulePrototype.cpp 2017-03-28 18:29:40 UTC (rev 214483)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModulePrototype.cpp 2017-03-28 18:41:53 UTC (rev 214484)
@@ -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
@@ -33,9 +33,12 @@
#include "JSArrayBuffer.h"
#include "JSCInlines.h"
#include "JSWebAssemblyModule.h"
+#include "ObjectConstructor.h"
namespace JSC {
static EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoCustomSections(ExecState*);
+static EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoImports(ExecState*);
+static EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoExports(ExecState*);
}
#include "WebAssemblyModulePrototype.lut.h"
@@ -47,6 +50,8 @@
/* Source for WebAssemblyModulePrototype.lut.h
@begin prototypeTableWebAssemblyModule
customSections webAssemblyModuleProtoCustomSections DontEnum|Function 1
+ imports webAssemblyModuleProtoImports DontEnum|Accessor 0
+ exports webAssemblyModuleProtoExports DontEnum|Accessor 0
@end
*/
@@ -58,8 +63,7 @@
JSWebAssemblyModule* module = jsDynamicCast<JSWebAssemblyModule*>(vm, exec->thisValue());
if (!module)
- throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Module.prototype.customSections called with non WebAssembly.Module |this| value")));
- RETURN_IF_EXCEPTION(throwScope, { });
+ return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Module.prototype.customSections called with non WebAssembly.Module |this| value"))));
const String sectionNameString = exec->argument(0).getString(exec);
RETURN_IF_EXCEPTION(throwScope, { });
@@ -72,7 +76,7 @@
if (section.name == sectionNameString) {
auto buffer = ArrayBuffer::tryCreate(section.payload.data(), section.payload.size());
if (!buffer)
- throwException(exec, throwScope, createOutOfMemoryError(exec));
+ return JSValue::encode(throwException(exec, throwScope, createOutOfMemoryError(exec)));
Structure* arrayBufferStructure = InternalFunction::createSubclassStructure(exec, JSValue(), globalObject->arrayBufferStructure(ArrayBufferSharingMode::Default));
RETURN_IF_EXCEPTION(throwScope, { });
@@ -85,6 +89,68 @@
return JSValue::encode(result);
}
+EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoImports(ExecState* exec)
+{
+ VM& vm = exec->vm();
+ auto* globalObject = exec->lexicalGlobalObject();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ JSWebAssemblyModule* module = jsDynamicCast<JSWebAssemblyModule*>(vm, exec->thisValue());
+ if (!module)
+ return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Module.prototype.imports called with non WebAssembly.Module |this| value"))));
+
+ JSArray* result = constructEmptyArray(exec, nullptr, globalObject);
+ RETURN_IF_EXCEPTION(throwScope, { });
+
+ const auto& imports = module->moduleInformation().imports;
+ if (imports.size()) {
+ Identifier module = Identifier::fromString(exec, "module");
+ Identifier name = Identifier::fromString(exec, "name");
+ Identifier kind = Identifier::fromString(exec, "kind");
+ for (const Wasm::Import& imp : imports) {
+ JSObject* obj = constructEmptyObject(exec);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ obj->putDirect(vm, module, jsString(exec, imp.module.string()));
+ obj->putDirect(vm, name, jsString(exec, imp.field.string()));
+ obj->putDirect(vm, kind, jsString(exec, String(makeString(imp.kind))));
+ result->push(exec, obj);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ }
+
+ return JSValue::encode(result);
+}
+
+EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoExports(ExecState* exec)
+{
+ VM& vm = exec->vm();
+ auto* globalObject = exec->lexicalGlobalObject();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ JSWebAssemblyModule* module = jsDynamicCast<JSWebAssemblyModule*>(vm, exec->thisValue());
+ if (!module)
+ return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Module.prototype.exports called with non WebAssembly.Module |this| value"))));
+
+ JSArray* result = constructEmptyArray(exec, nullptr, globalObject);
+ RETURN_IF_EXCEPTION(throwScope, { });
+
+ const auto& exports = module->moduleInformation().exports;
+ if (exports.size()) {
+ Identifier name = Identifier::fromString(exec, "name");
+ Identifier kind = Identifier::fromString(exec, "kind");
+ for (const Wasm::Export& exp : exports) {
+ JSObject* obj = constructEmptyObject(exec);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ obj->putDirect(vm, name, jsString(exec, exp.field.string()));
+ obj->putDirect(vm, kind, jsString(exec, String(makeString(exp.kind))));
+ result->push(exec, obj);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ }
+
+ return JSValue::encode(result);
+}
+
WebAssemblyModulePrototype* WebAssemblyModulePrototype::create(VM& vm, JSGlobalObject*, Structure* structure)
{
auto* object = new (NotNull, allocateCell<WebAssemblyModulePrototype>(vm.heap)) WebAssemblyModulePrototype(vm, structure);