| Index: src/codegen-ia32.cc
|
| ===================================================================
|
| --- src/codegen-ia32.cc (revision 1344)
|
| +++ src/codegen-ia32.cc (working copy)
|
| @@ -2365,11 +2365,15 @@
|
|
|
| } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
|
| Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
|
| - __ mov(eax,
|
| - ContextSlotOperandCheckExtensions(potential_slot,
|
| - ebx,
|
| - &slow));
|
| - __ jmp(&done);
|
| + // Only generate the fast case for locals that rewrite to slots.
|
| + // This rules out argument loads.
|
| + if (potential_slot != NULL) {
|
| + __ mov(eax,
|
| + ContextSlotOperandCheckExtensions(potential_slot,
|
| + ebx,
|
| + &slow));
|
| + __ jmp(&done);
|
| + }
|
| }
|
|
|
| __ bind(&slow);
|
| @@ -2414,7 +2418,8 @@
|
| // Check that no extension objects have been created by calls to
|
| // eval from the current scope to the global scope.
|
| Register context = esi;
|
| - for (Scope* s = scope(); s != NULL; s = s->outer_scope()) {
|
| + Scope* s = scope();
|
| + while (s != NULL) {
|
| if (s->num_heap_slots() > 0) {
|
| if (s->calls_eval()) {
|
| // Check that extension is NULL.
|
| @@ -2427,10 +2432,30 @@
|
| context = tmp;
|
| }
|
| // If no outer scope calls eval, we do not need to check more
|
| - // context extensions.
|
| - if (!s->outer_scope_calls_eval()) break;
|
| + // context extensions. If we have reached an eval scope, we check
|
| + // all extensions from this point.
|
| + if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break;
|
| + s = s->outer_scope();
|
| }
|
|
|
| + if (s->is_eval_scope()) {
|
| + Label next, fast;
|
| + if (!context.is(tmp)) __ mov(tmp, Operand(context));
|
| + __ bind(&next);
|
| + // Terminate at global context.
|
| + __ cmp(FieldOperand(tmp, HeapObject::kMapOffset),
|
| + Immediate(Factory::global_context_map()));
|
| + __ j(equal, &fast);
|
| + // Check that extension is NULL.
|
| + __ cmp(ContextOperand(tmp, Context::EXTENSION_INDEX), Immediate(0));
|
| + __ j(not_equal, slow, not_taken);
|
| + // Load next context in chain.
|
| + __ mov(tmp, ContextOperand(tmp, Context::CLOSURE_INDEX));
|
| + __ mov(tmp, FieldOperand(tmp, JSFunction::kContextOffset));
|
| + __ jmp(&next);
|
| + __ bind(&fast);
|
| + }
|
| +
|
| // All extension objects were empty and it is safe to use a global
|
| // load IC call.
|
| Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
|
|