| Index: src/ia32/full-codegen-ia32.cc
|
| diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
|
| index 4255347bad94a383e53ed212d85519c9023a867c..0a2b503ee662dd6984df3550e4dcd2049d4ffa73 100644
|
| --- a/src/ia32/full-codegen-ia32.cc
|
| +++ b/src/ia32/full-codegen-ia32.cc
|
| @@ -2283,6 +2283,27 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr) {
|
| }
|
|
|
|
|
| +void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
|
| + int arg_count) {
|
| + // Push copy of the first argument or undefined if it doesn't exist.
|
| + if (arg_count > 0) {
|
| + __ push(Operand(esp, arg_count * kPointerSize));
|
| + } else {
|
| + __ push(Immediate(Factory::undefined_value()));
|
| + }
|
| +
|
| + // Push the receiver of the enclosing function.
|
| + __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize));
|
| +
|
| + // Push the strict mode flag.
|
| + __ push(Immediate(Smi::FromInt(strict_mode_flag())));
|
| +
|
| + __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
|
| + ? Runtime::kResolvePossiblyDirectEvalNoLookup
|
| + : Runtime::kResolvePossiblyDirectEval, 4);
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::VisitCall(Call* expr) {
|
| #ifdef DEBUG
|
| // We want to verify that RecordJSReturnSite gets called on all paths
|
| @@ -2311,21 +2332,30 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
| VisitForStackValue(args->at(i));
|
| }
|
|
|
| - // Push copy of the function - found below the arguments.
|
| - __ push(Operand(esp, (arg_count + 1) * kPointerSize));
|
| -
|
| - // Push copy of the first argument or undefined if it doesn't exist.
|
| - if (arg_count > 0) {
|
| - __ push(Operand(esp, arg_count * kPointerSize));
|
| - } else {
|
| - __ push(Immediate(Factory::undefined_value()));
|
| + // If we know that eval can only be shadowed by eval-introduced
|
| + // variables we attempt to load the global eval function directly
|
| + // in generated code. If we succeed, there is no need to perform a
|
| + // context lookup in the runtime system.
|
| + Label done;
|
| + if (var->AsSlot() != NULL && var->mode() == Variable::DYNAMIC_GLOBAL) {
|
| + Label slow;
|
| + EmitLoadGlobalSlotCheckExtensions(var->AsSlot(),
|
| + NOT_INSIDE_TYPEOF,
|
| + &slow);
|
| + // Push the function and resolve eval.
|
| + __ push(eax);
|
| + EmitResolvePossiblyDirectEval(SKIP_CONTEXT_LOOKUP, arg_count);
|
| + __ jmp(&done);
|
| + __ bind(&slow);
|
| }
|
|
|
| - // Push the receiver of the enclosing function and do runtime call.
|
| - __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize));
|
| - // Push the strict mode flag.
|
| - __ push(Immediate(Smi::FromInt(strict_mode_flag())));
|
| - __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 4);
|
| + // Push copy of the function (found below the arguments) and
|
| + // resolve eval.
|
| + __ push(Operand(esp, (arg_count + 1) * kPointerSize));
|
| + EmitResolvePossiblyDirectEval(PERFORM_CONTEXT_LOOKUP, arg_count);
|
| + if (done.is_linked()) {
|
| + __ bind(&done);
|
| + }
|
|
|
| // The runtime call returns a pair of values in eax (function) and
|
| // edx (receiver). Touch up the stack with the right values.
|
|
|