OLD | NEW |
---|---|
(Empty) | |
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/interpreter/bytecode-array-builder.h" | |
6 | |
7 namespace v8 { | |
8 namespace internal { | |
9 namespace interpreter { | |
10 | |
11 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate) | |
12 : isolate_(isolate), | |
13 bytecode_generated_(false), | |
14 local_register_count_(-1), | |
15 temporary_register_next_(-1) {} | |
16 | |
17 | |
18 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { | |
19 local_register_count_ = number_of_locals; | |
20 temporary_register_next_ = local_register_count_; | |
21 } | |
22 | |
23 | |
24 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { | |
25 DCHECK(!bytecode_generated_); | |
26 DCHECK(local_register_count_ >= 0); | |
27 int bytecode_size = static_cast<int>(bytecodes_.size()); | |
28 int register_count = local_register_count_ + temporary_register_count_; | |
29 int frame_size = register_count * sizeof(intptr_t); | |
rmcilroy
2015/07/31 09:56:19
replace sizeof(intptr_t) with kPointerSize (otherw
oth
2015/07/31 11:20:59
Done.
| |
30 Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray( | |
31 bytecode_size, &bytecodes_.front(), frame_size); | |
32 bytecode_generated_ = true; | |
33 return output; | |
34 } | |
35 | |
36 | |
37 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value binop, | |
38 int reg) { | |
39 Output(BytecodeForBinaryOperation(binop), reg); | |
40 return *this; | |
41 } | |
42 | |
43 | |
44 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( | |
45 v8::internal::Smi* smi) { | |
46 int32_t raw_smi = smi->value(); | |
47 if (raw_smi == 0) { | |
48 Output(Bytecode::kLdaZero); | |
49 } else if (raw_smi > -128 && raw_smi <= 128) { | |
50 Output(Bytecode::kLdaSmi8, static_cast<uint8_t>(raw_smi)); | |
51 } else { | |
52 // TODO(oth): Put Smi in constant pool. | |
53 UNIMPLEMENTED(); | |
54 } | |
55 return *this; | |
56 } | |
57 | |
58 | |
59 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { | |
60 Output(Bytecode::kLdaUndefined); | |
61 return *this; | |
62 } | |
63 | |
64 | |
65 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() { | |
66 Output(Bytecode::kLdaNull); | |
67 return *this; | |
68 } | |
69 | |
70 | |
71 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTheHole() { | |
72 Output(Bytecode::kLdaTheHole); | |
73 return *this; | |
74 } | |
75 | |
76 | |
77 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTrue() { | |
78 Output(Bytecode::kLdaTrue); | |
79 return *this; | |
80 } | |
81 | |
82 | |
83 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { | |
84 Output(Bytecode::kLdaFalse); | |
85 return *this; | |
86 } | |
87 | |
88 | |
89 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( | |
90 int reg) { | |
91 Output(Bytecode::kLdar, reg); | |
92 return *this; | |
93 } | |
94 | |
95 | |
96 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( | |
97 int reg) { | |
98 Output(Bytecode::kStar, reg); | |
99 return *this; | |
100 } | |
101 | |
102 | |
103 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { | |
104 Output(Bytecode::kReturn); | |
105 return *this; | |
106 } | |
107 | |
108 | |
109 int BytecodeArrayBuilder::AllocateTemporaryRegister() { | |
110 DCHECK(local_register_count_ >= 0); | |
111 int temporary_register = temporary_register_next_++; | |
112 int count = temporary_register_next_ - local_register_count_; | |
113 if (count > temporary_register_count_) { | |
114 temporary_register_count_ = count; | |
115 } | |
116 return temporary_register; | |
117 } | |
118 | |
119 | |
120 void BytecodeArrayBuilder::FreeTemporaryRegister(int reg) { | |
121 DCHECK(reg == temporary_register_next_ - 1); | |
122 temporary_register_next_ = reg; | |
123 } | |
124 | |
125 | |
126 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | |
127 uint8_t operand1, uint8_t operand2) { | |
128 CHECK(Bytecodes::NumberOfOperands(bytecode) == 3); | |
129 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
130 bytecodes_.push_back(operand0); | |
131 bytecodes_.push_back(operand1); | |
132 bytecodes_.push_back(operand2); | |
133 } | |
134 | |
135 | |
136 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | |
137 uint8_t operand1) { | |
138 CHECK(Bytecodes::NumberOfOperands(bytecode) == 2); | |
139 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
140 bytecodes_.push_back(operand0); | |
141 bytecodes_.push_back(operand1); | |
142 } | |
143 | |
144 | |
145 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0) { | |
146 CHECK(Bytecodes::NumberOfOperands(bytecode) == 1); | |
147 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
148 bytecodes_.push_back(operand0); | |
149 } | |
150 | |
151 | |
152 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | |
153 CHECK(Bytecodes::NumberOfOperands(bytecode) == 0); | |
154 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
155 } | |
156 | |
157 | |
158 // static | |
159 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { | |
160 switch (op) { | |
161 case Token::Value::ADD: | |
162 return Bytecode::kAdd; | |
163 case Token::Value::SUB: | |
164 return Bytecode::kSub; | |
165 case Token::Value::MUL: | |
166 return Bytecode::kMul; | |
167 case Token::Value::DIV: | |
168 return Bytecode::kDiv; | |
169 default: | |
170 UNIMPLEMENTED(); | |
171 return static_cast<Bytecode>(-1); | |
172 } | |
173 } | |
174 | |
175 } // namespace interpreter | |
176 } // namespace internal | |
177 } // namespace v8 | |
OLD | NEW |