| 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 "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/execution.h" | 7 #include "src/execution.h" |
| 8 #include "src/handles.h" | 8 #include "src/handles.h" |
| 9 #include "src/interpreter/bytecode-array-builder.h" | 9 #include "src/interpreter/bytecode-array-builder.h" |
| 10 #include "src/interpreter/interpreter.h" | 10 #include "src/interpreter/interpreter.h" |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 344 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 345 | 345 |
| 346 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 346 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 347 auto callable = tester.GetCallable<>(); | 347 auto callable = tester.GetCallable<>(); |
| 348 Handle<Object> return_val = callable().ToHandleChecked(); | 348 Handle<Object> return_val = callable().ToHandleChecked(); |
| 349 CHECK(return_val.is_identical_to(true_value)); | 349 CHECK(return_val.is_identical_to(true_value)); |
| 350 } | 350 } |
| 351 } | 351 } |
| 352 | 352 |
| 353 | 353 |
| 354 static const Token::Value kArithmeticOperators[] = { | |
| 355 Token::Value::SHL, Token::Value::SAR, Token::Value::SHR, Token::Value::ADD, | |
| 356 Token::Value::SUB, Token::Value::MUL, Token::Value::DIV, Token::Value::MOD}; | |
| 357 | |
| 358 | |
| 359 static const Token::Value kShiftOperators[] = { | 354 static const Token::Value kShiftOperators[] = { |
| 360 Token::Value::SHL, Token::Value::SAR, Token::Value::SHR}; | 355 Token::Value::SHL, Token::Value::SAR, Token::Value::SHR}; |
| 361 | 356 |
| 362 | 357 |
| 358 static const Token::Value kArithmeticOperators[] = { |
| 359 Token::Value::BIT_OR, Token::Value::BIT_XOR, Token::Value::BIT_AND, |
| 360 Token::Value::SHL, Token::Value::SAR, Token::Value::SHR, |
| 361 Token::Value::ADD, Token::Value::SUB, Token::Value::MUL, |
| 362 Token::Value::DIV, Token::Value::MOD}; |
| 363 |
| 364 |
| 363 static double BinaryOpC(Token::Value op, double lhs, double rhs) { | 365 static double BinaryOpC(Token::Value op, double lhs, double rhs) { |
| 364 switch (op) { | 366 switch (op) { |
| 365 case Token::Value::ADD: | 367 case Token::Value::ADD: |
| 366 return lhs + rhs; | 368 return lhs + rhs; |
| 367 case Token::Value::SUB: | 369 case Token::Value::SUB: |
| 368 return lhs - rhs; | 370 return lhs - rhs; |
| 369 case Token::Value::MUL: | 371 case Token::Value::MUL: |
| 370 return lhs * rhs; | 372 return lhs * rhs; |
| 371 case Token::Value::DIV: | 373 case Token::Value::DIV: |
| 372 return lhs / rhs; | 374 return lhs / rhs; |
| 373 case Token::Value::MOD: | 375 case Token::Value::MOD: |
| 374 return std::fmod(lhs, rhs); | 376 return std::fmod(lhs, rhs); |
| 377 case Token::Value::BIT_OR: |
| 378 return (v8::internal::DoubleToInt32(lhs) | |
| 379 v8::internal::DoubleToInt32(rhs)); |
| 380 case Token::Value::BIT_XOR: |
| 381 return (v8::internal::DoubleToInt32(lhs) ^ |
| 382 v8::internal::DoubleToInt32(rhs)); |
| 383 case Token::Value::BIT_AND: |
| 384 return (v8::internal::DoubleToInt32(lhs) & |
| 385 v8::internal::DoubleToInt32(rhs)); |
| 375 case Token::Value::SHL: { | 386 case Token::Value::SHL: { |
| 376 int32_t val = v8::internal::DoubleToInt32(lhs); | 387 int32_t val = v8::internal::DoubleToInt32(lhs); |
| 377 uint32_t count = v8::internal::DoubleToUint32(rhs) & 0x1F; | 388 uint32_t count = v8::internal::DoubleToUint32(rhs) & 0x1F; |
| 378 int32_t result = val << count; | 389 int32_t result = val << count; |
| 379 return result; | 390 return result; |
| 380 } | 391 } |
| 381 case Token::Value::SAR: { | 392 case Token::Value::SAR: { |
| 382 int32_t val = v8::internal::DoubleToInt32(lhs); | 393 int32_t val = v8::internal::DoubleToInt32(lhs); |
| 383 uint32_t count = v8::internal::DoubleToUint32(rhs) & 0x1F; | 394 uint32_t count = v8::internal::DoubleToUint32(rhs) & 0x1F; |
| 384 int32_t result = val >> count; | 395 int32_t result = val >> count; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 408 BytecodeArrayBuilder builder(handles.main_isolate(), | 419 BytecodeArrayBuilder builder(handles.main_isolate(), |
| 409 handles.main_zone()); | 420 handles.main_zone()); |
| 410 builder.set_locals_count(1); | 421 builder.set_locals_count(1); |
| 411 builder.set_parameter_count(1); | 422 builder.set_parameter_count(1); |
| 412 Register reg(0); | 423 Register reg(0); |
| 413 int lhs = lhs_inputs[l]; | 424 int lhs = lhs_inputs[l]; |
| 414 int rhs = rhs_inputs[r]; | 425 int rhs = rhs_inputs[r]; |
| 415 builder.LoadLiteral(Smi::FromInt(lhs)) | 426 builder.LoadLiteral(Smi::FromInt(lhs)) |
| 416 .StoreAccumulatorInRegister(reg) | 427 .StoreAccumulatorInRegister(reg) |
| 417 .LoadLiteral(Smi::FromInt(rhs)) | 428 .LoadLiteral(Smi::FromInt(rhs)) |
| 418 .BinaryOperation(kArithmeticOperators[o], reg, Strength::WEAK) | 429 .BinaryOperation(kShiftOperators[o], reg, Strength::WEAK) |
| 419 .Return(); | 430 .Return(); |
| 420 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 431 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 421 | 432 |
| 422 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 433 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 423 auto callable = tester.GetCallable<>(); | 434 auto callable = tester.GetCallable<>(); |
| 424 Handle<Object> return_value = callable().ToHandleChecked(); | 435 Handle<Object> return_value = callable().ToHandleChecked(); |
| 425 Handle<Object> expected_value = | 436 Handle<Object> expected_value = |
| 426 factory->NewNumber(BinaryOpC(kShiftOperators[o], lhs, rhs)); | 437 factory->NewNumber(BinaryOpC(kShiftOperators[o], lhs, rhs)); |
| 427 CHECK(return_value->SameValue(*expected_value)); | 438 CHECK(return_value->SameValue(*expected_value)); |
| 428 } | 439 } |
| 429 } | 440 } |
| 430 } | 441 } |
| 431 } | 442 } |
| 432 | 443 |
| 433 | 444 |
| 434 TEST(InterpreterBinaryOpsSmi) { | 445 TEST(InterpreterBinaryOpsSmi) { |
| 435 int lhs_inputs[] = {3266, 1024, 0, -17, -18000}; | 446 int lhs_inputs[] = {3266, 1024, 0, -17, -18000}; |
| 436 int rhs_inputs[] = {3266, 5, 4, 3, 2, 1, -1, -2}; | 447 int rhs_inputs[] = {3266, 5, 4, 3, 2, 1, -1, -2}; |
| 437 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { | 448 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { |
| 438 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { | 449 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { |
| 439 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { | 450 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { |
| 440 HandleAndZoneScope handles; | 451 HandleAndZoneScope handles; |
| 441 i::Factory* factory = handles.main_isolate()->factory(); | 452 i::Factory* factory = handles.main_isolate()->factory(); |
| 442 BytecodeArrayBuilder builder(handles.main_isolate(), | 453 BytecodeArrayBuilder builder(handles.main_isolate(), |
| 443 handles.main_zone()); | 454 handles.main_zone()); |
| 444 builder.set_locals_count(1); | 455 builder.set_locals_count(1); |
| 445 builder.set_parameter_count(1); | 456 builder.set_parameter_count(1); |
| 446 Register reg(0); | 457 Register reg(0); |
| 447 int lhs = lhs_inputs[l]; | 458 int lhs = lhs_inputs[l]; |
| 448 int rhs = rhs_inputs[l]; | 459 int rhs = rhs_inputs[r]; |
| 449 builder.LoadLiteral(Smi::FromInt(lhs)) | 460 builder.LoadLiteral(Smi::FromInt(lhs)) |
| 450 .StoreAccumulatorInRegister(reg) | 461 .StoreAccumulatorInRegister(reg) |
| 451 .LoadLiteral(Smi::FromInt(rhs)) | 462 .LoadLiteral(Smi::FromInt(rhs)) |
| 452 .BinaryOperation(kArithmeticOperators[o], reg, Strength::WEAK) | 463 .BinaryOperation(kArithmeticOperators[o], reg, Strength::WEAK) |
| 453 .Return(); | 464 .Return(); |
| 454 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 465 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 455 | 466 |
| 456 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 467 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 457 auto callable = tester.GetCallable<>(); | 468 auto callable = tester.GetCallable<>(); |
| 458 Handle<Object> return_value = callable().ToHandleChecked(); | 469 Handle<Object> return_value = callable().ToHandleChecked(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 473 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { | 484 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { |
| 474 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { | 485 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { |
| 475 HandleAndZoneScope handles; | 486 HandleAndZoneScope handles; |
| 476 i::Factory* factory = handles.main_isolate()->factory(); | 487 i::Factory* factory = handles.main_isolate()->factory(); |
| 477 BytecodeArrayBuilder builder(handles.main_isolate(), | 488 BytecodeArrayBuilder builder(handles.main_isolate(), |
| 478 handles.main_zone()); | 489 handles.main_zone()); |
| 479 builder.set_locals_count(1); | 490 builder.set_locals_count(1); |
| 480 builder.set_parameter_count(1); | 491 builder.set_parameter_count(1); |
| 481 Register reg(0); | 492 Register reg(0); |
| 482 double lhs = lhs_inputs[l]; | 493 double lhs = lhs_inputs[l]; |
| 483 double rhs = rhs_inputs[l]; | 494 double rhs = rhs_inputs[r]; |
| 484 builder.LoadLiteral(factory->NewNumber(lhs)) | 495 builder.LoadLiteral(factory->NewNumber(lhs)) |
| 485 .StoreAccumulatorInRegister(reg) | 496 .StoreAccumulatorInRegister(reg) |
| 486 .LoadLiteral(factory->NewNumber(rhs)) | 497 .LoadLiteral(factory->NewNumber(rhs)) |
| 487 .BinaryOperation(kArithmeticOperators[o], reg, Strength::WEAK) | 498 .BinaryOperation(kArithmeticOperators[o], reg, Strength::WEAK) |
| 488 .Return(); | 499 .Return(); |
| 489 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 500 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 490 | 501 |
| 491 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 502 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 492 auto callable = tester.GetCallable<>(); | 503 auto callable = tester.GetCallable<>(); |
| 493 Handle<Object> return_value = callable().ToHandleChecked(); | 504 Handle<Object> return_value = callable().ToHandleChecked(); |
| (...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1602 .CallRuntime(Runtime::kAdd, Register(0), 2) | 1613 .CallRuntime(Runtime::kAdd, Register(0), 2) |
| 1603 .Return(); | 1614 .Return(); |
| 1604 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 1615 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 1605 | 1616 |
| 1606 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 1617 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 1607 auto callable = tester.GetCallable<>(); | 1618 auto callable = tester.GetCallable<>(); |
| 1608 | 1619 |
| 1609 Handle<Object> return_val = callable().ToHandleChecked(); | 1620 Handle<Object> return_val = callable().ToHandleChecked(); |
| 1610 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(55)); | 1621 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(55)); |
| 1611 } | 1622 } |
| OLD | NEW |