OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1568 __ push(eax); // Save result on the stack | 1568 __ push(eax); // Save result on the stack |
1569 result_saved = true; | 1569 result_saved = true; |
1570 } | 1570 } |
1571 switch (property->kind()) { | 1571 switch (property->kind()) { |
1572 case ObjectLiteral::Property::CONSTANT: | 1572 case ObjectLiteral::Property::CONSTANT: |
1573 UNREACHABLE(); | 1573 UNREACHABLE(); |
1574 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1574 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1575 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1575 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
1576 // Fall through. | 1576 // Fall through. |
1577 case ObjectLiteral::Property::COMPUTED: | 1577 case ObjectLiteral::Property::COMPUTED: |
1578 if (key->handle()->IsSymbol()) { | 1578 if (key->handle()->IsInternalizedString()) { |
1579 if (property->emit_store()) { | 1579 if (property->emit_store()) { |
1580 VisitForAccumulatorValue(value); | 1580 VisitForAccumulatorValue(value); |
1581 __ mov(ecx, Immediate(key->handle())); | 1581 __ mov(ecx, Immediate(key->handle())); |
1582 __ mov(edx, Operand(esp, 0)); | 1582 __ mov(edx, Operand(esp, 0)); |
1583 Handle<Code> ic = is_classic_mode() | 1583 Handle<Code> ic = is_classic_mode() |
1584 ? isolate()->builtins()->StoreIC_Initialize() | 1584 ? isolate()->builtins()->StoreIC_Initialize() |
1585 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 1585 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
1586 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | 1586 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); |
1587 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1587 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1588 } else { | 1588 } else { |
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2616 __ test_b(FieldOperand(ebx, Map::kBitField2Offset), | 2616 __ test_b(FieldOperand(ebx, Map::kBitField2Offset), |
2617 1 << Map::kStringWrapperSafeForDefaultValueOf); | 2617 1 << Map::kStringWrapperSafeForDefaultValueOf); |
2618 __ j(not_zero, if_true); | 2618 __ j(not_zero, if_true); |
2619 | 2619 |
2620 // Check for fast case object. Return false for slow case objects. | 2620 // Check for fast case object. Return false for slow case objects. |
2621 __ mov(ecx, FieldOperand(eax, JSObject::kPropertiesOffset)); | 2621 __ mov(ecx, FieldOperand(eax, JSObject::kPropertiesOffset)); |
2622 __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset)); | 2622 __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset)); |
2623 __ cmp(ecx, FACTORY->hash_table_map()); | 2623 __ cmp(ecx, FACTORY->hash_table_map()); |
2624 __ j(equal, if_false); | 2624 __ j(equal, if_false); |
2625 | 2625 |
2626 // Look for valueOf symbol in the descriptor array, and indicate false if | 2626 // Look for valueOf string in the descriptor array, and indicate false if |
2627 // found. Since we omit an enumeration index check, if it is added via a | 2627 // found. Since we omit an enumeration index check, if it is added via a |
2628 // transition that shares its descriptor array, this is a false positive. | 2628 // transition that shares its descriptor array, this is a false positive. |
2629 Label entry, loop, done; | 2629 Label entry, loop, done; |
2630 | 2630 |
2631 // Skip loop if no descriptors are valid. | 2631 // Skip loop if no descriptors are valid. |
2632 __ NumberOfOwnDescriptors(ecx, ebx); | 2632 __ NumberOfOwnDescriptors(ecx, ebx); |
2633 __ cmp(ecx, 0); | 2633 __ cmp(ecx, 0); |
2634 __ j(equal, &done); | 2634 __ j(equal, &done); |
2635 | 2635 |
2636 __ LoadInstanceDescriptors(ebx, ebx); | 2636 __ LoadInstanceDescriptors(ebx, ebx); |
2637 // ebx: descriptor array. | 2637 // ebx: descriptor array. |
2638 // ecx: valid entries in the descriptor array. | 2638 // ecx: valid entries in the descriptor array. |
2639 // Calculate the end of the descriptor array. | 2639 // Calculate the end of the descriptor array. |
2640 STATIC_ASSERT(kSmiTag == 0); | 2640 STATIC_ASSERT(kSmiTag == 0); |
2641 STATIC_ASSERT(kSmiTagSize == 1); | 2641 STATIC_ASSERT(kSmiTagSize == 1); |
2642 STATIC_ASSERT(kPointerSize == 4); | 2642 STATIC_ASSERT(kPointerSize == 4); |
2643 __ imul(ecx, ecx, DescriptorArray::kDescriptorSize); | 2643 __ imul(ecx, ecx, DescriptorArray::kDescriptorSize); |
2644 __ lea(ecx, Operand(ebx, ecx, times_2, DescriptorArray::kFirstOffset)); | 2644 __ lea(ecx, Operand(ebx, ecx, times_2, DescriptorArray::kFirstOffset)); |
2645 // Calculate location of the first key name. | 2645 // Calculate location of the first key name. |
2646 __ add(ebx, Immediate(DescriptorArray::kFirstOffset)); | 2646 __ add(ebx, Immediate(DescriptorArray::kFirstOffset)); |
2647 // Loop through all the keys in the descriptor array. If one of these is the | 2647 // Loop through all the keys in the descriptor array. If one of these is the |
2648 // symbol valueOf the result is false. | 2648 // internalized string "valueOf" the result is false. |
2649 __ jmp(&entry); | 2649 __ jmp(&entry); |
2650 __ bind(&loop); | 2650 __ bind(&loop); |
2651 __ mov(edx, FieldOperand(ebx, 0)); | 2651 __ mov(edx, FieldOperand(ebx, 0)); |
2652 __ cmp(edx, FACTORY->value_of_symbol()); | 2652 __ cmp(edx, FACTORY->value_of_string()); |
2653 __ j(equal, if_false); | 2653 __ j(equal, if_false); |
2654 __ add(ebx, Immediate(DescriptorArray::kDescriptorSize * kPointerSize)); | 2654 __ add(ebx, Immediate(DescriptorArray::kDescriptorSize * kPointerSize)); |
2655 __ bind(&entry); | 2655 __ bind(&entry); |
2656 __ cmp(ebx, ecx); | 2656 __ cmp(ebx, ecx); |
2657 __ j(not_equal, &loop); | 2657 __ j(not_equal, &loop); |
2658 | 2658 |
2659 __ bind(&done); | 2659 __ bind(&done); |
2660 | 2660 |
2661 // Reload map as register ebx was used as temporary above. | 2661 // Reload map as register ebx was used as temporary above. |
2662 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); | 2662 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2879 __ j(not_equal, &non_function_constructor); | 2879 __ j(not_equal, &non_function_constructor); |
2880 | 2880 |
2881 // eax now contains the constructor function. Grab the | 2881 // eax now contains the constructor function. Grab the |
2882 // instance class name from there. | 2882 // instance class name from there. |
2883 __ mov(eax, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset)); | 2883 __ mov(eax, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset)); |
2884 __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kInstanceClassNameOffset)); | 2884 __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kInstanceClassNameOffset)); |
2885 __ jmp(&done); | 2885 __ jmp(&done); |
2886 | 2886 |
2887 // Functions have class 'Function'. | 2887 // Functions have class 'Function'. |
2888 __ bind(&function); | 2888 __ bind(&function); |
2889 __ mov(eax, isolate()->factory()->function_class_symbol()); | 2889 __ mov(eax, isolate()->factory()->function_class_string()); |
2890 __ jmp(&done); | 2890 __ jmp(&done); |
2891 | 2891 |
2892 // Objects with a non-function constructor have class 'Object'. | 2892 // Objects with a non-function constructor have class 'Object'. |
2893 __ bind(&non_function_constructor); | 2893 __ bind(&non_function_constructor); |
2894 __ mov(eax, isolate()->factory()->Object_symbol()); | 2894 __ mov(eax, isolate()->factory()->Object_string()); |
2895 __ jmp(&done); | 2895 __ jmp(&done); |
2896 | 2896 |
2897 // Non-JS objects have class null. | 2897 // Non-JS objects have class null. |
2898 __ bind(&null); | 2898 __ bind(&null); |
2899 __ mov(eax, isolate()->factory()->null_value()); | 2899 __ mov(eax, isolate()->factory()->null_value()); |
2900 | 2900 |
2901 // All done. | 2901 // All done. |
2902 __ bind(&done); | 2902 __ bind(&done); |
2903 | 2903 |
2904 context()->Plug(eax); | 2904 context()->Plug(eax); |
(...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4212 Label* if_false = NULL; | 4212 Label* if_false = NULL; |
4213 Label* fall_through = NULL; | 4213 Label* fall_through = NULL; |
4214 context()->PrepareTest(&materialize_true, &materialize_false, | 4214 context()->PrepareTest(&materialize_true, &materialize_false, |
4215 &if_true, &if_false, &fall_through); | 4215 &if_true, &if_false, &fall_through); |
4216 | 4216 |
4217 { AccumulatorValueContext context(this); | 4217 { AccumulatorValueContext context(this); |
4218 VisitForTypeofValue(sub_expr); | 4218 VisitForTypeofValue(sub_expr); |
4219 } | 4219 } |
4220 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4220 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4221 | 4221 |
4222 if (check->Equals(isolate()->heap()->number_symbol())) { | 4222 if (check->Equals(isolate()->heap()->number_string())) { |
4223 __ JumpIfSmi(eax, if_true); | 4223 __ JumpIfSmi(eax, if_true); |
4224 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), | 4224 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), |
4225 isolate()->factory()->heap_number_map()); | 4225 isolate()->factory()->heap_number_map()); |
4226 Split(equal, if_true, if_false, fall_through); | 4226 Split(equal, if_true, if_false, fall_through); |
4227 } else if (check->Equals(isolate()->heap()->string_symbol())) { | 4227 } else if (check->Equals(isolate()->heap()->string_string())) { |
4228 __ JumpIfSmi(eax, if_false); | 4228 __ JumpIfSmi(eax, if_false); |
4229 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx); | 4229 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx); |
4230 __ j(above_equal, if_false); | 4230 __ j(above_equal, if_false); |
4231 // Check for undetectable objects => false. | 4231 // Check for undetectable objects => false. |
4232 __ test_b(FieldOperand(edx, Map::kBitFieldOffset), | 4232 __ test_b(FieldOperand(edx, Map::kBitFieldOffset), |
4233 1 << Map::kIsUndetectable); | 4233 1 << Map::kIsUndetectable); |
4234 Split(zero, if_true, if_false, fall_through); | 4234 Split(zero, if_true, if_false, fall_through); |
4235 } else if (check->Equals(isolate()->heap()->boolean_symbol())) { | 4235 } else if (check->Equals(isolate()->heap()->boolean_string())) { |
4236 __ cmp(eax, isolate()->factory()->true_value()); | 4236 __ cmp(eax, isolate()->factory()->true_value()); |
4237 __ j(equal, if_true); | 4237 __ j(equal, if_true); |
4238 __ cmp(eax, isolate()->factory()->false_value()); | 4238 __ cmp(eax, isolate()->factory()->false_value()); |
4239 Split(equal, if_true, if_false, fall_through); | 4239 Split(equal, if_true, if_false, fall_through); |
4240 } else if (FLAG_harmony_typeof && | 4240 } else if (FLAG_harmony_typeof && |
4241 check->Equals(isolate()->heap()->null_symbol())) { | 4241 check->Equals(isolate()->heap()->null_string())) { |
4242 __ cmp(eax, isolate()->factory()->null_value()); | 4242 __ cmp(eax, isolate()->factory()->null_value()); |
4243 Split(equal, if_true, if_false, fall_through); | 4243 Split(equal, if_true, if_false, fall_through); |
4244 } else if (check->Equals(isolate()->heap()->undefined_symbol())) { | 4244 } else if (check->Equals(isolate()->heap()->undefined_string())) { |
4245 __ cmp(eax, isolate()->factory()->undefined_value()); | 4245 __ cmp(eax, isolate()->factory()->undefined_value()); |
4246 __ j(equal, if_true); | 4246 __ j(equal, if_true); |
4247 __ JumpIfSmi(eax, if_false); | 4247 __ JumpIfSmi(eax, if_false); |
4248 // Check for undetectable objects => true. | 4248 // Check for undetectable objects => true. |
4249 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); | 4249 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); |
4250 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); | 4250 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); |
4251 __ test(ecx, Immediate(1 << Map::kIsUndetectable)); | 4251 __ test(ecx, Immediate(1 << Map::kIsUndetectable)); |
4252 Split(not_zero, if_true, if_false, fall_through); | 4252 Split(not_zero, if_true, if_false, fall_through); |
4253 } else if (check->Equals(isolate()->heap()->function_symbol())) { | 4253 } else if (check->Equals(isolate()->heap()->function_string())) { |
4254 __ JumpIfSmi(eax, if_false); | 4254 __ JumpIfSmi(eax, if_false); |
4255 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 4255 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
4256 __ CmpObjectType(eax, JS_FUNCTION_TYPE, edx); | 4256 __ CmpObjectType(eax, JS_FUNCTION_TYPE, edx); |
4257 __ j(equal, if_true); | 4257 __ j(equal, if_true); |
4258 __ CmpInstanceType(edx, JS_FUNCTION_PROXY_TYPE); | 4258 __ CmpInstanceType(edx, JS_FUNCTION_PROXY_TYPE); |
4259 Split(equal, if_true, if_false, fall_through); | 4259 Split(equal, if_true, if_false, fall_through); |
4260 } else if (check->Equals(isolate()->heap()->object_symbol())) { | 4260 } else if (check->Equals(isolate()->heap()->object_string())) { |
4261 __ JumpIfSmi(eax, if_false); | 4261 __ JumpIfSmi(eax, if_false); |
4262 if (!FLAG_harmony_typeof) { | 4262 if (!FLAG_harmony_typeof) { |
4263 __ cmp(eax, isolate()->factory()->null_value()); | 4263 __ cmp(eax, isolate()->factory()->null_value()); |
4264 __ j(equal, if_true); | 4264 __ j(equal, if_true); |
4265 } | 4265 } |
4266 __ CmpObjectType(eax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, edx); | 4266 __ CmpObjectType(eax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, edx); |
4267 __ j(below, if_false); | 4267 __ j(below, if_false); |
4268 __ CmpInstanceType(edx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4268 __ CmpInstanceType(edx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
4269 __ j(above, if_false); | 4269 __ j(above, if_false); |
4270 // Check for undetectable objects => false. | 4270 // Check for undetectable objects => false. |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4526 *stack_depth = 0; | 4526 *stack_depth = 0; |
4527 *context_length = 0; | 4527 *context_length = 0; |
4528 return previous_; | 4528 return previous_; |
4529 } | 4529 } |
4530 | 4530 |
4531 #undef __ | 4531 #undef __ |
4532 | 4532 |
4533 } } // namespace v8::internal | 4533 } } // namespace v8::internal |
4534 | 4534 |
4535 #endif // V8_TARGET_ARCH_IA32 | 4535 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |