WebAssembly: support name section
authorjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 May 2017 18:15:17 +0000 (18:15 +0000)
committerjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 May 2017 18:15:17 +0000 (18:15 +0000)
JSTests:

https://bugs.webkit.org/show_bug.cgi?id=171263

Reviewed by Keith Miller.

* wasm/function-tests/nameSection.js: Added.
(const.compile):
* wasm/function-tests/nameSection.wasm: Added.
* wasm/function-tests/stack-trace.js: Update format

Source/JavaScriptCore:

https://bugs.webkit.org/show_bug.cgi?id=171263

Reviewed by Keith Miller.

The name section is an optional custom section in the WebAssembly
spec. At least when debugging, developers expect to be able to use
this section to obtain intelligible stack traces, otherwise we
just number the wasm functions which is somewhat painful.

This patch parses this section, dropping its content eagerly on
error, and if there is a name section then backtraces use their
value instead of numbers. Otherwise we stick to numbers as before.

Note that the format of name sections changed in mid-February:
  https://github.com/WebAssembly/design/pull/984
And binaryen was only updated in early March:
  https://github.com/WebAssembly/binaryen/pull/933

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* interpreter/Interpreter.cpp:
(JSC::GetStackTraceFunctor::operator()):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::Frame::functionName):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::wasmFunctionIndexOrName):
* runtime/StackFrame.cpp:
(JSC::StackFrame::functionName):
* runtime/StackFrame.h:
(JSC::StackFrame::StackFrame):
(JSC::StackFrame::wasm):
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmCallee.cpp:
(JSC::Wasm::Callee::Callee):
* wasm/WasmCallee.h:
(JSC::Wasm::Callee::create):
(JSC::Wasm::Callee::indexOrName):
* wasm/WasmFormat.cpp:
(JSC::Wasm::makeString):
* wasm/WasmFormat.h:
(JSC::Wasm::isValidExternalKind):
(JSC::Wasm::isValidNameType):
(JSC::Wasm::NameSection::get):
* wasm/WasmIndexOrName.cpp: Copied from Source/JavaScriptCore/wasm/WasmCallee.cpp.
(JSC::Wasm::IndexOrName::IndexOrName):
(JSC::Wasm::makeString):
* wasm/WasmIndexOrName.h: Copied from Source/JavaScriptCore/wasm/WasmFormat.cpp.
* wasm/WasmModuleInformation.h:
* wasm/WasmModuleParser.cpp:
* wasm/WasmName.h: Copied from Source/JavaScriptCore/wasm/WasmCallee.cpp.
* wasm/WasmNameSectionParser.cpp: Added.
* wasm/WasmNameSectionParser.h: Copied from Source/JavaScriptCore/wasm/WasmCallee.cpp.
(JSC::Wasm::NameSectionParser::NameSectionParser):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
* wasm/WasmParser.h:
(JSC::Wasm::Parser<SuccessType>::consumeUTF8String):

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

26 files changed:
JSTests/ChangeLog
JSTests/wasm/function-tests/nameSection.js [new file with mode: 0644]
JSTests/wasm/function-tests/nameSection.wasm [new file with mode: 0644]
JSTests/wasm/function-tests/stack-trace.js
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/interpreter/StackVisitor.cpp
Source/JavaScriptCore/interpreter/StackVisitor.h
Source/JavaScriptCore/runtime/StackFrame.cpp
Source/JavaScriptCore/runtime/StackFrame.h
Source/JavaScriptCore/wasm/WasmBBQPlanInlines.h
Source/JavaScriptCore/wasm/WasmCallee.cpp
Source/JavaScriptCore/wasm/WasmCallee.h
Source/JavaScriptCore/wasm/WasmFormat.cpp
Source/JavaScriptCore/wasm/WasmFormat.h
Source/JavaScriptCore/wasm/WasmIndexOrName.cpp [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmIndexOrName.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmModuleInformation.h
Source/JavaScriptCore/wasm/WasmModuleParser.cpp
Source/JavaScriptCore/wasm/WasmName.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmNameSectionParser.cpp [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmNameSectionParser.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmOMGPlan.cpp
Source/JavaScriptCore/wasm/WasmParser.h

index 860e829..537b159 100644 (file)
@@ -1,3 +1,15 @@
+2017-05-10  JF Bastien  <jfbastien@apple.com>
+
+        WebAssembly: support name section
+        https://bugs.webkit.org/show_bug.cgi?id=171263
+
+        Reviewed by Keith Miller.
+
+        * wasm/function-tests/nameSection.js: Added.
+        (const.compile):
+        * wasm/function-tests/nameSection.wasm: Added.
+        * wasm/function-tests/stack-trace.js: Update format
+
 2017-05-10  Filip Pizlo  <fpizlo@apple.com>
 
         Null pointer dereference in WTF::RefPtr<WTF::StringImpl>::operator!() under slow_path_get_direct_pname
diff --git a/JSTests/wasm/function-tests/nameSection.js b/JSTests/wasm/function-tests/nameSection.js
new file mode 100644 (file)
index 0000000..ba5419e
--- /dev/null
@@ -0,0 +1,72 @@
+import * as assert from '../assert.js'
+
+/*
+This test loads a WebAssembly file compiled by Emscripten with:
+  ./emsdk-portable/emscripten/incoming/em++ ./nameSection.cc -O2 -g4 -s WASM=1 -o nameSection.js -s EXPORTED_FUNCTIONS="['_parrot']"
+
+From the following C++ source file:
+  extern "C" {
+  int silly(int);
+  __attribute__((noinline)) int eggs(int i) { return silly(i); }
+  __attribute__((noinline)) int bacon(int i) { return eggs(i); }
+  __attribute__((noinline)) int spam(int i) { return bacon(i); }
+  __attribute__((noinline)) int parrot(int i) { return spam(i); }
+  }
+*/
+
+const verbose = false;
+const wasmFile = 'nameSection.wasm';
+
+const compile = (location, importObject = {}) => {
+    if (verbose)
+        print(`Processing ${location}`);
+    let buf = typeof readbuffer !== "undefined"? readbuffer(location) : read(location, 'binary');
+    if (verbose)
+        print(`  Size: ${buf.byteLength}`);
+
+    let t0 = Date.now();
+    let module = new WebAssembly.Module(buf);
+    let t1 = Date.now();
+    if (verbose)
+        print(`new WebAssembly.Module(buf) took ${t1-t0} ms.`);
+
+    if (verbose)
+        print(`Creating fake import object with ${WebAssembly.Module.imports(module).length} imports`);
+    for (let imp of WebAssembly.Module.imports(module)) {
+        if (typeof importObject[imp.module] === "undefined")
+            importObject[imp.module] = {};
+        if (typeof importObject[imp.module][imp.name] === "undefined") {
+            switch (imp.kind) {
+            case "function": importObject[imp.module][imp.name] = () => {}; break;
+            case "table": importObject[imp.module][imp.name] = new WebAssembly.Table({ initial: 6, maximum: 6, element: "anyfunc" }); break;
+            case "memory": importObject[imp.module][imp.name] = new WebAssembly.Memory({ initial: 16777216 / (64 * 1024), maximum: 16777216 / (64 * 1024) }); break;
+            case "global": importObject[imp.module][imp.name] = 0; break;
+            }
+        }
+
+    }
+
+    let t2 = Date.now();
+    let instance = new WebAssembly.Instance(module, importObject);
+    let t3 = Date.now();
+    if (verbose)
+        print(`new WebAssembly.Module(buf) took ${t3-t2} ms.`);
+
+    return instance;
+};
+
+let stacktrace;
+const importObject = { env: { _silly: i => { stacktrace = (new Error).stack; return i + 42; } } };
+const instance = compile(wasmFile, importObject);
+const result = instance.exports._parrot(1);
+assert.eq(result, 1 + 42);
+
+assert.truthy(stacktrace);
+stacktrace = stacktrace.split("\n");
+assert.falsy(stacktrace[0].indexOf("_silly") === -1);
+assert.eq(stacktrace[1], "wasm function@[wasm code]"); // the wasm->js stub
+assert.eq(stacktrace[2], "wasm function: _eggs@[wasm code]");
+assert.eq(stacktrace[3], "wasm function: _bacon@[wasm code]");
+assert.eq(stacktrace[4], "wasm function: _spam@[wasm code]");
+assert.eq(stacktrace[5], "wasm function: _parrot@[wasm code]");
+assert.eq(stacktrace[6], "wasm function@[wasm code]"); // wasm entry
diff --git a/JSTests/wasm/function-tests/nameSection.wasm b/JSTests/wasm/function-tests/nameSection.wasm
new file mode 100644 (file)
index 0000000..24b22b1
Binary files /dev/null and b/JSTests/wasm/function-tests/nameSection.wasm differ
index fa6e7ed..d70b3ea 100644 (file)
@@ -47,10 +47,10 @@ for (let i = 0; i < 10000; ++i) {
     stacktrace = stacktrace.split("\n");
     assert(stacktrace[0].indexOf("imp") !== -1); // the arrow function import named "imp".
     assert(stacktrace[1] === "wasm function@[wasm code]"); // the wasm->js stub
-    assert(stacktrace[2] === "wasm function index: 4@[wasm code]");
-    assert(stacktrace[3] === "wasm function index: 2@[wasm code]");
-    assert(stacktrace[4] === "wasm function index: 3@[wasm code]");
-    assert(stacktrace[5] === "wasm function index: 1@[wasm code]");
+    assert(stacktrace[2] === "wasm function: 4@[wasm code]");
+    assert(stacktrace[3] === "wasm function: 2@[wasm code]");
+    assert(stacktrace[4] === "wasm function: 3@[wasm code]");
+    assert(stacktrace[5] === "wasm function: 1@[wasm code]");
     assert(stacktrace[6] === "wasm function@[wasm code]"); // wasm entry
 
     stacktrace = null;
index 691c0e5..2f0669e 100644 (file)
@@ -951,12 +951,14 @@ set(JavaScriptCore_SOURCES
     wasm/WasmContext.cpp
     wasm/WasmFaultSignalHandler.cpp
     wasm/WasmFormat.cpp
+    wasm/WasmIndexOrName.cpp
     wasm/WasmMachineThreads.cpp
     wasm/WasmMemory.cpp
     wasm/WasmMemoryInformation.cpp
     wasm/WasmModule.cpp
     wasm/WasmModuleInformation.cpp
     wasm/WasmModuleParser.cpp
+    wasm/WasmNameSectionParser.cpp
     wasm/WasmOMGPlan.cpp
     wasm/WasmOpcodeOrigin.cpp
     wasm/WasmPageCount.cpp
index d1c9f50..46f130f 100644 (file)
@@ -1,3 +1,67 @@
+2017-05-10  JF Bastien  <jfbastien@apple.com>
+
+        WebAssembly: support name section
+
+        https://bugs.webkit.org/show_bug.cgi?id=171263
+
+        Reviewed by Keith Miller.
+
+        The name section is an optional custom section in the WebAssembly
+        spec. At least when debugging, developers expect to be able to use
+        this section to obtain intelligible stack traces, otherwise we
+        just number the wasm functions which is somewhat painful.
+
+        This patch parses this section, dropping its content eagerly on
+        error, and if there is a name section then backtraces use their
+        value instead of numbers. Otherwise we stick to numbers as before.
+
+        Note that the format of name sections changed in mid-February:
+          https://github.com/WebAssembly/design/pull/984
+        And binaryen was only updated in early March:
+          https://github.com/WebAssembly/binaryen/pull/933
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * interpreter/Interpreter.cpp:
+        (JSC::GetStackTraceFunctor::operator()):
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::readNonInlinedFrame):
+        (JSC::StackVisitor::Frame::functionName):
+        * interpreter/StackVisitor.h:
+        (JSC::StackVisitor::Frame::wasmFunctionIndexOrName):
+        * runtime/StackFrame.cpp:
+        (JSC::StackFrame::functionName):
+        * runtime/StackFrame.h:
+        (JSC::StackFrame::StackFrame):
+        (JSC::StackFrame::wasm):
+        * wasm/WasmBBQPlanInlines.h:
+        (JSC::Wasm::BBQPlan::initializeCallees):
+        * wasm/WasmCallee.cpp:
+        (JSC::Wasm::Callee::Callee):
+        * wasm/WasmCallee.h:
+        (JSC::Wasm::Callee::create):
+        (JSC::Wasm::Callee::indexOrName):
+        * wasm/WasmFormat.cpp:
+        (JSC::Wasm::makeString):
+        * wasm/WasmFormat.h:
+        (JSC::Wasm::isValidExternalKind):
+        (JSC::Wasm::isValidNameType):
+        (JSC::Wasm::NameSection::get):
+        * wasm/WasmIndexOrName.cpp: Copied from Source/JavaScriptCore/wasm/WasmCallee.cpp.
+        (JSC::Wasm::IndexOrName::IndexOrName):
+        (JSC::Wasm::makeString):
+        * wasm/WasmIndexOrName.h: Copied from Source/JavaScriptCore/wasm/WasmFormat.cpp.
+        * wasm/WasmModuleInformation.h:
+        * wasm/WasmModuleParser.cpp:
+        * wasm/WasmName.h: Copied from Source/JavaScriptCore/wasm/WasmCallee.cpp.
+        * wasm/WasmNameSectionParser.cpp: Added.
+        * wasm/WasmNameSectionParser.h: Copied from Source/JavaScriptCore/wasm/WasmCallee.cpp.
+        (JSC::Wasm::NameSectionParser::NameSectionParser):
+        * wasm/WasmOMGPlan.cpp:
+        (JSC::Wasm::OMGPlan::work):
+        * wasm/WasmParser.h:
+        (JSC::Wasm::Parser<SuccessType>::consumeUTF8String):
+
 2017-05-10  Filip Pizlo  <fpizlo@apple.com>
 
         Null pointer dereference in WTF::RefPtr<WTF::StringImpl>::operator!() under slow_path_get_direct_pname
index c5389fd..54443c8 100644 (file)
                AD4937D41DDD27DE0077C807 /* WebAssemblyFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4937CA1DDD27340077C807 /* WebAssemblyFunction.h */; };
                AD4B1DF91DF244E20071AE32 /* WasmBinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD4B1DF71DF244D70071AE32 /* WasmBinding.cpp */; };
                AD4B1DFA1DF244E20071AE32 /* WasmBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4B1DF81DF244D70071AE32 /* WasmBinding.h */; };
+               AD5B416F1EBAFB77008EFA43 /* WasmName.h in Headers */ = {isa = PBXBuildFile; fileRef = AD5B416E1EBAFB65008EFA43 /* WasmName.h */; settings = {ATTRIBUTES = (Private, ); }; };
                AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = AD7438BF1E04579200FD0C2A /* WasmSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
                AD7438C11E0457AA00FD0C2A /* WasmSignature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */; };
                AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               AD8FF3971EB5BDA80087FF82 /* WasmIndexOrName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD8FF3961EB5BD850087FF82 /* WasmIndexOrName.cpp */; };
+               AD8FF3981EB5BDB20087FF82 /* WasmIndexOrName.h in Headers */ = {isa = PBXBuildFile; fileRef = AD8FF3951EB5BD850087FF82 /* WasmIndexOrName.h */; settings = {ATTRIBUTES = (Private, ); }; };
                AD9E852F1E8A0C7C008DE39E /* JSWebAssemblyCodeBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = AD9E852E1E8A0C6E008DE39E /* JSWebAssemblyCodeBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
                ADB6F67D1E15D7600082F384 /* WasmPageCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADB6F67C1E15D7500082F384 /* WasmPageCount.cpp */; };
                ADBC54D41DF8EA2B005BF738 /* WebAssemblyToJSCallee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADBC54D21DF8EA00005BF738 /* WebAssemblyToJSCallee.cpp */; };
                ADBC54D51DF8EA2B005BF738 /* WebAssemblyToJSCallee.h in Headers */ = {isa = PBXBuildFile; fileRef = ADBC54D31DF8EA00005BF738 /* WebAssemblyToJSCallee.h */; };
+               ADD8FA451EB3078E00DF542F /* WasmNameSectionParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADD8FA441EB3077100DF542F /* WasmNameSectionParser.cpp */; };
+               ADD8FA461EB3079700DF542F /* WasmNameSectionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = ADD8FA431EB3077100DF542F /* WasmNameSectionParser.h */; };
                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 */; };
                ADE802981E08F1DE0058DE78 /* JSWebAssemblyLinkError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADE802931E08F1C90058DE78 /* JSWebAssemblyLinkError.cpp */; };
                AD4937CA1DDD27340077C807 /* WebAssemblyFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyFunction.h; path = js/WebAssemblyFunction.h; sourceTree = "<group>"; };
                AD4B1DF71DF244D70071AE32 /* WasmBinding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmBinding.cpp; sourceTree = "<group>"; };
                AD4B1DF81DF244D70071AE32 /* WasmBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmBinding.h; sourceTree = "<group>"; };
+               AD5B416E1EBAFB65008EFA43 /* WasmName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmName.h; sourceTree = "<group>"; };
                AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmSignature.cpp; sourceTree = "<group>"; };
                AD7438BF1E04579200FD0C2A /* WasmSignature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmSignature.h; sourceTree = "<group>"; };
                AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = "<group>"; };
+               AD8FF3951EB5BD850087FF82 /* WasmIndexOrName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmIndexOrName.h; sourceTree = "<group>"; };
+               AD8FF3961EB5BD850087FF82 /* WasmIndexOrName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmIndexOrName.cpp; sourceTree = "<group>"; };
                AD9E852E1E8A0C6E008DE39E /* JSWebAssemblyCodeBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSWebAssemblyCodeBlock.h; path = js/JSWebAssemblyCodeBlock.h; sourceTree = "<group>"; };
                ADB6F67C1E15D7500082F384 /* WasmPageCount.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmPageCount.cpp; sourceTree = "<group>"; };
                ADBC54D21DF8EA00005BF738 /* WebAssemblyToJSCallee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyToJSCallee.cpp; path = js/WebAssemblyToJSCallee.cpp; sourceTree = "<group>"; };
                ADBC54D31DF8EA00005BF738 /* WebAssemblyToJSCallee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyToJSCallee.h; path = js/WebAssemblyToJSCallee.h; sourceTree = "<group>"; };
+               ADD8FA431EB3077100DF542F /* WasmNameSectionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmNameSectionParser.h; sourceTree = "<group>"; };
+               ADD8FA441EB3077100DF542F /* WasmNameSectionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmNameSectionParser.cpp; sourceTree = "<group>"; };
                ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueRootSet.h; sourceTree = "<group>"; };
                ADE802931E08F1C90058DE78 /* JSWebAssemblyLinkError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSWebAssemblyLinkError.cpp; path = js/JSWebAssemblyLinkError.cpp; sourceTree = "<group>"; };
                ADE802941E08F1C90058DE78 /* JSWebAssemblyLinkError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSWebAssemblyLinkError.h; path = js/JSWebAssemblyLinkError.h; sourceTree = "<group>"; };
                                AD412B311E7B2E8A008AF157 /* WasmContext.cpp */,
                                AD412B321E7B2E8A008AF157 /* WasmContext.h */,
                                79DAE2791E03C82200B526AA /* WasmExceptionType.h */,
+                               5381B9361E60E9660090F794 /* WasmFaultSignalHandler.cpp */,
+                               5381B9381E60E97D0090F794 /* WasmFaultSignalHandler.h */,
                                AD2FCC321DC4045300B3E736 /* WasmFormat.cpp */,
                                7BC547D21B69599B00959B58 /* WasmFormat.h */,
                                53F40E8A1D5901BB0099A1B6 /* WasmFunctionParser.h */,
+                               AD8FF3961EB5BD850087FF82 /* WasmIndexOrName.cpp */,
+                               AD8FF3951EB5BD850087FF82 /* WasmIndexOrName.h */,
                                53E9E0A91EAE83DE00FEE251 /* WasmMachineThreads.cpp */,
                                53E9E0AA1EAE83DE00FEE251 /* WasmMachineThreads.h */,
-                               790081361E95A8EC0052D7CD /* WasmModule.cpp */,
-                               790081371E95A8EC0052D7CD /* WasmModule.h */,
                                535557151D9DFA32006D583B /* WasmMemory.cpp */,
                                535557131D9D9EA5006D583B /* WasmMemory.h */,
                                79B759711DFA4C600052174C /* WasmMemoryInformation.cpp */,
                                79B759721DFA4C600052174C /* WasmMemoryInformation.h */,
+                               790081361E95A8EC0052D7CD /* WasmModule.cpp */,
+                               790081371E95A8EC0052D7CD /* WasmModule.h */,
                                53E777E11E92E265007CBEC4 /* WasmModuleInformation.cpp */,
                                53E777E21E92E265007CBEC4 /* WasmModuleInformation.h */,
                                53F40E961D5A7BEC0099A1B6 /* WasmModuleParser.cpp */,
                                53F40E941D5A7AEF0099A1B6 /* WasmModuleParser.h */,
+                               AD5B416E1EBAFB65008EFA43 /* WasmName.h */,
+                               ADD8FA441EB3077100DF542F /* WasmNameSectionParser.cpp */,
+                               ADD8FA431EB3077100DF542F /* WasmNameSectionParser.h */,
                                5311BD481EA581E500525281 /* WasmOMGPlan.cpp */,
                                5311BD491EA581E500525281 /* WasmOMGPlan.h */,
-                               ADB6F67C1E15D7500082F384 /* WasmPageCount.cpp */,
-                               5381B9361E60E9660090F794 /* WasmFaultSignalHandler.cpp */,
-                               5381B9381E60E97D0090F794 /* WasmFaultSignalHandler.h */,
                                53C6FEF01E8AFE0C00B18425 /* WasmOpcodeOrigin.cpp */,
                                53C6FEEE1E8ADFA900B18425 /* WasmOpcodeOrigin.h */,
+                               ADB6F67C1E15D7500082F384 /* WasmPageCount.cpp */,
                                79B759731DFA4C600052174C /* WasmPageCount.h */,
                                53F40E8C1D5901F20099A1B6 /* WasmParser.h */,
                                531374BE1D5CE95000AF7A0B /* WasmPlan.cpp */,
                                0F6183311C45BF070072450B /* AirLowerMacros.h in Headers */,
                                0F40E4A71C497F7400A577FA /* AirOpcode.h in Headers */,
                                0F40E4A81C497F7400A577FA /* AirOpcodeGenerated.h in Headers */,
+                               AD8FF3981EB5BDB20087FF82 /* WasmIndexOrName.h in Headers */,
                                0F40E4A91C497F7400A577FA /* AirOpcodeUtils.h in Headers */,
                                0FB387901BFBC44D00E3AB1E /* AirOptimizeBlockOrder.h in Headers */,
                                0F9CABC91DB54A7A0008E83B /* AirPadInterference.h in Headers */,
                                0FEC85241BDACDAC0080FF74 /* B3Origin.h in Headers */,
                                0F4C91661C29F4F2004341A6 /* B3OriginDump.h in Headers */,
                                0FEC85261BDACDAC0080FF74 /* B3PatchpointSpecial.h in Headers */,
+                               ADD8FA461EB3079700DF542F /* WasmNameSectionParser.h in Headers */,
                                0FEC85281BDACDAC0080FF74 /* B3PatchpointValue.h in Headers */,
                                799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */,
                                0FEC852A1BDACDAC0080FF74 /* B3PhaseScope.h in Headers */,
                                86EC9DD11328DF82002B2AD7 /* DFGRegisterBank.h in Headers */,
                                79FC8A081E32E9F000D88F0E /* DFGRegisteredStructure.h in Headers */,
                                7980C16D1E3A940E00B71615 /* DFGRegisteredStructureSet.h in Headers */,
+                               AD5B416F1EBAFB77008EFA43 /* WasmName.h in Headers */,
                                0F2FCCFC18A60070001A27F8 /* DFGSafepoint.h in Headers */,
                                A77A424317A0BBFD00A8DB81 /* DFGSafeToExecute.h in Headers */,
                                A741017F179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h in Headers */,
                                0F6C73501AC9F99F00BE1682 /* VariableWriteFireDetail.cpp in Sources */,
                                0FE0502C1AA9095600D33B33 /* VarOffset.cpp in Sources */,
                                0F20C2591A8013AB00DA3229 /* VirtualRegister.cpp in Sources */,
+                               AD8FF3971EB5BDA80087FF82 /* WasmIndexOrName.cpp in Sources */,
                                0F952AA21DF7860D00E06FBD /* VisitRaceKey.cpp in Sources */,
                                E18E3A590DF9278C00D90B34 /* VM.cpp in Sources */,
                                FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */,
                                86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
                                86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
                                86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
+                               ADD8FA451EB3078E00DF542F /* WasmNameSectionParser.cpp in Sources */,
                                321D9E4CFB67423A97F191A7 /* ModuleNamespaceAccessCase.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
index fa61eb9..205692c 100644 (file)
@@ -480,8 +480,7 @@ public:
 
         if (m_remainingCapacityForFrameCapture) {
             if (visitor->isWasmFrame()) {
-                std::optional<unsigned> wasmFunctionIndex = visitor->wasmFunctionIndex();
-                m_results.append(StackFrame::wasm(wasmFunctionIndex ? *wasmFunctionIndex : StackFrame::invalidWasmIndex));
+                m_results.append(StackFrame::wasm(visitor->wasmFunctionIndexOrName()));
             } else if (!!visitor->codeBlock() && !visitor->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) {
                 m_results.append(
                     StackFrame(m_vm, visitor->callee().asCell(), visitor->codeBlock(), visitor->bytecodeOffset()));
index 52eafc9..1d64d6e 100644 (file)
@@ -32,6 +32,7 @@
 #include "Interpreter.h"
 #include "JSCInlines.h"
 #include "WasmCallee.h"
+#include "WasmIndexOrName.h"
 #include <wtf/text/StringBuilder.h>
 
 namespace JSC {
@@ -166,7 +167,7 @@ void StackVisitor::readNonInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOri
 #if ENABLE(WEBASSEMBLY)
         CalleeBits bits = callFrame->callee();
         if (bits.isWasm())
-            m_frame.m_wasmFunctionIndex = bits.asWasmCallee()->index();
+            m_frame.m_wasmFunctionIndexOrName = bits.asWasmCallee()->indexOrName();
 #endif
     } else {
         m_frame.m_codeBlock = callFrame->codeBlock();
@@ -283,10 +284,10 @@ String StackVisitor::Frame::functionName() const
 
     switch (codeType()) {
     case CodeType::Wasm:
-        if (m_wasmFunctionIndex)
-            traceLine = makeString("wasm function index: ", String::number(*m_wasmFunctionIndex));
+        if (m_wasmFunctionIndexOrName.isEmpty())
+            traceLine = makeString("wasm function");
         else
-            traceLine = ASCIILiteral("wasm function");
+            traceLine = makeString("wasm function: ", makeString(m_wasmFunctionIndexOrName));
         break;
     case CodeType::Eval:
         traceLine = ASCIILiteral("eval code");
index 4510370..aa0b332 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "CalleeBits.h"
 #include "VMEntryRecord.h"
+#include "WasmIndexOrName.h"
 #include <functional>
 #include <wtf/Indenter.h>
 #include <wtf/text/WTFString.h>
@@ -77,10 +78,10 @@ public:
         bool isNativeFrame() const { return !codeBlock() && !isWasmFrame(); }
         bool isInlinedFrame() const { return !!inlineCallFrame(); }
         bool isWasmFrame() const;
-        std::optional<unsigned> const wasmFunctionIndex()
+        Wasm::IndexOrName const wasmFunctionIndexOrName()
         {
             ASSERT(isWasmFrame());
-            return m_wasmFunctionIndex;
+            return m_wasmFunctionIndexOrName;
         }
 
         JS_EXPORT_PRIVATE String functionName() const;
@@ -121,7 +122,7 @@ public:
         size_t m_index;
         size_t m_argumentCountIncludingThis;
         unsigned m_bytecodeOffset;
-        std::optional<unsigned> m_wasmFunctionIndex;
+        Wasm::IndexOrName m_wasmFunctionIndexOrName;
         bool m_callerIsVMEntryFrame : 1;
         bool m_isWasmFrame : 1;
 
index c6d23d9..836ea0c 100644 (file)
@@ -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
@@ -58,9 +58,9 @@ String StackFrame::sourceURL() const
 String StackFrame::functionName(VM& vm) const
 {
     if (m_isWasmFrame) {
-        if (m_wasmFunctionIndex == invalidWasmIndex)
+        if (m_wasmFunctionIndexOrName.isEmpty())
             return ASCIILiteral("wasm function");
-        return makeString("wasm function index: ", String::number(m_wasmFunctionIndex));
+        return makeString("wasm function: ", makeString(m_wasmFunctionIndexOrName));
     }
 
     if (m_codeBlock) {
index f83184d..4890878 100644 (file)
@@ -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
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "Strong.h"
+#include "WasmIndexOrName.h"
 #include <limits.h>
 
 namespace JSC {
@@ -35,7 +36,9 @@ class JSObject;
 
 class StackFrame {
 public:
-    StackFrame() = default;
+    StackFrame()
+        : m_bytecodeOffset(UINT_MAX)
+    { }
 
     StackFrame(VM& vm, JSCell* callee)
         : m_callee(vm, callee)
@@ -48,12 +51,11 @@ public:
         , m_bytecodeOffset(bytecodeOffset)
     { }
 
-    static constexpr unsigned invalidWasmIndex = UINT_MAX;
-    static StackFrame wasm(unsigned index)
+    static StackFrame wasm(Wasm::IndexOrName indexOrName)
     {
         StackFrame result;
         result.m_isWasmFrame = true;
-        result.m_wasmFunctionIndex = index;
+        result.m_wasmFunctionIndexOrName = indexOrName;
         return result;
     }
 
@@ -78,7 +80,7 @@ private:
     Strong<CodeBlock> m_codeBlock { };
     union {
         unsigned m_bytecodeOffset;
-        unsigned m_wasmFunctionIndex;
+        Wasm::IndexOrName m_wasmFunctionIndexOrName;
     };
     bool m_isWasmFrame { false };
 };
index f5a6523..af18143 100644 (file)
@@ -43,7 +43,8 @@ void BBQPlan::initializeCallees(const Functor& callback)
         Ref<Wasm::Callee> jsEntrypointCallee = Wasm::Callee::create(WTFMove(function->jsToWasmEntrypoint));
         MacroAssembler::repatchPointer(function->jsToWasmCalleeMoveLocation, CalleeBits::boxWasm(jsEntrypointCallee.ptr()));
 
-        Ref<Wasm::Callee> wasmEntrypointCallee = Wasm::Callee::create(WTFMove(function->wasmEntrypoint), internalFunctionIndex + m_moduleInformation->importFunctionCount());
+        size_t functionIndexSpace = internalFunctionIndex + m_moduleInformation->importFunctionCount();
+        Ref<Wasm::Callee> wasmEntrypointCallee = Wasm::Callee::create(WTFMove(function->wasmEntrypoint), functionIndexSpace, m_moduleInformation->nameSection.get(functionIndexSpace));
         MacroAssembler::repatchPointer(function->wasmCalleeMoveLocation, CalleeBits::boxWasm(wasmEntrypointCallee.ptr()));
 
         callback(internalFunctionIndex, WTFMove(jsEntrypointCallee), WTFMove(wasmEntrypointCallee));
index 6ec3ed1..9e83edf 100644 (file)
 
 namespace JSC { namespace Wasm {
 
-Callee::Callee(Entrypoint&& entrypoint, unsigned index)
+Callee::Callee(Entrypoint&& entrypoint)
     : m_entrypoint(WTFMove(entrypoint))
-    , m_index(index)
+{
+    registerCode(m_entrypoint.compilation->codeRef().executableMemory()->start(), m_entrypoint.compilation->codeRef().executableMemory()->end());
+}
+
+Callee::Callee(Entrypoint&& entrypoint, size_t index, const Name* name)
+    : m_entrypoint(WTFMove(entrypoint))
+    , m_indexOrName(index, name)
 {
     registerCode(m_entrypoint.compilation->codeRef().executableMemory()->start(), m_entrypoint.compilation->codeRef().executableMemory()->end());
 }
index 9db10c3..23c1ae5 100644 (file)
@@ -30,6 +30,7 @@
 #include "B3Compilation.h"
 #include "RegisterAtOffsetList.h"
 #include "WasmFormat.h"
+#include "WasmIndexOrName.h"
 #include <wtf/ThreadSafeRefCounted.h>
 
 namespace JSC { namespace Wasm {
@@ -37,31 +38,29 @@ namespace JSC { namespace Wasm {
 class Callee : public ThreadSafeRefCounted<Callee> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
+    static Ref<Callee> create(Wasm::Entrypoint&& entrypoint)
+    {
+        Callee* callee = new Callee(WTFMove(entrypoint));
+        return adoptRef(*callee);
+    }
 
-    // We use this when we're the JS entrypoint, we don't ascribe an index to those.
-    static constexpr unsigned invalidCalleeIndex = UINT_MAX;
-
-    static Ref<Callee> create(Wasm::Entrypoint&& entrypoint, unsigned index = invalidCalleeIndex)
+    static Ref<Callee> create(Wasm::Entrypoint&& entrypoint, size_t index, const Name* name)
     {
-        Callee* callee = new Callee(WTFMove(entrypoint), index);
+        Callee* callee = new Callee(WTFMove(entrypoint), index, name);
         return adoptRef(*callee);
     }
 
     void* entrypoint() const { return m_entrypoint.compilation->code().executableAddress(); }
 
     RegisterAtOffsetList* calleeSaveRegisters() { return &m_entrypoint.calleeSaveRegisters; }
-    std::optional<unsigned> index() const
-    {
-        if (m_index == invalidCalleeIndex)
-            return std::nullopt;
-        return m_index;
-    }
+    IndexOrName indexOrName() const { return m_indexOrName; }
 
 private:
-    JS_EXPORT_PRIVATE Callee(Wasm::Entrypoint&&, unsigned index);
+    JS_EXPORT_PRIVATE Callee(Wasm::Entrypoint&&);
+    JS_EXPORT_PRIVATE Callee(Wasm::Entrypoint&&, size_t, const Name*);
 
     Wasm::Entrypoint m_entrypoint;
-    unsigned m_index;
+    IndexOrName m_indexOrName;
 };
 
 } } // namespace JSC::Wasm
index e260601..e06e776 100644 (file)
@@ -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
@@ -55,7 +55,7 @@ Segment::Ptr Segment::adoptPtr(Segment* segment)
     return Ptr(segment, &Segment::destroy);
 }
 
-String makeString(const Vector<LChar>& characters)
+String makeString(const Name& characters)
 {
     String result = String::fromUTF8(characters);
     ASSERT(result);
index d9eb7b8..29dd287 100644 (file)
@@ -33,6 +33,7 @@
 #include "MacroAssemblerCodeRef.h"
 #include "RegisterAtOffsetList.h"
 #include "WasmMemoryInformation.h"
+#include "WasmName.h"
 #include "WasmOps.h"
 #include "WasmPageCount.h"
 #include "WasmSignature.h"
@@ -74,7 +75,7 @@ enum class ExternalKind : uint8_t {
 };
 
 template<typename Int>
-static bool isValidExternalKind(Int val)
+inline bool isValidExternalKind(Int val)
 {
     switch (val) {
     case static_cast<Int>(ExternalKind::Function):
@@ -82,9 +83,8 @@ static bool isValidExternalKind(Int val)
     case static_cast<Int>(ExternalKind::Memory):
     case static_cast<Int>(ExternalKind::Global):
         return true;
-    default:
-        return false;
     }
+    return false;
 }
 
 static_assert(static_cast<int>(ExternalKind::Function) == 0, "Wasm needs Function to have the value 0");
@@ -105,19 +105,19 @@ inline const char* makeString(ExternalKind kind)
 }
 
 struct Import {
-    const Vector<LChar> module;
-    const Vector<LChar> field;
+    const Name module;
+    const Name field;
     ExternalKind kind;
     unsigned kindIndex; // Index in the vector of the corresponding kind.
 };
 
 struct Export {
-    const Vector<LChar> field;
+    const Name field;
     ExternalKind kind;
     unsigned kindIndex; // Index in the vector of the corresponding kind.
 };
 
-String makeString(const Vector<LChar>& characters);
+String makeString(const Name& characters);
 
 struct Global {
     enum Mutability : uint8_t {
@@ -231,10 +231,34 @@ private:
 };
     
 struct CustomSection {
-    Vector<LChar> name;
+    Name name;
     Vector<uint8_t> payload;
 };
 
+enum class NameType : uint8_t {
+    Function = 1,
+    Local = 2,
+};
+    
+template<typename Int>
+inline bool isValidNameType(Int val)
+{
+    switch (val) {
+    case static_cast<Int>(NameType::Function):
+    case static_cast<Int>(NameType::Local):
+        return true;
+    }
+    return false;
+}
+    
+struct NameSection {
+    Vector<Name> functionNames;
+    const Name* get(size_t functionIndexSpace)
+    {
+        return functionIndexSpace < functionNames.size() ? &functionNames[functionIndexSpace] : nullptr;
+    }
+};
+
 struct UnlinkedWasmToWasmCall {
     CodeLocationNearCall callLocation;
     size_t functionIndexSpace;
diff --git a/Source/JavaScriptCore/wasm/WasmIndexOrName.cpp b/Source/JavaScriptCore/wasm/WasmIndexOrName.cpp
new file mode 100644 (file)
index 0000000..ab96961
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 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
+ * 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 "WasmIndexOrName.h"
+
+namespace JSC { namespace Wasm {
+
+IndexOrName::IndexOrName(Index index, const Name* name)
+{
+    static_assert(sizeof(m_index) == sizeof(m_name), "bit-tagging depends on sizes being equal");
+    static_assert(sizeof(m_index) == sizeof(*this), "bit-tagging depends on object being the size of the union's types");
+
+    if ((index & allTags) || (bitwise_cast<Index>(name) & allTags))
+        *this = IndexOrName();
+    else if (name)
+        m_name = name;
+    else
+        m_index = indexTag | index;
+}
+
+String makeString(const IndexOrName& ion)
+{
+    if (ion.isEmpty())
+        return String();
+    if (ion.isIndex())
+        return String::number(ion.m_index & ~IndexOrName::indexTag);
+    return String(ion.m_name->data(), ion.m_name->size());
+};
+
+} } // namespace JSC::Wasm
diff --git a/Source/JavaScriptCore/wasm/WasmIndexOrName.h b/Source/JavaScriptCore/wasm/WasmIndexOrName.h
new file mode 100644 (file)
index 0000000..d7545fa
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 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
+ * 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 "WasmName.h"
+#include <wtf/StdLibExtras.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC { namespace Wasm {
+
+struct IndexOrName {
+    typedef size_t Index;
+
+    IndexOrName()
+        : m_index(emptyTag)
+    { }
+    IndexOrName(Index, const Name*);
+    bool isEmpty() const { return bitwise_cast<Index>(*this) & emptyTag; }
+    bool isIndex() const { return bitwise_cast<Index>(*this) & indexTag; }
+    bool isName() const { return !(isEmpty() || isName()); }
+
+    friend String makeString(const IndexOrName&);
+
+private:
+    union {
+        Index m_index;
+        const Name* m_name;
+    };
+
+    // Use the top bits as tags. Neither pointers nor the function index space should use them.
+    static constexpr Index indexTag = 1ull << (CHAR_BIT * sizeof(Index) - 1);
+    static constexpr Index emptyTag = 1ull << (CHAR_BIT * sizeof(Index) - 2);
+    static constexpr Index allTags = indexTag | emptyTag;
+};
+
+String makeString(const IndexOrName&);
+
+} } // namespace JSC::Wasm
index 176339a..07b3899 100644 (file)
@@ -74,7 +74,7 @@ struct ModuleInformation : public ThreadSafeRefCounted<ModuleInformation> {
     Vector<Global> globals;
     unsigned firstInternalGlobal { 0 };
     Vector<CustomSection> customSections;
-
+    NameSection nameSection;
 };
 
     
index ee714c1..4cde165 100644 (file)
@@ -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
 
 #include "IdentifierInlines.h"
 #include "JSWebAssemblyTable.h"
-#include "WasmFormat.h"
 #include "WasmMemoryInformation.h"
+#include "WasmNameSectionParser.h"
 #include "WasmOps.h"
 #include "WasmSections.h"
 
-#include <sys/mman.h>
-
 namespace JSC { namespace Wasm {
 
 ALWAYS_INLINE I32InitExpr makeI32InitExpr(uint8_t opcode, uint32_t bits)
@@ -156,8 +154,8 @@ auto ModuleParser::parseImport() -> PartialResult
     for (uint32_t importNumber = 0; importNumber < importCount; ++importNumber) {
         uint32_t moduleLen;
         uint32_t fieldLen;
-        Vector<LChar> moduleString;
-        Vector<LChar> fieldString;
+        Name moduleString;
+        Name fieldString;
         ExternalKind kind;
         unsigned kindIndex { 0 };
 
@@ -368,7 +366,7 @@ auto ModuleParser::parseExport() -> PartialResult
     HashSet<String> exportNames;
     for (uint32_t exportNumber = 0; exportNumber < exportCount; ++exportNumber) {
         uint32_t fieldLen;
-        Vector<LChar> fieldString;
+        Name fieldString;
         ExternalKind kind;
         unsigned kindIndex;
 
@@ -605,7 +603,14 @@ auto ModuleParser::parseCustom(uint32_t sectionLength) -> PartialResult
         WASM_PARSER_FAIL_IF(!parseUInt8(byte), "can't get ", byteNumber, "th data byte from ", customSectionNumber, "th custom section");
         section.payload.uncheckedAppend(byte);
     }
-    
+
+    Name nameName = { 'n', 'a', 'm', 'e' };
+    if (section.name == nameName) {
+        NameSectionParser nameSectionParser(section.payload.begin(), section.payload.size(), m_info);
+        if (auto nameSection = nameSectionParser.parse())
+            m_info->nameSection = WTFMove(*nameSection);
+    }
+
     m_info->customSections.uncheckedAppend(WTFMove(section));
 
     return { };
diff --git a/Source/JavaScriptCore/wasm/WasmName.h b/Source/JavaScriptCore/wasm/WasmName.h
new file mode 100644 (file)
index 0000000..0e42792
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 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
+ * 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 <wtf/Vector.h>
+#include <wtf/text/LChar.h>
+
+namespace JSC {
+
+namespace Wasm {
+
+using Name = Vector<LChar>;
+
+} } // namespace JSC::Wasm
diff --git a/Source/JavaScriptCore/wasm/WasmNameSectionParser.cpp b/Source/JavaScriptCore/wasm/WasmNameSectionParser.cpp
new file mode 100644 (file)
index 0000000..8c04f58
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 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
+ * 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 "WasmNameSectionParser.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "IdentifierInlines.h"
+
+namespace JSC { namespace Wasm {
+
+auto NameSectionParser::parse() -> Result
+{
+    NameSection nameSection;
+    WASM_PARSER_FAIL_IF(!nameSection.functionNames.tryReserveCapacity(m_info.functionIndexSpaceSize()), "can't allocate enough memory for function names");
+    nameSection.functionNames.resize(m_info.functionIndexSpaceSize());
+
+    for (size_t payloadNumber = 0; m_offset < length(); ++payloadNumber) {
+        uint8_t nameType;
+        uint32_t payloadLength;
+        WASM_PARSER_FAIL_IF(!parseUInt7(nameType), "can't get name type for payload ", payloadNumber);
+        WASM_PARSER_FAIL_IF(!isValidNameType(nameType), "name type ", nameType, " is invalid for payload ", payloadNumber);
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(payloadLength), "can't get payload length for payload ", payloadNumber);
+        WASM_PARSER_FAIL_IF(payloadLength > length() - m_offset, "payload length is too big for payload ", payloadNumber);
+        const auto payloadStart = m_offset;
+
+        switch (static_cast<NameType>(nameType)) {
+        case NameType::Function: {
+            uint32_t count;
+            WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get function count for payload ", payloadNumber);
+            for (uint32_t function = 0; function < count; ++function) {
+                uint32_t index;
+                uint32_t nameLen;
+                Name nameString;
+                WASM_PARSER_FAIL_IF(!parseVarUInt32(index), "can't get function ", function, " index for payload ", payloadNumber);
+                WASM_PARSER_FAIL_IF(m_info.functionIndexSpaceSize() <= index, "function ", function, " index ", index, " is larger than function index space ", m_info.functionIndexSpaceSize(), " for payload ", payloadNumber);
+                WASM_PARSER_FAIL_IF(!parseVarUInt32(nameLen), "can't get functions ", function, "'s name length for payload ", payloadNumber);
+                WASM_PARSER_FAIL_IF(!consumeUTF8String(nameString, nameLen), "can't get function ", function, "'s name of length ", nameLen, " for payload ", payloadNumber);
+                nameSection.functionNames[index] = WTFMove(nameString);
+            }
+            break;
+        }
+        case NameType::Local: {
+            // Ignore local names for now, we don't do anything with them but we still need to parse them in order to properly ignore them.
+            uint32_t functionIndex;
+            uint32_t count;
+            WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't get local's function index for payload ", payloadNumber);
+            WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get local count for payload ", payloadNumber);
+            for (uint32_t local = 0; local < count; ++local) {
+                uint32_t index;
+                uint32_t nameLen;
+                Name nameString;
+                WASM_PARSER_FAIL_IF(!parseVarUInt32(index), "can't get local ", local, " index for payload ", payloadNumber);
+                WASM_PARSER_FAIL_IF(!parseVarUInt32(nameLen), "can't get local ", local, "'s name length for payload ", payloadNumber);
+                WASM_PARSER_FAIL_IF(!consumeUTF8String(nameString, nameLen), "can't get local ", local, "'s name of length ", nameLen, " for payload ", payloadNumber);
+            }
+            break;
+        }
+        }
+        WASM_PARSER_FAIL_IF(payloadStart + payloadLength != m_offset);
+    }
+    return nameSection;
+}
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
diff --git a/Source/JavaScriptCore/wasm/WasmNameSectionParser.h b/Source/JavaScriptCore/wasm/WasmNameSectionParser.h
new file mode 100644 (file)
index 0000000..b2970dd
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 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
+ * 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
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "WasmFormat.h"
+#include "WasmParser.h"
+
+namespace JSC { namespace Wasm {
+
+class NameSectionParser : public Parser<NameSection> {
+public:
+    NameSectionParser(const uint8_t* sourceBuffer, size_t sourceLength, const ModuleInformation& info)
+        : Parser(sourceBuffer, sourceLength)
+        , m_info(info)
+    {
+    }
+
+    Result WARN_UNUSED_RETURN parse();
+    
+private:
+    const ModuleInformation& m_info;
+};
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
index 629034e..0164877 100644 (file)
@@ -98,7 +98,7 @@ void OMGPlan::work(CompilationEffort)
     void* entrypoint;
     {
         ASSERT(m_codeBlock.ptr() == m_module->codeBlockFor(mode()));
-        Ref<Callee> callee = Callee::create(WTFMove(omgEntrypoint), functionIndexSpace);
+        Ref<Callee> callee = Callee::create(WTFMove(omgEntrypoint), functionIndexSpace, m_moduleInformation->nameSection.get(functionIndexSpace));
         MacroAssembler::repatchPointer(parseAndCompileResult.value()->wasmCalleeMoveLocation, CalleeBits::boxWasm(callee.ptr()));
         ASSERT(!m_codeBlock->m_optimizedCallees[m_functionIndex]);
         entrypoint = callee->entrypoint();
index 89ff10c..c2a8c14 100644 (file)
@@ -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
@@ -62,7 +62,7 @@ protected:
 
     bool WARN_UNUSED_RETURN consumeCharacter(char);
     bool WARN_UNUSED_RETURN consumeString(const char*);
-    bool WARN_UNUSED_RETURN consumeUTF8String(Vector<LChar>&, size_t);
+    bool WARN_UNUSED_RETURN consumeUTF8String(Name&, size_t);
 
     bool WARN_UNUSED_RETURN parseVarUInt1(uint8_t&);
     bool WARN_UNUSED_RETURN parseInt7(int8_t&);
@@ -142,7 +142,7 @@ ALWAYS_INLINE bool Parser<SuccessType>::consumeString(const char* str)
 }
 
 template<typename SuccessType>
-ALWAYS_INLINE bool Parser<SuccessType>::consumeUTF8String(Vector<LChar>& result, size_t stringLength)
+ALWAYS_INLINE bool Parser<SuccessType>::consumeUTF8String(Name& result, size_t stringLength)
 {
     if (length() < stringLength || m_offset > length() - stringLength)
         return false;