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 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1630 __ push(v0); // Save result on stack. | 1630 __ push(v0); // Save result on stack. |
1631 result_saved = true; | 1631 result_saved = true; |
1632 } | 1632 } |
1633 switch (property->kind()) { | 1633 switch (property->kind()) { |
1634 case ObjectLiteral::Property::CONSTANT: | 1634 case ObjectLiteral::Property::CONSTANT: |
1635 UNREACHABLE(); | 1635 UNREACHABLE(); |
1636 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1636 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1637 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1637 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1638 // Fall through. | 1638 // Fall through. |
1639 case ObjectLiteral::Property::COMPUTED: | 1639 case ObjectLiteral::Property::COMPUTED: |
1640 if (key->handle()->IsSymbol()) { | 1640 if (key->handle()->IsInternalizedString()) { |
1641 if (property->emit_store()) { | 1641 if (property->emit_store()) { |
1642 VisitForAccumulatorValue(value); | 1642 VisitForAccumulatorValue(value); |
1643 __ mov(a0, result_register()); | 1643 __ mov(a0, result_register()); |
1644 __ li(a2, Operand(key->handle())); | 1644 __ li(a2, Operand(key->handle())); |
1645 __ lw(a1, MemOperand(sp)); | 1645 __ lw(a1, MemOperand(sp)); |
1646 Handle<Code> ic = is_classic_mode() | 1646 Handle<Code> ic = is_classic_mode() |
1647 ? isolate()->builtins()->StoreIC_Initialize() | 1647 ? isolate()->builtins()->StoreIC_Initialize() |
1648 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 1648 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
1649 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | 1649 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); |
1650 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1650 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2703 __ lbu(t0, FieldMemOperand(a1, Map::kBitField2Offset)); | 2703 __ lbu(t0, FieldMemOperand(a1, Map::kBitField2Offset)); |
2704 __ And(t0, t0, 1 << Map::kStringWrapperSafeForDefaultValueOf); | 2704 __ And(t0, t0, 1 << Map::kStringWrapperSafeForDefaultValueOf); |
2705 __ Branch(if_true, ne, t0, Operand(zero_reg)); | 2705 __ Branch(if_true, ne, t0, Operand(zero_reg)); |
2706 | 2706 |
2707 // Check for fast case object. Generate false result for slow case object. | 2707 // Check for fast case object. Generate false result for slow case object. |
2708 __ lw(a2, FieldMemOperand(v0, JSObject::kPropertiesOffset)); | 2708 __ lw(a2, FieldMemOperand(v0, JSObject::kPropertiesOffset)); |
2709 __ lw(a2, FieldMemOperand(a2, HeapObject::kMapOffset)); | 2709 __ lw(a2, FieldMemOperand(a2, HeapObject::kMapOffset)); |
2710 __ LoadRoot(t0, Heap::kHashTableMapRootIndex); | 2710 __ LoadRoot(t0, Heap::kHashTableMapRootIndex); |
2711 __ Branch(if_false, eq, a2, Operand(t0)); | 2711 __ Branch(if_false, eq, a2, Operand(t0)); |
2712 | 2712 |
2713 // Look for valueOf symbol in the descriptor array, and indicate false if | 2713 // Look for valueOf name in the descriptor array, and indicate false if |
2714 // found. Since we omit an enumeration index check, if it is added via a | 2714 // found. Since we omit an enumeration index check, if it is added via a |
2715 // transition that shares its descriptor array, this is a false positive. | 2715 // transition that shares its descriptor array, this is a false positive. |
2716 Label entry, loop, done; | 2716 Label entry, loop, done; |
2717 | 2717 |
2718 // Skip loop if no descriptors are valid. | 2718 // Skip loop if no descriptors are valid. |
2719 __ NumberOfOwnDescriptors(a3, a1); | 2719 __ NumberOfOwnDescriptors(a3, a1); |
2720 __ Branch(&done, eq, a3, Operand(zero_reg)); | 2720 __ Branch(&done, eq, a3, Operand(zero_reg)); |
2721 | 2721 |
2722 __ LoadInstanceDescriptors(a1, t0); | 2722 __ LoadInstanceDescriptors(a1, t0); |
2723 // t0: descriptor array. | 2723 // t0: descriptor array. |
2724 // a3: valid entries in the descriptor array. | 2724 // a3: valid entries in the descriptor array. |
2725 STATIC_ASSERT(kSmiTag == 0); | 2725 STATIC_ASSERT(kSmiTag == 0); |
2726 STATIC_ASSERT(kSmiTagSize == 1); | 2726 STATIC_ASSERT(kSmiTagSize == 1); |
2727 STATIC_ASSERT(kPointerSize == 4); | 2727 STATIC_ASSERT(kPointerSize == 4); |
2728 __ li(at, Operand(DescriptorArray::kDescriptorSize)); | 2728 __ li(at, Operand(DescriptorArray::kDescriptorSize)); |
2729 __ Mul(a3, a3, at); | 2729 __ Mul(a3, a3, at); |
2730 // Calculate location of the first key name. | 2730 // Calculate location of the first key name. |
2731 __ Addu(t0, t0, Operand(DescriptorArray::kFirstOffset - kHeapObjectTag)); | 2731 __ Addu(t0, t0, Operand(DescriptorArray::kFirstOffset - kHeapObjectTag)); |
2732 // Calculate the end of the descriptor array. | 2732 // Calculate the end of the descriptor array. |
2733 __ mov(a2, t0); | 2733 __ mov(a2, t0); |
2734 __ sll(t1, a3, kPointerSizeLog2 - kSmiTagSize); | 2734 __ sll(t1, a3, kPointerSizeLog2 - kSmiTagSize); |
2735 __ Addu(a2, a2, t1); | 2735 __ Addu(a2, a2, t1); |
2736 | 2736 |
2737 // Loop through all the keys in the descriptor array. If one of these is the | 2737 // Loop through all the keys in the descriptor array. If one of these is the |
2738 // symbol valueOf the result is false. | 2738 // string "valueOf" the result is false. |
2739 // The use of t2 to store the valueOf symbol asumes that it is not otherwise | 2739 // The use of t2 to store the valueOf string assumes that it is not otherwise |
2740 // used in the loop below. | 2740 // used in the loop below. |
2741 __ LoadRoot(t2, Heap::kvalue_of_symbolRootIndex); | 2741 __ li(t2, Operand(FACTORY->value_of_string())); |
2742 __ jmp(&entry); | 2742 __ jmp(&entry); |
2743 __ bind(&loop); | 2743 __ bind(&loop); |
2744 __ lw(a3, MemOperand(t0, 0)); | 2744 __ lw(a3, MemOperand(t0, 0)); |
2745 __ Branch(if_false, eq, a3, Operand(t2)); | 2745 __ Branch(if_false, eq, a3, Operand(t2)); |
2746 __ Addu(t0, t0, Operand(DescriptorArray::kDescriptorSize * kPointerSize)); | 2746 __ Addu(t0, t0, Operand(DescriptorArray::kDescriptorSize * kPointerSize)); |
2747 __ bind(&entry); | 2747 __ bind(&entry); |
2748 __ Branch(&loop, ne, t0, Operand(a2)); | 2748 __ Branch(&loop, ne, t0, Operand(a2)); |
2749 | 2749 |
2750 __ bind(&done); | 2750 __ bind(&done); |
2751 // If a valueOf property is not found on the object check that its | 2751 // If a valueOf property is not found on the object check that its |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2962 __ Branch(&non_function_constructor, ne, a1, Operand(JS_FUNCTION_TYPE)); | 2962 __ Branch(&non_function_constructor, ne, a1, Operand(JS_FUNCTION_TYPE)); |
2963 | 2963 |
2964 // v0 now contains the constructor function. Grab the | 2964 // v0 now contains the constructor function. Grab the |
2965 // instance class name from there. | 2965 // instance class name from there. |
2966 __ lw(v0, FieldMemOperand(v0, JSFunction::kSharedFunctionInfoOffset)); | 2966 __ lw(v0, FieldMemOperand(v0, JSFunction::kSharedFunctionInfoOffset)); |
2967 __ lw(v0, FieldMemOperand(v0, SharedFunctionInfo::kInstanceClassNameOffset)); | 2967 __ lw(v0, FieldMemOperand(v0, SharedFunctionInfo::kInstanceClassNameOffset)); |
2968 __ Branch(&done); | 2968 __ Branch(&done); |
2969 | 2969 |
2970 // Functions have class 'Function'. | 2970 // Functions have class 'Function'. |
2971 __ bind(&function); | 2971 __ bind(&function); |
2972 __ LoadRoot(v0, Heap::kfunction_class_symbolRootIndex); | 2972 __ LoadRoot(v0, Heap::kfunction_class_stringRootIndex); |
2973 __ jmp(&done); | 2973 __ jmp(&done); |
2974 | 2974 |
2975 // Objects with a non-function constructor have class 'Object'. | 2975 // Objects with a non-function constructor have class 'Object'. |
2976 __ bind(&non_function_constructor); | 2976 __ bind(&non_function_constructor); |
2977 __ LoadRoot(v0, Heap::kObject_symbolRootIndex); | 2977 __ LoadRoot(v0, Heap::kObject_stringRootIndex); |
2978 __ jmp(&done); | 2978 __ jmp(&done); |
2979 | 2979 |
2980 // Non-JS objects have class null. | 2980 // Non-JS objects have class null. |
2981 __ bind(&null); | 2981 __ bind(&null); |
2982 __ LoadRoot(v0, Heap::kNullValueRootIndex); | 2982 __ LoadRoot(v0, Heap::kNullValueRootIndex); |
2983 | 2983 |
2984 // All done. | 2984 // All done. |
2985 __ bind(&done); | 2985 __ bind(&done); |
2986 | 2986 |
2987 context()->Plug(v0); | 2987 context()->Plug(v0); |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3337 &need_conversion, | 3337 &need_conversion, |
3338 &need_conversion, | 3338 &need_conversion, |
3339 &index_out_of_range, | 3339 &index_out_of_range, |
3340 STRING_INDEX_IS_NUMBER); | 3340 STRING_INDEX_IS_NUMBER); |
3341 generator.GenerateFast(masm_); | 3341 generator.GenerateFast(masm_); |
3342 __ jmp(&done); | 3342 __ jmp(&done); |
3343 | 3343 |
3344 __ bind(&index_out_of_range); | 3344 __ bind(&index_out_of_range); |
3345 // When the index is out of range, the spec requires us to return | 3345 // When the index is out of range, the spec requires us to return |
3346 // the empty string. | 3346 // the empty string. |
3347 __ LoadRoot(result, Heap::kEmptyStringRootIndex); | 3347 __ LoadRoot(result, Heap::kempty_stringRootIndex); |
3348 __ jmp(&done); | 3348 __ jmp(&done); |
3349 | 3349 |
3350 __ bind(&need_conversion); | 3350 __ bind(&need_conversion); |
3351 // Move smi zero into the result register, which will trigger | 3351 // Move smi zero into the result register, which will trigger |
3352 // conversion. | 3352 // conversion. |
3353 __ li(result, Operand(Smi::FromInt(0))); | 3353 __ li(result, Operand(Smi::FromInt(0))); |
3354 __ jmp(&done); | 3354 __ jmp(&done); |
3355 | 3355 |
3356 NopRuntimeCallHelper call_helper; | 3356 NopRuntimeCallHelper call_helper; |
3357 generator.GenerateSlow(masm_, call_helper); | 3357 generator.GenerateSlow(masm_, call_helper); |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3652 __ GetObjectType(array, scratch1, scratch2); | 3652 __ GetObjectType(array, scratch1, scratch2); |
3653 __ Branch(&bailout, ne, scratch2, Operand(JS_ARRAY_TYPE)); | 3653 __ Branch(&bailout, ne, scratch2, Operand(JS_ARRAY_TYPE)); |
3654 | 3654 |
3655 // Check that the array has fast elements. | 3655 // Check that the array has fast elements. |
3656 __ CheckFastElements(scratch1, scratch2, &bailout); | 3656 __ CheckFastElements(scratch1, scratch2, &bailout); |
3657 | 3657 |
3658 // If the array has length zero, return the empty string. | 3658 // If the array has length zero, return the empty string. |
3659 __ lw(array_length, FieldMemOperand(array, JSArray::kLengthOffset)); | 3659 __ lw(array_length, FieldMemOperand(array, JSArray::kLengthOffset)); |
3660 __ SmiUntag(array_length); | 3660 __ SmiUntag(array_length); |
3661 __ Branch(&non_trivial_array, ne, array_length, Operand(zero_reg)); | 3661 __ Branch(&non_trivial_array, ne, array_length, Operand(zero_reg)); |
3662 __ LoadRoot(v0, Heap::kEmptyStringRootIndex); | 3662 __ LoadRoot(v0, Heap::kempty_stringRootIndex); |
3663 __ Branch(&done); | 3663 __ Branch(&done); |
3664 | 3664 |
3665 __ bind(&non_trivial_array); | 3665 __ bind(&non_trivial_array); |
3666 | 3666 |
3667 // Get the FixedArray containing array's elements. | 3667 // Get the FixedArray containing array's elements. |
3668 elements = array; | 3668 elements = array; |
3669 __ lw(elements, FieldMemOperand(array, JSArray::kElementsOffset)); | 3669 __ lw(elements, FieldMemOperand(array, JSArray::kElementsOffset)); |
3670 array = no_reg; // End of array's live range. | 3670 array = no_reg; // End of array's live range. |
3671 | 3671 |
3672 // Check that all array elements are sequential ASCII strings, and | 3672 // Check that all array elements are sequential ASCII strings, and |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4267 Label* if_false = NULL; | 4267 Label* if_false = NULL; |
4268 Label* fall_through = NULL; | 4268 Label* fall_through = NULL; |
4269 context()->PrepareTest(&materialize_true, &materialize_false, | 4269 context()->PrepareTest(&materialize_true, &materialize_false, |
4270 &if_true, &if_false, &fall_through); | 4270 &if_true, &if_false, &fall_through); |
4271 | 4271 |
4272 { AccumulatorValueContext context(this); | 4272 { AccumulatorValueContext context(this); |
4273 VisitForTypeofValue(sub_expr); | 4273 VisitForTypeofValue(sub_expr); |
4274 } | 4274 } |
4275 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4275 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4276 | 4276 |
4277 if (check->Equals(isolate()->heap()->number_symbol())) { | 4277 if (check->Equals(isolate()->heap()->number_string())) { |
4278 __ JumpIfSmi(v0, if_true); | 4278 __ JumpIfSmi(v0, if_true); |
4279 __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset)); | 4279 __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset)); |
4280 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 4280 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
4281 Split(eq, v0, Operand(at), if_true, if_false, fall_through); | 4281 Split(eq, v0, Operand(at), if_true, if_false, fall_through); |
4282 } else if (check->Equals(isolate()->heap()->string_symbol())) { | 4282 } else if (check->Equals(isolate()->heap()->string_string())) { |
4283 __ JumpIfSmi(v0, if_false); | 4283 __ JumpIfSmi(v0, if_false); |
4284 // Check for undetectable objects => false. | 4284 // Check for undetectable objects => false. |
4285 __ GetObjectType(v0, v0, a1); | 4285 __ GetObjectType(v0, v0, a1); |
4286 __ Branch(if_false, ge, a1, Operand(FIRST_NONSTRING_TYPE)); | 4286 __ Branch(if_false, ge, a1, Operand(FIRST_NONSTRING_TYPE)); |
4287 __ lbu(a1, FieldMemOperand(v0, Map::kBitFieldOffset)); | 4287 __ lbu(a1, FieldMemOperand(v0, Map::kBitFieldOffset)); |
4288 __ And(a1, a1, Operand(1 << Map::kIsUndetectable)); | 4288 __ And(a1, a1, Operand(1 << Map::kIsUndetectable)); |
4289 Split(eq, a1, Operand(zero_reg), | 4289 Split(eq, a1, Operand(zero_reg), |
4290 if_true, if_false, fall_through); | 4290 if_true, if_false, fall_through); |
4291 } else if (check->Equals(isolate()->heap()->boolean_symbol())) { | 4291 } else if (check->Equals(isolate()->heap()->boolean_string())) { |
4292 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 4292 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
4293 __ Branch(if_true, eq, v0, Operand(at)); | 4293 __ Branch(if_true, eq, v0, Operand(at)); |
4294 __ LoadRoot(at, Heap::kFalseValueRootIndex); | 4294 __ LoadRoot(at, Heap::kFalseValueRootIndex); |
4295 Split(eq, v0, Operand(at), if_true, if_false, fall_through); | 4295 Split(eq, v0, Operand(at), if_true, if_false, fall_through); |
4296 } else if (FLAG_harmony_typeof && | 4296 } else if (FLAG_harmony_typeof && |
4297 check->Equals(isolate()->heap()->null_symbol())) { | 4297 check->Equals(isolate()->heap()->null_string())) { |
4298 __ LoadRoot(at, Heap::kNullValueRootIndex); | 4298 __ LoadRoot(at, Heap::kNullValueRootIndex); |
4299 Split(eq, v0, Operand(at), if_true, if_false, fall_through); | 4299 Split(eq, v0, Operand(at), if_true, if_false, fall_through); |
4300 } else if (check->Equals(isolate()->heap()->undefined_symbol())) { | 4300 } else if (check->Equals(isolate()->heap()->undefined_string())) { |
4301 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 4301 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
4302 __ Branch(if_true, eq, v0, Operand(at)); | 4302 __ Branch(if_true, eq, v0, Operand(at)); |
4303 __ JumpIfSmi(v0, if_false); | 4303 __ JumpIfSmi(v0, if_false); |
4304 // Check for undetectable objects => true. | 4304 // Check for undetectable objects => true. |
4305 __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset)); | 4305 __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset)); |
4306 __ lbu(a1, FieldMemOperand(v0, Map::kBitFieldOffset)); | 4306 __ lbu(a1, FieldMemOperand(v0, Map::kBitFieldOffset)); |
4307 __ And(a1, a1, Operand(1 << Map::kIsUndetectable)); | 4307 __ And(a1, a1, Operand(1 << Map::kIsUndetectable)); |
4308 Split(ne, a1, Operand(zero_reg), if_true, if_false, fall_through); | 4308 Split(ne, a1, Operand(zero_reg), if_true, if_false, fall_through); |
4309 } else if (check->Equals(isolate()->heap()->function_symbol())) { | 4309 } else if (check->Equals(isolate()->heap()->function_string())) { |
4310 __ JumpIfSmi(v0, if_false); | 4310 __ JumpIfSmi(v0, if_false); |
4311 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 4311 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
4312 __ GetObjectType(v0, v0, a1); | 4312 __ GetObjectType(v0, v0, a1); |
4313 __ Branch(if_true, eq, a1, Operand(JS_FUNCTION_TYPE)); | 4313 __ Branch(if_true, eq, a1, Operand(JS_FUNCTION_TYPE)); |
4314 Split(eq, a1, Operand(JS_FUNCTION_PROXY_TYPE), | 4314 Split(eq, a1, Operand(JS_FUNCTION_PROXY_TYPE), |
4315 if_true, if_false, fall_through); | 4315 if_true, if_false, fall_through); |
4316 } else if (check->Equals(isolate()->heap()->object_symbol())) { | 4316 } else if (check->Equals(isolate()->heap()->object_string())) { |
4317 __ JumpIfSmi(v0, if_false); | 4317 __ JumpIfSmi(v0, if_false); |
4318 if (!FLAG_harmony_typeof) { | 4318 if (!FLAG_harmony_typeof) { |
4319 __ LoadRoot(at, Heap::kNullValueRootIndex); | 4319 __ LoadRoot(at, Heap::kNullValueRootIndex); |
4320 __ Branch(if_true, eq, v0, Operand(at)); | 4320 __ Branch(if_true, eq, v0, Operand(at)); |
4321 } | 4321 } |
4322 // Check for JS objects => true. | 4322 // Check for JS objects => true. |
4323 __ GetObjectType(v0, v0, a1); | 4323 __ GetObjectType(v0, v0, a1); |
4324 __ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 4324 __ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
4325 __ lbu(a1, FieldMemOperand(v0, Map::kInstanceTypeOffset)); | 4325 __ lbu(a1, FieldMemOperand(v0, Map::kInstanceTypeOffset)); |
4326 __ Branch(if_false, gt, a1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 4326 __ Branch(if_false, gt, a1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4588 *context_length = 0; | 4588 *context_length = 0; |
4589 return previous_; | 4589 return previous_; |
4590 } | 4590 } |
4591 | 4591 |
4592 | 4592 |
4593 #undef __ | 4593 #undef __ |
4594 | 4594 |
4595 } } // namespace v8::internal | 4595 } } // namespace v8::internal |
4596 | 4596 |
4597 #endif // V8_TARGET_ARCH_MIPS | 4597 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |