Title: [271097] trunk
Revision
271097
Author
[email protected]
Date
2020-12-27 15:35:30 -0800 (Sun, 27 Dec 2020)

Log Message

[WASM-References] Add declared function indexes set to check from what functions we can create refs
https://bugs.webkit.org/show_bug.cgi?id=220009

Patch by Dmitry Bezhetskov <[email protected]> on 2020-12-27
Reviewed by Yusuke Suzuki.

JSTests:

Now we satisfy ref_func spec test so I've added it.

* wasm.yaml:
* wasm/references-spec-tests/ref_func.wast.js: Added.

Source/_javascript_Core:

By ref-types spec we can create references only from declared functions.
Declared function is a function that was mentioned:
as export,
as part of ref.func init _expression_ for a global,
in the element section.
In this patch declared function indexes set introduced to check this
requirement.
https://webassembly.github.io/reference-types/core/valid/instructions.html#reference-instructions.

* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::parseExpression):
* wasm/WasmModuleInformation.h:
(JSC::Wasm::ModuleInformation::isDeclaredFunction const):
(JSC::Wasm::ModuleInformation::addDeclaredFunction):
* wasm/WasmSectionParser.cpp:
(JSC::Wasm::SectionParser::parseGlobal):
(JSC::Wasm::SectionParser::parseExport):
(JSC::Wasm::SectionParser::parseElementSegmentVectorOfExpressions):
(JSC::Wasm::SectionParser::parseElementSegmentVectorOfIndexes):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (271096 => 271097)


--- trunk/JSTests/ChangeLog	2020-12-27 18:57:28 UTC (rev 271096)
+++ trunk/JSTests/ChangeLog	2020-12-27 23:35:30 UTC (rev 271097)
@@ -1,3 +1,15 @@
+2020-12-27  Dmitry Bezhetskov  <[email protected]>
+
+        [WASM-References] Add declared function indexes set to check from what functions we can create refs
+        https://bugs.webkit.org/show_bug.cgi?id=220009
+
+        Reviewed by Yusuke Suzuki.
+
+        Now we satisfy ref_func spec test so I've added it.
+
+        * wasm.yaml:
+        * wasm/references-spec-tests/ref_func.wast.js: Added.
+
 2020-12-25  Mark Lam  <[email protected]>
 
         VMInspector::dumpRegisters() should not dump beyond the start of the next frame.

Modified: trunk/JSTests/wasm/references/func_ref.js (271096 => 271097)


--- trunk/JSTests/wasm/references/func_ref.js	2020-12-27 18:57:28 UTC (rev 271096)
+++ trunk/JSTests/wasm/references/func_ref.js	2020-12-27 23:35:30 UTC (rev 271097)
@@ -78,7 +78,6 @@
               .Function("i")
               .Function("get_i")
               .Function("fix")
-              .Function("get_not_exported")
               .Function("local_read")
           .End()
           .Code()
@@ -107,10 +106,6 @@
               .RefFunc(2)
             .End()
 
-            .Function("get_not_exported", { params: [], ret: "funcref" }, [])
-              .RefFunc(4)
-            .End()
-
             .Function("ret_42", { params: [], ret: "i32" }, [])
               .I32Const(42)
             .End()
@@ -138,8 +133,6 @@
     assert.eq(instance.exports.get_i()(myfun), myfun)
     assert.throws(() => instance.exports.get_i()(5), Error, "Funcref must be an exported wasm function (evaluating 'func(...args)')")
 
-    assert.eq(instance.exports.get_not_exported()(), 42)
-
     assert.eq(instance.exports.fix()(), instance.exports.fix());
     assert.eq(instance.exports.fix(), instance.exports.fix);
 }
@@ -397,6 +390,9 @@
       .Table()
             .Table({initial: 1, element: "funcref"})
       .End()
+      .Global()
+          .RefFunc("funcref", 0, "immutable") // to declare the imported function.
+      .End()
       .Export()
           .Function("test1")
           .Function("test2")

Added: trunk/JSTests/wasm/references-spec-tests/ref_func.wast.js (0 => 271097)


--- trunk/JSTests/wasm/references-spec-tests/ref_func.wast.js	                        (rev 0)
+++ trunk/JSTests/wasm/references-spec-tests/ref_func.wast.js	2020-12-27 23:35:30 UTC (rev 271097)
@@ -0,0 +1,51 @@
+
+// ref_func.wast:1
+let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x01\x7f\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x20\x00\x0b");
+
+// ref_func.wast:4
+register("M", $1)
+
+// ref_func.wast:6
+let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x01\x7f\x01\x7f\x60\x00\x00\x60\x00\x01\x7f\x02\x87\x80\x80\x80\x00\x01\x01\x4d\x01\x66\x00\x00\x03\x8f\x80\x80\x80\x00\x0e\x00\x01\x01\x01\x01\x01\x02\x02\x02\x01\x01\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x06\x9a\x80\x80\x80\x00\x05\x70\x00\xd2\x00\x0b\x70\x00\xd2\x01\x0b\x70\x01\xd2\x00\x0b\x70\x00\xd2\x03\x0b\x70\x00\xd2\x04\x0b\x07\xd0\x80\x80\x80\x00\x08\x09\x69\x73\x5f\x6e\x75\x6c\x6c\x2d\x66\x00\x07\x09\x69\x73\x5f\x6e\x75\x6c\x6c\x2d\x67\x00\x08\x09\x69\x73\x5f\x6e\x75\x6c\x6c\x2d\x76\x00\x09\x05\x73\x65\x74\x2d\x66\x00\x0a\x05\x73\x65\x74\x2d\x67\x00\x0b\x06\x63\x61\x6c\x6c\x2d\x66\x00\x0c\x06\x63\x61\x6c\x6c\x2d\x67\x00\x0d\x06\x63\x61\x6c\x6c\x2d\x76\x00\x0e\x09\x90\x80\x80\x80\x00\x03\x03\x00\x02\x03\x05\x03\x00\x02\x04\x06\x03\x00\x02\x00\x01\x0a\xa6\x81\x80\x80\x00\x0e\x87\x80\x80\x80\x00\x00\x20\x00\x41\x01\x6a\x0b\x88\x80\x80\x80\x00\x00\xd2\x05\x1a\xd2\x06\x1a\x0b\
 x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x85\x80\x80\x80\x00\x00\xd2\x00\xd1\x0b\x85\x80\x80\x80\x00\x00\xd2\x01\xd1\x0b\x85\x80\x80\x80\x00\x00\x23\x02\xd1\x0b\x86\x80\x80\x80\x00\x00\xd2\x00\x24\x02\x0b\x86\x80\x80\x80\x00\x00\xd2\x01\x24\x02\x0b\x8f\x80\x80\x80\x00\x00\x41\x00\xd2\x00\x26\x00\x20\x00\x41\x00\x11\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x00\xd2\x01\x26\x00\x20\x00\x41\x00\x11\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x00\x23\x02\x26\x00\x20\x00\x41\x00\x11\x00\x00\x0b");
+
+// ref_func.wast:56
+assert_return(() => call($2, "is_null-f", []), 0);
+
+// ref_func.wast:57
+assert_return(() => call($2, "is_null-g", []), 0);
+
+// ref_func.wast:58
+assert_return(() => call($2, "is_null-v", []), 0);
+
+// ref_func.wast:60
+assert_return(() => call($2, "call-f", [4]), 4);
+
+// ref_func.wast:61
+assert_return(() => call($2, "call-g", [4]), 5);
+
+// ref_func.wast:62
+assert_return(() => call($2, "call-v", [4]), 4);
+
+// ref_func.wast:63
+run(() => call($2, "set-g", []));
+
+// ref_func.wast:64
+assert_return(() => call($2, "call-v", [4]), 5);
+
+// ref_func.wast:65
+run(() => call($2, "set-f", []));
+
+// ref_func.wast:66
+assert_return(() => call($2, "call-v", [4]), 4);
+
+// ref_func.wast:68
+assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x01\x7f\x01\x7f\x02\x8d\x80\x80\x80\x00\x02\x01\x4d\x01\x66\x00\x00\x01\x4d\x01\x67\x00\x00\x06\x86\x80\x80\x80\x00\x01\x70\x00\xd2\x07\x0b");
+
+// ref_func.wast:80
+let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x06\x86\x80\x80\x80\x00\x01\x70\x00\xd2\x00\x0b\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x01\x09\x95\x80\x80\x80\x00\x04\x00\x41\x00\x0b\x01\x02\x00\x41\x00\x0b\x01\x03\x01\x00\x01\x04\x01\x00\x01\x05\x0a\xbf\x80\x80\x80\x00\x07\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\xd2\x00\xd2\x01\xd2\x02\xd2\x03\xd2\x04\xd2\x05\x0f\x0b");
+
+// ref_func.wast:108
+assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xd2\x00\x1a\x0b");
+
+// ref_func.wast:112
+assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x08\x81\x80\x80\x80\x00\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xd2\x00\x1a\x0b");

Modified: trunk/JSTests/wasm.yaml (271096 => 271097)


--- trunk/JSTests/wasm.yaml	2020-12-27 18:57:28 UTC (rev 271096)
+++ trunk/JSTests/wasm.yaml	2020-12-27 23:35:30 UTC (rev 271097)
@@ -50,6 +50,8 @@
   cmd: runWebAssemblyReferenceSpecTest :normal
 - path: wasm/references-spec-tests/ref_is_null.wast.js
   cmd: runWebAssemblyReferenceSpecTest :normal
+- path: wasm/references-spec-tests/ref_func.wast.js
+  cmd: runWebAssemblyReferenceSpecTest :normal
 - path: wasm/references-spec-tests/table_copy.wast.js
   cmd: runWebAssemblyReferenceSpecTest :normal
 - path: wasm/references-spec-tests/table_init.wast.js

Modified: trunk/Source/_javascript_Core/ChangeLog (271096 => 271097)


--- trunk/Source/_javascript_Core/ChangeLog	2020-12-27 18:57:28 UTC (rev 271096)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-12-27 23:35:30 UTC (rev 271097)
@@ -1,3 +1,30 @@
+2020-12-27  Dmitry Bezhetskov  <[email protected]>
+
+        [WASM-References] Add declared function indexes set to check from what functions we can create refs
+        https://bugs.webkit.org/show_bug.cgi?id=220009
+
+        Reviewed by Yusuke Suzuki.
+
+        By ref-types spec we can create references only from declared functions.
+        Declared function is a function that was mentioned:
+        as export,
+        as part of ref.func init _expression_ for a global,
+        in the element section.
+        In this patch declared function indexes set introduced to check this
+        requirement.
+        https://webassembly.github.io/reference-types/core/valid/instructions.html#reference-instructions.
+
+        * wasm/WasmFunctionParser.h:
+        (JSC::Wasm::FunctionParser<Context>::parseExpression):
+        * wasm/WasmModuleInformation.h:
+        (JSC::Wasm::ModuleInformation::isDeclaredFunction const):
+        (JSC::Wasm::ModuleInformation::addDeclaredFunction):
+        * wasm/WasmSectionParser.cpp:
+        (JSC::Wasm::SectionParser::parseGlobal):
+        (JSC::Wasm::SectionParser::parseExport):
+        (JSC::Wasm::SectionParser::parseElementSegmentVectorOfExpressions):
+        (JSC::Wasm::SectionParser::parseElementSegmentVectorOfIndexes):
+
 2020-12-25  Mark Lam  <[email protected]>
 
         VMInspector::dumpRegisters() should not dump beyond the start of the next frame.

Modified: trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h (271096 => 271097)


--- trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h	2020-12-27 18:57:28 UTC (rev 271096)
+++ trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h	2020-12-27 23:35:30 UTC (rev 271097)
@@ -1005,13 +1005,15 @@
     }
 
     case RefFunc: {
+        WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled");
+
         uint32_t index;
-        ExpressionType result;
-        WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled");
         WASM_PARSER_FAIL_IF(!parseVarUInt32(index), "can't get index for ref.func");
-
         WASM_VALIDATOR_FAIL_IF(index >= m_info.functionIndexSpaceSize(), "ref.func index ", index, " is too large, max is ", m_info.functionIndexSpaceSize());
+        WASM_VALIDATOR_FAIL_IF(!m_info.isDeclaredFunction(index), "ref.func index ", index, " isn't declared");
         m_info.addReferencedFunction(index);
+
+        ExpressionType result;
         WASM_TRY_ADD_TO_CONTEXT(addRefFunc(index, result));
         m_expressionStack.constructAndAppend(Funcref, result);
         return { };

Modified: trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h (271096 => 271097)


--- trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h	2020-12-27 18:57:28 UTC (rev 271096)
+++ trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h	2020-12-27 23:35:30 UTC (rev 271097)
@@ -74,6 +74,9 @@
     const BitVector& referencedFunctions() const { return m_referencedFunctions; }
     void addReferencedFunction(unsigned index) const { m_referencedFunctions.set(index); }
 
+    bool isDeclaredFunction(uint32_t index) const { return m_declaredFunctions.contains(index); }
+    void addDeclaredFunction(uint32_t index) { m_declaredFunctions.set(index); }
+
     Vector<Import> imports;
     Vector<SignatureIndex> importFunctionSignatureIndices;
     Vector<SignatureIndex> internalFunctionSignatureIndices;
@@ -94,7 +97,8 @@
     Vector<CustomSection> customSections;
     Ref<NameSection> nameSection;
     uint32_t numberOfDataSegments { 0 };
-    
+
+    BitVector m_declaredFunctions;
     mutable BitVector m_referencedFunctions;
 };
 

Modified: trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp (271096 => 271097)


--- trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp	2020-12-27 18:57:28 UTC (rev 271096)
+++ trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp	2020-12-27 23:35:30 UTC (rev 271097)
@@ -306,6 +306,9 @@
             global.initializationType = GlobalInformation::FromExpression;
         WASM_PARSER_FAIL_IF(typeForInitOpcode != global.type, "Global init_expr opcode of type ", typeForInitOpcode, " doesn't match global's type ", global.type);
 
+        if (initOpcode == RefFunc)
+            m_info->addDeclaredFunction(global.initialBitsOrImportNumber);
+
         m_info->globals.uncheckedAppend(WTFMove(global));
     }
 
@@ -337,6 +340,7 @@
         switch (kind) {
         case ExternalKind::Function: {
             WASM_PARSER_FAIL_IF(kindIndex >= m_info->functionIndexSpaceSize(), exportNumber, "th Export has invalid function number ", kindIndex, " it exceeds the function index space ", m_info->functionIndexSpaceSize(), ", named '", fieldString, "'");
+            m_info->addDeclaredFunction(kindIndex);
             break;
         }
         case ExternalKind::Table: {
@@ -685,6 +689,7 @@
         if (opcode == RefFunc) {
             WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't get Element section's ", elementNum, "th element's ", index, "th index");
             WASM_PARSER_FAIL_IF(functionIndex >= m_info->functionIndexSpaceSize(), "Element section's ", elementNum, "th element's ", index, "th index is ", functionIndex, " which exceeds the function index space size of ", m_info->functionIndexSpaceSize());
+            m_info->addDeclaredFunction(functionIndex);
         } else {
             Type typeOfNull;
             WASM_PARSER_FAIL_IF(!parseRefType(typeOfNull), "ref.null type must be a func type in elem section");
@@ -708,6 +713,7 @@
         WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't get Element section's ", elementNum, "th element's ", index, "th index");
         WASM_PARSER_FAIL_IF(functionIndex >= m_info->functionIndexSpaceSize(), "Element section's ", elementNum, "th element's ", index, "th index is ", functionIndex, " which exceeds the function index space size of ", m_info->functionIndexSpaceSize());
 
+        m_info->addDeclaredFunction(functionIndex);
         result.uncheckedAppend(functionIndex);
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to