| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 696ce7d commit e23e345
12 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | 37 | # Reset this number to 0 on major V8 upgrades. | |
| 38 | 38 | # Increment by one for each non-official patch applied to deps/v8. | |
| 39 | - 'v8_embedder_string': '-node.11', | ||
| 39 | + 'v8_embedder_string': '-node.12', | ||
| 40 | 40 | ||
| 41 | 41 | ##### V8 defaults for Node.js ##### | |
| 42 | 42 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -35,6 +35,7 @@ | |||
| 35 | 35 | #include "src/objects/js-array-inl.h" | |
| 36 | 36 | #include "src/objects/megadom-handler.h" | |
| 37 | 37 | #include "src/objects/module-inl.h" | |
| 38 | + #include "src/objects/property-descriptor.h" | ||
| 38 | 39 | #include "src/objects/prototype.h" | |
| 39 | 40 | #include "src/objects/struct-inl.h" | |
| 40 | 41 | #include "src/runtime/runtime-utils.h" | |
@@ -1726,6 +1727,69 @@ MaybeHandle<Object> StoreGlobalIC::Store(Handle<Name> name, | |||
| 1726 | 1727 | return StoreIC::Store(global, name, value); | |
| 1727 | 1728 | } | |
| 1728 | 1729 | ||
| 1730 | + namespace { | ||
| 1731 | + Maybe<bool> DefineOwnDataProperty(LookupIterator* it, | ||
| 1732 | + LookupIterator::State original_state, | ||
| 1733 | + Handle<Object> value, | ||
| 1734 | + Maybe<ShouldThrow> should_throw, | ||
| 1735 | + StoreOrigin store_origin) { | ||
| 1736 | + // It should not be possible to call DefineOwnDataProperty in a | ||
| 1737 | + // contextual store (indicated by IsJSGlobalObject()). | ||
| 1738 | + DCHECK(!it->GetReceiver()->IsJSGlobalObject(it->isolate())); | ||
| 1739 | + | ||
| 1740 | + // Handle special cases that can't be handled by | ||
| 1741 | + // DefineOwnPropertyIgnoreAttributes first. | ||
| 1742 | + switch (it->state()) { | ||
| 1743 | + case LookupIterator::JSPROXY: { | ||
| 1744 | + PropertyDescriptor new_desc; | ||
| 1745 | + new_desc.set_value(value); | ||
| 1746 | + new_desc.set_writable(true); | ||
| 1747 | + new_desc.set_enumerable(true); | ||
| 1748 | + new_desc.set_configurable(true); | ||
| 1749 | + DCHECK_EQ(original_state, LookupIterator::JSPROXY); | ||
| 1750 | + // TODO(joyee): this will start the lookup again. Ideally we should | ||
| 1751 | + // implement something that reuses the existing LookupIterator. | ||
| 1752 | + return JSProxy::DefineOwnProperty(it->isolate(), it->GetHolder<JSProxy>(), | ||
| 1753 | + it->GetName(), &new_desc, should_throw); | ||
| 1754 | + } | ||
| 1755 | + // When lazy feedback is disabled, the original state could be different | ||
| 1756 | + // while the object is already prepared for TRANSITION. | ||
| 1757 | + case LookupIterator::TRANSITION: { | ||
| 1758 | + switch (original_state) { | ||
| 1759 | + case LookupIterator::JSPROXY: | ||
| 1760 | + case LookupIterator::TRANSITION: | ||
| 1761 | + case LookupIterator::DATA: | ||
| 1762 | + case LookupIterator::INTERCEPTOR: | ||
| 1763 | + case LookupIterator::ACCESSOR: | ||
| 1764 | + case LookupIterator::INTEGER_INDEXED_EXOTIC: | ||
| 1765 | + UNREACHABLE(); | ||
| 1766 | + case LookupIterator::ACCESS_CHECK: { | ||
| 1767 | + DCHECK(!it->GetHolder<JSObject>()->IsAccessCheckNeeded()); | ||
| 1768 | + V8_FALLTHROUGH; | ||
| 1769 | + } | ||
| 1770 | + case LookupIterator::NOT_FOUND: | ||
| 1771 | + return Object::AddDataProperty(it, value, NONE, | ||
| 1772 | + Nothing<ShouldThrow>(), store_origin); | ||
| 1773 | + } | ||
| 1774 | + } | ||
| 1775 | + case LookupIterator::ACCESS_CHECK: | ||
| 1776 | + case LookupIterator::NOT_FOUND: | ||
| 1777 | + case LookupIterator::DATA: | ||
| 1778 | + case LookupIterator::ACCESSOR: | ||
| 1779 | + case LookupIterator::INTERCEPTOR: | ||
| 1780 | + case LookupIterator::INTEGER_INDEXED_EXOTIC: | ||
| 1781 | + break; | ||
| 1782 | + } | ||
| 1783 | + | ||
| 1784 | + // We need to restart to handle interceptors properly. | ||
| 1785 | + it->Restart(); | ||
| 1786 | + | ||
| 1787 | + return JSObject::DefineOwnPropertyIgnoreAttributes( | ||
| 1788 | + it, value, NONE, should_throw, JSObject::DONT_FORCE_FIELD, | ||
| 1789 | + JSObject::EnforceDefineSemantics::kDefine); | ||
| 1790 | + } | ||
| 1791 | + } // namespace | ||
| 1792 | + | ||
| 1729 | 1793 | MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, | |
| 1730 | 1794 | Handle<Object> value, | |
| 1731 | 1795 | StoreOrigin store_origin) { | |
@@ -1737,7 +1801,15 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, | |||
| 1737 | 1801 | isolate(), object, key, | |
| 1738 | 1802 | IsAnyStoreOwn() ? LookupIterator::OWN : LookupIterator::DEFAULT); | |
| 1739 | 1803 | DCHECK_IMPLIES(IsStoreOwnIC(), it.IsFound() && it.HolderIsReceiver()); | |
| 1740 | - MAYBE_RETURN_NULL(Object::SetProperty(&it, value, StoreOrigin::kNamed)); | ||
| 1804 | + // TODO(joyee): IsStoreOwnIC() is used in [[DefineOwnProperty]] | ||
| 1805 | + // operations during initialization of object literals and class | ||
| 1806 | + // fields. Rename them or separate them out. | ||
| 1807 | + if (IsStoreOwnIC()) { | ||
| 1808 | + MAYBE_RETURN_NULL( | ||
| 1809 | + JSReceiver::CreateDataProperty(&it, value, Nothing<ShouldThrow>())); | ||
| 1810 | + } else { | ||
| 1811 | + MAYBE_RETURN_NULL(Object::SetProperty(&it, value, StoreOrigin::kNamed)); | ||
| 1812 | + } | ||
| 1741 | 1813 | return value; | |
| 1742 | 1814 | } | |
| 1743 | 1815 | ||
@@ -1785,6 +1857,23 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, | |||
| 1785 | 1857 | use_ic = false; | |
| 1786 | 1858 | } | |
| 1787 | 1859 | } | |
| 1860 | + | ||
| 1861 | + // For IsStoreOwnIC(), we can't simply do CreateDataProperty below | ||
| 1862 | + // because we need to check the attributes before UpdateCaches updates | ||
| 1863 | + // the state of the LookupIterator. | ||
| 1864 | + LookupIterator::State original_state = it.state(); | ||
| 1865 | + // We'll defer the check for JSProxy and objects with named interceptors, | ||
| 1866 | + // because the defineProperty traps need to be called first if they are | ||
| 1867 | + // present. | ||
| 1868 | + if (IsStoreOwnIC() && !object->IsJSProxy() && | ||
| 1869 | + !Handle<JSObject>::cast(object)->HasNamedInterceptor()) { | ||
| 1870 | + Maybe<bool> can_define = JSReceiver::CheckIfCanDefine( | ||
| 1871 | + isolate(), &it, value, Nothing<ShouldThrow>()); | ||
| 1872 | + if (can_define.IsNothing() || !can_define.FromJust()) { | ||
| 1873 | + return MaybeHandle<Object>(); | ||
| 1874 | + } | ||
| 1875 | + } | ||
| 1876 | + | ||
| 1788 | 1877 | if (use_ic) { | |
| 1789 | 1878 | UpdateCaches(&it, value, store_origin); | |
| 1790 | 1879 | } else if (state() == NO_FEEDBACK) { | |
@@ -1793,7 +1882,21 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, | |||
| 1793 | 1882 | : TraceIC("StoreIC", name); | |
| 1794 | 1883 | } | |
| 1795 | 1884 | ||
| 1796 | - MAYBE_RETURN_NULL(Object::SetProperty(&it, value, store_origin)); | ||
| 1885 | + // TODO(joyee): IsStoreOwnIC() is true in [[DefineOwnProperty]] | ||
| 1886 | + // operations during initialization of object literals and class | ||
| 1887 | + // fields. In both paths, Rename the operations properly to avoid | ||
| 1888 | + // confusion. | ||
| 1889 | + // ES #sec-definefield | ||
| 1890 | + // ES #sec-runtime-semantics-propertydefinitionevaluation | ||
| 1891 | + if (IsStoreOwnIC()) { | ||
| 1892 | + // Private property should be defined via DefineOwnIC (as private names) or | ||
| 1893 | + // stored via other store ICs through private symbols. | ||
| 1894 | + DCHECK(!name->IsPrivate()); | ||
| 1895 | + MAYBE_RETURN_NULL(DefineOwnDataProperty( | ||
| 1896 | + &it, original_state, value, Nothing<ShouldThrow>(), store_origin)); | ||
| 1897 | + } else { | ||
| 1898 | + MAYBE_RETURN_NULL(Object::SetProperty(&it, value, store_origin)); | ||
| 1899 | + } | ||
| 1797 | 1900 | return value; | |
| 1798 | 1901 | } | |
| 1799 | 1902 | ||
@@ -1871,11 +1974,14 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { | |||
| 1871 | 1974 | ||
| 1872 | 1975 | // If the interceptor is on the receiver... | |
| 1873 | 1976 | if (lookup->HolderIsReceiverOrHiddenPrototype() && !info.non_masking()) { | |
| 1874 | - // ...return a store interceptor Smi handler if there is one... | ||
| 1875 | - if (!info.setter().IsUndefined(isolate())) { | ||
| 1977 | + // ...return a store interceptor Smi handler if there is a setter | ||
| 1978 | + // interceptor and it's not StoreOwnIC (which should call the | ||
| 1979 | + // definer)... | ||
| 1980 | + if (!info.setter().IsUndefined(isolate()) && !IsStoreOwnIC()) { | ||
| 1876 | 1981 | return MaybeObjectHandle(StoreHandler::StoreInterceptor(isolate())); | |
| 1877 | 1982 | } | |
| 1878 | - // ...otherwise return a slow-case Smi handler. | ||
| 1983 | + // ...otherwise return a slow-case Smi handler, which invokes the | ||
| 1984 | + // definer for StoreOwnIC. | ||
| 1879 | 1985 | return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); | |
| 1880 | 1986 | } | |
| 1881 | 1987 | ||
@@ -2055,6 +2161,14 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { | |||
| 2055 | 2161 | Handle<JSReceiver> receiver = | |
| 2056 | 2162 | Handle<JSReceiver>::cast(lookup->GetReceiver()); | |
| 2057 | 2163 | Handle<JSProxy> holder = lookup->GetHolder<JSProxy>(); | |
| 2164 | + | ||
| 2165 | + // IsStoreOwnIC() is true when we are defining public fields on a Proxy. | ||
| 2166 | + // In that case use the slow stub to invoke the define trap. | ||
| 2167 | + if (IsStoreOwnIC()) { | ||
| 2168 | + TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | ||
| 2169 | + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); | ||
| 2170 | + } | ||
| 2171 | + | ||
| 2058 | 2172 | return MaybeObjectHandle(StoreHandler::StoreProxy( | |
| 2059 | 2173 | isolate(), lookup_start_object_map(), holder, receiver)); | |
| 2060 | 2174 | } | |
@@ -2766,9 +2880,10 @@ RUNTIME_FUNCTION(Runtime_StoreOwnIC_Slow) { | |||
| 2766 | 2880 | ||
| 2767 | 2881 | PropertyKey lookup_key(isolate, key); | |
| 2768 | 2882 | LookupIterator it(isolate, object, lookup_key, LookupIterator::OWN); | |
| 2769 | - MAYBE_RETURN(JSObject::DefineOwnPropertyIgnoreAttributes( | ||
| 2770 | - &it, value, NONE, Nothing<ShouldThrow>()), | ||
| 2771 | - ReadOnlyRoots(isolate).exception()); | ||
| 2883 | + | ||
| 2884 | + MAYBE_RETURN( | ||
| 2885 | + JSReceiver::CreateDataProperty(&it, value, Nothing<ShouldThrow>()), | ||
| 2886 | + ReadOnlyRoots(isolate).exception()); | ||
| 2772 | 2887 | return *value; | |
| 2773 | 2888 | } | |
| 2774 | 2889 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -151,7 +151,7 @@ class KeyedStoreGenericAssembler : public AccessorAssembler { | |||
| 151 | 151 | ||
| 152 | 152 | bool ShouldCheckPrototype() const { return IsKeyedStore(); } | |
| 153 | 153 | bool ShouldReconfigureExisting() const { return IsStoreInLiteral(); } | |
| 154 | - bool ShouldCallSetter() const { return IsKeyedStore() || IsKeyedStoreOwn(); } | ||
| 154 | + bool ShouldCallSetter() const { return IsKeyedStore(); } | ||
| 155 | 155 | bool ShouldCheckPrototypeValidity() const { | |
| 156 | 156 | // We don't do this for "in-literal" stores, because it is impossible for | |
| 157 | 157 | // the target object to be a "prototype". | |
@@ -1008,20 +1008,28 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( | |||
| 1008 | 1008 | if (!ShouldReconfigureExisting()) { | |
| 1009 | 1009 | BIND(&readonly); | |
| 1010 | 1010 | { | |
| 1011 | - LanguageMode language_mode; | ||
| 1012 | - if (maybe_language_mode.To(&language_mode)) { | ||
| 1013 | - if (language_mode == LanguageMode::kStrict) { | ||
| 1014 | - TNode<String> type = Typeof(p->receiver()); | ||
| 1015 | - ThrowTypeError(p->context(), MessageTemplate::kStrictReadOnlyProperty, | ||
| 1016 | - name, type, p->receiver()); | ||
| 1011 | + // FIXME(joyee): IsKeyedStoreOwn is actually true from | ||
| 1012 | + // StaNamedOwnProperty, which implements [[DefineOwnProperty]] | ||
| 1013 | + // semantics. Rename them. | ||
| 1014 | + if (IsKeyedDefineOwn() || IsKeyedStoreOwn()) { | ||
| 1015 | + Goto(slow); | ||
| 1016 | + } else { | ||
| 1017 | + LanguageMode language_mode; | ||
| 1018 | + if (maybe_language_mode.To(&language_mode)) { | ||
| 1019 | + if (language_mode == LanguageMode::kStrict) { | ||
| 1020 | + TNode<String> type = Typeof(p->receiver()); | ||
| 1021 | + ThrowTypeError(p->context(), | ||
| 1022 | + MessageTemplate::kStrictReadOnlyProperty, name, type, | ||
| 1023 | + p->receiver()); | ||
| 1024 | + } else { | ||
| 1025 | + exit_point->Return(p->value()); | ||
| 1026 | + } | ||
| 1017 | 1027 | } else { | |
| 1028 | + CallRuntime(Runtime::kThrowTypeErrorIfStrict, p->context(), | ||
| 1029 | + SmiConstant(MessageTemplate::kStrictReadOnlyProperty), | ||
| 1030 | + name, Typeof(p->receiver()), p->receiver()); | ||
| 1018 | 1031 | exit_point->Return(p->value()); | |
| 1019 | 1032 | } | |
| 1020 | - } else { | ||
| 1021 | - CallRuntime(Runtime::kThrowTypeErrorIfStrict, p->context(), | ||
| 1022 | - SmiConstant(MessageTemplate::kStrictReadOnlyProperty), name, | ||
| 1023 | - Typeof(p->receiver()), p->receiver()); | ||
| 1024 | - exit_point->Return(p->value()); | ||
| 1025 | 1033 | } | |
| 1026 | 1034 | } | |
| 1027 | 1035 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -184,6 +184,27 @@ Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate, | |||
| 184 | 184 | } | |
| 185 | 185 | } | |
| 186 | 186 | ||
| 187 | + // static | ||
| 188 | + Maybe<bool> JSReceiver::CheckIfCanDefine(Isolate* isolate, LookupIterator* it, | ||
| 189 | + Handle<Object> value, | ||
| 190 | + Maybe<ShouldThrow> should_throw) { | ||
| 191 | + if (it->IsFound()) { | ||
| 192 | + Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it); | ||
| 193 | + MAYBE_RETURN(attributes, Nothing<bool>()); | ||
| 194 | + if ((attributes.FromJust() & DONT_DELETE) != 0) { | ||
| 195 | + RETURN_FAILURE( | ||
| 196 | + isolate, GetShouldThrow(isolate, should_throw), | ||
| 197 | + NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName())); | ||
| 198 | + } | ||
| 199 | + } else if (!JSObject::IsExtensible( | ||
| 200 | + Handle<JSObject>::cast(it->GetReceiver()))) { | ||
| 201 | + RETURN_FAILURE( | ||
| 202 | + isolate, GetShouldThrow(isolate, should_throw), | ||
| 203 | + NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName())); | ||
| 204 | + } | ||
| 205 | + return Just(true); | ||
| 206 | + } | ||
| 207 | + | ||
| 187 | 208 | namespace { | |
| 188 | 209 | ||
| 189 | 210 | bool HasExcludedProperty( | |
@@ -3365,23 +3386,25 @@ void JSObject::AddProperty(Isolate* isolate, Handle<JSObject> object, | |||
| 3365 | 3386 | // hidden prototypes. | |
| 3366 | 3387 | MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes( | |
| 3367 | 3388 | LookupIterator* it, Handle<Object> value, PropertyAttributes attributes, | |
| 3368 | - AccessorInfoHandling handling) { | ||
| 3389 | + AccessorInfoHandling handling, EnforceDefineSemantics semantics) { | ||
| 3369 | 3390 | MAYBE_RETURN_NULL(DefineOwnPropertyIgnoreAttributes( | |
| 3370 | - it, value, attributes, Just(ShouldThrow::kThrowOnError), handling)); | ||
| 3391 | + it, value, attributes, Just(ShouldThrow::kThrowOnError), handling, | ||
| 3392 | + semantics)); | ||
| 3371 | 3393 | return value; | |
| 3372 | 3394 | } | |
| 3373 | 3395 | ||
| 3374 | 3396 | Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes( | |
| 3375 | 3397 | LookupIterator* it, Handle<Object> value, PropertyAttributes attributes, | |
| 3376 | - Maybe<ShouldThrow> should_throw, AccessorInfoHandling handling) { | ||
| 3398 | + Maybe<ShouldThrow> should_throw, AccessorInfoHandling handling, | ||
| 3399 | + EnforceDefineSemantics semantics) { | ||
| 3377 | 3400 | it->UpdateProtector(); | |
| 3378 | 3401 | Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); | |
| 3379 | 3402 | ||
| 3380 | 3403 | for (; it->IsFound(); it->Next()) { | |
| 3381 | 3404 | switch (it->state()) { | |
| 3382 | 3405 | case LookupIterator::JSPROXY: | |
| 3383 | - case LookupIterator::NOT_FOUND: | ||
| 3384 | 3406 | case LookupIterator::TRANSITION: | |
| 3407 | + case LookupIterator::NOT_FOUND: | ||
| 3385 | 3408 | UNREACHABLE(); | |
| 3386 | 3409 | ||
| 3387 | 3410 | case LookupIterator::ACCESS_CHECK: | |
@@ -3400,13 +3423,36 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes( | |||
| 3400 | 3423 | // TODO(verwaest): JSProxy afterwards verify the attributes that the | |
| 3401 | 3424 | // JSProxy claims it has, and verifies that they are compatible. If not, | |
| 3402 | 3425 | // they throw. Here we should do the same. | |
| 3403 | - case LookupIterator::INTERCEPTOR: | ||
| 3404 | - if (handling == DONT_FORCE_FIELD) { | ||
| 3405 | - Maybe<bool> result = | ||
| 3406 | - JSObject::SetPropertyWithInterceptor(it, should_throw, value); | ||
| 3407 | - if (result.IsNothing() || result.FromJust()) return result; | ||
| 3426 | + case LookupIterator::INTERCEPTOR: { | ||
| 3427 | + Maybe<bool> result = Just(false); | ||
| 3428 | + if (semantics == EnforceDefineSemantics::kDefine) { | ||
| 3429 | + PropertyDescriptor descriptor; | ||
| 3430 | + descriptor.set_configurable((attributes & DONT_DELETE) != 0); | ||
| 3431 | + descriptor.set_enumerable((attributes & DONT_ENUM) != 0); | ||
| 3432 | + descriptor.set_writable((attributes & READ_ONLY) != 0); | ||
| 3433 | + descriptor.set_value(value); | ||
| 3434 | + result = DefinePropertyWithInterceptorInternal( | ||
| 3435 | + it, it->GetInterceptor(), should_throw, &descriptor); | ||
| 3436 | + } else { | ||
| 3437 | + DCHECK_EQ(semantics, EnforceDefineSemantics::kSet); | ||
| 3438 | + if (handling == DONT_FORCE_FIELD) { | ||
| 3439 | + result = | ||
| 3440 | + JSObject::SetPropertyWithInterceptor(it, should_throw, value); | ||
| 3441 | + } | ||
| 3442 | + } | ||
| 3443 | + if (result.IsNothing() || result.FromJust()) return result; | ||
| 3444 | + | ||
| 3445 | + if (semantics == EnforceDefineSemantics::kDefine) { | ||
| 3446 | + it->Restart(); | ||
| 3447 | + Maybe<bool> can_define = JSReceiver::CheckIfCanDefine( | ||
| 3448 | + it->isolate(), it, value, should_throw); | ||
| 3449 | + if (can_define.IsNothing() || !can_define.FromJust()) { | ||
| 3450 | + return can_define; | ||
| 3451 | + } | ||
| 3452 | + it->Restart(); | ||
| 3408 | 3453 | } | |
| 3409 | 3454 | break; | |
| 3455 | + } | ||
| 3410 | 3456 | ||
| 3411 | 3457 | case LookupIterator::ACCESSOR: { | |
| 3412 | 3458 | Handle<Object> accessors = it->GetAccessors(); | |
@@ -3824,20 +3870,10 @@ Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it, | |||
| 3824 | 3870 | Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver()); | |
| 3825 | 3871 | Isolate* isolate = receiver->GetIsolate(); | |
| 3826 | 3872 | ||
| 3827 | - if (it->IsFound()) { | ||
| 3828 | - Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it); | ||
| 3829 | - MAYBE_RETURN(attributes, Nothing<bool>()); | ||
| 3830 | - if ((attributes.FromJust() & DONT_DELETE) != 0) { | ||
| 3831 | - RETURN_FAILURE( | ||
| 3832 | - isolate, GetShouldThrow(isolate, should_throw), | ||
| 3833 | - NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName())); | ||
| 3834 | - } | ||
| 3835 | - } else { | ||
| 3836 | - if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) { | ||
| 3837 | - RETURN_FAILURE( | ||
| 3838 | - isolate, GetShouldThrow(isolate, should_throw), | ||
| 3839 | - NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName())); | ||
| 3840 | - } | ||
| 3873 | + Maybe<bool> can_define = | ||
| 3874 | + JSReceiver::CheckIfCanDefine(isolate, it, value, should_throw); | ||
| 3875 | + if (can_define.IsNothing() || !can_define.FromJust()) { | ||
| 3876 | + return can_define; | ||
| 3841 | 3877 | } | |
| 3842 | 3878 | ||
| 3843 | 3879 | RETURN_ON_EXCEPTION_VALUE(it->isolate(), | |
| Back | FazBrowse Home | New Git URL |
0 commit comments