Revert "[wasm] [multival] Allow function types as block types"
This reverts commit e44fdc7067
.
Reason for revert: Breaks msan:
https://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20arm64%20-%20sim%20-%20MSAN/builds/17482
Original change's description:
> [wasm] [multival] Allow function types as block types
>
> Changes the binary encoding of multi-return blocks to contain a function type index instead of a vector of value types.
>
> Cf. https://github.com/WebAssembly/multi-value/blob/master/proposals/multi-value/Overview.md#binary-format
>
> Bug: v8:6672
> Change-Id: I506d9323bfd6dba1e7a24c8590bcf5a08b68c433
> Reviewed-on: https://chromium-review.googlesource.com/599807
> Reviewed-by: Ben Titzer <titzer@chromium.org>
> Commit-Queue: Andreas Rossberg <rossberg@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#48453}
TBR=titzer@chromium.org,rossberg@chromium.org
Change-Id: Ia711d16ec6bd1c0731a96d38b8661f05be71f64b
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:6672
Reviewed-on: https://chromium-review.googlesource.com/712634
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48455}
This commit is contained in:
parent
190fea6058
commit
a8590f9d6c
@ -163,31 +163,51 @@ struct GlobalIndexOperand {
|
||||
|
||||
template <bool validate>
|
||||
struct BlockTypeOperand {
|
||||
uint32_t arity = 0;
|
||||
const byte* types = nullptr; // pointer to encoded types for the block.
|
||||
unsigned length = 1;
|
||||
ValueType type = kWasmStmt;
|
||||
uint32_t sig_index;
|
||||
FunctionSig* sig = nullptr;
|
||||
|
||||
inline BlockTypeOperand(Decoder* decoder, const byte* pc) {
|
||||
uint8_t val = decoder->read_u8<validate>(pc + 1, "block type");
|
||||
if (!decode_local_type(val, &type)) {
|
||||
ValueType type = kWasmStmt;
|
||||
if (decode_local_type(val, &type)) {
|
||||
arity = type == kWasmStmt ? 0 : 1;
|
||||
types = pc + 1;
|
||||
} else {
|
||||
// Handle multi-value blocks.
|
||||
if (!VALIDATE(FLAG_experimental_wasm_mv)) {
|
||||
decoder->error(pc + 1, "invalid block arity > 1");
|
||||
return;
|
||||
}
|
||||
if (!VALIDATE(val == kMultivalBlock)) {
|
||||
decoder->error(pc + 1, "invalid block type");
|
||||
return;
|
||||
}
|
||||
int32_t index =
|
||||
decoder->read_i32v<validate>(pc + 1, &length, "block arity");
|
||||
if (!VALIDATE(length > 0 && index >= 0)) {
|
||||
decoder->error(pc + 1, "invalid block type index");
|
||||
return;
|
||||
// Decode and check the types vector of the block.
|
||||
unsigned len = 0;
|
||||
uint32_t count =
|
||||
decoder->read_u32v<validate>(pc + 2, &len, "block arity");
|
||||
// {count} is encoded as {arity-2}, so that a {0} count here corresponds
|
||||
// to a block with 2 values. This makes invalid/redundant encodings
|
||||
// impossible.
|
||||
arity = count + 2;
|
||||
length = 1 + len + arity;
|
||||
types = pc + 1 + 1 + len;
|
||||
|
||||
for (uint32_t i = 0; i < arity; i++) {
|
||||
uint32_t offset = 1 + 1 + len + i;
|
||||
val = decoder->read_u8<validate>(pc + offset, "block type");
|
||||
decode_local_type(val, &type);
|
||||
if (!VALIDATE(type != kWasmStmt)) {
|
||||
decoder->error(pc + offset, "invalid block type");
|
||||
return;
|
||||
}
|
||||
}
|
||||
sig_index = static_cast<uint32_t>(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Decode a byte representing a local type. Return {false} if the encoded
|
||||
// byte was invalid or the start of a type index.
|
||||
// byte was invalid or {kMultivalBlock}.
|
||||
inline bool decode_local_type(uint8_t val, ValueType* result) {
|
||||
switch (static_cast<ValueTypeCode>(val)) {
|
||||
case kLocalVoid:
|
||||
@ -209,29 +229,18 @@ struct BlockTypeOperand {
|
||||
*result = kWasmS128;
|
||||
return true;
|
||||
default:
|
||||
*result = kWasmVar;
|
||||
*result = kWasmStmt;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t in_arity() const {
|
||||
if (type != kWasmVar) return 0;
|
||||
return static_cast<uint32_t>(sig->parameter_count());
|
||||
}
|
||||
uint32_t out_arity() const {
|
||||
if (type == kWasmStmt) return 0;
|
||||
if (type != kWasmVar) return 1;
|
||||
return static_cast<uint32_t>(sig->return_count());
|
||||
}
|
||||
ValueType in_type(uint32_t index) {
|
||||
DCHECK_EQ(kWasmVar, type);
|
||||
return sig->GetParam(index);
|
||||
}
|
||||
ValueType out_type(uint32_t index) {
|
||||
if (type == kWasmVar) return sig->GetReturn(index);
|
||||
DCHECK_NE(kWasmStmt, type);
|
||||
DCHECK_EQ(0, index);
|
||||
return type;
|
||||
ValueType read_entry(unsigned index) {
|
||||
DCHECK_LT(index, arity);
|
||||
ValueType result;
|
||||
bool success = decode_local_type(types[index], &result);
|
||||
DCHECK(success);
|
||||
USE(success);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1256,7 +1265,6 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
break;
|
||||
case kExprBlock: {
|
||||
BlockTypeOperand<validate> operand(this, this->pc_);
|
||||
if (!LookupBlockType(&operand)) break;
|
||||
auto* block = PushBlock();
|
||||
SetBlockType(block, operand);
|
||||
len = 1 + operand.length;
|
||||
@ -1282,7 +1290,6 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
case kExprTry: {
|
||||
CHECK_PROTOTYPE_OPCODE(eh);
|
||||
BlockTypeOperand<validate> operand(this, this->pc_);
|
||||
if (!LookupBlockType(&operand)) break;
|
||||
auto* try_block = PushTry();
|
||||
SetBlockType(try_block, operand);
|
||||
len = 1 + operand.length;
|
||||
@ -1332,7 +1339,6 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
}
|
||||
case kExprLoop: {
|
||||
BlockTypeOperand<validate> operand(this, this->pc_);
|
||||
if (!LookupBlockType(&operand)) break;
|
||||
// The continue environment is the inner environment.
|
||||
auto* block = PushLoop();
|
||||
SetBlockType(&control_.back(), operand);
|
||||
@ -1343,7 +1349,6 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
case kExprIf: {
|
||||
// Condition on top of stack. Split environments for branches.
|
||||
BlockTypeOperand<validate> operand(this, this->pc_);
|
||||
if (!LookupBlockType(&operand)) break;
|
||||
auto cond = Pop(0, kWasmI32);
|
||||
auto* if_block = PushIf();
|
||||
SetBlockType(if_block, operand);
|
||||
@ -1803,30 +1808,14 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
interface_.EndControl(this, current);
|
||||
}
|
||||
|
||||
bool LookupBlockType(BlockTypeOperand<validate>* operand) {
|
||||
if (operand->type == kWasmVar) {
|
||||
if (!VALIDATE(this->module_ &&
|
||||
operand->sig_index < this->module_->signatures.size())) {
|
||||
this->errorf(
|
||||
this->pc_, "block type index %u out of bounds (%d signatures)",
|
||||
operand->sig_index,
|
||||
static_cast<int>(this->module_
|
||||
? this->module_->signatures.size() : 0));
|
||||
return false;
|
||||
}
|
||||
operand->sig = this->module_->signatures[operand->sig_index];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetBlockType(Control* c, BlockTypeOperand<validate>& operand) {
|
||||
c->merge.arity = operand.out_arity();
|
||||
c->merge.arity = operand.arity;
|
||||
if (c->merge.arity == 1) {
|
||||
c->merge.vals.first = Value::New(this->pc_, operand.out_type(0));
|
||||
c->merge.vals.first = Value::New(this->pc_, operand.read_entry(0));
|
||||
} else if (c->merge.arity > 1) {
|
||||
c->merge.vals.array = zone_->NewArray<Value>(c->merge.arity);
|
||||
for (unsigned i = 0; i < c->merge.arity; i++) {
|
||||
c->merge.vals.array[i] = Value::New(this->pc_, operand.out_type(i));
|
||||
c->merge.vals.array[i] = Value::New(this->pc_, operand.read_entry(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1018,8 +1018,8 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
|
||||
case kExprTry: {
|
||||
BlockTypeOperand<false> operand(&i, i.pc());
|
||||
os << " // @" << i.pc_offset();
|
||||
for (unsigned i = 0; i < operand.out_arity(); i++) {
|
||||
os << " " << WasmOpcodes::TypeName(operand.out_type(i));
|
||||
for (unsigned i = 0; i < operand.arity; i++) {
|
||||
os << " " << WasmOpcodes::TypeName(operand.read_entry(i));
|
||||
}
|
||||
control_depth++;
|
||||
break;
|
||||
|
@ -827,34 +827,24 @@ class SideTable : public ZoneObject {
|
||||
case kExprLoop: {
|
||||
bool is_loop = opcode == kExprLoop;
|
||||
BlockTypeOperand<false> operand(&i, i.pc());
|
||||
if (operand.type == kWasmVar) {
|
||||
operand.sig = module->signatures[operand.sig_index];
|
||||
}
|
||||
TRACE("control @%u: %s, arity %d->%d\n", i.pc_offset(),
|
||||
is_loop ? "Loop" : "Block",
|
||||
operand.in_arity(), operand.out_arity());
|
||||
TRACE("control @%u: %s, arity %d\n", i.pc_offset(),
|
||||
is_loop ? "Loop" : "Block", operand.arity);
|
||||
CLabel* label = CLabel::New(&control_transfer_zone, stack_height,
|
||||
is_loop ? operand.in_arity()
|
||||
: operand.out_arity());
|
||||
control_stack.emplace_back(i.pc(), label, operand.out_arity());
|
||||
is_loop ? 0 : operand.arity);
|
||||
control_stack.emplace_back(i.pc(), label, operand.arity);
|
||||
copy_unreachable();
|
||||
if (is_loop) label->Bind(i.pc());
|
||||
break;
|
||||
}
|
||||
case kExprIf: {
|
||||
TRACE("control @%u: If\n", i.pc_offset());
|
||||
BlockTypeOperand<false> operand(&i, i.pc());
|
||||
if (operand.type == kWasmVar) {
|
||||
operand.sig = module->signatures[operand.sig_index];
|
||||
}
|
||||
TRACE("control @%u: If, arity %d->%d\n", i.pc_offset(),
|
||||
operand.in_arity(), operand.out_arity());
|
||||
CLabel* end_label =
|
||||
CLabel::New(&control_transfer_zone, stack_height,
|
||||
operand.out_arity());
|
||||
CLabel::New(&control_transfer_zone, stack_height, operand.arity);
|
||||
CLabel* else_label =
|
||||
CLabel::New(&control_transfer_zone, stack_height, 0);
|
||||
control_stack.emplace_back(i.pc(), end_label, else_label,
|
||||
operand.out_arity());
|
||||
operand.arity);
|
||||
copy_unreachable();
|
||||
if (!unreachable) else_label->Ref(i.pc(), stack_height);
|
||||
break;
|
||||
|
@ -28,6 +28,9 @@ enum ValueTypeCode {
|
||||
kLocalS128 = 0x7b
|
||||
};
|
||||
|
||||
// Type code for multi-value block types.
|
||||
static const uint8_t kMultivalBlock = 0x41;
|
||||
|
||||
// We reuse the internal machine type to represent WebAssembly types.
|
||||
// A typedef improves readability without adding a whole new type system.
|
||||
using ValueType = MachineRepresentation;
|
||||
|
@ -103,10 +103,8 @@ void PrintWasmText(const WasmModule* module, const ModuleWireBytes& wire_bytes,
|
||||
case kExprTry: {
|
||||
BlockTypeOperand<false> operand(&i, i.pc());
|
||||
os << WasmOpcodes::OpcodeName(opcode);
|
||||
if (operand.type == kWasmVar) {
|
||||
os << " (type " << operand.sig_index << ")";
|
||||
} else if (operand.out_arity() > 0) {
|
||||
os << " " << WasmOpcodes::TypeName(operand.out_type(0));
|
||||
for (unsigned i = 0; i < operand.arity; i++) {
|
||||
os << " " << WasmOpcodes::TypeName(operand.read_entry(i));
|
||||
}
|
||||
control_depth++;
|
||||
break;
|
||||
|
@ -96,10 +96,7 @@ WASM_EXEC_TEST(Int32Add_P_fallthru) {
|
||||
|
||||
static void RunInt32AddTest(WasmExecutionMode execution_mode, const byte* code,
|
||||
size_t size) {
|
||||
TestSignatures sigs;
|
||||
WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
|
||||
r.builder().AddSignature(sigs.ii_v());
|
||||
r.builder().AddSignature(sigs.iii_v());
|
||||
r.Build(code, code + size);
|
||||
FOR_INT32_INPUTS(i) {
|
||||
FOR_INT32_INPUTS(j) {
|
||||
@ -120,7 +117,7 @@ WASM_EXEC_TEST(Int32Add_P2) {
|
||||
WASM_EXEC_TEST(Int32Add_block1) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(mv);
|
||||
static const byte code[] = {
|
||||
WASM_BLOCK_TT(0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
kExprI32Add};
|
||||
RunInt32AddTest(execution_mode, code, sizeof(code));
|
||||
}
|
||||
@ -128,7 +125,8 @@ WASM_EXEC_TEST(Int32Add_block1) {
|
||||
WASM_EXEC_TEST(Int32Add_block2) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(mv);
|
||||
static const byte code[] = {
|
||||
WASM_BLOCK_TT(0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), kExprBr, DEPTH_0),
|
||||
WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
|
||||
kExprBr, DEPTH_0),
|
||||
kExprI32Add};
|
||||
RunInt32AddTest(execution_mode, code, sizeof(code));
|
||||
}
|
||||
@ -136,7 +134,7 @@ WASM_EXEC_TEST(Int32Add_block2) {
|
||||
WASM_EXEC_TEST(Int32Add_multi_if) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(mv);
|
||||
static const byte code[] = {
|
||||
WASM_IF_ELSE_TT(0, WASM_GET_LOCAL(0),
|
||||
WASM_IF_ELSE_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
|
||||
WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
|
||||
kExprI32Add};
|
||||
|
@ -38,9 +38,7 @@ class TestSignatures {
|
||||
sig_v_i(0, 1, kIntTypes4),
|
||||
sig_v_ii(0, 2, kIntTypes4),
|
||||
sig_v_iii(0, 3, kIntTypes4),
|
||||
sig_s_i(1, 1, kSimd128IntTypes4),
|
||||
sig_ii_v(2, 0, kIntTypes4),
|
||||
sig_iii_v(3, 0, kIntTypes4) {
|
||||
sig_s_i(1, 1, kSimd128IntTypes4) {
|
||||
// I used C++ and you won't believe what happened next....
|
||||
for (int i = 0; i < 4; i++) kIntTypes4[i] = kWasmI32;
|
||||
for (int i = 0; i < 4; i++) kLongTypes4[i] = kWasmI64;
|
||||
@ -82,9 +80,6 @@ class TestSignatures {
|
||||
FunctionSig* v_iii() { return &sig_v_iii; }
|
||||
FunctionSig* s_i() { return &sig_s_i; }
|
||||
|
||||
FunctionSig* ii_v() { return &sig_ii_v; }
|
||||
FunctionSig* iii_v() { return &sig_iii_v; }
|
||||
|
||||
FunctionSig* many(Zone* zone, ValueType ret, ValueType param, int count) {
|
||||
FunctionSig::Builder builder(zone, ret == kWasmStmt ? 0 : 1, count);
|
||||
if (ret != kWasmStmt) builder.AddReturn(ret);
|
||||
@ -129,9 +124,6 @@ class TestSignatures {
|
||||
FunctionSig sig_v_ii;
|
||||
FunctionSig sig_v_iii;
|
||||
FunctionSig sig_s_i;
|
||||
|
||||
FunctionSig sig_ii_v;
|
||||
FunctionSig sig_iii_v;
|
||||
};
|
||||
} // namespace wasm
|
||||
} // namespace internal
|
||||
|
@ -70,17 +70,21 @@
|
||||
#define ARITY_2 2
|
||||
|
||||
#define WASM_BLOCK(...) kExprBlock, kLocalVoid, __VA_ARGS__, kExprEnd
|
||||
#define WASM_BLOCK_I(...) kExprBlock, kLocalI32, __VA_ARGS__, kExprEnd
|
||||
#define WASM_BLOCK_L(...) kExprBlock, kLocalI64, __VA_ARGS__, kExprEnd
|
||||
#define WASM_BLOCK_F(...) kExprBlock, kLocalF32, __VA_ARGS__, kExprEnd
|
||||
#define WASM_BLOCK_D(...) kExprBlock, kLocalF64, __VA_ARGS__, kExprEnd
|
||||
|
||||
#define WASM_BLOCK_T(t, ...) \
|
||||
kExprBlock, static_cast<byte>(WasmOpcodes::ValueTypeCodeFor(t)), \
|
||||
__VA_ARGS__, kExprEnd
|
||||
|
||||
#define WASM_BLOCK_TT(index, ...) \
|
||||
kExprBlock, static_cast<byte>(index), __VA_ARGS__, kExprEnd
|
||||
#define WASM_BLOCK_TT(t1, t2, ...) \
|
||||
kExprBlock, kMultivalBlock, 0, \
|
||||
static_cast<byte>(WasmOpcodes::ValueTypeCodeFor(t1)), \
|
||||
static_cast<byte>(WasmOpcodes::ValueTypeCodeFor(t2)), __VA_ARGS__, \
|
||||
kExprEnd
|
||||
|
||||
#define WASM_BLOCK_I(...) kExprBlock, kLocalI32, __VA_ARGS__, kExprEnd
|
||||
#define WASM_BLOCK_L(...) kExprBlock, kLocalI64, __VA_ARGS__, kExprEnd
|
||||
#define WASM_BLOCK_F(...) kExprBlock, kLocalF32, __VA_ARGS__, kExprEnd
|
||||
#define WASM_BLOCK_D(...) kExprBlock, kLocalF64, __VA_ARGS__, kExprEnd
|
||||
|
||||
#define WASM_INFINITE_LOOP kExprLoop, kLocalVoid, kExprBr, DEPTH_0, kExprEnd
|
||||
|
||||
@ -90,13 +94,6 @@
|
||||
#define WASM_LOOP_F(...) kExprLoop, kLocalF32, __VA_ARGS__, kExprEnd
|
||||
#define WASM_LOOP_D(...) kExprLoop, kLocalF64, __VA_ARGS__, kExprEnd
|
||||
|
||||
#define WASM_LOOP_T(t, ...) \
|
||||
kExprLoop, static_cast<byte>(WasmOpcodes::ValueTypeCodeFor(t)), \
|
||||
__VA_ARGS__, kExprEnd
|
||||
|
||||
#define WASM_LOOP_TT(index, ...) \
|
||||
kExprLoop, static_cast<byte>(index), __VA_ARGS__, kExprEnd
|
||||
|
||||
#define WASM_IF(cond, tstmt) cond, kExprIf, kLocalVoid, tstmt, kExprEnd
|
||||
|
||||
#define WASM_IF_ELSE(cond, tstmt, fstmt) \
|
||||
@ -106,8 +103,11 @@
|
||||
cond, kExprIf, static_cast<byte>(WasmOpcodes::ValueTypeCodeFor(t)), tstmt, \
|
||||
kExprElse, fstmt, kExprEnd
|
||||
|
||||
#define WASM_IF_ELSE_TT(index, cond, tstmt, fstmt) \
|
||||
cond, kExprIf, static_cast<byte>(index), tstmt, kExprElse, fstmt, kExprEnd
|
||||
#define WASM_IF_ELSE_TT(t1, t2, cond, tstmt, fstmt) \
|
||||
cond, kExprIf, kMultivalBlock, 0, \
|
||||
static_cast<byte>(WasmOpcodes::ValueTypeCodeFor(t1)), \
|
||||
static_cast<byte>(WasmOpcodes::ValueTypeCodeFor(t2)), tstmt, kExprElse, \
|
||||
fstmt, kExprEnd
|
||||
|
||||
#define WASM_IF_ELSE_I(cond, tstmt, fstmt) \
|
||||
cond, kExprIf, kLocalI32, tstmt, kExprElse, fstmt, kExprEnd
|
||||
|
@ -2387,127 +2387,45 @@ TEST_F(FunctionBodyDecoderTest, TryCatch) {
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, MultiValBlock1) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(mv);
|
||||
TestModuleBuilder builder;
|
||||
module = builder.module();
|
||||
byte f0 = builder.AddSignature(sigs.ii_v());
|
||||
EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
|
||||
WASM_GET_LOCAL(1)),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(i_ii, WASM_BLOCK_TT(f0, WASM_NOP), kExprI32Add);
|
||||
EXPECT_FAILURE(i_ii, WASM_BLOCK_TT(f0, WASM_GET_LOCAL(0)), kExprI32Add);
|
||||
EXPECT_FAILURE(i_ii, WASM_BLOCK_TT(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
|
||||
WASM_GET_LOCAL(0)),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(i_ii, WASM_BLOCK_TT(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
kExprF32Add);
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, MultiValBlock2) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(mv);
|
||||
TestModuleBuilder builder;
|
||||
module = builder.module();
|
||||
byte f0 = builder.AddSignature(sigs.ii_v());
|
||||
EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
|
||||
WASM_GET_LOCAL(1)),
|
||||
WASM_I32_ADD(WASM_NOP, WASM_NOP));
|
||||
EXPECT_FAILURE(i_ii, WASM_BLOCK_TT(f0, WASM_NOP),
|
||||
WASM_I32_ADD(WASM_NOP, WASM_NOP));
|
||||
EXPECT_FAILURE(i_ii, WASM_BLOCK_TT(f0, WASM_GET_LOCAL(0)),
|
||||
WASM_I32_ADD(WASM_NOP, WASM_NOP));
|
||||
EXPECT_FAILURE(i_ii, WASM_BLOCK_TT(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
|
||||
WASM_GET_LOCAL(0)),
|
||||
WASM_I32_ADD(WASM_NOP, WASM_NOP));
|
||||
EXPECT_FAILURE(i_ii, WASM_BLOCK_TT(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
WASM_F32_ADD(WASM_NOP, WASM_NOP));
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, MultiValBlockBr) {
|
||||
TEST_F(FunctionBodyDecoderTest, MultiValBlockBr1) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(mv);
|
||||
TestModuleBuilder builder;
|
||||
module = builder.module();
|
||||
byte f0 = builder.AddSignature(sigs.ii_v());
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_BLOCK_TT(f0, WASM_GET_LOCAL(0), WASM_BR(0)), kExprI32Add);
|
||||
EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(f0, WASM_GET_LOCAL(0),
|
||||
i_ii, WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), WASM_BR(0)),
|
||||
kExprI32Add);
|
||||
EXPECT_VERIFIES(i_ii, WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
|
||||
WASM_GET_LOCAL(1), WASM_BR(0)),
|
||||
kExprI32Add);
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, MultiValLoop1) {
|
||||
TEST_F(FunctionBodyDecoderTest, MultiValIf1) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(mv);
|
||||
TestModuleBuilder builder;
|
||||
module = builder.module();
|
||||
byte f0 = builder.AddSignature(sigs.ii_v());
|
||||
EXPECT_VERIFIES(i_ii, WASM_LOOP_TT(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(i_ii, WASM_LOOP_TT(f0, WASM_NOP), kExprI32Add);
|
||||
EXPECT_FAILURE(i_ii, WASM_LOOP_TT(f0, WASM_GET_LOCAL(0)), kExprI32Add);
|
||||
EXPECT_FAILURE(i_ii, WASM_LOOP_TT(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
|
||||
WASM_GET_LOCAL(0)),
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_IF_ELSE_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
|
||||
WASM_SEQ(WASM_GET_LOCAL(0)),
|
||||
WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(i_ii,
|
||||
WASM_IF_ELSE_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
|
||||
WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
WASM_SEQ(WASM_GET_LOCAL(1))),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(i_ii, WASM_LOOP_TT(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
kExprF32Add);
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, MultiValIf) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(mv);
|
||||
TestModuleBuilder builder;
|
||||
module = builder.module();
|
||||
byte f0 = builder.AddSignature(sigs.ii_v());
|
||||
EXPECT_VERIFIES(
|
||||
i_ii, WASM_IF_ELSE_TT(f0, WASM_GET_LOCAL(0),
|
||||
i_ii, WASM_IF_ELSE_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
|
||||
WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_IF_ELSE_TT(f0, WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_IF_ELSE_TT(f0, WASM_GET_LOCAL(0),
|
||||
WASM_NOP,
|
||||
WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_IF_ELSE_TT(f0, WASM_GET_LOCAL(0),
|
||||
WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
WASM_NOP),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_IF_ELSE_TT(f0, WASM_GET_LOCAL(0),
|
||||
WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_IF_ELSE_TT(f0, WASM_GET_LOCAL(0),
|
||||
WASM_GET_LOCAL(0),
|
||||
WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_IF_ELSE_TT(f0, WASM_GET_LOCAL(0),
|
||||
WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
WASM_GET_LOCAL(1)),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_IF_ELSE_TT(f0, WASM_GET_LOCAL(0),
|
||||
WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
|
||||
WASM_GET_LOCAL(0)),
|
||||
WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0),
|
||||
WASM_GET_LOCAL(0))),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_IF_ELSE_TT(f0, WASM_GET_LOCAL(0),
|
||||
WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
|
||||
WASM_GET_LOCAL(0)),
|
||||
WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_IF_ELSE_TT(f0, WASM_GET_LOCAL(0),
|
||||
WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(1),
|
||||
WASM_GET_LOCAL(1))),
|
||||
kExprI32Add);
|
||||
EXPECT_FAILURE(
|
||||
i_ii, WASM_IF_ELSE_TT(f0, WASM_GET_LOCAL(0),
|
||||
WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
|
||||
WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
|
||||
kExprF32Add);
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, Regression709741) {
|
||||
|
Loading…
Reference in New Issue
Block a user