Index: src/ia32/stub-cache-ia32.cc |
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc |
index e584cbbbae74c71f86efa48e4f48d0a444f50c69..b24f8f555cf48c1a75ced249c13eb9df814cf687 100644 |
--- a/src/ia32/stub-cache-ia32.cc |
+++ b/src/ia32/stub-cache-ia32.cc |
@@ -1354,6 +1354,140 @@ Object* CallStubCompiler::CompileArrayPopCall(Object* object, |
} |
+Object* CallStubCompiler::CompileStringCharCodeAtCall(Object* object, |
+ JSObject* holder, |
+ JSFunction* function, |
+ String* name, |
+ CheckType check) { |
+ // ----------- S t a t e ------------- |
+ // -- ecx : function name |
+ // -- esp[0] : return address |
+ // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
+ // -- ... |
+ // -- esp[(argc + 1) * 4] : receiver |
+ // ----------------------------------- |
+ |
+ const int argc = arguments().immediate(); |
+ |
+ Label miss; |
+ Label index_out_of_range; |
+ |
+ // Check that the maps starting from the prototype haven't changed. |
+ GenerateLoadGlobalFunctionPrototype(masm(), |
+ Context::STRING_FUNCTION_INDEX, |
+ eax); |
+ CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, |
+ ebx, edx, name, &miss); |
+ |
+ Register receiver = ebx; |
+ Register index = ecx; |
+ Register scratch = edx; |
+ Register result = eax; |
+ __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); |
+ if (argc > 0) { |
+ __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); |
+ } else { |
+ __ Set(index, Immediate(Factory::undefined_value())); |
+ } |
+ |
+ StringCharCodeAtGenerator char_code_at_generator(receiver, |
+ index, |
+ scratch, |
+ result, |
+ &miss, // When not a string. |
+ &miss, // When not a number. |
+ &index_out_of_range, |
+ STRING_ANY_NUMBER_INDEX); |
+ char_code_at_generator.GenerateFast(masm()); |
+ __ ret((argc + 1) * kPointerSize); |
+ |
+ ICRuntimeCallHelper call_helper; |
+ char_code_at_generator.GenerateSlow(masm(), call_helper); |
+ |
+ __ bind(&index_out_of_range); |
+ __ Set(eax, Immediate(Factory::nan_value())); |
+ __ ret((argc + 1) * kPointerSize); |
+ |
+ __ bind(&miss); |
+ // Restore function name in ecx. |
+ __ Set(ecx, Immediate(Handle<String>(name))); |
+ |
+ Handle<Code> ic = ComputeCallMiss(argc); |
+ __ jmp(ic, RelocInfo::CODE_TARGET); |
+ |
+ // Return the generated code. |
+ return GetCode(function); |
+} |
+ |
+ |
+Object* CallStubCompiler::CompileStringCharAtCall(Object* object, |
+ JSObject* holder, |
+ JSFunction* function, |
+ String* name, |
+ CheckType check) { |
+ // ----------- S t a t e ------------- |
+ // -- ecx : function name |
+ // -- esp[0] : return address |
+ // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
+ // -- ... |
+ // -- esp[(argc + 1) * 4] : receiver |
+ // ----------------------------------- |
+ |
+ const int argc = arguments().immediate(); |
+ |
+ Label miss; |
+ Label index_out_of_range; |
+ |
+ // Check that the maps starting from the prototype haven't changed. |
+ GenerateLoadGlobalFunctionPrototype(masm(), |
+ Context::STRING_FUNCTION_INDEX, |
+ eax); |
+ CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, |
+ ebx, edx, name, &miss); |
+ |
+ Register receiver = eax; |
+ Register index = ecx; |
+ Register scratch1 = ebx; |
+ Register scratch2 = edx; |
+ Register result = eax; |
+ __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); |
+ if (argc > 0) { |
+ __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); |
+ } else { |
+ __ Set(index, Immediate(Factory::undefined_value())); |
+ } |
+ |
+ StringCharAtGenerator char_at_generator(receiver, |
+ index, |
+ scratch1, |
+ scratch2, |
+ result, |
+ &miss, // When not a string. |
+ &miss, // When not a number. |
+ &index_out_of_range, |
+ STRING_ANY_NUMBER_INDEX); |
+ char_at_generator.GenerateFast(masm()); |
+ __ ret((argc + 1) * kPointerSize); |
+ |
+ ICRuntimeCallHelper call_helper; |
+ char_at_generator.GenerateSlow(masm(), call_helper); |
+ |
+ __ bind(&index_out_of_range); |
+ __ Set(eax, Immediate(Factory::empty_string())); |
+ __ ret((argc + 1) * kPointerSize); |
+ |
+ __ bind(&miss); |
+ // Restore function name in ecx. |
+ __ Set(ecx, Immediate(Handle<String>(name))); |
+ |
+ Handle<Code> ic = ComputeCallMiss(argc); |
+ __ jmp(ic, RelocInfo::CODE_TARGET); |
+ |
+ // Return the generated code. |
+ return GetCode(function); |
+} |
+ |
+ |
Object* CallStubCompiler::CompileCallConstant(Object* object, |
JSObject* holder, |
JSFunction* function, |