Skip to content

Commit c1e7dd8

Browse files
author
whesse@chromium.org
committed
Implement typeof in fast compiler.
Review URL: http://codereview.chromium.org/354027 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3222 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
1 parent 273e860 commit c1e7dd8

File tree

4 files changed

+110
-7
lines changed

4 files changed

+110
-7
lines changed

src/arm/fast-codegen-arm.cc

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
732732
if (key->AsLiteral() != NULL && key->AsLiteral()->handle()->IsSymbol() &&
733733
!String::cast(*(key->AsLiteral()->handle()))->AsArrayIndex(&dummy)) {
734734
// Do a NAMED property load.
735-
// The IC expects the property name in ecx and the receiver on the stack.
735+
// The IC expects the property name in r2 and the receiver on the stack.
736736
__ mov(r2, Operand(key->AsLiteral()->handle()));
737737
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
738738
__ Call(ic, RelocInfo::CODE_TARGET);
@@ -915,9 +915,9 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
915915

916916

917917
void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
918-
Comment cmnt(masm_, "[ UnaryOperation");
919918
switch (expr->op()) {
920-
case Token::VOID:
919+
case Token::VOID: {
920+
Comment cmnt(masm_, "[ UnaryOperation (VOID)");
921921
Visit(expr->expression());
922922
ASSERT_EQ(Expression::kEffect, expr->expression()->context());
923923
switch (expr->context()) {
@@ -940,8 +940,10 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
940940
break;
941941
}
942942
break;
943+
}
943944

944945
case Token::NOT: {
946+
Comment cmnt(masm_, "[ UnaryOperation (NOT)");
945947
ASSERT_EQ(Expression::kTest, expr->expression()->context());
946948

947949
Label push_true;
@@ -1006,6 +1008,38 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
10061008
break;
10071009
}
10081010

1011+
case Token::TYPEOF: {
1012+
Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
1013+
ASSERT_EQ(Expression::kValue, expr->expression()->context());
1014+
1015+
VariableProxy* proxy = expr->expression()->AsVariableProxy();
1016+
if (proxy != NULL && proxy->var()->is_global()) {
1017+
Comment cmnt(masm_, "Global variable");
1018+
__ ldr(r0, CodeGenerator::GlobalObject());
1019+
__ push(r0);
1020+
__ mov(r2, Operand(proxy->name()));
1021+
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1022+
// Use a regular load, not a contextual load, to avoid a reference
1023+
// error.
1024+
__ Call(ic, RelocInfo::CODE_TARGET);
1025+
__ str(r0, MemOperand(sp));
1026+
} else if (proxy != NULL &&
1027+
proxy->var()->slot() != NULL &&
1028+
proxy->var()->slot()->type() == Slot::LOOKUP) {
1029+
__ mov(r0, Operand(proxy->name()));
1030+
__ stm(db_w, sp, cp.bit() | r0.bit());
1031+
__ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
1032+
__ push(r0);
1033+
} else {
1034+
// This expression cannot throw a reference error at the top level.
1035+
Visit(expr->expression());
1036+
}
1037+
1038+
__ CallRuntime(Runtime::kTypeof, 1);
1039+
Move(expr->context(), r0);
1040+
break;
1041+
}
1042+
10091043
default:
10101044
UNREACHABLE();
10111045
}

src/compiler.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,9 @@ void CodeGenSelector::VisitUnaryOperation(UnaryOperation* expr) {
987987
case Token::NOT:
988988
ProcessExpression(expr->expression(), Expression::kTest);
989989
break;
990+
case Token::TYPEOF:
991+
ProcessExpression(expr->expression(), Expression::kValue);
992+
break;
990993
default:
991994
BAILOUT("UnaryOperation");
992995
}

src/ia32/fast-codegen-ia32.cc

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -916,9 +916,9 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
916916

917917

918918
void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
919-
Comment cmnt(masm_, "[ UnaryOperation");
920919
switch (expr->op()) {
921-
case Token::VOID:
920+
case Token::VOID: {
921+
Comment cmnt(masm_, "[ UnaryOperation (VOID)");
922922
Visit(expr->expression());
923923
ASSERT_EQ(Expression::kEffect, expr->expression()->context());
924924
switch (expr->context()) {
@@ -940,8 +940,10 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
940940
break;
941941
}
942942
break;
943+
}
943944

944945
case Token::NOT: {
946+
Comment cmnt(masm_, "[ UnaryOperation (NOT)");
945947
ASSERT_EQ(Expression::kTest, expr->expression()->context());
946948

947949
Label push_true;
@@ -1002,6 +1004,37 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
10021004
break;
10031005
}
10041006

1007+
case Token::TYPEOF: {
1008+
Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
1009+
ASSERT_EQ(Expression::kValue, expr->expression()->context());
1010+
1011+
VariableProxy* proxy = expr->expression()->AsVariableProxy();
1012+
if (proxy != NULL && proxy->var()->is_global()) {
1013+
Comment cmnt(masm_, "Global variable");
1014+
__ push(CodeGenerator::GlobalObject());
1015+
__ mov(ecx, Immediate(proxy->name()));
1016+
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1017+
// Use a regular load, not a contextual load, to avoid a reference
1018+
// error.
1019+
__ call(ic, RelocInfo::CODE_TARGET);
1020+
__ mov(Operand(esp, 0), eax);
1021+
} else if (proxy != NULL &&
1022+
proxy->var()->slot() != NULL &&
1023+
proxy->var()->slot()->type() == Slot::LOOKUP) {
1024+
__ push(esi);
1025+
__ push(Immediate(proxy->name()));
1026+
__ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
1027+
__ push(eax);
1028+
} else {
1029+
// This expression cannot throw a reference error at the top level.
1030+
Visit(expr->expression());
1031+
}
1032+
1033+
__ CallRuntime(Runtime::kTypeof, 1);
1034+
Move(expr->context(), eax);
1035+
break;
1036+
}
1037+
10051038
default:
10061039
UNREACHABLE();
10071040
}

src/x64/fast-codegen-x64.cc

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -991,9 +991,9 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
991991

992992

993993
void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
994-
Comment cmnt(masm_, "[ UnaryOperation");
995994
switch (expr->op()) {
996-
case Token::VOID:
995+
case Token::VOID: {
996+
Comment cmnt(masm_, "[ UnaryOperation (VOID)");
997997
Visit(expr->expression());
998998
ASSERT_EQ(Expression::kEffect, expr->expression()->context());
999999
switch (expr->context()) {
@@ -1015,8 +1015,10 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
10151015
break;
10161016
}
10171017
break;
1018+
}
10181019

10191020
case Token::NOT: {
1021+
Comment cmnt(masm_, "[ UnaryOperation (NOT)");
10201022
ASSERT_EQ(Expression::kTest, expr->expression()->context());
10211023

10221024
Label push_true;
@@ -1077,6 +1079,37 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
10771079
break;
10781080
}
10791081

1082+
case Token::TYPEOF: {
1083+
Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
1084+
ASSERT_EQ(Expression::kValue, expr->expression()->context());
1085+
1086+
VariableProxy* proxy = expr->expression()->AsVariableProxy();
1087+
if (proxy != NULL && proxy->var()->is_global()) {
1088+
Comment cmnt(masm_, "Global variable");
1089+
__ push(CodeGenerator::GlobalObject());
1090+
__ Move(rcx, proxy->name());
1091+
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1092+
// Use a regular load, not a contextual load, to avoid a reference
1093+
// error.
1094+
__ Call(ic, RelocInfo::CODE_TARGET);
1095+
__ movq(Operand(rsp, 0), rax);
1096+
} else if (proxy != NULL &&
1097+
proxy->var()->slot() != NULL &&
1098+
proxy->var()->slot()->type() == Slot::LOOKUP) {
1099+
__ push(rsi);
1100+
__ Push(proxy->name());
1101+
__ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
1102+
__ push(rax);
1103+
} else {
1104+
// This expression cannot throw a reference error at the top level.
1105+
Visit(expr->expression());
1106+
}
1107+
1108+
__ CallRuntime(Runtime::kTypeof, 1);
1109+
Move(expr->context(), rax);
1110+
break;
1111+
}
1112+
10801113
default:
10811114
UNREACHABLE();
10821115
}

0 commit comments

Comments
 (0)