| Index: src/ia32/code-stubs-ia32.cc
|
| ===================================================================
|
| --- src/ia32/code-stubs-ia32.cc (revision 7006)
|
| +++ src/ia32/code-stubs-ia32.cc (working copy)
|
| @@ -39,6 +39,28 @@
|
| namespace internal {
|
|
|
| #define __ ACCESS_MASM(masm)
|
| +
|
| +void ToNumberStub::Generate(MacroAssembler* masm) {
|
| + // The ToNumber stub takes one argument in eax.
|
| + NearLabel check_heap_number, call_builtin;
|
| + __ test(eax, Immediate(kSmiTagMask));
|
| + __ j(not_zero, &check_heap_number);
|
| + __ ret(0);
|
| +
|
| + __ bind(&check_heap_number);
|
| + __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
|
| + __ cmp(Operand(ebx), Immediate(FACTORY->heap_number_map()));
|
| + __ j(not_equal, &call_builtin);
|
| + __ ret(0);
|
| +
|
| + __ bind(&call_builtin);
|
| + __ pop(ecx); // Pop return address.
|
| + __ push(eax);
|
| + __ push(ecx); // Push return address.
|
| + __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
|
| +}
|
| +
|
| +
|
| void FastNewClosureStub::Generate(MacroAssembler* masm) {
|
| // Create a new closure from the given function info in new
|
| // space. Set the context to the current context in esi.
|
| @@ -3483,10 +3505,12 @@
|
| __ j(not_equal, ¬_minus_half);
|
|
|
| // Calculates reciprocal of square root.
|
| - // Note that 1/sqrt(x) = sqrt(1/x))
|
| - __ divsd(xmm3, xmm0);
|
| + // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
|
| + __ xorpd(xmm1, xmm1);
|
| + __ addsd(xmm1, xmm0);
|
| + __ sqrtsd(xmm1, xmm1);
|
| + __ divsd(xmm3, xmm1);
|
| __ movsd(xmm1, xmm3);
|
| - __ sqrtsd(xmm1, xmm1);
|
| __ jmp(&allocate_return);
|
|
|
| // Test for 0.5.
|
| @@ -3498,7 +3522,9 @@
|
| __ ucomisd(xmm2, xmm1);
|
| __ j(not_equal, &call_runtime);
|
| // Calculates square root.
|
| - __ movsd(xmm1, xmm0);
|
| + // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
|
| + __ xorpd(xmm1, xmm1);
|
| + __ addsd(xmm1, xmm0);
|
| __ sqrtsd(xmm1, xmm1);
|
|
|
| __ bind(&allocate_return);
|
| @@ -4706,6 +4732,24 @@
|
| __ test(ecx, Immediate(kFailureTagMask));
|
| __ j(zero, &failure_returned, not_taken);
|
|
|
| + ExternalReference pending_exception_address(
|
| + Isolate::k_pending_exception_address);
|
| +
|
| + // Check that there is no pending exception, otherwise we
|
| + // should have returned some failure value.
|
| + if (FLAG_debug_code) {
|
| + __ push(edx);
|
| + __ mov(edx, Operand::StaticVariable(
|
| + ExternalReference::the_hole_value_location()));
|
| + NearLabel okay;
|
| + __ cmp(edx, Operand::StaticVariable(pending_exception_address));
|
| + // Cannot use check here as it attempts to generate call into runtime.
|
| + __ j(equal, &okay);
|
| + __ int3();
|
| + __ bind(&okay);
|
| + __ pop(edx);
|
| + }
|
| +
|
| // Exit the JavaScript to C++ exit frame.
|
| __ LeaveExitFrame(save_doubles_);
|
| __ ret(0);
|
| @@ -4724,8 +4768,6 @@
|
| __ j(equal, throw_out_of_memory_exception);
|
|
|
| // Retrieve the pending exception and clear the variable.
|
| - ExternalReference pending_exception_address(
|
| - Isolate::k_pending_exception_address);
|
| __ mov(eax, Operand::StaticVariable(pending_exception_address));
|
| __ mov(edx,
|
| Operand::StaticVariable(ExternalReference::the_hole_value_location()));
|
| @@ -6500,6 +6542,54 @@
|
| }
|
|
|
|
|
| +// Loads a indexed element from a pixel array.
|
| +void GenerateFastPixelArrayLoad(MacroAssembler* masm,
|
| + Register receiver,
|
| + Register key,
|
| + Register elements,
|
| + Register untagged_key,
|
| + Register result,
|
| + Label* not_pixel_array,
|
| + Label* key_not_smi,
|
| + Label* out_of_range) {
|
| + // Register use:
|
| + // receiver - holds the receiver and is unchanged.
|
| + // key - holds the key and is unchanged (must be a smi).
|
| + // elements - is set to the the receiver's element if
|
| + // the receiver doesn't have a pixel array or the
|
| + // key is not a smi, otherwise it's the elements'
|
| + // external pointer.
|
| + // untagged_key - is set to the untagged key
|
| +
|
| + // Some callers already have verified that the key is a smi. key_not_smi is
|
| + // set to NULL as a sentinel for that case. Otherwise, add an explicit check
|
| + // to ensure the key is a smi must be added.
|
| + if (key_not_smi != NULL) {
|
| + __ JumpIfNotSmi(key, key_not_smi);
|
| + } else {
|
| + if (FLAG_debug_code) {
|
| + __ AbortIfNotSmi(key);
|
| + }
|
| + }
|
| + __ mov(untagged_key, key);
|
| + __ SmiUntag(untagged_key);
|
| +
|
| + // Verify that the receiver has pixel array elements.
|
| + __ mov(elements, FieldOperand(receiver, JSObject::kElementsOffset));
|
| + __ CheckMap(elements, FACTORY->pixel_array_map(), not_pixel_array, true);
|
| +
|
| + // Key must be in range.
|
| + __ cmp(untagged_key, FieldOperand(elements, PixelArray::kLengthOffset));
|
| + __ j(above_equal, out_of_range); // unsigned check handles negative keys.
|
| +
|
| + // Perform the indexed load and tag the result as a smi.
|
| + __ mov(elements, FieldOperand(elements, PixelArray::kExternalPointerOffset));
|
| + __ movzx_b(result, Operand(elements, untagged_key, times_1, 0));
|
| + __ SmiTag(result);
|
| + __ ret(0);
|
| +}
|
| +
|
| +
|
| #undef __
|
|
|
| } } // namespace v8::internal
|
|
|