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 <functional> | 5 #include <functional> |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 #include "src/compiler/operator-properties.h" | 10 #include "src/compiler/operator-properties.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 int32s.push_back(+1); | 44 int32s.push_back(+1); |
45 int32s.push_back(kMinInt); | 45 int32s.push_back(kMinInt); |
46 int32s.push_back(kMaxInt); | 46 int32s.push_back(kMaxInt); |
47 for (int i = 0; i < 10; ++i) { | 47 for (int i = 0; i < 10; ++i) { |
48 int32s.push_back(rng_->NextInt()); | 48 int32s.push_back(rng_->NextInt()); |
49 } | 49 } |
50 } | 50 } |
51 | 51 |
52 Types<Type, Type*, Zone> types_; | 52 Types<Type, Type*, Zone> types_; |
53 JSOperatorBuilder javascript_; | 53 JSOperatorBuilder javascript_; |
| 54 BinaryOperationHints const hints_ = BinaryOperationHints::Any(); |
54 Node* context_node_; | 55 Node* context_node_; |
55 v8::base::RandomNumberGenerator* rng_; | 56 v8::base::RandomNumberGenerator* rng_; |
56 std::vector<double> integers; | 57 std::vector<double> integers; |
57 std::vector<double> int32s; | 58 std::vector<double> int32s; |
58 | 59 |
59 Type* TypeBinaryOp(const Operator* op, Type* lhs, Type* rhs) { | 60 Type* TypeBinaryOp(const Operator* op, Type* lhs, Type* rhs) { |
60 Node* p0 = Parameter(0); | 61 Node* p0 = Parameter(0); |
61 Node* p1 = Parameter(1); | 62 Node* p1 = Parameter(1); |
62 NodeProperties::SetType(p0, lhs); | 63 NodeProperties::SetType(p0, lhs); |
63 NodeProperties::SetType(p1, rhs); | 64 NodeProperties::SetType(p1, rhs); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 | 233 |
233 | 234 |
234 //------------------------------------------------------------------------------ | 235 //------------------------------------------------------------------------------ |
235 // Soundness | 236 // Soundness |
236 // For simplicity, we currently only test soundness on expression operators | 237 // For simplicity, we currently only test soundness on expression operators |
237 // that have a direct equivalent in C++. Also, testing is currently limited | 238 // that have a direct equivalent in C++. Also, testing is currently limited |
238 // to ranges as input types. | 239 // to ranges as input types. |
239 | 240 |
240 | 241 |
241 TEST_F(TyperTest, TypeJSAdd) { | 242 TEST_F(TyperTest, TypeJSAdd) { |
242 TestBinaryArithOp(javascript_.Add(LanguageMode::SLOPPY), std::plus<double>()); | 243 TestBinaryArithOp(javascript_.Add(LanguageMode::SLOPPY, hints_), |
243 TestBinaryArithOp(javascript_.Add(LanguageMode::STRONG), std::plus<double>()); | 244 std::plus<double>()); |
| 245 TestBinaryArithOp(javascript_.Add(LanguageMode::STRONG, hints_), |
| 246 std::plus<double>()); |
244 } | 247 } |
245 | 248 |
246 | 249 |
247 TEST_F(TyperTest, TypeJSSubtract) { | 250 TEST_F(TyperTest, TypeJSSubtract) { |
248 TestBinaryArithOp(javascript_.Subtract(LanguageMode::SLOPPY), | 251 TestBinaryArithOp(javascript_.Subtract(LanguageMode::SLOPPY, hints_), |
249 std::minus<double>()); | 252 std::minus<double>()); |
250 TestBinaryArithOp(javascript_.Subtract(LanguageMode::STRONG), | 253 TestBinaryArithOp(javascript_.Subtract(LanguageMode::STRONG, hints_), |
251 std::minus<double>()); | 254 std::minus<double>()); |
252 } | 255 } |
253 | 256 |
254 | 257 |
255 TEST_F(TyperTest, TypeJSMultiply) { | 258 TEST_F(TyperTest, TypeJSMultiply) { |
256 TestBinaryArithOp(javascript_.Multiply(LanguageMode::SLOPPY), | 259 TestBinaryArithOp(javascript_.Multiply(LanguageMode::SLOPPY, hints_), |
257 std::multiplies<double>()); | 260 std::multiplies<double>()); |
258 TestBinaryArithOp(javascript_.Multiply(LanguageMode::STRONG), | 261 TestBinaryArithOp(javascript_.Multiply(LanguageMode::STRONG, hints_), |
259 std::multiplies<double>()); | 262 std::multiplies<double>()); |
260 } | 263 } |
261 | 264 |
262 | 265 |
263 TEST_F(TyperTest, TypeJSDivide) { | 266 TEST_F(TyperTest, TypeJSDivide) { |
264 TestBinaryArithOp(javascript_.Divide(LanguageMode::SLOPPY), | 267 TestBinaryArithOp(javascript_.Divide(LanguageMode::SLOPPY, hints_), |
265 std::divides<double>()); | 268 std::divides<double>()); |
266 TestBinaryArithOp(javascript_.Divide(LanguageMode::STRONG), | 269 TestBinaryArithOp(javascript_.Divide(LanguageMode::STRONG, hints_), |
267 std::divides<double>()); | 270 std::divides<double>()); |
268 } | 271 } |
269 | 272 |
270 | 273 |
271 TEST_F(TyperTest, TypeJSModulus) { | 274 TEST_F(TyperTest, TypeJSModulus) { |
272 TestBinaryArithOp(javascript_.Modulus(LanguageMode::SLOPPY), modulo); | 275 TestBinaryArithOp(javascript_.Modulus(LanguageMode::SLOPPY, hints_), modulo); |
273 TestBinaryArithOp(javascript_.Modulus(LanguageMode::STRONG), modulo); | 276 TestBinaryArithOp(javascript_.Modulus(LanguageMode::STRONG, hints_), modulo); |
274 } | 277 } |
275 | 278 |
276 | 279 |
277 TEST_F(TyperTest, TypeJSBitwiseOr) { | 280 TEST_F(TyperTest, TypeJSBitwiseOr) { |
278 TestBinaryBitOp(javascript_.BitwiseOr(LanguageMode::SLOPPY), bit_or); | 281 TestBinaryBitOp(javascript_.BitwiseOr(LanguageMode::SLOPPY, hints_), bit_or); |
279 TestBinaryBitOp(javascript_.BitwiseOr(LanguageMode::STRONG), bit_or); | 282 TestBinaryBitOp(javascript_.BitwiseOr(LanguageMode::STRONG, hints_), bit_or); |
280 } | 283 } |
281 | 284 |
282 | 285 |
283 TEST_F(TyperTest, TypeJSBitwiseAnd) { | 286 TEST_F(TyperTest, TypeJSBitwiseAnd) { |
284 TestBinaryBitOp(javascript_.BitwiseAnd(LanguageMode::SLOPPY), bit_and); | 287 TestBinaryBitOp(javascript_.BitwiseAnd(LanguageMode::SLOPPY, hints_), |
285 TestBinaryBitOp(javascript_.BitwiseAnd(LanguageMode::STRONG), bit_and); | 288 bit_and); |
| 289 TestBinaryBitOp(javascript_.BitwiseAnd(LanguageMode::STRONG, hints_), |
| 290 bit_and); |
286 } | 291 } |
287 | 292 |
288 | 293 |
289 TEST_F(TyperTest, TypeJSBitwiseXor) { | 294 TEST_F(TyperTest, TypeJSBitwiseXor) { |
290 TestBinaryBitOp(javascript_.BitwiseXor(LanguageMode::SLOPPY), bit_xor); | 295 TestBinaryBitOp(javascript_.BitwiseXor(LanguageMode::SLOPPY, hints_), |
291 TestBinaryBitOp(javascript_.BitwiseXor(LanguageMode::STRONG), bit_xor); | 296 bit_xor); |
| 297 TestBinaryBitOp(javascript_.BitwiseXor(LanguageMode::STRONG, hints_), |
| 298 bit_xor); |
292 } | 299 } |
293 | 300 |
294 | 301 |
295 TEST_F(TyperTest, TypeJSShiftLeft) { | 302 TEST_F(TyperTest, TypeJSShiftLeft) { |
296 TestBinaryBitOp(javascript_.ShiftLeft(LanguageMode::SLOPPY), shift_left); | 303 TestBinaryBitOp(javascript_.ShiftLeft(LanguageMode::SLOPPY, hints_), |
297 TestBinaryBitOp(javascript_.ShiftLeft(LanguageMode::STRONG), shift_left); | 304 shift_left); |
| 305 TestBinaryBitOp(javascript_.ShiftLeft(LanguageMode::STRONG, hints_), |
| 306 shift_left); |
298 } | 307 } |
299 | 308 |
300 | 309 |
301 TEST_F(TyperTest, TypeJSShiftRight) { | 310 TEST_F(TyperTest, TypeJSShiftRight) { |
302 TestBinaryBitOp(javascript_.ShiftRight(LanguageMode::SLOPPY), shift_right); | 311 TestBinaryBitOp(javascript_.ShiftRight(LanguageMode::SLOPPY, hints_), |
303 TestBinaryBitOp(javascript_.ShiftRight(LanguageMode::STRONG), shift_right); | 312 shift_right); |
| 313 TestBinaryBitOp(javascript_.ShiftRight(LanguageMode::STRONG, hints_), |
| 314 shift_right); |
304 } | 315 } |
305 | 316 |
306 | 317 |
307 TEST_F(TyperTest, TypeJSLessThan) { | 318 TEST_F(TyperTest, TypeJSLessThan) { |
308 TestBinaryCompareOp(javascript_.LessThan(LanguageMode::SLOPPY), | 319 TestBinaryCompareOp(javascript_.LessThan(LanguageMode::SLOPPY), |
309 std::less<double>()); | 320 std::less<double>()); |
310 TestBinaryCompareOp(javascript_.LessThan(LanguageMode::STRONG), | 321 TestBinaryCompareOp(javascript_.LessThan(LanguageMode::STRONG), |
311 std::less<double>()); | 322 std::less<double>()); |
312 } | 323 } |
313 | 324 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 TEST_F(TyperTest, TypeJSStrictNotEqual) { | 366 TEST_F(TyperTest, TypeJSStrictNotEqual) { |
356 TestBinaryCompareOp(javascript_.StrictNotEqual(), | 367 TestBinaryCompareOp(javascript_.StrictNotEqual(), |
357 std::not_equal_to<double>()); | 368 std::not_equal_to<double>()); |
358 } | 369 } |
359 | 370 |
360 | 371 |
361 //------------------------------------------------------------------------------ | 372 //------------------------------------------------------------------------------ |
362 // Monotonicity | 373 // Monotonicity |
363 | 374 |
364 | 375 |
365 // List should be in sync with JS_SIMPLE_BINOP_LIST. | 376 #define TEST_BINARY_MONOTONICITY(name) \ |
366 #define JSBINOP_LIST(V) \ | |
367 V(Equal) \ | |
368 V(NotEqual) \ | |
369 V(StrictEqual) \ | |
370 V(StrictNotEqual) | |
371 | |
372 | |
373 #define JSBINOP_WITH_STRONG_LIST(V) \ | |
374 V(LessThan) \ | |
375 V(GreaterThan) \ | |
376 V(LessThanOrEqual) \ | |
377 V(GreaterThanOrEqual) \ | |
378 V(BitwiseOr) \ | |
379 V(BitwiseXor) \ | |
380 V(BitwiseAnd) \ | |
381 V(ShiftLeft) \ | |
382 V(ShiftRight) \ | |
383 V(ShiftRightLogical) \ | |
384 V(Add) \ | |
385 V(Subtract) \ | |
386 V(Multiply) \ | |
387 V(Divide) \ | |
388 V(Modulus) | |
389 | |
390 | |
391 #define TEST_FUNC(name) \ | |
392 TEST_F(TyperTest, Monotonicity_##name) { \ | 377 TEST_F(TyperTest, Monotonicity_##name) { \ |
393 TestBinaryMonotonicity(javascript_.name()); \ | 378 TestBinaryMonotonicity(javascript_.name()); \ |
394 } | 379 } |
395 JSBINOP_LIST(TEST_FUNC) | 380 TEST_BINARY_MONOTONICITY(Equal) |
396 #undef TEST_FUNC | 381 TEST_BINARY_MONOTONICITY(NotEqual) |
| 382 TEST_BINARY_MONOTONICITY(StrictEqual) |
| 383 TEST_BINARY_MONOTONICITY(StrictNotEqual) |
| 384 #undef TEST_BINARY_MONOTONICITY |
397 | 385 |
398 | 386 |
399 #define TEST_FUNC(name) \ | 387 #define TEST_BINARY_MONOTONICITY(name) \ |
400 TEST_F(TyperTest, Monotonicity_##name) { \ | 388 TEST_F(TyperTest, Monotonicity_##name) { \ |
401 TestBinaryMonotonicity(javascript_.name(LanguageMode::SLOPPY)); \ | 389 TestBinaryMonotonicity(javascript_.name(LanguageMode::SLOPPY)); \ |
402 TestBinaryMonotonicity(javascript_.name(LanguageMode::STRONG)); \ | 390 TestBinaryMonotonicity(javascript_.name(LanguageMode::STRONG)); \ |
403 } | 391 } |
404 JSBINOP_WITH_STRONG_LIST(TEST_FUNC) | 392 TEST_BINARY_MONOTONICITY(LessThan) |
405 #undef TEST_FUNC | 393 TEST_BINARY_MONOTONICITY(GreaterThan) |
| 394 TEST_BINARY_MONOTONICITY(LessThanOrEqual) |
| 395 TEST_BINARY_MONOTONICITY(GreaterThanOrEqual) |
| 396 #undef TEST_BINARY_MONOTONICITY |
| 397 |
| 398 |
| 399 #define TEST_BINARY_MONOTONICITY(name) \ |
| 400 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 401 TestBinaryMonotonicity( \ |
| 402 javascript_.name(LanguageMode::SLOPPY, BinaryOperationHints::Any())); \ |
| 403 TestBinaryMonotonicity( \ |
| 404 javascript_.name(LanguageMode::STRONG, BinaryOperationHints::Any())); \ |
| 405 } |
| 406 TEST_BINARY_MONOTONICITY(BitwiseOr) |
| 407 TEST_BINARY_MONOTONICITY(BitwiseXor) |
| 408 TEST_BINARY_MONOTONICITY(BitwiseAnd) |
| 409 TEST_BINARY_MONOTONICITY(ShiftLeft) |
| 410 TEST_BINARY_MONOTONICITY(ShiftRight) |
| 411 TEST_BINARY_MONOTONICITY(ShiftRightLogical) |
| 412 TEST_BINARY_MONOTONICITY(Add) |
| 413 TEST_BINARY_MONOTONICITY(Subtract) |
| 414 TEST_BINARY_MONOTONICITY(Multiply) |
| 415 TEST_BINARY_MONOTONICITY(Divide) |
| 416 TEST_BINARY_MONOTONICITY(Modulus) |
| 417 #undef TEST_BINARY_MONOTONICITY |
406 | 418 |
407 | 419 |
408 //------------------------------------------------------------------------------ | 420 //------------------------------------------------------------------------------ |
409 // Regression tests | 421 // Regression tests |
410 | 422 |
411 | 423 |
412 TEST_F(TyperTest, TypeRegressInt32Constant) { | 424 TEST_F(TyperTest, TypeRegressInt32Constant) { |
413 int values[] = {-5, 10}; | 425 int values[] = {-5, 10}; |
414 for (auto i : values) { | 426 for (auto i : values) { |
415 Node* c = graph()->NewNode(common()->Int32Constant(i)); | 427 Node* c = graph()->NewNode(common()->Int32Constant(i)); |
416 Type* type = NodeProperties::GetType(c); | 428 Type* type = NodeProperties::GetType(c); |
417 EXPECT_TRUE(type->Is(NewRange(i, i))); | 429 EXPECT_TRUE(type->Is(NewRange(i, i))); |
418 } | 430 } |
419 } | 431 } |
420 | 432 |
421 } // namespace compiler | 433 } // namespace compiler |
422 } // namespace internal | 434 } // namespace internal |
423 } // namespace v8 | 435 } // namespace v8 |
OLD | NEW |