OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2623 ASSERT(args->length() == 1); | 2623 ASSERT(args->length() == 1); |
2624 Label done, null, function, non_function_constructor; | 2624 Label done, null, function, non_function_constructor; |
2625 | 2625 |
2626 VisitForAccumulatorValue(args->at(0)); | 2626 VisitForAccumulatorValue(args->at(0)); |
2627 | 2627 |
2628 // If the object is a smi, we return null. | 2628 // If the object is a smi, we return null. |
2629 __ JumpIfSmi(rax, &null); | 2629 __ JumpIfSmi(rax, &null); |
2630 | 2630 |
2631 // Check that the object is a JS object but take special care of JS | 2631 // Check that the object is a JS object but take special care of JS |
2632 // functions to make sure they have 'Function' as their class. | 2632 // functions to make sure they have 'Function' as their class. |
| 2633 // Assume that there are only two callable types, and one of them is at |
| 2634 // either end of the type range for JS object types. Saves extra comparisons. |
| 2635 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
2633 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rax); | 2636 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rax); |
2634 // Map is now in rax. | 2637 // Map is now in rax. |
2635 __ j(below, &null); | 2638 __ j(below, &null); |
| 2639 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == |
| 2640 FIRST_SPEC_OBJECT_TYPE + 1); |
| 2641 __ j(equal, &function); |
2636 | 2642 |
2637 // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type, and | 2643 __ CmpInstanceType(rax, LAST_SPEC_OBJECT_TYPE); |
2638 // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after | 2644 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == |
2639 // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter. | 2645 LAST_SPEC_OBJECT_TYPE - 1); |
2640 STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE); | 2646 __ j(equal, &function); |
2641 STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE == | 2647 // Assume that there is no larger type. |
2642 LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1); | 2648 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1); |
2643 __ CmpInstanceType(rax, FIRST_CALLABLE_SPEC_OBJECT_TYPE); | |
2644 __ j(above_equal, &function); | |
2645 | 2649 |
2646 // Check if the constructor in the map is a function. | 2650 // Check if the constructor in the map is a JS function. |
2647 __ movq(rax, FieldOperand(rax, Map::kConstructorOffset)); | 2651 __ movq(rax, FieldOperand(rax, Map::kConstructorOffset)); |
2648 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); | 2652 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); |
2649 __ j(not_equal, &non_function_constructor); | 2653 __ j(not_equal, &non_function_constructor); |
2650 | 2654 |
2651 // rax now contains the constructor function. Grab the | 2655 // rax now contains the constructor function. Grab the |
2652 // instance class name from there. | 2656 // instance class name from there. |
2653 __ movq(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset)); | 2657 __ movq(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset)); |
2654 __ movq(rax, FieldOperand(rax, SharedFunctionInfo::kInstanceClassNameOffset)); | 2658 __ movq(rax, FieldOperand(rax, SharedFunctionInfo::kInstanceClassNameOffset)); |
2655 __ jmp(&done); | 2659 __ jmp(&done); |
2656 | 2660 |
(...skipping 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3956 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); | 3960 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
3957 __ j(equal, if_true); | 3961 __ j(equal, if_true); |
3958 __ JumpIfSmi(rax, if_false); | 3962 __ JumpIfSmi(rax, if_false); |
3959 // Check for undetectable objects => true. | 3963 // Check for undetectable objects => true. |
3960 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); | 3964 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); |
3961 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), | 3965 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), |
3962 Immediate(1 << Map::kIsUndetectable)); | 3966 Immediate(1 << Map::kIsUndetectable)); |
3963 Split(not_zero, if_true, if_false, fall_through); | 3967 Split(not_zero, if_true, if_false, fall_through); |
3964 } else if (check->Equals(isolate()->heap()->function_symbol())) { | 3968 } else if (check->Equals(isolate()->heap()->function_symbol())) { |
3965 __ JumpIfSmi(rax, if_false); | 3969 __ JumpIfSmi(rax, if_false); |
3966 STATIC_ASSERT(LAST_CALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE); | 3970 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
3967 __ CmpObjectType(rax, FIRST_CALLABLE_SPEC_OBJECT_TYPE, rdx); | 3971 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rdx); |
3968 Split(above_equal, if_true, if_false, fall_through); | 3972 __ j(equal, if_true); |
| 3973 __ CmpInstanceType(rdx, JS_FUNCTION_PROXY_TYPE); |
| 3974 Split(equal, if_true, if_false, fall_through); |
3969 } else if (check->Equals(isolate()->heap()->object_symbol())) { | 3975 } else if (check->Equals(isolate()->heap()->object_symbol())) { |
3970 __ JumpIfSmi(rax, if_false); | 3976 __ JumpIfSmi(rax, if_false); |
3971 if (!FLAG_harmony_typeof) { | 3977 if (!FLAG_harmony_typeof) { |
3972 __ CompareRoot(rax, Heap::kNullValueRootIndex); | 3978 __ CompareRoot(rax, Heap::kNullValueRootIndex); |
3973 __ j(equal, if_true); | 3979 __ j(equal, if_true); |
3974 } | 3980 } |
3975 __ CmpObjectType(rax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, rdx); | 3981 __ CmpObjectType(rax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, rdx); |
3976 __ j(below, if_false); | 3982 __ j(below, if_false); |
3977 __ CmpInstanceType(rdx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 3983 __ CmpInstanceType(rdx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
3978 __ j(above, if_false); | 3984 __ j(above, if_false); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4212 __ jmp(rdx); | 4218 __ jmp(rdx); |
4213 } | 4219 } |
4214 | 4220 |
4215 | 4221 |
4216 #undef __ | 4222 #undef __ |
4217 | 4223 |
4218 | 4224 |
4219 } } // namespace v8::internal | 4225 } } // namespace v8::internal |
4220 | 4226 |
4221 #endif // V8_TARGET_ARCH_X64 | 4227 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |