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