Commit 2293a59f authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm] Remove anyref subtyping

All subtyping has been removed from the reference-types proposal. This
CL implements this proposal change now in V8.

R=manoskouk@chromium.org

Bug: v8:10556
Change-Id: I08ef064952278e03ea655461fa9f0c96426157c7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2222345
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68152}
parent 10cf6aeb
......@@ -121,9 +121,7 @@ class ValueType {
// TODO(7748): Extend this with struct and function subtyping.
// Keep up to date with funcref vs. anyref subtyping.
constexpr bool IsSubTypeOf(ValueType other) const {
return (*this == other) || (other.kind() == kAnyRef && IsReferenceType()) ||
(kind() == kNullRef && other.kind() != kRef &&
other.IsReferenceType()) ||
return (*this == other) ||
(other.kind() == kEqRef &&
(kind() == kExnRef || kind() == kOptRef || kind() == kRef)) ||
(kind() == kRef && other.kind() == kOptRef &&
......
......@@ -324,7 +324,6 @@
'regress/regress-crbug-1047368': [SKIP],
'regress/wasm/*': [SKIP],
'regress/regress-8947': [SKIP],
'regress/regress-9165': [SKIP],
'regress/regress-9209': [SKIP],
'regress/regress-1034394': [SKIP],
'regress/regress-v8-9106': [SKIP],
......
// Copyright 2018 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: --experimental-wasm-anyref
load("test/mjsunit/wasm/wasm-module-builder.js");
let kSig_r_i = makeSig([kWasmI32], [kWasmAnyRef]);
(function TestMergeOfAnyFuncIntoAnyRef() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addFunction("merge", kSig_r_i)
.addLocals({anyref_count: 1, anyfunc_count: 1})
.addBody([
kExprLocalGet, 0,
kExprI32Eqz,
kExprIf, kWasmAnyRef,
kExprLocalGet, 1,
kExprElse,
kExprLocalGet, 2,
kExprEnd,
]).exportFunc();
let instance = builder.instantiate();
assertEquals(null, instance.exports.merge(0));
assertEquals(null, instance.exports.merge(1));
})();
(function TestMergeOfAnyFuncIntoNullRef() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addFunction("merge", kSig_r_i)
.addLocals({anyfunc_count: 1})
.addBody([
kExprLocalGet, 0,
kExprI32Eqz,
kExprIf, kWasmAnyRef,
kExprRefNull, kWasmAnyRef,
kExprElse,
kExprLocalGet, 1,
kExprEnd,
]).exportFunc();
let instance = builder.instantiate();
assertEquals(null, instance.exports.merge(0));
assertEquals(null, instance.exports.merge(1));
})();
......@@ -183,32 +183,6 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
assertEquals(null, main());
})();
(function testImplicitReturnAnyFuncAsAnyRef() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
const sig_index = builder.addType(kSig_r_v);
builder.addFunction('main', sig_index)
.addLocals({anyfunc_count: 1})
.addBody([kExprLocalGet, 0])
.exportFunc();
const main = builder.instantiate().exports.main;
assertEquals(null, main());
})();
(function testExplicitReturnAnyFuncAsAnyRef() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
const sig_index = builder.addType(kSig_r_v);
builder.addFunction('main', sig_index)
.addLocals({anyfunc_count: 1})
.addBody([kExprLocalGet, 0, kExprReturn])
.exportFunc();
const main = builder.instantiate().exports.main;
assertEquals(null, main());
})();
(function testRefFuncOutOfBounds() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
......
......@@ -529,20 +529,6 @@ function dummy_func() {
assertEquals(obj3, instance2.exports.reexport3.value);
})();
(function TestImportImmutableAnyFuncGlobalAsAnyRef() {
print(arguments.callee.name);
let builder1 = new WasmModuleBuilder();
const g3 = builder1.addGlobal(kWasmAnyFunc, true).exportAs("e3");
builder1.addGlobal(kWasmAnyRef, false).exportAs("e1"); // Dummy.
builder1.addGlobal(kWasmAnyFunc, false).exportAs("e2"); // Dummy.
const instance1 = builder1.instantiate();
let builder2 = new WasmModuleBuilder();
const i1 = builder2.addImportedGlobal('exports', 'e1', kWasmAnyRef, false);
const i2 = builder2.addImportedGlobal('exports', 'e2', kWasmAnyRef, false);
builder2.instantiate(instance1);
})();
(function TestImportMutableAnyFuncGlobalAsAnyRefFails() {
print(arguments.callee.name);
let builder1 = new WasmModuleBuilder();
......
......@@ -104,7 +104,7 @@ load("test/mjsunit/wasm/exceptions-utils.js");
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let except = builder.addException(kSig_v_a);
builder.addFunction("throw_catch_local", kSig_r_v)
builder.addFunction("throw_catch_local", kSig_a_v)
.addLocals({anyfunc_count: 1})
.addBody([
kExprTry, kWasmAnyFunc,
......
......@@ -78,21 +78,3 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
assertEquals(value4, table4.get(offset4 + 1)());
assertEquals(value3, table4.get(offset4 + 2)());
})();
(function TestAnyRefTableWithAnyFuncInit() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
const table = builder.addTable(kWasmAnyRef, 5).index;
builder.addExportOfKind("table", kExternalTable, table);
const f1 = builder.addFunction('f1', kSig_i_v)
.addBody([kExprI32Const, 11])
.exportFunc().index;
const f2 = builder.addFunction('f2', kSig_i_v)
.addBody([kExprI32Const, 22])
.exportFunc().index;
builder.addElementSegment(table, 1, false, [f1, f2]);
const instance = builder.instantiate();
assertEquals(instance.exports.table.get(1)(), 11);
assertEquals(instance.exports.table.get(2)(), 22);
})();
......@@ -1942,14 +1942,11 @@ TEST_F(FunctionBodyDecoderTest, TableSet) {
byte tab_func1 = builder.AddTable(kWasmFuncRef, 20, true, 30);
byte tab_func2 = builder.AddTable(kWasmFuncRef, 10, false, 20);
byte tab_ref2 = builder.AddTable(kWasmAnyRef, 10, false, 20);
byte tab_null1 = builder.AddTable(kWasmNullRef, 10, true, 20);
byte tab_null2 = builder.AddTable(kWasmNullRef, 10, false, 20);
ValueType sig_types[]{kWasmAnyRef, kWasmFuncRef, kWasmNullRef, kWasmI32};
FunctionSig sig(0, 4, sig_types);
ValueType sig_types[]{kWasmAnyRef, kWasmFuncRef, kWasmI32};
FunctionSig sig(0, 3, sig_types);
byte local_ref = 0;
byte local_func = 1;
byte local_null = 2;
byte local_int = 3;
byte local_int = 2;
ExpectValidates(&sig, {WASM_TABLE_SET(tab_ref1, WASM_I32V(6),
WASM_GET_LOCAL(local_ref))});
ExpectValidates(&sig, {WASM_TABLE_SET(tab_func1, WASM_I32V(5),
......@@ -1959,55 +1956,26 @@ TEST_F(FunctionBodyDecoderTest, TableSet) {
ExpectValidates(&sig, {WASM_TABLE_SET(tab_ref2, WASM_I32V(8),
WASM_GET_LOCAL(local_ref))});
// We can store funcref values as anyref, but not the other way around.
ExpectValidates(&sig, {WASM_TABLE_SET(tab_ref1, WASM_I32V(4),
WASM_GET_LOCAL(local_func))});
// Only values of the correct type can be set to a table.
ExpectFailure(&sig, {WASM_TABLE_SET(tab_ref1, WASM_I32V(4),
WASM_GET_LOCAL(local_func))});
ExpectFailure(&sig, {WASM_TABLE_SET(tab_func1, WASM_I32V(9),
WASM_GET_LOCAL(local_ref))});
ExpectFailure(&sig, {WASM_TABLE_SET(tab_func2, WASM_I32V(3),
WASM_GET_LOCAL(local_ref))});
ExpectValidates(&sig, {WASM_TABLE_SET(tab_ref2, WASM_I32V(2),
WASM_GET_LOCAL(local_func))});
ExpectFailure(&sig, {WASM_TABLE_SET(tab_ref2, WASM_I32V(2),
WASM_GET_LOCAL(local_func))});
ExpectFailure(&sig, {WASM_TABLE_SET(tab_ref1, WASM_I32V(9),
WASM_GET_LOCAL(local_int))});
ExpectFailure(&sig, {WASM_TABLE_SET(tab_func1, WASM_I32V(3),
WASM_GET_LOCAL(local_int))});
// We can store nullref values as funcref or anyref but not the other way
// round.
ExpectValidates(&sig, {WASM_TABLE_SET(tab_null1, WASM_I32V(3),
WASM_GET_LOCAL(local_null))});
ExpectValidates(&sig, {WASM_TABLE_SET(tab_ref1, WASM_I32V(8),
WASM_GET_LOCAL(local_null))});
ExpectValidates(&sig, {WASM_TABLE_SET(tab_func1, WASM_I32V(8),
WASM_GET_LOCAL(local_null))});
ExpectFailure(&sig, {WASM_TABLE_SET(tab_null1, WASM_I32V(3),
WASM_GET_LOCAL(local_ref))});
ExpectFailure(&sig, {WASM_TABLE_SET(tab_null1, WASM_I32V(3),
WASM_GET_LOCAL(local_func))});
ExpectFailure(&sig, {WASM_TABLE_SET(tab_null1, WASM_I32V(3),
WASM_GET_LOCAL(local_int))});
ExpectValidates(&sig, {WASM_TABLE_SET(tab_null2, WASM_I32V(3),
WASM_GET_LOCAL(local_null))});
ExpectValidates(&sig, {WASM_TABLE_SET(tab_ref2, WASM_I32V(8),
WASM_GET_LOCAL(local_null))});
ExpectValidates(&sig, {WASM_TABLE_SET(tab_func2, WASM_I32V(8),
WASM_GET_LOCAL(local_null))});
ExpectFailure(&sig, {WASM_TABLE_SET(tab_null2, WASM_I32V(3),
WASM_GET_LOCAL(local_ref))});
ExpectFailure(&sig, {WASM_TABLE_SET(tab_null2, WASM_I32V(3),
WASM_GET_LOCAL(local_func))});
ExpectFailure(&sig, {WASM_TABLE_SET(tab_null2, WASM_I32V(3),
WASM_GET_LOCAL(local_int))});
// Out-of-bounds table index should fail.
byte oob_tab = 37;
ExpectFailure(
&sig, {WASM_TABLE_SET(oob_tab, WASM_I32V(9), WASM_GET_LOCAL(local_ref))});
ExpectFailure(&sig, {WASM_TABLE_SET(oob_tab, WASM_I32V(3),
WASM_GET_LOCAL(local_func))});
ExpectFailure(&sig, {WASM_TABLE_SET(oob_tab, WASM_I32V(3),
WASM_GET_LOCAL(local_null))});
}
TEST_F(FunctionBodyDecoderTest, TableGet) {
......@@ -2037,15 +2005,13 @@ TEST_F(FunctionBodyDecoderTest, TableGet) {
&sig, {WASM_SET_LOCAL(local_ref, WASM_SEQ(WASM_I32V(6), kExprTableGet,
U32V_2(tab_ref1)))});
// We can store funcref values as anyref, but not the other way around.
// We cannot store references as any other type.
ExpectFailure(&sig, {WASM_SET_LOCAL(local_func,
WASM_TABLE_GET(tab_ref1, WASM_I32V(4)))});
ExpectValidates(
&sig,
{WASM_SET_LOCAL(local_ref, WASM_TABLE_GET(tab_func1, WASM_I32V(9)))});
ExpectValidates(
&sig,
{WASM_SET_LOCAL(local_ref, WASM_TABLE_GET(tab_func2, WASM_I32V(3)))});
ExpectFailure(&sig, {WASM_SET_LOCAL(
local_ref, WASM_TABLE_GET(tab_func1, WASM_I32V(9)))});
ExpectFailure(&sig, {WASM_SET_LOCAL(
local_ref, WASM_TABLE_GET(tab_func2, WASM_I32V(3)))});
ExpectFailure(&sig, {WASM_SET_LOCAL(local_func,
WASM_TABLE_GET(tab_ref2, WASM_I32V(2)))});
......@@ -3208,7 +3174,6 @@ TEST_F(FunctionBodyDecoderTest, TableCopyWrongType) {
TEST_F(FunctionBodyDecoderTest, TableGrow) {
byte tab_func = builder.AddTable(kWasmFuncRef, 10, true, 20);
byte tab_ref = builder.AddTable(kWasmAnyRef, 10, true, 20);
byte tab_null = builder.AddTable(kWasmNullRef, 10, true, 20);
ExpectFailure(
sigs.i_a(),
......@@ -3220,22 +3185,12 @@ TEST_F(FunctionBodyDecoderTest, TableGrow) {
ExpectValidates(
sigs.i_r(),
{WASM_TABLE_GROW(tab_ref, WASM_REF_NULL(kLocalAnyRef), WASM_ONE)});
// FuncRef table cannot be initialized with an anyref value.
// FuncRef table cannot be initialized with an AnyRef value.
ExpectFailure(sigs.i_r(),
{WASM_TABLE_GROW(tab_func, WASM_GET_LOCAL(0), WASM_ONE)});
// FuncRef table can be initialized with a nullref value.
ExpectValidates(sigs.i_n(),
{WASM_TABLE_GROW(tab_func, WASM_GET_LOCAL(0), WASM_ONE)});
// Anyref table can be initialized with an funcref or nullref value.
ExpectValidates(sigs.i_a(),
{WASM_TABLE_GROW(tab_ref, WASM_GET_LOCAL(0), WASM_ONE)});
ExpectValidates(sigs.i_n(),
{WASM_TABLE_GROW(tab_ref, WASM_GET_LOCAL(0), WASM_ONE)});
// NullRef table cannot be initialized with an funcref or anyref value.
// AnyRef table cannot be initialized with a FuncRef value.
ExpectFailure(sigs.i_a(),
{WASM_TABLE_GROW(tab_null, WASM_GET_LOCAL(0), WASM_ONE)});
ExpectFailure(sigs.i_r(),
{WASM_TABLE_GROW(tab_null, WASM_GET_LOCAL(0), WASM_ONE)});
{WASM_TABLE_GROW(tab_ref, WASM_GET_LOCAL(0), WASM_ONE)});
// Check that the table index gets verified.
ExpectFailure(
sigs.i_r(),
......@@ -3265,17 +3220,12 @@ TEST_F(FunctionBodyDecoderTest, TableFill) {
ExpectValidates(sigs.v_r(),
{WASM_TABLE_FILL(tab_ref, WASM_ONE,
WASM_REF_NULL(kLocalAnyRef), WASM_ONE)});
// FuncRef table cannot be initialized with an anyref value.
// FuncRef table cannot be initialized with an AnyRef value.
ExpectFailure(sigs.v_r(), {WASM_TABLE_FILL(tab_func, WASM_ONE,
WASM_GET_LOCAL(0), WASM_ONE)});
// FuncRef table can be initialized with an nullref value.
ExpectValidates(sigs.v_n(), {WASM_TABLE_FILL(tab_func, WASM_ONE,
WASM_GET_LOCAL(0), WASM_ONE)});
// Anyref table can be initialized with an funcref or nullref value.
ExpectValidates(sigs.v_a(), {WASM_TABLE_FILL(tab_ref, WASM_ONE,
WASM_GET_LOCAL(0), WASM_ONE)});
ExpectValidates(sigs.v_n(), {WASM_TABLE_FILL(tab_ref, WASM_ONE,
WASM_GET_LOCAL(0), WASM_ONE)});
// AnyRef table cannot be initialized with a FuncRef value.
ExpectFailure(sigs.v_a(), {WASM_TABLE_FILL(tab_ref, WASM_ONE,
WASM_GET_LOCAL(0), WASM_ONE)});
// Check that the table index gets verified.
ExpectFailure(sigs.v_r(),
{WASM_TABLE_FILL(tab_ref + 2, WASM_ONE,
......@@ -3358,7 +3308,7 @@ TEST_F(FunctionBodyDecoderTest, TableInitMultiTable) {
{
TestModuleBuilder builder;
builder.AddTable(kWasmAnyRef, 10, true, 20);
builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
builder.AddPassiveElementSegment(wasm::kWasmAnyRef);
module = builder.module();
// We added one table, therefore table.init on table 0 should work.
int table_index = 0;
......@@ -3373,7 +3323,7 @@ TEST_F(FunctionBodyDecoderTest, TableInitMultiTable) {
TestModuleBuilder builder;
builder.AddTable(kWasmAnyRef, 10, true, 20);
builder.AddTable(kWasmAnyRef, 10, true, 20);
builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
builder.AddPassiveElementSegment(wasm::kWasmAnyRef);
module = builder.module();
// We added two tables, therefore table.init on table 0 should work.
int table_index = 0;
......
......@@ -1324,7 +1324,8 @@ TEST_F(WasmModuleVerifyTest, ElementSectionInitAnyRefTableWithFuncRef) {
ONE_EMPTY_BODY,
};
EXPECT_VERIFIES(data);
EXPECT_FAILURE_WITH_MSG(
data, "Invalid element segment. Table 0 is not a super-type of funcref");
}
TEST_F(WasmModuleVerifyTest, ElementSectionDontInitAnyRefImportedTable) {
......
......@@ -23,7 +23,6 @@
# TODO(v8:10556): Remove sub-typing in the reference-types implementation
'proposals/bulk-memory-operations/imports': [FAIL],
'proposals/reference-types/linking': [FAIL],
'proposals/reference-types/ref_func': [FAIL],
# TODO(wasm): This test declares a table larger than allowed by the spec.
......
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