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