Chromium Code Reviews| Index: src/interpreter/bytecode-generator.cc |
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc |
| index 1d8738ff6ae27cdb6ce9a46722805d26ce5f0e5c..2335859fd5e79f0a6eb459bbe96f50783141d2a6 100644 |
| --- a/src/interpreter/bytecode-generator.cc |
| +++ b/src/interpreter/bytecode-generator.cc |
| @@ -1615,6 +1615,7 @@ void BytecodeGenerator::VisitCall(Call* expr) { |
| execution_result()->PrepareForConsecutiveAllocations(args->length() + 1); |
| Register receiver = execution_result()->NextConsecutiveRegister(); |
| + bool possibly_eval = false; |
| switch (call_type) { |
| case Call::NAMED_PROPERTY_CALL: |
| case Call::KEYED_PROPERTY_CALL: { |
| @@ -1635,6 +1636,32 @@ void BytecodeGenerator::VisitCall(Call* expr) { |
| builder()->StoreAccumulatorInRegister(callee); |
| break; |
| } |
| + case Call::POSSIBLY_EVAL_CALL: { |
| + possibly_eval = true; |
| + if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { |
| + TemporaryRegisterScope temporary_register_scope(builder()); |
| + temporary_register_scope.PrepareForConsecutiveAllocations(2); |
| + Register context = temporary_register_scope.NextConsecutiveRegister(); |
| + Register name = temporary_register_scope.NextConsecutiveRegister(); |
| + |
| + Variable* variable = callee_expr->AsVariableProxy()->var(); |
| + builder() |
| + ->MoveRegister(Register::function_context(), context) |
| + .LoadLiteral(variable->name()) |
| + .StoreAccumulatorInRegister(name); |
| + |
| + // Call LoadLookupSlotCallee/Receiver to get the Callee and Receiver |
|
Michael Starzinger
2016/01/08 13:40:47
nit: Comment is outdated, also s/Callee/callee/ an
rmcilroy
2016/01/08 14:34:30
Done.
|
| + // Reuse the context and name arguments as the return registers (since |
| + // these are consecutive), and them move into callee and reciever |
| + // registers. |
| + builder() |
| + ->CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, context) |
| + .MoveRegister(context, callee) |
| + .MoveRegister(name, receiver); |
| + break; |
| + } |
| + // Fall through. |
| + } |
| case Call::OTHER_CALL: { |
| builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
| VisitForAccumulatorValue(callee_expr); |
| @@ -1645,7 +1672,6 @@ void BytecodeGenerator::VisitCall(Call* expr) { |
| case Call::KEYED_SUPER_PROPERTY_CALL: |
| case Call::LOOKUP_SLOT_CALL: |
| case Call::SUPER_CALL: |
| - case Call::POSSIBLY_EVAL_CALL: |
| UNIMPLEMENTED(); |
| } |
| @@ -1654,7 +1680,37 @@ void BytecodeGenerator::VisitCall(Call* expr) { |
| Register arg = VisitArguments(args); |
| CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); |
| - // TODO(rmcilroy): Deal with possible direct eval here? |
| + // Resolve callee and receiver for a potential direct eval call. This block |
| + // will mutate the callee and receiver values. |
|
Michael Starzinger
2016/01/08 13:40:47
nit: This comment is outdated (also in the AstGrap
rmcilroy
2016/01/08 14:34:30
Done (also in AstGraphBuilder).
|
| + if (possibly_eval && args->length() > 0) { |
| + TemporaryRegisterScope temporary_register_scope(builder()); |
| + temporary_register_scope.PrepareForConsecutiveAllocations(5); |
| + Register callee_for_eval = |
| + temporary_register_scope.NextConsecutiveRegister(); |
| + Register source = temporary_register_scope.NextConsecutiveRegister(); |
| + Register function = temporary_register_scope.NextConsecutiveRegister(); |
| + Register language = temporary_register_scope.NextConsecutiveRegister(); |
| + Register position = temporary_register_scope.NextConsecutiveRegister(); |
| + |
| + // Set up arguments for ResolvePossiblyDirectEval by copying callee, source |
| + // strings and function closure, and loading language and |
| + // position. |
| + builder() |
| + ->MoveRegister(callee, callee_for_eval) |
| + .MoveRegister(arg, source) |
| + .MoveRegister(Register::function_closure(), function) |
| + .LoadLiteral(Smi::FromInt(language_mode())) |
| + .StoreAccumulatorInRegister(language) |
| + .LoadLiteral( |
| + Smi::FromInt(execution_context()->scope()->start_position())) |
| + .StoreAccumulatorInRegister(position); |
| + |
| + // Call ResolvePossiblyDirectEval and modify the callee. |
| + builder() |
| + ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5) |
| + .StoreAccumulatorInRegister(callee); |
| + } |
| + |
| // TODO(rmcilroy): Use CallIC to allow call type feedback. |
| builder()->Call(callee, receiver, args->length(), |
| feedback_index(expr->CallFeedbackICSlot())); |
| @@ -2052,7 +2108,12 @@ void BytecodeGenerator::VisitBuildLocalActivationContext() { |
| Scope* scope = this->scope(); |
| if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { |
| - UNIMPLEMENTED(); |
| + Variable* variable = scope->receiver(); |
| + Register receiver(builder()->Parameter(0)); |
| + // Context variable (at bottom of the context chain). |
| + DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); |
| + builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot( |
| + execution_context()->reg(), variable->index()); |
| } |
| // Copy parameters into context if necessary. |