Commit 685d4882 authored by ahaas's avatar ahaas Committed by Commit bot

[wasm] Do not support grow_memory for asmjs modules.

With this CL the AstDecoder produces an error if it encounters a
grow_memory instruction in an asmjs module. Additionally asmjs
instructions are not allowed anymore in wasm modules.

BUG=chromium:644674
R=titzer@chromium.org

Review-Url: https://codereview.chromium.org/2324733002
Cr-Commit-Position: refs/heads/master@{#39339}
parent f0a0c432
......@@ -932,8 +932,6 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input,
return BuildI64UConvertF32(input, position);
case wasm::kExprI64UConvertF64:
return BuildI64UConvertF64(input, position);
case wasm::kExprGrowMemory:
return BuildGrowMemory(input);
case wasm::kExprI32AsmjsLoadMem8S:
return BuildAsmjsLoadMem(MachineType::Int8(), input);
case wasm::kExprI32AsmjsLoadMem8U:
......@@ -1667,7 +1665,7 @@ Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction(
return load;
}
Node* WasmGraphBuilder::BuildGrowMemory(Node* input) {
Node* WasmGraphBuilder::GrowMemory(Node* input) {
Diamond check_input_range(
graph(), jsgraph()->common(),
graph()->NewNode(
......
......@@ -133,6 +133,7 @@ class WasmGraphBuilder {
wasm::WasmCodePosition position = wasm::kNoCodePosition);
Node* Unop(wasm::WasmOpcode opcode, Node* input,
wasm::WasmCodePosition position = wasm::kNoCodePosition);
Node* GrowMemory(Node* input);
unsigned InputCount(Node* node);
bool IsPhiWithMerge(Node* phi, Node* merge);
void AppendToMerge(Node* merge, Node* from);
......@@ -319,7 +320,6 @@ class WasmGraphBuilder {
Node* BuildAllocateHeapNumberWithValue(Node* value, Node* control);
Node* BuildLoadHeapNumberValue(Node* value, Node* control);
Node* BuildHeapNumberValueIndexConstant();
Node* BuildGrowMemory(Node* input);
// Asm.js specific functionality.
Node* BuildI32AsmjsSConvertF32(Node* input);
......
......@@ -721,26 +721,7 @@ class WasmFullDecoder : public WasmDecoder {
FunctionSig* sig = WasmOpcodes::Signature(opcode);
if (sig) {
// Fast case of a simple operator.
TFNode* node;
switch (sig->parameter_count()) {
case 1: {
Value val = Pop(0, sig->GetParam(0));
node = BUILD(Unop, opcode, val.node, position());
break;
}
case 2: {
Value rval = Pop(1, sig->GetParam(1));
Value lval = Pop(0, sig->GetParam(0));
node = BUILD(Binop, opcode, lval.node, rval.node, position());
break;
}
default:
UNREACHABLE();
node = nullptr;
break;
}
Push(GetReturnType(sig), node);
BuildSimpleOperator(opcode, sig);
} else {
// Complex bytecode.
switch (opcode) {
......@@ -1236,7 +1217,14 @@ class WasmFullDecoder : public WasmDecoder {
case kExprF64StoreMem:
len = DecodeStoreMem(kAstF64, MachineType::Float64());
break;
case kExprGrowMemory:
if (module_->origin != kAsmJsOrigin) {
Value val = Pop(0, kAstI32);
Push(kAstI32, BUILD(GrowMemory, val.node));
} else {
error("grow_memory is not supported for asmjs modules");
}
break;
case kExprMemorySize:
Push(kAstI32, BUILD(MemSize, 0));
break;
......@@ -1286,8 +1274,16 @@ class WasmFullDecoder : public WasmDecoder {
break;
}
default:
error("Invalid opcode");
return;
// Deal with special asmjs opcodes.
if (module_->origin == kAsmJsOrigin) {
sig = WasmOpcodes::AsmjsSignature(opcode);
if (sig) {
BuildSimpleOperator(opcode, sig);
}
} else {
error("Invalid opcode");
return;
}
}
} // end complex bytecode
......@@ -1914,6 +1910,28 @@ class WasmFullDecoder : public WasmDecoder {
DCHECK_EQ(pc_ - start_, offset); // overflows cannot happen
return offset;
}
inline void BuildSimpleOperator(WasmOpcode opcode, FunctionSig* sig) {
TFNode* node;
switch (sig->parameter_count()) {
case 1: {
Value val = Pop(0, sig->GetParam(0));
node = BUILD(Unop, opcode, val.node, position());
break;
}
case 2: {
Value rval = Pop(1, sig->GetParam(1));
Value lval = Pop(0, sig->GetParam(0));
node = BUILD(Binop, opcode, lval.node, rval.node, position());
break;
}
default:
UNREACHABLE();
node = nullptr;
break;
}
Push(GetReturnType(sig), node);
}
};
bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start,
......
......@@ -86,6 +86,7 @@ static const FunctionSig* kSimdExprSigs[] = {
nullptr, FOREACH_SIMD_SIGNATURE(DECLARE_SIMD_SIG_ENTRY)};
static byte kSimpleExprSigTable[256];
static byte kSimpleAsmjsExprSigTable[256];
static byte kSimdExprSigTable[256];
// Initialize the signature table.
......@@ -93,9 +94,11 @@ static void InitSigTables() {
#define SET_SIG_TABLE(name, opcode, sig) \
kSimpleExprSigTable[opcode] = static_cast<int>(kSigEnum_##sig) + 1;
FOREACH_SIMPLE_OPCODE(SET_SIG_TABLE);
FOREACH_SIMPLE_MEM_OPCODE(SET_SIG_TABLE);
FOREACH_ASMJS_COMPAT_OPCODE(SET_SIG_TABLE);
#undef SET_SIG_TABLE
#define SET_ASMJS_SIG_TABLE(name, opcode, sig) \
kSimpleAsmjsExprSigTable[opcode] = static_cast<int>(kSigEnum_##sig) + 1;
FOREACH_ASMJS_COMPAT_OPCODE(SET_ASMJS_SIG_TABLE);
#undef SET_ASMJS_SIG_TABLE
byte simd_index;
#define SET_SIG_TABLE(name, opcode, sig) \
simd_index = opcode & 0xff; \
......@@ -114,6 +117,10 @@ class SigTable {
return const_cast<FunctionSig*>(
kSimpleExprSigs[kSimpleExprSigTable[static_cast<byte>(opcode)]]);
}
FunctionSig* AsmjsSignature(WasmOpcode opcode) const {
return const_cast<FunctionSig*>(
kSimpleExprSigs[kSimpleAsmjsExprSigTable[static_cast<byte>(opcode)]]);
}
FunctionSig* SimdSignature(WasmOpcode opcode) const {
return const_cast<FunctionSig*>(
kSimdExprSigs[kSimdExprSigTable[static_cast<byte>(opcode & 0xff)]]);
......@@ -130,6 +137,10 @@ FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) {
}
}
FunctionSig* WasmOpcodes::AsmjsSignature(WasmOpcode opcode) {
return sig_table.Get().AsmjsSignature(opcode);
}
// TODO(titzer): pull WASM_64 up to a common header.
#if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64
#define WASM_64 1
......
......@@ -490,6 +490,7 @@ class WasmOpcodes {
static const char* OpcodeName(WasmOpcode opcode);
static const char* ShortOpcodeName(WasmOpcode opcode);
static FunctionSig* Signature(WasmOpcode opcode);
static FunctionSig* AsmjsSignature(WasmOpcode opcode);
static bool IsPrefixOpcode(WasmOpcode opcode);
static int TrapReasonToMessageId(TrapReason reason);
......
......@@ -38,8 +38,9 @@ uint32_t GetMatchingRelocInfoCount(Handle<Code> code, RelocInfo::Mode rmode) {
}
WASM_EXEC_TEST(Int32AsmjsDivS) {
WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
MachineType::Int32());
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
BUILD(r, WASM_BINOP(kExprI32AsmjsDivS, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min();
CHECK_EQ(0, r.Call(0, 100));
......@@ -50,8 +51,9 @@ WASM_EXEC_TEST(Int32AsmjsDivS) {
}
WASM_EXEC_TEST(Int32AsmjsRemS) {
WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
MachineType::Int32());
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
BUILD(r, WASM_BINOP(kExprI32AsmjsRemS, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min();
CHECK_EQ(33, r.Call(133, 100));
......@@ -62,8 +64,9 @@ WASM_EXEC_TEST(Int32AsmjsRemS) {
}
WASM_EXEC_TEST(Int32AsmjsDivU) {
WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
MachineType::Int32());
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
BUILD(r, WASM_BINOP(kExprI32AsmjsDivU, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min();
CHECK_EQ(0, r.Call(0, 100));
......@@ -74,8 +77,9 @@ WASM_EXEC_TEST(Int32AsmjsDivU) {
}
WASM_EXEC_TEST(Int32AsmjsRemU) {
WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
MachineType::Int32());
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
BUILD(r, WASM_BINOP(kExprI32AsmjsRemU, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min();
CHECK_EQ(17, r.Call(217, 100));
......@@ -86,7 +90,9 @@ WASM_EXEC_TEST(Int32AsmjsRemU) {
}
WASM_EXEC_TEST(I32AsmjsSConvertF32) {
WasmRunner<int32_t> r(execution_mode, MachineType::Float32());
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
WasmRunner<int32_t> r(&module, MachineType::Float32());
BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF32, WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) {
......@@ -96,7 +102,9 @@ WASM_EXEC_TEST(I32AsmjsSConvertF32) {
}
WASM_EXEC_TEST(I32AsmjsSConvertF64) {
WasmRunner<int32_t> r(execution_mode, MachineType::Float64());
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
WasmRunner<int32_t> r(&module, MachineType::Float64());
BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF64, WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) {
......@@ -106,7 +114,9 @@ WASM_EXEC_TEST(I32AsmjsSConvertF64) {
}
WASM_EXEC_TEST(I32AsmjsUConvertF32) {
WasmRunner<uint32_t> r(execution_mode, MachineType::Float32());
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
WasmRunner<uint32_t> r(&module, MachineType::Float32());
BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF32, WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) {
......@@ -116,7 +126,9 @@ WASM_EXEC_TEST(I32AsmjsUConvertF32) {
}
WASM_EXEC_TEST(I32AsmjsUConvertF64) {
WasmRunner<uint32_t> r(execution_mode, MachineType::Float64());
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
WasmRunner<uint32_t> r(&module, MachineType::Float64());
BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF64, WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) {
......@@ -127,6 +139,7 @@ WASM_EXEC_TEST(I32AsmjsUConvertF64) {
WASM_EXEC_TEST(LoadMemI32_oob_asm) {
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
int32_t* memory = module.AddMemoryElems<int32_t>(8);
WasmRunner<int32_t> r(&module, MachineType::Uint32());
module.RandomizeMemory(1112);
......@@ -147,6 +160,7 @@ WASM_EXEC_TEST(LoadMemI32_oob_asm) {
WASM_EXEC_TEST(LoadMemF32_oob_asm) {
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
float* memory = module.AddMemoryElems<float>(8);
WasmRunner<float> r(&module, MachineType::Uint32());
module.RandomizeMemory(1112);
......@@ -167,6 +181,7 @@ WASM_EXEC_TEST(LoadMemF32_oob_asm) {
WASM_EXEC_TEST(LoadMemF64_oob_asm) {
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
double* memory = module.AddMemoryElems<double>(8);
WasmRunner<double> r(&module, MachineType::Uint32());
module.RandomizeMemory(1112);
......@@ -189,6 +204,7 @@ WASM_EXEC_TEST(LoadMemF64_oob_asm) {
WASM_EXEC_TEST(StoreMemI32_oob_asm) {
TestingModule module(execution_mode);
module.origin = kAsmJsOrigin;
int32_t* memory = module.AddMemoryElems<int32_t>(8);
WasmRunner<int32_t> r(&module, MachineType::Uint32(), MachineType::Uint32());
module.RandomizeMemory(1112);
......@@ -224,6 +240,7 @@ WASM_EXEC_TEST(StoreMemI32_oob_asm) {
#define INT_LOAD_TEST(OP_TYPE) \
TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \
TestingModule module(kExecuteCompiled); \
module.origin = kAsmJsOrigin; \
WasmRunner<int32_t> r(&module, MachineType::Uint32()); \
BUILD(r, WASM_UNOP(OP_TYPE, WASM_GET_LOCAL(0))); \
CHECK_EQ(1, GetMatchingRelocInfoCount(module.instance->function_code[0], \
......@@ -238,6 +255,7 @@ FOREACH_INT_CHECKED_LOAD_OP(INT_LOAD_TEST)
#define INT_STORE_TEST(OP_TYPE) \
TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \
TestingModule module(kExecuteCompiled); \
module.origin = kAsmJsOrigin; \
WasmRunner<int32_t> r(&module, MachineType::Uint32(), \
MachineType::Uint32()); \
BUILD(r, WASM_BINOP(OP_TYPE, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); \
......@@ -252,6 +270,7 @@ FOREACH_INT_CHECKED_STORE_OP(INT_STORE_TEST)
TEST(RunWasm_AsmCheckedLoadFloat32RelocInfo) {
TestingModule module(kExecuteCompiled);
module.origin = kAsmJsOrigin;
WasmRunner<float> r(&module, MachineType::Uint32());
BUILD(r, WASM_UNOP(kExprF32AsmjsLoadMem, WASM_GET_LOCAL(0)));
......@@ -263,6 +282,7 @@ TEST(RunWasm_AsmCheckedLoadFloat32RelocInfo) {
TEST(RunWasm_AsmCheckedStoreFloat32RelocInfo) {
TestingModule module(kExecuteCompiled);
module.origin = kAsmJsOrigin;
WasmRunner<float> r(&module, MachineType::Uint32(), MachineType::Float32());
BUILD(r, WASM_BINOP(kExprF32AsmjsStoreMem, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1)));
......@@ -275,6 +295,7 @@ TEST(RunWasm_AsmCheckedStoreFloat32RelocInfo) {
TEST(RunWasm_AsmCheckedLoadFloat64RelocInfo) {
TestingModule module(kExecuteCompiled);
module.origin = kAsmJsOrigin;
WasmRunner<double> r(&module, MachineType::Uint32());
BUILD(r, WASM_UNOP(kExprF64AsmjsLoadMem, WASM_GET_LOCAL(0)));
......@@ -286,6 +307,7 @@ TEST(RunWasm_AsmCheckedLoadFloat64RelocInfo) {
TEST(RunWasm_AsmCheckedStoreFloat64RelocInfo) {
TestingModule module(kExecuteCompiled);
module.origin = kAsmJsOrigin;
WasmRunner<double> r(&module, MachineType::Uint32(), MachineType::Float64());
BUILD(r, WASM_BINOP(kExprF64AsmjsStoreMem, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1)));
......
......@@ -30,7 +30,9 @@ class TestSignatures {
sig_l_l(1, 1, kLongTypes4),
sig_l_ll(1, 2, kLongTypes4),
sig_i_ll(1, 2, kIntLongTypes4),
sig_f_f(1, 1, kFloatTypes4),
sig_f_ff(1, 2, kFloatTypes4),
sig_d_d(1, 1, kDoubleTypes4),
sig_d_dd(1, 2, kDoubleTypes4),
sig_v_v(0, 0, kIntTypes4),
sig_v_i(0, 1, kIntTypes4),
......@@ -67,7 +69,9 @@ class TestSignatures {
FunctionSig* l_ll() { return &sig_l_ll; }
FunctionSig* i_ll() { return &sig_i_ll; }
FunctionSig* f_f() { return &sig_f_f; }
FunctionSig* f_ff() { return &sig_f_ff; }
FunctionSig* d_d() { return &sig_d_d; }
FunctionSig* d_dd() { return &sig_d_dd; }
FunctionSig* v_v() { return &sig_v_v; }
......@@ -110,7 +114,9 @@ class TestSignatures {
FunctionSig sig_l_ll;
FunctionSig sig_i_ll;
FunctionSig sig_f_f;
FunctionSig sig_f_ff;
FunctionSig sig_d_d;
FunctionSig sig_d_dd;
FunctionSig sig_v_v;
......
......@@ -13,6 +13,7 @@
#include "src/wasm/ast-decoder.h"
#include "src/wasm/wasm-macro-gen.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-opcodes.h"
namespace v8 {
namespace internal {
......@@ -1079,12 +1080,6 @@ TEST_F(AstDecoderTest, MemorySize) {
EXPECT_FAILURE(sigs.f_ff(), code);
}
TEST_F(AstDecoderTest, GrowMemory) {
byte code[] = {WASM_UNOP(kExprGrowMemory, WASM_GET_LOCAL(0))};
EXPECT_VERIFIES(sigs.i_i(), code);
EXPECT_FAILURE(sigs.i_d(), code);
}
TEST_F(AstDecoderTest, LoadMemOffset) {
for (int offset = 0; offset < 128; offset += 7) {
byte code[] = {kExprI8Const, 0, kExprI32LoadMem, ZERO_ALIGNMENT,
......@@ -1499,6 +1494,116 @@ TEST_F(AstDecoderTest, AllSetGlobalCombinations) {
}
}
TEST_F(AstDecoderTest, WasmGrowMemory) {
TestModuleEnv module_env;
module = &module_env;
module->origin = kWasmOrigin;
byte code[] = {WASM_UNOP(kExprGrowMemory, WASM_GET_LOCAL(0))};
EXPECT_VERIFIES(sigs.i_i(), code);
EXPECT_FAILURE(sigs.i_d(), code);
}
TEST_F(AstDecoderTest, AsmJsGrowMemory) {
TestModuleEnv module_env;
module = &module_env;
module->origin = kAsmJsOrigin;
byte code[] = {WASM_UNOP(kExprGrowMemory, WASM_GET_LOCAL(0))};
EXPECT_FAILURE(sigs.i_i(), code);
}
TEST_F(AstDecoderTest, AsmJsBinOpsCheckOrigin) {
LocalType float32int32float32[] = {kAstF32, kAstI32, kAstF32};
FunctionSig sig_f_if(1, 2, float32int32float32);
LocalType float64int32float64[] = {kAstF64, kAstI32, kAstF64};
FunctionSig sig_d_id(1, 2, float64int32float64);
struct {
WasmOpcode op;
FunctionSig* sig;
} AsmJsBinOps[] = {
{kExprF64Atan2, sigs.d_dd()},
{kExprF64Pow, sigs.d_dd()},
{kExprF64Mod, sigs.d_dd()},
{kExprI32AsmjsDivS, sigs.i_ii()},
{kExprI32AsmjsDivU, sigs.i_ii()},
{kExprI32AsmjsRemS, sigs.i_ii()},
{kExprI32AsmjsRemU, sigs.i_ii()},
{kExprI32AsmjsStoreMem8, sigs.i_ii()},
{kExprI32AsmjsStoreMem16, sigs.i_ii()},
{kExprI32AsmjsStoreMem, sigs.i_ii()},
{kExprF32AsmjsStoreMem, &sig_f_if},
{kExprF64AsmjsStoreMem, &sig_d_id},
};
{
TestModuleEnv module_env;
module = &module_env;
module->origin = kAsmJsOrigin;
for (int i = 0; i < arraysize(AsmJsBinOps); i++) {
TestBinop(AsmJsBinOps[i].op, AsmJsBinOps[i].sig);
}
}
{
TestModuleEnv module_env;
module = &module_env;
module->origin = kWasmOrigin;
for (int i = 0; i < arraysize(AsmJsBinOps); i++) {
byte code[] = {
WASM_BINOP(AsmJsBinOps[i].op, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))};
EXPECT_FAILURE(AsmJsBinOps[i].sig, code);
}
}
}
TEST_F(AstDecoderTest, AsmJsUnOpsCheckOrigin) {
LocalType float32int32[] = {kAstF32, kAstI32};
FunctionSig sig_f_i(1, 2, float32int32);
LocalType float64int32[] = {kAstF64, kAstI32};
FunctionSig sig_d_i(1, 2, float64int32);
struct {
WasmOpcode op;
FunctionSig* sig;
} AsmJsUnOps[] = {{kExprF64Acos, sigs.d_d()},
{kExprF64Asin, sigs.d_d()},
{kExprF64Atan, sigs.d_d()},
{kExprF64Cos, sigs.d_d()},
{kExprF64Sin, sigs.d_d()},
{kExprF64Tan, sigs.d_d()},
{kExprF64Exp, sigs.d_d()},
{kExprF64Log, sigs.d_d()},
{kExprI32AsmjsLoadMem8S, sigs.i_i()},
{kExprI32AsmjsLoadMem8U, sigs.i_i()},
{kExprI32AsmjsLoadMem16S, sigs.i_i()},
{kExprI32AsmjsLoadMem16U, sigs.i_i()},
{kExprI32AsmjsLoadMem, sigs.i_i()},
{kExprF32AsmjsLoadMem, &sig_f_i},
{kExprF64AsmjsLoadMem, &sig_d_i},
{kExprI32AsmjsSConvertF32, sigs.i_f()},
{kExprI32AsmjsUConvertF32, sigs.i_f()},
{kExprI32AsmjsSConvertF64, sigs.i_d()},
{kExprI32AsmjsUConvertF64, sigs.i_d()}};
{
TestModuleEnv module_env;
module = &module_env;
module->origin = kAsmJsOrigin;
for (int i = 0; i < arraysize(AsmJsUnOps); i++) {
TestUnop(AsmJsUnOps[i].op, AsmJsUnOps[i].sig);
}
}
{
TestModuleEnv module_env;
module = &module_env;
module->origin = kWasmOrigin;
for (int i = 0; i < arraysize(AsmJsUnOps); i++) {
byte code[] = {WASM_UNOP(AsmJsUnOps[i].op, WASM_GET_LOCAL(0))};
EXPECT_FAILURE(AsmJsUnOps[i].sig, code);
}
}
}
TEST_F(AstDecoderTest, BreakEnd) {
EXPECT_VERIFIES_INLINE(sigs.i_i(),
B1(WASM_I32_ADD(WASM_BRV(0, WASM_ZERO), WASM_ZERO)));
......
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