Index: src/ia32/fast-codegen-ia32.cc |
=================================================================== |
--- src/ia32/fast-codegen-ia32.cc (revision 3220) |
+++ src/ia32/fast-codegen-ia32.cc (working copy) |
@@ -916,9 +916,9 @@ |
void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
- Comment cmnt(masm_, "[ UnaryOperation"); |
switch (expr->op()) { |
- case Token::VOID: |
+ case Token::VOID: { |
+ Comment cmnt(masm_, "[ UnaryOperation (VOID)"); |
Visit(expr->expression()); |
ASSERT_EQ(Expression::kEffect, expr->expression()->context()); |
switch (expr->context()) { |
@@ -940,8 +940,10 @@ |
break; |
} |
break; |
+ } |
case Token::NOT: { |
+ Comment cmnt(masm_, "[ UnaryOperation (NOT)"); |
ASSERT_EQ(Expression::kTest, expr->expression()->context()); |
Label push_true; |
@@ -1002,6 +1004,36 @@ |
break; |
} |
+ case Token::TYPEOF: { |
+ Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
+ ASSERT_EQ(Expression::kValue, expr->expression()->context()); |
+ |
+ VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
+ if (proxy != NULL && proxy->var()->is_global()) { |
+ Comment cmnt(masm_, "Global variable"); |
+ __ push(CodeGenerator::GlobalObject()); |
+ __ mov(ecx, Immediate(proxy->name())); |
+ Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
+ // Use a regular load, not a contextual load, to avoid reference error. |
+ __ call(ic, RelocInfo::CODE_TARGET); |
+ __ mov(Operand(esp, 0), eax); |
+ } else if (proxy != NULL && |
+ proxy->var()->slot() != NULL && |
+ proxy->var()->slot()->type() == Slot::LOOKUP) { |
+ __ push(esi); |
+ __ push(Immediate(proxy->name())); |
+ __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
+ __ push(eax); |
+ } else { |
+ // This expression cannot throw a reference error at the top level. |
+ Visit(expr->expression()); |
+ } |
+ |
+ __ CallRuntime(Runtime::kTypeof, 1); |
+ Move(expr->context(), eax); |
+ break; |
+ } |
+ |
default: |
UNREACHABLE(); |
} |