1// Copyright 2016 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Flags: --expose-wasm 6 7const stdlib = { 8 Math: Math, 9 Int8Array: Int8Array, 10 Int16Array: Int16Array, 11 Int32Array: Int32Array, 12 Uint8Array: Uint8Array, 13 Uint16Array: Uint16Array, 14 Uint32Array: Uint32Array, 15 Float32Array: Float32Array, 16 Float64Array: Float64Array, 17}; 18 19const buffer = new ArrayBuffer(65536); 20const BASE = 1000000000; 21 22const OOB_INDEXES = [ 23 buffer.byteLength, 24 buffer.byteLength + 1, 25 buffer.byteLength + 2, 26 buffer.byteLength + 3, 27 buffer.byteLength + 4, 28 buffer.byteLength + 5, 29 buffer.byteLength + 6, 30 buffer.byteLength + 7, 31 buffer.byteLength + 8, 32 buffer.byteLength + 9, 33 buffer.byteLength + 10, 34 0x80000000, 35 0x80000004, 36 0xF0000000, 37 0xFFFFFFFF, 38 0xFFFFFFFE, 39 -1, -2, -3, -4, -5, -6, -7, -8 40]; 41 42function resetBuffer() { 43 var view = new Int32Array(buffer); 44 for (var i = 0; i < view.length; i++) { 45 view[i] = BASE | (i << 2); 46 } 47} 48resetBuffer(); 49 50 51function checkView(view, load, shift) { 52 for (var i = 0; i < 300; i++) { 53 assertEquals(view[i >> shift], load(i)); 54 } 55} 56 57function RunThreeWayTest(asmfunc, expect) { 58 var asm_source = asmfunc.toString(); 59 var nonasm_source = asm_source.replace(new RegExp("use asm"), ""); 60 61 var js_module = eval("(" + nonasm_source + ")")(stdlib, {}, buffer); 62 print("Testing " + asmfunc.name + " (js)..."); 63 expect(js_module); 64 65 print("Testing " + asmfunc.name + " (asm.js)..."); 66 var asm_module = asmfunc(stdlib, {}, buffer); 67 expect(asm_module); 68 69 print("Testing " + asmfunc.name + " (wasm)..."); 70 var wasm_module = Wasm.instantiateModuleFromAsm(asm_source, null, buffer); 71 expect(wasm_module); 72} 73 74function LoadAt_i32(stdlib, foreign, buffer) { 75 "use asm"; 76 var HEAP32 = new stdlib.Int32Array(buffer); 77 function load(a) { 78 a = a | 0; 79 return HEAP32[a >> 2] | 0; 80 } 81 return {load: load}; 82} 83 84RunThreeWayTest(LoadAt_i32, function(module) { 85 var load = module.load; 86 assertEquals(BASE, load(0)); 87 assertEquals(BASE | 0x30, load(0x30)); 88 assertEquals(BASE | 0x704, load(0x704)); 89 assertEquals(BASE | 0x704, load(0x705)); 90 assertEquals(BASE | 0x704, load(0x706)); 91 assertEquals(BASE | 0x704, load(0x707)); 92 93 var length = buffer.byteLength; 94 assertEquals(BASE | (length - 4), load(length - 4)); 95 assertEquals(BASE | (length - 4), load(length - 4 + 1)); 96 assertEquals(BASE | (length - 4), load(length - 4 + 2)); 97 assertEquals(BASE | (length - 4), load(length - 4 + 3)); 98 99 for (index of OOB_INDEXES) assertEquals(0, load(index)); 100 checkView(new Int32Array(buffer), load, 2); 101}); 102 103function LoadAt_i16(stdlib, foreign, buffer) { 104 "use asm"; 105 var HEAP16 = new stdlib.Int16Array(buffer); 106 function load(a) { 107 a = a | 0; 108 return HEAP16[a >> 1] | 0; 109 } 110 return {load: load}; 111} 112 113RunThreeWayTest(LoadAt_i16, function(module) { 114 var load = module.load; 115 var LOWER = (BASE << 16) >> 16; 116 var UPPER = BASE >> 16; 117 assertEquals(LOWER, load(0)); 118 assertEquals(UPPER, load(2)); 119 120 assertEquals(LOWER | 0x30, load(0x30)); 121 assertEquals(UPPER, load(0x32)); 122 123 assertEquals(LOWER | 0x504, load(0x504)); 124 assertEquals(LOWER | 0x504, load(0x505)); 125 126 assertEquals(UPPER, load(0x706)); 127 assertEquals(UPPER, load(0x707)); 128 129 var length = buffer.byteLength; 130 assertEquals(LOWER | (length - 4), load(length - 4)); 131 assertEquals(LOWER | (length - 4), load(length - 4 + 1)); 132 assertEquals(UPPER, load(length - 4 + 2)); 133 assertEquals(UPPER, load(length - 4 + 3)); 134 135 for (index of OOB_INDEXES) assertEquals(0, load(index)); 136 checkView(new Int16Array(buffer), load, 1); 137}); 138 139function LoadAt_u16(stdlib, foreign, buffer) { 140 "use asm"; 141 var HEAP16 = new stdlib.Uint16Array(buffer); 142 function load(a) { 143 a = a | 0; 144 return HEAP16[a >> 1] | 0; 145 } 146 return {load: load}; 147} 148 149RunThreeWayTest(LoadAt_u16, function(module) { 150 var load = module.load; 151 for (index of OOB_INDEXES) assertEquals(0, load(index)); 152 checkView(new Uint16Array(buffer), load, 1); 153}); 154 155function LoadAt_i8(stdlib, foreign, buffer) { 156 "use asm"; 157 var HEAP8 = new stdlib.Int8Array(buffer); 158 function load(a) { 159 a = a | 0; 160 return HEAP8[a >> 0] | 0; 161 } 162 return {load: load}; 163} 164 165RunThreeWayTest(LoadAt_i8, function(module) { 166 var load = module.load; 167 for (index of OOB_INDEXES) assertEquals(0, load(index)); 168 checkView(new Int8Array(buffer), load, 0); 169}); 170 171function LoadAt_u8(stdlib, foreign, buffer) { 172 "use asm"; 173 var HEAP8 = new stdlib.Uint8Array(buffer); 174 function load(a) { 175 a = a | 0; 176 return HEAP8[a >> 0] | 0; 177 } 178 return {load: load}; 179} 180 181RunThreeWayTest(LoadAt_u8, function(module) { 182 var load = module.load; 183 for (index of OOB_INDEXES) assertEquals(0, load(index)); 184 checkView(new Uint8Array(buffer), load, 0); 185}); 186 187 188function LoadAt_u32(stdlib, foreign, buffer) { 189 "use asm"; 190 var HEAP32 = new stdlib.Uint32Array(buffer); 191 function load(a) { 192 a = a | 0; 193 return +(HEAP32[a >> 2] >>> 0); 194 } 195 return {load: load}; 196} 197 198RunThreeWayTest(LoadAt_u32, function(module) { 199 var load = module.load; 200 for (index of OOB_INDEXES) assertEquals(0, load(index)); 201 checkView(new Uint32Array(buffer), load, 2); 202}); 203 204function LoadAt_f32(stdlib, foreign, buffer) { 205 "use asm"; 206 var HEAP32 = new stdlib.Float32Array(buffer); 207 var fround = stdlib.Math.fround; 208 function load(a) { 209 a = a | 0; 210 return fround(HEAP32[a >> 2]); 211 } 212 return {load: load}; 213} 214 215RunThreeWayTest(LoadAt_f32, function(module) { 216 var load = module.load; 217 for (index of OOB_INDEXES) assertEquals(NaN, load(index)); 218 checkView(new Float32Array(buffer), load, 2); 219}); 220 221function LoadAt_f64(stdlib, foreign, buffer) { 222 "use asm"; 223 var HEAP64 = new stdlib.Float64Array(buffer); 224 function load(a) { 225 a = a | 0; 226 return +HEAP64[a >> 3]; 227 } 228 return {load: load}; 229} 230 231RunThreeWayTest(LoadAt_f64, function(module) { 232 var load = module.load; 233 for (index of OOB_INDEXES) assertEquals(NaN, load(index)); 234 checkView(new Float64Array(buffer), load, 3); 235}); 236 237// TODO(titzer): constant heap indexes 238// TODO(titzer): heap accesses with offsets and arithmetic 239// TODO(titzer): [i >> K] where K is greater than log(size) 240