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 26663 : WASM_EXEC_TEST(Int32AsmjsDivS) {
23 24 : WasmRunner<int32_t, int32_t, int32_t> r(execution_tier);
24 : r.builder().ChangeOriginToAsmjs();
25 12 : 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 12 : CHECK_EQ(0, r.Call(0, 100));
28 12 : CHECK_EQ(0, r.Call(100, 0));
29 12 : CHECK_EQ(0, r.Call(-1001, 0));
30 12 : CHECK_EQ(kMin, r.Call(kMin, -1));
31 12 : CHECK_EQ(0, r.Call(kMin, 0));
32 12 : }
33 :
34 26663 : WASM_EXEC_TEST(Int32AsmjsRemS) {
35 24 : WasmRunner<int32_t, int32_t, int32_t> r(execution_tier);
36 : r.builder().ChangeOriginToAsmjs();
37 12 : 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 12 : CHECK_EQ(33, r.Call(133, 100));
40 12 : CHECK_EQ(0, r.Call(kMin, -1));
41 12 : CHECK_EQ(0, r.Call(100, 0));
42 12 : CHECK_EQ(0, r.Call(-1001, 0));
43 12 : CHECK_EQ(0, r.Call(kMin, 0));
44 12 : }
45 :
46 26663 : WASM_EXEC_TEST(Int32AsmjsDivU) {
47 24 : WasmRunner<int32_t, int32_t, int32_t> r(execution_tier);
48 : r.builder().ChangeOriginToAsmjs();
49 12 : 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 12 : CHECK_EQ(0, r.Call(0, 100));
52 12 : CHECK_EQ(0, r.Call(kMin, -1));
53 12 : CHECK_EQ(0, r.Call(100, 0));
54 12 : CHECK_EQ(0, r.Call(-1001, 0));
55 12 : CHECK_EQ(0, r.Call(kMin, 0));
56 12 : }
57 :
58 26663 : WASM_EXEC_TEST(Int32AsmjsRemU) {
59 24 : WasmRunner<int32_t, int32_t, int32_t> r(execution_tier);
60 : r.builder().ChangeOriginToAsmjs();
61 12 : 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 12 : CHECK_EQ(17, r.Call(217, 100));
64 12 : CHECK_EQ(0, r.Call(100, 0));
65 12 : CHECK_EQ(0, r.Call(-1001, 0));
66 12 : CHECK_EQ(0, r.Call(kMin, 0));
67 12 : CHECK_EQ(kMin, r.Call(kMin, -1));
68 12 : }
69 :
70 26663 : WASM_EXEC_TEST(I32AsmjsSConvertF32) {
71 24 : WasmRunner<int32_t, float> r(execution_tier);
72 : r.builder().ChangeOriginToAsmjs();
73 12 : BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF32, WASM_GET_LOCAL(0)));
74 :
75 2772 : FOR_FLOAT32_INPUTS(i) {
76 1380 : int32_t expected = DoubleToInt32(i);
77 1380 : CHECK_EQ(expected, r.Call(i));
78 : }
79 12 : }
80 :
81 26663 : WASM_EXEC_TEST(I32AsmjsSConvertF64) {
82 24 : WasmRunner<int32_t, double> r(execution_tier);
83 : r.builder().ChangeOriginToAsmjs();
84 12 : BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF64, WASM_GET_LOCAL(0)));
85 :
86 1188 : FOR_FLOAT64_INPUTS(i) {
87 588 : int32_t expected = DoubleToInt32(i);
88 588 : CHECK_EQ(expected, r.Call(i));
89 : }
90 12 : }
91 :
92 26663 : WASM_EXEC_TEST(I32AsmjsUConvertF32) {
93 24 : WasmRunner<uint32_t, float> r(execution_tier);
94 : r.builder().ChangeOriginToAsmjs();
95 12 : BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF32, WASM_GET_LOCAL(0)));
96 :
97 2772 : FOR_FLOAT32_INPUTS(i) {
98 1380 : uint32_t expected = DoubleToUint32(i);
99 1380 : CHECK_EQ(expected, r.Call(i));
100 : }
101 12 : }
102 :
103 26663 : WASM_EXEC_TEST(I32AsmjsUConvertF64) {
104 24 : WasmRunner<uint32_t, double> r(execution_tier);
105 : r.builder().ChangeOriginToAsmjs();
106 12 : BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF64, WASM_GET_LOCAL(0)));
107 :
108 1188 : FOR_FLOAT64_INPUTS(i) {
109 : uint32_t expected = DoubleToUint32(i);
110 588 : CHECK_EQ(expected, r.Call(i));
111 : }
112 12 : }
113 :
114 26663 : WASM_EXEC_TEST(LoadMemI32_oob_asm) {
115 24 : WasmRunner<int32_t, uint32_t> r(execution_tier);
116 : r.builder().ChangeOriginToAsmjs();
117 : int32_t* memory = r.builder().AddMemoryElems<int32_t>(8);
118 12 : r.builder().RandomizeMemory(1112);
119 :
120 12 : BUILD(r, WASM_UNOP(kExprI32AsmjsLoadMem, WASM_GET_LOCAL(0)));
121 :
122 12 : memory[0] = 999999;
123 12 : CHECK_EQ(999999, r.Call(0u));
124 : // TODO(titzer): offset 29-31 should also be OOB.
125 204 : for (uint32_t offset = 32; offset < 40; offset++) {
126 96 : CHECK_EQ(0, r.Call(offset));
127 : }
128 :
129 396 : for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
130 192 : CHECK_EQ(0, r.Call(offset));
131 : }
132 12 : }
133 :
134 26663 : WASM_EXEC_TEST(LoadMemF32_oob_asm) {
135 24 : WasmRunner<float, uint32_t> r(execution_tier);
136 : r.builder().ChangeOriginToAsmjs();
137 : float* memory = r.builder().AddMemoryElems<float>(8);
138 12 : r.builder().RandomizeMemory(1112);
139 :
140 12 : BUILD(r, WASM_UNOP(kExprF32AsmjsLoadMem, WASM_GET_LOCAL(0)));
141 :
142 12 : memory[0] = 9999.5f;
143 12 : CHECK_EQ(9999.5f, r.Call(0u));
144 : // TODO(titzer): offset 29-31 should also be OOB.
145 204 : for (uint32_t offset = 32; offset < 40; offset++) {
146 96 : CHECK(std::isnan(r.Call(offset)));
147 : }
148 :
149 396 : for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
150 192 : CHECK(std::isnan(r.Call(offset)));
151 : }
152 12 : }
153 :
154 26663 : WASM_EXEC_TEST(LoadMemF64_oob_asm) {
155 24 : WasmRunner<double, uint32_t> r(execution_tier);
156 : r.builder().ChangeOriginToAsmjs();
157 : double* memory = r.builder().AddMemoryElems<double>(8);
158 12 : r.builder().RandomizeMemory(1112);
159 :
160 12 : BUILD(r, WASM_UNOP(kExprF64AsmjsLoadMem, WASM_GET_LOCAL(0)));
161 :
162 12 : memory[0] = 9799.5;
163 12 : CHECK_EQ(9799.5, r.Call(0u));
164 12 : memory[1] = 11799.25;
165 12 : CHECK_EQ(11799.25, r.Call(8u));
166 : // TODO(titzer): offset 57-63 should also be OOB.
167 396 : for (uint32_t offset = 64; offset < 80; offset++) {
168 192 : CHECK(std::isnan(r.Call(offset)));
169 : }
170 :
171 396 : for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) {
172 192 : CHECK(std::isnan(r.Call(offset)));
173 : }
174 12 : }
175 :
176 26663 : WASM_EXEC_TEST(StoreMemI32_oob_asm) {
177 24 : 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 12 : r.builder().RandomizeMemory(1112);
181 :
182 12 : BUILD(r, WASM_BINOP(kExprI32AsmjsStoreMem, WASM_GET_LOCAL(0),
183 : WASM_GET_LOCAL(1)));
184 :
185 12 : memory[0] = 7777;
186 12 : CHECK_EQ(999999, r.Call(0u, 999999));
187 12 : CHECK_EQ(999999, memory[0]);
188 : // TODO(titzer): offset 29-31 should also be OOB.
189 204 : for (uint32_t offset = 32; offset < 40; offset++) {
190 96 : CHECK_EQ(8888, r.Call(offset, 8888));
191 : }
192 :
193 5388 : for (uint32_t offset = 0x10000000; offset < 0xF0000000; offset += 0x1000000) {
194 2688 : CHECK_EQ(7777, r.Call(offset, 7777));
195 : }
196 12 : }
197 :
198 : } // namespace wasm
199 : } // namespace internal
200 79917 : } // namespace v8
|