Index: src/arm/full-codegen-arm.cc |
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc |
index ff77fdf71c25f46b5816d28bb96c6327369f7158..d763db524ad71d15f77248cbb13a8e4ffc9a2b6a 100644 |
--- a/src/arm/full-codegen-arm.cc |
+++ b/src/arm/full-codegen-arm.cc |
@@ -1827,76 +1827,6 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
} |
-void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) { |
- Handle<String> name = expr->name(); |
- if (strcmp("_IsSmi", *name->ToCString()) == 0) { |
- EmitIsSmi(expr->arguments()); |
- } else if (strcmp("_IsNonNegativeSmi", *name->ToCString()) == 0) { |
- EmitIsNonNegativeSmi(expr->arguments()); |
- } else if (strcmp("_IsObject", *name->ToCString()) == 0) { |
- EmitIsObject(expr->arguments()); |
- } else if (strcmp("_IsUndetectableObject", *name->ToCString()) == 0) { |
- EmitIsUndetectableObject(expr->arguments()); |
- } else if (strcmp("_IsFunction", *name->ToCString()) == 0) { |
- EmitIsFunction(expr->arguments()); |
- } else if (strcmp("_IsArray", *name->ToCString()) == 0) { |
- EmitIsArray(expr->arguments()); |
- } else if (strcmp("_IsRegExp", *name->ToCString()) == 0) { |
- EmitIsRegExp(expr->arguments()); |
- } else if (strcmp("_IsConstructCall", *name->ToCString()) == 0) { |
- EmitIsConstructCall(expr->arguments()); |
- } else if (strcmp("_ObjectEquals", *name->ToCString()) == 0) { |
- EmitObjectEquals(expr->arguments()); |
- } else if (strcmp("_Arguments", *name->ToCString()) == 0) { |
- EmitArguments(expr->arguments()); |
- } else if (strcmp("_ArgumentsLength", *name->ToCString()) == 0) { |
- EmitArgumentsLength(expr->arguments()); |
- } else if (strcmp("_ClassOf", *name->ToCString()) == 0) { |
- EmitClassOf(expr->arguments()); |
- } else if (strcmp("_Log", *name->ToCString()) == 0) { |
- EmitLog(expr->arguments()); |
- } else if (strcmp("_RandomHeapNumber", *name->ToCString()) == 0) { |
- EmitRandomHeapNumber(expr->arguments()); |
- } else if (strcmp("_SubString", *name->ToCString()) == 0) { |
- EmitSubString(expr->arguments()); |
- } else if (strcmp("_RegExpExec", *name->ToCString()) == 0) { |
- EmitRegExpExec(expr->arguments()); |
- } else if (strcmp("_ValueOf", *name->ToCString()) == 0) { |
- EmitValueOf(expr->arguments()); |
- } else if (strcmp("_SetValueOf", *name->ToCString()) == 0) { |
- EmitSetValueOf(expr->arguments()); |
- } else if (strcmp("_NumberToString", *name->ToCString()) == 0) { |
- EmitNumberToString(expr->arguments()); |
- } else if (strcmp("_CharFromCode", *name->ToCString()) == 0) { |
- EmitCharFromCode(expr->arguments()); |
- } else if (strcmp("_FastCharCodeAt", *name->ToCString()) == 0) { |
- EmitFastCharCodeAt(expr->arguments()); |
- } else if (strcmp("_StringAdd", *name->ToCString()) == 0) { |
- EmitStringAdd(expr->arguments()); |
- } else if (strcmp("_StringCompare", *name->ToCString()) == 0) { |
- EmitStringCompare(expr->arguments()); |
- } else if (strcmp("_MathPow", *name->ToCString()) == 0) { |
- EmitMathPow(expr->arguments()); |
- } else if (strcmp("_MathSin", *name->ToCString()) == 0) { |
- EmitMathSin(expr->arguments()); |
- } else if (strcmp("_MathCos", *name->ToCString()) == 0) { |
- EmitMathCos(expr->arguments()); |
- } else if (strcmp("_MathSqrt", *name->ToCString()) == 0) { |
- EmitMathSqrt(expr->arguments()); |
- } else if (strcmp("_CallFunction", *name->ToCString()) == 0) { |
- EmitCallFunction(expr->arguments()); |
- } else if (strcmp("_RegExpConstructResult", *name->ToCString()) == 0) { |
- EmitRegExpConstructResult(expr->arguments()); |
- } else if (strcmp("_SwapElements", *name->ToCString()) == 0) { |
- EmitSwapElements(expr->arguments()); |
- } else if (strcmp("_GetFromCache", *name->ToCString()) == 0) { |
- EmitGetFromCache(expr->arguments()); |
- } else { |
- UNREACHABLE(); |
- } |
-} |
- |
- |
void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { |
ASSERT(args->length() == 1); |
@@ -2347,49 +2277,120 @@ void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { |
} |
-void FullCodeGenerator::EmitCharFromCode(ZoneList<Expression*>* args) { |
+void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) { |
ASSERT(args->length() == 1); |
VisitForValue(args->at(0), kAccumulator); |
- Label slow_case, done; |
- // Fast case of Heap::LookupSingleCharacterStringFromCode. |
- ASSERT(kSmiTag == 0); |
- ASSERT(kSmiShiftSize == 0); |
- ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1)); |
- __ tst(r0, Operand(kSmiTagMask | |
- ((~String::kMaxAsciiCharCode) << kSmiTagSize))); |
- __ b(nz, &slow_case); |
- __ mov(r1, Operand(Factory::single_character_string_cache())); |
- ASSERT(kSmiTag == 0); |
- ASSERT(kSmiTagSize == 1); |
- ASSERT(kSmiShiftSize == 0); |
- // At this point code register contains smi tagged ascii char code. |
- __ add(r1, r1, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
- __ ldr(r1, MemOperand(r1, FixedArray::kHeaderSize - kHeapObjectTag)); |
- __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
- __ cmp(r1, r2); |
- __ b(eq, &slow_case); |
- __ mov(r0, r1); |
- __ b(&done); |
+ Label done; |
+ StringCharFromCodeGenerator generator(r0, r1); |
+ generator.GenerateFast(masm_); |
+ __ jmp(&done); |
- __ bind(&slow_case); |
- __ push(r0); |
- __ CallRuntime(Runtime::kCharFromCode, 1); |
+ NopRuntimeCallHelper call_helper; |
+ generator.GenerateSlow(masm_, call_helper); |
__ bind(&done); |
- Apply(context_, r0); |
+ Apply(context_, r1); |
} |
-void FullCodeGenerator::EmitFastCharCodeAt(ZoneList<Expression*>* args) { |
- // TODO(fsc): Port the complete implementation from the classic back-end. |
- // Move the undefined value into the result register, which will |
- // trigger the slow case. |
- __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
- Apply(context_, r0); |
+void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) { |
+ ASSERT(args->length() == 2); |
+ |
+ VisitForValue(args->at(0), kStack); |
+ VisitForValue(args->at(1), kAccumulator); |
+ |
+ Register object = r1; |
+ Register index = r0; |
+ Register scratch = r2; |
+ Register result = r3; |
+ |
+ __ pop(object); |
+ |
+ Label need_conversion; |
+ Label index_out_of_range; |
+ Label done; |
+ StringCharCodeAtGenerator generator(object, |
+ index, |
+ scratch, |
+ result, |
+ &need_conversion, |
+ &need_conversion, |
+ &index_out_of_range, |
+ STRING_ANY_NUMBER_INDEX); |
+ generator.GenerateFast(masm_); |
+ __ jmp(&done); |
+ |
+ __ bind(&index_out_of_range); |
+ // When the index is out of range, the spec requires us to return |
+ // NaN. |
+ __ LoadRoot(result, Heap::kNanValueRootIndex); |
+ __ jmp(&done); |
+ |
+ __ bind(&need_conversion); |
+ // Load the undefined value into the result register, which will |
+ // trigger conversion. |
+ __ LoadRoot(result, Heap::kUndefinedValueRootIndex); |
+ __ jmp(&done); |
+ |
+ NopRuntimeCallHelper call_helper; |
+ generator.GenerateSlow(masm_, call_helper); |
+ |
+ __ bind(&done); |
+ Apply(context_, result); |
+} |
+ |
+ |
+void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) { |
+ ASSERT(args->length() == 2); |
+ |
+ VisitForValue(args->at(0), kStack); |
+ VisitForValue(args->at(1), kAccumulator); |
+ |
+ Register object = r1; |
+ Register index = r0; |
+ Register scratch1 = r2; |
+ Register scratch2 = r3; |
+ Register result = r0; |
+ |
+ __ pop(object); |
+ |
+ Label need_conversion; |
+ Label index_out_of_range; |
+ Label done; |
+ StringCharAtGenerator generator(object, |
+ index, |
+ scratch1, |
+ scratch2, |
+ result, |
+ &need_conversion, |
+ &need_conversion, |
+ &index_out_of_range, |
+ STRING_ANY_NUMBER_INDEX); |
+ generator.GenerateFast(masm_); |
+ __ jmp(&done); |
+ |
+ __ bind(&index_out_of_range); |
+ // When the index is out of range, the spec requires us to return |
+ // the empty string. |
+ __ LoadRoot(result, Heap::kEmptyStringRootIndex); |
+ __ jmp(&done); |
+ |
+ __ bind(&need_conversion); |
+ // Move smi zero into the result register, which will trigger |
+ // conversion. |
+ __ mov(result, Operand(Smi::FromInt(0))); |
+ __ jmp(&done); |
+ |
+ NopRuntimeCallHelper call_helper; |
+ generator.GenerateSlow(masm_, call_helper); |
+ |
+ __ bind(&done); |
+ Apply(context_, result); |
} |
+ |
void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { |
ASSERT_EQ(2, args->length()); |