| Index: src/arm/codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/codegen-arm.cc (revision 3208)
|
| +++ src/arm/codegen-arm.cc (working copy)
|
| @@ -92,7 +92,6 @@
|
|
|
| CodeGenState::CodeGenState(CodeGenerator* owner)
|
| : owner_(owner),
|
| - typeof_state_(NOT_INSIDE_TYPEOF),
|
| true_target_(NULL),
|
| false_target_(NULL),
|
| previous_(NULL) {
|
| @@ -101,11 +100,9 @@
|
|
|
|
|
| CodeGenState::CodeGenState(CodeGenerator* owner,
|
| - TypeofState typeof_state,
|
| JumpTarget* true_target,
|
| JumpTarget* false_target)
|
| : owner_(owner),
|
| - typeof_state_(typeof_state),
|
| true_target_(true_target),
|
| false_target_(false_target),
|
| previous_(owner->state()) {
|
| @@ -445,14 +442,13 @@
|
| // register was set, has_cc() is true and cc_reg_ contains the condition to
|
| // test for 'true'.
|
| void CodeGenerator::LoadCondition(Expression* x,
|
| - TypeofState typeof_state,
|
| JumpTarget* true_target,
|
| JumpTarget* false_target,
|
| bool force_cc) {
|
| ASSERT(!has_cc());
|
| int original_height = frame_->height();
|
|
|
| - { CodeGenState new_state(this, typeof_state, true_target, false_target);
|
| + { CodeGenState new_state(this, true_target, false_target);
|
| Visit(x);
|
|
|
| // If we hit a stack overflow, we may not have actually visited
|
| @@ -482,13 +478,13 @@
|
| }
|
|
|
|
|
| -void CodeGenerator::Load(Expression* x, TypeofState typeof_state) {
|
| +void CodeGenerator::Load(Expression* expr) {
|
| #ifdef DEBUG
|
| int original_height = frame_->height();
|
| #endif
|
| JumpTarget true_target;
|
| JumpTarget false_target;
|
| - LoadCondition(x, typeof_state, &true_target, &false_target, false);
|
| + LoadCondition(expr, &true_target, &false_target, false);
|
|
|
| if (has_cc()) {
|
| // Convert cc_reg_ into a boolean value.
|
| @@ -555,24 +551,29 @@
|
| }
|
|
|
|
|
| -// TODO(1241834): Get rid of this function in favor of just using Load, now
|
| -// that we have the INSIDE_TYPEOF typeof state. => Need to handle global
|
| -// variables w/o reference errors elsewhere.
|
| -void CodeGenerator::LoadTypeofExpression(Expression* x) {
|
| +void CodeGenerator::LoadTypeofExpression(Expression* expr) {
|
| + // Special handling of identifiers as subexpressions of typeof.
|
| VirtualFrame::SpilledScope spilled_scope;
|
| - Variable* variable = x->AsVariableProxy()->AsVariable();
|
| + Variable* variable = expr->AsVariableProxy()->AsVariable();
|
| if (variable != NULL && !variable->is_this() && variable->is_global()) {
|
| - // NOTE: This is somewhat nasty. We force the compiler to load
|
| - // the variable as if through '<global>.<variable>' to make sure we
|
| - // do not get reference errors.
|
| + // For a global variable we build the property reference
|
| + // <global>.<variable> and perform a (regular non-contextual) property
|
| + // load to make sure we do not get reference errors.
|
| Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX);
|
| Literal key(variable->name());
|
| // TODO(1241834): Fetch the position from the variable instead of using
|
| // no position.
|
| Property property(&global, &key, RelocInfo::kNoPosition);
|
| - LoadAndSpill(&property);
|
| + Reference ref(this, &property);
|
| + ref.GetValueAndSpill();
|
| + } else if (variable != NULL && variable->slot() != NULL) {
|
| + // For a variable that rewrites to a slot, we signal it is the immediate
|
| + // subexpression of a typeof.
|
| + LoadFromSlot(variable->slot(), INSIDE_TYPEOF);
|
| + frame_->SpillAll();
|
| } else {
|
| - LoadAndSpill(x, INSIDE_TYPEOF);
|
| + // Anything else can be handled normally.
|
| + LoadAndSpill(expr);
|
| }
|
| }
|
|
|
| @@ -1279,8 +1280,7 @@
|
| JumpTarget then;
|
| JumpTarget else_;
|
| // if (cond)
|
| - LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
|
| - &then, &else_, true);
|
| + LoadConditionAndSpill(node->condition(), &then, &else_, true);
|
| if (frame_ != NULL) {
|
| Branch(false, &else_);
|
| }
|
| @@ -1303,8 +1303,7 @@
|
| ASSERT(!has_else_stm);
|
| JumpTarget then;
|
| // if (cond)
|
| - LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
|
| - &then, &exit, true);
|
| + LoadConditionAndSpill(node->condition(), &then, &exit, true);
|
| if (frame_ != NULL) {
|
| Branch(false, &exit);
|
| }
|
| @@ -1319,8 +1318,7 @@
|
| ASSERT(!has_then_stm);
|
| JumpTarget else_;
|
| // if (!cond)
|
| - LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
|
| - &exit, &else_, true);
|
| + LoadConditionAndSpill(node->condition(), &exit, &else_, true);
|
| if (frame_ != NULL) {
|
| Branch(true, &exit);
|
| }
|
| @@ -1334,8 +1332,7 @@
|
| Comment cmnt(masm_, "[ If");
|
| ASSERT(!has_then_stm && !has_else_stm);
|
| // if (cond)
|
| - LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
|
| - &exit, &exit, false);
|
| + LoadConditionAndSpill(node->condition(), &exit, &exit, false);
|
| if (frame_ != NULL) {
|
| if (has_cc()) {
|
| cc_reg_ = al;
|
| @@ -1573,8 +1570,7 @@
|
| node->continue_target()->Bind();
|
| }
|
| if (has_valid_frame()) {
|
| - LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF,
|
| - &body, node->break_target(), true);
|
| + LoadConditionAndSpill(node->cond(), &body, node->break_target(), true);
|
| if (has_valid_frame()) {
|
| // A invalid frame here indicates that control did not
|
| // fall out of the test expression.
|
| @@ -1613,8 +1609,7 @@
|
|
|
| if (info == DONT_KNOW) {
|
| JumpTarget body;
|
| - LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF,
|
| - &body, node->break_target(), true);
|
| + LoadConditionAndSpill(node->cond(), &body, node->break_target(), true);
|
| if (has_valid_frame()) {
|
| // A NULL frame indicates that control did not fall out of the
|
| // test expression.
|
| @@ -1673,8 +1668,7 @@
|
| // If the test is always true, there is no need to compile it.
|
| if (info == DONT_KNOW) {
|
| JumpTarget body;
|
| - LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF,
|
| - &body, node->break_target(), true);
|
| + LoadConditionAndSpill(node->cond(), &body, node->break_target(), true);
|
| if (has_valid_frame()) {
|
| Branch(false, node->break_target());
|
| }
|
| @@ -2283,20 +2277,19 @@
|
| Comment cmnt(masm_, "[ Conditional");
|
| JumpTarget then;
|
| JumpTarget else_;
|
| - LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
|
| - &then, &else_, true);
|
| + LoadConditionAndSpill(node->condition(), &then, &else_, true);
|
| if (has_valid_frame()) {
|
| Branch(false, &else_);
|
| }
|
| if (has_valid_frame() || then.is_linked()) {
|
| then.Bind();
|
| - LoadAndSpill(node->then_expression(), typeof_state());
|
| + LoadAndSpill(node->then_expression());
|
| }
|
| if (else_.is_linked()) {
|
| JumpTarget exit;
|
| if (has_valid_frame()) exit.Jump();
|
| else_.Bind();
|
| - LoadAndSpill(node->else_expression(), typeof_state());
|
| + LoadAndSpill(node->else_expression());
|
| if (exit.is_linked()) exit.Bind();
|
| }
|
| ASSERT(frame_->height() == original_height + 1);
|
| @@ -2363,10 +2356,6 @@
|
| frame_->EmitPush(r0);
|
|
|
| } else {
|
| - // Note: We would like to keep the assert below, but it fires because of
|
| - // some nasty code in LoadTypeofExpression() which should be removed...
|
| - // ASSERT(!slot->var()->is_dynamic());
|
| -
|
| // Special handling for locals allocated in registers.
|
| __ ldr(r0, SlotOperand(slot, r2));
|
| frame_->EmitPush(r0);
|
| @@ -2461,7 +2450,7 @@
|
| #endif
|
| VirtualFrame::SpilledScope spilled_scope;
|
| Comment cmnt(masm_, "[ Slot");
|
| - LoadFromSlot(node, typeof_state());
|
| + LoadFromSlot(node, NOT_INSIDE_TYPEOF);
|
| ASSERT(frame_->height() == original_height + 1);
|
| }
|
|
|
| @@ -2480,7 +2469,7 @@
|
| } else {
|
| ASSERT(var->is_global());
|
| Reference ref(this, node);
|
| - ref.GetValueAndSpill(typeof_state());
|
| + ref.GetValueAndSpill();
|
| }
|
| ASSERT(frame_->height() == original_height + 1);
|
| }
|
| @@ -2816,7 +2805,7 @@
|
| } else {
|
| // +=, *= and similar binary assignments.
|
| // Get the old value of the lhs.
|
| - target.GetValueAndSpill(NOT_INSIDE_TYPEOF);
|
| + target.GetValueAndSpill();
|
| Literal* literal = node->value()->AsLiteral();
|
| bool overwrite =
|
| (node->value()->AsBinaryOperation() != NULL &&
|
| @@ -2881,7 +2870,7 @@
|
| Comment cmnt(masm_, "[ Property");
|
|
|
| { Reference property(this, node);
|
| - property.GetValueAndSpill(typeof_state());
|
| + property.GetValueAndSpill();
|
| }
|
| ASSERT(frame_->height() == original_height + 1);
|
| }
|
| @@ -3051,7 +3040,7 @@
|
|
|
| // Load the function to call from the property through a reference.
|
| Reference ref(this, property);
|
| - ref.GetValueAndSpill(NOT_INSIDE_TYPEOF); // receiver
|
| + ref.GetValueAndSpill(); // receiver
|
|
|
| // Pass receiver to called function.
|
| if (property->is_synthetic()) {
|
| @@ -3456,7 +3445,6 @@
|
|
|
| if (op == Token::NOT) {
|
| LoadConditionAndSpill(node->expression(),
|
| - NOT_INSIDE_TYPEOF,
|
| false_target(),
|
| true_target(),
|
| true);
|
| @@ -3617,7 +3605,7 @@
|
| ASSERT(frame_->height() == original_height + 1);
|
| return;
|
| }
|
| - target.GetValueAndSpill(NOT_INSIDE_TYPEOF);
|
| + target.GetValueAndSpill();
|
| frame_->EmitPop(r0);
|
|
|
| JumpTarget slow;
|
| @@ -3711,7 +3699,6 @@
|
| if (op == Token::AND) {
|
| JumpTarget is_true;
|
| LoadConditionAndSpill(node->left(),
|
| - NOT_INSIDE_TYPEOF,
|
| &is_true,
|
| false_target(),
|
| false);
|
| @@ -3747,7 +3734,6 @@
|
| }
|
| is_true.Bind();
|
| LoadConditionAndSpill(node->right(),
|
| - NOT_INSIDE_TYPEOF,
|
| true_target(),
|
| false_target(),
|
| false);
|
| @@ -3759,7 +3745,6 @@
|
| } else if (op == Token::OR) {
|
| JumpTarget is_false;
|
| LoadConditionAndSpill(node->left(),
|
| - NOT_INSIDE_TYPEOF,
|
| true_target(),
|
| &is_false,
|
| false);
|
| @@ -3795,7 +3780,6 @@
|
| }
|
| is_false.Bind();
|
| LoadConditionAndSpill(node->right(),
|
| - NOT_INSIDE_TYPEOF,
|
| true_target(),
|
| false_target(),
|
| false);
|
| @@ -4094,7 +4078,7 @@
|
| }
|
|
|
|
|
| -void Reference::GetValue(TypeofState typeof_state) {
|
| +void Reference::GetValue() {
|
| ASSERT(cgen_->HasValidEntryRegisters());
|
| ASSERT(!is_illegal());
|
| ASSERT(!cgen_->has_cc());
|
| @@ -4109,16 +4093,11 @@
|
| Comment cmnt(masm, "[ Load from Slot");
|
| Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
|
| ASSERT(slot != NULL);
|
| - cgen_->LoadFromSlot(slot, typeof_state);
|
| + cgen_->LoadFromSlot(slot, NOT_INSIDE_TYPEOF);
|
| break;
|
| }
|
|
|
| case NAMED: {
|
| - // TODO(1241834): Make sure that this it is safe to ignore the
|
| - // distinction between expressions in a typeof and not in a typeof. If
|
| - // there is a chance that reference errors can be thrown below, we
|
| - // must distinguish between the two kinds of loads (typeof expression
|
| - // loads must not throw a reference error).
|
| VirtualFrame* frame = cgen_->frame();
|
| Comment cmnt(masm, "[ Load from named Property");
|
| Handle<String> name(GetName());
|
| @@ -4137,9 +4116,6 @@
|
| }
|
|
|
| case KEYED: {
|
| - // TODO(1241834): Make sure that this it is safe to ignore the
|
| - // distinction between expressions in a typeof and not in a typeof.
|
| -
|
| // TODO(181): Implement inlined version of array indexing once
|
| // loop nesting is properly tracked on ARM.
|
| VirtualFrame* frame = cgen_->frame();
|
|
|