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

[wasm] Add support for 'except_ref' value type.

This adds experimental support for an 'except_ref' value type for caught
exceptions as per the exception handling proposal. In the current for it
is only allowed to have such types in the stack or in a local, support
for having it as part of any signature was left out.

The default value for a local of type 'except_ref' is the 'ref_null'
value for now. Since this value cannot escape a wasm function, the
concrete value is not actually observable.

R=ahaas@chromium.org
TEST=unittests/LocalDeclDecoderTest.ExceptRef,mjsunit/wasm/exceptions
BUG=v8:8091

Change-Id: I7bd65274327a833262f8749cbe0e24e737f6e0c1
Reviewed-on: https://chromium-review.googlesource.com/1196510Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55526}
parent b9540d44
......@@ -737,6 +737,13 @@ class WasmDecoder : public Decoder {
}
decoder->error(decoder->pc() - 1, "invalid local type");
return false;
case kLocalExceptRef:
if (enabled.eh) {
type = kWasmExceptRef;
break;
}
decoder->error(decoder->pc() - 1, "invalid local type");
return false;
case kLocalS128:
if (enabled.simd) {
type = kWasmS128;
......
......@@ -99,6 +99,12 @@ class WasmGraphBuildingInterface {
// instance parameter.
TFNode* start = builder_->Start(
static_cast<int>(decoder->sig_->parameter_count() + 1 + 1));
ssa_env->effect = start;
ssa_env->control = start;
// Initialize effect and control before initializing the locals default
// values (which might require instance loads) or loading the context.
builder_->set_effect_ptr(&ssa_env->effect);
builder_->set_control_ptr(&ssa_env->control);
// Initialize the instance parameter (index 0).
builder_->set_instance_node(builder_->Param(kWasmInstanceParameterIndex));
// Initialize local variables. Parameters are shifted by 1 because of the
......@@ -115,11 +121,6 @@ class WasmGraphBuildingInterface {
ssa_env->locals[index++] = node;
}
}
ssa_env->effect = start;
ssa_env->control = start;
// Initialize effect and control before loading the context.
builder_->set_effect_ptr(&ssa_env->effect);
builder_->set_control_ptr(&ssa_env->control);
LoadContextIntoSsa(ssa_env);
SetEnv(ssa_env);
}
......@@ -596,6 +597,8 @@ class WasmGraphBuildingInterface {
return builder_->Float64Constant(0);
case kWasmS128:
return builder_->S128Zero();
case kWasmExceptRef:
return builder_->RefNull();
default:
UNREACHABLE();
}
......
......@@ -21,6 +21,7 @@ enum ValueType : uint8_t {
kWasmS128,
kWasmAnyRef,
kWasmAnyFunc,
kWasmExceptRef,
kWasmVar,
};
......@@ -220,6 +221,8 @@ class V8_EXPORT_PRIVATE ValueTypes {
return kLocalS128;
case kWasmAnyRef:
return kLocalAnyRef;
case kWasmExceptRef:
return kLocalExceptRef;
case kWasmStmt:
return kLocalVoid;
default:
......
......@@ -25,7 +25,8 @@ enum ValueTypeCode : uint8_t {
kLocalF64 = 0x7c,
kLocalS128 = 0x7b,
kLocalAnyFunc = 0x70,
kLocalAnyRef = 0x6f
kLocalAnyRef = 0x6f,
kLocalExceptRef = 0x68,
};
// Binary encoding of other types.
constexpr uint8_t kWasmFunctionTypeCode = 0x60;
......
......@@ -7,6 +7,19 @@
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
// First we just test that "except_ref" local variables are allowed.
(function TestLocalExceptRef() {
let builder = new WasmModuleBuilder();
builder.addFunction("push_and_drop_except_ref", kSig_v_v)
.addBody([
kExprGetLocal, 0,
kExprDrop,
]).addLocals({except_count: 1}).exportFunc();
let instance = builder.instantiate();
assertDoesNotThrow(instance.exports.push_and_drop_except_ref);
})();
// The following method doesn't attempt to catch an raised exception.
(function TestThrowSimple() {
let builder = new WasmModuleBuilder();
......
......@@ -91,6 +91,7 @@ let kWasmF32 = 0x7d;
let kWasmF64 = 0x7c;
let kWasmS128 = 0x7b;
let kWasmAnyRef = 0x6f;
let kWasmExceptRef = 0x68;
let kExternalFunction = 0;
let kExternalTable = 1;
......
......@@ -569,6 +569,9 @@ class WasmModuleBuilder {
if (l.s128_count > 0) {
local_decls.push({count: l.s128_count, type: kWasmS128});
}
if (l.except_count > 0) {
local_decls.push({count: l.except_count, type: kWasmExceptRef});
}
}
let header = new Binary;
......
......@@ -3127,6 +3127,20 @@ TEST_F(LocalDeclDecoderTest, UseEncoder) {
pos = ExpectRun(map, pos, kWasmI64, 212);
}
TEST_F(LocalDeclDecoderTest, ExceptRef) {
WASM_FEATURE_SCOPE(eh);
ValueType type = kWasmExceptRef;
const byte data[] = {1, 1,
static_cast<byte>(ValueTypes::ValueTypeCodeFor(type))};
BodyLocalDecls decls(zone());
bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
EXPECT_TRUE(result);
EXPECT_EQ(1u, decls.type_list.size());
TypesOfLocals map = decls.type_list;
EXPECT_EQ(type, map[0]);
}
class BytecodeIteratorTest : public TestWithZone {};
TEST_F(BytecodeIteratorTest, SimpleForeach) {
......
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