Diff
Modified: trunk/JSTests/ChangeLog (272070 => 272071)
--- trunk/JSTests/ChangeLog 2021-01-29 19:25:36 UTC (rev 272070)
+++ trunk/JSTests/ChangeLog 2021-01-29 19:26:36 UTC (rev 272071)
@@ -1,3 +1,19 @@
+2021-01-29 Dmitry Bezhetskov <[email protected]>
+
+ [JSC] WebAssembly.Global should support Funcref and Externref
+ https://bugs.webkit.org/show_bug.cgi?id=220914
+
+ Reviewed by Yusuke Suzuki.
+
+ Add tests for WebAssembly.Global ctors with
+ new reference types:
+ https://webassembly.github.io/reference-types/js-api/index.html#dom-global-global.
+
+ * wasm/references/globals.js: Added.
+ (Pelmen):
+ (testGlobalConstructorForExternref):
+ (async testGlobalConstructorForFuncref):
+
2021-01-28 Yusuke Suzuki <[email protected]>
Unreviewed, recover removed tests
Added: trunk/JSTests/wasm/references/globals.js (0 => 272071)
--- trunk/JSTests/wasm/references/globals.js (rev 0)
+++ trunk/JSTests/wasm/references/globals.js 2021-01-29 19:26:36 UTC (rev 272071)
@@ -0,0 +1,47 @@
+//@ runWebAssemblySuite("--useWebAssemblyReferences=true")
+import * as assert from '../assert.js';
+import { instantiate } from "../wabt-wrapper.js";
+
+// trivial
+function Pelmen(calories) {
+ this.calories = calories;
+}
+const calories = 100;
+
+function testGlobalConstructorForExternref() {
+ {
+ let global = new WebAssembly.Global({ value: "externref", mutable: true });
+ assert.eq(global.value, undefined);
+
+ global.value = new Pelmen(calories);
+ assert.eq(global.value.calories, calories);
+ }
+
+ {
+ let global = new WebAssembly.Global({ value: "externref", mutable: true }, new Pelmen(calories));
+ assert.eq(global.value.calories, calories);
+ }
+}
+
+async function testGlobalConstructorForFuncref() {
+ const instance = await instantiate(`(module (func (export "foo")))`, {}, {reference_types: true});
+
+ {
+ let global = new WebAssembly.Global({ value: "anyfunc", mutable: true });
+ assert.eq(global.value, null);
+
+ global.value = instance.exports.foo;
+ assert.eq(global.value, instance.exports.foo);
+ }
+
+ {
+ let global = new WebAssembly.Global({ value: "anyfunc", mutable: true }, instance.exports.foo);
+ assert.eq(global.value, instance.exports.foo);
+ assert.throws(() => global.value = new Pelmen(calories), WebAssembly.RuntimeError, "Funcref must be an exported wasm function (evaluating 'global.value = new Pelmen(calories)')");
+ }
+
+ assert.throws(() => new WebAssembly.Global({ value: "anyfunc", mutable: true }, new Pelmen(calories)), WebAssembly.RuntimeError, "Funcref must be an exported wasm function (evaluating 'new WebAssembly.Global({ value: \"anyfunc\", mutable: true }, new Pelmen(calories))')");
+}
+
+testGlobalConstructorForExternref();
+assert.asyncTest(testGlobalConstructorForFuncref());
Modified: trunk/Source/_javascript_Core/ChangeLog (272070 => 272071)
--- trunk/Source/_javascript_Core/ChangeLog 2021-01-29 19:25:36 UTC (rev 272070)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-01-29 19:26:36 UTC (rev 272071)
@@ -1,3 +1,17 @@
+2021-01-29 Dmitry Bezhetskov <[email protected]>
+
+ [JSC] WebAssembly.Global should support Funcref and Externref
+ https://bugs.webkit.org/show_bug.cgi?id=220914
+
+ Reviewed by Yusuke Suzuki.
+
+ Allow using reference types in ctor of WebAssembly.Global
+ according to the spec
+ https://webassembly.github.io/reference-types/js-api/index.html#dom-global-global.
+
+ * wasm/js/WebAssemblyGlobalConstructor.cpp:
+ (JSC::JSC_DEFINE_HOST_FUNCTION):
+
2021-01-29 David Kilzer <[email protected]>
check-webkit-style: warn about WTF::BlockPtr use in _javascript_Core until ARC is enabled
Modified: trunk/Source/_javascript_Core/wasm/WasmTable.cpp (272070 => 272071)
--- trunk/Source/_javascript_Core/wasm/WasmTable.cpp 2021-01-29 19:25:36 UTC (rev 272070)
+++ trunk/Source/_javascript_Core/wasm/WasmTable.cpp 2021-01-29 19:26:36 UTC (rev 272071)
@@ -174,6 +174,14 @@
visitor.append(m_jsValues.get()[i]);
}
+Type Table::wasmType() const
+{
+ if (isExternrefTable())
+ return Type::Externref;
+ ASSERT(isFuncrefTable());
+ return Type::Funcref;
+}
+
FuncRefTable* Table::asFuncrefTable()
{
return m_type == TableElementType::Funcref ? static_cast<FuncRefTable*>(this) : nullptr;
Modified: trunk/Source/_javascript_Core/wasm/WasmTable.h (272070 => 272071)
--- trunk/Source/_javascript_Core/wasm/WasmTable.h 2021-01-29 19:25:36 UTC (rev 272070)
+++ trunk/Source/_javascript_Core/wasm/WasmTable.h 2021-01-29 19:26:36 UTC (rev 272071)
@@ -68,6 +68,7 @@
TableElementType type() const { return m_type; }
bool isExternrefTable() const { return m_type == TableElementType::Externref; }
bool isFuncrefTable() const { return m_type == TableElementType::Funcref; }
+ Type wasmType() const;
FuncRefTable* asFuncrefTable();
static bool isValidLength(uint32_t length) { return length < maxTableEntries; }
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyHelpers.h (272070 => 272071)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyHelpers.h 2021-01-29 19:25:36 UTC (rev 272070)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyHelpers.h 2021-01-29 19:26:36 UTC (rev 272071)
@@ -135,11 +135,12 @@
return isWebAssemblyHostFunction(vm, object, unused, unused2);
}
-ALWAYS_INLINE JSValue defaultValueForTable(const Wasm::TableElementType tableType)
+ALWAYS_INLINE JSValue defaultValueForReferenceType(const Wasm::Type type)
{
- if (tableType == Wasm::TableElementType::Externref)
+ ASSERT(Wasm::isRefType(type));
+ if (type == Wasm::Type::Externref)
return jsUndefined();
- ASSERT(tableType == Wasm::TableElementType::Funcref);
+ ASSERT(type == Wasm::Type::Funcref);
return jsNull();
}
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyGlobalConstructor.cpp (272070 => 272071)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyGlobalConstructor.cpp 2021-01-29 19:25:36 UTC (rev 272070)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyGlobalConstructor.cpp 2021-01-29 19:26:36 UTC (rev 272071)
@@ -30,6 +30,7 @@
#include "JSCInlines.h"
#include "JSWebAssemblyGlobal.h"
+#include "WasmFormat.h"
#include "WebAssemblyGlobalPrototype.h"
#include "WebAssemblyGlobalConstructor.lut.h"
@@ -93,6 +94,10 @@
type = Wasm::Type::F32;
else if (valueString == "f64")
type = Wasm::Type::F64;
+ else if (Options::useWebAssemblyReferences() && valueString == "anyfunc")
+ type = Wasm::Type::Funcref;
+ else if (Options::useWebAssemblyReferences() && valueString == "externref")
+ type = Wasm::Type::Externref;
else
return JSValue::encode(throwException(globalObject, throwScope, createTypeError(globalObject, "WebAssembly.Global expects its 'value' field to be the string 'i32', 'i64', 'f32', or 'f64'"_s)));
}
@@ -125,6 +130,12 @@
initialValue = bitwise_cast<uint64_t>(value);
break;
}
+ case Wasm::Type::Funcref:
+ case Wasm::Type::Externref: {
+ // We check default value for these types later in set method.
+ ASSERT(Options::useWebAssemblyReferences());
+ break;
+ }
default:
RELEASE_ASSERT_NOT_REACHED();
}
@@ -131,7 +142,17 @@
}
Ref<Wasm::Global> wasmGlobal = Wasm::Global::create(type, mutability, initialValue);
- RELEASE_AND_RETURN(throwScope, JSValue::encode(JSWebAssemblyGlobal::tryCreate(globalObject, vm, webAssemblyGlobalStructure, WTFMove(wasmGlobal))));
+ JSWebAssemblyGlobal* jsWebAssemblyGlobal = JSWebAssemblyGlobal::tryCreate(globalObject, vm, webAssemblyGlobalStructure, WTFMove(wasmGlobal));
+ RETURN_IF_EXCEPTION(throwScope, { });
+
+ if (Wasm::isRefType(type)) {
+ ASSERT(Options::useWebAssemblyReferences());
+ if (argument.isUndefined())
+ argument = defaultValueForReferenceType(type);
+ jsWebAssemblyGlobal->global()->set(globalObject, argument);
+ RETURN_IF_EXCEPTION(throwScope, { });
+ }
+ return JSValue::encode(jsWebAssemblyGlobal);
}
JSC_DEFINE_HOST_FUNCTION(callJSWebAssemblyGlobal, (JSGlobalObject* globalObject, CallFrame*))
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyTableConstructor.cpp (272070 => 272071)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyTableConstructor.cpp 2021-01-29 19:25:36 UTC (rev 272070)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyTableConstructor.cpp 2021-01-29 19:26:36 UTC (rev 272071)
@@ -122,7 +122,7 @@
if (Options::useWebAssemblyReferences()) {
JSValue defaultValue = callFrame->argumentCount() < 2
- ? defaultValueForTable(jsWebAssemblyTable->table()->type())
+ ? defaultValueForReferenceType(jsWebAssemblyTable->table()->wasmType())
: callFrame->uncheckedArgument(1);
WebAssemblyFunction* wasmFunction = nullptr;
WebAssemblyWrapperFunction* wasmWrapperFunction = nullptr;
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyTablePrototype.cpp (272070 => 272071)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyTablePrototype.cpp 2021-01-29 19:25:36 UTC (rev 272070)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyTablePrototype.cpp 2021-01-29 19:26:36 UTC (rev 272071)
@@ -94,7 +94,7 @@
JSValue defaultValue = jsNull();
if (Options::useWebAssemblyReferences()) {
if (callFrame->argumentCount() < 2)
- defaultValue = defaultValueForTable(table->table()->type());
+ defaultValue = defaultValueForReferenceType(table->table()->wasmType());
else
defaultValue = callFrame->uncheckedArgument(1);
}
@@ -140,7 +140,7 @@
JSValue value = callFrame->argument(1);
if (Options::useWebAssemblyReferences() && callFrame->argumentCount() < 2)
- value = defaultValueForTable(table->table()->type());
+ value = defaultValueForReferenceType(table->table()->wasmType());
if (table->table()->asFuncrefTable()) {
WebAssemblyFunction* wasmFunction = nullptr;