diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index c47af75446..42373e3deb 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -4833,6 +4833,61 @@ void StringCompareStub::Generate(MacroAssembler* masm) { __ TailCallRuntime(Runtime::kStringCompare, 2, 1); } + +void StringCharAtStub::Generate(MacroAssembler* masm) { + // Expects two arguments (object, index) on the stack: + + // Stack frame on entry. + // rsp[0]: return address + // rsp[8]: index + // rsp[16]: object + + Register object = rbx; + Register index = rax; + Register scratch1 = rcx; + Register scratch2 = rdx; + Register result = rax; + + __ pop(scratch1); // Return address. + __ pop(index); + __ pop(object); + __ push(scratch1); + + 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_INDEX_IS_NUMBER); + 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. + __ Move(result, Factory::empty_string()); + __ jmp(&done); + + __ bind(&need_conversion); + // Move smi zero into the result register, which will trigger + // conversion. + __ Move(result, Smi::FromInt(0)); + __ jmp(&done); + + StubRuntimeCallHelper call_helper; + generator.GenerateSlow(masm, call_helper); + + __ bind(&done); + __ ret(0); +} + + void ICCompareStub::GenerateSmis(MacroAssembler* masm) { ASSERT(state_ == CompareIC::SMIS); NearLabel miss; diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index e23fb89f98..d281c2fdf2 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -705,8 +705,8 @@ void LCodeGen::DoCallStub(LCallStub* instr) { break; } case CodeStub::StringCharAt: { - // TODO(1116): Add StringCharAt stub to x64. - Abort("Unimplemented: %s", "StringCharAt Stub"); + StringCharAtStub stub; + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); break; } case CodeStub::MathPow: {