79 lines
3.6 KiB
JavaScript
79 lines
3.6 KiB
JavaScript
|
// Copyright 2017 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: --allow-natives-syntax
|
||
|
|
||
|
load('test/mjsunit/wasm/wasm-constants.js');
|
||
|
load('test/mjsunit/wasm/wasm-module-builder.js');
|
||
|
|
||
|
// =============================================================================
|
||
|
// Tests in this file test the interaction between the wasm interpreter and
|
||
|
// compiled code.
|
||
|
// =============================================================================
|
||
|
|
||
|
(function testGrowMemoryBetweenInterpretedAndCompiled() {
|
||
|
// grow_memory can be called from interpreted or compiled code, and changes
|
||
|
// should be reflected in either execution.
|
||
|
var builder = new WasmModuleBuilder();
|
||
|
var grow_body = [kExprGetLocal, 0, kExprGrowMemory, kMemoryZero];
|
||
|
var load_body = [kExprGetLocal, 0, kExprI32LoadMem, 0, 0];
|
||
|
var store_body = [kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0];
|
||
|
builder.addFunction('grow_memory', kSig_i_i).addBody(grow_body).exportFunc();
|
||
|
builder.addFunction('load', kSig_i_i).addBody(load_body).exportFunc();
|
||
|
builder.addFunction('store', kSig_v_ii).addBody(store_body).exportFunc();
|
||
|
var grow_interp_function =
|
||
|
builder.addFunction('grow_memory_interpreted', kSig_i_i)
|
||
|
.addBody(grow_body)
|
||
|
.exportFunc();
|
||
|
var load_interp_function = builder.addFunction('load_interpreted', kSig_i_i)
|
||
|
.addBody(load_body)
|
||
|
.exportFunc();
|
||
|
var kNumPages = 2;
|
||
|
var kMaxPages = 10;
|
||
|
builder.addMemory(kNumPages, kMaxPages, false);
|
||
|
var instance = builder.instantiate();
|
||
|
var exp = instance.exports;
|
||
|
%RedirectToWasmInterpreter(instance, grow_interp_function.index);
|
||
|
%RedirectToWasmInterpreter(instance, load_interp_function.index);
|
||
|
|
||
|
// Initially, we can load from offset 12, but not OOB.
|
||
|
var oob_index = kNumPages * kPageSize;
|
||
|
var initial_interpreted = % WasmNumInterpretedCalls(instance);
|
||
|
assertEquals(0, exp.load(12));
|
||
|
assertEquals(0, exp.load_interpreted(12));
|
||
|
assertTraps(kTrapMemOutOfBounds, () => exp.load(oob_index));
|
||
|
assertTraps(
|
||
|
kTrapMemOutOfBounds, () => exp.load_interpreted(oob_index));
|
||
|
// Grow by 2 pages from compiled code, and ensure that this is reflected in
|
||
|
// the interpreter.
|
||
|
assertEquals(kNumPages, exp.grow_memory(2));
|
||
|
kNumPages += 2;
|
||
|
assertEquals(kNumPages, exp.grow_memory_interpreted(0));
|
||
|
assertEquals(kNumPages, exp.grow_memory(0));
|
||
|
// Now we can load from the previous OOB index.
|
||
|
assertEquals(0, exp.load(oob_index));
|
||
|
assertEquals(0, exp.load_interpreted(oob_index));
|
||
|
// Set new OOB index and ensure that it traps.
|
||
|
oob_index = kNumPages * kPageSize;
|
||
|
assertTraps(kTrapMemOutOfBounds, () => exp.load(oob_index));
|
||
|
assertTraps(
|
||
|
kTrapMemOutOfBounds, () => exp.load_interpreted(oob_index));
|
||
|
// Grow by another page in the interpreter, and ensure that this is reflected
|
||
|
// in compiled code.
|
||
|
assertEquals(kNumPages, exp.grow_memory_interpreted(1));
|
||
|
kNumPages += 1;
|
||
|
assertEquals(kNumPages, exp.grow_memory_interpreted(0));
|
||
|
assertEquals(kNumPages, exp.grow_memory(0));
|
||
|
// Now we can store to the previous OOB index and read it back in both
|
||
|
// environments.
|
||
|
exp.store(oob_index, 47);
|
||
|
assertEquals(47, exp.load(oob_index));
|
||
|
assertEquals(47, exp.load_interpreted(oob_index));
|
||
|
// We cannot grow beyong kMaxPages.
|
||
|
assertEquals(-1, exp.grow_memory(kMaxPages - kNumPages + 1));
|
||
|
assertEquals(-1, exp.grow_memory_interpreted(kMaxPages - kNumPages + 1));
|
||
|
// Overall, we executed 9 functions in the interpreter.
|
||
|
assertEquals(initial_interpreted + 9, % WasmNumInterpretedCalls(instance));
|
||
|
})();
|