| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft Corporation and contributors. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- const cliArgs = WScript.Arguments || [];
- if (cliArgs.indexOf("--help") !== -1) {
- print("usage: ch memory.js -args [-verbose] -endargs");
- WScript.quit(0);
- }
- // Parse arguments
- let verbose = 0;
- while (true) {
- const iVerbose = cliArgs.indexOf("-verbose");
- if (iVerbose === -1) {
- break;
- }
- cliArgs.splice(iVerbose, 1);
- ++verbose;
- }
- function testDetach(buffer) {
- try {
- ArrayBuffer.detach(buffer);
- print("Failed. Expected an error when trying to transfer ");
- } catch (e) {
- if (verbose > 1) {
- print(`Passed. Expected error: ${e.message}`);
- }
- }
- }
- function test({init, max, checkOOM} = {}) {
- if (verbose) {
- print(`Testing memory {init: ${init|0}, max: ${max}}`);
- }
- const moduleTxt = `
- (module
- (memory (export "mem") ${init|0} ${max !== undefined ? max|0 : ""})
- (func (export "grow") (param i32) (result i32) (memory.grow (get_local 0)))
- (func (export "current") (result i32) (memory.size))
- (func (export "load") (param i32) (result i32) (i32.load (get_local 0)))
- (func (export "store") (param i32 i32) (i32.store (get_local 0) (get_local 1)))
- )`;
- if (verbose > 1) {
- print(moduleTxt);
- }
- const module = new WebAssembly.Module(WebAssembly.wabt.convertWast2Wasm(moduleTxt));
- let instance;
- try {
- instance = new WebAssembly.Instance(module);
- } catch (e) {
- if (!checkOOM || !e.message.includes("Failed to create WebAssembly.Memory")) {
- print(`FAILED. failed to instanciate module with error: ${e}`);
- } else if (verbose) {
- print(e.message);
- }
- return;
- }
- const {exports: {grow, current, load, store, mem}} = instance;
- function testReadWrite(index, value, currentSize) {
- const shouldTrap = index < 0 || (index + 4) > currentSize;
- const commonMsg = op => `trap on ${op}(${index}, ${value})`;
- try {
- store(index, value);
- if (shouldTrap) {
- print(`Failed. Expected ${commonMsg("store")}`);
- return;
- }
- } catch (e) {
- if (shouldTrap) {
- if (verbose) {
- print(`Passed. Expected ${commonMsg("store")}`);
- }
- } else {
- print(`Failed. Unexpected ${commonMsg("store")}`);
- }
- }
- try {
- const loadedValue = load(index);
- if (shouldTrap) {
- print(`Failed. Expected ${commonMsg("load")}`);
- return;
- }
- if ((loadedValue|0) !== (value|0)) {
- print(`Failed. Expected value ${value|0} after load. Got ${loadedValue|0}`);
- }
- } catch (e) {
- if (shouldTrap) {
- if (verbose) {
- print(`Passed. Expected ${commonMsg("load")}`);
- }
- } else {
- print(`Failed. Unexpected ${commonMsg("load")}`);
- }
- }
- }
- function run(delta) {
- testDetach(mem.buffer);
- const beforePages = current();
- const growRes = grow(delta);
- if (growRes !== -1 && growRes !== beforePages) {
- print(`FAILED. Expected grow(${delta}) to return ${beforePages}`);
- }
- const afterPages = current();
- if (growRes !== -1 && beforePages + delta !== afterPages) {
- print(`FAILED. Expected to have ${beforePages + delta} pages. Got ${afterPages} pages`);
- }
- if (verbose) {
- print(`current: ${beforePages}, grow(${delta}): ${growRes}, after: ${afterPages}`);
- }
- const currentSize = afterPages * 0x10000;
- testReadWrite(-4, -4, currentSize);
- testReadWrite(-3, -3, currentSize);
- testReadWrite(-2, -2, currentSize);
- testReadWrite(-1, -1, currentSize);
- testReadWrite(0, 6, currentSize);
- testDetach(mem.buffer);
- testReadWrite(1, 7, currentSize);
- testDetach(mem.buffer);
- testReadWrite(1, 7, currentSize);
- testReadWrite(currentSize - 4, 457, currentSize);
- testReadWrite(currentSize - 3, -98745, currentSize);
- testReadWrite(currentSize - 2, 786452, currentSize);
- testReadWrite(currentSize - 1, -1324, currentSize);
- testReadWrite(currentSize, 123, currentSize);
- testDetach(mem.buffer);
- }
- run(0);
- run(3);
- run(5);
- run(1 << 13);
- }
- test({init: 0});
- test({init: 0, max: 5});
- test({init: 0, max: 10});
- test({init: 5});
- test({init: 5, max: 10});
- // test({init: 1 << 14, checkOOM: true}); // ArrayBuffer will throw OOM instead of returning a null buffer
- try {
- test({init: 1 << 15});
- print("Failed. Expected an error when allocating WebAssembly.Memory too big");
- } catch (e) {
- if (verbose) {
- print(`Passed. Expected error: ${e.message}`);
- }
- }
- print("PASSED");
|