Index: src/x64/fast-codegen-x64.cc |
=================================================================== |
--- src/x64/fast-codegen-x64.cc (revision 3220) |
+++ src/x64/fast-codegen-x64.cc (working copy) |
@@ -991,9 +991,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()) { |
@@ -1015,8 +1015,10 @@ |
break; |
} |
break; |
+ } |
case Token::NOT: { |
+ Comment cmnt(masm_, "[ UnaryOperation (NOT)"); |
ASSERT_EQ(Expression::kTest, expr->expression()->context()); |
Label push_true; |
@@ -1077,6 +1079,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()); |
+ __ Move(rcx, 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); |
+ __ movq(Operand(rsp, 0), rax); |
+ } else if (proxy != NULL && |
+ proxy->var()->slot() != NULL && |
+ proxy->var()->slot()->type() == Slot::LOOKUP) { |
+ __ push(rsi); |
+ __ Push(proxy->name()); |
+ __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
+ __ push(rax); |
+ } else { |
+ // This expression cannot throw a reference error at the top level. |
+ Visit(expr->expression()); |
+ } |
+ |
+ __ CallRuntime(Runtime::kTypeof, 1); |
+ Move(expr->context(), rax); |
+ break; |
+ } |
+ |
default: |
UNREACHABLE(); |
} |