1// META: global=window,dedicatedworker,jsshell 2// META: script=/wasm/jsapi/memory/assertions.js 3 4test(() => { 5 const argument = { "initial": 0 }; 6 const memory = new WebAssembly.Memory(argument); 7 assert_throws_js(TypeError, () => memory.grow()); 8}, "Missing arguments"); 9 10test(t => { 11 const thisValues = [ 12 undefined, 13 null, 14 true, 15 "", 16 Symbol(), 17 1, 18 {}, 19 WebAssembly.Memory, 20 WebAssembly.Memory.prototype, 21 ]; 22 23 const argument = { 24 valueOf: t.unreached_func("Should not touch the argument (valueOf)"), 25 toString: t.unreached_func("Should not touch the argument (toString)"), 26 }; 27 28 const fn = WebAssembly.Memory.prototype.grow; 29 30 for (const thisValue of thisValues) { 31 assert_throws_js(TypeError, () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`); 32 } 33}, "Branding"); 34 35test(() => { 36 const argument = { "initial": 0 }; 37 const memory = new WebAssembly.Memory(argument); 38 const oldMemory = memory.buffer; 39 assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); 40 41 const result = memory.grow(2); 42 assert_equals(result, 0); 43 44 const newMemory = memory.buffer; 45 assert_not_equals(oldMemory, newMemory); 46 assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); 47 assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); 48}, "Zero initial"); 49 50test(() => { 51 const argument = { "initial": { valueOf() { return 0 } } }; 52 const memory = new WebAssembly.Memory(argument); 53 const oldMemory = memory.buffer; 54 assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); 55 56 const result = memory.grow({ valueOf() { return 2 } }); 57 assert_equals(result, 0); 58 59 const newMemory = memory.buffer; 60 assert_not_equals(oldMemory, newMemory); 61 assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); 62 assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); 63}, "Zero initial with valueOf"); 64 65test(() => { 66 const argument = { "initial": 3 }; 67 const memory = new WebAssembly.Memory(argument); 68 const oldMemory = memory.buffer; 69 assert_ArrayBuffer(oldMemory, { "size": 3 }, "Buffer before growing"); 70 71 const result = memory.grow(2); 72 assert_equals(result, 3); 73 74 const newMemory = memory.buffer; 75 assert_not_equals(oldMemory, newMemory); 76 assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); 77 assert_ArrayBuffer(newMemory, { "size": 5 }, "New buffer after growing"); 78}, "Non-zero initial"); 79 80test(() => { 81 const argument = { "initial": 0, "maximum": 2 }; 82 const memory = new WebAssembly.Memory(argument); 83 const oldMemory = memory.buffer; 84 assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); 85 86 const result = memory.grow(2); 87 assert_equals(result, 0); 88 89 const newMemory = memory.buffer; 90 assert_not_equals(oldMemory, newMemory); 91 assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); 92 assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); 93}, "Zero initial with respected maximum"); 94 95test(() => { 96 const argument = { "initial": 0, "maximum": 2 }; 97 const memory = new WebAssembly.Memory(argument); 98 const oldMemory = memory.buffer; 99 assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); 100 101 const result = memory.grow(1); 102 assert_equals(result, 0); 103 104 const newMemory = memory.buffer; 105 assert_not_equals(oldMemory, newMemory); 106 assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing once"); 107 assert_ArrayBuffer(newMemory, { "size": 1 }, "New buffer after growing once"); 108 109 const result2 = memory.grow(1); 110 assert_equals(result2, 1); 111 112 const newestMemory = memory.buffer; 113 assert_not_equals(newMemory, newestMemory); 114 assert_ArrayBuffer(oldMemory, { "detached": true }, "New buffer after growing twice"); 115 assert_ArrayBuffer(newMemory, { "detached": true }, "New buffer after growing twice"); 116 assert_ArrayBuffer(newestMemory, { "size": 2 }, "Newest buffer after growing twice"); 117}, "Zero initial with respected maximum grown twice"); 118 119test(() => { 120 const argument = { "initial": 1, "maximum": 2 }; 121 const memory = new WebAssembly.Memory(argument); 122 const oldMemory = memory.buffer; 123 assert_ArrayBuffer(oldMemory, { "size": 1 }, "Buffer before growing"); 124 125 assert_throws_js(RangeError, () => memory.grow(2)); 126 assert_equals(memory.buffer, oldMemory); 127 assert_ArrayBuffer(memory.buffer, { "size": 1 }, "Buffer before trying to grow"); 128}, "Zero initial growing too much"); 129 130const outOfRangeValues = [ 131 undefined, 132 NaN, 133 Infinity, 134 -Infinity, 135 -1, 136 0x100000000, 137 0x1000000000, 138 "0x100000000", 139 { valueOf() { return 0x100000000; } }, 140]; 141 142for (const value of outOfRangeValues) { 143 test(() => { 144 const argument = { "initial": 0 }; 145 const memory = new WebAssembly.Memory(argument); 146 assert_throws_js(TypeError, () => memory.grow(value)); 147 }, `Out-of-range argument: ${format_value(value)}`); 148} 149 150test(() => { 151 const argument = { "initial": 0 }; 152 const memory = new WebAssembly.Memory(argument); 153 const oldMemory = memory.buffer; 154 assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); 155 156 const result = memory.grow(2, {}); 157 assert_equals(result, 0); 158 159 const newMemory = memory.buffer; 160 assert_not_equals(oldMemory, newMemory); 161 assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); 162 assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); 163}, "Stray argument"); 164 165test(() => { 166 const argument = { "initial": 1, "maximum": 2, "shared": true }; 167 const memory = new WebAssembly.Memory(argument); 168 const oldMemory = memory.buffer; 169 assert_ArrayBuffer(oldMemory, { "size": 1, "shared": true }, "Buffer before growing"); 170 171 const result = memory.grow(1); 172 assert_equals(result, 1); 173 174 const newMemory = memory.buffer; 175 assert_not_equals(oldMemory, newMemory); 176 assert_ArrayBuffer(oldMemory, { "size": 1, "shared": true }, "Old buffer after growing"); 177 assert_ArrayBuffer(newMemory, { "size": 2, "shared": true }, "New buffer after growing"); 178 179 // The old and new buffers must have the same value for the 180 // [[ArrayBufferData]] internal slot. 181 const oldArray = new Uint8Array(oldMemory); 182 const newArray = new Uint8Array(newMemory); 183 assert_equals(oldArray[0], 0, "old first element"); 184 assert_equals(newArray[0], 0, "new first element"); 185 oldArray[0] = 1; 186 assert_equals(oldArray[0], 1, "old first element"); 187 assert_equals(newArray[0], 1, "new first element"); 188 189}, "Growing shared memory does not detach old buffer"); 190