| Index: test/cctest/interpreter/test-interpreter.cc
|
| diff --git a/test/cctest/interpreter/test-interpreter.cc b/test/cctest/interpreter/test-interpreter.cc
|
| index 511e891d4939f0cda370d05496158367ca01dfb8..b4b7280748291047a73fa45641de96104cfd83e3 100644
|
| --- a/test/cctest/interpreter/test-interpreter.cc
|
| +++ b/test/cctest/interpreter/test-interpreter.cc
|
| @@ -7,6 +7,7 @@
|
| #include "src/execution.h"
|
| #include "src/handles.h"
|
| #include "src/interpreter/bytecode-array-builder.h"
|
| +#include "src/interpreter/bytecode-array-iterator.h"
|
| #include "src/interpreter/interpreter.h"
|
| #include "test/cctest/cctest.h"
|
| #include "test/cctest/interpreter/interpreter-tester.h"
|
| @@ -992,7 +993,6 @@ TEST(InterpreterConditionalJumps) {
|
| CHECK_EQ(Smi::cast(*return_value)->value(), 7);
|
| }
|
|
|
| -
|
| TEST(InterpreterConditionalJumps2) {
|
| // TODO(oth): Add tests for all conditional jumps near and far.
|
| HandleAndZoneScope handles;
|
| @@ -1026,6 +1026,92 @@ TEST(InterpreterConditionalJumps2) {
|
| CHECK_EQ(Smi::cast(*return_value)->value(), 7);
|
| }
|
|
|
| +TEST(InterpreterJumpConstantWith16BitOperand) {
|
| + HandleAndZoneScope handles;
|
| + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1,
|
| + 0, 257);
|
| + Register reg(0), scratch(256);
|
| + BytecodeLabel done;
|
| +
|
| + builder.LoadLiteral(Smi::FromInt(0));
|
| + builder.StoreAccumulatorInRegister(reg);
|
| + // Consume all 8-bit operands
|
| + for (int i = 1; i <= 256; i++) {
|
| + builder.LoadLiteral(handles.main_isolate()->factory()->NewNumber(i));
|
| + builder.BinaryOperation(Token::Value::ADD, reg);
|
| + builder.StoreAccumulatorInRegister(reg);
|
| + }
|
| + builder.Jump(&done);
|
| +
|
| + // Emit more than 16-bit immediate operands worth of code to jump over.
|
| + for (int i = 0; i < 6600; i++) {
|
| + builder.LoadLiteral(Smi::FromInt(0)); // 1-byte
|
| + builder.BinaryOperation(Token::Value::ADD, scratch); // 4-bytes
|
| + builder.StoreAccumulatorInRegister(scratch); // 4-bytes
|
| + builder.MoveRegister(scratch, reg); // 6-bytes
|
| + }
|
| + builder.Bind(&done);
|
| + builder.LoadAccumulatorWithRegister(reg);
|
| + builder.Return();
|
| +
|
| + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
|
| + BytecodeArrayIterator iterator(bytecode_array);
|
| +
|
| + bool found_16bit_constant_jump = false;
|
| + while (!iterator.done()) {
|
| + if (iterator.current_bytecode() == Bytecode::kJumpConstant &&
|
| + iterator.current_operand_scale() == OperandScale::kDouble) {
|
| + found_16bit_constant_jump = true;
|
| + break;
|
| + }
|
| + iterator.Advance();
|
| + }
|
| + CHECK(found_16bit_constant_jump);
|
| +
|
| + InterpreterTester tester(handles.main_isolate(), bytecode_array);
|
| + auto callable = tester.GetCallable<>();
|
| + Handle<Object> return_value = callable().ToHandleChecked();
|
| + CHECK_EQ(Smi::cast(*return_value)->value(), 256.0 / 2 * (1 + 256));
|
| +}
|
| +
|
| +TEST(InterpreterJumpWith32BitOperand) {
|
| + HandleAndZoneScope handles;
|
| + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1,
|
| + 0, 1);
|
| + Register reg(0);
|
| + BytecodeLabel done;
|
| +
|
| + builder.LoadLiteral(Smi::FromInt(0));
|
| + builder.StoreAccumulatorInRegister(reg);
|
| + // Consume all 16-bit constant pool entries
|
| + for (int i = 1; i <= 65536; i++) {
|
| + builder.LoadLiteral(handles.main_isolate()->factory()->NewNumber(i));
|
| + }
|
| + builder.Jump(&done);
|
| + builder.LoadLiteral(Smi::FromInt(0));
|
| + builder.Bind(&done);
|
| + builder.Return();
|
| +
|
| + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
|
| + BytecodeArrayIterator iterator(bytecode_array);
|
| +
|
| + bool found_32bit_jump = false;
|
| + while (!iterator.done()) {
|
| + if (iterator.current_bytecode() == Bytecode::kJump &&
|
| + iterator.current_operand_scale() == OperandScale::kQuadruple) {
|
| + found_32bit_jump = true;
|
| + break;
|
| + }
|
| + iterator.Advance();
|
| + }
|
| + CHECK(found_32bit_jump);
|
| +
|
| + InterpreterTester tester(handles.main_isolate(), bytecode_array);
|
| + auto callable = tester.GetCallable<>();
|
| + Handle<Object> return_value = callable().ToHandleChecked();
|
| + CHECK_EQ(Smi::cast(*return_value)->value(), 65536.0);
|
| +}
|
| +
|
| static const Token::Value kComparisonTypes[] = {
|
| Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT,
|
| Token::Value::LT, Token::Value::LTE, Token::Value::GT,
|
|
|