Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Unified Diff: test/unittests/interpreter/bytecode-array-builder-unittest.cc

Issue 1343363002: [Interpreter] Basic flow control. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Switch test-bytecode-generator/IfConditions to use new style bytecode array check. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « test/unittests/compiler/interpreter-assembler-unittest.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/unittests/interpreter/bytecode-array-builder-unittest.cc
diff --git a/test/unittests/interpreter/bytecode-array-builder-unittest.cc b/test/unittests/interpreter/bytecode-array-builder-unittest.cc
index 35a766320841ee44421d1b2df41bac4c3c5ce656..779361ffcff34c4b9bccdf6258becc055cff534f 100644
--- a/test/unittests/interpreter/bytecode-array-builder-unittest.cc
+++ b/test/unittests/interpreter/bytecode-array-builder-unittest.cc
@@ -5,6 +5,7 @@
#include "src/v8.h"
#include "src/interpreter/bytecode-array-builder.h"
+#include "src/interpreter/bytecode-array-iterator.h"
#include "test/unittests/test-utils.h"
namespace v8 {
@@ -51,14 +52,39 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
// Call operations.
builder.Call(reg, reg, 0);
- // Emit binary operators invocations.
+ // Emit binary operator invocations.
builder.BinaryOperation(Token::Value::ADD, reg)
.BinaryOperation(Token::Value::SUB, reg)
.BinaryOperation(Token::Value::MUL, reg)
.BinaryOperation(Token::Value::DIV, reg)
.BinaryOperation(Token::Value::MOD, reg);
+ // Emit test operator invocations.
+ builder.CompareOperation(Token::Value::EQ, reg, LanguageMode::SLOPPY)
+ .CompareOperation(Token::Value::NE, reg, LanguageMode::SLOPPY)
+ .CompareOperation(Token::Value::EQ_STRICT, reg, LanguageMode::SLOPPY)
+ .CompareOperation(Token::Value::NE_STRICT, reg, LanguageMode::SLOPPY)
+ .CompareOperation(Token::Value::LT, reg, LanguageMode::SLOPPY)
+ .CompareOperation(Token::Value::GT, reg, LanguageMode::SLOPPY)
+ .CompareOperation(Token::Value::LTE, reg, LanguageMode::SLOPPY)
+ .CompareOperation(Token::Value::GTE, reg, LanguageMode::SLOPPY)
+ .CompareOperation(Token::Value::INSTANCEOF, reg, LanguageMode::SLOPPY)
+ .CompareOperation(Token::Value::IN, reg, LanguageMode::SLOPPY);
+
+ // Emit cast operator invocations.
+ builder.LoadNull().CastAccumulatorToBoolean();
+
// Emit control flow. Return must be the last instruction.
+ BytecodeLabel start;
+ builder.Bind(&start);
+ // Short jumps with Imm8 operands
+ builder.Jump(&start).JumpIfTrue(&start).JumpIfFalse(&start);
+ // Insert dummy ops to force longer jumps
+ for (int i = 0; i < 128; i++) {
+ builder.LoadTrue();
+ }
+ // Longer jumps requiring Constant operand
+ builder.Jump(&start).JumpIfTrue(&start).JumpIfFalse(&start);
builder.Return();
// Generate BytecodeArray.
@@ -183,6 +209,189 @@ TEST_F(BytecodeArrayBuilderTest, Constants) {
CHECK_EQ(array->constant_pool()->length(), 3);
}
+
+TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
+ static const int kFarJumpDistance = 256;
+
+ BytecodeArrayBuilder builder(isolate(), zone());
+ builder.set_parameter_count(0);
+ builder.set_locals_count(0);
+
+ BytecodeLabel far0, far1, far2;
+ BytecodeLabel near0, near1, near2;
+
+ builder.Jump(&near0)
+ .JumpIfTrue(&near1)
+ .JumpIfFalse(&near2)
+ .Bind(&near0)
+ .Bind(&near1)
+ .Bind(&near2)
+ .Jump(&far0)
+ .JumpIfTrue(&far1)
+ .JumpIfFalse(&far2);
+ for (int i = 0; i < kFarJumpDistance - 6; i++) {
+ builder.LoadUndefined();
+ }
+ builder.Bind(&far0).Bind(&far1).Bind(&far2);
+ builder.Return();
+
+ Handle<BytecodeArray> array = builder.ToBytecodeArray();
+ DCHECK_EQ(array->length(), 12 + kFarJumpDistance - 6 + 1);
+
+ BytecodeArrayIterator iterator(array);
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
+ CHECK_EQ(iterator.GetSmi8Operand(0), 6);
+ iterator.Advance();
+
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
+ CHECK_EQ(iterator.GetSmi8Operand(0), 4);
+ iterator.Advance();
+
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
+ CHECK_EQ(iterator.GetSmi8Operand(0), 2);
+ iterator.Advance();
+
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
+ CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
+ Smi::FromInt(kFarJumpDistance));
+ CHECK_EQ(
+ array->get(iterator.current_offset() +
+ Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
+ Bytecodes::ToByte(Bytecode::kReturn));
+ iterator.Advance();
+
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
+ CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
+ Smi::FromInt(kFarJumpDistance - 2));
+ CHECK_EQ(
+ array->get(iterator.current_offset() +
+ Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
+ Bytecodes::ToByte(Bytecode::kReturn));
+ iterator.Advance();
+
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
+ CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
+ Smi::FromInt(kFarJumpDistance - 4));
+ CHECK_EQ(
+ array->get(iterator.current_offset() +
+ Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
+ Bytecodes::ToByte(Bytecode::kReturn));
+ iterator.Advance();
+}
+
+
+TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
+ BytecodeArrayBuilder builder(isolate(), zone());
+ builder.set_parameter_count(0);
+ builder.set_locals_count(0);
+
+ BytecodeLabel label0, label1, label2;
+ builder.Bind(&label0)
+ .Jump(&label0)
+ .Bind(&label1)
+ .JumpIfTrue(&label1)
+ .Bind(&label2)
+ .JumpIfFalse(&label2);
+ for (int i = 0; i < 64; i++) {
+ builder.Jump(&label2);
+ }
+ builder.JumpIfFalse(&label2);
+ builder.JumpIfTrue(&label1);
+ builder.Jump(&label0);
+ builder.Return();
+
+ Handle<BytecodeArray> array = builder.ToBytecodeArray();
+ BytecodeArrayIterator iterator(array);
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
+ CHECK_EQ(iterator.GetSmi8Operand(0), 0);
+ iterator.Advance();
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
+ CHECK_EQ(iterator.GetSmi8Operand(0), 0);
+ iterator.Advance();
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
+ CHECK_EQ(iterator.GetSmi8Operand(0), 0);
+ iterator.Advance();
+ for (int i = 0; i < 64; i++) {
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
+ CHECK_EQ(iterator.GetSmi8Operand(0), -i * 2 - 2);
+ iterator.Advance();
+ }
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
+ CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -130);
+ iterator.Advance();
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
+ CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -134);
+ iterator.Advance();
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
+ CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -138);
+ iterator.Advance();
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
+ iterator.Advance();
+ CHECK(iterator.done());
+}
+
+
+TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
+ BytecodeArrayBuilder builder(isolate(), zone());
+ builder.set_parameter_count(0);
+ builder.set_locals_count(0);
+
+ // Labels can only have 1 forward reference, but
+ // can be referred to mulitple times once bound.
+ BytecodeLabel label;
+
+ builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label).Return();
+
+ Handle<BytecodeArray> array = builder.ToBytecodeArray();
+ BytecodeArrayIterator iterator(array);
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
+ CHECK_EQ(iterator.GetSmi8Operand(0), 2);
+ iterator.Advance();
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
+ CHECK_EQ(iterator.GetSmi8Operand(0), 0);
+ iterator.Advance();
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
+ CHECK_EQ(iterator.GetSmi8Operand(0), -2);
+ iterator.Advance();
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
+ iterator.Advance();
+ CHECK(iterator.done());
+}
+
+
+TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) {
+ static const int kRepeats = 3;
+
+ BytecodeArrayBuilder builder(isolate(), zone());
+ builder.set_parameter_count(0);
+ builder.set_locals_count(0);
+
+ for (int i = 0; i < kRepeats; i++) {
+ BytecodeLabel label;
+ builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label);
+ }
+
+ builder.Return();
+
+ Handle<BytecodeArray> array = builder.ToBytecodeArray();
+ BytecodeArrayIterator iterator(array);
+ for (int i = 0; i < kRepeats; i++) {
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
+ CHECK_EQ(iterator.GetSmi8Operand(0), 2);
+ iterator.Advance();
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
+ CHECK_EQ(iterator.GetSmi8Operand(0), 0);
+ iterator.Advance();
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
+ CHECK_EQ(iterator.GetSmi8Operand(0), -2);
+ iterator.Advance();
+ }
+ CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
+ iterator.Advance();
+ CHECK(iterator.done());
+}
+
+
} // namespace interpreter
} // namespace internal
} // namespace v8
« no previous file with comments | « test/unittests/compiler/interpreter-assembler-unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698