WebAssembly JS API: implement basic stub
authorjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Oct 2016 21:36:05 +0000 (21:36 +0000)
committerjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Oct 2016 21:36:05 +0000 (21:36 +0000)
Implement the global WebAssembly JavaScript object, and its constructor +
function properties as described in:
  https://github.com/WebAssembly/design/blob/master/JS.md

These don't do anything at the moment, the parent bug will take care of adding
more functionality and associated tests.

WebAssembly JS API: implement basic stub
https://bugs.webkit.org/show_bug.cgi?id=163404

Reviewed by Keith Miller.

JSTests:

* wasm.yaml:
* wasm/js-api/test_basic_api.js: Added.
(const.f.of.functionProperties.WebAssembly.f.undefined.throw.new.Error.Couldn.const.c.of.constructorProperties.WebAssembly.c.undefined.throw.new.Error.Couldn):
(const.c.of.constructorProperties.catch):

Source/JavaScriptCore:

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* builtins/BuiltinNames.h: register the new WebAssembly object's name and its constructor properties
* jsc.cpp: remove useless include
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init): add the WebAssembly global object and its constructor properties, but only if the JSC option enables it
* runtime/Options.h: add the useWebAssembly (alias: enableWebAssembly) option, defaulting to false
* wasm/WebAssemblyObject.cpp: Added.
(JSC::WebAssemblyObject::create): boilerplate
(JSC::WebAssemblyObject::createStructure): boilerplate
(JSC::WebAssemblyObject::finishCreation): boilerplate
(JSC::WebAssemblyObject::WebAssemblyObject): boilerplate
(JSC::wasmObjectFuncvalidate): auto-throws for now
(JSC::wasmObjectFunccompile): auto-throws for now
* wasm/WebAssemblyObject.h: Added.

Tools:

* Scripts/run-jsc-stress-tests: use the new JSC option which exposes the WebAssembly object.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207432 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
JSTests/ChangeLog
JSTests/wasm.yaml
JSTests/wasm/js-api/test_basic_api.js [new file with mode: 0644]
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/builtins/BuiltinNames.h
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/Options.h
Source/JavaScriptCore/wasm/WebAssemblyObject.cpp [new file with mode: 0644]
Source/JavaScriptCore/wasm/WebAssemblyObject.h [new file with mode: 0644]
Tools/ChangeLog
Tools/Scripts/run-jsc-stress-tests

index a9a214a..90f162f 100644 (file)
@@ -1,3 +1,24 @@
+2016-10-17  JF Bastien  <jfbastien@apple.com>
+
+        WebAssembly JS API: implement basic stub
+
+        Implement the global WebAssembly JavaScript object, and its constructor +
+        function properties as described in:
+          https://github.com/WebAssembly/design/blob/master/JS.md
+
+        These don't do anything at the moment, the parent bug will take care of adding
+        more functionality and associated tests.
+
+        WebAssembly JS API: implement basic stub
+        https://bugs.webkit.org/show_bug.cgi?id=163404
+
+        Reviewed by Keith Miller.
+
+        * wasm.yaml:
+        * wasm/js-api/test_basic_api.js: Added.
+        (const.f.of.functionProperties.WebAssembly.f.undefined.throw.new.Error.Couldn.const.c.of.constructorProperties.WebAssembly.c.undefined.throw.new.Error.Couldn):
+        (const.c.of.constructorProperties.catch):
+
 2016-10-17  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [DOMJIT] Use DOMJIT::Patchpoint in IC
index 547ce72..8f4a86e 100644 (file)
@@ -23,3 +23,5 @@
 
 - path: wasm/self-test/
   cmd: runWebAssembly
+- path: wasm/js-api/
+  cmd: runWebAssembly
diff --git a/JSTests/wasm/js-api/test_basic_api.js b/JSTests/wasm/js-api/test_basic_api.js
new file mode 100644 (file)
index 0000000..1953cb0
--- /dev/null
@@ -0,0 +1,37 @@
+if (WebAssembly === undefined)
+    throw new Error("Couldn't find WebAssembly global object");
+
+const functionProperties = ["validate", "compile"];
+const constructorProperties = ["Module", "Instance", "Memory", "Table", "CompileError"];
+
+for (const f of functionProperties)
+    if (WebAssembly[f] === undefined)
+        throw new Error(`Couldn't find WebAssembly function property "${f}"`);
+
+for (const c of constructorProperties)
+    if (WebAssembly[c] === undefined)
+        throw new Error(`Couldn't find WebAssembly constructor property "${c}"`);
+
+// FIXME https://bugs.webkit.org/show_bug.cgi?id=159775 Implement and test these APIs further. For now they just throw.
+
+for (const f of functionProperties) {
+    try {
+        WebAssembly[f]();
+    } catch (e) {
+        if (e instanceof Error)
+            continue;
+        throw new Error(`Expected WebAssembly.${f}() to throw an Error, got ${e}`);
+    }
+    throw new Error(`Expected WebAssembly.${f}() to throw an Error`);
+}
+
+for (const c of constructorProperties) {
+    try {
+        let v = new WebAssembly[c]();
+    } catch (e) {
+        if (e instanceof Error)
+            continue;
+        throw new Error(`Expected new WebAssembly.${f}() to throw an Error, got ${e}`);
+    }
+    throw new Error(`Expected new WebAssembly.${f}() to throw an Error`);
+}
index 4fb856d..95406ef 100644 (file)
@@ -864,6 +864,7 @@ set(JavaScriptCore_SOURCES
     wasm/WASMCallingConvention.cpp
     wasm/WASMModuleParser.cpp
     wasm/WASMPlan.cpp
+    wasm/WebAssemblyObject.cpp
 
     yarr/RegularExpression.cpp
     yarr/YarrCanonicalizeUCS2.cpp
index 35f1ac9..6f1b6df 100644 (file)
@@ -1,3 +1,35 @@
+2016-10-17  JF Bastien  <jfbastien@apple.com>
+
+        WebAssembly JS API: implement basic stub
+
+        Implement the global WebAssembly JavaScript object, and its constructor +
+        function properties as described in:
+          https://github.com/WebAssembly/design/blob/master/JS.md
+
+        These don't do anything at the moment, the parent bug will take care of adding
+        more functionality and associated tests.
+
+        WebAssembly JS API: implement basic stub
+        https://bugs.webkit.org/show_bug.cgi?id=163404
+
+        Reviewed by Keith Miller.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/BuiltinNames.h: register the new WebAssembly object's name and its constructor properties
+        * jsc.cpp: remove useless include
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init): add the WebAssembly global object and its constructor properties, but only if the JSC option enables it
+        * runtime/Options.h: add the useWebAssembly (alias: enableWebAssembly) option, defaulting to false
+        * wasm/WebAssemblyObject.cpp: Added.
+        (JSC::WebAssemblyObject::create): boilerplate
+        (JSC::WebAssemblyObject::createStructure): boilerplate
+        (JSC::WebAssemblyObject::finishCreation): boilerplate
+        (JSC::WebAssemblyObject::WebAssemblyObject): boilerplate
+        (JSC::wasmObjectFuncvalidate): auto-throws for now
+        (JSC::wasmObjectFunccompile): auto-throws for now
+        * wasm/WebAssemblyObject.h: Added.
+
 2016-10-17  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         Unreviewed, build fix after r207428
index bcecac7..a9349f1 100644 (file)
                A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7FCC26D17A0B6AA00786D1A /* FTLSwitchCase.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FCC26C17A0B6AA00786D1A /* FTLSwitchCase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A8A4748E151A8306004123FF /* libWTF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A8A4748D151A8306004123FF /* libWTF.a */; };
+               AD2FCB881DAEBF3C00B3E736 /* WebAssemblyObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD2FCB861DAEBF3700B3E736 /* WebAssemblyObject.cpp */; };
+               AD2FCB891DAEBF3F00B3E736 /* WebAssemblyObject.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCB871DAEBF3700B3E736 /* WebAssemblyObject.h */; };
                AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                ADDB1F6318D77DBE009B58A8 /* OpaqueRootSet.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
                ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */; };
                A8E894310CD0602400367179 /* JSCallbackObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObjectFunctions.h; sourceTree = "<group>"; };
                A8E894330CD0603F00367179 /* JSGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObject.h; sourceTree = "<group>"; };
                AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyTable.cpp; sourceTree = "<group>"; };
+               AD2FCB861DAEBF3700B3E736 /* WebAssemblyObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebAssemblyObject.cpp; sourceTree = "<group>"; };
+               AD2FCB871DAEBF3700B3E736 /* WebAssemblyObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAssemblyObject.h; sourceTree = "<group>"; };
                AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = "<group>"; };
                ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueRootSet.h; sourceTree = "<group>"; };
                B59F89371891AD3300D5CCDC /* UnlinkedInstructionStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedInstructionStream.h; sourceTree = "<group>"; };
                7B98D1331B60CD1E0023B1A4 /* wasm */ = {
                        isa = PBXGroup;
                        children = (
+                               AD2FCB861DAEBF3700B3E736 /* WebAssemblyObject.cpp */,
+                               AD2FCB871DAEBF3700B3E736 /* WebAssemblyObject.h */,
                                7B98D1341B60CD5A0023B1A4 /* JSWASMModule.cpp */,
                                7B98D1351B60CD5A0023B1A4 /* JSWASMModule.h */,
                                53F40E8E1D5902820099A1B6 /* WASMB3IRGenerator.cpp */,
                                0FC97F34182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h in Headers */,
                                0FD8A31417D4326C00CA2C40 /* CodeBlockSet.h in Headers */,
                                0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */,
+                               AD2FCB891DAEBF3F00B3E736 /* WebAssemblyObject.h in Headers */,
                                A77F1822164088B200640A47 /* CodeCache.h in Headers */,
                                99CC0B6318BE9950006CEBCC /* CodeGeneratorReplayInputs.py in Headers */,
                                99CC0B6218BE9946006CEBCC /* CodeGeneratorReplayInputsTemplates.py in Headers */,
                                7905BB681D12050E0019FE57 /* InlineAccess.cpp in Sources */,
                                0FE050271AA9095600D33B33 /* ScopedArguments.cpp in Sources */,
                                0FE0502F1AAA806900D33B33 /* ScopedArgumentsTable.cpp in Sources */,
+                               AD2FCB881DAEBF3C00B3E736 /* WebAssemblyObject.cpp in Sources */,
                                992ABCF91BEA9BD2006403A0 /* RemoteAutomationTarget.cpp in Sources */,
                                0FE0502A1AA9095600D33B33 /* ScopeOffset.cpp in Sources */,
                                0FA7A8EE18CE4FD80052371D /* ScratchRegisterAllocator.cpp in Sources */,
index 6ebd339..d7412d7 100644 (file)
@@ -159,6 +159,13 @@ namespace JSC {
     macro(stringSubstrInternal) \
     macro(makeBoundFunction) \
     macro(hasOwnLengthProperty) \
+    macro(WebAssembly) \
+    macro(Module) \
+    macro(Instance) \
+    macro(Memory) \
+    macro(Table) \
+    macro(CompileError) \
+    macro(RuntimeError) \
 
 
 #define INITIALIZE_PRIVATE_TO_PUBLIC_ENTRY(name) m_privateToPublicMap.add(m_##name##PrivateName.impl(), &m_##name);
index 8402236..f5f1364 100644 (file)
@@ -53,7 +53,6 @@
 #include "JSProxy.h"
 #include "JSString.h"
 #include "JSTypedArrays.h"
-#include "JSWASMModule.h"
 #include "LLIntData.h"
 #include "ObjectConstructor.h"
 #include "ParserError.h"
index 3a4ead9..604c0bf 100644 (file)
 #include "JSTypedArrayViewConstructor.h"
 #include "JSTypedArrayViewPrototype.h"
 #include "JSTypedArrays.h"
-#include "JSWASMModule.h"
 #include "JSWeakMap.h"
 #include "JSWeakSet.h"
 #include "JSWithScope.h"
 #include "WeakMapPrototype.h"
 #include "WeakSetConstructor.h"
 #include "WeakSetPrototype.h"
+#include "WebAssemblyObject.h"
 #include <wtf/RandomNumber.h>
 
 #if ENABLE(INTL)
@@ -818,6 +818,22 @@ putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct
         putDirectWithoutTransition(vm, Identifier::fromString(exec, "$vm"), dollarVM, DontEnum);
     }
 
+#if ENABLE(WEBASSEMBLY)
+    if (Options::useWebAssembly()) {
+        auto* wasm = WebAssemblyObject::create(vm, this, WebAssemblyObject::createStructure(vm, this, m_objectPrototype.get()));
+        putDirectWithoutTransition(vm, Identifier::fromString(exec, "WebAssembly"), wasm, DontEnum);
+        GlobalPropertyInfo extraStaticGlobals[] = {
+            GlobalPropertyInfo(vm.propertyNames->builtinNames().ModulePrivateName(), wasm->getDirect(vm, Identifier::fromString(exec, "Module")), DontEnum | DontDelete | ReadOnly),
+            GlobalPropertyInfo(vm.propertyNames->builtinNames().InstancePrivateName(), wasm->getDirect(vm, Identifier::fromString(exec, "Instance")), DontEnum | DontDelete | ReadOnly),
+            GlobalPropertyInfo(vm.propertyNames->builtinNames().MemoryPrivateName(), wasm->getDirect(vm, Identifier::fromString(exec, "Memory")), DontEnum | DontDelete | ReadOnly),
+            GlobalPropertyInfo(vm.propertyNames->builtinNames().TablePrivateName(), wasm->getDirect(vm, Identifier::fromString(exec, "Table")), DontEnum | DontDelete | ReadOnly),
+            GlobalPropertyInfo(vm.propertyNames->builtinNames().CompileErrorPrivateName(), wasm->getDirect(vm, Identifier::fromString(exec, "CompileError")), DontEnum | DontDelete | ReadOnly),
+            GlobalPropertyInfo(vm.propertyNames->builtinNames().RuntimeErrorPrivateName(), wasm->getDirect(vm, Identifier::fromString(exec, "RuntimeError")), DontEnum | DontDelete | ReadOnly),
+        };
+        addStaticGlobals(extraStaticGlobals, WTF_ARRAY_LENGTH(extraStaticGlobals));
+    }
+#endif // ENABLE(WEBASSEMBLY)
+
     resetPrototype(vm, getPrototypeDirect());
 }
 
index db5c572..cc6d807 100644 (file)
@@ -390,6 +390,8 @@ typedef const char* optionString;
     \
     v(bool, useSourceProviderCache, true, Normal, "If false, the parser will not use the source provider cache. It's good to verify everything works when this is false. Because the cache is so successful, it can mask bugs.") \
     v(bool, useCodeCache, true, Normal, "If false, the unlinked byte code cache will not be used.") \
+    \
+    v(bool, useWebAssembly, false, Normal, "Expose the WebAssembly global object.") \
 
 enum OptionEquivalence {
     SameOption,
@@ -427,6 +429,7 @@ enum OptionEquivalence {
     v(enableExecutableAllocationFuzz, useExecutableAllocationFuzz, SameOption) \
     v(enableOSRExitFuzz, useOSRExitFuzz, SameOption) \
     v(enableDollarVM, useDollarVM, SameOption) \
+    v(enableWebAssembly, useWebAssembly, SameOption) \
 
 class Options {
 public:
diff --git a/Source/JavaScriptCore/wasm/WebAssemblyObject.cpp b/Source/JavaScriptCore/wasm/WebAssemblyObject.cpp
new file mode 100644 (file)
index 0000000..44c229b
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebAssemblyObject.h"
+
+#include "BuiltinNames.h"
+#include "FunctionPrototype.h"
+#include "InternalFunction.h"
+#include "JSCInlines.h"
+#include "JSDestructibleObject.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(WebAssemblyObject);
+
+// Name, functionLength
+#define FOR_EACH_WASM_CONSTRUCTOR_PROPERTY(DO) \
+    DO(Module, 1) \
+    DO(Instance, 2) \
+    DO(Memory, 1) \
+    DO(Table, 1) \
+    DO(CompileError, 1) \
+    DO(RuntimeError, 1)
+
+// Name, functionLength
+#define FOR_EACH_WASM_FUNCTION_PROPERTY(DO) \
+    DO(validate, 1) \
+    DO(compile, 1)
+
+// FIXME Implement each of these in their own header file, and autogenerate *.lut.h files for *PrototypeTable. https://bugs.webkit.org/show_bug.cgi?id=161709
+#define DEFINE_WASM_OBJECT_CONSTRUCTOR_PROPERTY(NAME, functionLength) \
+    class JSWebAssembly ## NAME : public JSDestructibleObject { \
+    public: \
+        typedef JSDestructibleObject Base; \
+        \
+        static JSWebAssembly ## NAME* create(VM& vm, Structure* structure) \
+        { \
+            auto* format = new (NotNull, allocateCell<JSWebAssembly ## NAME>(vm.heap)) JSWebAssembly ## NAME(vm, structure); \
+            format->finishCreation(vm); \
+            return format; \
+        } \
+        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) \
+        { \
+            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); \
+        } \
+        \
+        DECLARE_INFO; \
+        \
+    protected: \
+        JSWebAssembly ## NAME(VM& vm, Structure* structure) \
+            : JSDestructibleObject(vm, structure) \
+        { \
+        } \
+        void finishCreation(VM& vm) \
+        { \
+            Base::finishCreation(vm); \
+            ASSERT(inherits(info())); \
+        } \
+    }; \
+    const ClassInfo JSWebAssembly ## NAME::s_info = { "WebAssembly." #NAME, &Base::s_info, 0, CREATE_METHOD_TABLE(JSWebAssembly ## NAME) }; \
+    \
+    class WebAssembly ## NAME ## Prototype : public JSDestructibleObject { \
+    public: \
+        typedef JSDestructibleObject Base; \
+        static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable; \
+        \
+        static WebAssembly ## NAME ## Prototype* create(VM& vm, JSGlobalObject*, Structure* structure) \
+        { \
+            auto* object = new (NotNull, allocateCell<WebAssembly ## NAME ## Prototype>(vm.heap)) WebAssembly ## NAME ## Prototype(vm, structure); \
+            object->finishCreation(vm); \
+            return object; \
+        } \
+        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) \
+        { \
+            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); \
+        } \
+        \
+        DECLARE_INFO; \
+        \
+    protected: \
+        void finishCreation(VM& vm) \
+        { \
+            Base::finishCreation(vm); \
+        } \
+        \
+    private: \
+        WebAssembly ## NAME ## Prototype(VM& vm, Structure* structure) \
+            : JSDestructibleObject(vm, structure) \
+        { \
+        } \
+    }; \
+    static const struct CompactHashIndex NAME ## PrototypeTableIndex[] = { { 0, 0 } }; \
+    static const struct HashTableValue NAME ## PrototypeTableValues[] = { { nullptr, 0, NoIntrinsic, { 0 } } }; \
+    static const struct HashTable NAME ## PrototypeTable = { 0, 0, true, NAME ## PrototypeTableValues, NAME ## PrototypeTableIndex }; \
+    const ClassInfo WebAssembly ## NAME ## Prototype::s_info = { "WebAssembly." #NAME ".prototype", &Base::s_info, &NAME ## PrototypeTable, CREATE_METHOD_TABLE(WebAssembly ## NAME ## Prototype) }; \
+    \
+    static EncodedJSValue JSC_HOST_CALL constructJSWebAssembly ## NAME(ExecState* state) \
+    { \
+        VM& vm = state->vm(); \
+        auto scope = DECLARE_THROW_SCOPE(vm); \
+        return JSValue::encode(throwException(state, scope, createError(state, ASCIILiteral("WebAssembly doesn't yet implement the " #NAME " constructor property")))); \
+    } \
+    \
+    static EncodedJSValue JSC_HOST_CALL callJSWebAssembly ## NAME(ExecState* state) \
+    { \
+    VM& vm = state->vm(); \
+    auto scope = DECLARE_THROW_SCOPE(vm); \
+    return JSValue::encode(throwException(state, scope, createError(state, ASCIILiteral("WebAssembly doesn't yet implement the " #NAME " constructor property")))); \
+    } \
+    \
+    class WebAssembly ## NAME ## Constructor : public InternalFunction { \
+    public: \
+        typedef InternalFunction Base; \
+        static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable; \
+        \
+        static WebAssembly ## NAME ## Constructor* create(VM& vm, Structure* structure, WebAssembly ## NAME ## Prototype* NAME ## Prototype, Structure* NAME ## Structure) \
+        { \
+            WebAssembly ## NAME ## Constructor* constructor = new (NotNull, allocateCell<WebAssembly ## NAME ## Constructor>(vm.heap)) WebAssembly ## NAME ## Constructor(vm, structure); \
+            constructor->finishCreation(vm, NAME ## Prototype, NAME ## Structure); \
+            return constructor; \
+        } \
+        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) \
+        { \
+            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); \
+        } \
+        \
+        DECLARE_INFO; \
+        \
+        Structure* NAME ## Structure() const { return m_ ## NAME ## Structure.get(); } \
+        \
+    protected: \
+        void finishCreation(VM& vm, WebAssembly ## NAME ## Prototype* NAME ## Prototype, Structure* NAME ## Structure) \
+        { \
+            Base::finishCreation(vm, ASCIILiteral(#NAME)); \
+            putDirectWithoutTransition(vm, vm.propertyNames->prototype, NAME ## Prototype, DontEnum | DontDelete | ReadOnly); \
+            putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(functionLength), ReadOnly | DontEnum | DontDelete); \
+            m_ ## NAME ## Structure.set(vm, this, NAME ## Structure); \
+        } \
+        \
+    private: \
+        WebAssembly ## NAME ## Constructor(VM& vm, Structure* structure) \
+            : InternalFunction(vm, structure) \
+        { \
+        } \
+        static ConstructType getConstructData(JSCell*, ConstructData& constructData) \
+        { \
+            constructData.native.function = constructJSWebAssembly ## NAME; \
+            return ConstructType::Host; \
+        } \
+        static CallType getCallData(JSCell*, CallData& callData) \
+        { \
+            callData.native.function = callJSWebAssembly ## NAME; \
+            return CallType::Host; \
+        } \
+        static void visitChildren(JSCell* cell, SlotVisitor& visitor) \
+        { \
+            auto* thisObject = jsCast<WebAssembly ## NAME ## Constructor*>(cell); \
+            ASSERT_GC_OBJECT_INHERITS(thisObject, info()); \
+            Base::visitChildren(thisObject, visitor); \
+            visitor.append(&thisObject->m_ ## NAME ## Structure); \
+        } \
+        \
+        WriteBarrier<Structure> m_ ## NAME ## Structure; \
+    }; \
+    static const struct CompactHashIndex NAME ## ConstructorTableIndex[] = { { 0, 0 } }; \
+    static const struct HashTableValue NAME ## ConstructorTableValues[] = { { nullptr, 0, NoIntrinsic, { 0 } } }; \
+    static const struct HashTable NAME ## ConstructorTable = { 0, 0, true, NAME ## ConstructorTableValues, NAME ## ConstructorTableIndex }; \
+    const ClassInfo WebAssembly ## NAME ## Constructor::s_info = { "Function", &Base::s_info, &NAME ## ConstructorTable, CREATE_METHOD_TABLE(WebAssembly ## NAME ## Constructor) };
+
+FOR_EACH_WASM_CONSTRUCTOR_PROPERTY(DEFINE_WASM_OBJECT_CONSTRUCTOR_PROPERTY)
+
+
+#define DECLARE_WASM_OBJECT_FUNCTION(NAME, ...) EncodedJSValue JSC_HOST_CALL wasmObjectFunc ## NAME(ExecState*);
+FOR_EACH_WASM_FUNCTION_PROPERTY(DECLARE_WASM_OBJECT_FUNCTION)
+
+
+const ClassInfo WebAssemblyObject::s_info = { "WebAssembly", &Base::s_info, 0, CREATE_METHOD_TABLE(WebAssemblyObject) };
+
+WebAssemblyObject* WebAssemblyObject::create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+{
+    auto* object = new (NotNull, allocateCell<WebAssemblyObject>(vm.heap)) WebAssemblyObject(vm, structure);
+    object->finishCreation(vm, globalObject);
+    return object;
+}
+
+Structure* WebAssemblyObject::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+}
+
+void WebAssemblyObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(info()));
+
+#define SET_UP_WASM_CONSTRUCTOR_PROPERTY(NAME, ...) \
+    auto* prototype ## NAME = WebAssembly ## NAME ## Prototype::create(vm, globalObject, WebAssembly ## NAME ## Prototype::createStructure(vm, globalObject, globalObject->objectPrototype())); \
+    auto* structure ## NAME = JSWebAssembly ## NAME::createStructure(vm, globalObject, prototype ## NAME); \
+    auto* constructor ## NAME = WebAssembly ## NAME ## Constructor::create(vm, WebAssembly ## NAME ## Constructor::createStructure(vm, globalObject, globalObject->functionPrototype()), prototype ## NAME, structure ## NAME); \
+    prototype ## NAME->putDirectWithoutTransition(vm, vm.propertyNames->constructor, constructor ## NAME, DontEnum);
+    FOR_EACH_WASM_CONSTRUCTOR_PROPERTY(SET_UP_WASM_CONSTRUCTOR_PROPERTY)
+
+#define REGISTER_WASM_CONSTRUCTOR_PROPERTY(NAME, ...) \
+    putDirectWithoutTransition(vm, Identifier::fromString(globalObject->globalExec(), #NAME), constructor ## NAME, DontEnum);
+    FOR_EACH_WASM_CONSTRUCTOR_PROPERTY(REGISTER_WASM_CONSTRUCTOR_PROPERTY)
+
+#define REGISTER_WASM_FUNCTION_PROPERTY(NAME, LENGTH) \
+    putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, #NAME), LENGTH, wasmObjectFunc ## NAME, NoIntrinsic, DontEnum);
+    FOR_EACH_WASM_FUNCTION_PROPERTY(REGISTER_WASM_FUNCTION_PROPERTY)
+}
+
+WebAssemblyObject::WebAssemblyObject(VM& vm, Structure* structure)
+    : JSNonFinalObject(vm, structure)
+{
+}
+
+// ------------------------------ Constructors -----------------------------
+
+    
+// ------------------------------ Functions --------------------------------
+
+EncodedJSValue JSC_HOST_CALL wasmObjectFuncvalidate(ExecState* state)
+{
+    VM& vm = state->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+    return JSValue::encode(throwException(state, scope, createError(state, ASCIILiteral("WebAssembly doesn't yet implement the validate function property"))));
+}
+
+EncodedJSValue JSC_HOST_CALL wasmObjectFunccompile(ExecState* state)
+{
+    VM& vm = state->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+    return JSValue::encode(throwException(state, scope, createError(state, ASCIILiteral("WebAssembly doesn't yet implement the compile function property"))));
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/wasm/WebAssemblyObject.h b/Source/JavaScriptCore/wasm/WebAssemblyObject.h
new file mode 100644 (file)
index 0000000..5596341
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class WebAssemblyObject : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+
+    static WebAssemblyObject* create(VM&, JSGlobalObject*, Structure*);
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
+
+    DECLARE_INFO;
+
+protected:
+    void finishCreation(VM&, JSGlobalObject*);
+
+private:
+    WebAssemblyObject(VM&, Structure*);
+};
+
+} // namespace JSC
index 43330a6..0cd54a8 100644 (file)
@@ -1,3 +1,21 @@
+2016-10-17  JF Bastien  <jfbastien@apple.com>
+
+        WebAssembly JS API: implement basic stub
+
+        Implement the global WebAssembly JavaScript object, and its constructor +
+        function properties as described in:
+          https://github.com/WebAssembly/design/blob/master/JS.md
+
+        These don't do anything at the moment, the parent bug will take care of adding
+        more functionality and associated tests.
+
+        WebAssembly JS API: implement basic stub
+        https://bugs.webkit.org/show_bug.cgi?id=163404
+
+        Reviewed by Keith Miller.
+
+        * Scripts/run-jsc-stress-tests: use the new JSC option which exposes the WebAssembly object.
+
 2016-10-17  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         resolve-ChangeLogs: Specify --no-page to git diff
index 0f68ffd..02a090d 100755 (executable)
@@ -1160,7 +1160,7 @@ def runWebAssembly
     modules = Dir[WASMTESTS_PATH + "*.js"].map { |f| File.basename(f) }
     prepareExtraAbsoluteFiles(WASMTESTS_PATH, ["wasm.json"])
     prepareExtraRelativeFiles(modules.map { |f| "../" + f }, $collection)
-    run("default-wasm", "-m")
+    run("default-wasm", "-m", "--useWebAssembly=1")
 end
 
 def runChakra(mode, exception, baselineFile, extraFiles)