Index: src/ia32/fast-codegen-ia32.cc |
=================================================================== |
--- src/ia32/fast-codegen-ia32.cc (revision 3192) |
+++ src/ia32/fast-codegen-ia32.cc (working copy) |
@@ -932,6 +932,79 @@ |
} |
+void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { |
+ VariableProxy* v = expr->expression()->AsVariableProxy(); |
+ ASSERT(v->AsVariable() != NULL); |
+ ASSERT(v->AsVariable()->is_global()); |
+ |
+ Visit(v); |
+ |
+ __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); |
+ |
+ switch (expr->context()) { |
+ case Expression::kUninitialized: |
+ UNREACHABLE(); |
+ case Expression::kValue: // Fall through |
+ case Expression::kTest: // Fall through |
+ case Expression::kTestValue: // Fall through |
+ case Expression::kValueTest: |
+ // Duplicate the result on the stack. |
+ __ push(eax); |
+ break; |
+ case Expression::kEffect: |
+ // Do not save result. |
+ break; |
+ } |
+ // Call runtime for +1/-1. |
+ __ push(eax); |
+ __ push(Immediate(Smi::FromInt(1))); |
+ if (expr->op() == Token::INC) { |
+ __ CallRuntime(Runtime::kNumberAdd, 2); |
+ } else { |
+ __ CallRuntime(Runtime::kNumberSub, 2); |
+ } |
+ // Call Store IC. |
+ __ mov(ecx, v->AsVariable()->name()); |
+ __ push(CodeGenerator::GlobalObject()); |
+ Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
+ __ call(ic, RelocInfo::CODE_TARGET); |
+ // Restore up stack after store IC. |
+ __ add(Operand(esp), Immediate(kPointerSize)); |
+ |
+ switch (expr->context()) { |
+ case Expression::kUninitialized: |
+ UNREACHABLE(); |
+ case Expression::kEffect: // Fall through |
+ case Expression::kValue: |
+ // Do nothing. Result in either on the stack for value context |
+ // or discarded for effect context. |
+ break; |
+ case Expression::kTest: |
+ __ pop(eax); |
+ TestAndBranch(eax, true_label_, false_label_); |
+ break; |
+ case Expression::kValueTest: { |
+ Label discard; |
+ __ mov(eax, Operand(esp, 0)); |
+ TestAndBranch(eax, true_label_, &discard); |
+ __ bind(&discard); |
+ __ add(Operand(esp), Immediate(kPointerSize)); |
+ __ jmp(false_label_); |
+ break; |
+ } |
+ case Expression::kTestValue: { |
+ Label discard; |
+ __ mov(eax, Operand(esp, 0)); |
+ TestAndBranch(eax, &discard, false_label_); |
+ __ bind(&discard); |
+ __ add(Operand(esp), Immediate(kPointerSize)); |
+ __ jmp(true_label_); |
+ break; |
+ } |
+ } |
+} |
+ |
+ |
void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { |
switch (expr->op()) { |
case Token::COMMA: |