| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 4139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4150 } | 4150 } |
| 4151 | 4151 |
| 4152 *found = false; | 4152 *found = false; |
| 4153 return Nothing<bool>(); | 4153 return Nothing<bool>(); |
| 4154 } | 4154 } |
| 4155 | 4155 |
| 4156 | 4156 |
| 4157 Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value, | 4157 Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value, |
| 4158 LanguageMode language_mode, | 4158 LanguageMode language_mode, |
| 4159 StoreFromKeyed store_mode) { | 4159 StoreFromKeyed store_mode) { |
| 4160 bool found = false; | |
| 4161 Maybe<bool> result = | |
| 4162 SetPropertyInternal(it, value, language_mode, store_mode, &found); | |
| 4163 if (found) return result; | |
| 4164 ShouldThrow should_throw = | 4160 ShouldThrow should_throw = |
| 4165 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | 4161 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 4166 if (it->GetReceiver()->IsJSProxy() && it->GetName()->IsPrivate()) { | 4162 if (it->GetReceiver()->IsJSProxy() && it->GetName()->IsPrivate()) { |
| 4167 RETURN_FAILURE(it->isolate(), should_throw, | 4163 RETURN_FAILURE(it->isolate(), should_throw, |
| 4168 NewTypeError(MessageTemplate::kProxyPrivate)); | 4164 NewTypeError(MessageTemplate::kProxyPrivate)); |
| 4169 } | 4165 } |
| 4166 bool found = false; |
| 4167 Maybe<bool> result = |
| 4168 SetPropertyInternal(it, value, language_mode, store_mode, &found); |
| 4169 if (found) return result; |
| 4170 return AddDataProperty(it, value, NONE, should_throw, store_mode); | 4170 return AddDataProperty(it, value, NONE, should_throw, store_mode); |
| 4171 } | 4171 } |
| 4172 | 4172 |
| 4173 | 4173 |
| 4174 Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value, | 4174 Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value, |
| 4175 LanguageMode language_mode, | 4175 LanguageMode language_mode, |
| 4176 StoreFromKeyed store_mode) { | 4176 StoreFromKeyed store_mode) { |
| 4177 ShouldThrow should_throw = | 4177 ShouldThrow should_throw = |
| 4178 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; | 4178 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| 4179 Isolate* isolate = it->isolate(); | 4179 Isolate* isolate = it->isolate(); |
| 4180 if (it->GetReceiver()->IsJSProxy() && it->GetName()->IsPrivate()) { |
| 4181 RETURN_FAILURE(isolate, should_throw, |
| 4182 NewTypeError(MessageTemplate::kProxyPrivate)); |
| 4183 } |
| 4180 | 4184 |
| 4181 bool found = false; | 4185 bool found = false; |
| 4182 Maybe<bool> result = | 4186 Maybe<bool> result = |
| 4183 SetPropertyInternal(it, value, language_mode, store_mode, &found); | 4187 SetPropertyInternal(it, value, language_mode, store_mode, &found); |
| 4184 if (found) return result; | 4188 if (found) return result; |
| 4185 if (it->GetReceiver()->IsJSProxy() && it->GetName()->IsPrivate()) { | |
| 4186 RETURN_FAILURE(isolate, should_throw, | |
| 4187 NewTypeError(MessageTemplate::kProxyPrivate)); | |
| 4188 } | |
| 4189 | 4189 |
| 4190 // The property either doesn't exist on the holder or exists there as a data | 4190 // The property either doesn't exist on the holder or exists there as a data |
| 4191 // property. | 4191 // property. |
| 4192 | 4192 |
| 4193 if (!it->GetReceiver()->IsJSReceiver()) { | 4193 if (!it->GetReceiver()->IsJSReceiver()) { |
| 4194 return WriteToReadOnlyProperty(it, value, should_throw); | 4194 return WriteToReadOnlyProperty(it, value, should_throw); |
| 4195 } | 4195 } |
| 4196 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver()); | 4196 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver()); |
| 4197 | 4197 |
| 4198 LookupIterator::Configuration c = LookupIterator::OWN; | 4198 LookupIterator::Configuration c = LookupIterator::OWN; |
| (...skipping 1989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6188 if (result.IsEmpty()) return Nothing<bool>(); | 6188 if (result.IsEmpty()) return Nothing<bool>(); |
| 6189 | 6189 |
| 6190 DCHECK(result->IsBoolean()); | 6190 DCHECK(result->IsBoolean()); |
| 6191 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | 6191 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); |
| 6192 result_internal->VerifyApiCallResultType(); | 6192 result_internal->VerifyApiCallResultType(); |
| 6193 // Rebox CustomArguments::kReturnValueOffset before returning. | 6193 // Rebox CustomArguments::kReturnValueOffset before returning. |
| 6194 return Just(result_internal->BooleanValue()); | 6194 return Just(result_internal->BooleanValue()); |
| 6195 } | 6195 } |
| 6196 | 6196 |
| 6197 | 6197 |
| 6198 void JSObject::DeleteNormalizedProperty(Handle<JSObject> object, | 6198 void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object, |
| 6199 Handle<Name> name, int entry) { | 6199 Handle<Name> name, int entry) { |
| 6200 DCHECK(!object->HasFastProperties()); | 6200 DCHECK(!object->HasFastProperties()); |
| 6201 Isolate* isolate = object->GetIsolate(); | 6201 Isolate* isolate = object->GetIsolate(); |
| 6202 | 6202 |
| 6203 if (object->IsJSGlobalObject()) { | 6203 if (object->IsJSGlobalObject()) { |
| 6204 // If we have a global object, invalidate the cell and swap in a new one. | 6204 // If we have a global object, invalidate the cell and swap in a new one. |
| 6205 Handle<GlobalDictionary> dictionary(object->global_dictionary()); | 6205 Handle<GlobalDictionary> dictionary( |
| 6206 JSObject::cast(*object)->global_dictionary()); |
| 6206 DCHECK_NE(GlobalDictionary::kNotFound, entry); | 6207 DCHECK_NE(GlobalDictionary::kNotFound, entry); |
| 6207 | 6208 |
| 6208 auto cell = PropertyCell::InvalidateEntry(dictionary, entry); | 6209 auto cell = PropertyCell::InvalidateEntry(dictionary, entry); |
| 6209 cell->set_value(isolate->heap()->the_hole_value()); | 6210 cell->set_value(isolate->heap()->the_hole_value()); |
| 6210 // TODO(ishell): InvalidateForDelete | 6211 // TODO(ishell): InvalidateForDelete |
| 6211 cell->set_property_details( | 6212 cell->set_property_details( |
| 6212 cell->property_details().set_cell_type(PropertyCellType::kInvalidated)); | 6213 cell->property_details().set_cell_type(PropertyCellType::kInvalidated)); |
| 6213 } else { | 6214 } else { |
| 6214 Handle<NameDictionary> dictionary(object->property_dictionary()); | 6215 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 6215 DCHECK_NE(NameDictionary::kNotFound, entry); | 6216 DCHECK_NE(NameDictionary::kNotFound, entry); |
| 6216 | 6217 |
| 6217 NameDictionary::DeleteProperty(dictionary, entry); | 6218 NameDictionary::DeleteProperty(dictionary, entry); |
| 6218 Handle<NameDictionary> new_properties = | 6219 Handle<NameDictionary> new_properties = |
| 6219 NameDictionary::Shrink(dictionary, name); | 6220 NameDictionary::Shrink(dictionary, name); |
| 6220 object->set_properties(*new_properties); | 6221 object->set_properties(*new_properties); |
| 6221 } | 6222 } |
| 6222 } | 6223 } |
| 6223 | 6224 |
| 6224 | 6225 |
| 6225 Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it, | 6226 Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it, |
| 6226 LanguageMode language_mode) { | 6227 LanguageMode language_mode) { |
| 6227 Isolate* isolate = it->isolate(); | 6228 Isolate* isolate = it->isolate(); |
| 6228 | 6229 |
| 6229 if (it->state() == LookupIterator::JSPROXY) { | 6230 if (it->state() == LookupIterator::JSPROXY) { |
| 6230 return JSProxy::DeletePropertyOrElement(it->GetHolder<JSProxy>(), | 6231 return JSProxy::DeletePropertyOrElement(it->GetHolder<JSProxy>(), |
| 6231 it->GetName(), language_mode); | 6232 it->GetName(), language_mode); |
| 6232 } | 6233 } |
| 6233 | 6234 |
| 6234 if (it->GetReceiver()->IsJSProxy()) { | 6235 if (it->GetReceiver()->IsJSProxy()) { |
| 6235 DCHECK(it->state() == LookupIterator::NOT_FOUND); | 6236 if (it->state() != LookupIterator::NOT_FOUND) { |
| 6236 DCHECK(it->GetName()->IsPrivate()); | 6237 DCHECK_EQ(LookupIterator::DATA, it->state()); |
| 6238 DCHECK(it->GetName()->IsPrivate()); |
| 6239 it->Delete(); |
| 6240 } |
| 6237 return Just(true); | 6241 return Just(true); |
| 6238 } | 6242 } |
| 6239 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); | 6243 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); |
| 6240 | 6244 |
| 6241 bool is_observed = | 6245 bool is_observed = |
| 6242 receiver->map()->is_observed() && | 6246 receiver->map()->is_observed() && |
| 6243 (it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name())); | 6247 (it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name())); |
| 6244 | 6248 |
| 6245 Handle<Object> old_value = it->factory()->the_hole_value(); | 6249 Handle<Object> old_value = it->factory()->the_hole_value(); |
| 6246 | 6250 |
| (...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7071 } | 7075 } |
| 7072 | 7076 |
| 7073 | 7077 |
| 7074 // ES6 9.5.6 | 7078 // ES6 9.5.6 |
| 7075 // static | 7079 // static |
| 7076 Maybe<bool> JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> proxy, | 7080 Maybe<bool> JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> proxy, |
| 7077 Handle<Object> key, | 7081 Handle<Object> key, |
| 7078 PropertyDescriptor* desc, | 7082 PropertyDescriptor* desc, |
| 7079 ShouldThrow should_throw) { | 7083 ShouldThrow should_throw) { |
| 7080 STACK_CHECK(Nothing<bool>()); | 7084 STACK_CHECK(Nothing<bool>()); |
| 7085 if (key->IsSymbol() && Handle<Symbol>::cast(key)->IsPrivate()) { |
| 7086 return AddPrivateProperty(isolate, proxy, Handle<Symbol>::cast(key), desc, |
| 7087 should_throw); |
| 7088 } |
| 7081 Handle<String> trap_name = isolate->factory()->defineProperty_string(); | 7089 Handle<String> trap_name = isolate->factory()->defineProperty_string(); |
| 7082 // 1. Assert: IsPropertyKey(P) is true. | 7090 // 1. Assert: IsPropertyKey(P) is true. |
| 7083 DCHECK(key->IsName() || key->IsNumber()); | 7091 DCHECK(key->IsName() || key->IsNumber()); |
| 7084 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. | 7092 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. |
| 7085 Handle<Object> handler(proxy->handler(), isolate); | 7093 Handle<Object> handler(proxy->handler(), isolate); |
| 7086 // 3. If handler is null, throw a TypeError exception. | 7094 // 3. If handler is null, throw a TypeError exception. |
| 7087 // 4. Assert: Type(handler) is Object. | 7095 // 4. Assert: Type(handler) is Object. |
| 7088 if (proxy->IsRevoked()) { | 7096 if (proxy->IsRevoked()) { |
| 7089 isolate->Throw(*isolate->factory()->NewTypeError( | 7097 isolate->Throw(*isolate->factory()->NewTypeError( |
| 7090 MessageTemplate::kProxyRevoked, trap_name)); | 7098 MessageTemplate::kProxyRevoked, trap_name)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 7106 } | 7114 } |
| 7107 // 8. Let descObj be FromPropertyDescriptor(Desc). | 7115 // 8. Let descObj be FromPropertyDescriptor(Desc). |
| 7108 Handle<Object> desc_obj = desc->ToObject(isolate); | 7116 Handle<Object> desc_obj = desc->ToObject(isolate); |
| 7109 // 9. Let booleanTrapResult be | 7117 // 9. Let booleanTrapResult be |
| 7110 // ToBoolean(? Call(trap, handler, «target, P, descObj»)). | 7118 // ToBoolean(? Call(trap, handler, «target, P, descObj»)). |
| 7111 Handle<Name> property_name = | 7119 Handle<Name> property_name = |
| 7112 key->IsName() | 7120 key->IsName() |
| 7113 ? Handle<Name>::cast(key) | 7121 ? Handle<Name>::cast(key) |
| 7114 : Handle<Name>::cast(isolate->factory()->NumberToString(key)); | 7122 : Handle<Name>::cast(isolate->factory()->NumberToString(key)); |
| 7115 // Do not leak private property names. | 7123 // Do not leak private property names. |
| 7116 if (property_name->IsPrivate()) { | 7124 DCHECK(!property_name->IsPrivate()); |
| 7117 RETURN_FAILURE(isolate, should_throw, | |
| 7118 NewTypeError(MessageTemplate::kProxyPrivate)); | |
| 7119 } | |
| 7120 Handle<Object> trap_result_obj; | 7125 Handle<Object> trap_result_obj; |
| 7121 Handle<Object> args[] = {target, property_name, desc_obj}; | 7126 Handle<Object> args[] = {target, property_name, desc_obj}; |
| 7122 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 7127 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 7123 isolate, trap_result_obj, | 7128 isolate, trap_result_obj, |
| 7124 Execution::Call(isolate, trap, handler, arraysize(args), args), | 7129 Execution::Call(isolate, trap, handler, arraysize(args), args), |
| 7125 Nothing<bool>()); | 7130 Nothing<bool>()); |
| 7126 // 10. If booleanTrapResult is false, return false. | 7131 // 10. If booleanTrapResult is false, return false. |
| 7127 if (!trap_result_obj->BooleanValue()) { | 7132 if (!trap_result_obj->BooleanValue()) { |
| 7128 RETURN_FAILURE(isolate, should_throw, | 7133 RETURN_FAILURE(isolate, should_throw, |
| 7129 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor, | 7134 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsishFor, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7177 MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name)); | 7182 MessageTemplate::kProxyDefinePropertyNonConfigurable, property_name)); |
| 7178 return Nothing<bool>(); | 7183 return Nothing<bool>(); |
| 7179 } | 7184 } |
| 7180 } | 7185 } |
| 7181 // 17. Return true. | 7186 // 17. Return true. |
| 7182 return Just(true); | 7187 return Just(true); |
| 7183 } | 7188 } |
| 7184 | 7189 |
| 7185 | 7190 |
| 7186 // static | 7191 // static |
| 7192 Maybe<bool> JSProxy::AddPrivateProperty(Isolate* isolate, Handle<JSProxy> proxy, |
| 7193 Handle<Symbol> private_name, |
| 7194 PropertyDescriptor* desc, |
| 7195 ShouldThrow should_throw) { |
| 7196 // Despite the generic name, this can only add private data properties. |
| 7197 if (!PropertyDescriptor::IsDataDescriptor(desc) || |
| 7198 desc->ToAttributes() != DONT_ENUM) { |
| 7199 RETURN_FAILURE(isolate, should_throw, |
| 7200 NewTypeError(MessageTemplate::kProxyPrivate)); |
| 7201 } |
| 7202 DCHECK(proxy->map()->is_dictionary_map()); |
| 7203 Handle<Object> value = |
| 7204 desc->has_value() |
| 7205 ? desc->value() |
| 7206 : Handle<Object>::cast(isolate->factory()->undefined_value()); |
| 7207 |
| 7208 LookupIterator it(proxy, private_name); |
| 7209 |
| 7210 if (it.IsFound()) { |
| 7211 DCHECK_EQ(LookupIterator::DATA, it.state()); |
| 7212 DCHECK_EQ(DONT_ENUM, it.property_details().attributes()); |
| 7213 it.WriteDataValue(value); |
| 7214 return Just(true); |
| 7215 } |
| 7216 |
| 7217 Handle<NameDictionary> dict(proxy->property_dictionary()); |
| 7218 PropertyDetails details(DONT_ENUM, DATA, 0, PropertyCellType::kNoCell); |
| 7219 Handle<NameDictionary> result = |
| 7220 NameDictionary::Add(dict, private_name, value, details); |
| 7221 if (!dict.is_identical_to(result)) proxy->set_properties(*result); |
| 7222 return Just(true); |
| 7223 } |
| 7224 |
| 7225 |
| 7226 // static |
| 7187 Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate, | 7227 Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate, |
| 7188 Handle<JSReceiver> object, | 7228 Handle<JSReceiver> object, |
| 7189 Handle<Object> key, | 7229 Handle<Object> key, |
| 7190 PropertyDescriptor* desc) { | 7230 PropertyDescriptor* desc) { |
| 7191 bool success = false; | 7231 bool success = false; |
| 7192 DCHECK(key->IsName() || key->IsNumber()); // |key| is a PropertyKey... | 7232 DCHECK(key->IsName() || key->IsNumber()); // |key| is a PropertyKey... |
| 7193 LookupIterator it = LookupIterator::PropertyOrElement( | 7233 LookupIterator it = LookupIterator::PropertyOrElement( |
| 7194 isolate, object, key, &success, LookupIterator::HIDDEN); | 7234 isolate, object, key, &success, LookupIterator::HIDDEN); |
| 7195 DCHECK(success); // ...so creating a LookupIterator can't fail. | 7235 DCHECK(success); // ...so creating a LookupIterator can't fail. |
| 7196 return GetOwnPropertyDescriptor(&it, desc); | 7236 return GetOwnPropertyDescriptor(&it, desc); |
| (...skipping 12493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19690 if (cell->value() != *new_value) { | 19730 if (cell->value() != *new_value) { |
| 19691 cell->set_value(*new_value); | 19731 cell->set_value(*new_value); |
| 19692 Isolate* isolate = cell->GetIsolate(); | 19732 Isolate* isolate = cell->GetIsolate(); |
| 19693 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19733 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 19694 isolate, DependentCode::kPropertyCellChangedGroup); | 19734 isolate, DependentCode::kPropertyCellChangedGroup); |
| 19695 } | 19735 } |
| 19696 } | 19736 } |
| 19697 | 19737 |
| 19698 } // namespace internal | 19738 } // namespace internal |
| 19699 } // namespace v8 | 19739 } // namespace v8 |
| OLD | NEW |