Index: src/arm/stub-cache-arm.cc |
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc |
index 2a7c22d744a4fe89dd409856b5d1e934977a087b..344cb6fb9031da5ed2909a27692de72fbfec07c5 100644 |
--- a/src/arm/stub-cache-arm.cc |
+++ b/src/arm/stub-cache-arm.cc |
@@ -1363,8 +1363,68 @@ Object* CallStubCompiler::CompileStringCharCodeAtCall(Object* object, |
JSFunction* function, |
String* name, |
CheckType check) { |
- // TODO(722): implement this. |
- return Heap::undefined_value(); |
+ // ----------- S t a t e ------------- |
+ // -- r2 : function name |
+ // -- lr : return address |
+ // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
+ // -- ... |
+ // -- sp[argc * 4] : receiver |
+ // ----------------------------------- |
+ |
+ // If object is not a string, bail out to regular call. |
+ if (!object->IsString()) return Heap::undefined_value(); |
+ |
+ const int argc = arguments().immediate(); |
+ |
+ Label miss; |
+ Label index_out_of_range; |
+ GenerateNameCheck(name, &miss); |
+ |
+ // Check that the maps starting from the prototype haven't changed. |
+ GenerateDirectLoadGlobalFunctionPrototype(masm(), |
+ Context::STRING_FUNCTION_INDEX, |
+ r0); |
+ ASSERT(object != holder); |
+ CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, |
+ r1, r3, r4, name, &miss); |
+ |
+ Register receiver = r1; |
+ Register index = r4; |
+ Register scratch = r3; |
+ Register result = r0; |
+ __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
+ if (argc > 0) { |
+ __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
+ } else { |
+ __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
+ } |
+ |
+ StringCharCodeAtGenerator char_code_at_generator(receiver, |
+ index, |
+ scratch, |
+ result, |
+ &miss, // When not a string. |
+ &miss, // When not a number. |
+ &index_out_of_range, |
+ STRING_INDEX_IS_NUMBER); |
+ char_code_at_generator.GenerateFast(masm()); |
+ __ Drop(argc + 1); |
+ __ Ret(); |
+ |
+ ICRuntimeCallHelper call_helper; |
+ char_code_at_generator.GenerateSlow(masm(), call_helper); |
+ |
+ __ bind(&index_out_of_range); |
+ __ LoadRoot(r0, Heap::kNanValueRootIndex); |
+ __ Drop(argc + 1); |
+ __ Ret(); |
+ |
+ __ bind(&miss); |
+ Object* obj = GenerateMissBranch(); |
+ if (obj->IsFailure()) return obj; |
+ |
+ // Return the generated code. |
+ return GetCode(function); |
} |
@@ -1373,8 +1433,71 @@ Object* CallStubCompiler::CompileStringCharAtCall(Object* object, |
JSFunction* function, |
String* name, |
CheckType check) { |
- // TODO(722): implement this. |
- return Heap::undefined_value(); |
+ // ----------- S t a t e ------------- |
+ // -- r2 : function name |
+ // -- lr : return address |
+ // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
+ // -- ... |
+ // -- sp[argc * 4] : receiver |
+ // ----------------------------------- |
+ |
+ // If object is not a string, bail out to regular call. |
+ if (!object->IsString()) return Heap::undefined_value(); |
+ |
+ const int argc = arguments().immediate(); |
+ |
+ Label miss; |
+ Label index_out_of_range; |
+ |
+ GenerateNameCheck(name, &miss); |
+ |
+ // Check that the maps starting from the prototype haven't changed. |
+ GenerateDirectLoadGlobalFunctionPrototype(masm(), |
+ Context::STRING_FUNCTION_INDEX, |
+ r0); |
+ ASSERT(object != holder); |
+ CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, |
+ r1, r3, r4, name, &miss); |
+ |
+ Register receiver = r0; |
+ Register index = r4; |
+ Register scratch1 = r1; |
+ Register scratch2 = r3; |
+ Register result = r0; |
+ __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
+ if (argc > 0) { |
+ __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
+ } else { |
+ __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
+ } |
+ |
+ StringCharAtGenerator char_at_generator(receiver, |
+ index, |
+ scratch1, |
+ scratch2, |
+ result, |
+ &miss, // When not a string. |
+ &miss, // When not a number. |
+ &index_out_of_range, |
+ STRING_INDEX_IS_NUMBER); |
+ char_at_generator.GenerateFast(masm()); |
+ __ Drop(argc + 1); |
+ __ Ret(); |
+ |
+ ICRuntimeCallHelper call_helper; |
+ char_at_generator.GenerateSlow(masm(), call_helper); |
+ |
+ __ bind(&index_out_of_range); |
+ __ LoadRoot(r0, Heap::kEmptyStringRootIndex); |
+ __ Drop(argc + 1); |
+ __ Ret(); |
+ |
+ __ bind(&miss); |
+ Object* obj = GenerateMissBranch(); |
+ if (obj->IsFailure()) return obj; |
+ |
+ // Return the generated code. |
+ return GetCode(function); |
} |