Commit b1f89b61 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Extend support of "except_ref" global variables.

This extends the support for the "except_ref" type on global variables
to support mutable globals, as well as importing and exporting such
globals. Test coverage is also increased.

R=ahaas@chromium.org
TEST=mjsunit/wasm/exceptions-global
BUG=v8:8091

Change-Id: I816406e322ffb574a4f054947682491e7b40335f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1530802Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60327}
parent 62a8bdca
......@@ -5042,8 +5042,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* FromJS(Node* node, Node* js_context, wasm::ValueType type) {
DCHECK_NE(wasm::kWasmStmt, type);
// The parameter is of type AnyRef, we take it as is.
if (type == wasm::kWasmAnyRef) {
// The parameter is of type anyref or except_ref, we take it as is.
if (type == wasm::kWasmAnyRef || type == wasm::kWasmExceptRef) {
return node;
}
......
......@@ -1313,7 +1313,7 @@ void WebAssemblyException(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate);
ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Excepion()");
ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Exception()");
thrower.TypeError("WebAssembly.Exception cannot be called");
}
......@@ -1657,6 +1657,7 @@ void WebAssemblyGlobalGetValueCommon(
break;
case i::wasm::kWasmAnyRef:
case i::wasm::kWasmAnyFunc:
case i::wasm::kWasmExceptRef:
return_value.Set(Utils::ToLocal(receiver->GetRef()));
break;
default:
......@@ -1724,7 +1725,8 @@ void WebAssemblyGlobalSetValue(
receiver->SetF64(f64_value);
break;
}
case i::wasm::kWasmAnyRef: {
case i::wasm::kWasmAnyRef:
case i::wasm::kWasmExceptRef: {
receiver->SetAnyRef(Utils::OpenHandle(*args[0]));
break;
}
......
......@@ -164,7 +164,7 @@ double WasmGlobalObject::GetF64() {
}
Handle<Object> WasmGlobalObject::GetRef() {
// We use this getter also for anyfunc.
// We use this getter for anyref, anyfunc, and except_ref.
DCHECK(wasm::ValueTypes::IsReferenceType(type()));
return handle(tagged_buffer()->get(offset()), GetIsolate());
}
......@@ -186,7 +186,8 @@ void WasmGlobalObject::SetF64(double value) {
}
void WasmGlobalObject::SetAnyRef(Handle<Object> value) {
DCHECK_EQ(type(), wasm::kWasmAnyRef);
// We use this getter anyref and except_ref.
DCHECK(type() == wasm::kWasmAnyRef || type() == wasm::kWasmExceptRef);
tagged_buffer()->set(offset(), *value);
}
......
......@@ -37,8 +37,102 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
assertEquals(null, instance.exports.push_and_return_except_ref());
})();
// TODO(mstarzinger): Add test coverage for the following:
// - Catching exception in wasm and storing into global.
// - Taking "except_ref" parameter and storing into global.
// - Rethrowing "except_ref" from global (or parameter).
// - Importing a global "except_ref" during instantiation.
// Test storing a caught exception into an exported mutable "except_ref" global.
(function TestGlobalExceptRefSetCaught() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let except = builder.addException(kSig_v_i);
let g = builder.addGlobal(kWasmExceptRef, true).exportAs("exn");
builder.addFunction('catch_and_set_except_ref', kSig_v_i)
.addBody([
kExprTry, kWasmStmt,
kExprGetLocal, 0,
kExprThrow, except,
kExprCatch,
kExprSetGlobal, g.index,
kExprEnd,
]).exportFunc();
let instance = builder.instantiate();
assertDoesNotThrow(() => instance.exports.catch_and_set_except_ref(23));
let exception = instance.exports.exn.value; // Exported mutable global.
assertInstanceof(exception, WebAssembly.RuntimeError);
assertEquals(except, %GetWasmExceptionId(exception, instance));
})();
// Test storing a parameter into an exported mutable "except_ref" global.
(function TestGlobalExceptRefSetParameter() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let g = builder.addGlobal(kWasmExceptRef, true).exportAs("exn");
builder.addFunction('set_param_except_ref', kSig_v_e)
.addBody([
kExprTry, kWasmStmt,
kExprGetLocal, 0,
kExprRethrow,
kExprCatch,
kExprSetGlobal, g.index,
kExprEnd,
]).exportFunc();
let exception = "my fancy exception";
let instance = builder.instantiate();
assertDoesNotThrow(() => instance.exports.set_param_except_ref(exception));
assertEquals(exception, instance.exports.exn.value);
})();
// Test loading an imported "except_ref" global and re-throwing the exception.
(function TestGlobalExceptRefGetImportedAndRethrow() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let g_index = builder.addImportedGlobal("m", "exn", kWasmExceptRef);
builder.addFunction('rethrow_except_ref', kSig_v_v)
.addBody([
kExprGetGlobal, g_index,
kExprRethrow,
]).exportFunc();
let exception = "my fancy exception";
let instance = builder.instantiate({ "m": { "exn": exception }});
assertThrowsEquals(() => instance.exports.rethrow_except_ref(), exception);
})();
// Test loading an exported mutable "except_ref" being changed from the outside.
(function TestGlobalExceptRefGetExportedMutableAndRethrow() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let g = builder.addGlobal(kWasmExceptRef, true).exportAs("exn");
builder.addFunction('rethrow_except_ref', kSig_v_v)
.addBody([
kExprGetGlobal, g.index,
kExprRethrow,
]).exportFunc();
let instance = builder.instantiate();
let exception1 = instance.exports.exn.value = "my fancy exception";
assertThrowsEquals(() => instance.exports.rethrow_except_ref(), exception1);
let exception2 = instance.exports.exn.value = "an even fancier exception";
assertThrowsEquals(() => instance.exports.rethrow_except_ref(), exception2);
})();
// TODO(mstarzinger): Add the following test once proposal makes it clear how
// far interaction with the mutable globals proposal is intended to go.
// Test loading an imported mutable "except_ref" being changed from the outside.
/*(function TestGlobalExceptRefGetImportedMutableAndRethrow() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let g_index = builder.addImportedGlobal("m", "exn", kWasmExceptRef, true);
builder.addFunction('rethrow_except_ref', kSig_v_v)
.addBody([
kExprGetGlobal, g_index,
kExprRethrow,
]).exportFunc();
let exception1 = "my fancy exception";
let desc = { value: 'except_ref', mutable: true };
let mutable_global = new WebAssembly.Global(desc, exception1);
let instance = builder.instantiate({ "m": { "exn": mutable_global }});
assertThrowsEquals(() => instance.exports.rethrow_except_ref(), exception1);
let exception2 = mutable_global.value = "an even fancier exception";
assertThrowsEquals(() => instance.exports.rethrow_except_ref(), exception2);
})();*/
......@@ -153,6 +153,7 @@ let kSig_a_a = makeSig([kWasmAnyFunc], [kWasmAnyFunc]);
let kSig_i_r = makeSig([kWasmAnyRef], [kWasmI32]);
let kSig_v_r = makeSig([kWasmAnyRef], []);
let kSig_v_a = makeSig([kWasmAnyFunc], []);
let kSig_v_e = makeSig([kWasmExceptRef], []);
let kSig_v_rr = makeSig([kWasmAnyRef, kWasmAnyRef], []);
let kSig_v_aa = makeSig([kWasmAnyFunc, kWasmAnyFunc], []);
let kSig_r_v = makeSig([], [kWasmAnyRef]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment