| 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 <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 1399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1410 if (structure->IsAccessorInfo()) { | 1410 if (structure->IsAccessorInfo()) { |
| 1411 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 1411 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 1412 Handle<Name> name = it->GetName(); | 1412 Handle<Name> name = it->GetName(); |
| 1413 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure); | 1413 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure); |
| 1414 if (!info->IsCompatibleReceiver(*receiver)) { | 1414 if (!info->IsCompatibleReceiver(*receiver)) { |
| 1415 isolate->Throw(*isolate->factory()->NewTypeError( | 1415 isolate->Throw(*isolate->factory()->NewTypeError( |
| 1416 MessageTemplate::kIncompatibleMethodReceiver, name, receiver)); | 1416 MessageTemplate::kIncompatibleMethodReceiver, name, receiver)); |
| 1417 return Nothing<bool>(); | 1417 return Nothing<bool>(); |
| 1418 } | 1418 } |
| 1419 | 1419 |
| 1420 v8::AccessorNameSetterCallback call_fun = | 1420 // The actual type of call_fun is either v8::AccessorNameSetterCallback or |
| 1421 v8::ToCData<v8::AccessorNameSetterCallback>(info->setter()); | 1421 // i::Accesors::AccessorNameBooleanSetterCallback, depending on whether the |
| 1422 // TODO(verwaest): We should not get here anymore once all AccessorInfos are | 1422 // AccessorInfo was created by the API or internally (see accessors.cc). |
| 1423 // marked as special_data_property. They cannot both be writable and not | 1423 // Here we handle both cases using GenericNamedPropertySetterCallback and |
| 1424 // have a setter. | 1424 // its Call method. |
| 1425 if (call_fun == nullptr) return Just(true); | 1425 GenericNamedPropertySetterCallback call_fun = |
| 1426 v8::ToCData<GenericNamedPropertySetterCallback>(info->setter()); |
| 1427 |
| 1428 if (call_fun == nullptr) { |
| 1429 // TODO(verwaest): We should not get here anymore once all AccessorInfos |
| 1430 // are marked as special_data_property. They cannot both be writable and |
| 1431 // not have a setter. |
| 1432 return Just(true); |
| 1433 } |
| 1426 | 1434 |
| 1427 if (info->is_sloppy() && !receiver->IsJSReceiver()) { | 1435 if (info->is_sloppy() && !receiver->IsJSReceiver()) { |
| 1428 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 1436 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 1429 isolate, receiver, Object::ConvertReceiver(isolate, receiver), | 1437 isolate, receiver, Object::ConvertReceiver(isolate, receiver), |
| 1430 Nothing<bool>()); | 1438 Nothing<bool>()); |
| 1431 } | 1439 } |
| 1432 | 1440 |
| 1433 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, | 1441 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, |
| 1434 should_throw); | 1442 should_throw); |
| 1435 args.Call(call_fun, name, value); | 1443 Handle<Object> result = args.Call(call_fun, name, value); |
| 1444 // In the case of AccessorNameSetterCallback, we know that the result value |
| 1445 // cannot have been set, so the result of Call will be null. In the case of |
| 1446 // AccessorNameBooleanSetterCallback, the result will either be null |
| 1447 // (signalling an exception) or a boolean Oddball. |
| 1436 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); | 1448 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
| 1437 return Just(true); | 1449 if (result.is_null()) return Just(true); |
| 1450 DCHECK(result->BooleanValue() || should_throw == DONT_THROW); |
| 1451 return Just(result->BooleanValue()); |
| 1438 } | 1452 } |
| 1439 | 1453 |
| 1440 // Regular accessor. | 1454 // Regular accessor. |
| 1441 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | 1455 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
| 1442 if (setter->IsFunctionTemplateInfo()) { | 1456 if (setter->IsFunctionTemplateInfo()) { |
| 1443 Handle<Object> argv[] = {value}; | 1457 Handle<Object> argv[] = {value}; |
| 1444 RETURN_ON_EXCEPTION_VALUE( | 1458 RETURN_ON_EXCEPTION_VALUE( |
| 1445 isolate, Builtins::InvokeApiFunction( | 1459 isolate, Builtins::InvokeApiFunction( |
| 1446 isolate, false, Handle<FunctionTemplateInfo>::cast(setter), | 1460 isolate, false, Handle<FunctionTemplateInfo>::cast(setter), |
| 1447 receiver, arraysize(argv), argv, | 1461 receiver, arraysize(argv), argv, |
| (...skipping 4326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5774 PropertyAttributes current_attributes = it->property_attributes(); | 5788 PropertyAttributes current_attributes = it->property_attributes(); |
| 5775 // Ensure the context isn't changed after calling into accessors. | 5789 // Ensure the context isn't changed after calling into accessors. |
| 5776 AssertNoContextChange ncc(it->isolate()); | 5790 AssertNoContextChange ncc(it->isolate()); |
| 5777 | 5791 |
| 5778 // Update the attributes before calling the setter. The setter may | 5792 // Update the attributes before calling the setter. The setter may |
| 5779 // later change the shape of the property. | 5793 // later change the shape of the property. |
| 5780 if (current_attributes != attributes) { | 5794 if (current_attributes != attributes) { |
| 5781 it->TransitionToAccessorPair(accessors, attributes); | 5795 it->TransitionToAccessorPair(accessors, attributes); |
| 5782 } | 5796 } |
| 5783 | 5797 |
| 5784 Maybe<bool> result = | 5798 return JSObject::SetPropertyWithAccessor(it, value, should_throw); |
| 5785 JSObject::SetPropertyWithAccessor(it, value, should_throw); | |
| 5786 | |
| 5787 if (current_attributes == attributes || result.IsNothing()) { | |
| 5788 return result; | |
| 5789 } | |
| 5790 | |
| 5791 } else { | |
| 5792 it->ReconfigureDataProperty(value, attributes); | |
| 5793 } | 5799 } |
| 5794 | 5800 |
| 5801 it->ReconfigureDataProperty(value, attributes); |
| 5795 return Just(true); | 5802 return Just(true); |
| 5796 } | 5803 } |
| 5797 case LookupIterator::INTEGER_INDEXED_EXOTIC: | 5804 case LookupIterator::INTEGER_INDEXED_EXOTIC: |
| 5798 return RedefineIncompatibleProperty(it->isolate(), it->GetName(), value, | 5805 return RedefineIncompatibleProperty(it->isolate(), it->GetName(), value, |
| 5799 should_throw); | 5806 should_throw); |
| 5800 | 5807 |
| 5801 case LookupIterator::DATA: { | 5808 case LookupIterator::DATA: { |
| 5802 // Regular property update if the attributes match. | 5809 // Regular property update if the attributes match. |
| 5803 if (it->property_attributes() == attributes) { | 5810 if (it->property_attributes() == attributes) { |
| 5804 return SetDataProperty(it, value); | 5811 return SetDataProperty(it, value); |
| (...skipping 14413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20218 ns, Accessors::ModuleNamespaceEntryInfo(isolate, name, attr)) | 20225 ns, Accessors::ModuleNamespaceEntryInfo(isolate, name, attr)) |
| 20219 .Check(); | 20226 .Check(); |
| 20220 } | 20227 } |
| 20221 JSObject::PreventExtensions(ns, THROW_ON_ERROR).ToChecked(); | 20228 JSObject::PreventExtensions(ns, THROW_ON_ERROR).ToChecked(); |
| 20222 | 20229 |
| 20223 return ns; | 20230 return ns; |
| 20224 } | 20231 } |
| 20225 | 20232 |
| 20226 } // namespace internal | 20233 } // namespace internal |
| 20227 } // namespace v8 | 20234 } // namespace v8 |
| OLD | NEW |