Index: src/arm/full-codegen-arm.cc |
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc |
index 3d75c143aa118ff965337a4dce8ffa2a1cca730b..d0c663b4081d77fd0a191727e9ff075dba49cedb 100644 |
--- a/src/arm/full-codegen-arm.cc |
+++ b/src/arm/full-codegen-arm.cc |
@@ -394,7 +394,7 @@ void FullCodeGenerator::TestContext::Plug(Variable* var) const { |
ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
// For simplicity we always test the accumulator register. |
codegen()->GetVar(result_register(), var); |
- codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); |
+ codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
codegen()->DoTest(this); |
} |
@@ -417,7 +417,7 @@ void FullCodeGenerator::StackValueContext::Plug( |
void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { |
- codegen()->PrepareForBailoutBeforeSplit(TOS_REG, |
+ codegen()->PrepareForBailoutBeforeSplit(condition(), |
true, |
true_label_, |
false_label_); |
@@ -452,7 +452,7 @@ void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { |
void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { |
- codegen()->PrepareForBailoutBeforeSplit(TOS_REG, |
+ codegen()->PrepareForBailoutBeforeSplit(condition(), |
true, |
true_label_, |
false_label_); |
@@ -511,7 +511,7 @@ void FullCodeGenerator::TestContext::DropAndPlug(int count, |
// For simplicity we always test the accumulator register. |
__ Drop(count); |
__ Move(result_register(), reg); |
- codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); |
+ codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
codegen()->DoTest(this); |
} |
@@ -578,7 +578,7 @@ void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
void FullCodeGenerator::TestContext::Plug(bool flag) const { |
- codegen()->PrepareForBailoutBeforeSplit(TOS_REG, |
+ codegen()->PrepareForBailoutBeforeSplit(condition(), |
true, |
true_label_, |
false_label_); |
@@ -681,7 +681,7 @@ void FullCodeGenerator::SetVar(Variable* var, |
} |
-void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state, |
+void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, |
bool should_normalize, |
Label* if_true, |
Label* if_false) { |
@@ -692,13 +692,7 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state, |
Label skip; |
if (should_normalize) __ b(&skip); |
- |
- ForwardBailoutStack* current = forward_bailout_stack_; |
- while (current != NULL) { |
- PrepareForBailout(current->expr(), state); |
- current = current->parent(); |
- } |
- |
+ PrepareForBailout(expr, TOS_REG); |
if (should_normalize) { |
__ LoadRoot(ip, Heap::kTrueValueRootIndex); |
__ cmp(r0, ip); |
@@ -2377,7 +2371,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
} |
-void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForAccumulatorValue(args->at(0)); |
@@ -2389,7 +2384,7 @@ void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { |
context()->PrepareTest(&materialize_true, &materialize_false, |
&if_true, &if_false, &fall_through); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
__ tst(r0, Operand(kSmiTagMask)); |
Split(eq, if_true, if_false, fall_through); |
@@ -2397,7 +2392,8 @@ void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForAccumulatorValue(args->at(0)); |
@@ -2409,7 +2405,7 @@ void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) { |
context()->PrepareTest(&materialize_true, &materialize_false, |
&if_true, &if_false, &fall_through); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
__ tst(r0, Operand(kSmiTagMask | 0x80000000)); |
Split(eq, if_true, if_false, fall_through); |
@@ -2417,7 +2413,8 @@ void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitIsObject(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForAccumulatorValue(args->at(0)); |
@@ -2442,14 +2439,15 @@ void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) { |
__ cmp(r1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
__ b(lt, if_false); |
__ cmp(r1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
Split(le, if_true, if_false, fall_through); |
context()->Plug(if_true, if_false); |
} |
-void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForAccumulatorValue(args->at(0)); |
@@ -2463,14 +2461,15 @@ void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) { |
__ JumpIfSmi(r0, if_false); |
__ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
Split(ge, if_true, if_false, fall_through); |
context()->Plug(if_true, if_false); |
} |
-void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForAccumulatorValue(args->at(0)); |
@@ -2486,7 +2485,7 @@ void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { |
__ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); |
__ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset)); |
__ tst(r1, Operand(1 << Map::kIsUndetectable)); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
Split(ne, if_true, if_false, fall_through); |
context()->Plug(if_true, if_false); |
@@ -2494,8 +2493,8 @@ void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { |
void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( |
- ZoneList<Expression*>* args) { |
- |
+ CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForAccumulatorValue(args->at(0)); |
@@ -2574,12 +2573,13 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( |
__ strb(r2, FieldMemOperand(r1, Map::kBitField2Offset)); |
__ jmp(if_true); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
context()->Plug(if_true, if_false); |
} |
-void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForAccumulatorValue(args->at(0)); |
@@ -2593,14 +2593,15 @@ void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { |
__ JumpIfSmi(r0, if_false); |
__ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
Split(eq, if_true, if_false, fall_through); |
context()->Plug(if_true, if_false); |
} |
-void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForAccumulatorValue(args->at(0)); |
@@ -2614,14 +2615,15 @@ void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { |
__ JumpIfSmi(r0, if_false); |
__ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
Split(eq, if_true, if_false, fall_through); |
context()->Plug(if_true, if_false); |
} |
-void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForAccumulatorValue(args->at(0)); |
@@ -2635,7 +2637,7 @@ void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { |
__ JumpIfSmi(r0, if_false); |
__ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
Split(eq, if_true, if_false, fall_through); |
context()->Plug(if_true, if_false); |
@@ -2643,8 +2645,8 @@ void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { |
-void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { |
- ASSERT(args->length() == 0); |
+void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) { |
+ ASSERT(expr->arguments()->length() == 0); |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
@@ -2667,14 +2669,15 @@ void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { |
__ bind(&check_frame_marker); |
__ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset)); |
__ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
Split(eq, if_true, if_false, fall_through); |
context()->Plug(if_true, if_false); |
} |
-void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 2); |
// Load the two objects into registers and perform the comparison. |
@@ -2690,14 +2693,15 @@ void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) { |
__ pop(r1); |
__ cmp(r0, r1); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
Split(eq, if_true, if_false, fall_through); |
context()->Plug(if_true, if_false); |
} |
-void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitArguments(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
// ArgumentsAccessStub expects the key in edx and the formal |
@@ -2711,9 +2715,8 @@ void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { |
- ASSERT(args->length() == 0); |
- |
+void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { |
+ ASSERT(expr->arguments()->length() == 0); |
Label exit; |
// Get the number of formal parameters. |
__ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); |
@@ -2733,7 +2736,8 @@ void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitClassOf(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
Label done, null, function, non_function_constructor; |
@@ -2793,7 +2797,7 @@ void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitLog(CallRuntime* expr) { |
// Conditionally generate a log call. |
// Args: |
// 0 (literal string): The type of logging (corresponds to the flags). |
@@ -2801,6 +2805,7 @@ void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) { |
// 1 (string): Format string. Access the string at argument index 2 |
// with '%2s' (see Logger::LogRuntime for all the formats). |
// 2 (array): Arguments to the format string. |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT_EQ(args->length(), 3); |
if (CodeGenerator::ShouldGenerateLog(args->at(0))) { |
VisitForStackValue(args->at(1)); |
@@ -2814,9 +2819,8 @@ void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { |
- ASSERT(args->length() == 0); |
- |
+void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) { |
+ ASSERT(expr->arguments()->length() == 0); |
Label slow_allocate_heapnumber; |
Label heapnumber_allocated; |
@@ -2868,9 +2872,10 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
// Load the arguments on the stack and call the stub. |
SubStringStub stub; |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 3); |
VisitForStackValue(args->at(0)); |
VisitForStackValue(args->at(1)); |
@@ -2880,9 +2885,10 @@ void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
// Load the arguments on the stack and call the stub. |
RegExpExecStub stub; |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 4); |
VisitForStackValue(args->at(0)); |
VisitForStackValue(args->at(1)); |
@@ -2893,9 +2899,9 @@ void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
- |
VisitForAccumulatorValue(args->at(0)); // Load the object. |
Label done; |
@@ -2911,8 +2917,9 @@ void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
// Load the arguments on the stack and call the runtime function. |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 2); |
VisitForStackValue(args->at(0)); |
VisitForStackValue(args->at(1)); |
@@ -2922,9 +2929,9 @@ void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 2); |
- |
VisitForStackValue(args->at(0)); // Load the object. |
VisitForAccumulatorValue(args->at(1)); // Load the value. |
__ pop(r1); // r0 = value. r1 = object. |
@@ -2950,9 +2957,9 @@ void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT_EQ(args->length(), 1); |
- |
// Load the argument on the stack and call the stub. |
VisitForStackValue(args->at(0)); |
@@ -2962,9 +2969,9 @@ void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
- |
VisitForAccumulatorValue(args->at(0)); |
Label done; |
@@ -2980,9 +2987,9 @@ void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 2); |
- |
VisitForStackValue(args->at(0)); |
VisitForAccumulatorValue(args->at(1)); |
@@ -3027,9 +3034,9 @@ void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 2); |
- |
VisitForStackValue(args->at(0)); |
VisitForAccumulatorValue(args->at(1)); |
@@ -3076,9 +3083,9 @@ void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT_EQ(2, args->length()); |
- |
VisitForStackValue(args->at(0)); |
VisitForStackValue(args->at(1)); |
@@ -3088,9 +3095,9 @@ void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT_EQ(2, args->length()); |
- |
VisitForStackValue(args->at(0)); |
VisitForStackValue(args->at(1)); |
@@ -3100,10 +3107,11 @@ void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitMathSin(CallRuntime* expr) { |
// Load the argument on the stack and call the stub. |
TranscendentalCacheStub stub(TranscendentalCache::SIN, |
TranscendentalCacheStub::TAGGED); |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForStackValue(args->at(0)); |
__ CallStub(&stub); |
@@ -3111,10 +3119,11 @@ void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitMathCos(CallRuntime* expr) { |
// Load the argument on the stack and call the stub. |
TranscendentalCacheStub stub(TranscendentalCache::COS, |
TranscendentalCacheStub::TAGGED); |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForStackValue(args->at(0)); |
__ CallStub(&stub); |
@@ -3122,10 +3131,11 @@ void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitMathLog(CallRuntime* expr) { |
// Load the argument on the stack and call the stub. |
TranscendentalCacheStub stub(TranscendentalCache::LOG, |
TranscendentalCacheStub::TAGGED); |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForStackValue(args->at(0)); |
__ CallStub(&stub); |
@@ -3133,8 +3143,9 @@ void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) { |
// Load the argument on the stack and call the runtime function. |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForStackValue(args->at(0)); |
__ CallRuntime(Runtime::kMath_sqrt, 1); |
@@ -3142,7 +3153,8 @@ void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() >= 2); |
int arg_count = args->length() - 2; // 2 ~ receiver and function. |
@@ -3161,8 +3173,9 @@ void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { |
RegExpConstructResultStub stub; |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 3); |
VisitForStackValue(args->at(0)); |
VisitForStackValue(args->at(1)); |
@@ -3172,7 +3185,8 @@ void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitSwapElements(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 3); |
VisitForStackValue(args->at(0)); |
VisitForStackValue(args->at(1)); |
@@ -3269,9 +3283,9 @@ void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT_EQ(2, args->length()); |
- |
ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); |
@@ -3320,7 +3334,8 @@ void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitIsRegExpEquivalent(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT_EQ(2, args->length()); |
Register right = r0; |
@@ -3360,7 +3375,8 @@ void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
VisitForAccumulatorValue(args->at(0)); |
Label materialize_true, materialize_false; |
@@ -3372,14 +3388,15 @@ void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { |
__ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset)); |
__ tst(r0, Operand(String::kContainsCachedArrayIndexMask)); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
Split(eq, if_true, if_false, fall_through); |
context()->Plug(if_true, if_false); |
} |
-void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 1); |
VisitForAccumulatorValue(args->at(0)); |
@@ -3394,12 +3411,12 @@ void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { |
Label bailout, done, one_char_separator, long_separator, |
non_trivial_array, not_size_one_array, loop, |
empty_separator_loop, one_char_separator_loop, |
one_char_separator_loop_entry, long_separator_loop; |
- |
+ ZoneList<Expression*>* args = expr->arguments(); |
ASSERT(args->length() == 2); |
VisitForStackValue(args->at(1)); |
VisitForAccumulatorValue(args->at(0)); |
@@ -3727,18 +3744,35 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
// Unary NOT has no side effects so it's only necessary to visit the |
// subexpression. Match the optimizing compiler by not branching. |
VisitForEffect(expr->expression()); |
+ } else if (context()->IsTest()) { |
+ const TestContext* test = TestContext::cast(context()); |
+ // The labels are swapped for the recursive call. |
+ VisitForControl(expr->expression(), |
+ test->false_label(), |
+ test->true_label(), |
+ test->fall_through()); |
+ context()->Plug(test->true_label(), test->false_label()); |
} else { |
- Label materialize_true, materialize_false; |
- Label* if_true = NULL; |
- Label* if_false = NULL; |
- Label* fall_through = NULL; |
- |
- // Notice that the labels are swapped. |
- context()->PrepareTest(&materialize_true, &materialize_false, |
- &if_false, &if_true, &fall_through); |
- if (context()->IsTest()) ForwardBailoutToChild(expr); |
- VisitForControl(expr->expression(), if_true, if_false, fall_through); |
- context()->Plug(if_false, if_true); // Labels swapped. |
+ // We handle value contexts explicitly rather than simply visiting |
+ // for control and plugging the control flow into the context, |
+ // because we need to prepare a pair of extra administrative AST ids |
+ // for the optimizing compiler. |
+ ASSERT(context()->IsAccumulatorValue() || context()->IsStackValue()); |
+ Label materialize_true, materialize_false, done; |
+ VisitForControl(expr->expression(), |
+ &materialize_false, |
+ &materialize_true, |
+ &materialize_true); |
+ __ bind(&materialize_true); |
+ PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); |
+ __ LoadRoot(r0, Heap::kTrueValueRootIndex); |
+ if (context()->IsStackValue()) __ push(r0); |
+ __ jmp(&done); |
+ __ bind(&materialize_false); |
+ PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); |
+ __ LoadRoot(r0, Heap::kFalseValueRootIndex); |
+ if (context()->IsStackValue()) __ push(r0); |
+ __ bind(&done); |
} |
break; |
} |
@@ -3997,12 +4031,13 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
context()->Plug(r0); |
} else { |
// This expression cannot throw a reference error at the top level. |
- VisitInCurrentContext(expr); |
+ VisitInDuplicateContext(expr); |
} |
} |
void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
+ Expression* sub_expr, |
Handle<String> check) { |
Label materialize_true, materialize_false; |
Label* if_true = NULL; |
@@ -4012,9 +4047,9 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
&if_true, &if_false, &fall_through); |
{ AccumulatorValueContext context(this); |
- VisitForTypeofValue(expr); |
+ VisitForTypeofValue(sub_expr); |
} |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
if (check->Equals(isolate()->heap()->number_symbol())) { |
__ JumpIfSmi(r0, if_true); |
@@ -4101,7 +4136,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
case Token::IN: |
VisitForStackValue(expr->right()); |
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
- PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); |
+ PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
__ LoadRoot(ip, Heap::kTrueValueRootIndex); |
__ cmp(r0, ip); |
Split(eq, if_true, if_false, fall_through); |
@@ -4111,7 +4146,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
VisitForStackValue(expr->right()); |
InstanceofStub stub(InstanceofStub::kNoFlags); |
__ CallStub(&stub); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
// The stub returns 0 for true. |
__ tst(r0, r0); |
Split(eq, if_true, if_false, fall_through); |
@@ -4161,7 +4196,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
Handle<Code> ic = CompareIC::GetUninitialized(op); |
__ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
patch_site.EmitPatchInfo(); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
__ cmp(r0, Operand(0)); |
Split(cond, if_true, if_false, fall_through); |
} |
@@ -4184,7 +4219,7 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, |
&if_true, &if_false, &fall_through); |
VisitForAccumulatorValue(sub_expr); |
- PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
Heap::RootListIndex nil_value = nil == kNullValue ? |
Heap::kNullValueRootIndex : |
Heap::kUndefinedValueRootIndex; |