OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 | 324 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 |
325 // on page 74. | 325 // on page 74. |
326 Label use_receiver, exit; | 326 Label use_receiver, exit; |
327 | 327 |
328 // If the result is a smi, it is *not* an object in the ECMA sense. | 328 // If the result is a smi, it is *not* an object in the ECMA sense. |
329 __ test(eax, Immediate(kSmiTagMask)); | 329 __ test(eax, Immediate(kSmiTagMask)); |
330 __ j(zero, &use_receiver, not_taken); | 330 __ j(zero, &use_receiver, not_taken); |
331 | 331 |
332 // If the type of the result (stored in its map) is less than | 332 // If the type of the result (stored in its map) is less than |
333 // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense. | 333 // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense. |
334 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 334 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx); |
335 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 335 __ j(above_equal, &exit, not_taken); |
336 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); | |
337 __ j(greater_equal, &exit, not_taken); | |
338 | 336 |
339 // Throw away the result of the constructor invocation and use the | 337 // Throw away the result of the constructor invocation and use the |
340 // on-stack receiver as the result. | 338 // on-stack receiver as the result. |
341 __ bind(&use_receiver); | 339 __ bind(&use_receiver); |
342 __ mov(eax, Operand(esp, 0)); | 340 __ mov(eax, Operand(esp, 0)); |
343 | 341 |
344 // Restore the arguments count and leave the construct frame. | 342 // Restore the arguments count and leave the construct frame. |
345 __ bind(&exit); | 343 __ bind(&exit); |
346 __ mov(ebx, Operand(esp, kPointerSize)); // get arguments count | 344 __ mov(ebx, Operand(esp, kPointerSize)); // get arguments count |
347 __ LeaveConstructFrame(); | 345 __ LeaveConstructFrame(); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 | 460 |
463 __ mov(ebx, Operand(esp, eax, times_4, 0)); // First argument. | 461 __ mov(ebx, Operand(esp, eax, times_4, 0)); // First argument. |
464 __ test(ebx, Immediate(kSmiTagMask)); | 462 __ test(ebx, Immediate(kSmiTagMask)); |
465 __ j(zero, &convert_to_object); | 463 __ j(zero, &convert_to_object); |
466 | 464 |
467 __ cmp(ebx, Factory::null_value()); | 465 __ cmp(ebx, Factory::null_value()); |
468 __ j(equal, &use_global_receiver); | 466 __ j(equal, &use_global_receiver); |
469 __ cmp(ebx, Factory::undefined_value()); | 467 __ cmp(ebx, Factory::undefined_value()); |
470 __ j(equal, &use_global_receiver); | 468 __ j(equal, &use_global_receiver); |
471 | 469 |
| 470 // We don't use IsObjectJSObjectType here because we jump on success. |
472 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); | 471 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); |
473 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 472 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
474 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); | 473 __ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE)); |
475 __ j(below, &convert_to_object); | 474 __ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE); |
476 __ cmp(ecx, LAST_JS_OBJECT_TYPE); | |
477 __ j(below_equal, &shift_arguments); | 475 __ j(below_equal, &shift_arguments); |
478 | 476 |
479 __ bind(&convert_to_object); | 477 __ bind(&convert_to_object); |
480 __ EnterInternalFrame(); // In order to preserve argument count. | 478 __ EnterInternalFrame(); // In order to preserve argument count. |
481 __ SmiTag(eax); | 479 __ SmiTag(eax); |
482 __ push(eax); | 480 __ push(eax); |
483 | 481 |
484 __ push(ebx); | 482 __ push(ebx); |
485 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 483 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
486 __ mov(ebx, eax); | 484 __ mov(ebx, eax); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 __ mov(ebx, Operand(ebp, 3 * kPointerSize)); | 608 __ mov(ebx, Operand(ebp, 3 * kPointerSize)); |
611 __ test(ebx, Immediate(kSmiTagMask)); | 609 __ test(ebx, Immediate(kSmiTagMask)); |
612 __ j(zero, &call_to_object); | 610 __ j(zero, &call_to_object); |
613 __ cmp(ebx, Factory::null_value()); | 611 __ cmp(ebx, Factory::null_value()); |
614 __ j(equal, &use_global_receiver); | 612 __ j(equal, &use_global_receiver); |
615 __ cmp(ebx, Factory::undefined_value()); | 613 __ cmp(ebx, Factory::undefined_value()); |
616 __ j(equal, &use_global_receiver); | 614 __ j(equal, &use_global_receiver); |
617 | 615 |
618 // If given receiver is already a JavaScript object then there's no | 616 // If given receiver is already a JavaScript object then there's no |
619 // reason for converting it. | 617 // reason for converting it. |
| 618 // We don't use IsObjectJSObjectType here because we jump on success. |
620 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); | 619 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); |
621 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 620 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
622 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); | 621 __ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE)); |
623 __ j(less, &call_to_object); | 622 __ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE); |
624 __ cmp(ecx, LAST_JS_OBJECT_TYPE); | 623 __ j(below_equal, &push_receiver); |
625 __ j(less_equal, &push_receiver); | |
626 | 624 |
627 // Convert the receiver to an object. | 625 // Convert the receiver to an object. |
628 __ bind(&call_to_object); | 626 __ bind(&call_to_object); |
629 __ push(ebx); | 627 __ push(ebx); |
630 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 628 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
631 __ mov(ebx, Operand(eax)); | 629 __ mov(ebx, Operand(eax)); |
632 __ jmp(&push_receiver); | 630 __ jmp(&push_receiver); |
633 | 631 |
634 // Use the current global receiver object as the receiver. | 632 // Use the current global receiver object as the receiver. |
635 __ bind(&use_global_receiver); | 633 __ bind(&use_global_receiver); |
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1254 __ bind(&dont_adapt_arguments); | 1252 __ bind(&dont_adapt_arguments); |
1255 __ jmp(Operand(edx)); | 1253 __ jmp(Operand(edx)); |
1256 } | 1254 } |
1257 | 1255 |
1258 | 1256 |
1259 #undef __ | 1257 #undef __ |
1260 | 1258 |
1261 } } // namespace v8::internal | 1259 } } // namespace v8::internal |
1262 | 1260 |
1263 #endif // V8_TARGET_ARCH_IA32 | 1261 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |