| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index 520dbd4c03d086ea267c6efa62fc65423949dde4..2a330ca87059de709f9d3ab3c91039b6738ee064 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -342,27 +342,18 @@ void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); }
|
| void BytecodeGenerator::VisitThrow(Throw* expr) { UNIMPLEMENTED(); }
|
|
|
|
|
| -void BytecodeGenerator::VisitProperty(Property* expr) {
|
| +void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
|
| LhsKind property_kind = Property::GetAssignType(expr);
|
| FeedbackVectorICSlot slot = expr->PropertyFeedbackSlot();
|
| switch (property_kind) {
|
| case VARIABLE:
|
| UNREACHABLE();
|
| - break;
|
| case NAMED_PROPERTY: {
|
| - TemporaryRegisterScope temporary_register_scope(&builder_);
|
| - Register obj = temporary_register_scope.NewRegister();
|
| - Visit(expr->obj());
|
| - builder().StoreAccumulatorInRegister(obj);
|
| builder().LoadLiteral(expr->key()->AsLiteral()->AsPropertyName());
|
| builder().LoadNamedProperty(obj, feedback_index(slot), language_mode());
|
| break;
|
| }
|
| case KEYED_PROPERTY: {
|
| - TemporaryRegisterScope temporary_register_scope(&builder_);
|
| - Register obj = temporary_register_scope.NewRegister();
|
| - Visit(expr->obj());
|
| - builder().StoreAccumulatorInRegister(obj);
|
| Visit(expr->key());
|
| builder().LoadKeyedProperty(obj, feedback_index(slot), language_mode());
|
| break;
|
| @@ -374,7 +365,60 @@ void BytecodeGenerator::VisitProperty(Property* expr) {
|
| }
|
|
|
|
|
| -void BytecodeGenerator::VisitCall(Call* expr) { UNIMPLEMENTED(); }
|
| +void BytecodeGenerator::VisitProperty(Property* expr) {
|
| + TemporaryRegisterScope temporary_register_scope(&builder_);
|
| + Register obj = temporary_register_scope.NewRegister();
|
| + Visit(expr->obj());
|
| + builder().StoreAccumulatorInRegister(obj);
|
| + VisitPropertyLoad(obj, expr);
|
| +}
|
| +
|
| +
|
| +void BytecodeGenerator::VisitCall(Call* expr) {
|
| + Expression* callee_expr = expr->expression();
|
| + Call::CallType call_type = expr->GetCallType(isolate());
|
| +
|
| + // Prepare the callee and the receiver to the function call. This depends on
|
| + // the semantics of the underlying call type.
|
| + TemporaryRegisterScope temporary_register_scope(&builder_);
|
| + Register callee = temporary_register_scope.NewRegister();
|
| + Register receiver = temporary_register_scope.NewRegister();
|
| +
|
| + switch (call_type) {
|
| + case Call::PROPERTY_CALL: {
|
| + Property* property = callee_expr->AsProperty();
|
| + if (property->IsSuperAccess()) {
|
| + UNIMPLEMENTED();
|
| + }
|
| + Visit(property->obj());
|
| + builder().StoreAccumulatorInRegister(receiver);
|
| + // Perform a property load of the callee.
|
| + VisitPropertyLoad(receiver, property);
|
| + builder().StoreAccumulatorInRegister(callee);
|
| + break;
|
| + }
|
| + case Call::GLOBAL_CALL:
|
| + case Call::LOOKUP_SLOT_CALL:
|
| + case Call::SUPER_CALL:
|
| + case Call::POSSIBLY_EVAL_CALL:
|
| + case Call::OTHER_CALL:
|
| + UNIMPLEMENTED();
|
| + }
|
| +
|
| + // Evaluate all arguments to the function call and store in sequential
|
| + // registers.
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| + for (int i = 0; i < args->length(); ++i) {
|
| + Visit(args->at(i));
|
| + Register arg = temporary_register_scope.NewRegister();
|
| + DCHECK(arg.index() - i == receiver.index() + 1);
|
| + builder().StoreAccumulatorInRegister(arg);
|
| + }
|
| +
|
| + // TODO(rmcilroy): Deal with possible direct eval here?
|
| + // TODO(rmcilroy): Use CallIC to allow call type feedback.
|
| + builder().Call(callee, receiver, args->length());
|
| +}
|
|
|
|
|
| void BytecodeGenerator::VisitCallNew(CallNew* expr) { UNIMPLEMENTED(); }
|
|
|