Index: src/ia32/full-codegen-ia32.cc |
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc |
index 49a761f050d7597330b2b7082f13a6ba682a3cf0..39a713b47a400de25e0f32e477ae13157c2e04c1 100644 |
--- a/src/ia32/full-codegen-ia32.cc |
+++ b/src/ia32/full-codegen-ia32.cc |
@@ -1902,76 +1902,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); |
@@ -2430,50 +2360,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)); |
- __ test(eax, |
- Immediate(kSmiTagMask | |
- ((~String::kMaxAsciiCharCode) << kSmiTagSize))); |
- __ j(not_zero, &slow_case); |
- __ Set(ebx, Immediate(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. |
- __ mov(ebx, FieldOperand(ebx, |
- eax, times_half_pointer_size, |
- FixedArray::kHeaderSize)); |
- __ cmp(ebx, Factory::undefined_value()); |
- __ j(equal, &slow_case); |
- __ mov(eax, ebx); |
+ Label done; |
+ StringCharFromCodeGenerator generator(eax, ebx); |
+ generator.GenerateFast(masm_); |
__ jmp(&done); |
- __ bind(&slow_case); |
- __ push(eax); |
- __ CallRuntime(Runtime::kCharFromCode, 1); |
+ NopRuntimeCallHelper call_helper; |
+ generator.GenerateSlow(masm_, call_helper); |
__ bind(&done); |
- Apply(context_, eax); |
+ Apply(context_, ebx); |
} |
-void FullCodeGenerator::EmitFastCharCodeAt(ZoneList<Expression*>* args) { |
- // TODO(fsc): Port the complete implementation from the classic back-end. |
+void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) { |
+ ASSERT(args->length() == 2); |
+ |
+ VisitForValue(args->at(0), kStack); |
+ VisitForValue(args->at(1), kAccumulator); |
+ |
+ Register object = ebx; |
+ Register index = eax; |
+ Register scratch = ecx; |
+ Register result = edx; |
+ |
+ __ 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. |
+ __ Set(result, Immediate(Factory::nan_value())); |
+ __ jmp(&done); |
+ |
+ __ bind(&need_conversion); |
// Move the undefined value into the result register, which will |
- // trigger the slow case. |
- __ Set(eax, Immediate(Factory::undefined_value())); |
- Apply(context_, eax); |
+ // trigger conversion. |
+ __ Set(result, Immediate(Factory::undefined_value())); |
+ __ 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 = ebx; |
+ Register index = eax; |
+ Register scratch1 = ecx; |
+ Register scratch2 = edx; |
+ Register result = eax; |
+ |
+ __ 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. |
+ __ Set(result, Immediate(Factory::empty_string())); |
+ __ jmp(&done); |
+ |
+ __ bind(&need_conversion); |
+ // Move smi zero into the result register, which will trigger |
+ // conversion. |
+ __ Set(result, Immediate(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()); |