OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 2142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2153 ASSERT(!object->IsJSGlobalProxy()); | 2153 ASSERT(!object->IsJSGlobalProxy()); |
2154 Isolate* isolate = object->GetIsolate(); | 2154 Isolate* isolate = object->GetIsolate(); |
2155 | 2155 |
2156 if (!name->IsUniqueName()) { | 2156 if (!name->IsUniqueName()) { |
2157 name = isolate->factory()->InternalizeString( | 2157 name = isolate->factory()->InternalizeString( |
2158 Handle<String>::cast(name)); | 2158 Handle<String>::cast(name)); |
2159 } | 2159 } |
2160 | 2160 |
2161 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | 2161 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && |
2162 !object->map()->is_extensible()) { | 2162 !object->map()->is_extensible()) { |
2163 if (strict_mode == kNonStrictMode) { | 2163 if (strict_mode == kSloppyMode) { |
2164 return value; | 2164 return value; |
2165 } else { | 2165 } else { |
2166 Handle<Object> args[1] = { name }; | 2166 Handle<Object> args[1] = { name }; |
2167 Handle<Object> error = isolate->factory()->NewTypeError( | 2167 Handle<Object> error = isolate->factory()->NewTypeError( |
2168 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); | 2168 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); |
2169 isolate->Throw(*error); | 2169 isolate->Throw(*error); |
2170 return Handle<Object>(); | 2170 return Handle<Object>(); |
2171 } | 2171 } |
2172 } | 2172 } |
2173 | 2173 |
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2949 return value; | 2949 return value; |
2950 } | 2950 } |
2951 | 2951 |
2952 if (structure->IsAccessorPair()) { | 2952 if (structure->IsAccessorPair()) { |
2953 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | 2953 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
2954 if (setter->IsSpecFunction()) { | 2954 if (setter->IsSpecFunction()) { |
2955 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 2955 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
2956 return SetPropertyWithDefinedSetter( | 2956 return SetPropertyWithDefinedSetter( |
2957 object, Handle<JSReceiver>::cast(setter), value); | 2957 object, Handle<JSReceiver>::cast(setter), value); |
2958 } else { | 2958 } else { |
2959 if (strict_mode == kNonStrictMode) { | 2959 if (strict_mode == kSloppyMode) { |
2960 return value; | 2960 return value; |
2961 } | 2961 } |
2962 Handle<Object> args[2] = { name, holder }; | 2962 Handle<Object> args[2] = { name, holder }; |
2963 Handle<Object> error = | 2963 Handle<Object> error = |
2964 isolate->factory()->NewTypeError("no_setter_in_callback", | 2964 isolate->factory()->NewTypeError("no_setter_in_callback", |
2965 HandleVector(args, 2)); | 2965 HandleVector(args, 2)); |
2966 isolate->Throw(*error); | 2966 isolate->Throw(*error); |
2967 return Handle<Object>(); | 2967 return Handle<Object>(); |
2968 } | 2968 } |
2969 } | 2969 } |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3086 } | 3086 } |
3087 case TRANSITION: | 3087 case TRANSITION: |
3088 case NONEXISTENT: | 3088 case NONEXISTENT: |
3089 UNREACHABLE(); | 3089 UNREACHABLE(); |
3090 break; | 3090 break; |
3091 } | 3091 } |
3092 } | 3092 } |
3093 | 3093 |
3094 // If we get here with *done true, we have encountered a read-only property. | 3094 // If we get here with *done true, we have encountered a read-only property. |
3095 if (*done) { | 3095 if (*done) { |
3096 if (strict_mode == kNonStrictMode) return value; | 3096 if (strict_mode == kSloppyMode) return value; |
3097 Handle<Object> args[] = { name, object }; | 3097 Handle<Object> args[] = { name, object }; |
3098 Handle<Object> error = isolate->factory()->NewTypeError( | 3098 Handle<Object> error = isolate->factory()->NewTypeError( |
3099 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 3099 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
3100 isolate->Throw(*error); | 3100 isolate->Throw(*error); |
3101 return Handle<Object>(); | 3101 return Handle<Object>(); |
3102 } | 3102 } |
3103 return isolate->factory()->the_hole_value(); | 3103 return isolate->factory()->the_hole_value(); |
3104 } | 3104 } |
3105 | 3105 |
3106 | 3106 |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3641 if (hasWritable->IsTrue()) { | 3641 if (hasWritable->IsTrue()) { |
3642 Handle<String> writable_name = | 3642 Handle<String> writable_name = |
3643 isolate->factory()->InternalizeOneByteString( | 3643 isolate->factory()->InternalizeOneByteString( |
3644 STATIC_ASCII_VECTOR("writable_")); | 3644 STATIC_ASCII_VECTOR("writable_")); |
3645 Handle<Object> writable( | 3645 Handle<Object> writable( |
3646 v8::internal::GetProperty(isolate, desc, writable_name)); | 3646 v8::internal::GetProperty(isolate, desc, writable_name)); |
3647 ASSERT(!isolate->has_pending_exception()); | 3647 ASSERT(!isolate->has_pending_exception()); |
3648 ASSERT(writable->IsTrue() || writable->IsFalse()); | 3648 ASSERT(writable->IsTrue() || writable->IsFalse()); |
3649 *done = writable->IsFalse(); | 3649 *done = writable->IsFalse(); |
3650 if (!*done) return isolate->factory()->the_hole_value(); | 3650 if (!*done) return isolate->factory()->the_hole_value(); |
3651 if (strict_mode == kNonStrictMode) return value; | 3651 if (strict_mode == kSloppyMode) return value; |
3652 Handle<Object> args[] = { name, receiver }; | 3652 Handle<Object> args[] = { name, receiver }; |
3653 Handle<Object> error = isolate->factory()->NewTypeError( | 3653 Handle<Object> error = isolate->factory()->NewTypeError( |
3654 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 3654 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
3655 isolate->Throw(*error); | 3655 isolate->Throw(*error); |
3656 return Handle<Object>(); | 3656 return Handle<Object>(); |
3657 } | 3657 } |
3658 | 3658 |
3659 // We have an AccessorDescriptor. | 3659 // We have an AccessorDescriptor. |
3660 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( | 3660 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( |
3661 STATIC_ASCII_VECTOR("set_")); | 3661 STATIC_ASCII_VECTOR("set_")); |
3662 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name)); | 3662 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name)); |
3663 ASSERT(!isolate->has_pending_exception()); | 3663 ASSERT(!isolate->has_pending_exception()); |
3664 if (!setter->IsUndefined()) { | 3664 if (!setter->IsUndefined()) { |
3665 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 3665 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
3666 return SetPropertyWithDefinedSetter( | 3666 return SetPropertyWithDefinedSetter( |
3667 receiver, Handle<JSReceiver>::cast(setter), value); | 3667 receiver, Handle<JSReceiver>::cast(setter), value); |
3668 } | 3668 } |
3669 | 3669 |
3670 if (strict_mode == kNonStrictMode) return value; | 3670 if (strict_mode == kSloppyMode) return value; |
3671 Handle<Object> args2[] = { name, proxy }; | 3671 Handle<Object> args2[] = { name, proxy }; |
3672 Handle<Object> error = isolate->factory()->NewTypeError( | 3672 Handle<Object> error = isolate->factory()->NewTypeError( |
3673 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); | 3673 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); |
3674 isolate->Throw(*error); | 3674 isolate->Throw(*error); |
3675 return Handle<Object>(); | 3675 return Handle<Object>(); |
3676 } | 3676 } |
3677 | 3677 |
3678 | 3678 |
3679 Handle<Object> JSProxy::DeletePropertyWithHandler( | 3679 Handle<Object> JSProxy::DeletePropertyWithHandler( |
3680 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { | 3680 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3910 int descriptor = transition_map->LastAdded(); | 3910 int descriptor = transition_map->LastAdded(); |
3911 | 3911 |
3912 DescriptorArray* descriptors = transition_map->instance_descriptors(); | 3912 DescriptorArray* descriptors = transition_map->instance_descriptors(); |
3913 PropertyDetails details = descriptors->GetDetails(descriptor); | 3913 PropertyDetails details = descriptors->GetDetails(descriptor); |
3914 | 3914 |
3915 if (details.type() == CALLBACKS || attributes != details.attributes()) { | 3915 if (details.type() == CALLBACKS || attributes != details.attributes()) { |
3916 // AddProperty will either normalize the object, or create a new fast copy | 3916 // AddProperty will either normalize the object, or create a new fast copy |
3917 // of the map. If we get a fast copy of the map, all field representations | 3917 // of the map. If we get a fast copy of the map, all field representations |
3918 // will be tagged since the transition is omitted. | 3918 // will be tagged since the transition is omitted. |
3919 return JSObject::AddProperty( | 3919 return JSObject::AddProperty( |
3920 object, name, value, attributes, kNonStrictMode, | 3920 object, name, value, attributes, kSloppyMode, |
3921 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, | 3921 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, |
3922 JSReceiver::OMIT_EXTENSIBILITY_CHECK, | 3922 JSReceiver::OMIT_EXTENSIBILITY_CHECK, |
3923 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); | 3923 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); |
3924 } | 3924 } |
3925 | 3925 |
3926 // Keep the target CONSTANT if the same value is stored. | 3926 // Keep the target CONSTANT if the same value is stored. |
3927 // TODO(verwaest): Also support keeping the placeholder | 3927 // TODO(verwaest): Also support keeping the placeholder |
3928 // (value->IsUninitialized) as constant. | 3928 // (value->IsUninitialized) as constant. |
3929 if (details.type() == CONSTANT && | 3929 if (details.type() == CONSTANT && |
3930 descriptors->GetValue(descriptor) == *value) { | 3930 descriptors->GetValue(descriptor) == *value) { |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4177 LookupResult lookup(isolate); | 4177 LookupResult lookup(isolate); |
4178 object->LocalLookup(*name, &lookup, true); | 4178 object->LocalLookup(*name, &lookup, true); |
4179 if (!lookup.IsFound()) { | 4179 if (!lookup.IsFound()) { |
4180 object->map()->LookupTransition(*object, *name, &lookup); | 4180 object->map()->LookupTransition(*object, *name, &lookup); |
4181 } | 4181 } |
4182 | 4182 |
4183 // Check access rights if needed. | 4183 // Check access rights if needed. |
4184 if (object->IsAccessCheckNeeded()) { | 4184 if (object->IsAccessCheckNeeded()) { |
4185 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { | 4185 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { |
4186 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value, | 4186 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value, |
4187 false, kNonStrictMode); | 4187 false, kSloppyMode); |
4188 } | 4188 } |
4189 } | 4189 } |
4190 | 4190 |
4191 if (object->IsJSGlobalProxy()) { | 4191 if (object->IsJSGlobalProxy()) { |
4192 Handle<Object> proto(object->GetPrototype(), isolate); | 4192 Handle<Object> proto(object->GetPrototype(), isolate); |
4193 if (proto->IsNull()) return value; | 4193 if (proto->IsNull()) return value; |
4194 ASSERT(proto->IsJSGlobalObject()); | 4194 ASSERT(proto->IsJSGlobalObject()); |
4195 return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), | 4195 return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), |
4196 name, value, attributes, value_type, mode, extensibility_check); | 4196 name, value, attributes, value_type, mode, extensibility_check); |
4197 } | 4197 } |
4198 | 4198 |
4199 if (lookup.IsFound() && | 4199 if (lookup.IsFound() && |
4200 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) { | 4200 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) { |
4201 object->LocalLookupRealNamedProperty(*name, &lookup); | 4201 object->LocalLookupRealNamedProperty(*name, &lookup); |
4202 } | 4202 } |
4203 | 4203 |
4204 // Check for accessor in prototype chain removed here in clone. | 4204 // Check for accessor in prototype chain removed here in clone. |
4205 if (!lookup.IsFound()) { | 4205 if (!lookup.IsFound()) { |
4206 object->map()->LookupTransition(*object, *name, &lookup); | 4206 object->map()->LookupTransition(*object, *name, &lookup); |
4207 TransitionFlag flag = lookup.IsFound() | 4207 TransitionFlag flag = lookup.IsFound() |
4208 ? OMIT_TRANSITION : INSERT_TRANSITION; | 4208 ? OMIT_TRANSITION : INSERT_TRANSITION; |
4209 // Neither properties nor transitions found. | 4209 // Neither properties nor transitions found. |
4210 return AddProperty(object, name, value, attributes, kNonStrictMode, | 4210 return AddProperty(object, name, value, attributes, kSloppyMode, |
4211 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag); | 4211 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag); |
4212 } | 4212 } |
4213 | 4213 |
4214 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 4214 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
4215 PropertyAttributes old_attributes = ABSENT; | 4215 PropertyAttributes old_attributes = ABSENT; |
4216 bool is_observed = FLAG_harmony_observation && | 4216 bool is_observed = FLAG_harmony_observation && |
4217 object->map()->is_observed() && | 4217 object->map()->is_observed() && |
4218 *name != isolate->heap()->hidden_string(); | 4218 *name != isolate->heap()->hidden_string(); |
4219 if (is_observed && lookup.IsProperty()) { | 4219 if (is_observed && lookup.IsProperty()) { |
4220 if (lookup.IsDataProperty()) old_value = | 4220 if (lookup.IsDataProperty()) old_value = |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4730 } | 4730 } |
4731 | 4731 |
4732 | 4732 |
4733 MaybeObject* JSObject::NormalizeElements() { | 4733 MaybeObject* JSObject::NormalizeElements() { |
4734 ASSERT(!HasExternalArrayElements()); | 4734 ASSERT(!HasExternalArrayElements()); |
4735 | 4735 |
4736 // Find the backing store. | 4736 // Find the backing store. |
4737 FixedArrayBase* array = FixedArrayBase::cast(elements()); | 4737 FixedArrayBase* array = FixedArrayBase::cast(elements()); |
4738 Map* old_map = array->map(); | 4738 Map* old_map = array->map(); |
4739 bool is_arguments = | 4739 bool is_arguments = |
4740 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); | 4740 (old_map == old_map->GetHeap()->sloppy_arguments_elements_map()); |
4741 if (is_arguments) { | 4741 if (is_arguments) { |
4742 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); | 4742 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); |
4743 } | 4743 } |
4744 if (array->IsDictionary()) return array; | 4744 if (array->IsDictionary()) return array; |
4745 | 4745 |
4746 ASSERT(HasFastSmiOrObjectElements() || | 4746 ASSERT(HasFastSmiOrObjectElements() || |
4747 HasFastDoubleElements() || | 4747 HasFastDoubleElements() || |
4748 HasFastArgumentsElements()); | 4748 HasFastArgumentsElements()); |
4749 // Compute the effective length and allocate a new backing store. | 4749 // Compute the effective length and allocate a new backing store. |
4750 int length = IsJSArray() | 4750 int length = IsJSArray() |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5383 case FAST_SMI_ELEMENTS: | 5383 case FAST_SMI_ELEMENTS: |
5384 case FAST_HOLEY_SMI_ELEMENTS: | 5384 case FAST_HOLEY_SMI_ELEMENTS: |
5385 break; | 5385 break; |
5386 case FAST_ELEMENTS: | 5386 case FAST_ELEMENTS: |
5387 case FAST_HOLEY_ELEMENTS: | 5387 case FAST_HOLEY_ELEMENTS: |
5388 case DICTIONARY_ELEMENTS: { | 5388 case DICTIONARY_ELEMENTS: { |
5389 FixedArray* elements = FixedArray::cast(this->elements()); | 5389 FixedArray* elements = FixedArray::cast(this->elements()); |
5390 if (ReferencesObjectFromElements(elements, kind, obj)) return true; | 5390 if (ReferencesObjectFromElements(elements, kind, obj)) return true; |
5391 break; | 5391 break; |
5392 } | 5392 } |
5393 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 5393 case SLOPPY_ARGUMENTS_ELEMENTS: { |
5394 FixedArray* parameter_map = FixedArray::cast(elements()); | 5394 FixedArray* parameter_map = FixedArray::cast(elements()); |
5395 // Check the mapped parameters. | 5395 // Check the mapped parameters. |
5396 int length = parameter_map->length(); | 5396 int length = parameter_map->length(); |
5397 for (int i = 2; i < length; ++i) { | 5397 for (int i = 2; i < length; ++i) { |
5398 Object* value = parameter_map->get(i); | 5398 Object* value = parameter_map->get(i); |
5399 if (!value->IsTheHole() && value == obj) return true; | 5399 if (!value->IsTheHole() && value == obj) return true; |
5400 } | 5400 } |
5401 // Check the arguments. | 5401 // Check the arguments. |
5402 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 5402 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
5403 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : | 5403 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5521 } | 5521 } |
5522 details = details.CopyAddAttributes( | 5522 details = details.CopyAddAttributes( |
5523 static_cast<PropertyAttributes>(attrs)); | 5523 static_cast<PropertyAttributes>(attrs)); |
5524 dictionary->DetailsAtPut(i, details); | 5524 dictionary->DetailsAtPut(i, details); |
5525 } | 5525 } |
5526 } | 5526 } |
5527 } | 5527 } |
5528 | 5528 |
5529 | 5529 |
5530 Handle<Object> JSObject::Freeze(Handle<JSObject> object) { | 5530 Handle<Object> JSObject::Freeze(Handle<JSObject> object) { |
5531 // Freezing non-strict arguments should be handled elsewhere. | 5531 // Freezing sloppy arguments should be handled elsewhere. |
5532 ASSERT(!object->HasNonStrictArgumentsElements()); | 5532 ASSERT(!object->HasSloppyArgumentsElements()); |
5533 ASSERT(!object->map()->is_observed()); | 5533 ASSERT(!object->map()->is_observed()); |
5534 | 5534 |
5535 if (object->map()->is_frozen()) return object; | 5535 if (object->map()->is_frozen()) return object; |
5536 | 5536 |
5537 Isolate* isolate = object->GetIsolate(); | 5537 Isolate* isolate = object->GetIsolate(); |
5538 if (object->IsAccessCheckNeeded() && | 5538 if (object->IsAccessCheckNeeded() && |
5539 !isolate->MayNamedAccess(*object, | 5539 !isolate->MayNamedAccess(*object, |
5540 isolate->heap()->undefined_value(), | 5540 isolate->heap()->undefined_value(), |
5541 v8::ACCESS_KEYS)) { | 5541 v8::ACCESS_KEYS)) { |
5542 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); | 5542 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5789 Handle<Object> value( | 5789 Handle<Object> value( |
5790 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), | 5790 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), |
5791 isolate); | 5791 isolate); |
5792 if (value->IsJSObject()) { | 5792 if (value->IsJSObject()) { |
5793 Handle<JSObject> result = VisitElementOrProperty( | 5793 Handle<JSObject> result = VisitElementOrProperty( |
5794 copy, Handle<JSObject>::cast(value)); | 5794 copy, Handle<JSObject>::cast(value)); |
5795 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5795 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
5796 if (copying) { | 5796 if (copying) { |
5797 // Creating object copy for literals. No strict mode needed. | 5797 // Creating object copy for literals. No strict mode needed. |
5798 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty( | 5798 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty( |
5799 copy, key_string, result, NONE, kNonStrictMode)); | 5799 copy, key_string, result, NONE, kSloppyMode)); |
5800 } | 5800 } |
5801 } | 5801 } |
5802 } | 5802 } |
5803 } | 5803 } |
5804 | 5804 |
5805 // Deep copy local elements. | 5805 // Deep copy local elements. |
5806 // Pixel elements cannot be created using an object literal. | 5806 // Pixel elements cannot be created using an object literal. |
5807 ASSERT(!copy->HasExternalArrayElements()); | 5807 ASSERT(!copy->HasExternalArrayElements()); |
5808 switch (kind) { | 5808 switch (kind) { |
5809 case FAST_SMI_ELEMENTS: | 5809 case FAST_SMI_ELEMENTS: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5848 copy, Handle<JSObject>::cast(value)); | 5848 copy, Handle<JSObject>::cast(value)); |
5849 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5849 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
5850 if (copying) { | 5850 if (copying) { |
5851 element_dictionary->ValueAtPut(i, *result); | 5851 element_dictionary->ValueAtPut(i, *result); |
5852 } | 5852 } |
5853 } | 5853 } |
5854 } | 5854 } |
5855 } | 5855 } |
5856 break; | 5856 break; |
5857 } | 5857 } |
5858 case NON_STRICT_ARGUMENTS_ELEMENTS: | 5858 case SLOPPY_ARGUMENTS_ELEMENTS: |
5859 UNIMPLEMENTED(); | 5859 UNIMPLEMENTED(); |
5860 break; | 5860 break; |
5861 | 5861 |
5862 | 5862 |
5863 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 5863 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
5864 case EXTERNAL_##TYPE##_ELEMENTS: \ | 5864 case EXTERNAL_##TYPE##_ELEMENTS: \ |
5865 case TYPE##_ELEMENTS: \ | 5865 case TYPE##_ELEMENTS: \ |
5866 | 5866 |
5867 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 5867 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
5868 #undef TYPED_ARRAY_CASE | 5868 #undef TYPED_ARRAY_CASE |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6109 | 6109 |
6110 case DICTIONARY_ELEMENTS: | 6110 case DICTIONARY_ELEMENTS: |
6111 if (UpdateGetterSetterInDictionary(object->element_dictionary(), | 6111 if (UpdateGetterSetterInDictionary(object->element_dictionary(), |
6112 index, | 6112 index, |
6113 *getter, | 6113 *getter, |
6114 *setter, | 6114 *setter, |
6115 attributes)) { | 6115 attributes)) { |
6116 return; | 6116 return; |
6117 } | 6117 } |
6118 break; | 6118 break; |
6119 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 6119 case SLOPPY_ARGUMENTS_ELEMENTS: { |
6120 // Ascertain whether we have read-only properties or an existing | 6120 // Ascertain whether we have read-only properties or an existing |
6121 // getter/setter pair in an arguments elements dictionary backing | 6121 // getter/setter pair in an arguments elements dictionary backing |
6122 // store. | 6122 // store. |
6123 FixedArray* parameter_map = FixedArray::cast(object->elements()); | 6123 FixedArray* parameter_map = FixedArray::cast(object->elements()); |
6124 uint32_t length = parameter_map->length(); | 6124 uint32_t length = parameter_map->length(); |
6125 Object* probe = | 6125 Object* probe = |
6126 index < (length - 2) ? parameter_map->get(index + 2) : NULL; | 6126 index < (length - 2) ? parameter_map->get(index + 2) : NULL; |
6127 if (probe == NULL || probe->IsTheHole()) { | 6127 if (probe == NULL || probe->IsTheHole()) { |
6128 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 6128 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
6129 if (arguments->IsDictionary()) { | 6129 if (arguments->IsDictionary()) { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6260 bool had_dictionary_elements = object->HasDictionaryElements(); | 6260 bool had_dictionary_elements = object->HasDictionaryElements(); |
6261 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 6261 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
6262 ASSERT(object->HasDictionaryElements() || | 6262 ASSERT(object->HasDictionaryElements() || |
6263 object->HasDictionaryArgumentsElements()); | 6263 object->HasDictionaryArgumentsElements()); |
6264 // Update the dictionary with the new CALLBACKS property. | 6264 // Update the dictionary with the new CALLBACKS property. |
6265 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, | 6265 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, |
6266 details); | 6266 details); |
6267 dictionary->set_requires_slow_elements(); | 6267 dictionary->set_requires_slow_elements(); |
6268 | 6268 |
6269 // Update the dictionary backing store on the object. | 6269 // Update the dictionary backing store on the object. |
6270 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { | 6270 if (object->elements()->map() == heap->sloppy_arguments_elements_map()) { |
6271 // Also delete any parameter alias. | 6271 // Also delete any parameter alias. |
6272 // | 6272 // |
6273 // TODO(kmillikin): when deleting the last parameter alias we could | 6273 // TODO(kmillikin): when deleting the last parameter alias we could |
6274 // switch to a direct backing store without the parameter map. This | 6274 // switch to a direct backing store without the parameter map. This |
6275 // would allow GC of the context. | 6275 // would allow GC of the context. |
6276 FixedArray* parameter_map = FixedArray::cast(object->elements()); | 6276 FixedArray* parameter_map = FixedArray::cast(object->elements()); |
6277 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) { | 6277 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) { |
6278 parameter_map->set(index + 2, heap->the_hole_value()); | 6278 parameter_map->set(index + 2, heap->the_hole_value()); |
6279 } | 6279 } |
6280 parameter_map->set(1, *dictionary); | 6280 parameter_map->set(1, *dictionary); |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6560 case TYPE##_ELEMENTS: \ | 6560 case TYPE##_ELEMENTS: \ |
6561 | 6561 |
6562 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 6562 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
6563 #undef TYPED_ARRAY_CASE | 6563 #undef TYPED_ARRAY_CASE |
6564 // Ignore getters and setters on pixel and external array | 6564 // Ignore getters and setters on pixel and external array |
6565 // elements. | 6565 // elements. |
6566 return factory->undefined_value(); | 6566 return factory->undefined_value(); |
6567 | 6567 |
6568 case DICTIONARY_ELEMENTS: | 6568 case DICTIONARY_ELEMENTS: |
6569 break; | 6569 break; |
6570 case NON_STRICT_ARGUMENTS_ELEMENTS: | 6570 case SLOPPY_ARGUMENTS_ELEMENTS: |
6571 UNIMPLEMENTED(); | 6571 UNIMPLEMENTED(); |
6572 break; | 6572 break; |
6573 } | 6573 } |
6574 | 6574 |
6575 SetElementCallback(object, index, info, info->property_attributes()); | 6575 SetElementCallback(object, index, info, info->property_attributes()); |
6576 } else { | 6576 } else { |
6577 // Lookup the name. | 6577 // Lookup the name. |
6578 LookupResult result(isolate); | 6578 LookupResult result(isolate); |
6579 object->LocalLookup(*name, &result, true); | 6579 object->LocalLookup(*name, &result, true); |
6580 // ES5 forbids turning a property into an accessor if it's not | 6580 // ES5 forbids turning a property into an accessor if it's not |
(...skipping 3212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9793 } else { | 9793 } else { |
9794 function->map()->set_non_instance_prototype(false); | 9794 function->map()->set_non_instance_prototype(false); |
9795 } | 9795 } |
9796 | 9796 |
9797 return SetInstancePrototype(function, construct_prototype); | 9797 return SetInstancePrototype(function, construct_prototype); |
9798 } | 9798 } |
9799 | 9799 |
9800 | 9800 |
9801 void JSFunction::RemovePrototype() { | 9801 void JSFunction::RemovePrototype() { |
9802 Context* native_context = context()->native_context(); | 9802 Context* native_context = context()->native_context(); |
9803 Map* no_prototype_map = shared()->is_classic_mode() | 9803 Map* no_prototype_map = shared()->is_sloppy_mode() |
9804 ? native_context->function_without_prototype_map() | 9804 ? native_context->function_without_prototype_map() |
9805 : native_context->strict_mode_function_without_prototype_map(); | 9805 : native_context->strict_mode_function_without_prototype_map(); |
9806 | 9806 |
9807 if (map() == no_prototype_map) return; | 9807 if (map() == no_prototype_map) return; |
9808 | 9808 |
9809 ASSERT(map() == (shared()->is_classic_mode() | 9809 ASSERT(map() == (shared()->is_sloppy_mode() |
9810 ? native_context->function_map() | 9810 ? native_context->function_map() |
9811 : native_context->strict_mode_function_map())); | 9811 : native_context->strict_mode_function_map())); |
9812 | 9812 |
9813 set_map(no_prototype_map); | 9813 set_map(no_prototype_map); |
9814 set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value()); | 9814 set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value()); |
9815 } | 9815 } |
9816 | 9816 |
9817 | 9817 |
9818 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { | 9818 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { |
9819 if (function->has_initial_map()) return; | 9819 if (function->has_initial_map()) return; |
(...skipping 1412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11232 } else { | 11232 } else { |
11233 new_elements_kind = FAST_ELEMENTS; | 11233 new_elements_kind = FAST_ELEMENTS; |
11234 } | 11234 } |
11235 } | 11235 } |
11236 FixedArrayBase* old_elements = elements(); | 11236 FixedArrayBase* old_elements = elements(); |
11237 ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind); | 11237 ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind); |
11238 MaybeObject* maybe_obj = | 11238 MaybeObject* maybe_obj = |
11239 accessor->CopyElements(this, new_elements, elements_kind); | 11239 accessor->CopyElements(this, new_elements, elements_kind); |
11240 if (maybe_obj->IsFailure()) return maybe_obj; | 11240 if (maybe_obj->IsFailure()) return maybe_obj; |
11241 | 11241 |
11242 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) { | 11242 if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) { |
11243 Map* new_map = map(); | 11243 Map* new_map = map(); |
11244 if (new_elements_kind != elements_kind) { | 11244 if (new_elements_kind != elements_kind) { |
11245 MaybeObject* maybe = | 11245 MaybeObject* maybe = |
11246 GetElementsTransitionMap(GetIsolate(), new_elements_kind); | 11246 GetElementsTransitionMap(GetIsolate(), new_elements_kind); |
11247 if (!maybe->To(&new_map)) return maybe; | 11247 if (!maybe->To(&new_map)) return maybe; |
11248 } | 11248 } |
11249 ValidateElements(); | 11249 ValidateElements(); |
11250 set_map_and_elements(new_map, new_elements); | 11250 set_map_and_elements(new_map, new_elements); |
11251 | 11251 |
11252 // Transition through the allocation site as well if present. | 11252 // Transition through the allocation site as well if present. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11304 GetElementsTransitionMap(heap->isolate(), new_elements_kind); | 11304 GetElementsTransitionMap(heap->isolate(), new_elements_kind); |
11305 if (!maybe_obj->To(&new_map)) return maybe_obj; | 11305 if (!maybe_obj->To(&new_map)) return maybe_obj; |
11306 } | 11306 } |
11307 | 11307 |
11308 FixedArrayBase* old_elements = elements(); | 11308 FixedArrayBase* old_elements = elements(); |
11309 ElementsAccessor* accessor = ElementsAccessor::ForKind(FAST_DOUBLE_ELEMENTS); | 11309 ElementsAccessor* accessor = ElementsAccessor::ForKind(FAST_DOUBLE_ELEMENTS); |
11310 { MaybeObject* maybe_obj = | 11310 { MaybeObject* maybe_obj = |
11311 accessor->CopyElements(this, elems, elements_kind); | 11311 accessor->CopyElements(this, elems, elements_kind); |
11312 if (maybe_obj->IsFailure()) return maybe_obj; | 11312 if (maybe_obj->IsFailure()) return maybe_obj; |
11313 } | 11313 } |
11314 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) { | 11314 if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) { |
11315 ValidateElements(); | 11315 ValidateElements(); |
11316 set_map_and_elements(new_map, elems); | 11316 set_map_and_elements(new_map, elems); |
11317 } else { | 11317 } else { |
11318 FixedArray* parameter_map = FixedArray::cast(old_elements); | 11318 FixedArray* parameter_map = FixedArray::cast(old_elements); |
11319 parameter_map->set(1, elems); | 11319 parameter_map->set(1, elems); |
11320 } | 11320 } |
11321 | 11321 |
11322 if (FLAG_trace_elements_transitions) { | 11322 if (FLAG_trace_elements_transitions) { |
11323 PrintElementsTransition(stdout, elements_kind, old_elements, | 11323 PrintElementsTransition(stdout, elements_kind, old_elements, |
11324 GetElementsKind(), elems); | 11324 GetElementsKind(), elems); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11475 | 11475 |
11476 EndPerformSplice(self); | 11476 EndPerformSplice(self); |
11477 | 11477 |
11478 uint32_t index = Min(old_length, new_length); | 11478 uint32_t index = Min(old_length, new_length); |
11479 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; | 11479 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; |
11480 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; | 11480 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; |
11481 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 11481 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
11482 if (delete_count > 0) { | 11482 if (delete_count > 0) { |
11483 for (int i = indices.length() - 1; i >= 0; i--) { | 11483 for (int i = indices.length() - 1; i >= 0; i--) { |
11484 JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE, | 11484 JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE, |
11485 kNonStrictMode); | 11485 kSloppyMode); |
11486 } | 11486 } |
11487 | 11487 |
11488 SetProperty(deleted, isolate->factory()->length_string(), | 11488 SetProperty(deleted, isolate->factory()->length_string(), |
11489 isolate->factory()->NewNumberFromUint(delete_count), | 11489 isolate->factory()->NewNumberFromUint(delete_count), |
11490 NONE, kNonStrictMode); | 11490 NONE, kSloppyMode); |
11491 } | 11491 } |
11492 | 11492 |
11493 EnqueueSpliceRecord(self, index, deleted, add_count); | 11493 EnqueueSpliceRecord(self, index, deleted, add_count); |
11494 | 11494 |
11495 return *hresult; | 11495 return *hresult; |
11496 } | 11496 } |
11497 | 11497 |
11498 | 11498 |
11499 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map, | 11499 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map, |
11500 Handle<Object> prototype) { | 11500 Handle<Object> prototype) { |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12046 return value; | 12046 return value; |
12047 } | 12047 } |
12048 | 12048 |
12049 if (structure->IsAccessorPair()) { | 12049 if (structure->IsAccessorPair()) { |
12050 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | 12050 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
12051 if (setter->IsSpecFunction()) { | 12051 if (setter->IsSpecFunction()) { |
12052 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 12052 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
12053 return SetPropertyWithDefinedSetter( | 12053 return SetPropertyWithDefinedSetter( |
12054 object, Handle<JSReceiver>::cast(setter), value); | 12054 object, Handle<JSReceiver>::cast(setter), value); |
12055 } else { | 12055 } else { |
12056 if (strict_mode == kNonStrictMode) { | 12056 if (strict_mode == kSloppyMode) { |
12057 return value; | 12057 return value; |
12058 } | 12058 } |
12059 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); | 12059 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); |
12060 Handle<Object> args[2] = { key, holder }; | 12060 Handle<Object> args[2] = { key, holder }; |
12061 Handle<Object> error = isolate->factory()->NewTypeError( | 12061 Handle<Object> error = isolate->factory()->NewTypeError( |
12062 "no_setter_in_callback", HandleVector(args, 2)); | 12062 "no_setter_in_callback", HandleVector(args, 2)); |
12063 isolate->Throw(*error); | 12063 isolate->Throw(*error); |
12064 return Handle<Object>(); | 12064 return Handle<Object>(); |
12065 } | 12065 } |
12066 } | 12066 } |
12067 | 12067 |
12068 // TODO(dcarney): Handle correctly. | 12068 // TODO(dcarney): Handle correctly. |
12069 if (structure->IsDeclaredAccessorInfo()) return value; | 12069 if (structure->IsDeclaredAccessorInfo()) return value; |
12070 | 12070 |
12071 UNREACHABLE(); | 12071 UNREACHABLE(); |
12072 return Handle<Object>(); | 12072 return Handle<Object>(); |
12073 } | 12073 } |
12074 | 12074 |
12075 | 12075 |
12076 bool JSObject::HasFastArgumentsElements() { | 12076 bool JSObject::HasFastArgumentsElements() { |
12077 Heap* heap = GetHeap(); | 12077 Heap* heap = GetHeap(); |
12078 if (!elements()->IsFixedArray()) return false; | 12078 if (!elements()->IsFixedArray()) return false; |
12079 FixedArray* elements = FixedArray::cast(this->elements()); | 12079 FixedArray* elements = FixedArray::cast(this->elements()); |
12080 if (elements->map() != heap->non_strict_arguments_elements_map()) { | 12080 if (elements->map() != heap->sloppy_arguments_elements_map()) { |
12081 return false; | 12081 return false; |
12082 } | 12082 } |
12083 FixedArray* arguments = FixedArray::cast(elements->get(1)); | 12083 FixedArray* arguments = FixedArray::cast(elements->get(1)); |
12084 return !arguments->IsDictionary(); | 12084 return !arguments->IsDictionary(); |
12085 } | 12085 } |
12086 | 12086 |
12087 | 12087 |
12088 bool JSObject::HasDictionaryArgumentsElements() { | 12088 bool JSObject::HasDictionaryArgumentsElements() { |
12089 Heap* heap = GetHeap(); | 12089 Heap* heap = GetHeap(); |
12090 if (!elements()->IsFixedArray()) return false; | 12090 if (!elements()->IsFixedArray()) return false; |
12091 FixedArray* elements = FixedArray::cast(this->elements()); | 12091 FixedArray* elements = FixedArray::cast(this->elements()); |
12092 if (elements->map() != heap->non_strict_arguments_elements_map()) { | 12092 if (elements->map() != heap->sloppy_arguments_elements_map()) { |
12093 return false; | 12093 return false; |
12094 } | 12094 } |
12095 FixedArray* arguments = FixedArray::cast(elements->get(1)); | 12095 FixedArray* arguments = FixedArray::cast(elements->get(1)); |
12096 return arguments->IsDictionary(); | 12096 return arguments->IsDictionary(); |
12097 } | 12097 } |
12098 | 12098 |
12099 | 12099 |
12100 // Adding n elements in fast case is O(n*n). | 12100 // Adding n elements in fast case is O(n*n). |
12101 // Note: revisit design to have dual undefined values to capture absent | 12101 // Note: revisit design to have dual undefined values to capture absent |
12102 // elements. | 12102 // elements. |
(...skipping 11 matching lines...) Expand all Loading... |
12114 // returning undefined. If there is a store to the initial prototype object, | 12114 // returning undefined. If there is a store to the initial prototype object, |
12115 // make sure all of these optimizations are invalidated. | 12115 // make sure all of these optimizations are invalidated. |
12116 if (isolate->is_initial_object_prototype(*object) || | 12116 if (isolate->is_initial_object_prototype(*object) || |
12117 isolate->is_initial_array_prototype(*object)) { | 12117 isolate->is_initial_array_prototype(*object)) { |
12118 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, | 12118 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, |
12119 DependentCode::kElementsCantBeAddedGroup); | 12119 DependentCode::kElementsCantBeAddedGroup); |
12120 } | 12120 } |
12121 | 12121 |
12122 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); | 12122 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); |
12123 if (backing_store->map() == | 12123 if (backing_store->map() == |
12124 isolate->heap()->non_strict_arguments_elements_map()) { | 12124 isolate->heap()->sloppy_arguments_elements_map()) { |
12125 backing_store = handle(FixedArray::cast(backing_store->get(1))); | 12125 backing_store = handle(FixedArray::cast(backing_store->get(1))); |
12126 } else { | 12126 } else { |
12127 backing_store = EnsureWritableFastElements(object); | 12127 backing_store = EnsureWritableFastElements(object); |
12128 } | 12128 } |
12129 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); | 12129 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); |
12130 | 12130 |
12131 if (check_prototype && | 12131 if (check_prototype && |
12132 (index >= capacity || backing_store->get(index)->IsTheHole())) { | 12132 (index >= capacity || backing_store->get(index)->IsTheHole())) { |
12133 bool found; | 12133 bool found; |
12134 Handle<Object> result = SetElementWithCallbackSetterInPrototypes( | 12134 Handle<Object> result = SetElementWithCallbackSetterInPrototypes( |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12235 StrictModeFlag strict_mode, | 12235 StrictModeFlag strict_mode, |
12236 bool check_prototype, | 12236 bool check_prototype, |
12237 SetPropertyMode set_mode) { | 12237 SetPropertyMode set_mode) { |
12238 ASSERT(object->HasDictionaryElements() || | 12238 ASSERT(object->HasDictionaryElements() || |
12239 object->HasDictionaryArgumentsElements()); | 12239 object->HasDictionaryArgumentsElements()); |
12240 Isolate* isolate = object->GetIsolate(); | 12240 Isolate* isolate = object->GetIsolate(); |
12241 | 12241 |
12242 // Insert element in the dictionary. | 12242 // Insert element in the dictionary. |
12243 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 12243 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
12244 bool is_arguments = | 12244 bool is_arguments = |
12245 (elements->map() == isolate->heap()->non_strict_arguments_elements_map()); | 12245 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); |
12246 Handle<SeededNumberDictionary> dictionary(is_arguments | 12246 Handle<SeededNumberDictionary> dictionary(is_arguments |
12247 ? SeededNumberDictionary::cast(elements->get(1)) | 12247 ? SeededNumberDictionary::cast(elements->get(1)) |
12248 : SeededNumberDictionary::cast(*elements)); | 12248 : SeededNumberDictionary::cast(*elements)); |
12249 | 12249 |
12250 int entry = dictionary->FindEntry(index); | 12250 int entry = dictionary->FindEntry(index); |
12251 if (entry != SeededNumberDictionary::kNotFound) { | 12251 if (entry != SeededNumberDictionary::kNotFound) { |
12252 Handle<Object> element(dictionary->ValueAt(entry), isolate); | 12252 Handle<Object> element(dictionary->ValueAt(entry), isolate); |
12253 PropertyDetails details = dictionary->DetailsAt(entry); | 12253 PropertyDetails details = dictionary->DetailsAt(entry); |
12254 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { | 12254 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { |
12255 return SetElementWithCallback(object, element, index, value, object, | 12255 return SetElementWithCallback(object, element, index, value, object, |
12256 strict_mode); | 12256 strict_mode); |
12257 } else { | 12257 } else { |
12258 dictionary->UpdateMaxNumberKey(index); | 12258 dictionary->UpdateMaxNumberKey(index); |
12259 // If a value has not been initialized we allow writing to it even if it | 12259 // If a value has not been initialized we allow writing to it even if it |
12260 // is read-only (a declared const that has not been initialized). If a | 12260 // is read-only (a declared const that has not been initialized). If a |
12261 // value is being defined we skip attribute checks completely. | 12261 // value is being defined we skip attribute checks completely. |
12262 if (set_mode == DEFINE_PROPERTY) { | 12262 if (set_mode == DEFINE_PROPERTY) { |
12263 details = PropertyDetails( | 12263 details = PropertyDetails( |
12264 attributes, NORMAL, details.dictionary_index()); | 12264 attributes, NORMAL, details.dictionary_index()); |
12265 dictionary->DetailsAtPut(entry, details); | 12265 dictionary->DetailsAtPut(entry, details); |
12266 } else if (details.IsReadOnly() && !element->IsTheHole()) { | 12266 } else if (details.IsReadOnly() && !element->IsTheHole()) { |
12267 if (strict_mode == kNonStrictMode) { | 12267 if (strict_mode == kSloppyMode) { |
12268 return isolate->factory()->undefined_value(); | 12268 return isolate->factory()->undefined_value(); |
12269 } else { | 12269 } else { |
12270 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12270 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12271 Handle<Object> args[2] = { number, object }; | 12271 Handle<Object> args[2] = { number, object }; |
12272 Handle<Object> error = | 12272 Handle<Object> error = |
12273 isolate->factory()->NewTypeError("strict_read_only_property", | 12273 isolate->factory()->NewTypeError("strict_read_only_property", |
12274 HandleVector(args, 2)); | 12274 HandleVector(args, 2)); |
12275 isolate->Throw(*error); | 12275 isolate->Throw(*error); |
12276 return Handle<Object>(); | 12276 return Handle<Object>(); |
12277 } | 12277 } |
(...skipping 17 matching lines...) Expand all Loading... |
12295 if (check_prototype) { | 12295 if (check_prototype) { |
12296 bool found; | 12296 bool found; |
12297 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, | 12297 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, |
12298 index, value, &found, strict_mode); | 12298 index, value, &found, strict_mode); |
12299 if (found) return result; | 12299 if (found) return result; |
12300 } | 12300 } |
12301 | 12301 |
12302 // When we set the is_extensible flag to false we always force the | 12302 // When we set the is_extensible flag to false we always force the |
12303 // element into dictionary mode (and force them to stay there). | 12303 // element into dictionary mode (and force them to stay there). |
12304 if (!object->map()->is_extensible()) { | 12304 if (!object->map()->is_extensible()) { |
12305 if (strict_mode == kNonStrictMode) { | 12305 if (strict_mode == kSloppyMode) { |
12306 return isolate->factory()->undefined_value(); | 12306 return isolate->factory()->undefined_value(); |
12307 } else { | 12307 } else { |
12308 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12308 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12309 Handle<String> name = isolate->factory()->NumberToString(number); | 12309 Handle<String> name = isolate->factory()->NumberToString(number); |
12310 Handle<Object> args[1] = { name }; | 12310 Handle<Object> args[1] = { name }; |
12311 Handle<Object> error = | 12311 Handle<Object> error = |
12312 isolate->factory()->NewTypeError("object_not_extensible", | 12312 isolate->factory()->NewTypeError("object_not_extensible", |
12313 HandleVector(args, 1)); | 12313 HandleVector(args, 1)); |
12314 isolate->Throw(*error); | 12314 isolate->Throw(*error); |
12315 return Handle<Object>(); | 12315 return Handle<Object>(); |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12669 } | 12669 } |
12670 | 12670 |
12671 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 12671 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
12672 | 12672 |
12673 #undef TYPED_ARRAY_CASE | 12673 #undef TYPED_ARRAY_CASE |
12674 | 12674 |
12675 case DICTIONARY_ELEMENTS: | 12675 case DICTIONARY_ELEMENTS: |
12676 return SetDictionaryElement(object, index, value, attributes, strict_mode, | 12676 return SetDictionaryElement(object, index, value, attributes, strict_mode, |
12677 check_prototype, | 12677 check_prototype, |
12678 set_mode); | 12678 set_mode); |
12679 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 12679 case SLOPPY_ARGUMENTS_ELEMENTS: { |
12680 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); | 12680 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); |
12681 uint32_t length = parameter_map->length(); | 12681 uint32_t length = parameter_map->length(); |
12682 Handle<Object> probe = index < length - 2 ? | 12682 Handle<Object> probe = index < length - 2 ? |
12683 Handle<Object>(parameter_map->get(index + 2), isolate) : | 12683 Handle<Object>(parameter_map->get(index + 2), isolate) : |
12684 Handle<Object>(); | 12684 Handle<Object>(); |
12685 if (!probe.is_null() && !probe->IsTheHole()) { | 12685 if (!probe.is_null() && !probe->IsTheHole()) { |
12686 Handle<Context> context(Context::cast(parameter_map->get(0))); | 12686 Handle<Context> context(Context::cast(parameter_map->get(0))); |
12687 int context_index = Handle<Smi>::cast(probe)->value(); | 12687 int context_index = Handle<Smi>::cast(probe)->value(); |
12688 ASSERT(!context->get(context_index)->IsTheHole()); | 12688 ASSERT(!context->get(context_index)->IsTheHole()); |
12689 context->set(context_index, *value); | 12689 context->set(context_index, *value); |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13028 } | 13028 } |
13029 | 13029 |
13030 | 13030 |
13031 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { | 13031 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { |
13032 *capacity = 0; | 13032 *capacity = 0; |
13033 *used = 0; | 13033 *used = 0; |
13034 | 13034 |
13035 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); | 13035 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); |
13036 FixedArray* backing_store = NULL; | 13036 FixedArray* backing_store = NULL; |
13037 switch (GetElementsKind()) { | 13037 switch (GetElementsKind()) { |
13038 case NON_STRICT_ARGUMENTS_ELEMENTS: | 13038 case SLOPPY_ARGUMENTS_ELEMENTS: |
13039 backing_store_base = | 13039 backing_store_base = |
13040 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); | 13040 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); |
13041 backing_store = FixedArray::cast(backing_store_base); | 13041 backing_store = FixedArray::cast(backing_store_base); |
13042 if (backing_store->IsDictionary()) { | 13042 if (backing_store->IsDictionary()) { |
13043 SeededNumberDictionary* dictionary = | 13043 SeededNumberDictionary* dictionary = |
13044 SeededNumberDictionary::cast(backing_store); | 13044 SeededNumberDictionary::cast(backing_store); |
13045 *capacity = dictionary->Capacity(); | 13045 *capacity = dictionary->Capacity(); |
13046 *used = dictionary->NumberOfElements(); | 13046 *used = dictionary->NumberOfElements(); |
13047 break; | 13047 break; |
13048 } | 13048 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13128 if (!HasDenseElements()) return false; | 13128 if (!HasDenseElements()) return false; |
13129 // An object requiring access checks is never allowed to have fast | 13129 // An object requiring access checks is never allowed to have fast |
13130 // elements. If it had fast elements we would skip security checks. | 13130 // elements. If it had fast elements we would skip security checks. |
13131 if (IsAccessCheckNeeded()) return false; | 13131 if (IsAccessCheckNeeded()) return false; |
13132 // Observed objects may not go to fast mode because they rely on map checks, | 13132 // Observed objects may not go to fast mode because they rely on map checks, |
13133 // and for fast element accesses we sometimes check element kinds only. | 13133 // and for fast element accesses we sometimes check element kinds only. |
13134 if (FLAG_harmony_observation && map()->is_observed()) return false; | 13134 if (FLAG_harmony_observation && map()->is_observed()) return false; |
13135 | 13135 |
13136 FixedArray* elements = FixedArray::cast(this->elements()); | 13136 FixedArray* elements = FixedArray::cast(this->elements()); |
13137 SeededNumberDictionary* dictionary = NULL; | 13137 SeededNumberDictionary* dictionary = NULL; |
13138 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) { | 13138 if (elements->map() == GetHeap()->sloppy_arguments_elements_map()) { |
13139 dictionary = SeededNumberDictionary::cast(elements->get(1)); | 13139 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
13140 } else { | 13140 } else { |
13141 dictionary = SeededNumberDictionary::cast(elements); | 13141 dictionary = SeededNumberDictionary::cast(elements); |
13142 } | 13142 } |
13143 // If an element has been added at a very high index in the elements | 13143 // If an element has been added at a very high index in the elements |
13144 // dictionary, we cannot go back to fast case. | 13144 // dictionary, we cannot go back to fast case. |
13145 if (dictionary->requires_slow_elements()) return false; | 13145 if (dictionary->requires_slow_elements()) return false; |
13146 // If the dictionary backing storage takes up roughly half as much | 13146 // If the dictionary backing storage takes up roughly half as much |
13147 // space (in machine words) as a fast-case backing storage would, | 13147 // space (in machine words) as a fast-case backing storage would, |
13148 // the object should have fast elements. | 13148 // the object should have fast elements. |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13608 | 13608 |
13609 case DICTIONARY_ELEMENTS: { | 13609 case DICTIONARY_ELEMENTS: { |
13610 if (storage != NULL) { | 13610 if (storage != NULL) { |
13611 element_dictionary()->CopyKeysTo(storage, | 13611 element_dictionary()->CopyKeysTo(storage, |
13612 filter, | 13612 filter, |
13613 SeededNumberDictionary::SORTED); | 13613 SeededNumberDictionary::SORTED); |
13614 } | 13614 } |
13615 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); | 13615 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); |
13616 break; | 13616 break; |
13617 } | 13617 } |
13618 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 13618 case SLOPPY_ARGUMENTS_ELEMENTS: { |
13619 FixedArray* parameter_map = FixedArray::cast(elements()); | 13619 FixedArray* parameter_map = FixedArray::cast(elements()); |
13620 int mapped_length = parameter_map->length() - 2; | 13620 int mapped_length = parameter_map->length() - 2; |
13621 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 13621 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
13622 if (arguments->IsDictionary()) { | 13622 if (arguments->IsDictionary()) { |
13623 // Copy the keys from arguments first, because Dictionary::CopyKeysTo | 13623 // Copy the keys from arguments first, because Dictionary::CopyKeysTo |
13624 // will insert in storage starting at index 0. | 13624 // will insert in storage starting at index 0. |
13625 SeededNumberDictionary* dictionary = | 13625 SeededNumberDictionary* dictionary = |
13626 SeededNumberDictionary::cast(arguments); | 13626 SeededNumberDictionary::cast(arguments); |
13627 if (storage != NULL) { | 13627 if (storage != NULL) { |
13628 dictionary->CopyKeysTo( | 13628 dictionary->CopyKeysTo( |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13719 shared_(shared), | 13719 shared_(shared), |
13720 language_mode_(language_mode), | 13720 language_mode_(language_mode), |
13721 scope_position_(scope_position) { } | 13721 scope_position_(scope_position) { } |
13722 | 13722 |
13723 bool IsMatch(Object* other) { | 13723 bool IsMatch(Object* other) { |
13724 if (!other->IsFixedArray()) return false; | 13724 if (!other->IsFixedArray()) return false; |
13725 FixedArray* other_array = FixedArray::cast(other); | 13725 FixedArray* other_array = FixedArray::cast(other); |
13726 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 13726 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
13727 if (shared != shared_) return false; | 13727 if (shared != shared_) return false; |
13728 int language_unchecked = Smi::cast(other_array->get(2))->value(); | 13728 int language_unchecked = Smi::cast(other_array->get(2))->value(); |
13729 ASSERT(language_unchecked == CLASSIC_MODE || | 13729 ASSERT(language_unchecked == SLOPPY_MODE || |
13730 language_unchecked == STRICT_MODE || | 13730 language_unchecked == STRICT_MODE || |
13731 language_unchecked == EXTENDED_MODE); | 13731 language_unchecked == EXTENDED_MODE); |
13732 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); | 13732 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); |
13733 if (language_mode != language_mode_) return false; | 13733 if (language_mode != language_mode_) return false; |
13734 int scope_position = Smi::cast(other_array->get(3))->value(); | 13734 int scope_position = Smi::cast(other_array->get(3))->value(); |
13735 if (scope_position != scope_position_) return false; | 13735 if (scope_position != scope_position_) return false; |
13736 String* source = String::cast(other_array->get(1)); | 13736 String* source = String::cast(other_array->get(1)); |
13737 return source->Equals(source_); | 13737 return source->Equals(source_); |
13738 } | 13738 } |
13739 | 13739 |
(...skipping 20 matching lines...) Expand all Loading... |
13760 uint32_t Hash() { | 13760 uint32_t Hash() { |
13761 return StringSharedHashHelper( | 13761 return StringSharedHashHelper( |
13762 source_, shared_, language_mode_, scope_position_); | 13762 source_, shared_, language_mode_, scope_position_); |
13763 } | 13763 } |
13764 | 13764 |
13765 uint32_t HashForObject(Object* obj) { | 13765 uint32_t HashForObject(Object* obj) { |
13766 FixedArray* other_array = FixedArray::cast(obj); | 13766 FixedArray* other_array = FixedArray::cast(obj); |
13767 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 13767 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
13768 String* source = String::cast(other_array->get(1)); | 13768 String* source = String::cast(other_array->get(1)); |
13769 int language_unchecked = Smi::cast(other_array->get(2))->value(); | 13769 int language_unchecked = Smi::cast(other_array->get(2))->value(); |
13770 ASSERT(language_unchecked == CLASSIC_MODE || | 13770 ASSERT(language_unchecked == SLOPPY_MODE || |
13771 language_unchecked == STRICT_MODE || | 13771 language_unchecked == STRICT_MODE || |
13772 language_unchecked == EXTENDED_MODE); | 13772 language_unchecked == EXTENDED_MODE); |
13773 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); | 13773 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); |
13774 int scope_position = Smi::cast(other_array->get(3))->value(); | 13774 int scope_position = Smi::cast(other_array->get(3))->value(); |
13775 return StringSharedHashHelper( | 13775 return StringSharedHashHelper( |
13776 source, shared, language_mode, scope_position); | 13776 source, shared, language_mode, scope_position); |
13777 } | 13777 } |
13778 | 13778 |
13779 MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) { | 13779 MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) { |
13780 Object* obj; | 13780 Object* obj; |
(...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14985 } | 14985 } |
14986 | 14986 |
14987 | 14987 |
14988 // The key for the script compilation cache is dependent on the mode flags, | 14988 // The key for the script compilation cache is dependent on the mode flags, |
14989 // because they change the global language mode and thus binding behaviour. | 14989 // because they change the global language mode and thus binding behaviour. |
14990 // If flags change at some point, we must ensure that we do not hit the cache | 14990 // If flags change at some point, we must ensure that we do not hit the cache |
14991 // for code compiled with different settings. | 14991 // for code compiled with different settings. |
14992 static LanguageMode CurrentGlobalLanguageMode() { | 14992 static LanguageMode CurrentGlobalLanguageMode() { |
14993 return FLAG_use_strict | 14993 return FLAG_use_strict |
14994 ? (FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE) | 14994 ? (FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE) |
14995 : CLASSIC_MODE; | 14995 : SLOPPY_MODE; |
14996 } | 14996 } |
14997 | 14997 |
14998 | 14998 |
14999 Object* CompilationCacheTable::Lookup(String* src, Context* context) { | 14999 Object* CompilationCacheTable::Lookup(String* src, Context* context) { |
15000 SharedFunctionInfo* shared = context->closure()->shared(); | 15000 SharedFunctionInfo* shared = context->closure()->shared(); |
15001 StringSharedKey key(src, | 15001 StringSharedKey key(src, |
15002 shared, | 15002 shared, |
15003 CurrentGlobalLanguageMode(), | 15003 CurrentGlobalLanguageMode(), |
15004 RelocInfo::kNoPosition); | 15004 RelocInfo::kNoPosition); |
15005 int entry = FindEntry(&key); | 15005 int entry = FindEntry(&key); |
(...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16480 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16480 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16481 static const char* error_messages_[] = { | 16481 static const char* error_messages_[] = { |
16482 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16482 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16483 }; | 16483 }; |
16484 #undef ERROR_MESSAGES_TEXTS | 16484 #undef ERROR_MESSAGES_TEXTS |
16485 return error_messages_[reason]; | 16485 return error_messages_[reason]; |
16486 } | 16486 } |
16487 | 16487 |
16488 | 16488 |
16489 } } // namespace v8::internal | 16489 } } // namespace v8::internal |
OLD | NEW |