OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... | |
30 #include "src/hydrogen.h" | 30 #include "src/hydrogen.h" |
31 #include "src/ic/ic.h" | 31 #include "src/ic/ic.h" |
32 #include "src/interpreter/bytecodes.h" | 32 #include "src/interpreter/bytecodes.h" |
33 #include "src/isolate-inl.h" | 33 #include "src/isolate-inl.h" |
34 #include "src/log.h" | 34 #include "src/log.h" |
35 #include "src/lookup.h" | 35 #include "src/lookup.h" |
36 #include "src/macro-assembler.h" | 36 #include "src/macro-assembler.h" |
37 #include "src/messages.h" | 37 #include "src/messages.h" |
38 #include "src/objects-inl.h" | 38 #include "src/objects-inl.h" |
39 #include "src/profiler/cpu-profiler.h" | 39 #include "src/profiler/cpu-profiler.h" |
40 #include "src/property-descriptor.h" | |
40 #include "src/prototype.h" | 41 #include "src/prototype.h" |
41 #include "src/safepoint-table.h" | 42 #include "src/safepoint-table.h" |
42 #include "src/string-builder.h" | 43 #include "src/string-builder.h" |
43 #include "src/string-search.h" | 44 #include "src/string-search.h" |
44 #include "src/string-stream.h" | 45 #include "src/string-stream.h" |
45 #include "src/utils.h" | 46 #include "src/utils.h" |
46 | 47 |
47 #ifdef ENABLE_DISASSEMBLER | 48 #ifdef ENABLE_DISASSEMBLER |
48 #include "src/disasm.h" | 49 #include "src/disasm.h" |
49 #include "src/disassembler.h" | 50 #include "src/disassembler.h" |
(...skipping 5769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5819 | 5820 |
5820 | 5821 |
5821 MaybeHandle<Object> JSReceiver::DeletePropertyOrElement( | 5822 MaybeHandle<Object> JSReceiver::DeletePropertyOrElement( |
5822 Handle<JSReceiver> object, Handle<Name> name, LanguageMode language_mode) { | 5823 Handle<JSReceiver> object, Handle<Name> name, LanguageMode language_mode) { |
5823 LookupIterator it = LookupIterator::PropertyOrElement( | 5824 LookupIterator it = LookupIterator::PropertyOrElement( |
5824 name->GetIsolate(), object, name, LookupIterator::HIDDEN); | 5825 name->GetIsolate(), object, name, LookupIterator::HIDDEN); |
5825 return JSObject::DeleteProperty(&it, language_mode); | 5826 return JSObject::DeleteProperty(&it, language_mode); |
5826 } | 5827 } |
5827 | 5828 |
5828 | 5829 |
5830 // ES6 7.1.14 | |
5831 MaybeHandle<Object> ToPropertyKey(Isolate* isolate, Handle<Object> value) { | |
5832 // 1. Let key be ToPrimitive(argument, hint String). | |
5833 MaybeHandle<Object> maybe_key = | |
5834 Object::ToPrimitive(value, ToPrimitiveHint::kString); | |
5835 // 2. ReturnIfAbrupt(key). | |
5836 Handle<Object> key; | |
5837 if (!maybe_key.ToHandle(&key)) return key; | |
5838 // 3. If Type(key) is Symbol, then return key. | |
5839 if (key->IsSymbol()) return key; | |
5840 // 4. Return ToString(key). | |
5841 // Extending spec'ed behavior, we'd be happy to return an element index. | |
5842 if (key->IsSmi()) return key; | |
5843 if (key->IsHeapNumber()) { | |
5844 uint32_t uint_value; | |
5845 if (value->ToArrayLength(&uint_value) && | |
5846 uint_value <= static_cast<uint32_t>(Smi::kMaxValue)) { | |
5847 return handle(Smi::FromInt(static_cast<int>(uint_value)), isolate); | |
5848 } | |
5849 } | |
5850 return Object::ToString(isolate, key); | |
5851 } | |
5852 | |
5853 | |
5854 // ES6 19.1.2.4 | |
5855 // static | |
5856 Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> o, | |
5857 Handle<Object> name, | |
5858 Handle<Object> attributes) { | |
5859 // 1. If Type(O) is not Object, throw a TypeError exception. | |
5860 // TODO(jkummerow): Implement Proxy support, change to "IsSpecObject". | |
5861 if (!o->IsJSObject()) { | |
5862 Handle<String> fun_name = | |
5863 isolate->factory()->InternalizeUtf8String("Object.defineProperty"); | |
5864 THROW_NEW_ERROR_RETURN_FAILURE( | |
5865 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name)); | |
5866 } | |
5867 // 2. Let key be ToPropertyKey(P). | |
5868 // 3. ReturnIfAbrupt(key). | |
5869 Handle<Object> key; | |
5870 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key, | |
5871 ToPropertyKey(isolate, name)); | |
5872 // 4. Let desc be ToPropertyDescriptor(Attributes). | |
5873 // 5. ReturnIfAbrupt(desc). | |
5874 PropertyDescriptor desc; | |
5875 if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) { | |
5876 return isolate->heap()->exception(); | |
5877 } | |
5878 // 6. Let success be DefinePropertyOrThrow(O,key, desc). | |
5879 bool success = DefineOwnProperty(isolate, Handle<JSObject>::cast(o), key, | |
5880 &desc, true /* should_throw */); | |
5881 // 7. ReturnIfAbrupt(success). | |
5882 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | |
5883 CHECK(success == true); | |
5884 // 8. Return O. | |
5885 return *o; | |
5886 } | |
5887 | |
5888 | |
5889 // ES6 19.1.2.3.1 | |
5890 // static | |
5891 Object* JSReceiver::DefineProperties(Isolate* isolate, Handle<Object> o, | |
5892 Handle<Object> properties) { | |
5893 // 1. If Type(O) is not Object, throw a TypeError exception. | |
5894 // TODO(jkummerow): Implement Proxy support, change to "IsSpecObject". | |
5895 if (!o->IsJSObject()) { | |
5896 Handle<String> fun_name = | |
5897 isolate->factory()->InternalizeUtf8String("Object.defineProperties"); | |
5898 THROW_NEW_ERROR_RETURN_FAILURE( | |
5899 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name)); | |
5900 } | |
5901 // 2. Let props be ToObject(Properties). | |
5902 // 3. ReturnIfAbrupt(props). | |
5903 Handle<JSReceiver> props; | |
5904 if (!Object::ToObject(isolate, properties).ToHandle(&props)) { | |
5905 THROW_NEW_ERROR_RETURN_FAILURE( | |
5906 isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject)); | |
5907 } | |
5908 // 4. Let keys be props.[[OwnPropertyKeys]](). | |
5909 // 5. ReturnIfAbrupt(keys). | |
5910 Handle<FixedArray> keys; | |
5911 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
5912 isolate, keys, | |
5913 JSReceiver::GetKeys(props, JSReceiver::OWN_ONLY, INCLUDE_SYMBOLS)); | |
5914 // 6. Let descriptors be an empty List. | |
5915 int capacity = keys->length(); | |
5916 std::vector<PropertyDescriptor> descriptors(capacity); | |
5917 // 7. Repeat for each element nextKey of keys in List order, | |
5918 for (int i = 0; i < keys->length(); ++i) { | |
5919 Handle<Object> next_key(keys->get(i), isolate); | |
5920 // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey). | |
5921 // 7b. ReturnIfAbrupt(propDesc). | |
5922 bool success = false; | |
5923 LookupIterator it = LookupIterator::PropertyOrElement( | |
5924 isolate, props, next_key, &success, LookupIterator::HIDDEN); | |
5925 DCHECK(success); | |
5926 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it); | |
Toon Verwaest
2015/10/06 15:55:18
On proxy props this will call getPropertyDescripto
Jakob Kummerow
2015/10/09 13:46:12
Ack. Follow-up -> added TODO comment.
| |
5927 if (!maybe.IsJust()) return isolate->heap()->exception(); | |
5928 PropertyAttributes attrs = maybe.FromJust(); | |
5929 // 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true: | |
5930 if (attrs == ABSENT) continue; | |
5931 // GetKeys() only returns enumerable keys. | |
5932 DCHECK((attrs & DONT_ENUM) == 0); | |
5933 // 7c i. Let descObj be Get(props, nextKey). | |
5934 // 7c ii. ReturnIfAbrupt(descObj). | |
5935 Handle<Object> desc_obj; | |
5936 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, desc_obj, | |
5937 JSObject::GetProperty(&it)); | |
5938 // 7c iii. Let desc be ToPropertyDescriptor(descObj). | |
5939 success = PropertyDescriptor::ToPropertyDescriptor(isolate, desc_obj, | |
5940 &descriptors[i]); | |
5941 // 7c iv. ReturnIfAbrupt(desc). | |
5942 if (!success) return isolate->heap()->exception(); | |
5943 // 7c v. Append the pair (a two element List) consisting of nextKey and | |
5944 // desc to the end of descriptors. | |
5945 descriptors[i].set_name(next_key); | |
5946 } | |
5947 // 8. For each pair from descriptors in list order, | |
5948 for (int i = 0; i < descriptors.size(); ++i) { | |
5949 PropertyDescriptor* desc = &descriptors[i]; | |
5950 // 8a. Let P be the first element of pair. | |
5951 // 8b. Let desc be the second element of pair. | |
5952 // 8c. Let status be DefinePropertyOrThrow(O, P, desc). | |
5953 bool status = | |
5954 DefineOwnProperty(isolate, Handle<JSObject>::cast(o), desc->name(), | |
5955 desc, true /* should_throw */); | |
5956 // 8d. ReturnIfAbrupt(status). | |
5957 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | |
5958 CHECK(status == true); | |
5959 } | |
5960 // 9. Return o. | |
5961 return *o; | |
5962 } | |
5963 | |
5964 | |
5965 // static | |
5966 bool JSReceiver::DefineOwnProperty(Isolate* isolate, Handle<JSObject> obj, | |
5967 Handle<Object> name, | |
Toon Verwaest
2015/10/06 15:55:18
DefineOwnProperty is defined in 9.1.6 to be called
Jakob Kummerow
2015/10/09 13:46:12
Done.
| |
5968 PropertyDescriptor* desc, | |
5969 bool should_throw) { | |
5970 if (obj->IsJSArray()) { | |
5971 return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(obj), name, | |
5972 desc, should_throw); | |
5973 } | |
5974 // TODO(jkummerow): Do we need special support for arguments? (ES6 9.4.4.2) | |
Toon Verwaest
2015/10/06 15:55:18
I don't think so.
For data properties:
DefineOwnP
Jakob Kummerow
2015/10/09 13:46:12
Acknowledged.
| |
5975 // TODO(jkummerow): Do we need special support for IntegerIndexedExotic? | |
Toon Verwaest
2015/10/06 15:55:18
IntegerIndexedExotic for data properties is alread
Jakob Kummerow
2015/10/09 13:46:12
Acknowledged, changed the comment to reflect that.
| |
5976 // (ES6 9.4.5.3) | |
5977 // TODO(jkummerow): Support Modules (ES6 9.4.6.6) | |
5978 // TODO(jkummerow): Support Proxies (ES6 9.5.6) | |
5979 return OrdinaryDefineOwnProperty(isolate, obj, name, desc, should_throw); | |
5980 } | |
5981 | |
5982 | |
5983 // static | |
5984 bool JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate, Handle<JSObject> o, | |
5985 Handle<Object> name, | |
5986 PropertyDescriptor* desc, | |
5987 bool should_throw) { | |
5988 bool success = false; | |
5989 LookupIterator it = LookupIterator::PropertyOrElement( | |
5990 isolate, o, name, &success, LookupIterator::HIDDEN); | |
5991 if (!success) return false; | |
Toon Verwaest
2015/10/06 15:55:18
name -> property_key, so shouldn't happen(?).
Jakob Kummerow
2015/10/09 13:46:12
Done.
| |
5992 return OrdinaryDefineOwnProperty(&it, desc, should_throw); | |
5993 } | |
5994 | |
5995 | |
5996 // ES6 9.1.6.1 | |
5997 // static | |
5998 bool JSReceiver::OrdinaryDefineOwnProperty(LookupIterator* it, | |
5999 PropertyDescriptor* desc, | |
6000 bool should_throw) { | |
6001 Isolate* isolate = it->isolate(); | |
6002 // == OrdinaryDefineOwnProperty (O, P, Desc) == | |
6003 // 1. Let current be O.[[GetOwnProperty]](P). | |
6004 // 2. ReturnIfAbrupt(current). | |
6005 PropertyDescriptor current; | |
6006 if (!GetOwnPropertyDescriptor(it, ¤t) && | |
6007 isolate->has_pending_exception()) { | |
6008 return false; | |
6009 } | |
6010 // 3. Let extensible be the value of the [[Extensible]] internal slot of O. | |
6011 Handle<JSObject> o = Handle<JSObject>::cast(it->GetReceiver()); | |
6012 bool extensible = JSObject::IsExtensible(o); | |
6013 | |
6014 bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc); | |
6015 bool desc_is_accessor_descriptor = | |
6016 PropertyDescriptor::IsAccessorDescriptor(desc); | |
6017 bool desc_is_generic_descriptor = | |
6018 PropertyDescriptor::IsGenericDescriptor(desc); | |
6019 | |
6020 // == ValidateAndApplyPropertyDescriptor (O, P, extensible, Desc, current) == | |
6021 // 2. If current is undefined, then | |
6022 if (current.is_empty()) { | |
6023 // 2a. If extensible is false, return false. | |
6024 if (!extensible) { | |
6025 if (should_throw) { | |
6026 isolate->Throw(*isolate->factory()->NewTypeError( | |
6027 MessageTemplate::kDefineDisallowed, it->GetName())); | |
6028 } | |
6029 return false; | |
6030 } | |
6031 // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then: | |
6032 // (This is equivalent to !IsAccessorDescriptor(desc).) | |
6033 DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) == | |
6034 !desc_is_accessor_descriptor); | |
6035 if (!desc_is_accessor_descriptor) { | |
6036 // 2c i. If O is not undefined, create an own data property named P of | |
6037 // object O whose [[Value]], [[Writable]], [[Enumerable]] and | |
6038 // [[Configurable]] attribute values are described by Desc. If the value | |
6039 // of an attribute field of Desc is absent, the attribute of the newly | |
6040 // created property is set to its default value. | |
6041 if (!o->IsUndefined()) { | |
6042 if (!desc->has_writable()) desc->set_writable(false); | |
6043 if (!desc->has_enumerable()) desc->set_enumerable(false); | |
6044 if (!desc->has_configurable()) desc->set_configurable(false); | |
6045 Handle<Object> value( | |
6046 desc->has_value() | |
6047 ? desc->value() | |
6048 : Handle<Object>::cast(isolate->factory()->undefined_value())); | |
6049 MaybeHandle<Object> result = | |
6050 JSObject::DefineOwnPropertyIgnoreAttributes(it, value, | |
6051 desc->ToAttributes()); | |
6052 if (result.is_null()) return false; | |
6053 } | |
6054 } else { | |
6055 // 2d. Else Desc must be an accessor Property Descriptor, | |
6056 DCHECK(desc_is_accessor_descriptor); | |
6057 // 2d i. If O is not undefined, create an own accessor property named P | |
6058 // of object O whose [[Get]], [[Set]], [[Enumerable]] and | |
6059 // [[Configurable]] attribute values are described by Desc. If the value | |
6060 // of an attribute field of Desc is absent, the attribute of the newly | |
6061 // created property is set to its default value. | |
6062 if (!o->IsUndefined()) { | |
6063 if (!desc->has_enumerable()) desc->set_enumerable(false); | |
6064 if (!desc->has_configurable()) desc->set_configurable(false); | |
6065 Handle<Object> getter( | |
6066 desc->has_get() | |
6067 ? desc->get() | |
6068 : Handle<Object>::cast(isolate->factory()->undefined_value())); | |
6069 Handle<Object> setter( | |
6070 desc->has_set() | |
6071 ? desc->set() | |
6072 : Handle<Object>::cast(isolate->factory()->undefined_value())); | |
6073 MaybeHandle<Object> result = | |
6074 JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes()); | |
6075 if (result.is_null()) return false; | |
6076 } | |
6077 } | |
6078 // 2e. Return true. | |
6079 return true; | |
6080 } | |
6081 // 3. Return true, if every field in Desc is absent. | |
6082 // 4. Return true, if every field in Desc also occurs in current and the | |
6083 // value of every field in Desc is the same value as the corresponding field | |
6084 // in current when compared using the SameValue algorithm. | |
6085 if ((!desc->has_enumerable() || desc->enumerable() == current.enumerable()) && | |
6086 (!desc->has_configurable() || | |
6087 desc->configurable() == current.configurable()) && | |
6088 (!desc->has_value() || | |
6089 (current.has_value() && current.value()->SameValue(*desc->value()))) && | |
6090 (!desc->has_writable() || | |
6091 (current.has_writable() && current.writable() == desc->writable())) && | |
6092 (!desc->has_get() || | |
6093 (current.has_get() && current.get()->SameValue(*desc->get()))) && | |
6094 (!desc->has_set() || | |
6095 (current.has_set() && current.set()->SameValue(*desc->set())))) { | |
6096 return true; | |
6097 } | |
6098 // 5. If the [[Configurable]] field of current is false, then | |
6099 if (!current.configurable()) { | |
6100 // 5a. Return false, if the [[Configurable]] field of Desc is true. | |
6101 if (desc->has_configurable() && desc->configurable()) { | |
6102 if (should_throw) { | |
6103 isolate->Throw(*isolate->factory()->NewTypeError( | |
6104 MessageTemplate::kRedefineDisallowed, it->GetName())); | |
6105 } | |
6106 return false; | |
6107 } | |
6108 // 5b. Return false, if the [[Enumerable]] field of Desc is present and the | |
6109 // [[Enumerable]] fields of current and Desc are the Boolean negation of | |
6110 // each other. | |
6111 if (desc->has_enumerable() && desc->enumerable() != current.enumerable()) { | |
6112 if (should_throw) { | |
6113 isolate->Throw(*isolate->factory()->NewTypeError( | |
6114 MessageTemplate::kRedefineDisallowed, it->GetName())); | |
6115 } | |
6116 return false; | |
6117 } | |
6118 } | |
6119 | |
6120 bool current_is_data_descriptor = | |
6121 PropertyDescriptor::IsDataDescriptor(¤t); | |
6122 // 6. If IsGenericDescriptor(Desc) is true, no further validation is required. | |
6123 if (desc_is_generic_descriptor) { | |
6124 // Nothing to see here. | |
6125 | |
6126 // 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) have | |
6127 // different results, then: | |
6128 } else if (current_is_data_descriptor != desc_is_data_descriptor) { | |
6129 // 7a. Return false, if the [[Configurable]] field of current is false. | |
6130 if (!current.configurable()) { | |
6131 if (should_throw) { | |
6132 isolate->Throw(*isolate->factory()->NewTypeError( | |
6133 MessageTemplate::kRedefineDisallowed, it->GetName())); | |
6134 } | |
6135 return false; | |
6136 } | |
6137 // 7b. If IsDataDescriptor(current) is true, then: | |
6138 if (current_is_data_descriptor) { | |
6139 // 7b i. If O is not undefined, convert the property named P of object O | |
6140 // from a data property to an accessor property. Preserve the existing | |
6141 // values of the converted property's [[Configurable]] and [[Enumerable]] | |
6142 // attributes and set the rest of the property's attributes to their | |
6143 // default values. | |
6144 // --> Folded into step 10. | |
6145 } else { | |
6146 // 7c i. If O is not undefined, convert the property named P of object O | |
6147 // from an accessor property to a data property. Preserve the existing | |
6148 // values of the converted property’s [[Configurable]] and [[Enumerable]] | |
6149 // attributes and set the rest of the property’s attributes to their | |
6150 // default values. | |
6151 // --> Folded into step 10. | |
6152 } | |
6153 | |
6154 // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both | |
6155 // true, then: | |
6156 } else if (current_is_data_descriptor && desc_is_data_descriptor) { | |
6157 // 8a. If the [[Configurable]] field of current is false, then: | |
6158 if (!current.configurable()) { | |
6159 // [Strong mode] Disallow changing writable -> readonly for | |
6160 // non-configurable properties. | |
6161 if (current.writable() && desc->has_writable() && !desc->writable() && | |
6162 o->map()->is_strong()) { | |
6163 if (should_throw) { | |
6164 isolate->Throw(*isolate->factory()->NewTypeError( | |
6165 MessageTemplate::kStrongRedefineDisallowed, o, it->GetName())); | |
6166 } | |
6167 return false; | |
6168 } | |
6169 // 8a i. Return false, if the [[Writable]] field of current is false and | |
6170 // the [[Writable]] field of Desc is true. | |
6171 if (!current.writable() && desc->has_writable() && desc->writable()) { | |
6172 if (should_throw) { | |
6173 isolate->Throw(*isolate->factory()->NewTypeError( | |
6174 MessageTemplate::kRedefineDisallowed, it->GetName())); | |
6175 } | |
6176 return false; | |
6177 } | |
6178 // 8a ii. If the [[Writable]] field of current is false, then: | |
6179 if (!current.writable()) { | |
6180 // 8a ii 1. Return false, if the [[Value]] field of Desc is present and | |
6181 // SameValue(Desc.[[Value]], current.[[Value]]) is false. | |
6182 if (desc->has_value() && !desc->value()->SameValue(*current.value())) { | |
6183 if (should_throw) { | |
6184 isolate->Throw(*isolate->factory()->NewTypeError( | |
6185 MessageTemplate::kRedefineDisallowed, it->GetName())); | |
6186 } | |
6187 return false; | |
6188 } | |
6189 } | |
6190 } | |
6191 } else { | |
6192 // 9. Else IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc) | |
6193 // are both true, | |
6194 DCHECK(PropertyDescriptor::IsAccessorDescriptor(¤t) && | |
6195 desc_is_accessor_descriptor); | |
6196 // 9a. If the [[Configurable]] field of current is false, then: | |
6197 if (!current.configurable()) { | |
6198 // 9a i. Return false, if the [[Set]] field of Desc is present and | |
6199 // SameValue(Desc.[[Set]], current.[[Set]]) is false. | |
6200 if (desc->has_set() && !desc->set()->SameValue(*current.set())) { | |
6201 if (should_throw) { | |
6202 isolate->Throw(*isolate->factory()->NewTypeError( | |
6203 MessageTemplate::kRedefineDisallowed, it->GetName())); | |
6204 } | |
6205 return false; | |
6206 } | |
6207 // 9a ii. Return false, if the [[Get]] field of Desc is present and | |
6208 // SameValue(Desc.[[Get]], current.[[Get]]) is false. | |
6209 if (desc->has_get() && !desc->get()->SameValue(*current.get())) { | |
6210 if (should_throw) { | |
6211 isolate->Throw(*isolate->factory()->NewTypeError( | |
6212 MessageTemplate::kRedefineDisallowed, it->GetName())); | |
6213 } | |
6214 return false; | |
6215 } | |
6216 } | |
6217 } | |
6218 | |
6219 // 10. If O is not undefined, then: | |
6220 if (!o->IsUndefined()) { | |
6221 // 10a. For each field of Desc that is present, set the corresponding | |
6222 // attribute of the property named P of object O to the value of the field. | |
6223 PropertyAttributes attrs = NONE; | |
6224 | |
6225 if (desc->has_enumerable()) { | |
6226 attrs = static_cast<PropertyAttributes>( | |
6227 attrs | (desc->enumerable() ? NONE : DONT_ENUM)); | |
6228 } else { | |
6229 attrs = static_cast<PropertyAttributes>( | |
6230 attrs | (current.enumerable() ? NONE : DONT_ENUM)); | |
6231 } | |
6232 if (desc->has_configurable()) { | |
6233 attrs = static_cast<PropertyAttributes>( | |
6234 attrs | (desc->configurable() ? NONE : DONT_DELETE)); | |
6235 } else { | |
6236 attrs = static_cast<PropertyAttributes>( | |
6237 attrs | (current.configurable() ? NONE : DONT_DELETE)); | |
6238 } | |
6239 if (desc_is_data_descriptor || | |
6240 (desc_is_generic_descriptor && current_is_data_descriptor)) { | |
6241 if (desc->has_writable()) { | |
6242 attrs = static_cast<PropertyAttributes>( | |
6243 attrs | (desc->writable() ? NONE : READ_ONLY)); | |
6244 } else { | |
6245 attrs = static_cast<PropertyAttributes>( | |
6246 attrs | (current.writable() ? NONE : READ_ONLY)); | |
6247 } | |
6248 Handle<Object> value( | |
6249 desc->has_value() ? desc->value() | |
6250 : current.has_value() | |
6251 ? current.value() | |
6252 : Handle<Object>::cast( | |
6253 isolate->factory()->undefined_value())); | |
6254 MaybeHandle<Object> result = JSObject::DefineOwnPropertyIgnoreAttributes( | |
6255 it, value, attrs, JSObject::DONT_FORCE_FIELD); | |
6256 if (result.is_null()) return false; | |
6257 } else { | |
6258 DCHECK(desc_is_accessor_descriptor || | |
6259 (desc_is_generic_descriptor && | |
6260 PropertyDescriptor::IsAccessorDescriptor(¤t))); | |
6261 Handle<Object> getter( | |
6262 desc->has_get() | |
6263 ? desc->get() | |
6264 : current.has_get() ? current.get() | |
6265 : Handle<Object>::cast( | |
6266 isolate->factory()->undefined_value())); | |
6267 Handle<Object> setter( | |
6268 desc->has_set() | |
6269 ? desc->set() | |
6270 : current.has_set() ? current.set() | |
6271 : Handle<Object>::cast( | |
6272 isolate->factory()->undefined_value())); | |
6273 MaybeHandle<Object> result = | |
6274 JSObject::DefineAccessor(it, getter, setter, attrs); | |
6275 if (result.is_null()) return false; | |
6276 } | |
6277 } | |
6278 | |
6279 // 11. Return true. | |
6280 return true; | |
6281 } | |
6282 | |
6283 | |
6284 // TODO(jkummerow): Consider unification with FastAsArrayLength() in | |
6285 // accessors.cc. | |
6286 bool PropertyKeyToArrayLength(Handle<Object> value, uint32_t* length) { | |
6287 DCHECK(value->IsNumber() || value->IsName()); | |
6288 if (value->ToArrayLength(length)) return true; | |
6289 if (value->IsString()) return String::cast(*value)->AsArrayIndex(length); | |
Toon Verwaest
2015/10/06 15:55:18
Ugh ... :)
Jakob Kummerow
2015/10/09 13:46:12
Acknowledged.
| |
6290 return false; | |
6291 } | |
6292 | |
6293 | |
6294 bool PropertyKeyToArrayIndex(Handle<Object> index_obj, uint32_t* output) { | |
6295 return PropertyKeyToArrayLength(index_obj, output) && *output != kMaxUInt32; | |
6296 } | |
6297 | |
6298 | |
6299 // ES6 9.4.2.1 | |
6300 // static | |
6301 bool JSArray::DefineOwnProperty(Isolate* isolate, Handle<JSArray> o, | |
6302 Handle<Object> name, PropertyDescriptor* desc, | |
6303 bool should_throw) { | |
6304 // 1. Assert: IsPropertyKey(P) is true. ("P" is |name|.) | |
6305 // 2. If P is "length", then: | |
6306 // TODO(jkummerow): Check if we need slow string comparison. | |
6307 if (*name == isolate->heap()->length_string()) { | |
6308 // 2a. Return ArraySetLength(A, Desc). | |
6309 return ArraySetLength(isolate, o, desc, should_throw); | |
6310 } | |
6311 // 3. Else if P is an array index, then: | |
6312 uint32_t index = 0; | |
6313 if (PropertyKeyToArrayIndex(name, &index)) { | |
6314 // 3a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length"). | |
6315 PropertyDescriptor old_len_desc; | |
6316 bool success = GetOwnPropertyDescriptor( | |
6317 isolate, o, isolate->factory()->length_string(), &old_len_desc); | |
6318 // 3b. (Assert) | |
6319 DCHECK(success); | |
6320 USE(success); | |
6321 // 3c. Let oldLen be oldLenDesc.[[Value]]. | |
6322 uint32_t old_len = 0; | |
6323 CHECK(old_len_desc.value()->ToArrayLength(&old_len)); | |
6324 // 3d. Let index be ToUint32(P). | |
6325 // (Already done above.) | |
6326 // 3e. (Assert) | |
6327 // 3f. If index >= oldLen and oldLenDesc.[[Writable]] is false, | |
6328 // return false. | |
6329 if (index >= old_len && old_len_desc.has_writable() && | |
6330 !old_len_desc.writable()) { | |
6331 if (should_throw) { | |
6332 isolate->Throw(*isolate->factory()->NewTypeError( | |
6333 MessageTemplate::kDefineDisallowed, name)); | |
6334 } | |
6335 return false; | |
6336 } | |
6337 // 3g. Let succeeded be OrdinaryDefineOwnProperty(A, P, Desc). | |
6338 bool succeeded = | |
6339 OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw); | |
6340 // 3h. (Assert) | |
6341 // 3i. If succeeded is false, return false. | |
6342 if (!succeeded) return false; | |
6343 // 3j. If index >= oldLen, then: | |
6344 if (index >= old_len) { | |
6345 // 3j i. Set oldLenDesc.[[Value]] to index + 1. | |
6346 old_len_desc.set_value(isolate->factory()->NewNumberFromUint(index + 1)); | |
6347 // 3j ii. Let succeeded be | |
6348 // OrdinaryDefineOwnProperty(A, "length", oldLenDesc). | |
6349 OrdinaryDefineOwnProperty(isolate, o, isolate->factory()->length_string(), | |
6350 &old_len_desc, should_throw); | |
6351 // 3j iii. (Assert) | |
6352 } | |
6353 // 3k. Return true. | |
6354 return true; | |
6355 } | |
6356 | |
6357 // 4. Return OrdinaryDefineOwnProperty(A, P, Desc). | |
6358 return OrdinaryDefineOwnProperty(isolate, o, name, desc, should_throw); | |
6359 } | |
6360 | |
6361 | |
6362 // TODO(jkummerow): Consider unification with ArrayLengthSetter in accessors.cc. | |
6363 bool AnythingToArrayLength(Isolate* isolate, Handle<Object> length_obj, | |
6364 uint32_t* output) { | |
6365 // Fast path: check numbers and strings that can be converted directly | |
6366 // and unobservably. | |
6367 if (length_obj->ToUint32(output)) return true; | |
6368 if (length_obj->IsString() && | |
6369 Handle<String>::cast(length_obj)->AsArrayIndex(output)) { | |
6370 return true; | |
6371 } | |
6372 // Slow path: follow steps in ES6 9.4.2.4 "ArraySetLength". | |
6373 // 3. Let newLen be ToUint32(Desc.[[Value]]). | |
6374 Handle<Object> uint32_v; | |
6375 if (!Object::ToUint32(isolate, length_obj).ToHandle(&uint32_v)) { | |
6376 // 4. ReturnIfAbrupt(newLen). | |
6377 return false; | |
6378 } | |
6379 // 5. Let numberLen be ToNumber(Desc.[[Value]]). | |
6380 Handle<Object> number_v; | |
6381 if (!Object::ToNumber(length_obj).ToHandle(&number_v)) { | |
6382 // 6. ReturnIfAbrupt(newLen). | |
6383 return false; | |
6384 } | |
6385 // 7. If newLen != numberLen, throw a RangeError exception. | |
6386 if (uint32_v->Number() != number_v->Number()) { | |
6387 Handle<Object> exception = | |
6388 isolate->factory()->NewRangeError(MessageTemplate::kInvalidArrayLength); | |
6389 isolate->Throw(*exception); | |
6390 return false; | |
6391 } | |
6392 return uint32_v->ToArrayLength(output); | |
6393 } | |
6394 | |
6395 | |
6396 // ES6 9.4.2.4 | |
6397 // static | |
6398 bool JSArray::ArraySetLength(Isolate* isolate, Handle<JSArray> a, | |
6399 PropertyDescriptor* desc, bool should_throw) { | |
6400 // 1. If the [[Value]] field of Desc is absent, then | |
Toon Verwaest
2015/10/06 15:55:18
Most of this code duplicates the ArrayLengthSetter
Jakob Kummerow
2015/10/09 13:46:12
Well, ArrayLengthSetter is mostly concerned with c
| |
6401 if (!desc->has_value()) { | |
6402 // 1a. Return OrdinaryDefineOwnProperty(A, "length", Desc). | |
6403 return OrdinaryDefineOwnProperty( | |
6404 isolate, a, isolate->factory()->length_string(), desc, should_throw); | |
6405 } | |
6406 // 2. Let newLenDesc be a copy of Desc. | |
6407 // (Actual copying is not necessary.) | |
6408 PropertyDescriptor* new_len_desc = desc; | |
6409 // 3. - 7. Convert Desc.[[Value]] to newLen. | |
6410 uint32_t new_len = 0; | |
6411 if (!AnythingToArrayLength(isolate, desc->value(), &new_len)) { | |
6412 if (should_throw && !isolate->has_pending_exception()) { | |
6413 isolate->Throw(*isolate->factory()->NewTypeError( | |
6414 MessageTemplate::kCannotConvertToPrimitive)); | |
6415 } | |
6416 return false; | |
6417 } | |
6418 // 8. Set newLenDesc.[[Value]] to newLen. | |
6419 // (Done below, if needed.) | |
6420 // 9. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length"). | |
6421 PropertyDescriptor old_len_desc; | |
6422 bool success = GetOwnPropertyDescriptor( | |
6423 isolate, a, isolate->factory()->length_string(), &old_len_desc); | |
6424 // 10. (Assert) | |
6425 DCHECK(success); | |
6426 USE(success); | |
6427 // 11. Let oldLen be oldLenDesc.[[Value]]. | |
6428 uint32_t old_len = 0; | |
6429 CHECK(old_len_desc.value()->ToArrayLength(&old_len)); | |
6430 // 12. If newLen >= oldLen, then | |
6431 if (new_len >= old_len) { | |
6432 // 8. Set newLenDesc.[[Value]] to newLen. | |
6433 // 12a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc). | |
6434 new_len_desc->set_value(isolate->factory()->NewNumberFromUint(new_len)); | |
6435 return OrdinaryDefineOwnProperty(isolate, a, | |
6436 isolate->factory()->length_string(), | |
6437 new_len_desc, should_throw); | |
6438 } | |
6439 // 13. If oldLenDesc.[[Writable]] is false, return false. | |
6440 if (!old_len_desc.writable()) { | |
6441 if (should_throw) | |
6442 isolate->Throw(*isolate->factory()->NewTypeError( | |
6443 MessageTemplate::kRedefineDisallowed, | |
6444 isolate->factory()->length_string())); | |
6445 return false; | |
6446 } | |
6447 // 14. If newLenDesc.[[Writable]] is absent or has the value true, | |
6448 // let newWritable be true. | |
6449 bool new_writable = false; | |
6450 if (!new_len_desc->has_writable() || new_len_desc->writable()) { | |
6451 new_writable = true; | |
6452 } else { | |
6453 // 15. Else, | |
6454 // 15a. Need to defer setting the [[Writable]] attribute to false in case | |
6455 // any elements cannot be deleted. | |
Toon Verwaest
2015/10/06 15:55:18
gee ...
| |
6456 // 15b. Let newWritable be false. (It's initialized as "false" anyway.) | |
6457 // 15c. Set newLenDesc.[[Writable]] to true. | |
6458 // (Not needed.) | |
6459 } | |
6460 // Most of steps 16 through 19 is implemented by JSArray::SetLength. | |
6461 if (JSArray::ObservableSetLength(a, new_len).is_null()) { | |
6462 if (should_throw) isolate->OptionalRescheduleException(false); | |
6463 return false; | |
6464 } | |
6465 // Steps 19d-ii, 20. | |
6466 if (!new_writable) { | |
6467 PropertyDescriptor readonly; | |
6468 readonly.set_writable(false); | |
6469 OrdinaryDefineOwnProperty(isolate, a, isolate->factory()->length_string(), | |
6470 &readonly, should_throw); | |
6471 } | |
6472 uint32_t actual_new_len = 0; | |
6473 CHECK(a->length()->ToArrayLength(&actual_new_len)); | |
6474 // Steps 19d-v, 21. Return false if there were non-deletable elements. | |
6475 return actual_new_len == new_len; | |
6476 } | |
6477 | |
6478 | |
6479 // static | |
6480 bool JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate, | |
6481 Handle<JSObject> obj, | |
6482 Handle<Object> name, | |
6483 PropertyDescriptor* desc) { | |
6484 bool success = false; | |
6485 LookupIterator it = LookupIterator::PropertyOrElement( | |
6486 isolate, obj, name, &success, LookupIterator::HIDDEN); | |
Toon Verwaest
2015/10/06 15:55:18
property key "p" (spec) (name -> key), so cannot f
Jakob Kummerow
2015/10/09 13:46:12
Done.
| |
6487 if (!success) return false; | |
6488 return GetOwnPropertyDescriptor(&it, desc); | |
6489 } | |
6490 | |
6491 | |
6492 // ES6 9.1.5.1 | |
6493 // TODO(jkummerow): Any chance to unify this with | |
6494 // "MaybeHandle<Object> GetOwnProperty()" in runtime-object.cc? | |
Toon Verwaest
2015/10/06 15:55:18
TODO(): proxies: call getOwnPropertyDescriptor tra
Jakob Kummerow
2015/10/09 13:46:12
Done.
| |
6495 // Returns true on success; false if there was an exception or no property. | |
6496 // static | |
6497 bool JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it, | |
6498 PropertyDescriptor* desc) { | |
6499 Isolate* isolate = it->isolate(); | |
6500 // 1. (Assert) | |
6501 // 2. If O does not have an own property with key P, return undefined. | |
6502 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(it); | |
6503 | |
6504 if (!maybe.IsJust()) return false; | |
6505 PropertyAttributes attrs = maybe.FromJust(); | |
6506 if (attrs == ABSENT) return false; | |
6507 DCHECK(!isolate->has_pending_exception()); | |
6508 | |
6509 // 3. Let D be a newly created Property Descriptor with no fields. | |
6510 DCHECK(desc->is_empty()); | |
6511 // 4. Let X be O's own property whose key is P. | |
6512 // 5. If X is a data property, then | |
6513 bool is_accessor_pair = it->state() == LookupIterator::ACCESSOR && | |
6514 it->GetAccessors()->IsAccessorPair(); | |
6515 if (!is_accessor_pair) { | |
6516 // 5a. Set D.[[Value]] to the value of X's [[Value]] attribute. | |
6517 Handle<Object> value = JSObject::GetProperty(it).ToHandleChecked(); | |
6518 desc->set_value(value); | |
6519 // 5b. Set D.[[Writable]] to the value of X's [[Writable]] attribute | |
6520 desc->set_writable((attrs & READ_ONLY) == 0); | |
6521 } else { | |
6522 // 6. Else X is an accessor property, so | |
6523 Handle<AccessorPair> accessors = | |
6524 Handle<AccessorPair>::cast(it->GetAccessors()); | |
6525 // 6a. Set D.[[Get]] to the value of X's [[Get]] attribute. | |
6526 desc->set_get(handle(accessors->GetComponent(ACCESSOR_GETTER), isolate)); | |
6527 // 6b. Set D.[[Set]] to the value of X's [[Set]] attribute. | |
6528 desc->set_set(handle(accessors->GetComponent(ACCESSOR_SETTER), isolate)); | |
6529 } | |
6530 | |
6531 // 7. Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute. | |
6532 desc->set_enumerable((attrs & DONT_ENUM) == 0); | |
6533 // 8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute. | |
6534 desc->set_configurable((attrs & DONT_DELETE) == 0); | |
6535 // 9. Return D. | |
6536 return true; | |
6537 } | |
6538 | |
6539 | |
5829 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 6540 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
5830 ElementsKind kind, | 6541 ElementsKind kind, |
5831 Object* object) { | 6542 Object* object) { |
5832 DCHECK(IsFastObjectElementsKind(kind) || | 6543 DCHECK(IsFastObjectElementsKind(kind) || |
5833 kind == DICTIONARY_ELEMENTS); | 6544 kind == DICTIONARY_ELEMENTS); |
5834 if (IsFastObjectElementsKind(kind)) { | 6545 if (IsFastObjectElementsKind(kind)) { |
5835 int length = IsJSArray() | 6546 int length = IsJSArray() |
5836 ? Smi::cast(JSArray::cast(this)->length())->value() | 6547 ? Smi::cast(JSArray::cast(this)->length())->value() |
5837 : elements->length(); | 6548 : elements->length(); |
5838 for (int i = 0; i < length; ++i) { | 6549 for (int i = 0; i < length; ++i) { |
(...skipping 1137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6976 | 7687 |
6977 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, | 7688 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, |
6978 Handle<Name> name, | 7689 Handle<Name> name, |
6979 Handle<Object> getter, | 7690 Handle<Object> getter, |
6980 Handle<Object> setter, | 7691 Handle<Object> setter, |
6981 PropertyAttributes attributes) { | 7692 PropertyAttributes attributes) { |
6982 Isolate* isolate = object->GetIsolate(); | 7693 Isolate* isolate = object->GetIsolate(); |
6983 | 7694 |
6984 LookupIterator it = LookupIterator::PropertyOrElement( | 7695 LookupIterator it = LookupIterator::PropertyOrElement( |
6985 isolate, object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); | 7696 isolate, object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); |
7697 return DefineAccessor(&it, getter, setter, attributes); | |
7698 } | |
6986 | 7699 |
6987 if (it.state() == LookupIterator::ACCESS_CHECK) { | 7700 |
6988 if (!it.HasAccess()) { | 7701 MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it, |
6989 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>()); | 7702 Handle<Object> getter, |
7703 Handle<Object> setter, | |
7704 PropertyAttributes attributes) { | |
7705 Isolate* isolate = it->isolate(); | |
7706 | |
7707 if (it->state() == LookupIterator::ACCESS_CHECK) { | |
7708 if (!it->HasAccess()) { | |
7709 isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>()); | |
6990 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 7710 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
6991 return isolate->factory()->undefined_value(); | 7711 return isolate->factory()->undefined_value(); |
6992 } | 7712 } |
6993 it.Next(); | 7713 it->Next(); |
6994 } | 7714 } |
6995 | 7715 |
7716 Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); | |
6996 // Ignore accessors on typed arrays. | 7717 // Ignore accessors on typed arrays. |
6997 if (it.IsElement() && object->HasFixedTypedArrayElements()) { | 7718 if (it->IsElement() && object->HasFixedTypedArrayElements()) { |
6998 return it.factory()->undefined_value(); | 7719 return it->factory()->undefined_value(); |
6999 } | 7720 } |
7000 | 7721 |
7001 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 7722 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
7002 bool is_observed = object->map()->is_observed() && | 7723 bool is_observed = object->map()->is_observed() && |
7003 !isolate->IsInternallyUsedPropertyName(name); | 7724 !isolate->IsInternallyUsedPropertyName(it->GetName()); |
7004 bool preexists = false; | 7725 bool preexists = false; |
7005 if (is_observed) { | 7726 if (is_observed) { |
7006 CHECK(GetPropertyAttributes(&it).IsJust()); | 7727 CHECK(GetPropertyAttributes(it).IsJust()); |
7007 preexists = it.IsFound(); | 7728 preexists = it->IsFound(); |
7008 if (preexists && (it.state() == LookupIterator::DATA || | 7729 if (preexists && (it->state() == LookupIterator::DATA || |
7009 it.GetAccessors()->IsAccessorInfo())) { | 7730 it->GetAccessors()->IsAccessorInfo())) { |
7010 old_value = GetProperty(&it).ToHandleChecked(); | 7731 old_value = GetProperty(it).ToHandleChecked(); |
7011 } | 7732 } |
7012 } | 7733 } |
7013 | 7734 |
7014 DCHECK(getter->IsCallable() || getter->IsUndefined() || getter->IsNull()); | 7735 DCHECK(getter->IsCallable() || getter->IsUndefined() || getter->IsNull()); |
7015 DCHECK(setter->IsCallable() || setter->IsUndefined() || setter->IsNull()); | 7736 DCHECK(setter->IsCallable() || setter->IsUndefined() || setter->IsNull()); |
7016 // At least one of the accessors needs to be a new value. | 7737 // At least one of the accessors needs to be a new value. |
7017 DCHECK(!getter->IsNull() || !setter->IsNull()); | 7738 DCHECK(!getter->IsNull() || !setter->IsNull()); |
7018 if (!getter->IsNull()) { | 7739 if (!getter->IsNull()) { |
7019 it.TransitionToAccessorProperty(ACCESSOR_GETTER, getter, attributes); | 7740 it->TransitionToAccessorProperty(ACCESSOR_GETTER, getter, attributes); |
7020 } | 7741 } |
7021 if (!setter->IsNull()) { | 7742 if (!setter->IsNull()) { |
7022 it.TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes); | 7743 it->TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes); |
7023 } | 7744 } |
7024 | 7745 |
7025 if (is_observed) { | 7746 if (is_observed) { |
7026 // Make sure the top context isn't changed. | 7747 // Make sure the top context isn't changed. |
7027 AssertNoContextChange ncc(isolate); | 7748 AssertNoContextChange ncc(isolate); |
7028 const char* type = preexists ? "reconfigure" : "add"; | 7749 const char* type = preexists ? "reconfigure" : "add"; |
7029 RETURN_ON_EXCEPTION( | 7750 RETURN_ON_EXCEPTION( |
7030 isolate, EnqueueChangeRecord(object, type, name, old_value), Object); | 7751 isolate, EnqueueChangeRecord(object, type, it->GetName(), old_value), |
7752 Object); | |
7031 } | 7753 } |
7032 | 7754 |
7033 return isolate->factory()->undefined_value(); | 7755 return isolate->factory()->undefined_value(); |
7034 } | 7756 } |
7035 | 7757 |
7036 | 7758 |
7037 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, | 7759 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, |
7038 Handle<AccessorInfo> info) { | 7760 Handle<AccessorInfo> info) { |
7039 Isolate* isolate = object->GetIsolate(); | 7761 Isolate* isolate = object->GetIsolate(); |
7040 Handle<Name> name(Name::cast(info->name()), isolate); | 7762 Handle<Name> name(Name::cast(info->name()), isolate); |
(...skipping 9827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16868 if (cell->value() != *new_value) { | 17590 if (cell->value() != *new_value) { |
16869 cell->set_value(*new_value); | 17591 cell->set_value(*new_value); |
16870 Isolate* isolate = cell->GetIsolate(); | 17592 Isolate* isolate = cell->GetIsolate(); |
16871 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17593 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
16872 isolate, DependentCode::kPropertyCellChangedGroup); | 17594 isolate, DependentCode::kPropertyCellChangedGroup); |
16873 } | 17595 } |
16874 } | 17596 } |
16875 | 17597 |
16876 } // namespace internal | 17598 } // namespace internal |
16877 } // namespace v8 | 17599 } // namespace v8 |
OLD | NEW |