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