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 3 // found in the LICENSE file. 4 5 #include "src/v8.h" 6 7 #include "src/interpreter/bytecode-array-builder.h" 8 #include "src/interpreter/bytecode-array-iterator.h" 9 #include "test/unittests/test-utils.h" 10 11 namespace v8 { 12 namespace internal { 13 namespace interpreter { 14 15 class BytecodeArrayIteratorTest : public TestWithIsolateAndZone { 16 public: 17 BytecodeArrayIteratorTest() {} 18 ~BytecodeArrayIteratorTest() override {} 19 }; 20 21 22 TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) { 23 // Use a builder to create an array with containing multiple bytecodes 24 // with 0, 1 and 2 operands. 25 BytecodeArrayBuilder builder(isolate(), zone()); 26 builder.set_parameter_count(3); 27 builder.set_locals_count(2); 28 builder.set_context_count(0); 29 30 Factory* factory = isolate()->factory(); 31 Handle<HeapObject> heap_num_0 = factory->NewHeapNumber(2.718); 32 Handle<HeapObject> heap_num_1 = factory->NewHeapNumber(2147483647); 33 Smi* zero = Smi::FromInt(0); 34 Smi* smi_0 = Smi::FromInt(64); 35 Smi* smi_1 = Smi::FromInt(-65536); 36 Register reg_0(0); 37 Register reg_1(1); 38 Register reg_2 = Register::FromParameterIndex(2, builder.parameter_count()); 39 Handle<String> name = factory->NewStringFromStaticChars("abc"); 40 int name_index = 3; 41 int feedback_slot = 97; 42 43 builder.LoadLiteral(heap_num_0) 44 .LoadLiteral(heap_num_1) 45 .LoadLiteral(zero) 46 .LoadLiteral(smi_0) 47 .LoadLiteral(smi_1) 48 .LoadAccumulatorWithRegister(reg_0) 49 .LoadNamedProperty(reg_1, name, feedback_slot, LanguageMode::SLOPPY) 50 .StoreAccumulatorInRegister(reg_2) 51 .CallRuntime(Runtime::kLoadIC_Miss, reg_0, 1) 52 .Return(); 53 54 // Test iterator sees the expected output from the builder. 55 BytecodeArrayIterator iterator(builder.ToBytecodeArray()); 56 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant); 57 CHECK(iterator.GetConstantForIndexOperand(0).is_identical_to(heap_num_0)); 58 CHECK(!iterator.done()); 59 iterator.Advance(); 60 61 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant); 62 CHECK(iterator.GetConstantForIndexOperand(0).is_identical_to(heap_num_1)); 63 CHECK(!iterator.done()); 64 iterator.Advance(); 65 66 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaZero); 67 CHECK(!iterator.done()); 68 iterator.Advance(); 69 70 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi8); 71 CHECK_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_0); 72 CHECK(!iterator.done()); 73 iterator.Advance(); 74 75 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant); 76 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), smi_1); 77 CHECK(!iterator.done()); 78 iterator.Advance(); 79 80 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdar); 81 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index()); 82 CHECK(!iterator.done()); 83 iterator.Advance(); 84 85 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLoadICSloppy); 86 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index()); 87 CHECK_EQ(iterator.GetIndexOperand(1), name_index); 88 CHECK_EQ(iterator.GetIndexOperand(2), feedback_slot); 89 CHECK(!iterator.done()); 90 iterator.Advance(); 91 92 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar); 93 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_2.index()); 94 CHECK(!iterator.done()); 95 iterator.Advance(); 96 97 CHECK_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime); 98 CHECK_EQ(static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0)), 99 Runtime::kLoadIC_Miss); 100 CHECK_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index()); 101 CHECK_EQ(iterator.GetCountOperand(2), 1); 102 CHECK(!iterator.done()); 103 iterator.Advance(); 104 105 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 106 CHECK(!iterator.done()); 107 iterator.Advance(); 108 CHECK(iterator.done()); 109 } 110 111 } // namespace interpreter 112 } // namespace internal 113 } // namespace v8 114