[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/1196510 Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#55526}
This commit is contained in:
parent
b9540d447f
commit
f19a70681d
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user