OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 #include <stdint.h> | 5 #include <stdint.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "src/base/utils/random-number-generator.h" | 9 #include "src/base/utils/random-number-generator.h" |
10 | 10 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 if (module == nullptr) { | 190 if (module == nullptr) { |
191 module = new WasmModule(); | 191 module = new WasmModule(); |
192 module->globals = nullptr; | 192 module->globals = nullptr; |
193 module->functions = nullptr; | 193 module->functions = nullptr; |
194 module->data_segments = nullptr; | 194 module->data_segments = nullptr; |
195 } | 195 } |
196 } | 196 } |
197 }; | 197 }; |
198 | 198 |
199 | 199 |
| 200 static void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, FunctionEnv* env, |
| 201 const byte* start, const byte* end) { |
| 202 compiler::WasmGraphBuilder builder(zone, jsgraph, env->sig); |
| 203 TreeResult result = BuildTFGraph(&builder, env, start, end); |
| 204 if (result.failed()) { |
| 205 ptrdiff_t pc = result.error_pc - result.start; |
| 206 ptrdiff_t pt = result.error_pt - result.start; |
| 207 std::ostringstream str; |
| 208 str << "Verification failed: " << result.error_code << " pc = +" << pc; |
| 209 if (result.error_pt) str << ", pt = +" << pt; |
| 210 str << ", msg = " << result.error_msg.get(); |
| 211 FATAL(str.str().c_str()); |
| 212 } |
| 213 if (FLAG_trace_turbo_graph) { |
| 214 OFStream os(stdout); |
| 215 os << AsRPO(*jsgraph->graph()); |
| 216 } |
| 217 } |
| 218 |
| 219 |
200 // A helper for compiling functions that are only internally callable WASM code. | 220 // A helper for compiling functions that are only internally callable WASM code. |
201 class WasmFunctionCompiler : public HandleAndZoneScope, | 221 class WasmFunctionCompiler : public HandleAndZoneScope, |
202 private GraphAndBuilders { | 222 private GraphAndBuilders { |
203 public: | 223 public: |
204 explicit WasmFunctionCompiler(FunctionSig* sig) | 224 explicit WasmFunctionCompiler(FunctionSig* sig) |
205 : GraphAndBuilders(main_zone()), | 225 : GraphAndBuilders(main_zone()), |
206 jsgraph(this->isolate(), this->graph(), this->common(), nullptr, | 226 jsgraph(this->isolate(), this->graph(), this->common(), nullptr, |
207 nullptr, this->machine()), | 227 nullptr, this->machine()), |
208 descriptor_(nullptr) { | 228 descriptor_(nullptr) { |
209 init_env(&env, sig); | 229 init_env(&env, sig); |
210 } | 230 } |
211 | 231 |
212 JSGraph jsgraph; | 232 JSGraph jsgraph; |
213 FunctionEnv env; | 233 FunctionEnv env; |
214 // The call descriptor is initialized when the function is compiled. | 234 // The call descriptor is initialized when the function is compiled. |
215 CallDescriptor* descriptor_; | 235 CallDescriptor* descriptor_; |
216 | 236 |
217 Isolate* isolate() { return main_isolate(); } | 237 Isolate* isolate() { return main_isolate(); } |
218 Graph* graph() const { return main_graph_; } | 238 Graph* graph() const { return main_graph_; } |
219 Zone* zone() const { return graph()->zone(); } | 239 Zone* zone() const { return graph()->zone(); } |
220 CommonOperatorBuilder* common() { return &main_common_; } | 240 CommonOperatorBuilder* common() { return &main_common_; } |
221 MachineOperatorBuilder* machine() { return &main_machine_; } | 241 MachineOperatorBuilder* machine() { return &main_machine_; } |
222 CallDescriptor* descriptor() { return descriptor_; } | 242 CallDescriptor* descriptor() { return descriptor_; } |
223 | 243 |
224 void Build(const byte* start, const byte* end) { | 244 void Build(const byte* start, const byte* end) { |
225 compiler::WasmGraphBuilder builder(main_zone(), &jsgraph, env.sig); | 245 TestBuildingGraph(main_zone(), &jsgraph, &env, start, end); |
226 TreeResult result = BuildTFGraph(&builder, &env, start, end); | |
227 if (result.failed()) { | |
228 ptrdiff_t pc = result.error_pc - result.start; | |
229 ptrdiff_t pt = result.error_pt - result.start; | |
230 std::ostringstream str; | |
231 str << "Verification failed: " << result.error_code << " pc = +" << pc; | |
232 if (result.error_pt) str << ", pt = +" << pt; | |
233 str << ", msg = " << result.error_msg.get(); | |
234 FATAL(str.str().c_str()); | |
235 } | |
236 if (FLAG_trace_turbo_graph) { | |
237 OFStream os(stdout); | |
238 os << AsRPO(*jsgraph.graph()); | |
239 } | |
240 } | 246 } |
241 | 247 |
242 byte AllocateLocal(LocalType type) { | 248 byte AllocateLocal(LocalType type) { |
243 int result = static_cast<int>(env.total_locals); | 249 int result = static_cast<int>(env.total_locals); |
244 env.AddLocals(type, 1); | 250 env.AddLocals(type, 1); |
245 byte b = static_cast<byte>(result); | 251 byte b = static_cast<byte>(result); |
246 CHECK_EQ(result, b); | 252 CHECK_EQ(result, b); |
247 return b; | 253 return b; |
248 } | 254 } |
249 | 255 |
(...skipping 2080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2330 | 2336 |
2331 TEST(Run_Wasm_Infinite_Loop_not_taken2_brif) { | 2337 TEST(Run_Wasm_Infinite_Loop_not_taken2_brif) { |
2332 WasmRunner<int32_t> r(MachineType::Int32()); | 2338 WasmRunner<int32_t> r(MachineType::Int32()); |
2333 BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(45)), | 2339 BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(45)), |
2334 WASM_INFINITE_LOOP)); | 2340 WASM_INFINITE_LOOP)); |
2335 // Run the code, but don't go into the infinite loop. | 2341 // Run the code, but don't go into the infinite loop. |
2336 CHECK_EQ(45, r.Call(1)); | 2342 CHECK_EQ(45, r.Call(1)); |
2337 } | 2343 } |
2338 | 2344 |
2339 | 2345 |
2340 // TODO(titzer): Fix for nosee4 and re-enable. | 2346 static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) { |
2341 #if 0 | 2347 if (!WasmOpcodes::IsSupported(opcode)) return; |
2342 | 2348 |
2343 static void TestBuildGraphForUnop(WasmOpcode opcode, FunctionSig* sig) { | 2349 Zone zone; |
2344 WasmRunner<int32_t> r(MachineType::Int32()); | 2350 Isolate* isolate = CcTest::InitIsolateOnce(); |
2345 init_env(r.env(), sig); | 2351 HandleScope scope(isolate); |
2346 BUILD(r, static_cast<byte>(opcode), kExprGetLocal, 0); | 2352 // Enable all optional operators. |
2347 } | 2353 CommonOperatorBuilder common(&zone); |
| 2354 MachineOperatorBuilder machine(&zone, MachineType::PointerRepresentation(), |
| 2355 MachineOperatorBuilder::kAllOptionalOps); |
| 2356 Graph graph(&zone); |
| 2357 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); |
| 2358 FunctionEnv env; |
| 2359 FunctionSig* sig = WasmOpcodes::Signature(opcode); |
| 2360 init_env(&env, sig); |
2348 | 2361 |
2349 | 2362 if (sig->parameter_count() == 1) { |
2350 static void TestBuildGraphForBinop(WasmOpcode opcode, FunctionSig* sig) { | 2363 byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0}; |
2351 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); | 2364 TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code)); |
2352 init_env(r.env(), sig); | 2365 } else { |
2353 BUILD(r, static_cast<byte>(opcode), kExprGetLocal, 0, kExprGetLocal, 1); | 2366 CHECK_EQ(2, sig->parameter_count()); |
| 2367 byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0, kExprGetLocal, |
| 2368 1}; |
| 2369 TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code)); |
| 2370 } |
2354 } | 2371 } |
2355 | 2372 |
2356 | 2373 |
2357 TEST(Build_Wasm_SimpleExprs) { | 2374 TEST(Build_Wasm_SimpleExprs) { |
2358 // Test that the decoder can build a graph for all supported simple expressions. | 2375 // Test that the decoder can build a graph for all supported simple expressions. |
2359 #define GRAPH_BUILD_TEST(name, opcode, sig) \ | 2376 #define GRAPH_BUILD_TEST(name, opcode, sig) \ |
2360 if (WasmOpcodes::IsSupported(kExpr##name)) { \ | 2377 TestBuildGraphForSimpleExpression(kExpr##name); |
2361 FunctionSig* sig = WasmOpcodes::Signature(kExpr##name); \ | |
2362 printf("expression: " #name "\n"); \ | |
2363 if (sig->parameter_count() == 1) { \ | |
2364 TestBuildGraphForUnop(kExpr##name, sig); \ | |
2365 } else { \ | |
2366 TestBuildGraphForBinop(kExpr##name, sig); \ | |
2367 } \ | |
2368 } | |
2369 | 2378 |
2370 FOREACH_SIMPLE_OPCODE(GRAPH_BUILD_TEST); | 2379 FOREACH_SIMPLE_OPCODE(GRAPH_BUILD_TEST); |
2371 | 2380 |
2372 #undef GRAPH_BUILD_TEST | 2381 #undef GRAPH_BUILD_TEST |
2373 } | 2382 } |
2374 | 2383 |
2375 #endif | |
2376 | |
2377 | 2384 |
2378 TEST(Run_Wasm_Int32LoadInt8_signext) { | 2385 TEST(Run_Wasm_Int32LoadInt8_signext) { |
2379 TestingModule module; | 2386 TestingModule module; |
2380 const int kNumElems = 16; | 2387 const int kNumElems = 16; |
2381 int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems); | 2388 int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems); |
2382 module.RandomizeMemory(); | 2389 module.RandomizeMemory(); |
2383 memory[0] = -1; | 2390 memory[0] = -1; |
2384 WasmRunner<int32_t> r(MachineType::Int32()); | 2391 WasmRunner<int32_t> r(MachineType::Int32()); |
2385 r.env()->module = &module; | 2392 r.env()->module = &module; |
2386 BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))); | 2393 BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))); |
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3609 TEST(Run_Wasm_F32CopySign) { | 3616 TEST(Run_Wasm_F32CopySign) { |
3610 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32()); | 3617 WasmRunner<float> r(MachineType::Float32(), MachineType::Float32()); |
3611 BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 3618 BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
3612 | 3619 |
3613 FOR_FLOAT32_INPUTS(i) { | 3620 FOR_FLOAT32_INPUTS(i) { |
3614 FOR_FLOAT32_INPUTS(j) { CheckFloatEq(copysign(*i, *j), r.Call(*i, *j)); } | 3621 FOR_FLOAT32_INPUTS(j) { CheckFloatEq(copysign(*i, *j), r.Call(*i, *j)); } |
3615 } | 3622 } |
3616 } | 3623 } |
3617 | 3624 |
3618 #endif | 3625 #endif |
OLD | NEW |