| Index: src/arm/ic-arm.cc
|
| ===================================================================
|
| --- src/arm/ic-arm.cc (revision 4542)
|
| +++ src/arm/ic-arm.cc (working copy)
|
| @@ -800,29 +800,68 @@
|
| // -- sp[0] : key
|
| // -- sp[4] : receiver
|
| // -----------------------------------
|
| + Label miss;
|
| + Label index_not_smi;
|
| + Label index_out_of_range;
|
| + Label slow_char_code;
|
| + Label got_char_code;
|
|
|
| - Label miss, index_ok;
|
| -
|
| // Get the key and receiver object from the stack.
|
| __ ldm(ia, sp, r0.bit() | r1.bit());
|
|
|
| - // Check that the receiver isn't a smi.
|
| - __ BranchOnSmi(r1, &miss);
|
| + Register object = r1;
|
| + Register index = r0;
|
| + Register code = r2;
|
| + Register scratch = r3;
|
|
|
| - // Check that the receiver is a string.
|
| - Condition is_string = masm->IsObjectStringType(r1, r2);
|
| - __ b(NegateCondition(is_string), &miss);
|
| + StringHelper::GenerateFastCharCodeAt(masm,
|
| + object,
|
| + index,
|
| + scratch,
|
| + code,
|
| + &miss, // When not a string.
|
| + &index_not_smi,
|
| + &index_out_of_range,
|
| + &slow_char_code);
|
|
|
| - // Check if key is a smi or a heap number.
|
| - __ BranchOnSmi(r0, &index_ok);
|
| - __ CheckMap(r0, r2, Factory::heap_number_map(), &miss, false);
|
| + // If we didn't bail out, code register contains smi tagged char
|
| + // code.
|
| + __ bind(&got_char_code);
|
| + StringHelper::GenerateCharFromCode(masm, code, scratch, r0, JUMP_FUNCTION);
|
| +#ifdef DEBUG
|
| + __ Abort("Unexpected fall-through from char from code tail call");
|
| +#endif
|
|
|
| - __ bind(&index_ok);
|
| - // Duplicate receiver and key since they are expected on the stack after
|
| - // the KeyedLoadIC call.
|
| - __ Push(r1, r0);
|
| - __ InvokeBuiltin(Builtins::STRING_CHAR_AT, JUMP_JS);
|
| + // Check if key is a heap number.
|
| + __ bind(&index_not_smi);
|
| + __ CheckMap(index, scratch, Factory::heap_number_map(), &miss, true);
|
|
|
| + // Push receiver and key on the stack (now that we know they are a
|
| + // string and a number), and call runtime.
|
| + __ bind(&slow_char_code);
|
| + __ EnterInternalFrame();
|
| + __ Push(object, index);
|
| + __ CallRuntime(Runtime::kStringCharCodeAt, 2);
|
| + ASSERT(!code.is(r0));
|
| + __ mov(code, r0);
|
| + __ LeaveInternalFrame();
|
| +
|
| + // Check if the runtime call returned NaN char code. If yes, return
|
| + // undefined. Otherwise, we can continue.
|
| + if (FLAG_debug_code) {
|
| + __ BranchOnSmi(code, &got_char_code);
|
| + __ ldr(scratch, FieldMemOperand(code, HeapObject::kMapOffset));
|
| + __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
|
| + __ cmp(scratch, ip);
|
| + __ Assert(eq, "StringCharCodeAt must return smi or heap number");
|
| + }
|
| + __ LoadRoot(scratch, Heap::kNanValueRootIndex);
|
| + __ cmp(code, scratch);
|
| + __ b(ne, &got_char_code);
|
| + __ bind(&index_out_of_range);
|
| + __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
|
| + __ Ret();
|
| +
|
| __ bind(&miss);
|
| GenerateGeneric(masm);
|
| }
|
|
|