| 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)); |
| 67 expect(asm_module); | 68 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 } | 69 } |
| 74 | 70 |
| 75 function LoadAt_i32(stdlib, foreign, buffer) { | 71 function LoadAt_i32(stdlib, foreign, buffer) { |
| 76 "use asm"; | 72 "use asm"; |
| 77 var HEAP32 = new stdlib.Int32Array(buffer); | 73 var HEAP32 = new stdlib.Int32Array(buffer); |
| 78 function load(a) { | 74 function load(a) { |
| 79 a = a | 0; | 75 a = a | 0; |
| 80 return HEAP32[a >> 2] | 0; | 76 return HEAP32[a >> 2] | 0; |
| 81 } | 77 } |
| 82 return {load: load}; | 78 return {load: load}; |
| 83 } | 79 } |
| 84 | 80 |
| 85 RunThreeWayTest(LoadAt_i32, function(module) { | 81 RunAsmJsTest(LoadAt_i32, function(module) { |
| 86 var load = module.load; | 82 var load = module.load; |
| 87 assertEquals(BASE, load(0)); | 83 assertEquals(BASE, load(0)); |
| 88 assertEquals(BASE | 0x30, load(0x30)); | 84 assertEquals(BASE | 0x30, load(0x30)); |
| 89 assertEquals(BASE | 0x704, load(0x704)); | 85 assertEquals(BASE | 0x704, load(0x704)); |
| 90 assertEquals(BASE | 0x704, load(0x705)); | 86 assertEquals(BASE | 0x704, load(0x705)); |
| 91 assertEquals(BASE | 0x704, load(0x706)); | 87 assertEquals(BASE | 0x704, load(0x706)); |
| 92 assertEquals(BASE | 0x704, load(0x707)); | 88 assertEquals(BASE | 0x704, load(0x707)); |
| 93 | 89 |
| 94 var length = buffer.byteLength; | 90 var length = buffer.byteLength; |
| 95 assertEquals(BASE | (length - 4), load(length - 4)); | 91 assertEquals(BASE | (length - 4), load(length - 4)); |
| 96 assertEquals(BASE | (length - 4), load(length - 4 + 1)); | 92 assertEquals(BASE | (length - 4), load(length - 4 + 1)); |
| 97 assertEquals(BASE | (length - 4), load(length - 4 + 2)); | 93 assertEquals(BASE | (length - 4), load(length - 4 + 2)); |
| 98 assertEquals(BASE | (length - 4), load(length - 4 + 3)); | 94 assertEquals(BASE | (length - 4), load(length - 4 + 3)); |
| 99 | 95 |
| 100 for (index of OOB_INDEXES) assertEquals(0, load(index)); | 96 for (index of OOB_INDEXES) assertEquals(0, load(index)); |
| 101 checkView(new Int32Array(buffer), load, 2); | 97 checkView(new Int32Array(buffer), load, 2); |
| 102 }); | 98 }); |
| 103 | 99 |
| 104 function LoadAt_i16(stdlib, foreign, buffer) { | 100 function LoadAt_i16(stdlib, foreign, buffer) { |
| 105 "use asm"; | 101 "use asm"; |
| 106 var HEAP16 = new stdlib.Int16Array(buffer); | 102 var HEAP16 = new stdlib.Int16Array(buffer); |
| 107 function load(a) { | 103 function load(a) { |
| 108 a = a | 0; | 104 a = a | 0; |
| 109 return HEAP16[a >> 1] | 0; | 105 return HEAP16[a >> 1] | 0; |
| 110 } | 106 } |
| 111 return {load: load}; | 107 return {load: load}; |
| 112 } | 108 } |
| 113 | 109 |
| 114 RunThreeWayTest(LoadAt_i16, function(module) { | 110 RunAsmJsTest(LoadAt_i16, function(module) { |
| 115 var load = module.load; | 111 var load = module.load; |
| 116 var LOWER = (BASE << 16) >> 16; | 112 var LOWER = (BASE << 16) >> 16; |
| 117 var UPPER = BASE >> 16; | 113 var UPPER = BASE >> 16; |
| 118 assertEquals(LOWER, load(0)); | 114 assertEquals(LOWER, load(0)); |
| 119 assertEquals(UPPER, load(2)); | 115 assertEquals(UPPER, load(2)); |
| 120 | 116 |
| 121 assertEquals(LOWER | 0x30, load(0x30)); | 117 assertEquals(LOWER | 0x30, load(0x30)); |
| 122 assertEquals(UPPER, load(0x32)); | 118 assertEquals(UPPER, load(0x32)); |
| 123 | 119 |
| 124 assertEquals(LOWER | 0x504, load(0x504)); | 120 assertEquals(LOWER | 0x504, load(0x504)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 140 function LoadAt_u16(stdlib, foreign, buffer) { | 136 function LoadAt_u16(stdlib, foreign, buffer) { |
| 141 "use asm"; | 137 "use asm"; |
| 142 var HEAP16 = new stdlib.Uint16Array(buffer); | 138 var HEAP16 = new stdlib.Uint16Array(buffer); |
| 143 function load(a) { | 139 function load(a) { |
| 144 a = a | 0; | 140 a = a | 0; |
| 145 return HEAP16[a >> 1] | 0; | 141 return HEAP16[a >> 1] | 0; |
| 146 } | 142 } |
| 147 return {load: load}; | 143 return {load: load}; |
| 148 } | 144 } |
| 149 | 145 |
| 150 RunThreeWayTest(LoadAt_u16, function(module) { | 146 RunAsmJsTest(LoadAt_u16, function(module) { |
| 151 var load = module.load; | 147 var load = module.load; |
| 152 for (index of OOB_INDEXES) assertEquals(0, load(index)); | 148 for (index of OOB_INDEXES) assertEquals(0, load(index)); |
| 153 checkView(new Uint16Array(buffer), load, 1); | 149 checkView(new Uint16Array(buffer), load, 1); |
| 154 }); | 150 }); |
| 155 | 151 |
| 156 function LoadAt_i8(stdlib, foreign, buffer) { | 152 function LoadAt_i8(stdlib, foreign, buffer) { |
| 157 "use asm"; | 153 "use asm"; |
| 158 var HEAP8 = new stdlib.Int8Array(buffer); | 154 var HEAP8 = new stdlib.Int8Array(buffer); |
| 159 function load(a) { | 155 function load(a) { |
| 160 a = a | 0; | 156 a = a | 0; |
| 161 return HEAP8[a >> 0] | 0; | 157 return HEAP8[a >> 0] | 0; |
| 162 } | 158 } |
| 163 return {load: load}; | 159 return {load: load}; |
| 164 } | 160 } |
| 165 | 161 |
| 166 RunThreeWayTest(LoadAt_i8, function(module) { | 162 RunAsmJsTest(LoadAt_i8, function(module) { |
| 167 var load = module.load; | 163 var load = module.load; |
| 168 for (index of OOB_INDEXES) assertEquals(0, load(index)); | 164 for (index of OOB_INDEXES) assertEquals(0, load(index)); |
| 169 checkView(new Int8Array(buffer), load, 0); | 165 checkView(new Int8Array(buffer), load, 0); |
| 170 }); | 166 }); |
| 171 | 167 |
| 172 function LoadAt_u8(stdlib, foreign, buffer) { | 168 function LoadAt_u8(stdlib, foreign, buffer) { |
| 173 "use asm"; | 169 "use asm"; |
| 174 var HEAP8 = new stdlib.Uint8Array(buffer); | 170 var HEAP8 = new stdlib.Uint8Array(buffer); |
| 175 function load(a) { | 171 function load(a) { |
| 176 a = a | 0; | 172 a = a | 0; |
| 177 return HEAP8[a >> 0] | 0; | 173 return HEAP8[a >> 0] | 0; |
| 178 } | 174 } |
| 179 return {load: load}; | 175 return {load: load}; |
| 180 } | 176 } |
| 181 | 177 |
| 182 RunThreeWayTest(LoadAt_u8, function(module) { | 178 RunAsmJsTest(LoadAt_u8, function(module) { |
| 183 var load = module.load; | 179 var load = module.load; |
| 184 for (index of OOB_INDEXES) assertEquals(0, load(index)); | 180 for (index of OOB_INDEXES) assertEquals(0, load(index)); |
| 185 checkView(new Uint8Array(buffer), load, 0); | 181 checkView(new Uint8Array(buffer), load, 0); |
| 186 }); | 182 }); |
| 187 | 183 |
| 188 | 184 |
| 189 function LoadAt_u32(stdlib, foreign, buffer) { | 185 function LoadAt_u32(stdlib, foreign, buffer) { |
| 190 "use asm"; | 186 "use asm"; |
| 191 var HEAP32 = new stdlib.Uint32Array(buffer); | 187 var HEAP32 = new stdlib.Uint32Array(buffer); |
| 192 function load(a) { | 188 function load(a) { |
| 193 a = a | 0; | 189 a = a | 0; |
| 194 return +(HEAP32[a >> 2] >>> 0); | 190 return +(HEAP32[a >> 2] >>> 0); |
| 195 } | 191 } |
| 196 return {load: load}; | 192 return {load: load}; |
| 197 } | 193 } |
| 198 | 194 |
| 199 RunThreeWayTest(LoadAt_u32, function(module) { | 195 RunAsmJsTest(LoadAt_u32, function(module) { |
| 200 var load = module.load; | 196 var load = module.load; |
| 201 for (index of OOB_INDEXES) assertEquals(0, load(index)); | 197 for (index of OOB_INDEXES) assertEquals(0, load(index)); |
| 202 checkView(new Uint32Array(buffer), load, 2); | 198 checkView(new Uint32Array(buffer), load, 2); |
| 203 }); | 199 }); |
| 204 | 200 |
| 205 function LoadAt_f32(stdlib, foreign, buffer) { | 201 function LoadAt_f32(stdlib, foreign, buffer) { |
| 206 "use asm"; | 202 "use asm"; |
| 207 var HEAP32 = new stdlib.Float32Array(buffer); | 203 var HEAP32 = new stdlib.Float32Array(buffer); |
| 208 var fround = stdlib.Math.fround; | 204 var fround = stdlib.Math.fround; |
| 209 function load(a) { | 205 function load(a) { |
| 210 a = a | 0; | 206 a = a | 0; |
| 211 return fround(HEAP32[a >> 2]); | 207 return fround(HEAP32[a >> 2]); |
| 212 } | 208 } |
| 213 return {load: load}; | 209 return {load: load}; |
| 214 } | 210 } |
| 215 | 211 |
| 216 RunThreeWayTest(LoadAt_f32, function(module) { | 212 RunAsmJsTest(LoadAt_f32, function(module) { |
| 217 var load = module.load; | 213 var load = module.load; |
| 218 for (index of OOB_INDEXES) assertEquals(NaN, load(index)); | 214 for (index of OOB_INDEXES) assertEquals(NaN, load(index)); |
| 219 checkView(new Float32Array(buffer), load, 2); | 215 checkView(new Float32Array(buffer), load, 2); |
| 220 }); | 216 }); |
| 221 | 217 |
| 222 function LoadAt_f64(stdlib, foreign, buffer) { | 218 function LoadAt_f64(stdlib, foreign, buffer) { |
| 223 "use asm"; | 219 "use asm"; |
| 224 var HEAP64 = new stdlib.Float64Array(buffer); | 220 var HEAP64 = new stdlib.Float64Array(buffer); |
| 225 function load(a) { | 221 function load(a) { |
| 226 a = a | 0; | 222 a = a | 0; |
| 227 return +HEAP64[a >> 3]; | 223 return +HEAP64[a >> 3]; |
| 228 } | 224 } |
| 229 return {load: load}; | 225 return {load: load}; |
| 230 } | 226 } |
| 231 | 227 |
| 232 RunThreeWayTest(LoadAt_f64, function(module) { | 228 RunAsmJsTest(LoadAt_f64, function(module) { |
| 233 var load = module.load; | 229 var load = module.load; |
| 234 for (index of OOB_INDEXES) assertEquals(NaN, load(index)); | 230 for (index of OOB_INDEXES) assertEquals(NaN, load(index)); |
| 235 checkView(new Float64Array(buffer), load, 3); | 231 checkView(new Float64Array(buffer), load, 3); |
| 236 }); | 232 }); |
| 237 | 233 |
| 238 // TODO(titzer): constant heap indexes | 234 // TODO(titzer): constant heap indexes |
| 239 // TODO(titzer): heap accesses with offsets and arithmetic | 235 // TODO(titzer): heap accesses with offsets and arithmetic |
| 240 // TODO(titzer): [i >> K] where K is greater than log(size) | 236 // TODO(titzer): [i >> K] where K is greater than log(size) |
| OLD | NEW |