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-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
6 | 6 |
7 #include <stack> | 7 #include <stack> |
8 | 8 |
9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 } | 335 } |
336 } | 336 } |
337 | 337 |
338 | 338 |
339 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } | 339 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } |
340 | 340 |
341 | 341 |
342 void BytecodeGenerator::VisitThrow(Throw* expr) { UNIMPLEMENTED(); } | 342 void BytecodeGenerator::VisitThrow(Throw* expr) { UNIMPLEMENTED(); } |
343 | 343 |
344 | 344 |
345 void BytecodeGenerator::VisitProperty(Property* expr) { | 345 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) { |
346 LhsKind property_kind = Property::GetAssignType(expr); | 346 LhsKind property_kind = Property::GetAssignType(expr); |
347 FeedbackVectorICSlot slot = expr->PropertyFeedbackSlot(); | 347 FeedbackVectorICSlot slot = expr->PropertyFeedbackSlot(); |
348 switch (property_kind) { | 348 switch (property_kind) { |
349 case VARIABLE: | 349 case VARIABLE: |
350 UNREACHABLE(); | 350 UNREACHABLE(); |
351 break; | |
352 case NAMED_PROPERTY: { | 351 case NAMED_PROPERTY: { |
353 TemporaryRegisterScope temporary_register_scope(&builder_); | |
354 Register obj = temporary_register_scope.NewRegister(); | |
355 Visit(expr->obj()); | |
356 builder().StoreAccumulatorInRegister(obj); | |
357 builder().LoadLiteral(expr->key()->AsLiteral()->AsPropertyName()); | 352 builder().LoadLiteral(expr->key()->AsLiteral()->AsPropertyName()); |
358 builder().LoadNamedProperty(obj, feedback_index(slot), language_mode()); | 353 builder().LoadNamedProperty(obj, feedback_index(slot), language_mode()); |
359 break; | 354 break; |
360 } | 355 } |
361 case KEYED_PROPERTY: { | 356 case KEYED_PROPERTY: { |
362 TemporaryRegisterScope temporary_register_scope(&builder_); | |
363 Register obj = temporary_register_scope.NewRegister(); | |
364 Visit(expr->obj()); | |
365 builder().StoreAccumulatorInRegister(obj); | |
366 Visit(expr->key()); | 357 Visit(expr->key()); |
367 builder().LoadKeyedProperty(obj, feedback_index(slot), language_mode()); | 358 builder().LoadKeyedProperty(obj, feedback_index(slot), language_mode()); |
368 break; | 359 break; |
369 } | 360 } |
370 case NAMED_SUPER_PROPERTY: | 361 case NAMED_SUPER_PROPERTY: |
371 case KEYED_SUPER_PROPERTY: | 362 case KEYED_SUPER_PROPERTY: |
372 UNIMPLEMENTED(); | 363 UNIMPLEMENTED(); |
373 } | 364 } |
374 } | 365 } |
375 | 366 |
376 | 367 |
377 void BytecodeGenerator::VisitCall(Call* expr) { UNIMPLEMENTED(); } | 368 void BytecodeGenerator::VisitProperty(Property* expr) { |
| 369 TemporaryRegisterScope temporary_register_scope(&builder_); |
| 370 Register obj = temporary_register_scope.NewRegister(); |
| 371 Visit(expr->obj()); |
| 372 builder().StoreAccumulatorInRegister(obj); |
| 373 VisitPropertyLoad(obj, expr); |
| 374 } |
| 375 |
| 376 |
| 377 void BytecodeGenerator::VisitCall(Call* expr) { |
| 378 Expression* callee_expr = expr->expression(); |
| 379 Call::CallType call_type = expr->GetCallType(isolate()); |
| 380 |
| 381 // Prepare the callee and the receiver to the function call. This depends on |
| 382 // the semantics of the underlying call type. |
| 383 TemporaryRegisterScope temporary_register_scope(&builder_); |
| 384 Register callee = temporary_register_scope.NewRegister(); |
| 385 Register receiver = temporary_register_scope.NewRegister(); |
| 386 |
| 387 switch (call_type) { |
| 388 case Call::PROPERTY_CALL: { |
| 389 Property* property = callee_expr->AsProperty(); |
| 390 if (property->IsSuperAccess()) { |
| 391 UNIMPLEMENTED(); |
| 392 } |
| 393 Visit(property->obj()); |
| 394 builder().StoreAccumulatorInRegister(receiver); |
| 395 // Perform a property load of the callee. |
| 396 VisitPropertyLoad(receiver, property); |
| 397 builder().StoreAccumulatorInRegister(callee); |
| 398 break; |
| 399 } |
| 400 case Call::GLOBAL_CALL: |
| 401 case Call::LOOKUP_SLOT_CALL: |
| 402 case Call::SUPER_CALL: |
| 403 case Call::POSSIBLY_EVAL_CALL: |
| 404 case Call::OTHER_CALL: |
| 405 UNIMPLEMENTED(); |
| 406 } |
| 407 |
| 408 // Evaluate all arguments to the function call and store in sequential |
| 409 // registers. |
| 410 ZoneList<Expression*>* args = expr->arguments(); |
| 411 for (int i = 0; i < args->length(); ++i) { |
| 412 Visit(args->at(i)); |
| 413 Register arg = temporary_register_scope.NewRegister(); |
| 414 DCHECK(arg.index() - i == receiver.index() + 1); |
| 415 builder().StoreAccumulatorInRegister(arg); |
| 416 } |
| 417 |
| 418 // TODO(rmcilroy): Deal with possible direct eval here? |
| 419 // TODO(rmcilroy): Use CallIC to allow call type feedback. |
| 420 builder().Call(callee, receiver, args->length()); |
| 421 } |
378 | 422 |
379 | 423 |
380 void BytecodeGenerator::VisitCallNew(CallNew* expr) { UNIMPLEMENTED(); } | 424 void BytecodeGenerator::VisitCallNew(CallNew* expr) { UNIMPLEMENTED(); } |
381 | 425 |
382 | 426 |
383 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { UNIMPLEMENTED(); } | 427 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { UNIMPLEMENTED(); } |
384 | 428 |
385 | 429 |
386 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 430 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
387 UNIMPLEMENTED(); | 431 UNIMPLEMENTED(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 } | 500 } |
457 | 501 |
458 | 502 |
459 int BytecodeGenerator::feedback_index(FeedbackVectorICSlot slot) const { | 503 int BytecodeGenerator::feedback_index(FeedbackVectorICSlot slot) const { |
460 return info()->feedback_vector()->GetIndex(slot); | 504 return info()->feedback_vector()->GetIndex(slot); |
461 } | 505 } |
462 | 506 |
463 } // namespace interpreter | 507 } // namespace interpreter |
464 } // namespace internal | 508 } // namespace internal |
465 } // namespace v8 | 509 } // namespace v8 |
OLD | NEW |