[wasm] Fix and tighten memory validation
Makes us pass the spec's memory.wast test. R=titzer@chromium.org BUG= Review-Url: https://codereview.chromium.org/2640453003 Cr-Commit-Position: refs/heads/master@{#42452}
This commit is contained in:
parent
3c89788373
commit
b86ef5ce8a
@ -622,6 +622,13 @@ class WasmFullDecoder : public WasmDecoder {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
bool CheckHasMemory() {
|
||||
if (!module_->has_memory) {
|
||||
error(pc_ - 1, "memory instruction with no memory");
|
||||
}
|
||||
return module_->has_memory;
|
||||
}
|
||||
|
||||
// Decodes the body of a function.
|
||||
void DecodeFunctionBody() {
|
||||
TRACE("wasm-decode %p...%p (module+%d, %d bytes) %s\n",
|
||||
@ -1112,6 +1119,7 @@ class WasmFullDecoder : public WasmDecoder {
|
||||
len = DecodeStoreMem(kWasmF64, MachineType::Float64());
|
||||
break;
|
||||
case kExprGrowMemory: {
|
||||
if (!CheckHasMemory()) break;
|
||||
MemoryIndexOperand operand(this, pc_);
|
||||
DCHECK_NOT_NULL(module_);
|
||||
if (module_->origin != kAsmJsOrigin) {
|
||||
@ -1124,6 +1132,7 @@ class WasmFullDecoder : public WasmDecoder {
|
||||
break;
|
||||
}
|
||||
case kExprMemorySize: {
|
||||
if (!CheckHasMemory()) break;
|
||||
MemoryIndexOperand operand(this, pc_);
|
||||
Push(kWasmI32, BUILD(CurrentMemoryPages));
|
||||
len = 1 + operand.length;
|
||||
@ -1304,6 +1313,7 @@ class WasmFullDecoder : public WasmDecoder {
|
||||
void PopControl() { control_.pop_back(); }
|
||||
|
||||
int DecodeLoadMem(ValueType type, MachineType mem_type) {
|
||||
if (!CheckHasMemory()) return 0;
|
||||
MemoryAccessOperand operand(this, pc_,
|
||||
ElementSizeLog2Of(mem_type.representation()));
|
||||
|
||||
@ -1315,6 +1325,7 @@ class WasmFullDecoder : public WasmDecoder {
|
||||
}
|
||||
|
||||
int DecodeStoreMem(ValueType type, MachineType mem_type) {
|
||||
if (!CheckHasMemory()) return 0;
|
||||
MemoryAccessOperand operand(this, pc_,
|
||||
ElementSizeLog2Of(mem_type.representation()));
|
||||
Value val = Pop(1, type);
|
||||
|
@ -308,7 +308,10 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
|
||||
MaybeLocal<Value> instance =
|
||||
InstantiateModuleImpl(i_isolate, i_module_obj, args, &thrower);
|
||||
if (instance.IsEmpty()) return;
|
||||
if (instance.IsEmpty()) {
|
||||
DCHECK(thrower.error());
|
||||
return;
|
||||
}
|
||||
|
||||
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
||||
return_value.Set(instance.ToLocalChecked());
|
||||
|
@ -1293,7 +1293,7 @@ class WasmInstanceBuilder {
|
||||
Address mem_start = static_cast<Address>(memory_->backing_store());
|
||||
uint32_t mem_size =
|
||||
static_cast<uint32_t>(memory_->byte_length()->Number());
|
||||
LoadDataSegments(mem_start, mem_size);
|
||||
if (!LoadDataSegments(mem_start, mem_size)) return nothing;
|
||||
|
||||
uint32_t old_mem_size = compiled_module_->mem_size();
|
||||
Address old_mem_start =
|
||||
@ -1305,7 +1305,7 @@ class WasmInstanceBuilder {
|
||||
old_mem_size, mem_size);
|
||||
compiled_module_->set_memory(memory_);
|
||||
} else {
|
||||
LoadDataSegments(nullptr, 0);
|
||||
if (!LoadDataSegments(nullptr, 0)) return nothing;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -1545,7 +1545,7 @@ class WasmInstanceBuilder {
|
||||
}
|
||||
|
||||
// Load data segments into the memory.
|
||||
void LoadDataSegments(Address mem_addr, size_t mem_size) {
|
||||
bool LoadDataSegments(Address mem_addr, size_t mem_size) {
|
||||
Handle<SeqOneByteString> module_bytes(compiled_module_->module_bytes(),
|
||||
isolate_);
|
||||
for (const WasmDataSegment& segment : module_->data_segments) {
|
||||
@ -1553,18 +1553,19 @@ class WasmInstanceBuilder {
|
||||
// Segments of size == 0 are just nops.
|
||||
if (source_size == 0) continue;
|
||||
uint32_t dest_offset = EvalUint32InitExpr(segment.dest_addr);
|
||||
if (dest_offset >= mem_size || source_size >= mem_size ||
|
||||
dest_offset > (mem_size - source_size)) {
|
||||
if (dest_offset + source_size > mem_size ||
|
||||
dest_offset + source_size < dest_offset) {
|
||||
thrower_->LinkError("data segment (start = %" PRIu32 ", size = %" PRIu32
|
||||
") does not fit into memory (size = %" PRIuS ")",
|
||||
dest_offset, source_size, mem_size);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
byte* dest = mem_addr + dest_offset;
|
||||
const byte* src = reinterpret_cast<const byte*>(
|
||||
module_bytes->GetCharsAddress() + segment.source_offset);
|
||||
memcpy(dest, src, source_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WriteGlobalValue(WasmGlobal& global, Handle<Object> value) {
|
||||
|
@ -1808,6 +1808,7 @@ TEST(Build_Wasm_UnreachableIf2) {
|
||||
|
||||
WASM_EXEC_TEST(Unreachable_Load) {
|
||||
WasmRunner<int32_t, int32_t> r(execution_mode);
|
||||
r.module().AddMemory(0L);
|
||||
BUILD(r, WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)),
|
||||
WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))));
|
||||
CHECK_EQ(11, r.Call(11));
|
||||
|
@ -101,6 +101,7 @@ TEST(IllegalLoad) {
|
||||
TestSignatures sigs;
|
||||
// Set the execution context, such that a runtime error can be thrown.
|
||||
r.SetModuleContext();
|
||||
r.module().AddMemory(0L);
|
||||
|
||||
BUILD(r, WASM_IF(WASM_ONE, WASM_SEQ(WASM_LOAD_MEM(MachineType::Int32(),
|
||||
WASM_I32V_1(-3)),
|
||||
|
@ -105,8 +105,10 @@ class TestingModule : public ModuleEnv {
|
||||
void ChangeOriginToAsmjs() { module_.origin = kAsmJsOrigin; }
|
||||
|
||||
byte* AddMemory(uint32_t size) {
|
||||
CHECK(!module_.has_memory);
|
||||
CHECK_NULL(instance->mem_start);
|
||||
CHECK_EQ(0, instance->mem_size);
|
||||
module_.has_memory = true;
|
||||
instance->mem_start = reinterpret_cast<byte*>(malloc(size));
|
||||
CHECK(instance->mem_start);
|
||||
memset(instance->mem_start, 0, size);
|
||||
|
@ -9,6 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
|
||||
(function() {
|
||||
var builder = new WasmModuleBuilder();
|
||||
builder.addMemory(0, 0, false);
|
||||
builder.addFunction("test", kSig_i_iii)
|
||||
.addBody([
|
||||
kExprI32Const, 0x0b,
|
||||
|
@ -184,6 +184,7 @@ testGrowMemoryReadWrite8();
|
||||
|
||||
function testGrowMemoryZeroInitialSize() {
|
||||
var builder = genGrowMemoryBuilder();
|
||||
builder.addMemory(0, kV8MaxPages, false);
|
||||
var module = builder.instantiate();
|
||||
var offset;
|
||||
function peek() { return module.exports.load(offset); }
|
||||
@ -217,6 +218,7 @@ testGrowMemoryZeroInitialSize();
|
||||
|
||||
function testGrowMemoryZeroInitialSize32() {
|
||||
var builder = genGrowMemoryBuilder();
|
||||
builder.addMemory(0, kV8MaxPages, false);
|
||||
var module = builder.instantiate();
|
||||
var offset;
|
||||
function peek() { return module.exports.load(offset); }
|
||||
@ -242,6 +244,7 @@ testGrowMemoryZeroInitialSize32();
|
||||
|
||||
function testGrowMemoryZeroInitialSize16() {
|
||||
var builder = genGrowMemoryBuilder();
|
||||
builder.addMemory(0, kV8MaxPages, false);
|
||||
var module = builder.instantiate();
|
||||
var offset;
|
||||
function peek() { return module.exports.load16(offset); }
|
||||
@ -267,6 +270,7 @@ testGrowMemoryZeroInitialSize16();
|
||||
|
||||
function testGrowMemoryZeroInitialSize8() {
|
||||
var builder = genGrowMemoryBuilder();
|
||||
builder.addMemory(0, kV8MaxPages, false);
|
||||
var module = builder.instantiate();
|
||||
var offset;
|
||||
function peek() { return module.exports.load8(offset); }
|
||||
@ -292,6 +296,7 @@ testGrowMemoryZeroInitialSize8();
|
||||
|
||||
function testGrowMemoryTrapMaxPagesZeroInitialMemory() {
|
||||
var builder = genGrowMemoryBuilder();
|
||||
builder.addMemory(0, kV8MaxPages, false);
|
||||
var module = builder.instantiate();
|
||||
var maxPages = 16385;
|
||||
function growMem(pages) { return module.exports.grow_memory(pages); }
|
||||
@ -313,6 +318,7 @@ testGrowMemoryTrapMaxPages();
|
||||
|
||||
function testGrowMemoryTrapsWithNonSmiInput() {
|
||||
var builder = genGrowMemoryBuilder();
|
||||
builder.addMemory(0, kV8MaxPages, false);
|
||||
var module = builder.instantiate();
|
||||
function growMem(pages) { return module.exports.grow_memory(pages); }
|
||||
// The parameter of grow_memory is unsigned. Therefore -1 stands for
|
||||
|
@ -10,6 +10,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
(function testMemorySizeZero() {
|
||||
print("testMemorySizeZero()");
|
||||
var builder = new WasmModuleBuilder();
|
||||
builder.addMemory(0, 0, false);
|
||||
builder.addFunction("memory_size", kSig_i_v)
|
||||
.addBody([kExprMemorySize, kMemoryZero])
|
||||
.exportFunc();
|
||||
|
@ -42,6 +42,8 @@ function STACK() {
|
||||
|
||||
var builder = new WasmModuleBuilder();
|
||||
|
||||
builder.addMemory(0, 1, false);
|
||||
|
||||
builder.addImport("mod", "func", kSig_v_v);
|
||||
|
||||
builder.addFunction("main", kSig_v_v)
|
||||
@ -70,8 +72,8 @@ var module = builder.instantiate({mod: {func: STACK}});
|
||||
// The line numbers below will change as this test gains / loses lines..
|
||||
" at STACK (stack.js:39:11)\n" + // --
|
||||
" at main (<WASM>[1]+1)\n" + // --
|
||||
" at testSimpleStack (stack.js:76:18)\n" + // --
|
||||
" at stack.js:78:3"; // --
|
||||
" at testSimpleStack (stack.js:78:18)\n" + // --
|
||||
" at stack.js:80:3"; // --
|
||||
|
||||
module.exports.main();
|
||||
assertEquals(expected_string, stripPath(stack));
|
||||
@ -90,8 +92,8 @@ Error.prepareStackTrace = function(error, frames) {
|
||||
// isWasm function line pos file
|
||||
[ false, "STACK", 39, 0, "stack.js"],
|
||||
[ true, "main", 1, 1, null],
|
||||
[ false, "testStackFrames", 87, 0, "stack.js"],
|
||||
[ false, null, 96, 0, "stack.js"]
|
||||
[ false, "testStackFrames", 89, 0, "stack.js"],
|
||||
[ false, null, 98, 0, "stack.js"]
|
||||
]);
|
||||
})();
|
||||
|
||||
@ -104,8 +106,8 @@ Error.prepareStackTrace = function(error, frames) {
|
||||
verifyStack(e.stack, [
|
||||
// isWasm function line pos file
|
||||
[ true, "exec_unreachable", 2, 1, null],
|
||||
[ false, "testWasmUnreachable", 100, 0, "stack.js"],
|
||||
[ false, null, 111, 0, "stack.js"]
|
||||
[ false, "testWasmUnreachable", 102, 0, "stack.js"],
|
||||
[ false, null, 113, 0, "stack.js"]
|
||||
]);
|
||||
}
|
||||
})();
|
||||
@ -120,8 +122,8 @@ Error.prepareStackTrace = function(error, frames) {
|
||||
// isWasm function line pos file
|
||||
[ true, "", 3, 3, null],
|
||||
[ true, "call_mem_out_of_bounds", 4, 1, null],
|
||||
[ false, "testWasmMemOutOfBounds", 115, 0, "stack.js"],
|
||||
[ false, null, 127, 0, "stack.js"]
|
||||
[ false, "testWasmMemOutOfBounds", 117, 0, "stack.js"],
|
||||
[ false, null, 129, 0, "stack.js"]
|
||||
]);
|
||||
}
|
||||
})();
|
||||
|
@ -14,6 +14,8 @@ Error.prepareStackTrace = function(error, frames) {
|
||||
|
||||
var builder = new WasmModuleBuilder();
|
||||
|
||||
builder.addMemory(0, 1, false);
|
||||
|
||||
var sig_index = builder.addType(kSig_i_v)
|
||||
|
||||
// Build a function to resemble this code:
|
||||
|
@ -14,6 +14,8 @@ Error.prepareStackTrace = function(error, frames) {
|
||||
|
||||
var builder = new WasmModuleBuilder();
|
||||
|
||||
builder.addMemory(0, 1, false);
|
||||
|
||||
var sig_index = builder.addType(kSig_i_v)
|
||||
|
||||
// Build a function to resemble this code:
|
||||
|
@ -201,6 +201,60 @@ class FunctionBodyDecoderTest : public TestWithZone {
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
// A helper for tests that require a module environment for functions,
|
||||
// globals, or memories.
|
||||
class TestModuleEnv : public ModuleEnv {
|
||||
public:
|
||||
explicit TestModuleEnv(ModuleOrigin origin = kWasmOrigin)
|
||||
: ModuleEnv(&mod, nullptr) {
|
||||
mod.origin = origin;
|
||||
}
|
||||
byte AddGlobal(ValueType type, bool mutability = true) {
|
||||
mod.globals.push_back({type, mutability, WasmInitExpr(), 0, false, false});
|
||||
CHECK(mod.globals.size() <= 127);
|
||||
return static_cast<byte>(mod.globals.size() - 1);
|
||||
}
|
||||
byte AddSignature(FunctionSig* sig) {
|
||||
mod.signatures.push_back(sig);
|
||||
CHECK(mod.signatures.size() <= 127);
|
||||
return static_cast<byte>(mod.signatures.size() - 1);
|
||||
}
|
||||
byte AddFunction(FunctionSig* sig) {
|
||||
mod.functions.push_back({sig, // sig
|
||||
0, // func_index
|
||||
0, // sig_index
|
||||
0, // name_offset
|
||||
0, // name_length
|
||||
0, // code_start_offset
|
||||
0, // code_end_offset
|
||||
false, // import
|
||||
false}); // export
|
||||
CHECK(mod.functions.size() <= 127);
|
||||
return static_cast<byte>(mod.functions.size() - 1);
|
||||
}
|
||||
byte AddImport(FunctionSig* sig) {
|
||||
byte result = AddFunction(sig);
|
||||
mod.functions[result].imported = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
void InitializeMemory() {
|
||||
mod.has_memory = true;
|
||||
mod.min_mem_pages = 1;
|
||||
mod.max_mem_pages = 100;
|
||||
}
|
||||
|
||||
void InitializeFunctionTable() {
|
||||
mod.function_tables.push_back(
|
||||
{0, 0, true, std::vector<int32_t>(), false, false, SignatureMap()});
|
||||
}
|
||||
|
||||
private:
|
||||
WasmModule mod;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, Int32Const1) {
|
||||
byte code[] = {kExprI32Const, 0};
|
||||
for (int i = -64; i <= 63; i++) {
|
||||
@ -1023,6 +1077,9 @@ TEST_F(FunctionBodyDecoderTest, TypeConversions) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, MacrosStmt) {
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
EXPECT_VERIFIES(v_i, WASM_SET_LOCAL(0, WASM_I32V_3(87348)));
|
||||
EXPECT_VERIFIES(v_i, WASM_STORE_MEM(MachineType::Int32(), WASM_I32V_1(24),
|
||||
WASM_I32V_1(40)));
|
||||
@ -1159,12 +1216,18 @@ TEST_F(FunctionBodyDecoderTest, AllSimpleExpressions) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, MemorySize) {
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
byte code[] = {kExprMemorySize, 0};
|
||||
EXPECT_VERIFIES_C(i_i, code);
|
||||
EXPECT_FAILURE_C(f_ff, code);
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, LoadMemOffset) {
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
for (int offset = 0; offset < 128; offset += 7) {
|
||||
byte code[] = {kExprI32Const, 0, kExprI32LoadMem, ZERO_ALIGNMENT,
|
||||
static_cast<byte>(offset)};
|
||||
@ -1173,6 +1236,9 @@ TEST_F(FunctionBodyDecoderTest, LoadMemOffset) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, LoadMemAlignment) {
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
struct {
|
||||
WasmOpcode instruction;
|
||||
uint32_t maximum_aligment;
|
||||
@ -1207,6 +1273,9 @@ TEST_F(FunctionBodyDecoderTest, LoadMemAlignment) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, StoreMemOffset) {
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
for (int offset = 0; offset < 128; offset += 7) {
|
||||
byte code[] = {WASM_STORE_MEM_OFFSET(MachineType::Int32(), offset,
|
||||
WASM_ZERO, WASM_ZERO)};
|
||||
@ -1215,6 +1284,9 @@ TEST_F(FunctionBodyDecoderTest, StoreMemOffset) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, StoreMemOffset_void) {
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
EXPECT_FAILURE(i_i, WASM_STORE_MEM_OFFSET(MachineType::Int32(), 0, WASM_ZERO,
|
||||
WASM_ZERO));
|
||||
}
|
||||
@ -1230,6 +1302,9 @@ TEST_F(FunctionBodyDecoderTest, StoreMemOffset_void) {
|
||||
#define VARINT4(x) BYTE0(x) | 0x80, BYTE1(x) | 0x80, BYTE2(x) | 0x80, BYTE3(x)
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, LoadMemOffset_varint) {
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
EXPECT_VERIFIES(i_i, WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT,
|
||||
VARINT1(0x45));
|
||||
EXPECT_VERIFIES(i_i, WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT,
|
||||
@ -1241,6 +1316,9 @@ TEST_F(FunctionBodyDecoderTest, LoadMemOffset_varint) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, StoreMemOffset_varint) {
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
EXPECT_VERIFIES(v_i, WASM_ZERO, WASM_ZERO, kExprI32StoreMem, ZERO_ALIGNMENT,
|
||||
VARINT1(0x33));
|
||||
EXPECT_VERIFIES(v_i, WASM_ZERO, WASM_ZERO, kExprI32StoreMem, ZERO_ALIGNMENT,
|
||||
@ -1252,6 +1330,9 @@ TEST_F(FunctionBodyDecoderTest, StoreMemOffset_varint) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, AllLoadMemCombinations) {
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
for (size_t i = 0; i < arraysize(kValueTypes); i++) {
|
||||
ValueType local_type = kValueTypes[i];
|
||||
for (size_t j = 0; j < arraysize(machineTypes); j++) {
|
||||
@ -1268,6 +1349,9 @@ TEST_F(FunctionBodyDecoderTest, AllLoadMemCombinations) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, AllStoreMemCombinations) {
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
for (size_t i = 0; i < arraysize(kValueTypes); i++) {
|
||||
ValueType local_type = kValueTypes[i];
|
||||
for (size_t j = 0; j < arraysize(machineTypes); j++) {
|
||||
@ -1283,54 +1367,6 @@ TEST_F(FunctionBodyDecoderTest, AllStoreMemCombinations) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
// A helper for tests that require a module environment for functions and
|
||||
// globals.
|
||||
class TestModuleEnv : public ModuleEnv {
|
||||
public:
|
||||
explicit TestModuleEnv(ModuleOrigin origin = kWasmOrigin)
|
||||
: ModuleEnv(&mod, nullptr) {
|
||||
mod.origin = origin;
|
||||
}
|
||||
byte AddGlobal(ValueType type, bool mutability = true) {
|
||||
mod.globals.push_back({type, mutability, WasmInitExpr(), 0, false, false});
|
||||
CHECK(mod.globals.size() <= 127);
|
||||
return static_cast<byte>(mod.globals.size() - 1);
|
||||
}
|
||||
byte AddSignature(FunctionSig* sig) {
|
||||
mod.signatures.push_back(sig);
|
||||
CHECK(mod.signatures.size() <= 127);
|
||||
return static_cast<byte>(mod.signatures.size() - 1);
|
||||
}
|
||||
byte AddFunction(FunctionSig* sig) {
|
||||
mod.functions.push_back({sig, // sig
|
||||
0, // func_index
|
||||
0, // sig_index
|
||||
0, // name_offset
|
||||
0, // name_length
|
||||
0, // code_start_offset
|
||||
0, // code_end_offset
|
||||
false, // import
|
||||
false}); // export
|
||||
CHECK(mod.functions.size() <= 127);
|
||||
return static_cast<byte>(mod.functions.size() - 1);
|
||||
}
|
||||
byte AddImport(FunctionSig* sig) {
|
||||
byte result = AddFunction(sig);
|
||||
mod.functions[result].imported = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
void InitializeFunctionTable() {
|
||||
mod.function_tables.push_back(
|
||||
{0, 0, true, std::vector<int32_t>(), false, false, SignatureMap()});
|
||||
}
|
||||
|
||||
private:
|
||||
WasmModule mod;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, SimpleCalls) {
|
||||
FunctionSig* sig = sigs.i_i();
|
||||
TestModuleEnv module_env;
|
||||
@ -1665,6 +1701,7 @@ TEST_F(FunctionBodyDecoderTest, AllSetGlobalCombinations) {
|
||||
TEST_F(FunctionBodyDecoderTest, WasmGrowMemory) {
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
|
||||
byte code[] = {WASM_GET_LOCAL(0), kExprGrowMemory, 0};
|
||||
EXPECT_VERIFIES_C(i_i, code);
|
||||
@ -1674,6 +1711,7 @@ TEST_F(FunctionBodyDecoderTest, WasmGrowMemory) {
|
||||
TEST_F(FunctionBodyDecoderTest, AsmJsGrowMemory) {
|
||||
TestModuleEnv module_env(kAsmJsOrigin);
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
|
||||
byte code[] = {WASM_GET_LOCAL(0), kExprGrowMemory, 0};
|
||||
EXPECT_FAILURE_C(i_i, code);
|
||||
@ -1705,6 +1743,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsBinOpsCheckOrigin) {
|
||||
{
|
||||
TestModuleEnv module_env(kAsmJsOrigin);
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) {
|
||||
TestBinop(AsmJsBinOps[i].op, AsmJsBinOps[i].sig);
|
||||
}
|
||||
@ -1713,6 +1752,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsBinOpsCheckOrigin) {
|
||||
{
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) {
|
||||
byte code[] = {
|
||||
WASM_BINOP(AsmJsBinOps[i].op, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))};
|
||||
@ -1751,6 +1791,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsUnOpsCheckOrigin) {
|
||||
{
|
||||
TestModuleEnv module_env(kAsmJsOrigin);
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) {
|
||||
TestUnop(AsmJsUnOps[i].op, AsmJsUnOps[i].sig);
|
||||
}
|
||||
@ -1759,6 +1800,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsUnOpsCheckOrigin) {
|
||||
{
|
||||
TestModuleEnv module_env;
|
||||
module = &module_env;
|
||||
module_env.InitializeMemory();
|
||||
for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) {
|
||||
byte code[] = {WASM_UNOP(AsmJsUnOps[i].op, WASM_GET_LOCAL(0))};
|
||||
EXPECT_FAILURE_SC(AsmJsUnOps[i].sig, code);
|
||||
|
Loading…
Reference in New Issue
Block a user