Index: src/mips/full-codegen-mips.cc |
=================================================================== |
--- src/mips/full-codegen-mips.cc (revision 9022) |
+++ src/mips/full-codegen-mips.cc (working copy) |
@@ -55,7 +55,6 @@ |
static unsigned GetPropertyId(Property* property) { |
- if (property->is_synthetic()) return AstNode::kNoNumber; |
return property->id(); |
} |
@@ -697,109 +696,77 @@ |
Comment cmnt(masm_, "[ Declaration"); |
ASSERT(variable != NULL); // Must have been resolved. |
Slot* slot = variable->AsSlot(); |
- Property* prop = variable->AsProperty(); |
+ ASSERT(slot != NULL); |
+ switch (slot->type()) { |
+ case Slot::PARAMETER: |
+ case Slot::LOCAL: |
+ if (mode == Variable::CONST) { |
+ __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); |
+ __ sw(t0, MemOperand(fp, SlotOffset(slot))); |
+ } else if (function != NULL) { |
+ VisitForAccumulatorValue(function); |
+ __ sw(result_register(), MemOperand(fp, SlotOffset(slot))); |
+ } |
+ break; |
- if (slot != NULL) { |
- switch (slot->type()) { |
- case Slot::PARAMETER: |
- case Slot::LOCAL: |
- if (mode == Variable::CONST) { |
- __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); |
- __ sw(t0, MemOperand(fp, SlotOffset(slot))); |
- } else if (function != NULL) { |
- VisitForAccumulatorValue(function); |
- __ sw(result_register(), MemOperand(fp, SlotOffset(slot))); |
- } |
- break; |
+ case Slot::CONTEXT: |
+ // We bypass the general EmitSlotSearch because we know more about |
+ // this specific context. |
- case Slot::CONTEXT: |
- // We bypass the general EmitSlotSearch because we know more about |
- // this specific context. |
- |
- // The variable in the decl always resides in the current function |
- // context. |
- ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); |
- if (FLAG_debug_code) { |
- // Check that we're not inside a with or catch context. |
- __ lw(a1, FieldMemOperand(cp, HeapObject::kMapOffset)); |
- __ LoadRoot(t0, Heap::kWithContextMapRootIndex); |
- __ Check(ne, "Declaration in with context.", |
- a1, Operand(t0)); |
- __ LoadRoot(t0, Heap::kCatchContextMapRootIndex); |
- __ Check(ne, "Declaration in catch context.", |
- a1, Operand(t0)); |
- } |
- if (mode == Variable::CONST) { |
- __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
- __ sw(at, ContextOperand(cp, slot->index())); |
- // No write barrier since the_hole_value is in old space. |
- } else if (function != NULL) { |
- VisitForAccumulatorValue(function); |
- __ sw(result_register(), ContextOperand(cp, slot->index())); |
- int offset = Context::SlotOffset(slot->index()); |
- // We know that we have written a function, which is not a smi. |
- __ mov(a1, cp); |
- __ RecordWrite(a1, Operand(offset), a2, result_register()); |
- } |
- break; |
- |
- case Slot::LOOKUP: { |
- __ li(a2, Operand(variable->name())); |
- // Declaration nodes are always introduced in one of two modes. |
- ASSERT(mode == Variable::VAR || |
- mode == Variable::CONST || |
- mode == Variable::LET); |
- PropertyAttributes attr = (mode == Variable::CONST) ? READ_ONLY : NONE; |
- __ li(a1, Operand(Smi::FromInt(attr))); |
- // Push initial value, if any. |
- // Note: For variables we must not push an initial value (such as |
- // 'undefined') because we may have a (legal) redeclaration and we |
- // must not destroy the current value. |
- if (mode == Variable::CONST) { |
- __ LoadRoot(a0, Heap::kTheHoleValueRootIndex); |
- __ Push(cp, a2, a1, a0); |
- } else if (function != NULL) { |
- __ Push(cp, a2, a1); |
- // Push initial value for function declaration. |
- VisitForStackValue(function); |
- } else { |
- ASSERT(Smi::FromInt(0) == 0); |
- // No initial value! |
- __ mov(a0, zero_reg); // Operand(Smi::FromInt(0))); |
- __ Push(cp, a2, a1, a0); |
- } |
- __ CallRuntime(Runtime::kDeclareContextSlot, 4); |
- break; |
+ // The variable in the decl always resides in the current function |
+ // context. |
+ ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); |
+ if (FLAG_debug_code) { |
+ // Check that we're not inside a with or catch context. |
+ __ lw(a1, FieldMemOperand(cp, HeapObject::kMapOffset)); |
+ __ LoadRoot(t0, Heap::kWithContextMapRootIndex); |
+ __ Check(ne, "Declaration in with context.", |
+ a1, Operand(t0)); |
+ __ LoadRoot(t0, Heap::kCatchContextMapRootIndex); |
+ __ Check(ne, "Declaration in catch context.", |
+ a1, Operand(t0)); |
} |
- } |
- |
- } else if (prop != NULL) { |
- // A const declaration aliasing a parameter is an illegal redeclaration. |
- ASSERT(mode != Variable::CONST); |
- if (function != NULL) { |
- // We are declaring a function that rewrites to a property. |
- // Use (keyed) IC to set the initial value. We cannot visit the |
- // rewrite because it's shared and we risk recording duplicate AST |
- // IDs for bailouts from optimized code. |
- ASSERT(prop->obj()->AsVariableProxy() != NULL); |
- { AccumulatorValueContext for_object(this); |
- EmitVariableLoad(prop->obj()->AsVariableProxy()); |
+ if (mode == Variable::CONST) { |
+ __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
+ __ sw(at, ContextOperand(cp, slot->index())); |
+ // No write barrier since the_hole_value is in old space. |
+ } else if (function != NULL) { |
+ VisitForAccumulatorValue(function); |
+ __ sw(result_register(), ContextOperand(cp, slot->index())); |
+ int offset = Context::SlotOffset(slot->index()); |
+ // We know that we have written a function, which is not a smi. |
+ __ mov(a1, cp); |
+ __ RecordWrite(a1, Operand(offset), a2, result_register()); |
} |
+ break; |
- __ push(result_register()); |
- VisitForAccumulatorValue(function); |
- __ mov(a0, result_register()); |
- __ pop(a2); |
- |
- ASSERT(prop->key()->AsLiteral() != NULL && |
- prop->key()->AsLiteral()->handle()->IsSmi()); |
- __ li(a1, Operand(prop->key()->AsLiteral()->handle())); |
- |
- Handle<Code> ic = is_strict_mode() |
- ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
- : isolate()->builtins()->KeyedStoreIC_Initialize(); |
- __ Call(ic); |
- // Value in v0 is ignored (declarations are statements). |
+ case Slot::LOOKUP: { |
+ __ li(a2, Operand(variable->name())); |
+ // Declaration nodes are always introduced in one of two modes. |
+ ASSERT(mode == Variable::VAR || |
+ mode == Variable::CONST || |
+ mode == Variable::LET); |
+ PropertyAttributes attr = (mode == Variable::CONST) ? READ_ONLY : NONE; |
+ __ li(a1, Operand(Smi::FromInt(attr))); |
+ // Push initial value, if any. |
+ // Note: For variables we must not push an initial value (such as |
+ // 'undefined') because we may have a (legal) redeclaration and we |
+ // must not destroy the current value. |
+ if (mode == Variable::CONST) { |
+ __ LoadRoot(a0, Heap::kTheHoleValueRootIndex); |
+ __ Push(cp, a2, a1, a0); |
+ } else if (function != NULL) { |
+ __ Push(cp, a2, a1); |
+ // Push initial value for function declaration. |
+ VisitForStackValue(function); |
+ } else { |
+ ASSERT(Smi::FromInt(0) == 0); |
+ // No initial value! |
+ __ mov(a0, zero_reg); // Operand(Smi::FromInt(0))); |
+ __ Push(cp, a2, a1, a0); |
+ } |
+ __ CallRuntime(Runtime::kDeclareContextSlot, 4); |
+ break; |
} |
} |
} |
@@ -2286,36 +2253,10 @@ |
EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
} else { |
// Call to a keyed property. |
- // For a synthetic property use keyed load IC followed by function call, |
- // for a regular property use EmitKeyedCallWithIC. |
- if (prop->is_synthetic()) { |
- // Do not visit the object and key subexpressions (they are shared |
- // by all occurrences of the same rewritten parameter). |
- ASSERT(prop->obj()->AsVariableProxy() != NULL); |
- ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); |
- Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); |
- MemOperand operand = EmitSlotSearch(slot, a1); |
- __ lw(a1, operand); |
- |
- ASSERT(prop->key()->AsLiteral() != NULL); |
- ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
- __ li(a0, Operand(prop->key()->AsLiteral()->handle())); |
- |
- // Record source code position for IC call. |
- SetSourcePosition(prop->position()); |
- |
- Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
- __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
- __ lw(a1, GlobalObjectOperand()); |
- __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); |
- __ Push(v0, a1); // Function, receiver. |
- EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
- } else { |
- { PreservePositionScope scope(masm()->positions_recorder()); |
- VisitForStackValue(prop->obj()); |
- } |
- EmitKeyedCallWithIC(expr, prop->key()); |
+ { PreservePositionScope scope(masm()->positions_recorder()); |
+ VisitForStackValue(prop->obj()); |
} |
+ EmitKeyedCallWithIC(expr, prop->key()); |
} |
} else { |
{ PreservePositionScope scope(masm()->positions_recorder()); |
@@ -3686,18 +3627,12 @@ |
Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
if (prop != NULL) { |
- if (prop->is_synthetic()) { |
- // Result of deleting parameters is false, even when they rewrite |
- // to accesses on the arguments object. |
- context()->Plug(false); |
- } else { |
- VisitForStackValue(prop->obj()); |
- VisitForStackValue(prop->key()); |
- __ li(a1, Operand(Smi::FromInt(strict_mode_flag()))); |
- __ push(a1); |
- __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
- context()->Plug(v0); |
- } |
+ VisitForStackValue(prop->obj()); |
+ VisitForStackValue(prop->key()); |
+ __ li(a1, Operand(Smi::FromInt(strict_mode_flag()))); |
+ __ push(a1); |
+ __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
+ context()->Plug(v0); |
} else if (var != NULL) { |
// Delete of an unqualified identifier is disallowed in strict mode |
// but "delete this" is. |