| 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 |