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/interpreter/bytecode-array-builder.h" | 5 #include "src/interpreter/bytecode-array-builder.h" |
6 | 6 |
7 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 namespace interpreter { | 9 namespace interpreter { |
10 | 10 |
11 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) | 11 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) |
12 : isolate_(isolate), | 12 : isolate_(isolate), |
13 bytecodes_(zone), | 13 bytecodes_(zone), |
14 bytecode_generated_(false), | 14 bytecode_generated_(false), |
15 constants_map_(isolate->heap(), zone), | 15 constants_map_(isolate->heap(), zone), |
16 constants_(zone), | 16 constants_(zone), |
17 forward_labels_(zone), | |
18 bound_labels_(zone), | |
17 parameter_count_(-1), | 19 parameter_count_(-1), |
18 local_register_count_(-1), | 20 local_register_count_(-1), |
19 temporary_register_count_(0), | 21 temporary_register_count_(0), |
20 temporary_register_next_(0) {} | 22 temporary_register_next_(0) {} |
21 | 23 |
22 | 24 |
23 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { | 25 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { |
24 local_register_count_ = number_of_locals; | 26 local_register_count_ = number_of_locals; |
25 temporary_register_next_ = local_register_count_; | 27 temporary_register_next_ = local_register_count_; |
26 } | 28 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
69 } | 71 } |
70 | 72 |
71 Handle<BytecodeArray> output = | 73 Handle<BytecodeArray> output = |
72 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, | 74 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, |
73 parameter_count_, constant_pool); | 75 parameter_count_, constant_pool); |
74 bytecode_generated_ = true; | 76 bytecode_generated_ = true; |
75 return output; | 77 return output; |
76 } | 78 } |
77 | 79 |
78 | 80 |
79 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value binop, | 81 template <size_t N> |
82 void BytecodeArrayBuilder::RawOutputAt(ZoneVector<uint8_t>::iterator pos, | |
83 uint8_t(&bytes)[N]) { | |
84 DCHECK_EQ(Bytecodes::NumberOfOperands(Bytecodes::FromByte(bytes[0])), N - 1); | |
85 for (int i = 1; i < static_cast<int>(N); i++) { | |
86 DCHECK(OperandIsValid(Bytecodes::FromByte(bytes[0]), i - 1, bytes[i])); | |
87 } | |
88 | |
89 if (bytecodes()->end() == pos) { | |
rmcilroy
2015/09/18 10:42:23
I'm not keen on having the Output operators do pat
oth
2015/09/23 10:46:55
Done.
| |
90 bytecodes()->insert(pos, bytes, bytes + N); | |
91 } else { | |
92 std::copy(bytes, bytes + N, pos); | |
93 } | |
94 } | |
95 | |
96 | |
97 void BytecodeArrayBuilder::Output(const ZoneVector<uint8_t>::iterator& pos, | |
98 Bytecode bytecode, uint8_t operand0) { | |
99 uint8_t bytes[] = {Bytecodes::ToByte(bytecode), operand0}; | |
100 RawOutputAt(pos, bytes); | |
101 } | |
102 | |
103 | |
104 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | |
105 uint8_t operand1, uint8_t operand2) { | |
106 uint8_t bytes[] = {Bytecodes::ToByte(bytecode), operand0, operand1, operand2}; | |
107 RawOutputAt(bytecodes()->end(), bytes); | |
108 } | |
109 | |
110 | |
111 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | |
112 uint8_t operand1) { | |
113 uint8_t bytes[] = {Bytecodes::ToByte(bytecode), operand0, operand1}; | |
114 RawOutputAt(bytecodes()->end(), bytes); | |
115 } | |
116 | |
117 | |
118 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0) { | |
119 uint8_t bytes[] = {Bytecodes::ToByte(bytecode), operand0}; | |
120 RawOutputAt(bytecodes()->end(), bytes); | |
121 } | |
122 | |
123 | |
124 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | |
125 uint8_t bytes[] = {Bytecodes::ToByte(bytecode)}; | |
126 RawOutputAt(bytecodes()->end(), bytes); | |
127 } | |
128 | |
129 | |
130 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | |
80 Register reg) { | 131 Register reg) { |
81 Output(BytecodeForBinaryOperation(binop), reg.ToOperand()); | 132 Output(BytecodeForBinaryOperation(op), reg.ToOperand()); |
82 return *this; | 133 return *this; |
83 } | 134 } |
84 | 135 |
136 | |
137 BytecodeArrayBuilder& BytecodeArrayBuilder::Add(Register reg) { | |
138 return BinaryOperation(Token::Value::ADD, reg); | |
139 } | |
140 | |
141 | |
142 BytecodeArrayBuilder& BytecodeArrayBuilder::Subtract(Register reg) { | |
143 return BinaryOperation(Token::Value::SUB, reg); | |
144 } | |
145 | |
146 | |
147 BytecodeArrayBuilder& BytecodeArrayBuilder::Multiply(Register reg) { | |
148 return BinaryOperation(Token::Value::MUL, reg); | |
149 } | |
150 | |
151 | |
152 BytecodeArrayBuilder& BytecodeArrayBuilder::Divide(Register reg) { | |
153 return BinaryOperation(Token::Value::DIV, reg); | |
154 } | |
155 | |
156 | |
157 BytecodeArrayBuilder& BytecodeArrayBuilder::Modulo(Register reg) { | |
158 return BinaryOperation(Token::Value::MOD, reg); | |
159 } | |
160 | |
161 | |
162 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op, | |
163 Register reg) { | |
164 Output(BytecodeForCompareOperation(op), reg.ToOperand()); | |
165 return *this; | |
166 } | |
167 | |
85 | 168 |
86 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( | 169 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( |
87 v8::internal::Smi* smi) { | 170 v8::internal::Smi* smi) { |
88 int32_t raw_smi = smi->value(); | 171 int32_t raw_smi = smi->value(); |
89 if (raw_smi == 0) { | 172 if (raw_smi == 0) { |
90 Output(Bytecode::kLdaZero); | 173 Output(Bytecode::kLdaZero); |
91 } else if (raw_smi >= -128 && raw_smi <= 127) { | 174 } else if (raw_smi >= -128 && raw_smi <= 127) { |
92 Output(Bytecode::kLdaSmi8, static_cast<uint8_t>(raw_smi)); | 175 Output(Bytecode::kLdaSmi8, static_cast<uint8_t>(raw_smi)); |
93 } else { | 176 } else { |
94 LoadLiteral(Handle<Object>(smi, isolate_)); | 177 LoadLiteral(Handle<Object>(smi, isolate_)); |
95 } | 178 } |
96 return *this; | 179 return *this; |
97 } | 180 } |
98 | 181 |
99 | 182 |
100 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { | 183 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { |
101 size_t entry = GetConstantPoolEntry(object); | 184 size_t entry = GetConstantPoolEntry(object); |
102 if (FitsInByteOperand(entry)) { | 185 if (FitsInIdxOperand(entry)) { |
103 Output(Bytecode::kLdaConstant, static_cast<uint8_t>(entry)); | 186 Output(Bytecode::kLdaConstant, static_cast<uint8_t>(entry)); |
104 } else { | 187 } else { |
105 UNIMPLEMENTED(); | 188 UNIMPLEMENTED(); |
106 } | 189 } |
107 return *this; | 190 return *this; |
108 } | 191 } |
109 | 192 |
110 | 193 |
194 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(int value) { | |
195 Handle<Object> v = isolate()->factory()->NewNumberFromInt(value); | |
196 if (v->IsSmi()) { | |
197 return LoadLiteral(Smi::cast(*v)); | |
198 } else { | |
199 return LoadLiteral(v); | |
200 } | |
201 } | |
202 | |
203 | |
204 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(double value) { | |
205 return LoadLiteral(isolate()->factory()->NewNumber(value)); | |
206 } | |
207 | |
208 | |
111 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { | 209 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { |
112 Output(Bytecode::kLdaUndefined); | 210 Output(Bytecode::kLdaUndefined); |
113 return *this; | 211 return *this; |
114 } | 212 } |
115 | 213 |
116 | 214 |
117 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() { | 215 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() { |
118 Output(Bytecode::kLdaNull); | 216 Output(Bytecode::kLdaNull); |
119 return *this; | 217 return *this; |
120 } | 218 } |
(...skipping 30 matching lines...) Expand all Loading... | |
151 return *this; | 249 return *this; |
152 } | 250 } |
153 | 251 |
154 | 252 |
155 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( | 253 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( |
156 Register object, int feedback_slot, LanguageMode language_mode) { | 254 Register object, int feedback_slot, LanguageMode language_mode) { |
157 if (!is_sloppy(language_mode)) { | 255 if (!is_sloppy(language_mode)) { |
158 UNIMPLEMENTED(); | 256 UNIMPLEMENTED(); |
159 } | 257 } |
160 | 258 |
161 if (FitsInByteOperand(feedback_slot)) { | 259 if (FitsInIdxOperand(feedback_slot)) { |
162 Output(Bytecode::kLoadIC, object.ToOperand(), | 260 Output(Bytecode::kLoadIC, object.ToOperand(), |
163 static_cast<uint8_t>(feedback_slot)); | 261 static_cast<uint8_t>(feedback_slot)); |
164 } else { | 262 } else { |
165 UNIMPLEMENTED(); | 263 UNIMPLEMENTED(); |
166 } | 264 } |
167 return *this; | 265 return *this; |
168 } | 266 } |
169 | 267 |
170 | 268 |
171 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( | 269 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( |
172 Register object, int feedback_slot, LanguageMode language_mode) { | 270 Register object, int feedback_slot, LanguageMode language_mode) { |
173 if (!is_sloppy(language_mode)) { | 271 if (!is_sloppy(language_mode)) { |
174 UNIMPLEMENTED(); | 272 UNIMPLEMENTED(); |
175 } | 273 } |
176 | 274 |
177 if (FitsInByteOperand(feedback_slot)) { | 275 if (FitsInIdxOperand(feedback_slot)) { |
178 Output(Bytecode::kKeyedLoadIC, object.ToOperand(), | 276 Output(Bytecode::kKeyedLoadIC, object.ToOperand(), |
179 static_cast<uint8_t>(feedback_slot)); | 277 static_cast<uint8_t>(feedback_slot)); |
180 } else { | 278 } else { |
181 UNIMPLEMENTED(); | 279 UNIMPLEMENTED(); |
182 } | 280 } |
183 return *this; | 281 return *this; |
184 } | 282 } |
185 | 283 |
186 | 284 |
187 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( | 285 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( |
188 Register object, Register name, int feedback_slot, | 286 Register object, Register name, int feedback_slot, |
189 LanguageMode language_mode) { | 287 LanguageMode language_mode) { |
190 if (!is_sloppy(language_mode)) { | 288 if (!is_sloppy(language_mode)) { |
191 UNIMPLEMENTED(); | 289 UNIMPLEMENTED(); |
192 } | 290 } |
193 | 291 |
194 if (FitsInByteOperand(feedback_slot)) { | 292 if (FitsInIdxOperand(feedback_slot)) { |
195 Output(Bytecode::kStoreIC, object.ToOperand(), name.ToOperand(), | 293 Output(Bytecode::kStoreIC, object.ToOperand(), name.ToOperand(), |
196 static_cast<uint8_t>(feedback_slot)); | 294 static_cast<uint8_t>(feedback_slot)); |
197 } else { | 295 } else { |
198 UNIMPLEMENTED(); | 296 UNIMPLEMENTED(); |
199 } | 297 } |
200 return *this; | 298 return *this; |
201 } | 299 } |
202 | 300 |
203 | 301 |
204 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( | 302 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( |
205 Register object, Register key, int feedback_slot, | 303 Register object, Register key, int feedback_slot, |
206 LanguageMode language_mode) { | 304 LanguageMode language_mode) { |
207 if (!is_sloppy(language_mode)) { | 305 if (!is_sloppy(language_mode)) { |
208 UNIMPLEMENTED(); | 306 UNIMPLEMENTED(); |
209 } | 307 } |
210 | 308 |
211 if (FitsInByteOperand(feedback_slot)) { | 309 if (FitsInIdxOperand(feedback_slot)) { |
212 Output(Bytecode::kKeyedStoreIC, object.ToOperand(), key.ToOperand(), | 310 Output(Bytecode::kKeyedStoreIC, object.ToOperand(), key.ToOperand(), |
213 static_cast<uint8_t>(feedback_slot)); | 311 static_cast<uint8_t>(feedback_slot)); |
214 } else { | 312 } else { |
215 UNIMPLEMENTED(); | 313 UNIMPLEMENTED(); |
216 } | 314 } |
217 return *this; | 315 return *this; |
218 } | 316 } |
219 | 317 |
220 | 318 |
319 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { | |
320 auto forward_labels_iterator = forward_labels_.find(label); | |
321 if (forward_labels_.end() != forward_labels_iterator) { | |
322 // Label is forward referred to, update the referring jump instruction. | |
323 ZoneVector<uint8_t>::iterator it = bytecodes()->begin() + label->offset(); | |
324 OutputJump(Bytecodes::FromByte(*it), it, bytecodes()->end()); | |
325 forward_labels_.erase(forward_labels_iterator); | |
326 // Now treat as if the label will only be back referred to. | |
327 } | |
328 | |
329 DCHECK(bound_labels_.end() == bound_labels_.find(label)); | |
330 label->bind_to(bytecodes()->size()); | |
331 bound_labels_.insert(label); | |
332 return *this; | |
333 } | |
334 | |
335 | |
336 // static | |
337 bool BytecodeArrayBuilder::IsJumpWithSmi8Operand(Bytecode jump_bytecode) { | |
338 return jump_bytecode == Bytecode::kJumpSmi8 || | |
339 jump_bytecode == Bytecode::kJumpIfTrueSmi8 || | |
340 jump_bytecode == Bytecode::kJumpIfFalseSmi8; | |
341 } | |
342 | |
343 | |
344 // static | |
345 Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand( | |
346 Bytecode jump_bytecode) { | |
347 switch (jump_bytecode) { | |
348 case Bytecode::kJumpSmi8: | |
349 return Bytecode::kJumpConstant; | |
350 case Bytecode::kJumpIfTrueSmi8: | |
351 return Bytecode::kJumpIfTrueConstant; | |
352 case Bytecode::kJumpIfFalseSmi8: | |
353 return Bytecode::kJumpIfFalseConstant; | |
354 default: | |
355 UNREACHABLE(); | |
356 return Bytecode::kJumpConstant; | |
357 } | |
358 } | |
359 | |
360 | |
361 void BytecodeArrayBuilder::OutputJump( | |
362 Bytecode jump_bytecode, const ZoneVector<uint8_t>::iterator& jump_location, | |
363 const ZoneVector<uint8_t>::iterator& jump_target) { | |
364 DCHECK(IsJumpWithSmi8Operand(jump_bytecode)); | |
365 | |
366 int delta = static_cast<int>(jump_target - jump_location); | |
367 if (FitsInImm8Operand(delta)) { | |
368 Output(jump_location, jump_bytecode, static_cast<uint8_t>(delta)); | |
369 } else { | |
370 size_t entry = GetConstantPoolEntry(handle(Smi::FromInt(delta), isolate())); | |
371 if (FitsInIdxOperand(entry)) { | |
372 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); | |
373 Output(jump_location, jump_bytecode, static_cast<uint8_t>(entry)); | |
374 } else { | |
375 UNIMPLEMENTED(); | |
376 } | |
377 } | |
378 } | |
379 | |
380 | |
381 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(Bytecode jump_bytecode, | |
382 BytecodeLabel* label) { | |
383 if (bound_labels_.find(label) != bound_labels_.end()) { | |
384 // Label has been bound already so this is a backwards jump. | |
385 OutputJump(jump_bytecode, bytecodes()->end(), | |
386 bytecodes()->begin() + label->offset()); | |
387 } else { | |
388 // Label has not yet been bound so this is a forward reference | |
389 // that will be patched when the label is bound. | |
390 DCHECK(forward_labels_.find(label) == forward_labels_.end()); | |
391 label->bind_to(bytecodes()->size()); | |
392 forward_labels_.insert(label); | |
393 OutputJump(jump_bytecode, bytecodes()->end(), bytecodes()->end()); | |
394 } | |
395 return *this; | |
396 } | |
397 | |
398 | |
399 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { | |
400 return Jump(Bytecode::kJumpSmi8, label); | |
401 } | |
402 | |
403 | |
404 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { | |
405 return Jump(Bytecode::kJumpIfTrueSmi8, label); | |
406 } | |
407 | |
408 | |
409 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { | |
410 return Jump(Bytecode::kJumpIfFalseSmi8, label); | |
411 } | |
412 | |
413 | |
221 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { | 414 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { |
222 Output(Bytecode::kReturn); | 415 Output(Bytecode::kReturn); |
223 return *this; | 416 return *this; |
224 } | 417 } |
225 | 418 |
226 | 419 |
227 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, | 420 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, |
228 Register receiver, | 421 Register receiver, |
229 size_t arg_count) { | 422 size_t arg_count) { |
230 if (FitsInByteOperand(arg_count)) { | 423 if (FitsInIdxOperand(arg_count)) { |
231 Output(Bytecode::kCall, callable.ToOperand(), receiver.ToOperand(), | 424 Output(Bytecode::kCall, callable.ToOperand(), receiver.ToOperand(), |
232 static_cast<uint8_t>(arg_count)); | 425 static_cast<uint8_t>(arg_count)); |
233 } else { | 426 } else { |
234 UNIMPLEMENTED(); | 427 UNIMPLEMENTED(); |
235 } | 428 } |
236 return *this; | 429 return *this; |
237 } | 430 } |
238 | 431 |
239 | 432 |
240 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 433 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 } else { | 485 } else { |
293 return (reg.index() >= 0 && reg.index() < temporary_register_next_); | 486 return (reg.index() >= 0 && reg.index() < temporary_register_next_); |
294 } | 487 } |
295 } | 488 } |
296 } | 489 } |
297 UNREACHABLE(); | 490 UNREACHABLE(); |
298 return false; | 491 return false; |
299 } | 492 } |
300 | 493 |
301 | 494 |
302 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | |
303 uint8_t operand1, uint8_t operand2) { | |
304 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3); | |
305 DCHECK(OperandIsValid(bytecode, 0, operand0) && | |
306 OperandIsValid(bytecode, 1, operand1) && | |
307 OperandIsValid(bytecode, 2, operand2)); | |
308 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
309 bytecodes_.push_back(operand0); | |
310 bytecodes_.push_back(operand1); | |
311 bytecodes_.push_back(operand2); | |
312 } | |
313 | |
314 | |
315 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | |
316 uint8_t operand1) { | |
317 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2); | |
318 DCHECK(OperandIsValid(bytecode, 0, operand0) && | |
319 OperandIsValid(bytecode, 1, operand1)); | |
320 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
321 bytecodes_.push_back(operand0); | |
322 bytecodes_.push_back(operand1); | |
323 } | |
324 | |
325 | |
326 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0) { | |
327 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1); | |
328 DCHECK(OperandIsValid(bytecode, 0, operand0)); | |
329 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
330 bytecodes_.push_back(operand0); | |
331 } | |
332 | |
333 | |
334 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | |
335 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); | |
336 bytecodes_.push_back(Bytecodes::ToByte(bytecode)); | |
337 } | |
338 | |
339 | |
340 // static | 495 // static |
341 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { | 496 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { |
342 switch (op) { | 497 switch (op) { |
343 case Token::Value::ADD: | 498 case Token::Value::ADD: |
344 return Bytecode::kAdd; | 499 return Bytecode::kAdd; |
345 case Token::Value::SUB: | 500 case Token::Value::SUB: |
346 return Bytecode::kSub; | 501 return Bytecode::kSub; |
347 case Token::Value::MUL: | 502 case Token::Value::MUL: |
348 return Bytecode::kMul; | 503 return Bytecode::kMul; |
349 case Token::Value::DIV: | 504 case Token::Value::DIV: |
350 return Bytecode::kDiv; | 505 return Bytecode::kDiv; |
351 case Token::Value::MOD: | 506 case Token::Value::MOD: |
352 return Bytecode::kMod; | 507 return Bytecode::kMod; |
353 default: | 508 default: |
354 UNIMPLEMENTED(); | 509 UNIMPLEMENTED(); |
355 return static_cast<Bytecode>(-1); | 510 return static_cast<Bytecode>(-1); |
356 } | 511 } |
357 } | 512 } |
358 | 513 |
359 | 514 |
360 // static | 515 // static |
361 bool BytecodeArrayBuilder::FitsInByteOperand(int value) { | 516 Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) { |
517 switch (op) { | |
518 case Token::Value::EQ: | |
519 return Bytecode::kTestEqual; | |
520 case Token::Value::NE: | |
521 return Bytecode::kTestNotEqual; | |
522 case Token::Value::EQ_STRICT: | |
523 return Bytecode::kTestEqualStrict; | |
524 case Token::Value::NE_STRICT: | |
525 return Bytecode::kTestNotEqualStrict; | |
526 case Token::Value::LT: | |
527 return Bytecode::kTestLessThan; | |
528 case Token::Value::GT: | |
529 return Bytecode::kTestGreaterThan; | |
530 case Token::Value::LTE: | |
531 return Bytecode::kTestLessThanEqual; | |
532 case Token::Value::GTE: | |
533 return Bytecode::kTestGreaterThanEqual; | |
534 case Token::Value::INSTANCEOF: | |
535 return Bytecode::kTestInstanceOf; | |
536 case Token::Value::IN: | |
537 return Bytecode::kTestIn; | |
538 default: | |
539 UNIMPLEMENTED(); | |
540 return static_cast<Bytecode>(-1); | |
541 } | |
542 } | |
543 | |
544 | |
545 // static | |
546 bool BytecodeArrayBuilder::FitsInIdxOperand(int value) { | |
362 return 0 <= value && value <= 255; | 547 return 0 <= value && value <= 255; |
363 } | 548 } |
364 | 549 |
365 | 550 |
366 // static | 551 // static |
367 bool BytecodeArrayBuilder::FitsInByteOperand(size_t value) { | 552 bool BytecodeArrayBuilder::FitsInIdxOperand(size_t value) { |
368 return value <= 255; | 553 return value <= 255; |
369 } | 554 } |
370 | 555 |
371 | 556 |
557 // static | |
558 bool BytecodeArrayBuilder::FitsInImm8Operand(int value) { | |
559 return -128 <= value && value < 127; | |
560 } | |
561 | |
562 | |
372 TemporaryRegisterScope::TemporaryRegisterScope(BytecodeArrayBuilder* builder) | 563 TemporaryRegisterScope::TemporaryRegisterScope(BytecodeArrayBuilder* builder) |
373 : builder_(builder), count_(0), last_register_index_(-1) {} | 564 : builder_(builder), count_(0), last_register_index_(-1) {} |
374 | 565 |
375 | 566 |
376 TemporaryRegisterScope::~TemporaryRegisterScope() { | 567 TemporaryRegisterScope::~TemporaryRegisterScope() { |
377 while (count_-- != 0) { | 568 while (count_-- != 0) { |
378 builder_->ReturnTemporaryRegister(last_register_index_--); | 569 builder_->ReturnTemporaryRegister(last_register_index_--); |
379 } | 570 } |
380 } | 571 } |
381 | 572 |
382 | 573 |
383 Register TemporaryRegisterScope::NewRegister() { | 574 Register TemporaryRegisterScope::NewRegister() { |
384 count_++; | 575 count_++; |
385 last_register_index_ = builder_->BorrowTemporaryRegister(); | 576 last_register_index_ = builder_->BorrowTemporaryRegister(); |
386 return Register(last_register_index_); | 577 return Register(last_register_index_); |
387 } | 578 } |
388 | 579 |
389 } // namespace interpreter | 580 } // namespace interpreter |
390 } // namespace internal | 581 } // namespace internal |
391 } // namespace v8 | 582 } // namespace v8 |
OLD | NEW |