// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Flags: --validate-asm --allow-natives-syntax var stdlib = this; let kMinHeapSize = 4096; function assertValidAsm(func) { assertTrue(%IsAsmWasmCode(func), "must be valid asm code"); } function assertWasm(expected, func, ffi) { print("Testing " + func.name + "..."); assertEquals( expected, func(stdlib, ffi, new ArrayBuffer(kMinHeapSize)).caller()); assertValidAsm(func); } function TestInt32HeapAccess(stdlib, foreign, buffer) { "use asm"; var m = new stdlib.Int32Array(buffer); function caller() { var i = 4; m[0] = (i + 1) | 0; m[i >> 2] = ((m[0]|0) + 1) | 0; m[2] = ((m[i >> 2]|0) + 1) | 0; return m[2] | 0; } return {caller: caller}; } assertWasm(7, TestInt32HeapAccess); function TestInt32HeapAccessExternal() { var memory = new ArrayBuffer(kMinHeapSize); var memory_int32 = new Int32Array(memory); var module_decl = eval('(' + TestInt32HeapAccess.toString() + ')'); var module = module_decl(stdlib, null, memory); assertValidAsm(module_decl); assertEquals(7, module.caller()); assertEquals(7, memory_int32[2]); } TestInt32HeapAccessExternal(); function TestHeapAccessIntTypes() { var types = [ [Int8Array, 'Int8Array', '>> 0'], [Uint8Array, 'Uint8Array', '>> 0'], [Int16Array, 'Int16Array', '>> 1'], [Uint16Array, 'Uint16Array', '>> 1'], [Int32Array, 'Int32Array', '>> 2'], [Uint32Array, 'Uint32Array', '>> 2'], ]; for (var i = 0; i < types.length; i++) { var code = TestInt32HeapAccess.toString(); code = code.replace('Int32Array', types[i][1]); code = code.replace(/>> 2/g, types[i][2]); var memory = new ArrayBuffer(kMinHeapSize); var memory_view = new types[i][0](memory); var module_decl = eval('(' + code + ')'); var module = module_decl(stdlib, null, memory); assertValidAsm(module_decl); assertEquals(7, module.caller()); assertEquals(7, memory_view[2]); assertValidAsm(module_decl); } } TestHeapAccessIntTypes(); function TestFloatHeapAccess(stdlib, foreign, buffer) { "use asm"; var f32 = new stdlib.Float32Array(buffer); var f64 = new stdlib.Float64Array(buffer); var fround = stdlib.Math.fround; function caller() { var i = 8; var j = 8; var v = 6.0; f64[2] = v + 1.0; f64[i >> 3] = +f64[2] + 1.0; f64[j >> 3] = +f64[j >> 3] + 1.0; i = +f64[i >> 3] == 9.0; return i|0; } return {caller: caller}; } assertWasm(1, TestFloatHeapAccess); function TestFloatHeapAccessExternal() { var memory = new ArrayBuffer(kMinHeapSize); var memory_float64 = new Float64Array(memory); var module_decl = eval('(' + TestFloatHeapAccess.toString() + ')'); var module = module_decl(stdlib, null, memory); assertValidAsm(module_decl); assertEquals(1, module.caller()); assertEquals(9.0, memory_float64[1]); } TestFloatHeapAccessExternal(); (function() { function TestByteHeapAccessCompat(stdlib, foreign, buffer) { "use asm"; var HEAP8 = new stdlib.Uint8Array(buffer); var HEAP32 = new stdlib.Int32Array(buffer); function store(i, v) { i = i | 0; v = v | 0; HEAP32[i >> 2] = v; } function storeb(i, v) { i = i | 0; v = v | 0; HEAP8[i | 0] = v; } function load(i) { i = i | 0; return HEAP8[i] | 0; } function iload(i) { i = i | 0; return HEAP8[HEAP32[i >> 2] | 0] | 0; } return {load: load, iload: iload, store: store, storeb: storeb}; } var memory = new ArrayBuffer(kMinHeapSize); var module_decl = eval('(' + TestByteHeapAccessCompat.toString() + ')'); var m = module_decl(stdlib, null, memory); assertValidAsm(module_decl); m.store(0, 20); m.store(4, 21); m.store(8, 22); m.storeb(20, 123); m.storeb(21, 42); m.storeb(22, 77); assertEquals(123, m.load(20)); assertEquals(42, m.load(21)); assertEquals(77, m.load(22)); assertEquals(123, m.iload(0)); assertEquals(42, m.iload(4)); assertEquals(77, m.iload(8)); })(); function TestIntishAssignment(stdlib, foreign, heap) { "use asm"; var HEAP32 = new stdlib.Int32Array(heap); function func() { var a = 1; var b = 2; HEAP32[0] = a + b; return HEAP32[0] | 0; } return {caller: func}; } assertWasm(3, TestIntishAssignment); function TestFloatishAssignment(stdlib, foreign, heap) { "use asm"; var HEAPF32 = new stdlib.Float32Array(heap); var fround = stdlib.Math.fround; function func() { var a = fround(1.0); var b = fround(2.0); HEAPF32[0] = a + b; return +HEAPF32[0]; } return {caller: func}; } assertWasm(3, TestFloatishAssignment); function TestDoubleToFloatAssignment(stdlib, foreign, heap) { "use asm"; var HEAPF32 = new stdlib.Float32Array(heap); var fround = stdlib.Math.fround; function func() { var a = 1.23; HEAPF32[0] = a; return +HEAPF32[0]; } return {caller: func}; } assertWasm(Math.fround(1.23), TestDoubleToFloatAssignment);