Line data Source code
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 : #include <stdint.h>
6 : #include <stdlib.h>
7 : #include <string.h>
8 :
9 : #include "src/assembler-inl.h"
10 : #include "src/base/platform/elapsed-timer.h"
11 :
12 : #include "test/cctest/cctest.h"
13 : #include "test/cctest/compiler/value-helper.h"
14 : #include "test/cctest/wasm/wasm-run-utils.h"
15 : #include "test/common/wasm/test-signatures.h"
16 : #include "test/common/wasm/wasm-macro-gen.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 : namespace wasm {
21 :
22 28367 : WASM_EXEC_TEST(Int32AsmjsDivS) {
23 15 : WasmRunner<int32_t, int32_t, int32_t> r(execution_tier);
24 : r.builder().ChangeOriginToAsmjs();
25 15 : BUILD(r, WASM_BINOP(kExprI32AsmjsDivS, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
26 : const int32_t kMin = std::numeric_limits<int32_t>::min();
27 15 : CHECK_EQ(0, r.Call(0, 100));
28 15 : CHECK_EQ(0, r.Call(100, 0));
29 15 : CHECK_EQ(0, r.Call(-1001, 0));
30 15 : CHECK_EQ(kMin, r.Call(kMin, -1));
31 15 : CHECK_EQ(0, r.Call(kMin, 0));
32 15 : }
33 :
34 28367 : WASM_EXEC_TEST(Int32AsmjsRemS) {
35 15 : WasmRunner<int32_t, int32_t, int32_t> r(execution_tier);
36 : r.builder().ChangeOriginToAsmjs();
37 15 : BUILD(r, WASM_BINOP(kExprI32AsmjsRemS, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
38 : const int32_t kMin = std::numeric_limits<int32_t>::min();
39 15 : CHECK_EQ(33, r.Call(133, 100));
40 15 : CHECK_EQ(0, r.Call(kMin, -1));
41 15 : CHECK_EQ(0, r.Call(100, 0));
42 15 : CHECK_EQ(0, r.Call(-1001, 0));
43 15 : CHECK_EQ(0, r.Call(kMin, 0));
44 15 : }
45 :
46 28367 : WASM_EXEC_TEST(Int32AsmjsDivU) {
47 15 : WasmRunner<int32_t, int32_t, int32_t> r(execution_tier);
48 : r.builder().ChangeOriginToAsmjs();
49 15 : BUILD(r, WASM_BINOP(kExprI32AsmjsDivU, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
50 : const int32_t kMin = std::numeric_limits<int32_t>::min();
51 15 : CHECK_EQ(0, r.Call(0, 100));
52 15 : CHECK_EQ(0, r.Call(kMin, -1));
53 15 : CHECK_EQ(0, r.Call(100, 0));
54 15 : CHECK_EQ(0, r.Call(-1001, 0));
55 15 : CHECK_EQ(0, r.Call(kMin, 0));
56 15 : }
57 :
58 28367 : WASM_EXEC_TEST(Int32AsmjsRemU) {
59 15 : WasmRunner<int32_t, int32_t, int32_t> r(execution_tier);
60 : r.builder().ChangeOriginToAsmjs();
61 15 : BUILD(r, WASM_BINOP(kExprI32AsmjsRemU, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
62 : const int32_t kMin = std::numeric_limits<int32_t>::min();
63 15 : CHECK_EQ(17, r.Call(217, 100));
64 15 : CHECK_EQ(0, r.Call(100, 0));
65 15 : CHECK_EQ(0, r.Call(-1001, 0));
66 15 : CHECK_EQ(0, r.Call(kMin, 0));
67 15 : CHECK_EQ(kMin, r.Call(kMin, -1));
68 15 : }
69 :
70 28367 : WASM_EXEC_TEST(I32AsmjsSConvertF32) {
71 15 : WasmRunner<int32_t, float> r(execution_tier);
72 : r.builder().ChangeOriginToAsmjs();
73 15 : BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF32, WASM_GET_LOCAL(0)));
74 :
75 1740 : FOR_FLOAT32_INPUTS(i) {
76 1725 : int32_t expected = DoubleToInt32(*i);
77 1725 : CHECK_EQ(expected, r.Call(*i));
78 : }
79 15 : }
80 :
81 28367 : WASM_EXEC_TEST(I32AsmjsSConvertF64) {
82 15 : WasmRunner<int32_t, double> r(execution_tier);
83 : r.builder().ChangeOriginToAsmjs();
84 15 : BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF64, WASM_GET_LOCAL(0)));
85 :
86 750 : FOR_FLOAT64_INPUTS(i) {
87 735 : int32_t expected = DoubleToInt32(*i);
88 735 : CHECK_EQ(expected, r.Call(*i));
89 : }
90 15 : }
91 :
92 28367 : WASM_EXEC_TEST(I32AsmjsUConvertF32) {
93 15 : WasmRunner<uint32_t, float> r(execution_tier);
94 : r.builder().ChangeOriginToAsmjs();
95 15 : BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF32, WASM_GET_LOCAL(0)));
96 :
97 1740 : FOR_FLOAT32_INPUTS(i) {
98 1725 : uint32_t expected = DoubleToUint32(*i);
99 1725 : CHECK_EQ(expected, r.Call(*i));
100 : }
101 15 : }
102 :
103 28367 : WASM_EXEC_TEST(I32AsmjsUConvertF64) {
104 15 : WasmRunner<uint32_t, double> r(execution_tier);
105 : r.builder().ChangeOriginToAsmjs();
106 15 : BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF64, WASM_GET_LOCAL(0)));
107 :
108 750 : FOR_FLOAT64_INPUTS(i) {
109 735 : uint32_t expected = DoubleToUint32(*i);
110 735 : CHECK_EQ(expected, r.Call(*i));
111 : }
112 15 : }
113 :
114 28367 : WASM_EXEC_TEST(LoadMemI32_oob_asm) {
115 15 : WasmRunner<int32_t, uint32_t> r(execution_tier);
116 : r.builder().ChangeOriginToAsmjs();
117 : int32_t* memory = r.builder().AddMemoryElems<int32_t>(8);
118 15 : r.builder().RandomizeMemory(1112);
119 :
120 15 : BUILD(r, WASM_UNOP(kExprI32AsmjsLoadMem, WASM_GET_LOCAL(0)));
121 :
122 15 : memory[0] = 999999;
123 15 : CHECK_EQ(999999, r.Call(0u));
124 : // TODO(titzer): offset 29-31 should also be OOB.
125 120 : for (uint32_t offset = 32; offset < 40; offset++) {
126 120 : CHECK_EQ(0, r.Call(offset));
127 : }
128 :
129 240 : for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
130 240 : CHECK_EQ(0, r.Call(offset));
131 : }
132 15 : }
133 :
134 28367 : WASM_EXEC_TEST(LoadMemF32_oob_asm) {
135 15 : WasmRunner<float, uint32_t> r(execution_tier);
136 : r.builder().ChangeOriginToAsmjs();
137 : float* memory = r.builder().AddMemoryElems<float>(8);
138 15 : r.builder().RandomizeMemory(1112);
139 :
140 15 : BUILD(r, WASM_UNOP(kExprF32AsmjsLoadMem, WASM_GET_LOCAL(0)));
141 :
142 15 : memory[0] = 9999.5f;
143 15 : CHECK_EQ(9999.5f, r.Call(0u));
144 : // TODO(titzer): offset 29-31 should also be OOB.
145 120 : for (uint32_t offset = 32; offset < 40; offset++) {
146 120 : CHECK(std::isnan(r.Call(offset)));
147 : }
148 :
149 240 : for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
150 240 : CHECK(std::isnan(r.Call(offset)));
151 : }
152 15 : }
153 :
154 28367 : WASM_EXEC_TEST(LoadMemF64_oob_asm) {
155 15 : WasmRunner<double, uint32_t> r(execution_tier);
156 : r.builder().ChangeOriginToAsmjs();
157 : double* memory = r.builder().AddMemoryElems<double>(8);
158 15 : r.builder().RandomizeMemory(1112);
159 :
160 15 : BUILD(r, WASM_UNOP(kExprF64AsmjsLoadMem, WASM_GET_LOCAL(0)));
161 :
162 15 : memory[0] = 9799.5;
163 15 : CHECK_EQ(9799.5, r.Call(0u));
164 15 : memory[1] = 11799.25;
165 15 : CHECK_EQ(11799.25, r.Call(8u));
166 : // TODO(titzer): offset 57-63 should also be OOB.
167 240 : for (uint32_t offset = 64; offset < 80; offset++) {
168 240 : CHECK(std::isnan(r.Call(offset)));
169 : }
170 :
171 240 : for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
172 240 : CHECK(std::isnan(r.Call(offset)));
173 : }
174 15 : }
175 :
176 28367 : WASM_EXEC_TEST(StoreMemI32_oob_asm) {
177 15 : WasmRunner<int32_t, uint32_t, uint32_t> r(execution_tier);
178 : r.builder().ChangeOriginToAsmjs();
179 : int32_t* memory = r.builder().AddMemoryElems<int32_t>(8);
180 15 : r.builder().RandomizeMemory(1112);
181 :
182 15 : BUILD(r, WASM_BINOP(kExprI32AsmjsStoreMem, WASM_GET_LOCAL(0),
183 : WASM_GET_LOCAL(1)));
184 :
185 15 : memory[0] = 7777;
186 15 : CHECK_EQ(999999, r.Call(0u, 999999));
187 15 : CHECK_EQ(999999, memory[0]);
188 : // TODO(titzer): offset 29-31 should also be OOB.
189 120 : for (uint32_t offset = 32; offset < 40; offset++) {
190 120 : CHECK_EQ(8888, r.Call(offset, 8888));
191 : }
192 :
193 3360 : for (uint32_t offset = 0x10000000; offset < 0xF0000000; offset += 0x1000000) {
194 3360 : CHECK_EQ(7777, r.Call(offset, 7777));
195 : }
196 15 : }
197 :
198 : } // namespace wasm
199 : } // namespace internal
200 85011 : } // namespace v8
|