Chromium Code Reviews| 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, | |
| 125 BytecodeLabel* label) { | |
| 126 BytecodeNode node(bytecode, 0, &latest_source_info_); | |
| 127 pipeline_->WriteJump(&node, label); | |
| 128 LeaveBasicBlock(); | |
| 129 } | |
| 130 | |
| 131 void BytecodeArrayBuilder::OutputJump(Bytecode bytecode, | |
| 132 uint32_t operand0, BytecodeLabel* label) { | |
| 133 BytecodeNode node(bytecode, 0, operand0, &latest_source_info_); | |
| 134 pipeline_->WriteJump(&node, label); | |
| 135 LeaveBasicBlock(); | |
| 136 } | |
| 137 | |
| 152 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 138 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 
| 153 Register reg, | 139 Register reg, | 
| 154 int feedback_slot) { | 140 int feedback_slot) { | 
| 155 Output(BytecodeForBinaryOperation(op), RegisterOperand(reg), | 141 switch (op) { | 
| 156 UnsignedOperand(feedback_slot)); | 142 case Token::Value::ADD: | 
| 143 Output(Bytecode::kAdd, RegisterOperand(reg), | |
| 144 UnsignedOperand(feedback_slot)); | |
| 145 break; | |
| 146 case Token::Value::SUB: | |
| 147 Output(Bytecode::kSub, RegisterOperand(reg), | |
| 148 UnsignedOperand(feedback_slot)); | |
| 149 break; | |
| 150 case Token::Value::MUL: | |
| 151 Output(Bytecode::kMul, RegisterOperand(reg), | |
| 152 UnsignedOperand(feedback_slot)); | |
| 153 break; | |
| 154 case Token::Value::DIV: | |
| 155 Output(Bytecode::kDiv, RegisterOperand(reg), | |
| 156 UnsignedOperand(feedback_slot)); | |
| 157 break; | |
| 158 case Token::Value::MOD: | |
| 159 Output(Bytecode::kMod, RegisterOperand(reg), | |
| 160 UnsignedOperand(feedback_slot)); | |
| 161 break; | |
| 162 case Token::Value::BIT_OR: | |
| 163 Output(Bytecode::kBitwiseOr, RegisterOperand(reg), | |
| 164 UnsignedOperand(feedback_slot)); | |
| 165 break; | |
| 166 case Token::Value::BIT_XOR: | |
| 167 Output(Bytecode::kBitwiseXor, RegisterOperand(reg), | |
| 168 UnsignedOperand(feedback_slot)); | |
| 169 break; | |
| 170 case Token::Value::BIT_AND: | |
| 171 Output(Bytecode::kBitwiseAnd, RegisterOperand(reg), | |
| 172 UnsignedOperand(feedback_slot)); | |
| 173 break; | |
| 174 case Token::Value::SHL: | |
| 175 Output(Bytecode::kShiftLeft, RegisterOperand(reg), | |
| 176 UnsignedOperand(feedback_slot)); | |
| 177 break; | |
| 178 case Token::Value::SAR: | |
| 179 Output(Bytecode::kShiftRight, RegisterOperand(reg), | |
| 180 UnsignedOperand(feedback_slot)); | |
| 181 break; | |
| 182 case Token::Value::SHR: | |
| 183 Output(Bytecode::kShiftRightLogical, RegisterOperand(reg), | |
| 184 UnsignedOperand(feedback_slot)); | |
| 185 break; | |
| 186 default: | |
| 187 UNREACHABLE(); | |
| 188 } | |
| 157 return *this; | 189 return *this; | 
| 158 } | 190 } | 
| 159 | 191 | 
| 160 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, | 192 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, | 
| 161 int feedback_slot) { | 193 int feedback_slot) { | 
| 162 Output(BytecodeForCountOperation(op), UnsignedOperand(feedback_slot)); | 194 if (op == Token::Value::ADD) { | 
| 195 Output(Bytecode::kInc, UnsignedOperand(feedback_slot)); | |
| 196 } else { | |
| 197 DCHECK_EQ(op, Token::Value::SUB); | |
| 198 Output(Bytecode::kDec, UnsignedOperand(feedback_slot)); | |
| 199 } | |
| 163 return *this; | 200 return *this; | 
| 164 } | 201 } | 
| 165 | 202 | 
| 166 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { | 203 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { | 
| 167 Output(Bytecode::kToBooleanLogicalNot); | 204 Output(Bytecode::kToBooleanLogicalNot); | 
| 168 return *this; | 205 return *this; | 
| 169 } | 206 } | 
| 170 | 207 | 
| 171 | |
| 172 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { | 208 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { | 
| 173 Output(Bytecode::kTypeOf); | 209 Output(Bytecode::kTypeOf); | 
| 174 return *this; | 210 return *this; | 
| 175 } | 211 } | 
| 176 | 212 | 
| 177 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( | 213 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( | 
| 178 Token::Value op, Register reg, int feedback_slot) { | 214 Token::Value op, Register reg, int feedback_slot) { | 
| 179 if (op == Token::INSTANCEOF || op == Token::IN) { | 215 switch (op) { | 
| 180 Output(BytecodeForCompareOperation(op), RegisterOperand(reg)); | 216 case Token::Value::EQ: | 
| 181 } else { | 217 Output(Bytecode::kTestEqual, RegisterOperand(reg), | 
| 182 Output(BytecodeForCompareOperation(op), RegisterOperand(reg), | 218 UnsignedOperand(feedback_slot)); | 
| 183 UnsignedOperand(feedback_slot)); | 219 break; | 
| 220 case Token::Value::NE: | |
| 221 Output(Bytecode::kTestNotEqual, RegisterOperand(reg), | |
| 222 UnsignedOperand(feedback_slot)); | |
| 223 break; | |
| 224 case Token::Value::EQ_STRICT: | |
| 225 Output(Bytecode::kTestEqualStrict, RegisterOperand(reg), | |
| 226 UnsignedOperand(feedback_slot)); | |
| 227 break; | |
| 228 case Token::Value::LT: | |
| 229 Output(Bytecode::kTestLessThan, RegisterOperand(reg), | |
| 230 UnsignedOperand(feedback_slot)); | |
| 231 break; | |
| 232 case Token::Value::GT: | |
| 233 Output(Bytecode::kTestGreaterThan, RegisterOperand(reg), | |
| 234 UnsignedOperand(feedback_slot)); | |
| 235 break; | |
| 236 case Token::Value::LTE: | |
| 237 Output(Bytecode::kTestLessThanOrEqual, RegisterOperand(reg), | |
| 238 UnsignedOperand(feedback_slot)); | |
| 239 break; | |
| 240 case Token::Value::GTE: | |
| 241 Output(Bytecode::kTestGreaterThanOrEqual, RegisterOperand(reg), | |
| 242 UnsignedOperand(feedback_slot)); | |
| 243 break; | |
| 244 case Token::Value::INSTANCEOF: | |
| 245 Output(Bytecode::kTestInstanceOf, RegisterOperand(reg)); | |
| 246 break; | |
| 247 case Token::Value::IN: | |
| 248 Output(Bytecode::kTestIn, RegisterOperand(reg)); | |
| 249 break; | |
| 250 default: | |
| 251 UNREACHABLE(); | |
| 184 } | 252 } | 
| 185 return *this; | 253 return *this; | 
| 186 } | 254 } | 
| 187 | 255 | 
| 188 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry( | 256 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry( | 
| 189 size_t entry) { | 257 size_t entry) { | 
| 190 Output(Bytecode::kLdaConstant, UnsignedOperand(entry)); | 258 Output(Bytecode::kLdaConstant, UnsignedOperand(entry)); | 
| 191 return *this; | 259 return *this; | 
| 192 } | 260 } | 
| 193 | 261 | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 | 315 | 
| 248 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, | 316 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, | 
| 249 Register to) { | 317 Register to) { | 
| 250 DCHECK(from != to); | 318 DCHECK(from != to); | 
| 251 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to)); | 319 Output(Bytecode::kMov, RegisterOperand(from), RegisterOperand(to)); | 
| 252 return *this; | 320 return *this; | 
| 253 } | 321 } | 
| 254 | 322 | 
| 255 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int feedback_slot, | 323 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int feedback_slot, | 
| 256 TypeofMode typeof_mode) { | 324 TypeofMode typeof_mode) { | 
| 257 // TODO(rmcilroy): Potentially store typeof information in an | 325 if (typeof_mode == INSIDE_TYPEOF) { | 
| 258 // operand rather than having extra bytecodes. | 326 Output(Bytecode::kLdaGlobalInsideTypeof, feedback_slot); | 
| 259 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); | 327 } else { | 
| 260 Output(bytecode, UnsignedOperand(feedback_slot)); | 328 DCHECK_EQ(typeof_mode, NOT_INSIDE_TYPEOF); | 
| 329 Output(Bytecode::kLdaGlobal, UnsignedOperand(feedback_slot)); | |
| 330 } | |
| 261 return *this; | 331 return *this; | 
| 262 } | 332 } | 
| 263 | 333 | 
| 264 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( | 334 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( | 
| 265 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { | 335 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { | 
| 266 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); | |
| 267 size_t name_index = GetConstantPoolEntry(name); | 336 size_t name_index = GetConstantPoolEntry(name); | 
| 268 Output(bytecode, UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | 337 if (language_mode == SLOPPY) { | 
| 338 Output(Bytecode::kStaGlobalSloppy, UnsignedOperand(name_index), | |
| 339 UnsignedOperand(feedback_slot)); | |
| 340 } else { | |
| 341 DCHECK_EQ(language_mode, STRICT); | |
| 342 Output(Bytecode::kStaGlobalStrict, UnsignedOperand(name_index), | |
| 343 UnsignedOperand(feedback_slot)); | |
| 344 } | |
| 269 return *this; | 345 return *this; | 
| 270 } | 346 } | 
| 271 | 347 | 
| 272 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, | 348 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, | 
| 273 int slot_index, | 349 int slot_index, | 
| 274 int depth) { | 350 int depth) { | 
| 275 Output(Bytecode::kLdaContextSlot, RegisterOperand(context), | 351 Output(Bytecode::kLdaContextSlot, RegisterOperand(context), | 
| 276 UnsignedOperand(slot_index), UnsignedOperand(depth)); | 352 UnsignedOperand(slot_index), UnsignedOperand(depth)); | 
| 277 return *this; | 353 return *this; | 
| 278 } | 354 } | 
| 279 | 355 | 
| 280 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, | 356 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, | 
| 281 int slot_index, | 357 int slot_index, | 
| 282 int depth) { | 358 int depth) { | 
| 283 Output(Bytecode::kStaContextSlot, RegisterOperand(context), | 359 Output(Bytecode::kStaContextSlot, RegisterOperand(context), | 
| 284 UnsignedOperand(slot_index), UnsignedOperand(depth)); | 360 UnsignedOperand(slot_index), UnsignedOperand(depth)); | 
| 285 return *this; | 361 return *this; | 
| 286 } | 362 } | 
| 287 | 363 | 
| 288 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( | 364 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( | 
| 289 const Handle<String> name, TypeofMode typeof_mode) { | 365 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); | 366 size_t name_index = GetConstantPoolEntry(name); | 
| 294 Output(bytecode, UnsignedOperand(name_index)); | 367 if (typeof_mode == INSIDE_TYPEOF) { | 
| 368 Output(Bytecode::kLdaLookupSlotInsideTypeof, UnsignedOperand(name_index)); | |
| 369 } else { | |
| 370 DCHECK_EQ(typeof_mode, NOT_INSIDE_TYPEOF); | |
| 371 Output(Bytecode::kLdaLookupSlot, UnsignedOperand(name_index)); | |
| 372 } | |
| 295 return *this; | 373 return *this; | 
| 296 } | 374 } | 
| 297 | 375 | 
| 298 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( | 376 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( | 
| 299 const Handle<String> name, LanguageMode language_mode) { | 377 const Handle<String> name, LanguageMode language_mode) { | 
| 300 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode); | |
| 301 size_t name_index = GetConstantPoolEntry(name); | 378 size_t name_index = GetConstantPoolEntry(name); | 
| 302 Output(bytecode, UnsignedOperand(name_index)); | 379 if (language_mode == SLOPPY) { | 
| 380 Output(Bytecode::kStaLookupSlotSloppy, UnsignedOperand(name_index)); | |
| 381 } else { | |
| 
 
Leszek Swirski
2016/09/20 10:37:56
DCHECK for strict
 
rmcilroy
2016/09/20 16:57:25
Done.
 
 | |
| 382 Output(Bytecode::kStaLookupSlotStrict, UnsignedOperand(name_index)); | |
| 383 } | |
| 303 return *this; | 384 return *this; | 
| 304 } | 385 } | 
| 305 | 386 | 
| 306 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( | 387 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( | 
| 307 Register object, const Handle<Name> name, int feedback_slot) { | 388 Register object, const Handle<Name> name, int feedback_slot) { | 
| 308 size_t name_index = GetConstantPoolEntry(name); | 389 size_t name_index = GetConstantPoolEntry(name); | 
| 309 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object), | 390 Output(Bytecode::kLdaNamedProperty, RegisterOperand(object), | 
| 310 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | 391 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | 
| 311 return *this; | 392 return *this; | 
| 312 } | 393 } | 
| 313 | 394 | 
| 314 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( | 395 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( | 
| 315 Register object, int feedback_slot) { | 396 Register object, int feedback_slot) { | 
| 316 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object), | 397 Output(Bytecode::kLdaKeyedProperty, RegisterOperand(object), | 
| 317 UnsignedOperand(feedback_slot)); | 398 UnsignedOperand(feedback_slot)); | 
| 318 return *this; | 399 return *this; | 
| 319 } | 400 } | 
| 320 | 401 | 
| 321 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( | 402 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( | 
| 322 Register object, const Handle<Name> name, int feedback_slot, | 403 Register object, const Handle<Name> name, int feedback_slot, | 
| 323 LanguageMode language_mode) { | 404 LanguageMode language_mode) { | 
| 324 Bytecode bytecode = BytecodeForStoreNamedProperty(language_mode); | |
| 325 size_t name_index = GetConstantPoolEntry(name); | 405 size_t name_index = GetConstantPoolEntry(name); | 
| 326 Output(bytecode, RegisterOperand(object), UnsignedOperand(name_index), | 406 if (language_mode == SLOPPY) { | 
| 327 UnsignedOperand(feedback_slot)); | 407 Output(Bytecode::kStaNamedPropertySloppy, RegisterOperand(object), | 
| 408 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | |
| 409 } else { | |
| 410 DCHECK_EQ(language_mode, STRICT); | |
| 411 Output(Bytecode::kStaNamedPropertyStrict, RegisterOperand(object), | |
| 412 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | |
| 413 } | |
| 328 return *this; | 414 return *this; | 
| 329 } | 415 } | 
| 330 | 416 | 
| 331 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( | 417 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( | 
| 332 Register object, Register key, int feedback_slot, | 418 Register object, Register key, int feedback_slot, | 
| 333 LanguageMode language_mode) { | 419 LanguageMode language_mode) { | 
| 334 Bytecode bytecode = BytecodeForStoreKeyedProperty(language_mode); | 420 if (language_mode == SLOPPY) { | 
| 335 Output(bytecode, RegisterOperand(object), RegisterOperand(key), | 421 Output(Bytecode::kStaKeyedPropertySloppy, RegisterOperand(object), | 
| 336 UnsignedOperand(feedback_slot)); | 422 RegisterOperand(key), UnsignedOperand(feedback_slot)); | 
| 423 } else { | |
| 424 DCHECK_EQ(language_mode, STRICT); | |
| 425 Output(Bytecode::kStaKeyedPropertyStrict, RegisterOperand(object), | |
| 426 RegisterOperand(key), UnsignedOperand(feedback_slot)); | |
| 427 } | |
| 337 return *this; | 428 return *this; | 
| 338 } | 429 } | 
| 339 | 430 | 
| 340 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry, | 431 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry, | 
| 341 int flags) { | 432 int flags) { | 
| 342 Output(Bytecode::kCreateClosure, UnsignedOperand(entry), | 433 Output(Bytecode::kCreateClosure, UnsignedOperand(entry), | 
| 343 UnsignedOperand(flags)); | 434 UnsignedOperand(flags)); | 
| 344 return *this; | 435 return *this; | 
| 345 } | 436 } | 
| 346 | 437 | 
| (...skipping 21 matching lines...) Expand all Loading... | |
| 368 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext( | 459 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext( | 
| 369 Register object, Handle<ScopeInfo> scope_info) { | 460 Register object, Handle<ScopeInfo> scope_info) { | 
| 370 size_t scope_info_index = GetConstantPoolEntry(scope_info); | 461 size_t scope_info_index = GetConstantPoolEntry(scope_info); | 
| 371 Output(Bytecode::kCreateWithContext, RegisterOperand(object), | 462 Output(Bytecode::kCreateWithContext, RegisterOperand(object), | 
| 372 UnsignedOperand(scope_info_index)); | 463 UnsignedOperand(scope_info_index)); | 
| 373 return *this; | 464 return *this; | 
| 374 } | 465 } | 
| 375 | 466 | 
| 376 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( | 467 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( | 
| 377 CreateArgumentsType type) { | 468 CreateArgumentsType type) { | 
| 378 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather | 469 switch (type) { | 
| 379 // than having two different bytecodes once we have better support for | 470 case CreateArgumentsType::kMappedArguments: | 
| 380 // branches in the InterpreterAssembler. | 471 Output(Bytecode::kCreateMappedArguments); | 
| 381 Bytecode bytecode = BytecodeForCreateArguments(type); | 472 break; | 
| 382 Output(bytecode); | 473 case CreateArgumentsType::kUnmappedArguments: | 
| 474 Output(Bytecode::kCreateUnmappedArguments); | |
| 475 break; | |
| 476 case CreateArgumentsType::kRestParameter: | |
| 477 Output(Bytecode::kCreateRestParameter); | |
| 478 break; | |
| 479 default: | |
| 480 UNREACHABLE(); | |
| 481 } | |
| 383 return *this; | 482 return *this; | 
| 384 } | 483 } | 
| 385 | 484 | 
| 386 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( | 485 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( | 
| 387 Handle<String> pattern, int literal_index, int flags) { | 486 Handle<String> pattern, int literal_index, int flags) { | 
| 388 size_t pattern_entry = GetConstantPoolEntry(pattern); | 487 size_t pattern_entry = GetConstantPoolEntry(pattern); | 
| 389 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry), | 488 Output(Bytecode::kCreateRegExpLiteral, UnsignedOperand(pattern_entry), | 
| 390 UnsignedOperand(literal_index), UnsignedOperand(flags)); | 489 UnsignedOperand(literal_index), UnsignedOperand(flags)); | 
| 391 return *this; | 490 return *this; | 
| 392 } | 491 } | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 return *this; | 544 return *this; | 
| 446 } | 545 } | 
| 447 | 546 | 
| 448 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, | 547 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, | 
| 449 BytecodeLabel* label) { | 548 BytecodeLabel* label) { | 
| 450 pipeline_->BindLabel(target, label); | 549 pipeline_->BindLabel(target, label); | 
| 451 LeaveBasicBlock(); | 550 LeaveBasicBlock(); | 
| 452 return *this; | 551 return *this; | 
| 453 } | 552 } | 
| 454 | 553 | 
| 455 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(BytecodeNode* node, | |
| 456 BytecodeLabel* label) { | |
| 457 AttachSourceInfo(node); | |
| 458 pipeline_->WriteJump(node, label); | |
| 459 LeaveBasicBlock(); | |
| 460 return *this; | |
| 461 } | |
| 462 | |
| 463 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { | 554 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { | 
| 464 BytecodeNode node(Bytecode::kJump, 0); | 555 OutputJump(Bytecode::kJump, label); | 
| 465 return OutputJump(&node, label); | 556 return *this; | 
| 466 } | 557 } | 
| 467 | 558 | 
| 468 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { | 559 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { | 
| 469 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue | 560 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue | 
| 470 // to JumpIfTrue. | 561 // to JumpIfTrue. | 
| 471 BytecodeNode node(Bytecode::kJumpIfToBooleanTrue, 0); | 562 OutputJump(Bytecode::kJumpIfToBooleanTrue, label); | 
| 472 return OutputJump(&node, label); | 563 return *this; | 
| 473 } | 564 } | 
| 474 | 565 | 
| 475 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { | 566 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { | 
| 476 // The peephole optimizer attempts to simplify JumpIfToBooleanFalse | 567 OutputJump(Bytecode::kJumpIfToBooleanFalse, label); | 
| 477 // to JumpIfFalse. | 568 return *this; | 
| 478 BytecodeNode node(Bytecode::kJumpIfToBooleanFalse, 0); | |
| 479 return OutputJump(&node, label); | |
| 480 } | 569 } | 
| 481 | 570 | 
| 482 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { | 571 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { | 
| 483 BytecodeNode node(Bytecode::kJumpIfNull, 0); | 572 OutputJump(Bytecode::kJumpIfNull, label); | 
| 484 return OutputJump(&node, label); | 573 return *this; | 
| 485 } | 574 } | 
| 486 | 575 | 
| 487 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( | 576 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( | 
| 488 BytecodeLabel* label) { | 577 BytecodeLabel* label) { | 
| 489 BytecodeNode node(Bytecode::kJumpIfUndefined, 0); | 578 OutputJump(Bytecode::kJumpIfUndefined, label); | 
| 490 return OutputJump(&node, label); | 579 return *this; | 
| 491 } | 580 } | 
| 492 | 581 | 
| 493 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( | 582 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( | 
| 494 BytecodeLabel* label) { | 583 BytecodeLabel* label) { | 
| 495 BytecodeNode node(Bytecode::kJumpIfNotHole, 0); | 584 OutputJump(Bytecode::kJumpIfNotHole, label); | 
| 496 return OutputJump(&node, label); | 585 return *this; | 
| 497 } | 586 } | 
| 498 | 587 | 
| 499 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label, | 588 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label, | 
| 500 int loop_depth) { | 589 int loop_depth) { | 
| 501 BytecodeNode node(Bytecode::kJumpLoop, 0, UnsignedOperand(loop_depth)); | 590 OutputJump(Bytecode::kJumpLoop, UnsignedOperand(loop_depth), label); | 
| 502 return OutputJump(&node, label); | 591 return *this; | 
| 503 } | 592 } | 
| 504 | 593 | 
| 505 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { | 594 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { | 
| 506 if (position != kNoSourcePosition) { | 595 if (position != kNoSourcePosition) { | 
| 507 // We need to attach a non-breakable source position to a stack | 596 // We need to attach a non-breakable source position to a stack | 
| 508 // check, so we simply add it as expression position. There can be | 597 // check, so we simply add it as expression position. There can be | 
| 509 // a prior statement position from constructs like: | 598 // a prior statement position from constructs like: | 
| 510 // | 599 // | 
| 511 // do var x; while (false); | 600 // do var x; while (false); | 
| 512 // | 601 // | 
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 613 Return(); | 702 Return(); | 
| 614 } | 703 } | 
| 615 DCHECK(return_seen_in_block_); | 704 DCHECK(return_seen_in_block_); | 
| 616 } | 705 } | 
| 617 | 706 | 
| 618 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, | 707 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, | 
| 619 Register receiver_args, | 708 Register receiver_args, | 
| 620 size_t receiver_args_count, | 709 size_t receiver_args_count, | 
| 621 int feedback_slot, | 710 int feedback_slot, | 
| 622 TailCallMode tail_call_mode) { | 711 TailCallMode tail_call_mode) { | 
| 623 Bytecode bytecode = BytecodeForCall(tail_call_mode); | 712 if (tail_call_mode == TailCallMode::kDisallow) { | 
| 624 Output(bytecode, RegisterOperand(callable), RegisterOperand(receiver_args), | 713 Output(Bytecode::kCall, RegisterOperand(callable), | 
| 625 UnsignedOperand(receiver_args_count), UnsignedOperand(feedback_slot)); | 714 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count), | 
| 715 UnsignedOperand(feedback_slot)); | |
| 716 } else { | |
| 717 DCHECK(tail_call_mode == TailCallMode::kAllow); | |
| 718 Output(Bytecode::kTailCall, RegisterOperand(callable), | |
| 719 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count), | |
| 720 UnsignedOperand(feedback_slot)); | |
| 721 } | |
| 626 return *this; | 722 return *this; | 
| 627 } | 723 } | 
| 628 | 724 | 
| 629 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, | 725 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, | 
| 630 Register first_arg, | 726 Register first_arg, | 
| 631 size_t arg_count, | 727 size_t arg_count, | 
| 632 int feedback_slot_id) { | 728 int feedback_slot_id) { | 
| 633 if (!first_arg.is_valid()) { | 729 if (!first_arg.is_valid()) { | 
| 634 DCHECK_EQ(0u, arg_count); | 730 DCHECK_EQ(0u, arg_count); | 
| 635 first_arg = Register(0); | 731 first_arg = Register(0); | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 678 | 774 | 
| 679 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( | 775 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( | 
| 680 int context_index, Register receiver_args, size_t receiver_args_count) { | 776 int context_index, Register receiver_args, size_t receiver_args_count) { | 
| 681 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index), | 777 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index), | 
| 682 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count)); | 778 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count)); | 
| 683 return *this; | 779 return *this; | 
| 684 } | 780 } | 
| 685 | 781 | 
| 686 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, | 782 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, | 
| 687 LanguageMode language_mode) { | 783 LanguageMode language_mode) { | 
| 688 Output(BytecodeForDelete(language_mode), RegisterOperand(object)); | 784 if (language_mode == SLOPPY) { | 
| 785 Output(Bytecode::kDeletePropertySloppy, RegisterOperand(object)); | |
| 786 } else { | |
| 787 DCHECK_EQ(language_mode, STRICT); | |
| 788 Output(Bytecode::kDeletePropertyStrict, RegisterOperand(object)); | |
| 789 } | |
| 689 return *this; | 790 return *this; | 
| 690 } | 791 } | 
| 691 | 792 | 
| 692 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 793 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 
| 693 return constant_array_builder()->Insert(object); | 794 return constant_array_builder()->Insert(object); | 
| 694 } | 795 } | 
| 695 | 796 | 
| 696 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() { | 797 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() { | 
| 697 return constant_array_builder()->AllocateEntry(); | 798 return constant_array_builder()->AllocateEntry(); | 
| 698 } | 799 } | 
| 699 | 800 | 
| 700 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry, | 801 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry, | 
| 701 Handle<Object> object) { | 802 Handle<Object> object) { | 
| 702 constant_array_builder()->InsertAllocatedEntry(entry, object); | 803 constant_array_builder()->InsertAllocatedEntry(entry, object); | 
| 703 } | 804 } | 
| 704 | 805 | 
| 705 void BytecodeArrayBuilder::SetReturnPosition() { | 806 void BytecodeArrayBuilder::SetReturnPosition() { | 
| 706 if (return_position_ == kNoSourcePosition) return; | 807 if (return_position_ == kNoSourcePosition) return; | 
| 707 latest_source_info_.MakeStatementPosition(return_position_); | 808 latest_source_info_.MakeStatementPosition(return_position_); | 
| 708 } | 809 } | 
| 709 | 810 | 
| 710 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { | |
| 711 if (stmt->position() == kNoSourcePosition) return; | |
| 712 latest_source_info_.MakeStatementPosition(stmt->position()); | |
| 713 } | |
| 714 | |
| 715 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { | |
| 716 if (expr->position() == kNoSourcePosition) return; | |
| 717 if (!latest_source_info_.is_statement()) { | |
| 718 // Ensure the current expression position is overwritten with the | |
| 719 // latest value. | |
| 720 latest_source_info_.MakeExpressionPosition(expr->position()); | |
| 721 } | |
| 722 } | |
| 723 | |
| 724 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { | |
| 725 if (expr->position() == kNoSourcePosition) return; | |
| 726 latest_source_info_.MakeStatementPosition(expr->position()); | |
| 727 } | |
| 728 | |
| 729 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 811 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 
| 730 return temporary_register_allocator()->RegisterIsLive(reg); | 812 return temporary_register_allocator()->RegisterIsLive(reg); | 
| 731 } | 813 } | 
| 732 | 814 | 
| 733 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { | 815 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { | 
| 734 if (!reg.is_valid()) { | 816 if (!reg.is_valid()) { | 
| 735 return false; | 817 return false; | 
| 736 } | 818 } | 
| 737 | 819 | 
| 738 if (reg.is_current_context() || reg.is_function_closure() || | 820 if (reg.is_current_context() || reg.is_function_closure() || | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 782 } | 864 } | 
| 783 break; | 865 break; | 
| 784 case OperandType::kRuntimeId: | 866 case OperandType::kRuntimeId: | 
| 785 if (Bytecodes::SizeForUnsignedOperand(operands[i]) > | 867 if (Bytecodes::SizeForUnsignedOperand(operands[i]) > | 
| 786 OperandSize::kShort) { | 868 OperandSize::kShort) { | 
| 787 return false; | 869 return false; | 
| 788 } | 870 } | 
| 789 break; | 871 break; | 
| 790 case OperandType::kIdx: | 872 case OperandType::kIdx: | 
| 791 // TODO(leszeks): Possibly split this up into constant pool indices and | 873 // TODO(leszeks): Possibly split this up into constant pool indices and | 
| 792 // other indices, for checking | 874 // other indices, for checking. | 
| 793 break; | 875 break; | 
| 794 case OperandType::kUImm: | 876 case OperandType::kUImm: | 
| 795 case OperandType::kImm: | 877 case OperandType::kImm: | 
| 796 break; | 878 break; | 
| 797 case OperandType::kMaybeReg: | 879 case OperandType::kMaybeReg: | 
| 798 if (Register::FromOperand(operands[i]) == Register(0)) { | 880 if (Register::FromOperand(operands[i]) == Register(0)) { | 
| 799 break; | 881 break; | 
| 800 } | 882 } | 
| 801 // Fall-through to kReg case. | 883 // Fall-through to kReg case. | 
| 802 case OperandType::kReg: | 884 case OperandType::kReg: | 
| (...skipping 22 matching lines...) Expand all Loading... | |
| 825 return false; | 907 return false; | 
| 826 } | 908 } | 
| 827 break; | 909 break; | 
| 828 } | 910 } | 
| 829 } | 911 } | 
| 830 } | 912 } | 
| 831 | 913 | 
| 832 return true; | 914 return true; | 
| 833 } | 915 } | 
| 834 | 916 | 
| 835 // static | |
| 836 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { | |
| 837 switch (op) { | |
| 838 case Token::Value::ADD: | |
| 839 return Bytecode::kAdd; | |
| 840 case Token::Value::SUB: | |
| 841 return Bytecode::kSub; | |
| 842 case Token::Value::MUL: | |
| 843 return Bytecode::kMul; | |
| 844 case Token::Value::DIV: | |
| 845 return Bytecode::kDiv; | |
| 846 case Token::Value::MOD: | |
| 847 return Bytecode::kMod; | |
| 848 case Token::Value::BIT_OR: | |
| 849 return Bytecode::kBitwiseOr; | |
| 850 case Token::Value::BIT_XOR: | |
| 851 return Bytecode::kBitwiseXor; | |
| 852 case Token::Value::BIT_AND: | |
| 853 return Bytecode::kBitwiseAnd; | |
| 854 case Token::Value::SHL: | |
| 855 return Bytecode::kShiftLeft; | |
| 856 case Token::Value::SAR: | |
| 857 return Bytecode::kShiftRight; | |
| 858 case Token::Value::SHR: | |
| 859 return Bytecode::kShiftRightLogical; | |
| 860 default: | |
| 861 UNREACHABLE(); | |
| 862 return Bytecode::kIllegal; | |
| 863 } | |
| 864 } | |
| 865 | |
| 866 // static | |
| 867 Bytecode BytecodeArrayBuilder::BytecodeForCountOperation(Token::Value op) { | |
| 868 switch (op) { | |
| 869 case Token::Value::ADD: | |
| 870 return Bytecode::kInc; | |
| 871 case Token::Value::SUB: | |
| 872 return Bytecode::kDec; | |
| 873 default: | |
| 874 UNREACHABLE(); | |
| 875 return Bytecode::kIllegal; | |
| 876 } | |
| 877 } | |
| 878 | |
| 879 // static | |
| 880 Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) { | |
| 881 switch (op) { | |
| 882 case Token::Value::EQ: | |
| 883 return Bytecode::kTestEqual; | |
| 884 case Token::Value::NE: | |
| 885 return Bytecode::kTestNotEqual; | |
| 886 case Token::Value::EQ_STRICT: | |
| 887 return Bytecode::kTestEqualStrict; | |
| 888 case Token::Value::LT: | |
| 889 return Bytecode::kTestLessThan; | |
| 890 case Token::Value::GT: | |
| 891 return Bytecode::kTestGreaterThan; | |
| 892 case Token::Value::LTE: | |
| 893 return Bytecode::kTestLessThanOrEqual; | |
| 894 case Token::Value::GTE: | |
| 895 return Bytecode::kTestGreaterThanOrEqual; | |
| 896 case Token::Value::INSTANCEOF: | |
| 897 return Bytecode::kTestInstanceOf; | |
| 898 case Token::Value::IN: | |
| 899 return Bytecode::kTestIn; | |
| 900 default: | |
| 901 UNREACHABLE(); | |
| 902 return Bytecode::kIllegal; | |
| 903 } | |
| 904 } | |
| 905 | |
| 906 // static | |
| 907 Bytecode BytecodeArrayBuilder::BytecodeForStoreNamedProperty( | |
| 908 LanguageMode language_mode) { | |
| 909 switch (language_mode) { | |
| 910 case SLOPPY: | |
| 911 return Bytecode::kStaNamedPropertySloppy; | |
| 912 case STRICT: | |
| 913 return Bytecode::kStaNamedPropertyStrict; | |
| 914 default: | |
| 915 UNREACHABLE(); | |
| 916 } | |
| 917 return Bytecode::kIllegal; | |
| 918 } | |
| 919 | |
| 920 // static | |
| 921 Bytecode BytecodeArrayBuilder::BytecodeForStoreKeyedProperty( | |
| 922 LanguageMode language_mode) { | |
| 923 switch (language_mode) { | |
| 924 case SLOPPY: | |
| 925 return Bytecode::kStaKeyedPropertySloppy; | |
| 926 case STRICT: | |
| 927 return Bytecode::kStaKeyedPropertyStrict; | |
| 928 default: | |
| 929 UNREACHABLE(); | |
| 930 } | |
| 931 return Bytecode::kIllegal; | |
| 932 } | |
| 933 | |
| 934 // static | |
| 935 Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) { | |
| 936 return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof | |
| 937 : Bytecode::kLdaGlobal; | |
| 938 } | |
| 939 | |
| 940 // static | |
| 941 Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal( | |
| 942 LanguageMode language_mode) { | |
| 943 switch (language_mode) { | |
| 944 case SLOPPY: | |
| 945 return Bytecode::kStaGlobalSloppy; | |
| 946 case STRICT: | |
| 947 return Bytecode::kStaGlobalStrict; | |
| 948 default: | |
| 949 UNREACHABLE(); | |
| 950 } | |
| 951 return Bytecode::kIllegal; | |
| 952 } | |
| 953 | |
| 954 // static | |
| 955 Bytecode BytecodeArrayBuilder::BytecodeForStoreLookupSlot( | |
| 956 LanguageMode language_mode) { | |
| 957 switch (language_mode) { | |
| 958 case SLOPPY: | |
| 959 return Bytecode::kStaLookupSlotSloppy; | |
| 960 case STRICT: | |
| 961 return Bytecode::kStaLookupSlotStrict; | |
| 962 default: | |
| 963 UNREACHABLE(); | |
| 964 } | |
| 965 return Bytecode::kIllegal; | |
| 966 } | |
| 967 | |
| 968 // static | |
| 969 Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments( | |
| 970 CreateArgumentsType type) { | |
| 971 switch (type) { | |
| 972 case CreateArgumentsType::kMappedArguments: | |
| 973 return Bytecode::kCreateMappedArguments; | |
| 974 case CreateArgumentsType::kUnmappedArguments: | |
| 975 return Bytecode::kCreateUnmappedArguments; | |
| 976 case CreateArgumentsType::kRestParameter: | |
| 977 return Bytecode::kCreateRestParameter; | |
| 978 } | |
| 979 UNREACHABLE(); | |
| 980 return Bytecode::kIllegal; | |
| 981 } | |
| 982 | |
| 983 // static | |
| 984 Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) { | |
| 985 switch (language_mode) { | |
| 986 case SLOPPY: | |
| 987 return Bytecode::kDeletePropertySloppy; | |
| 988 case STRICT: | |
| 989 return Bytecode::kDeletePropertyStrict; | |
| 990 default: | |
| 991 UNREACHABLE(); | |
| 992 } | |
| 993 return Bytecode::kIllegal; | |
| 994 } | |
| 995 | |
| 996 // static | |
| 997 Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) { | |
| 998 switch (tail_call_mode) { | |
| 999 case TailCallMode::kDisallow: | |
| 1000 return Bytecode::kCall; | |
| 1001 case TailCallMode::kAllow: | |
| 1002 return Bytecode::kTailCall; | |
| 1003 default: | |
| 1004 UNREACHABLE(); | |
| 1005 } | |
| 1006 return Bytecode::kIllegal; | |
| 1007 } | |
| 1008 | |
| 1009 } // namespace interpreter | 917 } // namespace interpreter | 
| 1010 } // namespace internal | 918 } // namespace internal | 
| 1011 } // namespace v8 | 919 } // namespace v8 | 
| OLD | NEW |