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 #include "src/globals.h" | 7 #include "src/globals.h" |
8 #include "src/interpreter/bytecode-array-writer.h" | 8 #include "src/interpreter/bytecode-array-writer.h" |
9 #include "src/interpreter/bytecode-dead-code-optimizer.h" | 9 #include "src/interpreter/bytecode-dead-code-optimizer.h" |
10 #include "src/interpreter/bytecode-label.h" | 10 #include "src/interpreter/bytecode-label.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 return reg.is_parameter() || reg.index() < locals_count(); | 73 return reg.is_parameter() || reg.index() < locals_count(); |
74 } | 74 } |
75 | 75 |
76 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(Isolate* isolate) { | 76 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(Isolate* isolate) { |
77 DCHECK(return_seen_in_block_); | 77 DCHECK(return_seen_in_block_); |
78 DCHECK(!bytecode_generated_); | 78 DCHECK(!bytecode_generated_); |
79 bytecode_generated_ = true; | 79 bytecode_generated_ = true; |
80 | 80 |
81 Handle<FixedArray> handler_table = | 81 Handle<FixedArray> handler_table = |
82 handler_table_builder()->ToHandlerTable(isolate); | 82 handler_table_builder()->ToHandlerTable(isolate); |
83 return pipeline_->ToBytecodeArray(isolate, | 83 return pipeline_->ToBytecodeArray(isolate, fixed_register_count(), |
84 fixed_and_temporary_register_count(), | |
85 parameter_count(), handler_table); | 84 parameter_count(), handler_table); |
86 } | 85 } |
87 | 86 |
| 87 namespace { |
| 88 |
| 89 static bool ExpressionPositionIsNeeded(Bytecode bytecode) { |
| 90 // An expression position is always needed if filtering is turned |
| 91 // off. Otherwise an expression is only needed if the bytecode has |
| 92 // external side effects. |
| 93 return !FLAG_ignition_filter_expression_positions || |
| 94 !Bytecodes::IsWithoutExternalSideEffects(bytecode); |
| 95 } |
| 96 |
| 97 } // namespace |
| 98 |
| 99 void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) { |
| 100 if (latest_source_info_.is_valid()) { |
| 101 // Statement positions need to be emitted immediately. Expression |
| 102 // positions can be pushed back until a bytecode is found that can |
| 103 // throw. Hence we only invalidate the existing source position |
| 104 // information if it is used. |
| 105 if (latest_source_info_.is_statement() || |
| 106 ExpressionPositionIsNeeded(node->bytecode())) { |
| 107 node->source_info().Clone(latest_source_info_); |
| 108 latest_source_info_.set_invalid(); |
| 109 } |
| 110 } |
| 111 } |
| 112 |
88 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | 113 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
89 uint32_t operand1, uint32_t operand2, | 114 uint32_t operand1, uint32_t operand2, |
90 uint32_t operand3) { | 115 uint32_t operand3) { |
91 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3)); | 116 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3)); |
92 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3, | 117 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3); |
93 &latest_source_info_); | 118 AttachSourceInfo(&node); |
94 pipeline()->Write(&node); | 119 pipeline()->Write(&node); |
95 } | 120 } |
96 | 121 |
97 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | 122 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
98 uint32_t operand1, uint32_t operand2) { | 123 uint32_t operand1, uint32_t operand2) { |
99 DCHECK(OperandsAreValid(bytecode, 3, operand0, operand1, operand2)); | 124 DCHECK(OperandsAreValid(bytecode, 3, operand0, operand1, operand2)); |
100 BytecodeNode node(bytecode, operand0, operand1, operand2, | 125 BytecodeNode node(bytecode, operand0, operand1, operand2); |
101 &latest_source_info_); | 126 AttachSourceInfo(&node); |
102 pipeline()->Write(&node); | 127 pipeline()->Write(&node); |
103 } | 128 } |
104 | 129 |
105 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | 130 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
106 uint32_t operand1) { | 131 uint32_t operand1) { |
107 DCHECK(OperandsAreValid(bytecode, 2, operand0, operand1)); | 132 DCHECK(OperandsAreValid(bytecode, 2, operand0, operand1)); |
108 BytecodeNode node(bytecode, operand0, operand1, &latest_source_info_); | 133 BytecodeNode node(bytecode, operand0, operand1); |
| 134 AttachSourceInfo(&node); |
109 pipeline()->Write(&node); | 135 pipeline()->Write(&node); |
110 } | 136 } |
111 | 137 |
112 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { | 138 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { |
113 DCHECK(OperandsAreValid(bytecode, 1, operand0)); | 139 DCHECK(OperandsAreValid(bytecode, 1, operand0)); |
114 BytecodeNode node(bytecode, operand0, &latest_source_info_); | 140 BytecodeNode node(bytecode, operand0); |
| 141 AttachSourceInfo(&node); |
115 pipeline()->Write(&node); | 142 pipeline()->Write(&node); |
116 } | 143 } |
117 | 144 |
118 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 145 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
119 DCHECK(OperandsAreValid(bytecode, 0)); | 146 DCHECK(OperandsAreValid(bytecode, 0)); |
120 BytecodeNode node(bytecode, &latest_source_info_); | 147 BytecodeNode node(bytecode); |
| 148 AttachSourceInfo(&node); |
121 pipeline()->Write(&node); | 149 pipeline()->Write(&node); |
122 } | 150 } |
123 | 151 |
124 void BytecodeArrayBuilder::OutputJump(Bytecode bytecode, BytecodeLabel* label) { | |
125 BytecodeNode node(bytecode, 0, &latest_source_info_); | |
126 pipeline_->WriteJump(&node, label); | |
127 LeaveBasicBlock(); | |
128 } | |
129 | |
130 void BytecodeArrayBuilder::OutputJump(Bytecode bytecode, uint32_t operand0, | |
131 BytecodeLabel* label) { | |
132 BytecodeNode node(bytecode, 0, operand0, &latest_source_info_); | |
133 pipeline_->WriteJump(&node, label); | |
134 LeaveBasicBlock(); | |
135 } | |
136 | |
137 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 152 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
138 Register reg, | 153 Register reg, |
139 int feedback_slot) { | 154 int feedback_slot) { |
140 switch (op) { | 155 Output(BytecodeForBinaryOperation(op), RegisterOperand(reg), |
141 case Token::Value::ADD: | 156 UnsignedOperand(feedback_slot)); |
142 Output(Bytecode::kAdd, RegisterOperand(reg), | |
143 UnsignedOperand(feedback_slot)); | |
144 break; | |
145 case Token::Value::SUB: | |
146 Output(Bytecode::kSub, RegisterOperand(reg), | |
147 UnsignedOperand(feedback_slot)); | |
148 break; | |
149 case Token::Value::MUL: | |
150 Output(Bytecode::kMul, RegisterOperand(reg), | |
151 UnsignedOperand(feedback_slot)); | |
152 break; | |
153 case Token::Value::DIV: | |
154 Output(Bytecode::kDiv, RegisterOperand(reg), | |
155 UnsignedOperand(feedback_slot)); | |
156 break; | |
157 case Token::Value::MOD: | |
158 Output(Bytecode::kMod, RegisterOperand(reg), | |
159 UnsignedOperand(feedback_slot)); | |
160 break; | |
161 case Token::Value::BIT_OR: | |
162 Output(Bytecode::kBitwiseOr, RegisterOperand(reg), | |
163 UnsignedOperand(feedback_slot)); | |
164 break; | |
165 case Token::Value::BIT_XOR: | |
166 Output(Bytecode::kBitwiseXor, RegisterOperand(reg), | |
167 UnsignedOperand(feedback_slot)); | |
168 break; | |
169 case Token::Value::BIT_AND: | |
170 Output(Bytecode::kBitwiseAnd, RegisterOperand(reg), | |
171 UnsignedOperand(feedback_slot)); | |
172 break; | |
173 case Token::Value::SHL: | |
174 Output(Bytecode::kShiftLeft, RegisterOperand(reg), | |
175 UnsignedOperand(feedback_slot)); | |
176 break; | |
177 case Token::Value::SAR: | |
178 Output(Bytecode::kShiftRight, RegisterOperand(reg), | |
179 UnsignedOperand(feedback_slot)); | |
180 break; | |
181 case Token::Value::SHR: | |
182 Output(Bytecode::kShiftRightLogical, RegisterOperand(reg), | |
183 UnsignedOperand(feedback_slot)); | |
184 break; | |
185 default: | |
186 UNREACHABLE(); | |
187 } | |
188 return *this; | 157 return *this; |
189 } | 158 } |
190 | 159 |
191 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, | 160 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, |
192 int feedback_slot) { | 161 int feedback_slot) { |
193 if (op == Token::Value::ADD) { | 162 Output(BytecodeForCountOperation(op), UnsignedOperand(feedback_slot)); |
194 Output(Bytecode::kInc, UnsignedOperand(feedback_slot)); | |
195 } else { | |
196 DCHECK_EQ(op, Token::Value::SUB); | |
197 Output(Bytecode::kDec, UnsignedOperand(feedback_slot)); | |
198 } | |
199 return *this; | 163 return *this; |
200 } | 164 } |
201 | 165 |
202 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { | 166 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { |
203 Output(Bytecode::kToBooleanLogicalNot); | 167 Output(Bytecode::kToBooleanLogicalNot); |
204 return *this; | 168 return *this; |
205 } | 169 } |
206 | 170 |
| 171 |
207 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { | 172 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { |
208 Output(Bytecode::kTypeOf); | 173 Output(Bytecode::kTypeOf); |
209 return *this; | 174 return *this; |
210 } | 175 } |
211 | 176 |
212 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( | 177 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( |
213 Token::Value op, Register reg, int feedback_slot) { | 178 Token::Value op, Register reg, int feedback_slot) { |
214 switch (op) { | 179 if (op == Token::INSTANCEOF || op == Token::IN) { |
215 case Token::Value::EQ: | 180 Output(BytecodeForCompareOperation(op), RegisterOperand(reg)); |
216 Output(Bytecode::kTestEqual, RegisterOperand(reg), | 181 } else { |
217 UnsignedOperand(feedback_slot)); | 182 Output(BytecodeForCompareOperation(op), RegisterOperand(reg), |
218 break; | 183 UnsignedOperand(feedback_slot)); |
219 case Token::Value::NE: | |
220 Output(Bytecode::kTestNotEqual, RegisterOperand(reg), | |
221 UnsignedOperand(feedback_slot)); | |
222 break; | |
223 case Token::Value::EQ_STRICT: | |
224 Output(Bytecode::kTestEqualStrict, RegisterOperand(reg), | |
225 UnsignedOperand(feedback_slot)); | |
226 break; | |
227 case Token::Value::LT: | |
228 Output(Bytecode::kTestLessThan, RegisterOperand(reg), | |
229 UnsignedOperand(feedback_slot)); | |
230 break; | |
231 case Token::Value::GT: | |
232 Output(Bytecode::kTestGreaterThan, RegisterOperand(reg), | |
233 UnsignedOperand(feedback_slot)); | |
234 break; | |
235 case Token::Value::LTE: | |
236 Output(Bytecode::kTestLessThanOrEqual, RegisterOperand(reg), | |
237 UnsignedOperand(feedback_slot)); | |
238 break; | |
239 case Token::Value::GTE: | |
240 Output(Bytecode::kTestGreaterThanOrEqual, RegisterOperand(reg), | |
241 UnsignedOperand(feedback_slot)); | |
242 break; | |
243 case Token::Value::INSTANCEOF: | |
244 Output(Bytecode::kTestInstanceOf, RegisterOperand(reg)); | |
245 break; | |
246 case Token::Value::IN: | |
247 Output(Bytecode::kTestIn, RegisterOperand(reg)); | |
248 break; | |
249 default: | |
250 UNREACHABLE(); | |
251 } | 184 } |
252 return *this; | 185 return *this; |
253 } | 186 } |
254 | 187 |
255 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry( | 188 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry( |
256 size_t entry) { | 189 size_t entry) { |
257 Output(Bytecode::kLdaConstant, UnsignedOperand(entry)); | 190 Output(Bytecode::kLdaConstant, UnsignedOperand(entry)); |
258 return *this; | 191 return *this; |
259 } | 192 } |
260 | 193 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 | 247 |
315 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, | 248 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, |
316 Register to) { | 249 Register to) { |
317 DCHECK(from != to); | 250 DCHECK(from != to); |
318 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to)); | 251 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to)); |
319 return *this; | 252 return *this; |
320 } | 253 } |
321 | 254 |
322 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int feedback_slot, | 255 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int feedback_slot, |
323 TypeofMode typeof_mode) { | 256 TypeofMode typeof_mode) { |
324 if (typeof_mode == INSIDE_TYPEOF) { | 257 // TODO(rmcilroy): Potentially store typeof information in an |
325 Output(Bytecode::kLdaGlobalInsideTypeof, feedback_slot); | 258 // operand rather than having extra bytecodes. |
326 } else { | 259 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); |
327 DCHECK_EQ(typeof_mode, NOT_INSIDE_TYPEOF); | 260 Output(bytecode, UnsignedOperand(feedback_slot)); |
328 Output(Bytecode::kLdaGlobal, UnsignedOperand(feedback_slot)); | |
329 } | |
330 return *this; | 261 return *this; |
331 } | 262 } |
332 | 263 |
333 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( | 264 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( |
334 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { | 265 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { |
| 266 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); |
335 size_t name_index = GetConstantPoolEntry(name); | 267 size_t name_index = GetConstantPoolEntry(name); |
336 if (language_mode == SLOPPY) { | 268 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
337 Output(Bytecode::kStaGlobalSloppy, UnsignedOperand(name_index), | |
338 UnsignedOperand(feedback_slot)); | |
339 } else { | |
340 DCHECK_EQ(language_mode, STRICT); | |
341 Output(Bytecode::kStaGlobalStrict, UnsignedOperand(name_index), | |
342 UnsignedOperand(feedback_slot)); | |
343 } | |
344 return *this; | 269 return *this; |
345 } | 270 } |
346 | 271 |
347 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, | 272 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, |
348 int slot_index, | 273 int slot_index, |
349 int depth) { | 274 int depth) { |
350 Output(Bytecode::kLdaContextSlot, RegisterOperand(context), | 275 Output(Bytecode::kLdaContextSlot, RegisterOperand(context), |
351 UnsignedOperand(slot_index), UnsignedOperand(depth)); | 276 UnsignedOperand(slot_index), UnsignedOperand(depth)); |
352 return *this; | 277 return *this; |
353 } | 278 } |
354 | 279 |
355 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, | 280 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, |
356 int slot_index, | 281 int slot_index, |
357 int depth) { | 282 int depth) { |
358 Output(Bytecode::kStaContextSlot, RegisterOperand(context), | 283 Output(Bytecode::kStaContextSlot, RegisterOperand(context), |
359 UnsignedOperand(slot_index), UnsignedOperand(depth)); | 284 UnsignedOperand(slot_index), UnsignedOperand(depth)); |
360 return *this; | 285 return *this; |
361 } | 286 } |
362 | 287 |
363 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( | 288 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( |
364 const Handle<String> name, TypeofMode typeof_mode) { | 289 const Handle<String> name, TypeofMode typeof_mode) { |
| 290 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) |
| 291 ? Bytecode::kLdaLookupSlotInsideTypeof |
| 292 : Bytecode::kLdaLookupSlot; |
365 size_t name_index = GetConstantPoolEntry(name); | 293 size_t name_index = GetConstantPoolEntry(name); |
366 if (typeof_mode == INSIDE_TYPEOF) { | 294 Output(bytecode, UnsignedOperand(name_index)); |
367 Output(Bytecode::kLdaLookupSlotInsideTypeof, UnsignedOperand(name_index)); | |
368 } else { | |
369 DCHECK_EQ(typeof_mode, NOT_INSIDE_TYPEOF); | |
370 Output(Bytecode::kLdaLookupSlot, UnsignedOperand(name_index)); | |
371 } | |
372 return *this; | 295 return *this; |
373 } | 296 } |
374 | 297 |
375 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupContextSlot( | 298 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupContextSlot( |
376 const Handle<String> name, TypeofMode typeof_mode, int slot_index, | 299 const Handle<String> name, TypeofMode typeof_mode, int slot_index, |
377 int depth) { | 300 int depth) { |
378 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) | 301 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) |
379 ? Bytecode::kLdaLookupContextSlotInsideTypeof | 302 ? Bytecode::kLdaLookupContextSlotInsideTypeof |
380 : Bytecode::kLdaLookupContextSlot; | 303 : Bytecode::kLdaLookupContextSlot; |
381 size_t name_index = GetConstantPoolEntry(name); | 304 size_t name_index = GetConstantPoolEntry(name); |
382 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(slot_index), | 305 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(slot_index), |
383 UnsignedOperand(depth)); | 306 UnsignedOperand(depth)); |
384 return *this; | 307 return *this; |
385 } | 308 } |
386 | 309 |
387 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupGlobalSlot( | 310 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupGlobalSlot( |
388 const Handle<String> name, TypeofMode typeof_mode, int feedback_slot, | 311 const Handle<String> name, TypeofMode typeof_mode, int feedback_slot, |
389 int depth) { | 312 int depth) { |
390 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) | 313 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) |
391 ? Bytecode::kLdaLookupGlobalSlotInsideTypeof | 314 ? Bytecode::kLdaLookupGlobalSlotInsideTypeof |
392 : Bytecode::kLdaLookupGlobalSlot; | 315 : Bytecode::kLdaLookupGlobalSlot; |
393 size_t name_index = GetConstantPoolEntry(name); | 316 size_t name_index = GetConstantPoolEntry(name); |
394 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot), | 317 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot), |
395 UnsignedOperand(depth)); | 318 UnsignedOperand(depth)); |
396 return *this; | 319 return *this; |
397 } | 320 } |
398 | 321 |
399 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( | 322 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( |
400 const Handle<String> name, LanguageMode language_mode) { | 323 const Handle<String> name, LanguageMode language_mode) { |
| 324 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode); |
401 size_t name_index = GetConstantPoolEntry(name); | 325 size_t name_index = GetConstantPoolEntry(name); |
402 if (language_mode == SLOPPY) { | 326 Output(bytecode, UnsignedOperand(name_index)); |
403 Output(Bytecode::kStaLookupSlotSloppy, UnsignedOperand(name_index)); | |
404 } else { | |
405 DCHECK_EQ(language_mode, STRICT); | |
406 Output(Bytecode::kStaLookupSlotStrict, UnsignedOperand(name_index)); | |
407 } | |
408 return *this; | 327 return *this; |
409 } | 328 } |
410 | 329 |
411 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( | 330 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( |
412 Register object, const Handle<Name> name, int feedback_slot) { | 331 Register object, const Handle<Name> name, int feedback_slot) { |
413 size_t name_index = GetConstantPoolEntry(name); | 332 size_t name_index = GetConstantPoolEntry(name); |
414 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object), | 333 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object), |
415 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | 334 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
416 return *this; | 335 return *this; |
417 } | 336 } |
418 | 337 |
419 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( | 338 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( |
420 Register object, int feedback_slot) { | 339 Register object, int feedback_slot) { |
421 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object), | 340 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object), |
422 UnsignedOperand(feedback_slot)); | 341 UnsignedOperand(feedback_slot)); |
423 return *this; | 342 return *this; |
424 } | 343 } |
425 | 344 |
426 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( | 345 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( |
427 Register object, const Handle<Name> name, int feedback_slot, | 346 Register object, const Handle<Name> name, int feedback_slot, |
428 LanguageMode language_mode) { | 347 LanguageMode language_mode) { |
| 348 Bytecode bytecode = BytecodeForStoreNamedProperty(language_mode); |
429 size_t name_index = GetConstantPoolEntry(name); | 349 size_t name_index = GetConstantPoolEntry(name); |
430 if (language_mode == SLOPPY) { | 350 Output(bytecode, RegisterOperand(object), UnsignedOperand(name_index), |
431 Output(Bytecode::kStaNamedPropertySloppy, RegisterOperand(object), | 351 UnsignedOperand(feedback_slot)); |
432 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | |
433 } else { | |
434 DCHECK_EQ(language_mode, STRICT); | |
435 Output(Bytecode::kStaNamedPropertyStrict, RegisterOperand(object), | |
436 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | |
437 } | |
438 return *this; | 352 return *this; |
439 } | 353 } |
440 | 354 |
441 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( | 355 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( |
442 Register object, Register key, int feedback_slot, | 356 Register object, Register key, int feedback_slot, |
443 LanguageMode language_mode) { | 357 LanguageMode language_mode) { |
444 if (language_mode == SLOPPY) { | 358 Bytecode bytecode = BytecodeForStoreKeyedProperty(language_mode); |
445 Output(Bytecode::kStaKeyedPropertySloppy, RegisterOperand(object), | 359 Output(bytecode, RegisterOperand(object), RegisterOperand(key), |
446 RegisterOperand(key), UnsignedOperand(feedback_slot)); | 360 UnsignedOperand(feedback_slot)); |
447 } else { | |
448 DCHECK_EQ(language_mode, STRICT); | |
449 Output(Bytecode::kStaKeyedPropertyStrict, RegisterOperand(object), | |
450 RegisterOperand(key), UnsignedOperand(feedback_slot)); | |
451 } | |
452 return *this; | 361 return *this; |
453 } | 362 } |
454 | 363 |
455 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry, | 364 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry, |
456 int flags) { | 365 int flags) { |
457 Output(Bytecode::kCreateClosure, UnsignedOperand(entry), | 366 Output(Bytecode::kCreateClosure, UnsignedOperand(entry), |
458 UnsignedOperand(flags)); | 367 UnsignedOperand(flags)); |
459 return *this; | 368 return *this; |
460 } | 369 } |
461 | 370 |
(...skipping 21 matching lines...) Expand all Loading... |
483 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext( | 392 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext( |
484 Register object, Handle<ScopeInfo> scope_info) { | 393 Register object, Handle<ScopeInfo> scope_info) { |
485 size_t scope_info_index = GetConstantPoolEntry(scope_info); | 394 size_t scope_info_index = GetConstantPoolEntry(scope_info); |
486 Output(Bytecode::kCreateWithContext, RegisterOperand(object), | 395 Output(Bytecode::kCreateWithContext, RegisterOperand(object), |
487 UnsignedOperand(scope_info_index)); | 396 UnsignedOperand(scope_info_index)); |
488 return *this; | 397 return *this; |
489 } | 398 } |
490 | 399 |
491 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( | 400 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( |
492 CreateArgumentsType type) { | 401 CreateArgumentsType type) { |
493 switch (type) { | 402 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather |
494 case CreateArgumentsType::kMappedArguments: | 403 // than having two different bytecodes once we have better support for |
495 Output(Bytecode::kCreateMappedArguments); | 404 // branches in the InterpreterAssembler. |
496 break; | 405 Bytecode bytecode = BytecodeForCreateArguments(type); |
497 case CreateArgumentsType::kUnmappedArguments: | 406 Output(bytecode); |
498 Output(Bytecode::kCreateUnmappedArguments); | |
499 break; | |
500 case CreateArgumentsType::kRestParameter: | |
501 Output(Bytecode::kCreateRestParameter); | |
502 break; | |
503 default: | |
504 UNREACHABLE(); | |
505 } | |
506 return *this; | 407 return *this; |
507 } | 408 } |
508 | 409 |
509 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( | 410 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( |
510 Handle<String> pattern, int literal_index, int flags) { | 411 Handle<String> pattern, int literal_index, int flags) { |
511 size_t pattern_entry = GetConstantPoolEntry(pattern); | 412 size_t pattern_entry = GetConstantPoolEntry(pattern); |
512 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry), | 413 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry), |
513 UnsignedOperand(literal_index), UnsignedOperand(flags)); | 414 UnsignedOperand(literal_index), UnsignedOperand(flags)); |
514 return *this; | 415 return *this; |
515 } | 416 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 return *this; | 469 return *this; |
569 } | 470 } |
570 | 471 |
571 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, | 472 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, |
572 BytecodeLabel* label) { | 473 BytecodeLabel* label) { |
573 pipeline_->BindLabel(target, label); | 474 pipeline_->BindLabel(target, label); |
574 LeaveBasicBlock(); | 475 LeaveBasicBlock(); |
575 return *this; | 476 return *this; |
576 } | 477 } |
577 | 478 |
| 479 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(BytecodeNode* node, |
| 480 BytecodeLabel* label) { |
| 481 AttachSourceInfo(node); |
| 482 pipeline_->WriteJump(node, label); |
| 483 LeaveBasicBlock(); |
| 484 return *this; |
| 485 } |
| 486 |
578 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { | 487 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { |
579 OutputJump(Bytecode::kJump, label); | 488 BytecodeNode node(Bytecode::kJump, 0); |
580 return *this; | 489 return OutputJump(&node, label); |
581 } | 490 } |
582 | 491 |
583 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { | 492 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { |
584 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue | 493 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue |
585 // to JumpIfTrue. | 494 // to JumpIfTrue. |
586 OutputJump(Bytecode::kJumpIfToBooleanTrue, label); | 495 BytecodeNode node(Bytecode::kJumpIfToBooleanTrue, 0); |
587 return *this; | 496 return OutputJump(&node, label); |
588 } | 497 } |
589 | 498 |
590 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { | 499 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { |
591 OutputJump(Bytecode::kJumpIfToBooleanFalse, label); | 500 // The peephole optimizer attempts to simplify JumpIfToBooleanFalse |
592 return *this; | 501 // to JumpIfFalse. |
| 502 BytecodeNode node(Bytecode::kJumpIfToBooleanFalse, 0); |
| 503 return OutputJump(&node, label); |
593 } | 504 } |
594 | 505 |
595 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { | 506 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { |
596 OutputJump(Bytecode::kJumpIfNull, label); | 507 BytecodeNode node(Bytecode::kJumpIfNull, 0); |
597 return *this; | 508 return OutputJump(&node, label); |
598 } | 509 } |
599 | 510 |
600 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( | 511 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( |
601 BytecodeLabel* label) { | 512 BytecodeLabel* label) { |
602 OutputJump(Bytecode::kJumpIfUndefined, label); | 513 BytecodeNode node(Bytecode::kJumpIfUndefined, 0); |
603 return *this; | 514 return OutputJump(&node, label); |
604 } | 515 } |
605 | 516 |
606 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( | 517 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( |
607 BytecodeLabel* label) { | 518 BytecodeLabel* label) { |
608 OutputJump(Bytecode::kJumpIfNotHole, label); | 519 BytecodeNode node(Bytecode::kJumpIfNotHole, 0); |
609 return *this; | 520 return OutputJump(&node, label); |
610 } | 521 } |
611 | 522 |
612 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label, | 523 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label, |
613 int loop_depth) { | 524 int loop_depth) { |
614 OutputJump(Bytecode::kJumpLoop, UnsignedOperand(loop_depth), label); | 525 BytecodeNode node(Bytecode::kJumpLoop, 0, UnsignedOperand(loop_depth)); |
615 return *this; | 526 return OutputJump(&node, label); |
616 } | 527 } |
617 | 528 |
618 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { | 529 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { |
619 if (position != kNoSourcePosition) { | 530 if (position != kNoSourcePosition) { |
620 // We need to attach a non-breakable source position to a stack | 531 // We need to attach a non-breakable source position to a stack |
621 // check, so we simply add it as expression position. There can be | 532 // check, so we simply add it as expression position. There can be |
622 // a prior statement position from constructs like: | 533 // a prior statement position from constructs like: |
623 // | 534 // |
624 // do var x; while (false); | 535 // do var x; while (false); |
625 // | 536 // |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 Return(); | 637 Return(); |
727 } | 638 } |
728 DCHECK(return_seen_in_block_); | 639 DCHECK(return_seen_in_block_); |
729 } | 640 } |
730 | 641 |
731 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, | 642 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, |
732 Register receiver_args, | 643 Register receiver_args, |
733 size_t receiver_args_count, | 644 size_t receiver_args_count, |
734 int feedback_slot, | 645 int feedback_slot, |
735 TailCallMode tail_call_mode) { | 646 TailCallMode tail_call_mode) { |
736 if (tail_call_mode == TailCallMode::kDisallow) { | 647 Bytecode bytecode = BytecodeForCall(tail_call_mode); |
737 Output(Bytecode::kCall, RegisterOperand(callable), | 648 Output(bytecode, RegisterOperand(callable), RegisterOperand(receiver_args), |
738 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count), | 649 UnsignedOperand(receiver_args_count), UnsignedOperand(feedback_slot)); |
739 UnsignedOperand(feedback_slot)); | |
740 } else { | |
741 DCHECK(tail_call_mode == TailCallMode::kAllow); | |
742 Output(Bytecode::kTailCall, RegisterOperand(callable), | |
743 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count), | |
744 UnsignedOperand(feedback_slot)); | |
745 } | |
746 return *this; | 650 return *this; |
747 } | 651 } |
748 | 652 |
749 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, | 653 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, |
750 Register first_arg, | 654 Register first_arg, |
751 size_t arg_count, | 655 size_t arg_count, |
752 int feedback_slot_id) { | 656 int feedback_slot_id) { |
753 if (!first_arg.is_valid()) { | 657 if (!first_arg.is_valid()) { |
754 DCHECK_EQ(0u, arg_count); | 658 DCHECK_EQ(0u, arg_count); |
755 first_arg = Register(0); | 659 first_arg = Register(0); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 | 702 |
799 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( | 703 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( |
800 int context_index, Register receiver_args, size_t receiver_args_count) { | 704 int context_index, Register receiver_args, size_t receiver_args_count) { |
801 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index), | 705 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index), |
802 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count)); | 706 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count)); |
803 return *this; | 707 return *this; |
804 } | 708 } |
805 | 709 |
806 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, | 710 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, |
807 LanguageMode language_mode) { | 711 LanguageMode language_mode) { |
808 if (language_mode == SLOPPY) { | 712 Output(BytecodeForDelete(language_mode), RegisterOperand(object)); |
809 Output(Bytecode::kDeletePropertySloppy, RegisterOperand(object)); | |
810 } else { | |
811 DCHECK_EQ(language_mode, STRICT); | |
812 Output(Bytecode::kDeletePropertyStrict, RegisterOperand(object)); | |
813 } | |
814 return *this; | 713 return *this; |
815 } | 714 } |
816 | 715 |
817 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 716 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
818 return constant_array_builder()->Insert(object); | 717 return constant_array_builder()->Insert(object); |
819 } | 718 } |
820 | 719 |
821 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() { | 720 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() { |
822 return constant_array_builder()->AllocateEntry(); | 721 return constant_array_builder()->AllocateEntry(); |
823 } | 722 } |
824 | 723 |
825 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry, | 724 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry, |
826 Handle<Object> object) { | 725 Handle<Object> object) { |
827 constant_array_builder()->InsertAllocatedEntry(entry, object); | 726 constant_array_builder()->InsertAllocatedEntry(entry, object); |
828 } | 727 } |
829 | 728 |
830 void BytecodeArrayBuilder::SetReturnPosition() { | 729 void BytecodeArrayBuilder::SetReturnPosition() { |
831 if (return_position_ == kNoSourcePosition) return; | 730 if (return_position_ == kNoSourcePosition) return; |
832 latest_source_info_.MakeStatementPosition(return_position_); | 731 latest_source_info_.MakeStatementPosition(return_position_); |
833 } | 732 } |
834 | 733 |
| 734 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { |
| 735 if (stmt->position() == kNoSourcePosition) return; |
| 736 latest_source_info_.MakeStatementPosition(stmt->position()); |
| 737 } |
| 738 |
| 739 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { |
| 740 if (expr->position() == kNoSourcePosition) return; |
| 741 if (!latest_source_info_.is_statement()) { |
| 742 // Ensure the current expression position is overwritten with the |
| 743 // latest value. |
| 744 latest_source_info_.MakeExpressionPosition(expr->position()); |
| 745 } |
| 746 } |
| 747 |
| 748 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { |
| 749 if (expr->position() == kNoSourcePosition) return; |
| 750 latest_source_info_.MakeStatementPosition(expr->position()); |
| 751 } |
| 752 |
835 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 753 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { |
836 return temporary_register_allocator()->RegisterIsLive(reg); | 754 return temporary_register_allocator()->RegisterIsLive(reg); |
837 } | 755 } |
838 | 756 |
839 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { | 757 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { |
840 if (!reg.is_valid()) { | 758 if (!reg.is_valid()) { |
841 return false; | 759 return false; |
842 } | 760 } |
843 | 761 |
844 if (reg.is_current_context() || reg.is_function_closure() || | 762 if (reg.is_current_context() || reg.is_function_closure() || |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 } | 806 } |
889 break; | 807 break; |
890 case OperandType::kRuntimeId: | 808 case OperandType::kRuntimeId: |
891 if (Bytecodes::SizeForUnsignedOperand(operands[i]) > | 809 if (Bytecodes::SizeForUnsignedOperand(operands[i]) > |
892 OperandSize::kShort) { | 810 OperandSize::kShort) { |
893 return false; | 811 return false; |
894 } | 812 } |
895 break; | 813 break; |
896 case OperandType::kIdx: | 814 case OperandType::kIdx: |
897 // TODO(leszeks): Possibly split this up into constant pool indices and | 815 // TODO(leszeks): Possibly split this up into constant pool indices and |
898 // other indices, for checking. | 816 // other indices, for checking |
899 break; | 817 break; |
900 case OperandType::kUImm: | 818 case OperandType::kUImm: |
901 case OperandType::kImm: | 819 case OperandType::kImm: |
902 break; | 820 break; |
903 case OperandType::kMaybeReg: | 821 case OperandType::kMaybeReg: |
904 if (Register::FromOperand(operands[i]) == Register(0)) { | 822 if (Register::FromOperand(operands[i]) == Register(0)) { |
905 break; | 823 break; |
906 } | 824 } |
907 // Fall-through to kReg case. | 825 // Fall-through to kReg case. |
908 case OperandType::kReg: | 826 case OperandType::kReg: |
(...skipping 22 matching lines...) Expand all Loading... |
931 return false; | 849 return false; |
932 } | 850 } |
933 break; | 851 break; |
934 } | 852 } |
935 } | 853 } |
936 } | 854 } |
937 | 855 |
938 return true; | 856 return true; |
939 } | 857 } |
940 | 858 |
| 859 // static |
| 860 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { |
| 861 switch (op) { |
| 862 case Token::Value::ADD: |
| 863 return Bytecode::kAdd; |
| 864 case Token::Value::SUB: |
| 865 return Bytecode::kSub; |
| 866 case Token::Value::MUL: |
| 867 return Bytecode::kMul; |
| 868 case Token::Value::DIV: |
| 869 return Bytecode::kDiv; |
| 870 case Token::Value::MOD: |
| 871 return Bytecode::kMod; |
| 872 case Token::Value::BIT_OR: |
| 873 return Bytecode::kBitwiseOr; |
| 874 case Token::Value::BIT_XOR: |
| 875 return Bytecode::kBitwiseXor; |
| 876 case Token::Value::BIT_AND: |
| 877 return Bytecode::kBitwiseAnd; |
| 878 case Token::Value::SHL: |
| 879 return Bytecode::kShiftLeft; |
| 880 case Token::Value::SAR: |
| 881 return Bytecode::kShiftRight; |
| 882 case Token::Value::SHR: |
| 883 return Bytecode::kShiftRightLogical; |
| 884 default: |
| 885 UNREACHABLE(); |
| 886 return Bytecode::kIllegal; |
| 887 } |
| 888 } |
| 889 |
| 890 // static |
| 891 Bytecode BytecodeArrayBuilder::BytecodeForCountOperation(Token::Value op) { |
| 892 switch (op) { |
| 893 case Token::Value::ADD: |
| 894 return Bytecode::kInc; |
| 895 case Token::Value::SUB: |
| 896 return Bytecode::kDec; |
| 897 default: |
| 898 UNREACHABLE(); |
| 899 return Bytecode::kIllegal; |
| 900 } |
| 901 } |
| 902 |
| 903 // static |
| 904 Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) { |
| 905 switch (op) { |
| 906 case Token::Value::EQ: |
| 907 return Bytecode::kTestEqual; |
| 908 case Token::Value::NE: |
| 909 return Bytecode::kTestNotEqual; |
| 910 case Token::Value::EQ_STRICT: |
| 911 return Bytecode::kTestEqualStrict; |
| 912 case Token::Value::LT: |
| 913 return Bytecode::kTestLessThan; |
| 914 case Token::Value::GT: |
| 915 return Bytecode::kTestGreaterThan; |
| 916 case Token::Value::LTE: |
| 917 return Bytecode::kTestLessThanOrEqual; |
| 918 case Token::Value::GTE: |
| 919 return Bytecode::kTestGreaterThanOrEqual; |
| 920 case Token::Value::INSTANCEOF: |
| 921 return Bytecode::kTestInstanceOf; |
| 922 case Token::Value::IN: |
| 923 return Bytecode::kTestIn; |
| 924 default: |
| 925 UNREACHABLE(); |
| 926 return Bytecode::kIllegal; |
| 927 } |
| 928 } |
| 929 |
| 930 // static |
| 931 Bytecode BytecodeArrayBuilder::BytecodeForStoreNamedProperty( |
| 932 LanguageMode language_mode) { |
| 933 switch (language_mode) { |
| 934 case SLOPPY: |
| 935 return Bytecode::kStaNamedPropertySloppy; |
| 936 case STRICT: |
| 937 return Bytecode::kStaNamedPropertyStrict; |
| 938 default: |
| 939 UNREACHABLE(); |
| 940 } |
| 941 return Bytecode::kIllegal; |
| 942 } |
| 943 |
| 944 // static |
| 945 Bytecode BytecodeArrayBuilder::BytecodeForStoreKeyedProperty( |
| 946 LanguageMode language_mode) { |
| 947 switch (language_mode) { |
| 948 case SLOPPY: |
| 949 return Bytecode::kStaKeyedPropertySloppy; |
| 950 case STRICT: |
| 951 return Bytecode::kStaKeyedPropertyStrict; |
| 952 default: |
| 953 UNREACHABLE(); |
| 954 } |
| 955 return Bytecode::kIllegal; |
| 956 } |
| 957 |
| 958 // static |
| 959 Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) { |
| 960 return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof |
| 961 : Bytecode::kLdaGlobal; |
| 962 } |
| 963 |
| 964 // static |
| 965 Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal( |
| 966 LanguageMode language_mode) { |
| 967 switch (language_mode) { |
| 968 case SLOPPY: |
| 969 return Bytecode::kStaGlobalSloppy; |
| 970 case STRICT: |
| 971 return Bytecode::kStaGlobalStrict; |
| 972 default: |
| 973 UNREACHABLE(); |
| 974 } |
| 975 return Bytecode::kIllegal; |
| 976 } |
| 977 |
| 978 // static |
| 979 Bytecode BytecodeArrayBuilder::BytecodeForStoreLookupSlot( |
| 980 LanguageMode language_mode) { |
| 981 switch (language_mode) { |
| 982 case SLOPPY: |
| 983 return Bytecode::kStaLookupSlotSloppy; |
| 984 case STRICT: |
| 985 return Bytecode::kStaLookupSlotStrict; |
| 986 default: |
| 987 UNREACHABLE(); |
| 988 } |
| 989 return Bytecode::kIllegal; |
| 990 } |
| 991 |
| 992 // static |
| 993 Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments( |
| 994 CreateArgumentsType type) { |
| 995 switch (type) { |
| 996 case CreateArgumentsType::kMappedArguments: |
| 997 return Bytecode::kCreateMappedArguments; |
| 998 case CreateArgumentsType::kUnmappedArguments: |
| 999 return Bytecode::kCreateUnmappedArguments; |
| 1000 case CreateArgumentsType::kRestParameter: |
| 1001 return Bytecode::kCreateRestParameter; |
| 1002 } |
| 1003 UNREACHABLE(); |
| 1004 return Bytecode::kIllegal; |
| 1005 } |
| 1006 |
| 1007 // static |
| 1008 Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) { |
| 1009 switch (language_mode) { |
| 1010 case SLOPPY: |
| 1011 return Bytecode::kDeletePropertySloppy; |
| 1012 case STRICT: |
| 1013 return Bytecode::kDeletePropertyStrict; |
| 1014 default: |
| 1015 UNREACHABLE(); |
| 1016 } |
| 1017 return Bytecode::kIllegal; |
| 1018 } |
| 1019 |
| 1020 // static |
| 1021 Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) { |
| 1022 switch (tail_call_mode) { |
| 1023 case TailCallMode::kDisallow: |
| 1024 return Bytecode::kCall; |
| 1025 case TailCallMode::kAllow: |
| 1026 return Bytecode::kTailCall; |
| 1027 default: |
| 1028 UNREACHABLE(); |
| 1029 } |
| 1030 return Bytecode::kIllegal; |
| 1031 } |
| 1032 |
941 } // namespace interpreter | 1033 } // namespace interpreter |
942 } // namespace internal | 1034 } // namespace internal |
943 } // namespace v8 | 1035 } // namespace v8 |
OLD | NEW |