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, fixed_register_count(), | 83 return pipeline_->ToBytecodeArray(isolate, |
| 84 fixed_and_temporary_register_count(), |
84 parameter_count(), handler_table); | 85 parameter_count(), handler_table); |
85 } | 86 } |
86 | 87 |
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 | |
113 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | 88 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
114 uint32_t operand1, uint32_t operand2, | 89 uint32_t operand1, uint32_t operand2, |
115 uint32_t operand3) { | 90 uint32_t operand3) { |
116 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3)); | 91 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3)); |
117 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3); | 92 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3, |
118 AttachSourceInfo(&node); | 93 &latest_source_info_); |
119 pipeline()->Write(&node); | 94 pipeline()->Write(&node); |
120 } | 95 } |
121 | 96 |
122 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | 97 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
123 uint32_t operand1, uint32_t operand2) { | 98 uint32_t operand1, uint32_t operand2) { |
124 DCHECK(OperandsAreValid(bytecode, 3, operand0, operand1, operand2)); | 99 DCHECK(OperandsAreValid(bytecode, 3, operand0, operand1, operand2)); |
125 BytecodeNode node(bytecode, operand0, operand1, operand2); | 100 BytecodeNode node(bytecode, operand0, operand1, operand2, |
126 AttachSourceInfo(&node); | 101 &latest_source_info_); |
127 pipeline()->Write(&node); | 102 pipeline()->Write(&node); |
128 } | 103 } |
129 | 104 |
130 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | 105 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
131 uint32_t operand1) { | 106 uint32_t operand1) { |
132 DCHECK(OperandsAreValid(bytecode, 2, operand0, operand1)); | 107 DCHECK(OperandsAreValid(bytecode, 2, operand0, operand1)); |
133 BytecodeNode node(bytecode, operand0, operand1); | 108 BytecodeNode node(bytecode, operand0, operand1, &latest_source_info_); |
134 AttachSourceInfo(&node); | |
135 pipeline()->Write(&node); | 109 pipeline()->Write(&node); |
136 } | 110 } |
137 | 111 |
138 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { | 112 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { |
139 DCHECK(OperandsAreValid(bytecode, 1, operand0)); | 113 DCHECK(OperandsAreValid(bytecode, 1, operand0)); |
140 BytecodeNode node(bytecode, operand0); | 114 BytecodeNode node(bytecode, operand0, &latest_source_info_); |
141 AttachSourceInfo(&node); | |
142 pipeline()->Write(&node); | 115 pipeline()->Write(&node); |
143 } | 116 } |
144 | 117 |
145 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 118 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
146 DCHECK(OperandsAreValid(bytecode, 0)); | 119 DCHECK(OperandsAreValid(bytecode, 0)); |
147 BytecodeNode node(bytecode); | 120 BytecodeNode node(bytecode, &latest_source_info_); |
148 AttachSourceInfo(&node); | |
149 pipeline()->Write(&node); | 121 pipeline()->Write(&node); |
150 } | 122 } |
151 | 123 |
| 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 |
152 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 137 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
153 Register reg, | 138 Register reg, |
154 int feedback_slot) { | 139 int feedback_slot) { |
155 Output(BytecodeForBinaryOperation(op), RegisterOperand(reg), | 140 switch (op) { |
156 UnsignedOperand(feedback_slot)); | 141 case Token::Value::ADD: |
| 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 } |
157 return *this; | 188 return *this; |
158 } | 189 } |
159 | 190 |
160 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, | 191 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, |
161 int feedback_slot) { | 192 int feedback_slot) { |
162 Output(BytecodeForCountOperation(op), UnsignedOperand(feedback_slot)); | 193 if (op == Token::Value::ADD) { |
| 194 Output(Bytecode::kInc, UnsignedOperand(feedback_slot)); |
| 195 } else { |
| 196 DCHECK_EQ(op, Token::Value::SUB); |
| 197 Output(Bytecode::kDec, UnsignedOperand(feedback_slot)); |
| 198 } |
163 return *this; | 199 return *this; |
164 } | 200 } |
165 | 201 |
166 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { | 202 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { |
167 Output(Bytecode::kToBooleanLogicalNot); | 203 Output(Bytecode::kToBooleanLogicalNot); |
168 return *this; | 204 return *this; |
169 } | 205 } |
170 | 206 |
171 | |
172 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { | 207 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { |
173 Output(Bytecode::kTypeOf); | 208 Output(Bytecode::kTypeOf); |
174 return *this; | 209 return *this; |
175 } | 210 } |
176 | 211 |
177 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( | 212 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( |
178 Token::Value op, Register reg, int feedback_slot) { | 213 Token::Value op, Register reg, int feedback_slot) { |
179 if (op == Token::INSTANCEOF || op == Token::IN) { | 214 switch (op) { |
180 Output(BytecodeForCompareOperation(op), RegisterOperand(reg)); | 215 case Token::Value::EQ: |
181 } else { | 216 Output(Bytecode::kTestEqual, RegisterOperand(reg), |
182 Output(BytecodeForCompareOperation(op), RegisterOperand(reg), | 217 UnsignedOperand(feedback_slot)); |
183 UnsignedOperand(feedback_slot)); | 218 break; |
| 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(); |
184 } | 251 } |
185 return *this; | 252 return *this; |
186 } | 253 } |
187 | 254 |
188 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry( | 255 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry( |
189 size_t entry) { | 256 size_t entry) { |
190 Output(Bytecode::kLdaConstant, UnsignedOperand(entry)); | 257 Output(Bytecode::kLdaConstant, UnsignedOperand(entry)); |
191 return *this; | 258 return *this; |
192 } | 259 } |
193 | 260 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 | 314 |
248 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, | 315 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, |
249 Register to) { | 316 Register to) { |
250 DCHECK(from != to); | 317 DCHECK(from != to); |
251 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to)); | 318 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to)); |
252 return *this; | 319 return *this; |
253 } | 320 } |
254 | 321 |
255 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int feedback_slot, | 322 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int feedback_slot, |
256 TypeofMode typeof_mode) { | 323 TypeofMode typeof_mode) { |
257 // TODO(rmcilroy): Potentially store typeof information in an | 324 if (typeof_mode == INSIDE_TYPEOF) { |
258 // operand rather than having extra bytecodes. | 325 Output(Bytecode::kLdaGlobalInsideTypeof, feedback_slot); |
259 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); | 326 } else { |
260 Output(bytecode, UnsignedOperand(feedback_slot)); | 327 DCHECK_EQ(typeof_mode, NOT_INSIDE_TYPEOF); |
| 328 Output(Bytecode::kLdaGlobal, UnsignedOperand(feedback_slot)); |
| 329 } |
261 return *this; | 330 return *this; |
262 } | 331 } |
263 | 332 |
264 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( | 333 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( |
265 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { | 334 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { |
266 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); | |
267 size_t name_index = GetConstantPoolEntry(name); | 335 size_t name_index = GetConstantPoolEntry(name); |
268 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | 336 if (language_mode == SLOPPY) { |
| 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 } |
269 return *this; | 344 return *this; |
270 } | 345 } |
271 | 346 |
272 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, | 347 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, |
273 int slot_index, | 348 int slot_index, |
274 int depth) { | 349 int depth) { |
275 Output(Bytecode::kLdaContextSlot, RegisterOperand(context), | 350 Output(Bytecode::kLdaContextSlot, RegisterOperand(context), |
276 UnsignedOperand(slot_index), UnsignedOperand(depth)); | 351 UnsignedOperand(slot_index), UnsignedOperand(depth)); |
277 return *this; | 352 return *this; |
278 } | 353 } |
279 | 354 |
280 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, | 355 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, |
281 int slot_index, | 356 int slot_index, |
282 int depth) { | 357 int depth) { |
283 Output(Bytecode::kStaContextSlot, RegisterOperand(context), | 358 Output(Bytecode::kStaContextSlot, RegisterOperand(context), |
284 UnsignedOperand(slot_index), UnsignedOperand(depth)); | 359 UnsignedOperand(slot_index), UnsignedOperand(depth)); |
285 return *this; | 360 return *this; |
286 } | 361 } |
287 | 362 |
288 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( | 363 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( |
289 const Handle<String> name, TypeofMode typeof_mode) { | 364 const Handle<String> name, TypeofMode typeof_mode) { |
290 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) | |
291 ? Bytecode::kLdaLookupSlotInsideTypeof | |
292 : Bytecode::kLdaLookupSlot; | |
293 size_t name_index = GetConstantPoolEntry(name); | 365 size_t name_index = GetConstantPoolEntry(name); |
294 Output(bytecode, UnsignedOperand(name_index)); | 366 if (typeof_mode == INSIDE_TYPEOF) { |
| 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 } |
295 return *this; | 372 return *this; |
296 } | 373 } |
297 | 374 |
298 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupContextSlot( | 375 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupContextSlot( |
299 const Handle<String> name, TypeofMode typeof_mode, int slot_index, | 376 const Handle<String> name, TypeofMode typeof_mode, int slot_index, |
300 int depth) { | 377 int depth) { |
301 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) | 378 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) |
302 ? Bytecode::kLdaLookupContextSlotInsideTypeof | 379 ? Bytecode::kLdaLookupContextSlotInsideTypeof |
303 : Bytecode::kLdaLookupContextSlot; | 380 : Bytecode::kLdaLookupContextSlot; |
304 size_t name_index = GetConstantPoolEntry(name); | 381 size_t name_index = GetConstantPoolEntry(name); |
305 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(slot_index), | 382 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(slot_index), |
306 UnsignedOperand(depth)); | 383 UnsignedOperand(depth)); |
307 return *this; | 384 return *this; |
308 } | 385 } |
309 | 386 |
310 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupGlobalSlot( | 387 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupGlobalSlot( |
311 const Handle<String> name, TypeofMode typeof_mode, int feedback_slot, | 388 const Handle<String> name, TypeofMode typeof_mode, int feedback_slot, |
312 int depth) { | 389 int depth) { |
313 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) | 390 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) |
314 ? Bytecode::kLdaLookupGlobalSlotInsideTypeof | 391 ? Bytecode::kLdaLookupGlobalSlotInsideTypeof |
315 : Bytecode::kLdaLookupGlobalSlot; | 392 : Bytecode::kLdaLookupGlobalSlot; |
316 size_t name_index = GetConstantPoolEntry(name); | 393 size_t name_index = GetConstantPoolEntry(name); |
317 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot), | 394 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot), |
318 UnsignedOperand(depth)); | 395 UnsignedOperand(depth)); |
319 return *this; | 396 return *this; |
320 } | 397 } |
321 | 398 |
322 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( | 399 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( |
323 const Handle<String> name, LanguageMode language_mode) { | 400 const Handle<String> name, LanguageMode language_mode) { |
324 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode); | |
325 size_t name_index = GetConstantPoolEntry(name); | 401 size_t name_index = GetConstantPoolEntry(name); |
326 Output(bytecode, UnsignedOperand(name_index)); | 402 if (language_mode == SLOPPY) { |
| 403 Output(Bytecode::kStaLookupSlotSloppy, UnsignedOperand(name_index)); |
| 404 } else { |
| 405 DCHECK_EQ(language_mode, STRICT); |
| 406 Output(Bytecode::kStaLookupSlotStrict, UnsignedOperand(name_index)); |
| 407 } |
327 return *this; | 408 return *this; |
328 } | 409 } |
329 | 410 |
330 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( | 411 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( |
331 Register object, const Handle<Name> name, int feedback_slot) { | 412 Register object, const Handle<Name> name, int feedback_slot) { |
332 size_t name_index = GetConstantPoolEntry(name); | 413 size_t name_index = GetConstantPoolEntry(name); |
333 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object), | 414 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object), |
334 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | 415 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
335 return *this; | 416 return *this; |
336 } | 417 } |
337 | 418 |
338 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( | 419 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( |
339 Register object, int feedback_slot) { | 420 Register object, int feedback_slot) { |
340 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object), | 421 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object), |
341 UnsignedOperand(feedback_slot)); | 422 UnsignedOperand(feedback_slot)); |
342 return *this; | 423 return *this; |
343 } | 424 } |
344 | 425 |
345 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( | 426 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( |
346 Register object, const Handle<Name> name, int feedback_slot, | 427 Register object, const Handle<Name> name, int feedback_slot, |
347 LanguageMode language_mode) { | 428 LanguageMode language_mode) { |
348 Bytecode bytecode = BytecodeForStoreNamedProperty(language_mode); | |
349 size_t name_index = GetConstantPoolEntry(name); | 429 size_t name_index = GetConstantPoolEntry(name); |
350 Output(bytecode, RegisterOperand(object), UnsignedOperand(name_index), | 430 if (language_mode == SLOPPY) { |
351 UnsignedOperand(feedback_slot)); | 431 Output(Bytecode::kStaNamedPropertySloppy, RegisterOperand(object), |
| 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 } |
352 return *this; | 438 return *this; |
353 } | 439 } |
354 | 440 |
355 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( | 441 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( |
356 Register object, Register key, int feedback_slot, | 442 Register object, Register key, int feedback_slot, |
357 LanguageMode language_mode) { | 443 LanguageMode language_mode) { |
358 Bytecode bytecode = BytecodeForStoreKeyedProperty(language_mode); | 444 if (language_mode == SLOPPY) { |
359 Output(bytecode, RegisterOperand(object), RegisterOperand(key), | 445 Output(Bytecode::kStaKeyedPropertySloppy, RegisterOperand(object), |
360 UnsignedOperand(feedback_slot)); | 446 RegisterOperand(key), UnsignedOperand(feedback_slot)); |
| 447 } else { |
| 448 DCHECK_EQ(language_mode, STRICT); |
| 449 Output(Bytecode::kStaKeyedPropertyStrict, RegisterOperand(object), |
| 450 RegisterOperand(key), UnsignedOperand(feedback_slot)); |
| 451 } |
361 return *this; | 452 return *this; |
362 } | 453 } |
363 | 454 |
364 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry, | 455 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry, |
365 int flags) { | 456 int flags) { |
366 Output(Bytecode::kCreateClosure, UnsignedOperand(entry), | 457 Output(Bytecode::kCreateClosure, UnsignedOperand(entry), |
367 UnsignedOperand(flags)); | 458 UnsignedOperand(flags)); |
368 return *this; | 459 return *this; |
369 } | 460 } |
370 | 461 |
(...skipping 21 matching lines...) Expand all Loading... |
392 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext( | 483 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext( |
393 Register object, Handle<ScopeInfo> scope_info) { | 484 Register object, Handle<ScopeInfo> scope_info) { |
394 size_t scope_info_index = GetConstantPoolEntry(scope_info); | 485 size_t scope_info_index = GetConstantPoolEntry(scope_info); |
395 Output(Bytecode::kCreateWithContext, RegisterOperand(object), | 486 Output(Bytecode::kCreateWithContext, RegisterOperand(object), |
396 UnsignedOperand(scope_info_index)); | 487 UnsignedOperand(scope_info_index)); |
397 return *this; | 488 return *this; |
398 } | 489 } |
399 | 490 |
400 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( | 491 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( |
401 CreateArgumentsType type) { | 492 CreateArgumentsType type) { |
402 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather | 493 switch (type) { |
403 // than having two different bytecodes once we have better support for | 494 case CreateArgumentsType::kMappedArguments: |
404 // branches in the InterpreterAssembler. | 495 Output(Bytecode::kCreateMappedArguments); |
405 Bytecode bytecode = BytecodeForCreateArguments(type); | 496 break; |
406 Output(bytecode); | 497 case CreateArgumentsType::kUnmappedArguments: |
| 498 Output(Bytecode::kCreateUnmappedArguments); |
| 499 break; |
| 500 case CreateArgumentsType::kRestParameter: |
| 501 Output(Bytecode::kCreateRestParameter); |
| 502 break; |
| 503 default: |
| 504 UNREACHABLE(); |
| 505 } |
407 return *this; | 506 return *this; |
408 } | 507 } |
409 | 508 |
410 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( | 509 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( |
411 Handle<String> pattern, int literal_index, int flags) { | 510 Handle<String> pattern, int literal_index, int flags) { |
412 size_t pattern_entry = GetConstantPoolEntry(pattern); | 511 size_t pattern_entry = GetConstantPoolEntry(pattern); |
413 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry), | 512 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry), |
414 UnsignedOperand(literal_index), UnsignedOperand(flags)); | 513 UnsignedOperand(literal_index), UnsignedOperand(flags)); |
415 return *this; | 514 return *this; |
416 } | 515 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 return *this; | 568 return *this; |
470 } | 569 } |
471 | 570 |
472 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, | 571 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, |
473 BytecodeLabel* label) { | 572 BytecodeLabel* label) { |
474 pipeline_->BindLabel(target, label); | 573 pipeline_->BindLabel(target, label); |
475 LeaveBasicBlock(); | 574 LeaveBasicBlock(); |
476 return *this; | 575 return *this; |
477 } | 576 } |
478 | 577 |
479 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(BytecodeNode* node, | |
480 BytecodeLabel* label) { | |
481 AttachSourceInfo(node); | |
482 pipeline_->WriteJump(node, label); | |
483 LeaveBasicBlock(); | |
484 return *this; | |
485 } | |
486 | |
487 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { | 578 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { |
488 BytecodeNode node(Bytecode::kJump, 0); | 579 OutputJump(Bytecode::kJump, label); |
489 return OutputJump(&node, label); | 580 return *this; |
490 } | 581 } |
491 | 582 |
492 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { | 583 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { |
493 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue | 584 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue |
494 // to JumpIfTrue. | 585 // to JumpIfTrue. |
495 BytecodeNode node(Bytecode::kJumpIfToBooleanTrue, 0); | 586 OutputJump(Bytecode::kJumpIfToBooleanTrue, label); |
496 return OutputJump(&node, label); | 587 return *this; |
497 } | 588 } |
498 | 589 |
499 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { | 590 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { |
500 // The peephole optimizer attempts to simplify JumpIfToBooleanFalse | 591 OutputJump(Bytecode::kJumpIfToBooleanFalse, label); |
501 // to JumpIfFalse. | 592 return *this; |
502 BytecodeNode node(Bytecode::kJumpIfToBooleanFalse, 0); | |
503 return OutputJump(&node, label); | |
504 } | 593 } |
505 | 594 |
506 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { | 595 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { |
507 BytecodeNode node(Bytecode::kJumpIfNull, 0); | 596 OutputJump(Bytecode::kJumpIfNull, label); |
508 return OutputJump(&node, label); | 597 return *this; |
509 } | 598 } |
510 | 599 |
511 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( | 600 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( |
512 BytecodeLabel* label) { | 601 BytecodeLabel* label) { |
513 BytecodeNode node(Bytecode::kJumpIfUndefined, 0); | 602 OutputJump(Bytecode::kJumpIfUndefined, label); |
514 return OutputJump(&node, label); | 603 return *this; |
515 } | 604 } |
516 | 605 |
517 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( | 606 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( |
518 BytecodeLabel* label) { | 607 BytecodeLabel* label) { |
519 BytecodeNode node(Bytecode::kJumpIfNotHole, 0); | 608 OutputJump(Bytecode::kJumpIfNotHole, label); |
520 return OutputJump(&node, label); | 609 return *this; |
521 } | 610 } |
522 | 611 |
523 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label, | 612 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label, |
524 int loop_depth) { | 613 int loop_depth) { |
525 BytecodeNode node(Bytecode::kJumpLoop, 0, UnsignedOperand(loop_depth)); | 614 OutputJump(Bytecode::kJumpLoop, UnsignedOperand(loop_depth), label); |
526 return OutputJump(&node, label); | 615 return *this; |
527 } | 616 } |
528 | 617 |
529 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { | 618 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { |
530 if (position != kNoSourcePosition) { | 619 if (position != kNoSourcePosition) { |
531 // We need to attach a non-breakable source position to a stack | 620 // We need to attach a non-breakable source position to a stack |
532 // check, so we simply add it as expression position. There can be | 621 // check, so we simply add it as expression position. There can be |
533 // a prior statement position from constructs like: | 622 // a prior statement position from constructs like: |
534 // | 623 // |
535 // do var x; while (false); | 624 // do var x; while (false); |
536 // | 625 // |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 Return(); | 726 Return(); |
638 } | 727 } |
639 DCHECK(return_seen_in_block_); | 728 DCHECK(return_seen_in_block_); |
640 } | 729 } |
641 | 730 |
642 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, | 731 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, |
643 Register receiver_args, | 732 Register receiver_args, |
644 size_t receiver_args_count, | 733 size_t receiver_args_count, |
645 int feedback_slot, | 734 int feedback_slot, |
646 TailCallMode tail_call_mode) { | 735 TailCallMode tail_call_mode) { |
647 Bytecode bytecode = BytecodeForCall(tail_call_mode); | 736 if (tail_call_mode == TailCallMode::kDisallow) { |
648 Output(bytecode, RegisterOperand(callable), RegisterOperand(receiver_args), | 737 Output(Bytecode::kCall, RegisterOperand(callable), |
649 UnsignedOperand(receiver_args_count), UnsignedOperand(feedback_slot)); | 738 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count), |
| 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 } |
650 return *this; | 746 return *this; |
651 } | 747 } |
652 | 748 |
653 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, | 749 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, |
654 Register first_arg, | 750 Register first_arg, |
655 size_t arg_count, | 751 size_t arg_count, |
656 int feedback_slot_id) { | 752 int feedback_slot_id) { |
657 if (!first_arg.is_valid()) { | 753 if (!first_arg.is_valid()) { |
658 DCHECK_EQ(0u, arg_count); | 754 DCHECK_EQ(0u, arg_count); |
659 first_arg = Register(0); | 755 first_arg = Register(0); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 | 798 |
703 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( | 799 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( |
704 int context_index, Register receiver_args, size_t receiver_args_count) { | 800 int context_index, Register receiver_args, size_t receiver_args_count) { |
705 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index), | 801 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index), |
706 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count)); | 802 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count)); |
707 return *this; | 803 return *this; |
708 } | 804 } |
709 | 805 |
710 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, | 806 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, |
711 LanguageMode language_mode) { | 807 LanguageMode language_mode) { |
712 Output(BytecodeForDelete(language_mode), RegisterOperand(object)); | 808 if (language_mode == SLOPPY) { |
| 809 Output(Bytecode::kDeletePropertySloppy, RegisterOperand(object)); |
| 810 } else { |
| 811 DCHECK_EQ(language_mode, STRICT); |
| 812 Output(Bytecode::kDeletePropertyStrict, RegisterOperand(object)); |
| 813 } |
713 return *this; | 814 return *this; |
714 } | 815 } |
715 | 816 |
716 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 817 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
717 return constant_array_builder()->Insert(object); | 818 return constant_array_builder()->Insert(object); |
718 } | 819 } |
719 | 820 |
720 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() { | 821 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() { |
721 return constant_array_builder()->AllocateEntry(); | 822 return constant_array_builder()->AllocateEntry(); |
722 } | 823 } |
723 | 824 |
724 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry, | 825 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry, |
725 Handle<Object> object) { | 826 Handle<Object> object) { |
726 constant_array_builder()->InsertAllocatedEntry(entry, object); | 827 constant_array_builder()->InsertAllocatedEntry(entry, object); |
727 } | 828 } |
728 | 829 |
729 void BytecodeArrayBuilder::SetReturnPosition() { | 830 void BytecodeArrayBuilder::SetReturnPosition() { |
730 if (return_position_ == kNoSourcePosition) return; | 831 if (return_position_ == kNoSourcePosition) return; |
731 latest_source_info_.MakeStatementPosition(return_position_); | 832 latest_source_info_.MakeStatementPosition(return_position_); |
732 } | 833 } |
733 | 834 |
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 | |
753 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 835 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { |
754 return temporary_register_allocator()->RegisterIsLive(reg); | 836 return temporary_register_allocator()->RegisterIsLive(reg); |
755 } | 837 } |
756 | 838 |
757 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { | 839 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { |
758 if (!reg.is_valid()) { | 840 if (!reg.is_valid()) { |
759 return false; | 841 return false; |
760 } | 842 } |
761 | 843 |
762 if (reg.is_current_context() || reg.is_function_closure() || | 844 if (reg.is_current_context() || reg.is_function_closure() || |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 } | 888 } |
807 break; | 889 break; |
808 case OperandType::kRuntimeId: | 890 case OperandType::kRuntimeId: |
809 if (Bytecodes::SizeForUnsignedOperand(operands[i]) > | 891 if (Bytecodes::SizeForUnsignedOperand(operands[i]) > |
810 OperandSize::kShort) { | 892 OperandSize::kShort) { |
811 return false; | 893 return false; |
812 } | 894 } |
813 break; | 895 break; |
814 case OperandType::kIdx: | 896 case OperandType::kIdx: |
815 // TODO(leszeks): Possibly split this up into constant pool indices and | 897 // TODO(leszeks): Possibly split this up into constant pool indices and |
816 // other indices, for checking | 898 // other indices, for checking. |
817 break; | 899 break; |
818 case OperandType::kUImm: | 900 case OperandType::kUImm: |
819 case OperandType::kImm: | 901 case OperandType::kImm: |
820 break; | 902 break; |
821 case OperandType::kMaybeReg: | 903 case OperandType::kMaybeReg: |
822 if (Register::FromOperand(operands[i]) == Register(0)) { | 904 if (Register::FromOperand(operands[i]) == Register(0)) { |
823 break; | 905 break; |
824 } | 906 } |
825 // Fall-through to kReg case. | 907 // Fall-through to kReg case. |
826 case OperandType::kReg: | 908 case OperandType::kReg: |
(...skipping 22 matching lines...) Expand all Loading... |
849 return false; | 931 return false; |
850 } | 932 } |
851 break; | 933 break; |
852 } | 934 } |
853 } | 935 } |
854 } | 936 } |
855 | 937 |
856 return true; | 938 return true; |
857 } | 939 } |
858 | 940 |
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 | |
1033 } // namespace interpreter | 941 } // namespace interpreter |
1034 } // namespace internal | 942 } // namespace internal |
1035 } // namespace v8 | 943 } // namespace v8 |
OLD | NEW |