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

[wasm] Preliminary support for "except_ref" globals.

This adds basic support and tests for having global variables of type
"except_ref" that are default initialized to "null". The functionality
is part of the exception handling proposal and solely enabled by the
corresponding feature flag.

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

Change-Id: I581bc942fbe6688a5c58790a842fb024de22d924
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1528439
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60317}
parent 761fdf72
...@@ -4988,6 +4988,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4988,6 +4988,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
return BuildChangeFloat64ToTagged(node); return BuildChangeFloat64ToTagged(node);
case wasm::kWasmAnyRef: case wasm::kWasmAnyRef:
case wasm::kWasmAnyFunc: case wasm::kWasmAnyFunc:
case wasm::kWasmExceptRef:
return node; return node;
default: default:
UNREACHABLE(); UNREACHABLE();
......
...@@ -1533,7 +1533,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1533,7 +1533,7 @@ class ModuleDecoderImpl : public Decoder {
break; break;
} }
case kExprRefNull: { case kExprRefNull: {
if (enabled_features_.anyref) { if (enabled_features_.anyref || enabled_features_.eh) {
expr.kind = WasmInitExpr::kRefNullConst; expr.kind = WasmInitExpr::kRefNullConst;
len = 0; len = 0;
break; break;
...@@ -1590,6 +1590,9 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1590,6 +1590,9 @@ class ModuleDecoderImpl : public Decoder {
case kLocalAnyRef: case kLocalAnyRef:
if (enabled_features_.anyref) return kWasmAnyRef; if (enabled_features_.anyref) return kWasmAnyRef;
break; break;
case kLocalExceptRef:
if (enabled_features_.eh) return kWasmExceptRef;
break;
default: default:
break; break;
} }
......
...@@ -1194,7 +1194,7 @@ void InstanceBuilder::InitGlobals() { ...@@ -1194,7 +1194,7 @@ void InstanceBuilder::InitGlobals() {
global.init.val.f64_const); global.init.val.f64_const);
break; break;
case WasmInitExpr::kRefNullConst: case WasmInitExpr::kRefNullConst:
DCHECK(enabled_.anyref); DCHECK(enabled_.anyref || enabled_.eh);
if (global.imported) break; // We already initialized imported globals. if (global.imported) break; // We already initialized imported globals.
tagged_globals_->set(global.offset, tagged_globals_->set(global.offset,
......
...@@ -182,7 +182,12 @@ class V8_EXPORT_PRIVATE ValueTypes { ...@@ -182,7 +182,12 @@ class V8_EXPORT_PRIVATE ValueTypes {
return (expected == actual) || return (expected == actual) ||
(expected == kWasmAnyRef && actual == kWasmNullRef) || (expected == kWasmAnyRef && actual == kWasmNullRef) ||
(expected == kWasmAnyRef && actual == kWasmAnyFunc) || (expected == kWasmAnyRef && actual == kWasmAnyFunc) ||
(expected == kWasmAnyFunc && actual == kWasmNullRef); (expected == kWasmAnyRef && actual == kWasmExceptRef) ||
(expected == kWasmAnyFunc && actual == kWasmNullRef) ||
// TODO(mstarzinger): For now we treat "null_ref" as a sub-type of
// "except_ref", which is correct but might change. See here:
// https://github.com/WebAssembly/exception-handling/issues/55
(expected == kWasmExceptRef && actual == kWasmNullRef);
} }
static inline bool IsReferenceType(ValueType type) { static inline bool IsReferenceType(ValueType type) {
...@@ -190,7 +195,8 @@ class V8_EXPORT_PRIVATE ValueTypes { ...@@ -190,7 +195,8 @@ class V8_EXPORT_PRIVATE ValueTypes {
// {kWasmNullRef}. If this assumption is wrong, it should be added to the // {kWasmNullRef}. If this assumption is wrong, it should be added to the
// result calculation below. // result calculation below.
DCHECK_NE(type, kWasmNullRef); DCHECK_NE(type, kWasmNullRef);
return type == kWasmAnyRef || type == kWasmAnyFunc; return type == kWasmAnyRef || type == kWasmAnyFunc ||
type == kWasmExceptRef;
} }
static byte MemSize(MachineType type) { static byte MemSize(MachineType type) {
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --experimental-wasm-eh --allow-natives-syntax
// Note that this test does not pass --experimental-wasm-anyref on purpose so
// that we make sure the two flags can be controlled separately/independently.
load("test/mjsunit/wasm/wasm-module-builder.js");
// First we just test that "except_ref" global variables are allowed.
(function TestGlobalExceptRefSupported() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let g = builder.addGlobal(kWasmExceptRef);
builder.addFunction("push_and_drop_except_ref", kSig_v_v)
.addBody([
kExprGetGlobal, g.index,
kExprDrop,
]).exportFunc();
let instance = builder.instantiate();
assertDoesNotThrow(instance.exports.push_and_drop_except_ref);
})();
// Test default value that global "except_ref" variables are initialized with.
(function TestGlobalExceptRefDefaultValue() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let g = builder.addGlobal(kWasmExceptRef);
builder.addFunction('push_and_return_except_ref', kSig_e_v)
.addBody([kExprGetGlobal, g.index])
.exportFunc();
let instance = builder.instantiate();
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.
...@@ -158,6 +158,7 @@ let kSig_v_aa = makeSig([kWasmAnyFunc, kWasmAnyFunc], []); ...@@ -158,6 +158,7 @@ let kSig_v_aa = makeSig([kWasmAnyFunc, kWasmAnyFunc], []);
let kSig_r_v = makeSig([], [kWasmAnyRef]); let kSig_r_v = makeSig([], [kWasmAnyRef]);
let kSig_a_v = makeSig([], [kWasmAnyFunc]); let kSig_a_v = makeSig([], [kWasmAnyFunc]);
let kSig_a_i = makeSig([kWasmI32], [kWasmAnyFunc]); let kSig_a_i = makeSig([kWasmI32], [kWasmAnyFunc]);
let kSig_e_v = makeSig([], [kWasmExceptRef]);
function makeSig(params, results) { function makeSig(params, results) {
return {params: params, results: results}; return {params: params, results: results};
...@@ -1078,6 +1079,7 @@ class WasmModuleBuilder { ...@@ -1078,6 +1079,7 @@ class WasmModuleBuilder {
break; break;
case kWasmAnyRef: case kWasmAnyRef:
case kWasmAnyFunc: case kWasmAnyFunc:
case kWasmExceptRef:
section.emit_u8(kExprRefNull); section.emit_u8(kExprRefNull);
break; break;
} }
......
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