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