| 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());
|
|
|
|
|