11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/objects/js-objects.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/api/api-arguments-inl.h"
81cb0ef41Sopenharmony_ci#include "src/base/optional.h"
91cb0ef41Sopenharmony_ci#include "src/common/globals.h"
101cb0ef41Sopenharmony_ci#include "src/date/date.h"
111cb0ef41Sopenharmony_ci#include "src/execution/arguments.h"
121cb0ef41Sopenharmony_ci#include "src/execution/frames.h"
131cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
141cb0ef41Sopenharmony_ci#include "src/handles/handles-inl.h"
151cb0ef41Sopenharmony_ci#include "src/handles/maybe-handles.h"
161cb0ef41Sopenharmony_ci#include "src/heap/factory-inl.h"
171cb0ef41Sopenharmony_ci#include "src/heap/heap-inl.h"
181cb0ef41Sopenharmony_ci#include "src/heap/memory-chunk.h"
191cb0ef41Sopenharmony_ci#include "src/init/bootstrapper.h"
201cb0ef41Sopenharmony_ci#include "src/logging/counters.h"
211cb0ef41Sopenharmony_ci#include "src/logging/log.h"
221cb0ef41Sopenharmony_ci#include "src/objects/allocation-site-inl.h"
231cb0ef41Sopenharmony_ci#include "src/objects/api-callbacks.h"
241cb0ef41Sopenharmony_ci#include "src/objects/arguments-inl.h"
251cb0ef41Sopenharmony_ci#include "src/objects/dictionary.h"
261cb0ef41Sopenharmony_ci#include "src/objects/elements.h"
271cb0ef41Sopenharmony_ci#include "src/objects/field-type.h"
281cb0ef41Sopenharmony_ci#include "src/objects/fixed-array.h"
291cb0ef41Sopenharmony_ci#include "src/objects/heap-number.h"
301cb0ef41Sopenharmony_ci#include "src/objects/heap-object.h"
311cb0ef41Sopenharmony_ci#include "src/objects/js-array-buffer-inl.h"
321cb0ef41Sopenharmony_ci#include "src/objects/js-array-inl.h"
331cb0ef41Sopenharmony_ci#include "src/objects/lookup.h"
341cb0ef41Sopenharmony_ci#include "src/objects/map-updater.h"
351cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
361cb0ef41Sopenharmony_ci#ifdef V8_INTL_SUPPORT
371cb0ef41Sopenharmony_ci#include "src/objects/js-break-iterator.h"
381cb0ef41Sopenharmony_ci#include "src/objects/js-collator.h"
391cb0ef41Sopenharmony_ci#endif  // V8_INTL_SUPPORT
401cb0ef41Sopenharmony_ci#include "src/objects/js-collection.h"
411cb0ef41Sopenharmony_ci#ifdef V8_INTL_SUPPORT
421cb0ef41Sopenharmony_ci#include "src/objects/js-date-time-format.h"
431cb0ef41Sopenharmony_ci#include "src/objects/js-display-names.h"
441cb0ef41Sopenharmony_ci#endif  // V8_INTL_SUPPORT
451cb0ef41Sopenharmony_ci#include "src/objects/js-generator-inl.h"
461cb0ef41Sopenharmony_ci#ifdef V8_INTL_SUPPORT
471cb0ef41Sopenharmony_ci#include "src/objects/js-list-format.h"
481cb0ef41Sopenharmony_ci#include "src/objects/js-locale.h"
491cb0ef41Sopenharmony_ci#include "src/objects/js-number-format.h"
501cb0ef41Sopenharmony_ci#include "src/objects/js-plural-rules.h"
511cb0ef41Sopenharmony_ci#endif  // V8_INTL_SUPPORT
521cb0ef41Sopenharmony_ci#include "src/objects/js-promise.h"
531cb0ef41Sopenharmony_ci#include "src/objects/js-regexp-inl.h"
541cb0ef41Sopenharmony_ci#include "src/objects/js-regexp-string-iterator.h"
551cb0ef41Sopenharmony_ci#include "src/objects/js-shadow-realms.h"
561cb0ef41Sopenharmony_ci#ifdef V8_INTL_SUPPORT
571cb0ef41Sopenharmony_ci#include "src/objects/js-relative-time-format.h"
581cb0ef41Sopenharmony_ci#include "src/objects/js-segment-iterator.h"
591cb0ef41Sopenharmony_ci#include "src/objects/js-segmenter.h"
601cb0ef41Sopenharmony_ci#include "src/objects/js-segments.h"
611cb0ef41Sopenharmony_ci#endif  // V8_INTL_SUPPORT
621cb0ef41Sopenharmony_ci#include "src/objects/js-struct-inl.h"
631cb0ef41Sopenharmony_ci#include "src/objects/js-temporal-objects-inl.h"
641cb0ef41Sopenharmony_ci#include "src/objects/js-weak-refs.h"
651cb0ef41Sopenharmony_ci#include "src/objects/map-inl.h"
661cb0ef41Sopenharmony_ci#include "src/objects/module.h"
671cb0ef41Sopenharmony_ci#include "src/objects/oddball.h"
681cb0ef41Sopenharmony_ci#include "src/objects/property-cell.h"
691cb0ef41Sopenharmony_ci#include "src/objects/property-descriptor.h"
701cb0ef41Sopenharmony_ci#include "src/objects/property.h"
711cb0ef41Sopenharmony_ci#include "src/objects/prototype-info.h"
721cb0ef41Sopenharmony_ci#include "src/objects/prototype.h"
731cb0ef41Sopenharmony_ci#include "src/objects/shared-function-info.h"
741cb0ef41Sopenharmony_ci#include "src/objects/swiss-name-dictionary-inl.h"
751cb0ef41Sopenharmony_ci#include "src/objects/transitions.h"
761cb0ef41Sopenharmony_ci#include "src/strings/string-builder-inl.h"
771cb0ef41Sopenharmony_ci#include "src/strings/string-stream.h"
781cb0ef41Sopenharmony_ci#include "src/utils/ostreams.h"
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
811cb0ef41Sopenharmony_ci#include "src/wasm/wasm-objects.h"
821cb0ef41Sopenharmony_ci#include "src/debug/debug-wasm-objects.h"
831cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_cinamespace v8 {
861cb0ef41Sopenharmony_cinamespace internal {
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci// static
891cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::HasProperty(LookupIterator* it) {
901cb0ef41Sopenharmony_ci  for (; it->IsFound(); it->Next()) {
911cb0ef41Sopenharmony_ci    switch (it->state()) {
921cb0ef41Sopenharmony_ci      case LookupIterator::NOT_FOUND:
931cb0ef41Sopenharmony_ci      case LookupIterator::TRANSITION:
941cb0ef41Sopenharmony_ci        UNREACHABLE();
951cb0ef41Sopenharmony_ci      case LookupIterator::JSPROXY:
961cb0ef41Sopenharmony_ci        return JSProxy::HasProperty(it->isolate(), it->GetHolder<JSProxy>(),
971cb0ef41Sopenharmony_ci                                    it->GetName());
981cb0ef41Sopenharmony_ci      case LookupIterator::INTERCEPTOR: {
991cb0ef41Sopenharmony_ci        Maybe<PropertyAttributes> result =
1001cb0ef41Sopenharmony_ci            JSObject::GetPropertyAttributesWithInterceptor(it);
1011cb0ef41Sopenharmony_ci        if (result.IsNothing()) return Nothing<bool>();
1021cb0ef41Sopenharmony_ci        if (result.FromJust() != ABSENT) return Just(true);
1031cb0ef41Sopenharmony_ci        break;
1041cb0ef41Sopenharmony_ci      }
1051cb0ef41Sopenharmony_ci      case LookupIterator::ACCESS_CHECK: {
1061cb0ef41Sopenharmony_ci        if (it->HasAccess()) break;
1071cb0ef41Sopenharmony_ci        Maybe<PropertyAttributes> result =
1081cb0ef41Sopenharmony_ci            JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
1091cb0ef41Sopenharmony_ci        if (result.IsNothing()) return Nothing<bool>();
1101cb0ef41Sopenharmony_ci        return Just(result.FromJust() != ABSENT);
1111cb0ef41Sopenharmony_ci      }
1121cb0ef41Sopenharmony_ci      case LookupIterator::INTEGER_INDEXED_EXOTIC:
1131cb0ef41Sopenharmony_ci        // TypedArray out-of-bounds access.
1141cb0ef41Sopenharmony_ci        return Just(false);
1151cb0ef41Sopenharmony_ci      case LookupIterator::ACCESSOR:
1161cb0ef41Sopenharmony_ci      case LookupIterator::DATA:
1171cb0ef41Sopenharmony_ci        return Just(true);
1181cb0ef41Sopenharmony_ci    }
1191cb0ef41Sopenharmony_ci  }
1201cb0ef41Sopenharmony_ci  return Just(false);
1211cb0ef41Sopenharmony_ci}
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci// static
1241cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::HasOwnProperty(Isolate* isolate,
1251cb0ef41Sopenharmony_ci                                       Handle<JSReceiver> object,
1261cb0ef41Sopenharmony_ci                                       Handle<Name> name) {
1271cb0ef41Sopenharmony_ci  if (object->IsJSModuleNamespace()) {
1281cb0ef41Sopenharmony_ci    PropertyDescriptor desc;
1291cb0ef41Sopenharmony_ci    return JSReceiver::GetOwnPropertyDescriptor(isolate, object, name, &desc);
1301cb0ef41Sopenharmony_ci  }
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  if (object->IsJSObject()) {  // Shortcut.
1331cb0ef41Sopenharmony_ci    PropertyKey key(isolate, name);
1341cb0ef41Sopenharmony_ci    LookupIterator it(isolate, object, key, LookupIterator::OWN);
1351cb0ef41Sopenharmony_ci    return HasProperty(&it);
1361cb0ef41Sopenharmony_ci  }
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci  Maybe<PropertyAttributes> attributes =
1391cb0ef41Sopenharmony_ci      JSReceiver::GetOwnPropertyAttributes(object, name);
1401cb0ef41Sopenharmony_ci  MAYBE_RETURN(attributes, Nothing<bool>());
1411cb0ef41Sopenharmony_ci  return Just(attributes.FromJust() != ABSENT);
1421cb0ef41Sopenharmony_ci}
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ciHandle<Object> JSReceiver::GetDataProperty(LookupIterator* it,
1451cb0ef41Sopenharmony_ci                                           AllocationPolicy allocation_policy) {
1461cb0ef41Sopenharmony_ci  for (; it->IsFound(); it->Next()) {
1471cb0ef41Sopenharmony_ci    switch (it->state()) {
1481cb0ef41Sopenharmony_ci      case LookupIterator::INTERCEPTOR:
1491cb0ef41Sopenharmony_ci      case LookupIterator::NOT_FOUND:
1501cb0ef41Sopenharmony_ci      case LookupIterator::TRANSITION:
1511cb0ef41Sopenharmony_ci        UNREACHABLE();
1521cb0ef41Sopenharmony_ci      case LookupIterator::ACCESS_CHECK:
1531cb0ef41Sopenharmony_ci        // Support calling this method without an active context, but refuse
1541cb0ef41Sopenharmony_ci        // access to access-checked objects in that case.
1551cb0ef41Sopenharmony_ci        if (!it->isolate()->context().is_null() && it->HasAccess()) continue;
1561cb0ef41Sopenharmony_ci        V8_FALLTHROUGH;
1571cb0ef41Sopenharmony_ci      case LookupIterator::JSPROXY:
1581cb0ef41Sopenharmony_ci        it->NotFound();
1591cb0ef41Sopenharmony_ci        return it->isolate()->factory()->undefined_value();
1601cb0ef41Sopenharmony_ci      case LookupIterator::ACCESSOR:
1611cb0ef41Sopenharmony_ci        // TODO(verwaest): For now this doesn't call into AccessorInfo, since
1621cb0ef41Sopenharmony_ci        // clients don't need it. Update once relevant.
1631cb0ef41Sopenharmony_ci        it->NotFound();
1641cb0ef41Sopenharmony_ci        return it->isolate()->factory()->undefined_value();
1651cb0ef41Sopenharmony_ci      case LookupIterator::INTEGER_INDEXED_EXOTIC:
1661cb0ef41Sopenharmony_ci        return it->isolate()->factory()->undefined_value();
1671cb0ef41Sopenharmony_ci      case LookupIterator::DATA:
1681cb0ef41Sopenharmony_ci        return it->GetDataValue(allocation_policy);
1691cb0ef41Sopenharmony_ci    }
1701cb0ef41Sopenharmony_ci  }
1711cb0ef41Sopenharmony_ci  return it->isolate()->factory()->undefined_value();
1721cb0ef41Sopenharmony_ci}
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci// static
1751cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate,
1761cb0ef41Sopenharmony_ci                                            Handle<JSReceiver> object,
1771cb0ef41Sopenharmony_ci                                            Handle<Object> proto) {
1781cb0ef41Sopenharmony_ci  PrototypeIterator iter(isolate, object, kStartAtReceiver);
1791cb0ef41Sopenharmony_ci  while (true) {
1801cb0ef41Sopenharmony_ci    if (!iter.AdvanceFollowingProxies()) return Nothing<bool>();
1811cb0ef41Sopenharmony_ci    if (iter.IsAtEnd()) return Just(false);
1821cb0ef41Sopenharmony_ci    if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) {
1831cb0ef41Sopenharmony_ci      return Just(true);
1841cb0ef41Sopenharmony_ci    }
1851cb0ef41Sopenharmony_ci  }
1861cb0ef41Sopenharmony_ci}
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci// static
1891cb0ef41Sopenharmony_cibool JSReceiver::CheckPrivateNameStore(LookupIterator* it, bool is_define) {
1901cb0ef41Sopenharmony_ci  DCHECK(it->GetName()->IsPrivateName());
1911cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
1921cb0ef41Sopenharmony_ci  Handle<String> name_string(
1931cb0ef41Sopenharmony_ci      String::cast(Handle<Symbol>::cast(it->GetName())->description()),
1941cb0ef41Sopenharmony_ci      isolate);
1951cb0ef41Sopenharmony_ci  bool should_throw = GetShouldThrow(isolate, Nothing<ShouldThrow>()) ==
1961cb0ef41Sopenharmony_ci                      ShouldThrow::kThrowOnError;
1971cb0ef41Sopenharmony_ci  for (; it->IsFound(); it->Next()) {
1981cb0ef41Sopenharmony_ci    switch (it->state()) {
1991cb0ef41Sopenharmony_ci      case LookupIterator::TRANSITION:
2001cb0ef41Sopenharmony_ci      case LookupIterator::INTERCEPTOR:
2011cb0ef41Sopenharmony_ci      case LookupIterator::JSPROXY:
2021cb0ef41Sopenharmony_ci      case LookupIterator::NOT_FOUND:
2031cb0ef41Sopenharmony_ci      case LookupIterator::INTEGER_INDEXED_EXOTIC:
2041cb0ef41Sopenharmony_ci      case LookupIterator::ACCESSOR:
2051cb0ef41Sopenharmony_ci        UNREACHABLE();
2061cb0ef41Sopenharmony_ci      case LookupIterator::ACCESS_CHECK:
2071cb0ef41Sopenharmony_ci        if (!it->HasAccess()) {
2081cb0ef41Sopenharmony_ci          isolate->ReportFailedAccessCheck(
2091cb0ef41Sopenharmony_ci              Handle<JSObject>::cast(it->GetReceiver()));
2101cb0ef41Sopenharmony_ci          RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false);
2111cb0ef41Sopenharmony_ci          return false;
2121cb0ef41Sopenharmony_ci        }
2131cb0ef41Sopenharmony_ci        break;
2141cb0ef41Sopenharmony_ci      case LookupIterator::DATA:
2151cb0ef41Sopenharmony_ci        if (is_define && should_throw) {
2161cb0ef41Sopenharmony_ci          MessageTemplate message =
2171cb0ef41Sopenharmony_ci              it->GetName()->IsPrivateBrand()
2181cb0ef41Sopenharmony_ci                  ? MessageTemplate::kInvalidPrivateBrandReinitialization
2191cb0ef41Sopenharmony_ci                  : MessageTemplate::kInvalidPrivateFieldReinitialization;
2201cb0ef41Sopenharmony_ci          isolate->Throw(*(isolate->factory()->NewTypeError(
2211cb0ef41Sopenharmony_ci              message, name_string, it->GetReceiver())));
2221cb0ef41Sopenharmony_ci          return false;
2231cb0ef41Sopenharmony_ci        }
2241cb0ef41Sopenharmony_ci        return true;
2251cb0ef41Sopenharmony_ci    }
2261cb0ef41Sopenharmony_ci  }
2271cb0ef41Sopenharmony_ci  DCHECK(!it->IsFound());
2281cb0ef41Sopenharmony_ci  if (!is_define && should_throw) {
2291cb0ef41Sopenharmony_ci    isolate->Throw(*(isolate->factory()->NewTypeError(
2301cb0ef41Sopenharmony_ci        MessageTemplate::kInvalidPrivateMemberWrite, name_string,
2311cb0ef41Sopenharmony_ci        it->GetReceiver())));
2321cb0ef41Sopenharmony_ci    return false;
2331cb0ef41Sopenharmony_ci  }
2341cb0ef41Sopenharmony_ci  return true;
2351cb0ef41Sopenharmony_ci}
2361cb0ef41Sopenharmony_ci
2371cb0ef41Sopenharmony_ci// static
2381cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::CheckIfCanDefine(Isolate* isolate, LookupIterator* it,
2391cb0ef41Sopenharmony_ci                                         Handle<Object> value,
2401cb0ef41Sopenharmony_ci                                         Maybe<ShouldThrow> should_throw) {
2411cb0ef41Sopenharmony_ci  if (it->IsFound()) {
2421cb0ef41Sopenharmony_ci    Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
2431cb0ef41Sopenharmony_ci    MAYBE_RETURN(attributes, Nothing<bool>());
2441cb0ef41Sopenharmony_ci    if ((attributes.FromJust() & DONT_DELETE) != 0) {
2451cb0ef41Sopenharmony_ci      RETURN_FAILURE(
2461cb0ef41Sopenharmony_ci          isolate, GetShouldThrow(isolate, should_throw),
2471cb0ef41Sopenharmony_ci          NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
2481cb0ef41Sopenharmony_ci    }
2491cb0ef41Sopenharmony_ci  } else if (!JSObject::IsExtensible(
2501cb0ef41Sopenharmony_ci                 Handle<JSObject>::cast(it->GetReceiver()))) {
2511cb0ef41Sopenharmony_ci    RETURN_FAILURE(
2521cb0ef41Sopenharmony_ci        isolate, GetShouldThrow(isolate, should_throw),
2531cb0ef41Sopenharmony_ci        NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
2541cb0ef41Sopenharmony_ci  }
2551cb0ef41Sopenharmony_ci  return Just(true);
2561cb0ef41Sopenharmony_ci}
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_cinamespace {
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_cibool HasExcludedProperty(
2611cb0ef41Sopenharmony_ci    const base::ScopedVector<Handle<Object>>* excluded_properties,
2621cb0ef41Sopenharmony_ci    Handle<Object> search_element) {
2631cb0ef41Sopenharmony_ci  // TODO(gsathya): Change this to be a hashtable.
2641cb0ef41Sopenharmony_ci  for (int i = 0; i < excluded_properties->length(); i++) {
2651cb0ef41Sopenharmony_ci    if (search_element->SameValue(*excluded_properties->at(i))) {
2661cb0ef41Sopenharmony_ci      return true;
2671cb0ef41Sopenharmony_ci    }
2681cb0ef41Sopenharmony_ci  }
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci  return false;
2711cb0ef41Sopenharmony_ci}
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_ciV8_WARN_UNUSED_RESULT Maybe<bool> FastAssign(
2741cb0ef41Sopenharmony_ci    Handle<JSReceiver> target, Handle<Object> source,
2751cb0ef41Sopenharmony_ci    PropertiesEnumerationMode mode,
2761cb0ef41Sopenharmony_ci    const base::ScopedVector<Handle<Object>>* excluded_properties,
2771cb0ef41Sopenharmony_ci    bool use_set) {
2781cb0ef41Sopenharmony_ci  // Non-empty strings are the only non-JSReceivers that need to be handled
2791cb0ef41Sopenharmony_ci  // explicitly by Object.assign.
2801cb0ef41Sopenharmony_ci  if (!source->IsJSReceiver()) {
2811cb0ef41Sopenharmony_ci    return Just(!source->IsString() || String::cast(*source).length() == 0);
2821cb0ef41Sopenharmony_ci  }
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci  Isolate* isolate = target->GetIsolate();
2851cb0ef41Sopenharmony_ci
2861cb0ef41Sopenharmony_ci  // If the target is deprecated, the object will be updated on first store. If
2871cb0ef41Sopenharmony_ci  // the source for that store equals the target, this will invalidate the
2881cb0ef41Sopenharmony_ci  // cached representation of the source. Preventively upgrade the target.
2891cb0ef41Sopenharmony_ci  // Do this on each iteration since any property load could cause deprecation.
2901cb0ef41Sopenharmony_ci  if (target->map().is_deprecated()) {
2911cb0ef41Sopenharmony_ci    JSObject::MigrateInstance(isolate, Handle<JSObject>::cast(target));
2921cb0ef41Sopenharmony_ci  }
2931cb0ef41Sopenharmony_ci
2941cb0ef41Sopenharmony_ci  Handle<Map> map(JSReceiver::cast(*source).map(), isolate);
2951cb0ef41Sopenharmony_ci
2961cb0ef41Sopenharmony_ci  if (!map->IsJSObjectMap()) return Just(false);
2971cb0ef41Sopenharmony_ci  if (!map->OnlyHasSimpleProperties()) return Just(false);
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_ci  Handle<JSObject> from = Handle<JSObject>::cast(source);
3001cb0ef41Sopenharmony_ci  if (from->elements() != ReadOnlyRoots(isolate).empty_fixed_array()) {
3011cb0ef41Sopenharmony_ci    return Just(false);
3021cb0ef41Sopenharmony_ci  }
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci  // We should never try to copy properties from an object itself.
3051cb0ef41Sopenharmony_ci  CHECK_IMPLIES(!use_set, !target.is_identical_to(from));
3061cb0ef41Sopenharmony_ci
3071cb0ef41Sopenharmony_ci  Handle<DescriptorArray> descriptors(map->instance_descriptors(isolate),
3081cb0ef41Sopenharmony_ci                                      isolate);
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci  bool stable = true;
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_ci  // Process symbols last and only do that if we found symbols.
3131cb0ef41Sopenharmony_ci  bool has_symbol = false;
3141cb0ef41Sopenharmony_ci  bool process_symbol_only = false;
3151cb0ef41Sopenharmony_ci  while (true) {
3161cb0ef41Sopenharmony_ci    for (InternalIndex i : map->IterateOwnDescriptors()) {
3171cb0ef41Sopenharmony_ci      HandleScope inner_scope(isolate);
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_ci      Handle<Name> next_key(descriptors->GetKey(i), isolate);
3201cb0ef41Sopenharmony_ci      if (mode == PropertiesEnumerationMode::kEnumerationOrder) {
3211cb0ef41Sopenharmony_ci        if (next_key->IsSymbol()) {
3221cb0ef41Sopenharmony_ci          has_symbol = true;
3231cb0ef41Sopenharmony_ci          if (!process_symbol_only) continue;
3241cb0ef41Sopenharmony_ci        } else {
3251cb0ef41Sopenharmony_ci          if (process_symbol_only) continue;
3261cb0ef41Sopenharmony_ci        }
3271cb0ef41Sopenharmony_ci      }
3281cb0ef41Sopenharmony_ci      Handle<Object> prop_value;
3291cb0ef41Sopenharmony_ci      // Directly decode from the descriptor array if |from| did not change
3301cb0ef41Sopenharmony_ci      // shape.
3311cb0ef41Sopenharmony_ci      if (stable) {
3321cb0ef41Sopenharmony_ci        DCHECK_EQ(from->map(), *map);
3331cb0ef41Sopenharmony_ci        DCHECK_EQ(*descriptors, map->instance_descriptors(isolate));
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_ci        PropertyDetails details = descriptors->GetDetails(i);
3361cb0ef41Sopenharmony_ci        if (!details.IsEnumerable()) continue;
3371cb0ef41Sopenharmony_ci        if (details.kind() == PropertyKind::kData) {
3381cb0ef41Sopenharmony_ci          if (details.location() == PropertyLocation::kDescriptor) {
3391cb0ef41Sopenharmony_ci            prop_value = handle(descriptors->GetStrongValue(i), isolate);
3401cb0ef41Sopenharmony_ci          } else {
3411cb0ef41Sopenharmony_ci            Representation representation = details.representation();
3421cb0ef41Sopenharmony_ci            FieldIndex index = FieldIndex::ForPropertyIndex(
3431cb0ef41Sopenharmony_ci                *map, details.field_index(), representation);
3441cb0ef41Sopenharmony_ci            prop_value =
3451cb0ef41Sopenharmony_ci                JSObject::FastPropertyAt(isolate, from, representation, index);
3461cb0ef41Sopenharmony_ci          }
3471cb0ef41Sopenharmony_ci        } else {
3481cb0ef41Sopenharmony_ci          LookupIterator it(isolate, from, next_key,
3491cb0ef41Sopenharmony_ci                            LookupIterator::OWN_SKIP_INTERCEPTOR);
3501cb0ef41Sopenharmony_ci          ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3511cb0ef41Sopenharmony_ci              isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
3521cb0ef41Sopenharmony_ci          stable = from->map() == *map;
3531cb0ef41Sopenharmony_ci          descriptors.PatchValue(map->instance_descriptors(isolate));
3541cb0ef41Sopenharmony_ci        }
3551cb0ef41Sopenharmony_ci      } else {
3561cb0ef41Sopenharmony_ci        // If the map did change, do a slower lookup. We are still guaranteed
3571cb0ef41Sopenharmony_ci        // that the object has a simple shape, and that the key is a name.
3581cb0ef41Sopenharmony_ci        LookupIterator it(isolate, from, next_key, from,
3591cb0ef41Sopenharmony_ci                          LookupIterator::OWN_SKIP_INTERCEPTOR);
3601cb0ef41Sopenharmony_ci        if (!it.IsFound()) continue;
3611cb0ef41Sopenharmony_ci        DCHECK(it.state() == LookupIterator::DATA ||
3621cb0ef41Sopenharmony_ci               it.state() == LookupIterator::ACCESSOR);
3631cb0ef41Sopenharmony_ci        if (!it.IsEnumerable()) continue;
3641cb0ef41Sopenharmony_ci        ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3651cb0ef41Sopenharmony_ci            isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
3661cb0ef41Sopenharmony_ci      }
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ci      if (use_set) {
3691cb0ef41Sopenharmony_ci        // The lookup will walk the prototype chain, so we have to be careful
3701cb0ef41Sopenharmony_ci        // to treat any key correctly for any receiver/holder.
3711cb0ef41Sopenharmony_ci        PropertyKey key(isolate, next_key);
3721cb0ef41Sopenharmony_ci        LookupIterator it(isolate, target, key);
3731cb0ef41Sopenharmony_ci        Maybe<bool> result =
3741cb0ef41Sopenharmony_ci            Object::SetProperty(&it, prop_value, StoreOrigin::kNamed,
3751cb0ef41Sopenharmony_ci                                Just(ShouldThrow::kThrowOnError));
3761cb0ef41Sopenharmony_ci        if (result.IsNothing()) return result;
3771cb0ef41Sopenharmony_ci        if (stable) {
3781cb0ef41Sopenharmony_ci          stable = from->map() == *map;
3791cb0ef41Sopenharmony_ci          descriptors.PatchValue(map->instance_descriptors(isolate));
3801cb0ef41Sopenharmony_ci        }
3811cb0ef41Sopenharmony_ci      } else {
3821cb0ef41Sopenharmony_ci        // No element indexes should get here or the exclusion check may
3831cb0ef41Sopenharmony_ci        // yield false negatives for type mismatch.
3841cb0ef41Sopenharmony_ci        if (excluded_properties != nullptr &&
3851cb0ef41Sopenharmony_ci            HasExcludedProperty(excluded_properties, next_key)) {
3861cb0ef41Sopenharmony_ci          continue;
3871cb0ef41Sopenharmony_ci        }
3881cb0ef41Sopenharmony_ci
3891cb0ef41Sopenharmony_ci        // 4a ii 2. Perform ? CreateDataProperty(target, nextKey, propValue).
3901cb0ef41Sopenharmony_ci        // This is an OWN lookup, so constructing a named-mode LookupIterator
3911cb0ef41Sopenharmony_ci        // from {next_key} is safe.
3921cb0ef41Sopenharmony_ci        LookupIterator it(isolate, target, next_key, LookupIterator::OWN);
3931cb0ef41Sopenharmony_ci        CHECK(JSObject::CreateDataProperty(&it, prop_value, Just(kThrowOnError))
3941cb0ef41Sopenharmony_ci                  .FromJust());
3951cb0ef41Sopenharmony_ci      }
3961cb0ef41Sopenharmony_ci    }
3971cb0ef41Sopenharmony_ci    if (mode == PropertiesEnumerationMode::kEnumerationOrder) {
3981cb0ef41Sopenharmony_ci      if (process_symbol_only || !has_symbol) {
3991cb0ef41Sopenharmony_ci        return Just(true);
4001cb0ef41Sopenharmony_ci      }
4011cb0ef41Sopenharmony_ci      if (has_symbol) {
4021cb0ef41Sopenharmony_ci        process_symbol_only = true;
4031cb0ef41Sopenharmony_ci      }
4041cb0ef41Sopenharmony_ci    } else {
4051cb0ef41Sopenharmony_ci      DCHECK_EQ(mode, PropertiesEnumerationMode::kPropertyAdditionOrder);
4061cb0ef41Sopenharmony_ci      return Just(true);
4071cb0ef41Sopenharmony_ci    }
4081cb0ef41Sopenharmony_ci  }
4091cb0ef41Sopenharmony_ci  UNREACHABLE();
4101cb0ef41Sopenharmony_ci}
4111cb0ef41Sopenharmony_ci}  // namespace
4121cb0ef41Sopenharmony_ci
4131cb0ef41Sopenharmony_ci// static
4141cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::SetOrCopyDataProperties(
4151cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source,
4161cb0ef41Sopenharmony_ci    PropertiesEnumerationMode mode,
4171cb0ef41Sopenharmony_ci    const base::ScopedVector<Handle<Object>>* excluded_properties,
4181cb0ef41Sopenharmony_ci    bool use_set) {
4191cb0ef41Sopenharmony_ci  Maybe<bool> fast_assign =
4201cb0ef41Sopenharmony_ci      FastAssign(target, source, mode, excluded_properties, use_set);
4211cb0ef41Sopenharmony_ci  if (fast_assign.IsNothing()) return Nothing<bool>();
4221cb0ef41Sopenharmony_ci  if (fast_assign.FromJust()) return Just(true);
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_ci  Handle<JSReceiver> from = Object::ToObject(isolate, source).ToHandleChecked();
4251cb0ef41Sopenharmony_ci
4261cb0ef41Sopenharmony_ci  // 3b. Let keys be ? from.[[OwnPropertyKeys]]().
4271cb0ef41Sopenharmony_ci  Handle<FixedArray> keys;
4281cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
4291cb0ef41Sopenharmony_ci      isolate, keys,
4301cb0ef41Sopenharmony_ci      KeyAccumulator::GetKeys(from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
4311cb0ef41Sopenharmony_ci                              GetKeysConversion::kKeepNumbers),
4321cb0ef41Sopenharmony_ci      Nothing<bool>());
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ci  if (!from->HasFastProperties() && target->HasFastProperties() &&
4351cb0ef41Sopenharmony_ci      !target->IsJSGlobalProxy()) {
4361cb0ef41Sopenharmony_ci    // JSProxy is always in slow-mode.
4371cb0ef41Sopenharmony_ci    DCHECK(!target->IsJSProxy());
4381cb0ef41Sopenharmony_ci    // Convert to slow properties if we're guaranteed to overflow the number of
4391cb0ef41Sopenharmony_ci    // descriptors.
4401cb0ef41Sopenharmony_ci    int source_length;
4411cb0ef41Sopenharmony_ci    if (from->IsJSGlobalObject()) {
4421cb0ef41Sopenharmony_ci      source_length = JSGlobalObject::cast(*from)
4431cb0ef41Sopenharmony_ci                          .global_dictionary(kAcquireLoad)
4441cb0ef41Sopenharmony_ci                          .NumberOfEnumerableProperties();
4451cb0ef41Sopenharmony_ci    } else if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
4461cb0ef41Sopenharmony_ci      source_length =
4471cb0ef41Sopenharmony_ci          from->property_dictionary_swiss().NumberOfEnumerableProperties();
4481cb0ef41Sopenharmony_ci    } else {
4491cb0ef41Sopenharmony_ci      source_length =
4501cb0ef41Sopenharmony_ci          from->property_dictionary().NumberOfEnumerableProperties();
4511cb0ef41Sopenharmony_ci    }
4521cb0ef41Sopenharmony_ci    if (source_length > kMaxNumberOfDescriptors) {
4531cb0ef41Sopenharmony_ci      JSObject::NormalizeProperties(isolate, Handle<JSObject>::cast(target),
4541cb0ef41Sopenharmony_ci                                    CLEAR_INOBJECT_PROPERTIES, source_length,
4551cb0ef41Sopenharmony_ci                                    "Copying data properties");
4561cb0ef41Sopenharmony_ci    }
4571cb0ef41Sopenharmony_ci  }
4581cb0ef41Sopenharmony_ci
4591cb0ef41Sopenharmony_ci  // 4. Repeat for each element nextKey of keys in List order,
4601cb0ef41Sopenharmony_ci  for (int i = 0; i < keys->length(); ++i) {
4611cb0ef41Sopenharmony_ci    Handle<Object> next_key(keys->get(i), isolate);
4621cb0ef41Sopenharmony_ci    if (excluded_properties != nullptr &&
4631cb0ef41Sopenharmony_ci        HasExcludedProperty(excluded_properties, next_key)) {
4641cb0ef41Sopenharmony_ci      continue;
4651cb0ef41Sopenharmony_ci    }
4661cb0ef41Sopenharmony_ci
4671cb0ef41Sopenharmony_ci    // 4a i. Let desc be ? from.[[GetOwnProperty]](nextKey).
4681cb0ef41Sopenharmony_ci    PropertyDescriptor desc;
4691cb0ef41Sopenharmony_ci    Maybe<bool> found =
4701cb0ef41Sopenharmony_ci        JSReceiver::GetOwnPropertyDescriptor(isolate, from, next_key, &desc);
4711cb0ef41Sopenharmony_ci    if (found.IsNothing()) return Nothing<bool>();
4721cb0ef41Sopenharmony_ci    // 4a ii. If desc is not undefined and desc.[[Enumerable]] is true, then
4731cb0ef41Sopenharmony_ci    if (found.FromJust() && desc.enumerable()) {
4741cb0ef41Sopenharmony_ci      // 4a ii 1. Let propValue be ? Get(from, nextKey).
4751cb0ef41Sopenharmony_ci      Handle<Object> prop_value;
4761cb0ef41Sopenharmony_ci      ASSIGN_RETURN_ON_EXCEPTION_VALUE(
4771cb0ef41Sopenharmony_ci          isolate, prop_value,
4781cb0ef41Sopenharmony_ci          Runtime::GetObjectProperty(isolate, from, next_key), Nothing<bool>());
4791cb0ef41Sopenharmony_ci
4801cb0ef41Sopenharmony_ci      if (use_set) {
4811cb0ef41Sopenharmony_ci        // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true).
4821cb0ef41Sopenharmony_ci        Handle<Object> status;
4831cb0ef41Sopenharmony_ci        ASSIGN_RETURN_ON_EXCEPTION_VALUE(
4841cb0ef41Sopenharmony_ci            isolate, status,
4851cb0ef41Sopenharmony_ci            Runtime::SetObjectProperty(isolate, target, next_key, prop_value,
4861cb0ef41Sopenharmony_ci                                       StoreOrigin::kMaybeKeyed,
4871cb0ef41Sopenharmony_ci                                       Just(ShouldThrow::kThrowOnError)),
4881cb0ef41Sopenharmony_ci            Nothing<bool>());
4891cb0ef41Sopenharmony_ci      } else {
4901cb0ef41Sopenharmony_ci        // 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue).
4911cb0ef41Sopenharmony_ci        PropertyKey key(isolate, next_key);
4921cb0ef41Sopenharmony_ci        LookupIterator it(isolate, target, key, LookupIterator::OWN);
4931cb0ef41Sopenharmony_ci        CHECK(JSObject::CreateDataProperty(&it, prop_value, Just(kThrowOnError))
4941cb0ef41Sopenharmony_ci                  .FromJust());
4951cb0ef41Sopenharmony_ci      }
4961cb0ef41Sopenharmony_ci    }
4971cb0ef41Sopenharmony_ci  }
4981cb0ef41Sopenharmony_ci
4991cb0ef41Sopenharmony_ci  return Just(true);
5001cb0ef41Sopenharmony_ci}
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_ciString JSReceiver::class_name() {
5031cb0ef41Sopenharmony_ci  ReadOnlyRoots roots = GetReadOnlyRoots();
5041cb0ef41Sopenharmony_ci  if (IsFunction()) return roots.Function_string();
5051cb0ef41Sopenharmony_ci  if (IsJSArgumentsObject()) return roots.Arguments_string();
5061cb0ef41Sopenharmony_ci  if (IsJSArray()) return roots.Array_string();
5071cb0ef41Sopenharmony_ci  if (IsJSArrayBuffer()) {
5081cb0ef41Sopenharmony_ci    if (JSArrayBuffer::cast(*this).is_shared()) {
5091cb0ef41Sopenharmony_ci      return roots.SharedArrayBuffer_string();
5101cb0ef41Sopenharmony_ci    }
5111cb0ef41Sopenharmony_ci    return roots.ArrayBuffer_string();
5121cb0ef41Sopenharmony_ci  }
5131cb0ef41Sopenharmony_ci  if (IsJSArrayIterator()) return roots.ArrayIterator_string();
5141cb0ef41Sopenharmony_ci  if (IsJSDate()) return roots.Date_string();
5151cb0ef41Sopenharmony_ci  if (IsJSError()) return roots.Error_string();
5161cb0ef41Sopenharmony_ci  if (IsJSGeneratorObject()) return roots.Generator_string();
5171cb0ef41Sopenharmony_ci  if (IsJSMap()) return roots.Map_string();
5181cb0ef41Sopenharmony_ci  if (IsJSMapIterator()) return roots.MapIterator_string();
5191cb0ef41Sopenharmony_ci  if (IsJSProxy()) {
5201cb0ef41Sopenharmony_ci    return map().is_callable() ? roots.Function_string()
5211cb0ef41Sopenharmony_ci                               : roots.Object_string();
5221cb0ef41Sopenharmony_ci  }
5231cb0ef41Sopenharmony_ci  if (IsJSRegExp()) return roots.RegExp_string();
5241cb0ef41Sopenharmony_ci  if (IsJSSet()) return roots.Set_string();
5251cb0ef41Sopenharmony_ci  if (IsJSSetIterator()) return roots.SetIterator_string();
5261cb0ef41Sopenharmony_ci  if (IsJSTypedArray()) {
5271cb0ef41Sopenharmony_ci#define SWITCH_KIND(Type, type, TYPE, ctype)      \
5281cb0ef41Sopenharmony_ci  if (map().elements_kind() == TYPE##_ELEMENTS) { \
5291cb0ef41Sopenharmony_ci    return roots.Type##Array_string();            \
5301cb0ef41Sopenharmony_ci  }
5311cb0ef41Sopenharmony_ci    TYPED_ARRAYS(SWITCH_KIND)
5321cb0ef41Sopenharmony_ci#undef SWITCH_KIND
5331cb0ef41Sopenharmony_ci  }
5341cb0ef41Sopenharmony_ci  if (IsJSPrimitiveWrapper()) {
5351cb0ef41Sopenharmony_ci    Object value = JSPrimitiveWrapper::cast(*this).value();
5361cb0ef41Sopenharmony_ci    if (value.IsBoolean()) return roots.Boolean_string();
5371cb0ef41Sopenharmony_ci    if (value.IsString()) return roots.String_string();
5381cb0ef41Sopenharmony_ci    if (value.IsNumber()) return roots.Number_string();
5391cb0ef41Sopenharmony_ci    if (value.IsBigInt()) return roots.BigInt_string();
5401cb0ef41Sopenharmony_ci    if (value.IsSymbol()) return roots.Symbol_string();
5411cb0ef41Sopenharmony_ci    if (value.IsScript()) return roots.Script_string();
5421cb0ef41Sopenharmony_ci    UNREACHABLE();
5431cb0ef41Sopenharmony_ci  }
5441cb0ef41Sopenharmony_ci  if (IsJSWeakMap()) return roots.WeakMap_string();
5451cb0ef41Sopenharmony_ci  if (IsJSWeakSet()) return roots.WeakSet_string();
5461cb0ef41Sopenharmony_ci  if (IsJSGlobalProxy()) return roots.global_string();
5471cb0ef41Sopenharmony_ci
5481cb0ef41Sopenharmony_ci  return roots.Object_string();
5491cb0ef41Sopenharmony_ci}
5501cb0ef41Sopenharmony_ci
5511cb0ef41Sopenharmony_cinamespace {
5521cb0ef41Sopenharmony_cistd::pair<MaybeHandle<JSFunction>, Handle<String>> GetConstructorHelper(
5531cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSReceiver> receiver) {
5541cb0ef41Sopenharmony_ci  // If the object was instantiated simply with base == new.target, the
5551cb0ef41Sopenharmony_ci  // constructor on the map provides the most accurate name.
5561cb0ef41Sopenharmony_ci  // Don't provide the info for prototypes, since their constructors are
5571cb0ef41Sopenharmony_ci  // reclaimed and replaced by Object in OptimizeAsPrototype.
5581cb0ef41Sopenharmony_ci  if (!receiver->IsJSProxy() && receiver->map().new_target_is_base() &&
5591cb0ef41Sopenharmony_ci      !receiver->map().is_prototype_map()) {
5601cb0ef41Sopenharmony_ci    Handle<Object> maybe_constructor(receiver->map().GetConstructor(), isolate);
5611cb0ef41Sopenharmony_ci    if (maybe_constructor->IsJSFunction()) {
5621cb0ef41Sopenharmony_ci      Handle<JSFunction> constructor =
5631cb0ef41Sopenharmony_ci          Handle<JSFunction>::cast(maybe_constructor);
5641cb0ef41Sopenharmony_ci      Handle<String> name =
5651cb0ef41Sopenharmony_ci          SharedFunctionInfo::DebugName(handle(constructor->shared(), isolate));
5661cb0ef41Sopenharmony_ci      if (name->length() != 0 &&
5671cb0ef41Sopenharmony_ci          !name->Equals(ReadOnlyRoots(isolate).Object_string())) {
5681cb0ef41Sopenharmony_ci        return std::make_pair(constructor, name);
5691cb0ef41Sopenharmony_ci      }
5701cb0ef41Sopenharmony_ci    }
5711cb0ef41Sopenharmony_ci  }
5721cb0ef41Sopenharmony_ci
5731cb0ef41Sopenharmony_ci  for (PrototypeIterator it(isolate, receiver, kStartAtReceiver); !it.IsAtEnd();
5741cb0ef41Sopenharmony_ci       it.AdvanceIgnoringProxies()) {
5751cb0ef41Sopenharmony_ci    auto current = PrototypeIterator::GetCurrent<JSReceiver>(it);
5761cb0ef41Sopenharmony_ci
5771cb0ef41Sopenharmony_ci    LookupIterator it_to_string_tag(
5781cb0ef41Sopenharmony_ci        isolate, receiver, isolate->factory()->to_string_tag_symbol(), current,
5791cb0ef41Sopenharmony_ci        LookupIterator::OWN_SKIP_INTERCEPTOR);
5801cb0ef41Sopenharmony_ci    auto maybe_to_string_tag = JSReceiver::GetDataProperty(
5811cb0ef41Sopenharmony_ci        &it_to_string_tag, AllocationPolicy::kAllocationDisallowed);
5821cb0ef41Sopenharmony_ci    if (maybe_to_string_tag->IsString()) {
5831cb0ef41Sopenharmony_ci      return std::make_pair(MaybeHandle<JSFunction>(),
5841cb0ef41Sopenharmony_ci                            Handle<String>::cast(maybe_to_string_tag));
5851cb0ef41Sopenharmony_ci    }
5861cb0ef41Sopenharmony_ci
5871cb0ef41Sopenharmony_ci    // Consider the following example:
5881cb0ef41Sopenharmony_ci    //
5891cb0ef41Sopenharmony_ci    //   function A() {}
5901cb0ef41Sopenharmony_ci    //   function B() {}
5911cb0ef41Sopenharmony_ci    //   B.prototype = new A();
5921cb0ef41Sopenharmony_ci    //   B.prototype.constructor = B;
5931cb0ef41Sopenharmony_ci    //
5941cb0ef41Sopenharmony_ci    // The constructor name for `B.prototype` must yield "A", so we don't take
5951cb0ef41Sopenharmony_ci    // "constructor" into account for the receiver itself, but only starting
5961cb0ef41Sopenharmony_ci    // on the prototype chain.
5971cb0ef41Sopenharmony_ci    if (!receiver.is_identical_to(current)) {
5981cb0ef41Sopenharmony_ci      LookupIterator it_constructor(
5991cb0ef41Sopenharmony_ci          isolate, receiver, isolate->factory()->constructor_string(), current,
6001cb0ef41Sopenharmony_ci          LookupIterator::OWN_SKIP_INTERCEPTOR);
6011cb0ef41Sopenharmony_ci      auto maybe_constructor = JSReceiver::GetDataProperty(
6021cb0ef41Sopenharmony_ci          &it_constructor, AllocationPolicy::kAllocationDisallowed);
6031cb0ef41Sopenharmony_ci      if (maybe_constructor->IsJSFunction()) {
6041cb0ef41Sopenharmony_ci        auto constructor = Handle<JSFunction>::cast(maybe_constructor);
6051cb0ef41Sopenharmony_ci        auto name = SharedFunctionInfo::DebugName(
6061cb0ef41Sopenharmony_ci            handle(constructor->shared(), isolate));
6071cb0ef41Sopenharmony_ci
6081cb0ef41Sopenharmony_ci        if (name->length() != 0 &&
6091cb0ef41Sopenharmony_ci            !name->Equals(ReadOnlyRoots(isolate).Object_string())) {
6101cb0ef41Sopenharmony_ci          return std::make_pair(constructor, name);
6111cb0ef41Sopenharmony_ci        }
6121cb0ef41Sopenharmony_ci      }
6131cb0ef41Sopenharmony_ci    }
6141cb0ef41Sopenharmony_ci  }
6151cb0ef41Sopenharmony_ci
6161cb0ef41Sopenharmony_ci  return std::make_pair(MaybeHandle<JSFunction>(),
6171cb0ef41Sopenharmony_ci                        handle(receiver->class_name(), isolate));
6181cb0ef41Sopenharmony_ci}
6191cb0ef41Sopenharmony_ci}  // anonymous namespace
6201cb0ef41Sopenharmony_ci
6211cb0ef41Sopenharmony_ci// static
6221cb0ef41Sopenharmony_ciMaybeHandle<JSFunction> JSReceiver::GetConstructor(
6231cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSReceiver> receiver) {
6241cb0ef41Sopenharmony_ci  return GetConstructorHelper(isolate, receiver).first;
6251cb0ef41Sopenharmony_ci}
6261cb0ef41Sopenharmony_ci
6271cb0ef41Sopenharmony_ci// static
6281cb0ef41Sopenharmony_ciHandle<String> JSReceiver::GetConstructorName(Isolate* isolate,
6291cb0ef41Sopenharmony_ci                                              Handle<JSReceiver> receiver) {
6301cb0ef41Sopenharmony_ci  return GetConstructorHelper(isolate, receiver).second;
6311cb0ef41Sopenharmony_ci}
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_ciMaybeHandle<NativeContext> JSReceiver::GetCreationContext() {
6341cb0ef41Sopenharmony_ci  JSReceiver receiver = *this;
6351cb0ef41Sopenharmony_ci  // Externals are JSObjects with null as a constructor.
6361cb0ef41Sopenharmony_ci  DCHECK(!receiver.IsJSExternalObject());
6371cb0ef41Sopenharmony_ci  Object constructor = receiver.map().GetConstructor();
6381cb0ef41Sopenharmony_ci  JSFunction function;
6391cb0ef41Sopenharmony_ci  if (constructor.IsJSFunction()) {
6401cb0ef41Sopenharmony_ci    function = JSFunction::cast(constructor);
6411cb0ef41Sopenharmony_ci  } else if (constructor.IsFunctionTemplateInfo()) {
6421cb0ef41Sopenharmony_ci    // Remote objects don't have a creation context.
6431cb0ef41Sopenharmony_ci    return MaybeHandle<NativeContext>();
6441cb0ef41Sopenharmony_ci  } else if (receiver.IsJSGeneratorObject()) {
6451cb0ef41Sopenharmony_ci    function = JSGeneratorObject::cast(receiver).function();
6461cb0ef41Sopenharmony_ci  } else if (receiver.IsJSFunction()) {
6471cb0ef41Sopenharmony_ci    function = JSFunction::cast(receiver);
6481cb0ef41Sopenharmony_ci  } else {
6491cb0ef41Sopenharmony_ci    return MaybeHandle<NativeContext>();
6501cb0ef41Sopenharmony_ci  }
6511cb0ef41Sopenharmony_ci
6521cb0ef41Sopenharmony_ci  return function.has_context()
6531cb0ef41Sopenharmony_ci             ? Handle<NativeContext>(function.native_context(),
6541cb0ef41Sopenharmony_ci                                     receiver.GetIsolate())
6551cb0ef41Sopenharmony_ci             : MaybeHandle<NativeContext>();
6561cb0ef41Sopenharmony_ci}
6571cb0ef41Sopenharmony_ci
6581cb0ef41Sopenharmony_ci// static
6591cb0ef41Sopenharmony_ciMaybeHandle<NativeContext> JSReceiver::GetFunctionRealm(
6601cb0ef41Sopenharmony_ci    Handle<JSReceiver> receiver) {
6611cb0ef41Sopenharmony_ci  Isolate* isolate = receiver->GetIsolate();
6621cb0ef41Sopenharmony_ci  // This is implemented as a loop because it's possible to construct very
6631cb0ef41Sopenharmony_ci  // long chains of bound functions or proxies where a recursive implementation
6641cb0ef41Sopenharmony_ci  // would run out of stack space.
6651cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
6661cb0ef41Sopenharmony_ci  JSReceiver current = *receiver;
6671cb0ef41Sopenharmony_ci  do {
6681cb0ef41Sopenharmony_ci    DCHECK(current.map().is_constructor());
6691cb0ef41Sopenharmony_ci    if (current.IsJSProxy()) {
6701cb0ef41Sopenharmony_ci      JSProxy proxy = JSProxy::cast(current);
6711cb0ef41Sopenharmony_ci      if (proxy.IsRevoked()) {
6721cb0ef41Sopenharmony_ci        AllowGarbageCollection allow_allocating_errors;
6731cb0ef41Sopenharmony_ci        THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kProxyRevoked),
6741cb0ef41Sopenharmony_ci                        NativeContext);
6751cb0ef41Sopenharmony_ci      }
6761cb0ef41Sopenharmony_ci      current = JSReceiver::cast(proxy.target());
6771cb0ef41Sopenharmony_ci      continue;
6781cb0ef41Sopenharmony_ci    }
6791cb0ef41Sopenharmony_ci    if (current.IsJSFunction()) {
6801cb0ef41Sopenharmony_ci      JSFunction function = JSFunction::cast(current);
6811cb0ef41Sopenharmony_ci      return handle(function.native_context(), isolate);
6821cb0ef41Sopenharmony_ci    }
6831cb0ef41Sopenharmony_ci    if (current.IsJSBoundFunction()) {
6841cb0ef41Sopenharmony_ci      JSBoundFunction function = JSBoundFunction::cast(current);
6851cb0ef41Sopenharmony_ci      current = function.bound_target_function();
6861cb0ef41Sopenharmony_ci      continue;
6871cb0ef41Sopenharmony_ci    }
6881cb0ef41Sopenharmony_ci    if (current.IsJSWrappedFunction()) {
6891cb0ef41Sopenharmony_ci      JSWrappedFunction function = JSWrappedFunction::cast(current);
6901cb0ef41Sopenharmony_ci      current = function.wrapped_target_function();
6911cb0ef41Sopenharmony_ci      continue;
6921cb0ef41Sopenharmony_ci    }
6931cb0ef41Sopenharmony_ci    JSObject object = JSObject::cast(current);
6941cb0ef41Sopenharmony_ci    DCHECK(!object.IsJSFunction());
6951cb0ef41Sopenharmony_ci    return object.GetCreationContext();
6961cb0ef41Sopenharmony_ci  } while (true);
6971cb0ef41Sopenharmony_ci}
6981cb0ef41Sopenharmony_ci
6991cb0ef41Sopenharmony_ci// static
7001cb0ef41Sopenharmony_ciMaybeHandle<NativeContext> JSReceiver::GetContextForMicrotask(
7011cb0ef41Sopenharmony_ci    Handle<JSReceiver> receiver) {
7021cb0ef41Sopenharmony_ci  Isolate* isolate = receiver->GetIsolate();
7031cb0ef41Sopenharmony_ci  while (receiver->IsJSBoundFunction() || receiver->IsJSProxy()) {
7041cb0ef41Sopenharmony_ci    if (receiver->IsJSBoundFunction()) {
7051cb0ef41Sopenharmony_ci      receiver = handle(
7061cb0ef41Sopenharmony_ci          Handle<JSBoundFunction>::cast(receiver)->bound_target_function(),
7071cb0ef41Sopenharmony_ci          isolate);
7081cb0ef41Sopenharmony_ci    } else {
7091cb0ef41Sopenharmony_ci      DCHECK(receiver->IsJSProxy());
7101cb0ef41Sopenharmony_ci      Handle<Object> target(Handle<JSProxy>::cast(receiver)->target(), isolate);
7111cb0ef41Sopenharmony_ci      if (!target->IsJSReceiver()) return MaybeHandle<NativeContext>();
7121cb0ef41Sopenharmony_ci      receiver = Handle<JSReceiver>::cast(target);
7131cb0ef41Sopenharmony_ci    }
7141cb0ef41Sopenharmony_ci  }
7151cb0ef41Sopenharmony_ci
7161cb0ef41Sopenharmony_ci  if (!receiver->IsJSFunction()) return MaybeHandle<NativeContext>();
7171cb0ef41Sopenharmony_ci  return handle(Handle<JSFunction>::cast(receiver)->native_context(), isolate);
7181cb0ef41Sopenharmony_ci}
7191cb0ef41Sopenharmony_ci
7201cb0ef41Sopenharmony_ciMaybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
7211cb0ef41Sopenharmony_ci    LookupIterator* it) {
7221cb0ef41Sopenharmony_ci  for (; it->IsFound(); it->Next()) {
7231cb0ef41Sopenharmony_ci    switch (it->state()) {
7241cb0ef41Sopenharmony_ci      case LookupIterator::NOT_FOUND:
7251cb0ef41Sopenharmony_ci      case LookupIterator::TRANSITION:
7261cb0ef41Sopenharmony_ci        UNREACHABLE();
7271cb0ef41Sopenharmony_ci      case LookupIterator::JSPROXY:
7281cb0ef41Sopenharmony_ci        return JSProxy::GetPropertyAttributes(it);
7291cb0ef41Sopenharmony_ci      case LookupIterator::INTERCEPTOR: {
7301cb0ef41Sopenharmony_ci        Maybe<PropertyAttributes> result =
7311cb0ef41Sopenharmony_ci            JSObject::GetPropertyAttributesWithInterceptor(it);
7321cb0ef41Sopenharmony_ci        if (result.IsNothing()) return result;
7331cb0ef41Sopenharmony_ci        if (result.FromJust() != ABSENT) return result;
7341cb0ef41Sopenharmony_ci        break;
7351cb0ef41Sopenharmony_ci      }
7361cb0ef41Sopenharmony_ci      case LookupIterator::ACCESS_CHECK:
7371cb0ef41Sopenharmony_ci        if (it->HasAccess()) break;
7381cb0ef41Sopenharmony_ci        return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
7391cb0ef41Sopenharmony_ci      case LookupIterator::INTEGER_INDEXED_EXOTIC:
7401cb0ef41Sopenharmony_ci        return Just(ABSENT);
7411cb0ef41Sopenharmony_ci      case LookupIterator::ACCESSOR:
7421cb0ef41Sopenharmony_ci        if (it->GetHolder<Object>()->IsJSModuleNamespace()) {
7431cb0ef41Sopenharmony_ci          return JSModuleNamespace::GetPropertyAttributes(it);
7441cb0ef41Sopenharmony_ci        } else {
7451cb0ef41Sopenharmony_ci          return Just(it->property_attributes());
7461cb0ef41Sopenharmony_ci        }
7471cb0ef41Sopenharmony_ci      case LookupIterator::DATA:
7481cb0ef41Sopenharmony_ci        return Just(it->property_attributes());
7491cb0ef41Sopenharmony_ci    }
7501cb0ef41Sopenharmony_ci  }
7511cb0ef41Sopenharmony_ci  return Just(ABSENT);
7521cb0ef41Sopenharmony_ci}
7531cb0ef41Sopenharmony_ci
7541cb0ef41Sopenharmony_cinamespace {
7551cb0ef41Sopenharmony_ci
7561cb0ef41Sopenharmony_ciObject SetHashAndUpdateProperties(HeapObject properties, int hash) {
7571cb0ef41Sopenharmony_ci  DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
7581cb0ef41Sopenharmony_ci  DCHECK(PropertyArray::HashField::is_valid(hash));
7591cb0ef41Sopenharmony_ci
7601cb0ef41Sopenharmony_ci  ReadOnlyRoots roots = properties.GetReadOnlyRoots();
7611cb0ef41Sopenharmony_ci  if (properties == roots.empty_fixed_array() ||
7621cb0ef41Sopenharmony_ci      properties == roots.empty_property_array() ||
7631cb0ef41Sopenharmony_ci      properties == roots.empty_property_dictionary() ||
7641cb0ef41Sopenharmony_ci      properties == roots.empty_swiss_property_dictionary()) {
7651cb0ef41Sopenharmony_ci    return Smi::FromInt(hash);
7661cb0ef41Sopenharmony_ci  }
7671cb0ef41Sopenharmony_ci
7681cb0ef41Sopenharmony_ci  if (properties.IsPropertyArray()) {
7691cb0ef41Sopenharmony_ci    PropertyArray::cast(properties).SetHash(hash);
7701cb0ef41Sopenharmony_ci    DCHECK_LT(0, PropertyArray::cast(properties).length());
7711cb0ef41Sopenharmony_ci    return properties;
7721cb0ef41Sopenharmony_ci  }
7731cb0ef41Sopenharmony_ci
7741cb0ef41Sopenharmony_ci  if (properties.IsGlobalDictionary()) {
7751cb0ef41Sopenharmony_ci    GlobalDictionary::cast(properties).SetHash(hash);
7761cb0ef41Sopenharmony_ci    return properties;
7771cb0ef41Sopenharmony_ci  }
7781cb0ef41Sopenharmony_ci
7791cb0ef41Sopenharmony_ci  if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
7801cb0ef41Sopenharmony_ci    DCHECK(properties.IsSwissNameDictionary());
7811cb0ef41Sopenharmony_ci    SwissNameDictionary::cast(properties).SetHash(hash);
7821cb0ef41Sopenharmony_ci  } else {
7831cb0ef41Sopenharmony_ci    DCHECK(properties.IsNameDictionary());
7841cb0ef41Sopenharmony_ci    NameDictionary::cast(properties).SetHash(hash);
7851cb0ef41Sopenharmony_ci  }
7861cb0ef41Sopenharmony_ci  return properties;
7871cb0ef41Sopenharmony_ci}
7881cb0ef41Sopenharmony_ci
7891cb0ef41Sopenharmony_ciint GetIdentityHashHelper(JSReceiver object) {
7901cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
7911cb0ef41Sopenharmony_ci  Object properties = object.raw_properties_or_hash();
7921cb0ef41Sopenharmony_ci  if (properties.IsSmi()) {
7931cb0ef41Sopenharmony_ci    return Smi::ToInt(properties);
7941cb0ef41Sopenharmony_ci  }
7951cb0ef41Sopenharmony_ci
7961cb0ef41Sopenharmony_ci  if (properties.IsPropertyArray()) {
7971cb0ef41Sopenharmony_ci    return PropertyArray::cast(properties).Hash();
7981cb0ef41Sopenharmony_ci  }
7991cb0ef41Sopenharmony_ci  if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL &&
8001cb0ef41Sopenharmony_ci      properties.IsSwissNameDictionary()) {
8011cb0ef41Sopenharmony_ci    return SwissNameDictionary::cast(properties).Hash();
8021cb0ef41Sopenharmony_ci  }
8031cb0ef41Sopenharmony_ci
8041cb0ef41Sopenharmony_ci  if (properties.IsNameDictionary()) {
8051cb0ef41Sopenharmony_ci    DCHECK(!V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL);
8061cb0ef41Sopenharmony_ci    return NameDictionary::cast(properties).Hash();
8071cb0ef41Sopenharmony_ci  }
8081cb0ef41Sopenharmony_ci
8091cb0ef41Sopenharmony_ci  if (properties.IsGlobalDictionary()) {
8101cb0ef41Sopenharmony_ci    return GlobalDictionary::cast(properties).Hash();
8111cb0ef41Sopenharmony_ci  }
8121cb0ef41Sopenharmony_ci
8131cb0ef41Sopenharmony_ci#ifdef DEBUG
8141cb0ef41Sopenharmony_ci  ReadOnlyRoots roots = object.GetReadOnlyRoots();
8151cb0ef41Sopenharmony_ci  DCHECK(properties == roots.empty_fixed_array() ||
8161cb0ef41Sopenharmony_ci         properties == roots.empty_property_dictionary() ||
8171cb0ef41Sopenharmony_ci         properties == roots.empty_swiss_property_dictionary());
8181cb0ef41Sopenharmony_ci#endif
8191cb0ef41Sopenharmony_ci
8201cb0ef41Sopenharmony_ci  return PropertyArray::kNoHashSentinel;
8211cb0ef41Sopenharmony_ci}
8221cb0ef41Sopenharmony_ci}  // namespace
8231cb0ef41Sopenharmony_ci
8241cb0ef41Sopenharmony_civoid JSReceiver::SetIdentityHash(int hash) {
8251cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
8261cb0ef41Sopenharmony_ci  DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
8271cb0ef41Sopenharmony_ci  DCHECK(PropertyArray::HashField::is_valid(hash));
8281cb0ef41Sopenharmony_ci
8291cb0ef41Sopenharmony_ci  HeapObject existing_properties = HeapObject::cast(raw_properties_or_hash());
8301cb0ef41Sopenharmony_ci  Object new_properties = SetHashAndUpdateProperties(existing_properties, hash);
8311cb0ef41Sopenharmony_ci  set_raw_properties_or_hash(new_properties, kRelaxedStore);
8321cb0ef41Sopenharmony_ci}
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_civoid JSReceiver::SetProperties(HeapObject properties) {
8351cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(properties.IsPropertyArray() &&
8361cb0ef41Sopenharmony_ci                     PropertyArray::cast(properties).length() == 0,
8371cb0ef41Sopenharmony_ci                 properties == GetReadOnlyRoots().empty_property_array());
8381cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
8391cb0ef41Sopenharmony_ci  int hash = GetIdentityHashHelper(*this);
8401cb0ef41Sopenharmony_ci  Object new_properties = properties;
8411cb0ef41Sopenharmony_ci
8421cb0ef41Sopenharmony_ci  // TODO(cbruni): Make GetIdentityHashHelper return a bool so that we
8431cb0ef41Sopenharmony_ci  // don't have to manually compare against kNoHashSentinel.
8441cb0ef41Sopenharmony_ci  if (hash != PropertyArray::kNoHashSentinel) {
8451cb0ef41Sopenharmony_ci    new_properties = SetHashAndUpdateProperties(properties, hash);
8461cb0ef41Sopenharmony_ci  }
8471cb0ef41Sopenharmony_ci
8481cb0ef41Sopenharmony_ci  set_raw_properties_or_hash(new_properties, kRelaxedStore);
8491cb0ef41Sopenharmony_ci}
8501cb0ef41Sopenharmony_ci
8511cb0ef41Sopenharmony_ciObject JSReceiver::GetIdentityHash() {
8521cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
8531cb0ef41Sopenharmony_ci
8541cb0ef41Sopenharmony_ci  int hash = GetIdentityHashHelper(*this);
8551cb0ef41Sopenharmony_ci  if (hash == PropertyArray::kNoHashSentinel) {
8561cb0ef41Sopenharmony_ci    return GetReadOnlyRoots().undefined_value();
8571cb0ef41Sopenharmony_ci  }
8581cb0ef41Sopenharmony_ci
8591cb0ef41Sopenharmony_ci  return Smi::FromInt(hash);
8601cb0ef41Sopenharmony_ci}
8611cb0ef41Sopenharmony_ci
8621cb0ef41Sopenharmony_ci// static
8631cb0ef41Sopenharmony_ciSmi JSReceiver::CreateIdentityHash(Isolate* isolate, JSReceiver key) {
8641cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
8651cb0ef41Sopenharmony_ci  int hash = isolate->GenerateIdentityHash(PropertyArray::HashField::kMax);
8661cb0ef41Sopenharmony_ci  DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
8671cb0ef41Sopenharmony_ci
8681cb0ef41Sopenharmony_ci  key.SetIdentityHash(hash);
8691cb0ef41Sopenharmony_ci  return Smi::FromInt(hash);
8701cb0ef41Sopenharmony_ci}
8711cb0ef41Sopenharmony_ci
8721cb0ef41Sopenharmony_ciSmi JSReceiver::GetOrCreateIdentityHash(Isolate* isolate) {
8731cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
8741cb0ef41Sopenharmony_ci
8751cb0ef41Sopenharmony_ci  int hash = GetIdentityHashHelper(*this);
8761cb0ef41Sopenharmony_ci  if (hash != PropertyArray::kNoHashSentinel) {
8771cb0ef41Sopenharmony_ci    return Smi::FromInt(hash);
8781cb0ef41Sopenharmony_ci  }
8791cb0ef41Sopenharmony_ci
8801cb0ef41Sopenharmony_ci  return JSReceiver::CreateIdentityHash(isolate, *this);
8811cb0ef41Sopenharmony_ci}
8821cb0ef41Sopenharmony_ci
8831cb0ef41Sopenharmony_civoid JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object,
8841cb0ef41Sopenharmony_ci                                          InternalIndex entry) {
8851cb0ef41Sopenharmony_ci  DCHECK(!object->HasFastProperties());
8861cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
8871cb0ef41Sopenharmony_ci  DCHECK(entry.is_found());
8881cb0ef41Sopenharmony_ci
8891cb0ef41Sopenharmony_ci  if (object->IsJSGlobalObject()) {
8901cb0ef41Sopenharmony_ci    // If we have a global object, invalidate the cell and remove it from the
8911cb0ef41Sopenharmony_ci    // global object's dictionary.
8921cb0ef41Sopenharmony_ci    Handle<GlobalDictionary> dictionary(
8931cb0ef41Sopenharmony_ci        JSGlobalObject::cast(*object).global_dictionary(kAcquireLoad), isolate);
8941cb0ef41Sopenharmony_ci
8951cb0ef41Sopenharmony_ci    Handle<PropertyCell> cell(dictionary->CellAt(entry), isolate);
8961cb0ef41Sopenharmony_ci
8971cb0ef41Sopenharmony_ci    Handle<GlobalDictionary> new_dictionary =
8981cb0ef41Sopenharmony_ci        GlobalDictionary::DeleteEntry(isolate, dictionary, entry);
8991cb0ef41Sopenharmony_ci    JSGlobalObject::cast(*object).set_global_dictionary(*new_dictionary,
9001cb0ef41Sopenharmony_ci                                                        kReleaseStore);
9011cb0ef41Sopenharmony_ci
9021cb0ef41Sopenharmony_ci    cell->ClearAndInvalidate(ReadOnlyRoots(isolate));
9031cb0ef41Sopenharmony_ci  } else {
9041cb0ef41Sopenharmony_ci    if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
9051cb0ef41Sopenharmony_ci      Handle<SwissNameDictionary> dictionary(
9061cb0ef41Sopenharmony_ci          object->property_dictionary_swiss(), isolate);
9071cb0ef41Sopenharmony_ci
9081cb0ef41Sopenharmony_ci      dictionary = SwissNameDictionary::DeleteEntry(isolate, dictionary, entry);
9091cb0ef41Sopenharmony_ci      object->SetProperties(*dictionary);
9101cb0ef41Sopenharmony_ci    } else {
9111cb0ef41Sopenharmony_ci      Handle<NameDictionary> dictionary(object->property_dictionary(), isolate);
9121cb0ef41Sopenharmony_ci
9131cb0ef41Sopenharmony_ci      dictionary = NameDictionary::DeleteEntry(isolate, dictionary, entry);
9141cb0ef41Sopenharmony_ci      object->SetProperties(*dictionary);
9151cb0ef41Sopenharmony_ci    }
9161cb0ef41Sopenharmony_ci  }
9171cb0ef41Sopenharmony_ci  if (object->map().is_prototype_map()) {
9181cb0ef41Sopenharmony_ci    // Invalidate prototype validity cell as this may invalidate transitioning
9191cb0ef41Sopenharmony_ci    // store IC handlers.
9201cb0ef41Sopenharmony_ci    JSObject::InvalidatePrototypeChains(object->map());
9211cb0ef41Sopenharmony_ci  }
9221cb0ef41Sopenharmony_ci}
9231cb0ef41Sopenharmony_ci
9241cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::DeleteProperty(LookupIterator* it,
9251cb0ef41Sopenharmony_ci                                       LanguageMode language_mode) {
9261cb0ef41Sopenharmony_ci  it->UpdateProtector();
9271cb0ef41Sopenharmony_ci
9281cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
9291cb0ef41Sopenharmony_ci
9301cb0ef41Sopenharmony_ci  if (it->state() == LookupIterator::JSPROXY) {
9311cb0ef41Sopenharmony_ci    return JSProxy::DeletePropertyOrElement(it->GetHolder<JSProxy>(),
9321cb0ef41Sopenharmony_ci                                            it->GetName(), language_mode);
9331cb0ef41Sopenharmony_ci  }
9341cb0ef41Sopenharmony_ci
9351cb0ef41Sopenharmony_ci  if (it->GetReceiver()->IsJSProxy()) {
9361cb0ef41Sopenharmony_ci    if (it->state() != LookupIterator::NOT_FOUND) {
9371cb0ef41Sopenharmony_ci      DCHECK_EQ(LookupIterator::DATA, it->state());
9381cb0ef41Sopenharmony_ci      DCHECK(it->name()->IsPrivate());
9391cb0ef41Sopenharmony_ci      it->Delete();
9401cb0ef41Sopenharmony_ci    }
9411cb0ef41Sopenharmony_ci    return Just(true);
9421cb0ef41Sopenharmony_ci  }
9431cb0ef41Sopenharmony_ci  Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
9441cb0ef41Sopenharmony_ci
9451cb0ef41Sopenharmony_ci  for (; it->IsFound(); it->Next()) {
9461cb0ef41Sopenharmony_ci    switch (it->state()) {
9471cb0ef41Sopenharmony_ci      case LookupIterator::JSPROXY:
9481cb0ef41Sopenharmony_ci      case LookupIterator::NOT_FOUND:
9491cb0ef41Sopenharmony_ci      case LookupIterator::TRANSITION:
9501cb0ef41Sopenharmony_ci        UNREACHABLE();
9511cb0ef41Sopenharmony_ci      case LookupIterator::ACCESS_CHECK:
9521cb0ef41Sopenharmony_ci        if (it->HasAccess()) break;
9531cb0ef41Sopenharmony_ci        isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
9541cb0ef41Sopenharmony_ci        RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
9551cb0ef41Sopenharmony_ci        return Just(false);
9561cb0ef41Sopenharmony_ci      case LookupIterator::INTERCEPTOR: {
9571cb0ef41Sopenharmony_ci        ShouldThrow should_throw =
9581cb0ef41Sopenharmony_ci            is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
9591cb0ef41Sopenharmony_ci        Maybe<bool> result =
9601cb0ef41Sopenharmony_ci            JSObject::DeletePropertyWithInterceptor(it, should_throw);
9611cb0ef41Sopenharmony_ci        // An exception was thrown in the interceptor. Propagate.
9621cb0ef41Sopenharmony_ci        if (isolate->has_pending_exception()) return Nothing<bool>();
9631cb0ef41Sopenharmony_ci        // Delete with interceptor succeeded. Return result.
9641cb0ef41Sopenharmony_ci        // TODO(neis): In strict mode, we should probably throw if the
9651cb0ef41Sopenharmony_ci        // interceptor returns false.
9661cb0ef41Sopenharmony_ci        if (result.IsJust()) return result;
9671cb0ef41Sopenharmony_ci        break;
9681cb0ef41Sopenharmony_ci      }
9691cb0ef41Sopenharmony_ci      case LookupIterator::INTEGER_INDEXED_EXOTIC:
9701cb0ef41Sopenharmony_ci        return Just(true);
9711cb0ef41Sopenharmony_ci      case LookupIterator::DATA:
9721cb0ef41Sopenharmony_ci      case LookupIterator::ACCESSOR: {
9731cb0ef41Sopenharmony_ci        Handle<JSObject> holder = it->GetHolder<JSObject>();
9741cb0ef41Sopenharmony_ci        if (!it->IsConfigurable() ||
9751cb0ef41Sopenharmony_ci            (holder->IsJSTypedArray() && it->IsElement(*holder))) {
9761cb0ef41Sopenharmony_ci          // Fail if the property is not configurable if the property is a
9771cb0ef41Sopenharmony_ci          // TypedArray element.
9781cb0ef41Sopenharmony_ci          if (is_strict(language_mode)) {
9791cb0ef41Sopenharmony_ci            isolate->Throw(*isolate->factory()->NewTypeError(
9801cb0ef41Sopenharmony_ci                MessageTemplate::kStrictDeleteProperty, it->GetName(),
9811cb0ef41Sopenharmony_ci                receiver));
9821cb0ef41Sopenharmony_ci            return Nothing<bool>();
9831cb0ef41Sopenharmony_ci          }
9841cb0ef41Sopenharmony_ci          return Just(false);
9851cb0ef41Sopenharmony_ci        }
9861cb0ef41Sopenharmony_ci
9871cb0ef41Sopenharmony_ci        it->Delete();
9881cb0ef41Sopenharmony_ci
9891cb0ef41Sopenharmony_ci        return Just(true);
9901cb0ef41Sopenharmony_ci      }
9911cb0ef41Sopenharmony_ci    }
9921cb0ef41Sopenharmony_ci  }
9931cb0ef41Sopenharmony_ci
9941cb0ef41Sopenharmony_ci  return Just(true);
9951cb0ef41Sopenharmony_ci}
9961cb0ef41Sopenharmony_ci
9971cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::DeleteElement(Handle<JSReceiver> object, uint32_t index,
9981cb0ef41Sopenharmony_ci                                      LanguageMode language_mode) {
9991cb0ef41Sopenharmony_ci  LookupIterator it(object->GetIsolate(), object, index, object,
10001cb0ef41Sopenharmony_ci                    LookupIterator::OWN);
10011cb0ef41Sopenharmony_ci  return DeleteProperty(&it, language_mode);
10021cb0ef41Sopenharmony_ci}
10031cb0ef41Sopenharmony_ci
10041cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
10051cb0ef41Sopenharmony_ci                                       Handle<Name> name,
10061cb0ef41Sopenharmony_ci                                       LanguageMode language_mode) {
10071cb0ef41Sopenharmony_ci  LookupIterator it(object->GetIsolate(), object, name, object,
10081cb0ef41Sopenharmony_ci                    LookupIterator::OWN);
10091cb0ef41Sopenharmony_ci  return DeleteProperty(&it, language_mode);
10101cb0ef41Sopenharmony_ci}
10111cb0ef41Sopenharmony_ci
10121cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::DeletePropertyOrElement(Handle<JSReceiver> object,
10131cb0ef41Sopenharmony_ci                                                Handle<Name> name,
10141cb0ef41Sopenharmony_ci                                                LanguageMode language_mode) {
10151cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
10161cb0ef41Sopenharmony_ci  PropertyKey key(isolate, name);
10171cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, key, object, LookupIterator::OWN);
10181cb0ef41Sopenharmony_ci  return DeleteProperty(&it, language_mode);
10191cb0ef41Sopenharmony_ci}
10201cb0ef41Sopenharmony_ci
10211cb0ef41Sopenharmony_ci// ES6 19.1.2.4
10221cb0ef41Sopenharmony_ci// static
10231cb0ef41Sopenharmony_ciObject JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object,
10241cb0ef41Sopenharmony_ci                                  Handle<Object> key,
10251cb0ef41Sopenharmony_ci                                  Handle<Object> attributes) {
10261cb0ef41Sopenharmony_ci  // 1. If Type(O) is not Object, throw a TypeError exception.
10271cb0ef41Sopenharmony_ci  if (!object->IsJSReceiver()) {
10281cb0ef41Sopenharmony_ci    Handle<String> fun_name =
10291cb0ef41Sopenharmony_ci        isolate->factory()->InternalizeUtf8String("Object.defineProperty");
10301cb0ef41Sopenharmony_ci    THROW_NEW_ERROR_RETURN_FAILURE(
10311cb0ef41Sopenharmony_ci        isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name));
10321cb0ef41Sopenharmony_ci  }
10331cb0ef41Sopenharmony_ci  // 2. Let key be ToPropertyKey(P).
10341cb0ef41Sopenharmony_ci  // 3. ReturnIfAbrupt(key).
10351cb0ef41Sopenharmony_ci  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
10361cb0ef41Sopenharmony_ci                                     Object::ToPropertyKey(isolate, key));
10371cb0ef41Sopenharmony_ci  // 4. Let desc be ToPropertyDescriptor(Attributes).
10381cb0ef41Sopenharmony_ci  // 5. ReturnIfAbrupt(desc).
10391cb0ef41Sopenharmony_ci  PropertyDescriptor desc;
10401cb0ef41Sopenharmony_ci  if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
10411cb0ef41Sopenharmony_ci    return ReadOnlyRoots(isolate).exception();
10421cb0ef41Sopenharmony_ci  }
10431cb0ef41Sopenharmony_ci  // 6. Let success be DefinePropertyOrThrow(O,key, desc).
10441cb0ef41Sopenharmony_ci  Maybe<bool> success =
10451cb0ef41Sopenharmony_ci      DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object), key, &desc,
10461cb0ef41Sopenharmony_ci                        Just(kThrowOnError));
10471cb0ef41Sopenharmony_ci  // 7. ReturnIfAbrupt(success).
10481cb0ef41Sopenharmony_ci  MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
10491cb0ef41Sopenharmony_ci  CHECK(success.FromJust());
10501cb0ef41Sopenharmony_ci  // 8. Return O.
10511cb0ef41Sopenharmony_ci  return *object;
10521cb0ef41Sopenharmony_ci}
10531cb0ef41Sopenharmony_ci
10541cb0ef41Sopenharmony_ci// ES6 19.1.2.3.1
10551cb0ef41Sopenharmony_ci// static
10561cb0ef41Sopenharmony_ciMaybeHandle<Object> JSReceiver::DefineProperties(Isolate* isolate,
10571cb0ef41Sopenharmony_ci                                                 Handle<Object> object,
10581cb0ef41Sopenharmony_ci                                                 Handle<Object> properties) {
10591cb0ef41Sopenharmony_ci  // 1. If Type(O) is not Object, throw a TypeError exception.
10601cb0ef41Sopenharmony_ci  if (!object->IsJSReceiver()) {
10611cb0ef41Sopenharmony_ci    Handle<String> fun_name =
10621cb0ef41Sopenharmony_ci        isolate->factory()->InternalizeUtf8String("Object.defineProperties");
10631cb0ef41Sopenharmony_ci    THROW_NEW_ERROR(isolate,
10641cb0ef41Sopenharmony_ci                    NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name),
10651cb0ef41Sopenharmony_ci                    Object);
10661cb0ef41Sopenharmony_ci  }
10671cb0ef41Sopenharmony_ci  // 2. Let props be ToObject(Properties).
10681cb0ef41Sopenharmony_ci  // 3. ReturnIfAbrupt(props).
10691cb0ef41Sopenharmony_ci  Handle<JSReceiver> props;
10701cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION(isolate, props,
10711cb0ef41Sopenharmony_ci                             Object::ToObject(isolate, properties), Object);
10721cb0ef41Sopenharmony_ci
10731cb0ef41Sopenharmony_ci  // 4. Let keys be props.[[OwnPropertyKeys]]().
10741cb0ef41Sopenharmony_ci  // 5. ReturnIfAbrupt(keys).
10751cb0ef41Sopenharmony_ci  Handle<FixedArray> keys;
10761cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION(
10771cb0ef41Sopenharmony_ci      isolate, keys,
10781cb0ef41Sopenharmony_ci      KeyAccumulator::GetKeys(props, KeyCollectionMode::kOwnOnly,
10791cb0ef41Sopenharmony_ci                              ALL_PROPERTIES),
10801cb0ef41Sopenharmony_ci      Object);
10811cb0ef41Sopenharmony_ci  // 6. Let descriptors be an empty List.
10821cb0ef41Sopenharmony_ci  int capacity = keys->length();
10831cb0ef41Sopenharmony_ci  std::vector<PropertyDescriptor> descriptors(capacity);
10841cb0ef41Sopenharmony_ci  size_t descriptors_index = 0;
10851cb0ef41Sopenharmony_ci  // 7. Repeat for each element nextKey of keys in List order,
10861cb0ef41Sopenharmony_ci  for (int i = 0; i < keys->length(); ++i) {
10871cb0ef41Sopenharmony_ci    Handle<Object> next_key(keys->get(i), isolate);
10881cb0ef41Sopenharmony_ci    // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey).
10891cb0ef41Sopenharmony_ci    // 7b. ReturnIfAbrupt(propDesc).
10901cb0ef41Sopenharmony_ci    PropertyKey key(isolate, next_key);
10911cb0ef41Sopenharmony_ci    LookupIterator it(isolate, props, key, LookupIterator::OWN);
10921cb0ef41Sopenharmony_ci    Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
10931cb0ef41Sopenharmony_ci    if (maybe.IsNothing()) return MaybeHandle<Object>();
10941cb0ef41Sopenharmony_ci    PropertyAttributes attrs = maybe.FromJust();
10951cb0ef41Sopenharmony_ci    // 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true:
10961cb0ef41Sopenharmony_ci    if (attrs == ABSENT) continue;
10971cb0ef41Sopenharmony_ci    if (attrs & DONT_ENUM) continue;
10981cb0ef41Sopenharmony_ci    // 7c i. Let descObj be Get(props, nextKey).
10991cb0ef41Sopenharmony_ci    // 7c ii. ReturnIfAbrupt(descObj).
11001cb0ef41Sopenharmony_ci    Handle<Object> desc_obj;
11011cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION(isolate, desc_obj, Object::GetProperty(&it),
11021cb0ef41Sopenharmony_ci                               Object);
11031cb0ef41Sopenharmony_ci    // 7c iii. Let desc be ToPropertyDescriptor(descObj).
11041cb0ef41Sopenharmony_ci    bool success = PropertyDescriptor::ToPropertyDescriptor(
11051cb0ef41Sopenharmony_ci        isolate, desc_obj, &descriptors[descriptors_index]);
11061cb0ef41Sopenharmony_ci    // 7c iv. ReturnIfAbrupt(desc).
11071cb0ef41Sopenharmony_ci    if (!success) return MaybeHandle<Object>();
11081cb0ef41Sopenharmony_ci    // 7c v. Append the pair (a two element List) consisting of nextKey and
11091cb0ef41Sopenharmony_ci    //       desc to the end of descriptors.
11101cb0ef41Sopenharmony_ci    descriptors[descriptors_index].set_name(next_key);
11111cb0ef41Sopenharmony_ci    descriptors_index++;
11121cb0ef41Sopenharmony_ci  }
11131cb0ef41Sopenharmony_ci  // 8. For each pair from descriptors in list order,
11141cb0ef41Sopenharmony_ci  for (size_t i = 0; i < descriptors_index; ++i) {
11151cb0ef41Sopenharmony_ci    PropertyDescriptor* desc = &descriptors[i];
11161cb0ef41Sopenharmony_ci    // 8a. Let P be the first element of pair.
11171cb0ef41Sopenharmony_ci    // 8b. Let desc be the second element of pair.
11181cb0ef41Sopenharmony_ci    // 8c. Let status be DefinePropertyOrThrow(O, P, desc).
11191cb0ef41Sopenharmony_ci    Maybe<bool> status =
11201cb0ef41Sopenharmony_ci        DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object),
11211cb0ef41Sopenharmony_ci                          desc->name(), desc, Just(kThrowOnError));
11221cb0ef41Sopenharmony_ci    // 8d. ReturnIfAbrupt(status).
11231cb0ef41Sopenharmony_ci    if (status.IsNothing()) return MaybeHandle<Object>();
11241cb0ef41Sopenharmony_ci    CHECK(status.FromJust());
11251cb0ef41Sopenharmony_ci  }
11261cb0ef41Sopenharmony_ci  // 9. Return o.
11271cb0ef41Sopenharmony_ci  return object;
11281cb0ef41Sopenharmony_ci}
11291cb0ef41Sopenharmony_ci
11301cb0ef41Sopenharmony_ci// static
11311cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::DefineOwnProperty(Isolate* isolate,
11321cb0ef41Sopenharmony_ci                                          Handle<JSReceiver> object,
11331cb0ef41Sopenharmony_ci                                          Handle<Object> key,
11341cb0ef41Sopenharmony_ci                                          PropertyDescriptor* desc,
11351cb0ef41Sopenharmony_ci                                          Maybe<ShouldThrow> should_throw) {
11361cb0ef41Sopenharmony_ci  if (object->IsJSArray()) {
11371cb0ef41Sopenharmony_ci    return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object),
11381cb0ef41Sopenharmony_ci                                      key, desc, should_throw);
11391cb0ef41Sopenharmony_ci  }
11401cb0ef41Sopenharmony_ci  if (object->IsJSProxy()) {
11411cb0ef41Sopenharmony_ci    return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object),
11421cb0ef41Sopenharmony_ci                                      key, desc, should_throw);
11431cb0ef41Sopenharmony_ci  }
11441cb0ef41Sopenharmony_ci  if (object->IsJSTypedArray()) {
11451cb0ef41Sopenharmony_ci    return JSTypedArray::DefineOwnProperty(
11461cb0ef41Sopenharmony_ci        isolate, Handle<JSTypedArray>::cast(object), key, desc, should_throw);
11471cb0ef41Sopenharmony_ci  }
11481cb0ef41Sopenharmony_ci  if (object->IsJSModuleNamespace()) {
11491cb0ef41Sopenharmony_ci    return JSModuleNamespace::DefineOwnProperty(
11501cb0ef41Sopenharmony_ci        isolate, Handle<JSModuleNamespace>::cast(object), key, desc,
11511cb0ef41Sopenharmony_ci        should_throw);
11521cb0ef41Sopenharmony_ci  }
11531cb0ef41Sopenharmony_ci
11541cb0ef41Sopenharmony_ci  // OrdinaryDefineOwnProperty, by virtue of calling
11551cb0ef41Sopenharmony_ci  // DefineOwnPropertyIgnoreAttributes, can handle arguments
11561cb0ef41Sopenharmony_ci  // (ES#sec-arguments-exotic-objects-defineownproperty-p-desc).
11571cb0ef41Sopenharmony_ci  return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key,
11581cb0ef41Sopenharmony_ci                                   desc, should_throw);
11591cb0ef41Sopenharmony_ci}
11601cb0ef41Sopenharmony_ci
11611cb0ef41Sopenharmony_ci// static
11621cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::OrdinaryDefineOwnProperty(
11631cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSObject> object, Handle<Object> key,
11641cb0ef41Sopenharmony_ci    PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw) {
11651cb0ef41Sopenharmony_ci  DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey.
11661cb0ef41Sopenharmony_ci  PropertyKey lookup_key(isolate, key);
11671cb0ef41Sopenharmony_ci  return OrdinaryDefineOwnProperty(isolate, object, lookup_key, desc,
11681cb0ef41Sopenharmony_ci                                   should_throw);
11691cb0ef41Sopenharmony_ci}
11701cb0ef41Sopenharmony_ci
11711cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::OrdinaryDefineOwnProperty(
11721cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSObject> object, const PropertyKey& key,
11731cb0ef41Sopenharmony_ci    PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw) {
11741cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, key, LookupIterator::OWN);
11751cb0ef41Sopenharmony_ci
11761cb0ef41Sopenharmony_ci  // Deal with access checks first.
11771cb0ef41Sopenharmony_ci  if (it.state() == LookupIterator::ACCESS_CHECK) {
11781cb0ef41Sopenharmony_ci    if (!it.HasAccess()) {
11791cb0ef41Sopenharmony_ci      isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
11801cb0ef41Sopenharmony_ci      RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
11811cb0ef41Sopenharmony_ci      return Just(true);
11821cb0ef41Sopenharmony_ci    }
11831cb0ef41Sopenharmony_ci    it.Next();
11841cb0ef41Sopenharmony_ci  }
11851cb0ef41Sopenharmony_ci
11861cb0ef41Sopenharmony_ci  return OrdinaryDefineOwnProperty(&it, desc, should_throw);
11871cb0ef41Sopenharmony_ci}
11881cb0ef41Sopenharmony_ci
11891cb0ef41Sopenharmony_cinamespace {
11901cb0ef41Sopenharmony_ci
11911cb0ef41Sopenharmony_ciMaybeHandle<Object> GetPropertyWithInterceptorInternal(
11921cb0ef41Sopenharmony_ci    LookupIterator* it, Handle<InterceptorInfo> interceptor, bool* done) {
11931cb0ef41Sopenharmony_ci  *done = false;
11941cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
11951cb0ef41Sopenharmony_ci  // Make sure that the top context does not change when doing callbacks or
11961cb0ef41Sopenharmony_ci  // interceptor calls.
11971cb0ef41Sopenharmony_ci  AssertNoContextChange ncc(isolate);
11981cb0ef41Sopenharmony_ci
11991cb0ef41Sopenharmony_ci  if (interceptor->getter().IsUndefined(isolate)) {
12001cb0ef41Sopenharmony_ci    return isolate->factory()->undefined_value();
12011cb0ef41Sopenharmony_ci  }
12021cb0ef41Sopenharmony_ci
12031cb0ef41Sopenharmony_ci  Handle<JSObject> holder = it->GetHolder<JSObject>();
12041cb0ef41Sopenharmony_ci  Handle<Object> result;
12051cb0ef41Sopenharmony_ci  Handle<Object> receiver = it->GetReceiver();
12061cb0ef41Sopenharmony_ci  if (!receiver->IsJSReceiver()) {
12071cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION(
12081cb0ef41Sopenharmony_ci        isolate, receiver, Object::ConvertReceiver(isolate, receiver), Object);
12091cb0ef41Sopenharmony_ci  }
12101cb0ef41Sopenharmony_ci  PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
12111cb0ef41Sopenharmony_ci                                 *holder, Just(kDontThrow));
12121cb0ef41Sopenharmony_ci
12131cb0ef41Sopenharmony_ci  if (it->IsElement(*holder)) {
12141cb0ef41Sopenharmony_ci    result = args.CallIndexedGetter(interceptor, it->array_index());
12151cb0ef41Sopenharmony_ci  } else {
12161cb0ef41Sopenharmony_ci    result = args.CallNamedGetter(interceptor, it->name());
12171cb0ef41Sopenharmony_ci  }
12181cb0ef41Sopenharmony_ci
12191cb0ef41Sopenharmony_ci  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
12201cb0ef41Sopenharmony_ci  if (result.is_null()) return isolate->factory()->undefined_value();
12211cb0ef41Sopenharmony_ci  *done = true;
12221cb0ef41Sopenharmony_ci  // Rebox handle before return
12231cb0ef41Sopenharmony_ci  return handle(*result, isolate);
12241cb0ef41Sopenharmony_ci}
12251cb0ef41Sopenharmony_ci
12261cb0ef41Sopenharmony_ciMaybe<PropertyAttributes> GetPropertyAttributesWithInterceptorInternal(
12271cb0ef41Sopenharmony_ci    LookupIterator* it, Handle<InterceptorInfo> interceptor) {
12281cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
12291cb0ef41Sopenharmony_ci  // Make sure that the top context does not change when doing
12301cb0ef41Sopenharmony_ci  // callbacks or interceptor calls.
12311cb0ef41Sopenharmony_ci  AssertNoContextChange ncc(isolate);
12321cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
12331cb0ef41Sopenharmony_ci
12341cb0ef41Sopenharmony_ci  Handle<JSObject> holder = it->GetHolder<JSObject>();
12351cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(!it->IsElement(*holder) && it->name()->IsSymbol(),
12361cb0ef41Sopenharmony_ci                 interceptor->can_intercept_symbols());
12371cb0ef41Sopenharmony_ci  Handle<Object> receiver = it->GetReceiver();
12381cb0ef41Sopenharmony_ci  if (!receiver->IsJSReceiver()) {
12391cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
12401cb0ef41Sopenharmony_ci                                     Object::ConvertReceiver(isolate, receiver),
12411cb0ef41Sopenharmony_ci                                     Nothing<PropertyAttributes>());
12421cb0ef41Sopenharmony_ci  }
12431cb0ef41Sopenharmony_ci  PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
12441cb0ef41Sopenharmony_ci                                 *holder, Just(kDontThrow));
12451cb0ef41Sopenharmony_ci  if (!interceptor->query().IsUndefined(isolate)) {
12461cb0ef41Sopenharmony_ci    Handle<Object> result;
12471cb0ef41Sopenharmony_ci    if (it->IsElement(*holder)) {
12481cb0ef41Sopenharmony_ci      result = args.CallIndexedQuery(interceptor, it->array_index());
12491cb0ef41Sopenharmony_ci    } else {
12501cb0ef41Sopenharmony_ci      result = args.CallNamedQuery(interceptor, it->name());
12511cb0ef41Sopenharmony_ci    }
12521cb0ef41Sopenharmony_ci    if (!result.is_null()) {
12531cb0ef41Sopenharmony_ci      int32_t value;
12541cb0ef41Sopenharmony_ci      CHECK(result->ToInt32(&value));
12551cb0ef41Sopenharmony_ci      DCHECK_IMPLIES((value & ~PropertyAttributes::ALL_ATTRIBUTES_MASK) != 0,
12561cb0ef41Sopenharmony_ci                     value == PropertyAttributes::ABSENT);
12571cb0ef41Sopenharmony_ci      return Just(static_cast<PropertyAttributes>(value));
12581cb0ef41Sopenharmony_ci    }
12591cb0ef41Sopenharmony_ci  } else if (!interceptor->getter().IsUndefined(isolate)) {
12601cb0ef41Sopenharmony_ci    // TODO(verwaest): Use GetPropertyWithInterceptor?
12611cb0ef41Sopenharmony_ci    Handle<Object> result;
12621cb0ef41Sopenharmony_ci    if (it->IsElement(*holder)) {
12631cb0ef41Sopenharmony_ci      result = args.CallIndexedGetter(interceptor, it->array_index());
12641cb0ef41Sopenharmony_ci    } else {
12651cb0ef41Sopenharmony_ci      result = args.CallNamedGetter(interceptor, it->name());
12661cb0ef41Sopenharmony_ci    }
12671cb0ef41Sopenharmony_ci    if (!result.is_null()) return Just(DONT_ENUM);
12681cb0ef41Sopenharmony_ci  }
12691cb0ef41Sopenharmony_ci
12701cb0ef41Sopenharmony_ci  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
12711cb0ef41Sopenharmony_ci  return Just(ABSENT);
12721cb0ef41Sopenharmony_ci}
12731cb0ef41Sopenharmony_ci
12741cb0ef41Sopenharmony_ciMaybe<bool> SetPropertyWithInterceptorInternal(
12751cb0ef41Sopenharmony_ci    LookupIterator* it, Handle<InterceptorInfo> interceptor,
12761cb0ef41Sopenharmony_ci    Maybe<ShouldThrow> should_throw, Handle<Object> value) {
12771cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
12781cb0ef41Sopenharmony_ci  // Make sure that the top context does not change when doing callbacks or
12791cb0ef41Sopenharmony_ci  // interceptor calls.
12801cb0ef41Sopenharmony_ci  AssertNoContextChange ncc(isolate);
12811cb0ef41Sopenharmony_ci
12821cb0ef41Sopenharmony_ci  if (interceptor->setter().IsUndefined(isolate)) return Just(false);
12831cb0ef41Sopenharmony_ci
12841cb0ef41Sopenharmony_ci  Handle<JSObject> holder = it->GetHolder<JSObject>();
12851cb0ef41Sopenharmony_ci  bool result;
12861cb0ef41Sopenharmony_ci  Handle<Object> receiver = it->GetReceiver();
12871cb0ef41Sopenharmony_ci  if (!receiver->IsJSReceiver()) {
12881cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
12891cb0ef41Sopenharmony_ci                                     Object::ConvertReceiver(isolate, receiver),
12901cb0ef41Sopenharmony_ci                                     Nothing<bool>());
12911cb0ef41Sopenharmony_ci  }
12921cb0ef41Sopenharmony_ci  PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
12931cb0ef41Sopenharmony_ci                                 *holder, should_throw);
12941cb0ef41Sopenharmony_ci
12951cb0ef41Sopenharmony_ci  if (it->IsElement(*holder)) {
12961cb0ef41Sopenharmony_ci    // TODO(neis): In the future, we may want to actually return the
12971cb0ef41Sopenharmony_ci    // interceptor's result, which then should be a boolean.
12981cb0ef41Sopenharmony_ci    result = !args.CallIndexedSetter(interceptor, it->array_index(), value)
12991cb0ef41Sopenharmony_ci                  .is_null();
13001cb0ef41Sopenharmony_ci  } else {
13011cb0ef41Sopenharmony_ci    result = !args.CallNamedSetter(interceptor, it->name(), value).is_null();
13021cb0ef41Sopenharmony_ci  }
13031cb0ef41Sopenharmony_ci
13041cb0ef41Sopenharmony_ci  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
13051cb0ef41Sopenharmony_ci  return Just(result);
13061cb0ef41Sopenharmony_ci}
13071cb0ef41Sopenharmony_ci
13081cb0ef41Sopenharmony_ciMaybe<bool> DefinePropertyWithInterceptorInternal(
13091cb0ef41Sopenharmony_ci    LookupIterator* it, Handle<InterceptorInfo> interceptor,
13101cb0ef41Sopenharmony_ci    Maybe<ShouldThrow> should_throw, PropertyDescriptor* desc) {
13111cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
13121cb0ef41Sopenharmony_ci  // Make sure that the top context does not change when doing callbacks or
13131cb0ef41Sopenharmony_ci  // interceptor calls.
13141cb0ef41Sopenharmony_ci  AssertNoContextChange ncc(isolate);
13151cb0ef41Sopenharmony_ci
13161cb0ef41Sopenharmony_ci  if (interceptor->definer().IsUndefined(isolate)) return Just(false);
13171cb0ef41Sopenharmony_ci
13181cb0ef41Sopenharmony_ci  Handle<JSObject> holder = it->GetHolder<JSObject>();
13191cb0ef41Sopenharmony_ci  bool result;
13201cb0ef41Sopenharmony_ci  Handle<Object> receiver = it->GetReceiver();
13211cb0ef41Sopenharmony_ci  if (!receiver->IsJSReceiver()) {
13221cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
13231cb0ef41Sopenharmony_ci                                     Object::ConvertReceiver(isolate, receiver),
13241cb0ef41Sopenharmony_ci                                     Nothing<bool>());
13251cb0ef41Sopenharmony_ci  }
13261cb0ef41Sopenharmony_ci  PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
13271cb0ef41Sopenharmony_ci                                 *holder, should_throw);
13281cb0ef41Sopenharmony_ci
13291cb0ef41Sopenharmony_ci  std::unique_ptr<v8::PropertyDescriptor> descriptor(
13301cb0ef41Sopenharmony_ci      new v8::PropertyDescriptor());
13311cb0ef41Sopenharmony_ci  if (PropertyDescriptor::IsAccessorDescriptor(desc)) {
13321cb0ef41Sopenharmony_ci    descriptor.reset(new v8::PropertyDescriptor(
13331cb0ef41Sopenharmony_ci        v8::Utils::ToLocal(desc->get()), v8::Utils::ToLocal(desc->set())));
13341cb0ef41Sopenharmony_ci  } else if (PropertyDescriptor::IsDataDescriptor(desc)) {
13351cb0ef41Sopenharmony_ci    if (desc->has_writable()) {
13361cb0ef41Sopenharmony_ci      descriptor.reset(new v8::PropertyDescriptor(
13371cb0ef41Sopenharmony_ci          v8::Utils::ToLocal(desc->value()), desc->writable()));
13381cb0ef41Sopenharmony_ci    } else {
13391cb0ef41Sopenharmony_ci      descriptor.reset(
13401cb0ef41Sopenharmony_ci          new v8::PropertyDescriptor(v8::Utils::ToLocal(desc->value())));
13411cb0ef41Sopenharmony_ci    }
13421cb0ef41Sopenharmony_ci  }
13431cb0ef41Sopenharmony_ci  if (desc->has_enumerable()) {
13441cb0ef41Sopenharmony_ci    descriptor->set_enumerable(desc->enumerable());
13451cb0ef41Sopenharmony_ci  }
13461cb0ef41Sopenharmony_ci  if (desc->has_configurable()) {
13471cb0ef41Sopenharmony_ci    descriptor->set_configurable(desc->configurable());
13481cb0ef41Sopenharmony_ci  }
13491cb0ef41Sopenharmony_ci
13501cb0ef41Sopenharmony_ci  if (it->IsElement(*holder)) {
13511cb0ef41Sopenharmony_ci    result =
13521cb0ef41Sopenharmony_ci        !args.CallIndexedDefiner(interceptor, it->array_index(), *descriptor)
13531cb0ef41Sopenharmony_ci             .is_null();
13541cb0ef41Sopenharmony_ci  } else {
13551cb0ef41Sopenharmony_ci    result =
13561cb0ef41Sopenharmony_ci        !args.CallNamedDefiner(interceptor, it->name(), *descriptor).is_null();
13571cb0ef41Sopenharmony_ci  }
13581cb0ef41Sopenharmony_ci
13591cb0ef41Sopenharmony_ci  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
13601cb0ef41Sopenharmony_ci  return Just(result);
13611cb0ef41Sopenharmony_ci}
13621cb0ef41Sopenharmony_ci
13631cb0ef41Sopenharmony_ci}  // namespace
13641cb0ef41Sopenharmony_ci
13651cb0ef41Sopenharmony_ci// ES6 9.1.6.1
13661cb0ef41Sopenharmony_ci// static
13671cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::OrdinaryDefineOwnProperty(
13681cb0ef41Sopenharmony_ci    LookupIterator* it, PropertyDescriptor* desc,
13691cb0ef41Sopenharmony_ci    Maybe<ShouldThrow> should_throw) {
13701cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
13711cb0ef41Sopenharmony_ci  // 1. Let current be O.[[GetOwnProperty]](P).
13721cb0ef41Sopenharmony_ci  // 2. ReturnIfAbrupt(current).
13731cb0ef41Sopenharmony_ci  PropertyDescriptor current;
13741cb0ef41Sopenharmony_ci  MAYBE_RETURN(GetOwnPropertyDescriptor(it, &current), Nothing<bool>());
13751cb0ef41Sopenharmony_ci
13761cb0ef41Sopenharmony_ci  it->Restart();
13771cb0ef41Sopenharmony_ci  // Handle interceptor
13781cb0ef41Sopenharmony_ci  for (; it->IsFound(); it->Next()) {
13791cb0ef41Sopenharmony_ci    if (it->state() == LookupIterator::INTERCEPTOR) {
13801cb0ef41Sopenharmony_ci      if (it->HolderIsReceiverOrHiddenPrototype()) {
13811cb0ef41Sopenharmony_ci        Maybe<bool> result = DefinePropertyWithInterceptorInternal(
13821cb0ef41Sopenharmony_ci            it, it->GetInterceptor(), should_throw, desc);
13831cb0ef41Sopenharmony_ci        if (result.IsNothing() || result.FromJust()) {
13841cb0ef41Sopenharmony_ci          return result;
13851cb0ef41Sopenharmony_ci        }
13861cb0ef41Sopenharmony_ci      }
13871cb0ef41Sopenharmony_ci    }
13881cb0ef41Sopenharmony_ci  }
13891cb0ef41Sopenharmony_ci
13901cb0ef41Sopenharmony_ci  // TODO(jkummerow/verwaest): It would be nice if we didn't have to reset
13911cb0ef41Sopenharmony_ci  // the iterator every time. Currently, the reasons why we need it are:
13921cb0ef41Sopenharmony_ci  // - handle interceptors correctly
13931cb0ef41Sopenharmony_ci  // - handle accessors correctly (which might change the holder's map)
13941cb0ef41Sopenharmony_ci  it->Restart();
13951cb0ef41Sopenharmony_ci  // 3. Let extensible be the value of the [[Extensible]] internal slot of O.
13961cb0ef41Sopenharmony_ci  Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
13971cb0ef41Sopenharmony_ci  bool extensible = JSObject::IsExtensible(object);
13981cb0ef41Sopenharmony_ci
13991cb0ef41Sopenharmony_ci  return ValidateAndApplyPropertyDescriptor(
14001cb0ef41Sopenharmony_ci      isolate, it, extensible, desc, &current, should_throw, Handle<Name>());
14011cb0ef41Sopenharmony_ci}
14021cb0ef41Sopenharmony_ci
14031cb0ef41Sopenharmony_ci// ES6 9.1.6.2
14041cb0ef41Sopenharmony_ci// static
14051cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::IsCompatiblePropertyDescriptor(
14061cb0ef41Sopenharmony_ci    Isolate* isolate, bool extensible, PropertyDescriptor* desc,
14071cb0ef41Sopenharmony_ci    PropertyDescriptor* current, Handle<Name> property_name,
14081cb0ef41Sopenharmony_ci    Maybe<ShouldThrow> should_throw) {
14091cb0ef41Sopenharmony_ci  // 1. Return ValidateAndApplyPropertyDescriptor(undefined, undefined,
14101cb0ef41Sopenharmony_ci  //    Extensible, Desc, Current).
14111cb0ef41Sopenharmony_ci  return ValidateAndApplyPropertyDescriptor(
14121cb0ef41Sopenharmony_ci      isolate, nullptr, extensible, desc, current, should_throw, property_name);
14131cb0ef41Sopenharmony_ci}
14141cb0ef41Sopenharmony_ci
14151cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-validateandapplypropertydescriptor
14161cb0ef41Sopenharmony_ci// static
14171cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
14181cb0ef41Sopenharmony_ci    Isolate* isolate, LookupIterator* it, bool extensible,
14191cb0ef41Sopenharmony_ci    PropertyDescriptor* desc, PropertyDescriptor* current,
14201cb0ef41Sopenharmony_ci    Maybe<ShouldThrow> should_throw, Handle<Name> property_name) {
14211cb0ef41Sopenharmony_ci  // We either need a LookupIterator, or a property name.
14221cb0ef41Sopenharmony_ci  DCHECK((it == nullptr) != property_name.is_null());
14231cb0ef41Sopenharmony_ci  Handle<JSObject> object;
14241cb0ef41Sopenharmony_ci  if (it != nullptr) object = Handle<JSObject>::cast(it->GetReceiver());
14251cb0ef41Sopenharmony_ci  bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc);
14261cb0ef41Sopenharmony_ci  bool desc_is_accessor_descriptor =
14271cb0ef41Sopenharmony_ci      PropertyDescriptor::IsAccessorDescriptor(desc);
14281cb0ef41Sopenharmony_ci  bool desc_is_generic_descriptor =
14291cb0ef41Sopenharmony_ci      PropertyDescriptor::IsGenericDescriptor(desc);
14301cb0ef41Sopenharmony_ci  // 1. (Assert)
14311cb0ef41Sopenharmony_ci  // 2. If current is undefined, then
14321cb0ef41Sopenharmony_ci  if (current->is_empty()) {
14331cb0ef41Sopenharmony_ci    // 2a. If extensible is false, return false.
14341cb0ef41Sopenharmony_ci    if (!extensible) {
14351cb0ef41Sopenharmony_ci      RETURN_FAILURE(
14361cb0ef41Sopenharmony_ci          isolate, GetShouldThrow(isolate, should_throw),
14371cb0ef41Sopenharmony_ci          NewTypeError(MessageTemplate::kDefineDisallowed,
14381cb0ef41Sopenharmony_ci                       it != nullptr ? it->GetName() : property_name));
14391cb0ef41Sopenharmony_ci    }
14401cb0ef41Sopenharmony_ci    // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then:
14411cb0ef41Sopenharmony_ci    // (This is equivalent to !IsAccessorDescriptor(desc).)
14421cb0ef41Sopenharmony_ci    DCHECK_EQ(desc_is_generic_descriptor || desc_is_data_descriptor,
14431cb0ef41Sopenharmony_ci              !desc_is_accessor_descriptor);
14441cb0ef41Sopenharmony_ci    if (!desc_is_accessor_descriptor) {
14451cb0ef41Sopenharmony_ci      // 2c i. If O is not undefined, create an own data property named P of
14461cb0ef41Sopenharmony_ci      // object O whose [[Value]], [[Writable]], [[Enumerable]] and
14471cb0ef41Sopenharmony_ci      // [[Configurable]] attribute values are described by Desc. If the value
14481cb0ef41Sopenharmony_ci      // of an attribute field of Desc is absent, the attribute of the newly
14491cb0ef41Sopenharmony_ci      // created property is set to its default value.
14501cb0ef41Sopenharmony_ci      if (it != nullptr) {
14511cb0ef41Sopenharmony_ci        if (!desc->has_writable()) desc->set_writable(false);
14521cb0ef41Sopenharmony_ci        if (!desc->has_enumerable()) desc->set_enumerable(false);
14531cb0ef41Sopenharmony_ci        if (!desc->has_configurable()) desc->set_configurable(false);
14541cb0ef41Sopenharmony_ci        Handle<Object> value(
14551cb0ef41Sopenharmony_ci            desc->has_value()
14561cb0ef41Sopenharmony_ci                ? desc->value()
14571cb0ef41Sopenharmony_ci                : Handle<Object>::cast(isolate->factory()->undefined_value()));
14581cb0ef41Sopenharmony_ci        MaybeHandle<Object> result =
14591cb0ef41Sopenharmony_ci            JSObject::DefineOwnPropertyIgnoreAttributes(it, value,
14601cb0ef41Sopenharmony_ci                                                        desc->ToAttributes());
14611cb0ef41Sopenharmony_ci        if (result.is_null()) return Nothing<bool>();
14621cb0ef41Sopenharmony_ci      }
14631cb0ef41Sopenharmony_ci    } else {
14641cb0ef41Sopenharmony_ci      // 2d. Else Desc must be an accessor Property Descriptor,
14651cb0ef41Sopenharmony_ci      DCHECK(desc_is_accessor_descriptor);
14661cb0ef41Sopenharmony_ci      // 2d i. If O is not undefined, create an own accessor property named P
14671cb0ef41Sopenharmony_ci      // of object O whose [[Get]], [[Set]], [[Enumerable]] and
14681cb0ef41Sopenharmony_ci      // [[Configurable]] attribute values are described by Desc. If the value
14691cb0ef41Sopenharmony_ci      // of an attribute field of Desc is absent, the attribute of the newly
14701cb0ef41Sopenharmony_ci      // created property is set to its default value.
14711cb0ef41Sopenharmony_ci      if (it != nullptr) {
14721cb0ef41Sopenharmony_ci        if (!desc->has_enumerable()) desc->set_enumerable(false);
14731cb0ef41Sopenharmony_ci        if (!desc->has_configurable()) desc->set_configurable(false);
14741cb0ef41Sopenharmony_ci        Handle<Object> getter(
14751cb0ef41Sopenharmony_ci            desc->has_get()
14761cb0ef41Sopenharmony_ci                ? desc->get()
14771cb0ef41Sopenharmony_ci                : Handle<Object>::cast(isolate->factory()->null_value()));
14781cb0ef41Sopenharmony_ci        Handle<Object> setter(
14791cb0ef41Sopenharmony_ci            desc->has_set()
14801cb0ef41Sopenharmony_ci                ? desc->set()
14811cb0ef41Sopenharmony_ci                : Handle<Object>::cast(isolate->factory()->null_value()));
14821cb0ef41Sopenharmony_ci        MaybeHandle<Object> result =
14831cb0ef41Sopenharmony_ci            JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes());
14841cb0ef41Sopenharmony_ci        if (result.is_null()) return Nothing<bool>();
14851cb0ef41Sopenharmony_ci      }
14861cb0ef41Sopenharmony_ci    }
14871cb0ef41Sopenharmony_ci    // 2e. Return true.
14881cb0ef41Sopenharmony_ci    return Just(true);
14891cb0ef41Sopenharmony_ci  }
14901cb0ef41Sopenharmony_ci  // 3. If every field in Desc is absent, return true. (This also has a shortcut
14911cb0ef41Sopenharmony_ci  // not in the spec: if every field value matches the current value, return.)
14921cb0ef41Sopenharmony_ci  if ((!desc->has_enumerable() ||
14931cb0ef41Sopenharmony_ci       desc->enumerable() == current->enumerable()) &&
14941cb0ef41Sopenharmony_ci      (!desc->has_configurable() ||
14951cb0ef41Sopenharmony_ci       desc->configurable() == current->configurable()) &&
14961cb0ef41Sopenharmony_ci      (!desc->has_value() ||
14971cb0ef41Sopenharmony_ci       (current->has_value() && current->value()->SameValue(*desc->value()))) &&
14981cb0ef41Sopenharmony_ci      (!desc->has_writable() ||
14991cb0ef41Sopenharmony_ci       (current->has_writable() && current->writable() == desc->writable())) &&
15001cb0ef41Sopenharmony_ci      (!desc->has_get() ||
15011cb0ef41Sopenharmony_ci       (current->has_get() && current->get()->SameValue(*desc->get()))) &&
15021cb0ef41Sopenharmony_ci      (!desc->has_set() ||
15031cb0ef41Sopenharmony_ci       (current->has_set() && current->set()->SameValue(*desc->set())))) {
15041cb0ef41Sopenharmony_ci    return Just(true);
15051cb0ef41Sopenharmony_ci  }
15061cb0ef41Sopenharmony_ci  // 4. If current.[[Configurable]] is false, then
15071cb0ef41Sopenharmony_ci  if (!current->configurable()) {
15081cb0ef41Sopenharmony_ci    // 4a. If Desc.[[Configurable]] is present and its value is true, return
15091cb0ef41Sopenharmony_ci    // false.
15101cb0ef41Sopenharmony_ci    if (desc->has_configurable() && desc->configurable()) {
15111cb0ef41Sopenharmony_ci      RETURN_FAILURE(
15121cb0ef41Sopenharmony_ci          isolate, GetShouldThrow(isolate, should_throw),
15131cb0ef41Sopenharmony_ci          NewTypeError(MessageTemplate::kRedefineDisallowed,
15141cb0ef41Sopenharmony_ci                       it != nullptr ? it->GetName() : property_name));
15151cb0ef41Sopenharmony_ci    }
15161cb0ef41Sopenharmony_ci    // 4b. If Desc.[[Enumerable]] is present and
15171cb0ef41Sopenharmony_ci    // ! SameValue(Desc.[[Enumerable]], current.[[Enumerable]]) is false, return
15181cb0ef41Sopenharmony_ci    // false.
15191cb0ef41Sopenharmony_ci    if (desc->has_enumerable() && desc->enumerable() != current->enumerable()) {
15201cb0ef41Sopenharmony_ci      RETURN_FAILURE(
15211cb0ef41Sopenharmony_ci          isolate, GetShouldThrow(isolate, should_throw),
15221cb0ef41Sopenharmony_ci          NewTypeError(MessageTemplate::kRedefineDisallowed,
15231cb0ef41Sopenharmony_ci                       it != nullptr ? it->GetName() : property_name));
15241cb0ef41Sopenharmony_ci    }
15251cb0ef41Sopenharmony_ci  }
15261cb0ef41Sopenharmony_ci
15271cb0ef41Sopenharmony_ci  bool current_is_data_descriptor =
15281cb0ef41Sopenharmony_ci      PropertyDescriptor::IsDataDescriptor(current);
15291cb0ef41Sopenharmony_ci  // 5. If ! IsGenericDescriptor(Desc) is true, no further validation is
15301cb0ef41Sopenharmony_ci  // required.
15311cb0ef41Sopenharmony_ci  if (desc_is_generic_descriptor) {
15321cb0ef41Sopenharmony_ci    // Nothing to see here.
15331cb0ef41Sopenharmony_ci
15341cb0ef41Sopenharmony_ci    // 6. Else if ! SameValue(!IsDataDescriptor(current),
15351cb0ef41Sopenharmony_ci    // !IsDataDescriptor(Desc)) is false, the
15361cb0ef41Sopenharmony_ci  } else if (current_is_data_descriptor != desc_is_data_descriptor) {
15371cb0ef41Sopenharmony_ci    // 6a. If current.[[Configurable]] is false, return false.
15381cb0ef41Sopenharmony_ci    if (!current->configurable()) {
15391cb0ef41Sopenharmony_ci      RETURN_FAILURE(
15401cb0ef41Sopenharmony_ci          isolate, GetShouldThrow(isolate, should_throw),
15411cb0ef41Sopenharmony_ci          NewTypeError(MessageTemplate::kRedefineDisallowed,
15421cb0ef41Sopenharmony_ci                       it != nullptr ? it->GetName() : property_name));
15431cb0ef41Sopenharmony_ci    }
15441cb0ef41Sopenharmony_ci    // 6b. If IsDataDescriptor(current) is true, then:
15451cb0ef41Sopenharmony_ci    if (current_is_data_descriptor) {
15461cb0ef41Sopenharmony_ci      // 6b i. If O is not undefined, convert the property named P of object O
15471cb0ef41Sopenharmony_ci      // from a data property to an accessor property. Preserve the existing
15481cb0ef41Sopenharmony_ci      // values of the converted property's [[Configurable]] and [[Enumerable]]
15491cb0ef41Sopenharmony_ci      // attributes and set the rest of the property's attributes to their
15501cb0ef41Sopenharmony_ci      // default values.
15511cb0ef41Sopenharmony_ci      // --> Folded into step 9
15521cb0ef41Sopenharmony_ci    } else {
15531cb0ef41Sopenharmony_ci      // 6c i. If O is not undefined, convert the property named P of object O
15541cb0ef41Sopenharmony_ci      // from an accessor property to a data property. Preserve the existing
15551cb0ef41Sopenharmony_ci      // values of the converted property’s [[Configurable]] and [[Enumerable]]
15561cb0ef41Sopenharmony_ci      // attributes and set the rest of the property’s attributes to their
15571cb0ef41Sopenharmony_ci      // default values.
15581cb0ef41Sopenharmony_ci      // --> Folded into step 9
15591cb0ef41Sopenharmony_ci    }
15601cb0ef41Sopenharmony_ci
15611cb0ef41Sopenharmony_ci    // 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both
15621cb0ef41Sopenharmony_ci    // true, then:
15631cb0ef41Sopenharmony_ci  } else if (current_is_data_descriptor && desc_is_data_descriptor) {
15641cb0ef41Sopenharmony_ci    // 7a. If current.[[Configurable]] is false and current.[[Writable]] is
15651cb0ef41Sopenharmony_ci    // false, then
15661cb0ef41Sopenharmony_ci    if (!current->configurable() && !current->writable()) {
15671cb0ef41Sopenharmony_ci      // 7a i. If Desc.[[Writable]] is present and Desc.[[Writable]] is true,
15681cb0ef41Sopenharmony_ci      // return false.
15691cb0ef41Sopenharmony_ci      if (desc->has_writable() && desc->writable()) {
15701cb0ef41Sopenharmony_ci        RETURN_FAILURE(
15711cb0ef41Sopenharmony_ci            isolate, GetShouldThrow(isolate, should_throw),
15721cb0ef41Sopenharmony_ci            NewTypeError(MessageTemplate::kRedefineDisallowed,
15731cb0ef41Sopenharmony_ci                         it != nullptr ? it->GetName() : property_name));
15741cb0ef41Sopenharmony_ci      }
15751cb0ef41Sopenharmony_ci      // 7a ii. If Desc.[[Value]] is present and SameValue(Desc.[[Value]],
15761cb0ef41Sopenharmony_ci      // current.[[Value]]) is false, return false.
15771cb0ef41Sopenharmony_ci      if (desc->has_value() && !desc->value()->SameValue(*current->value())) {
15781cb0ef41Sopenharmony_ci        RETURN_FAILURE(
15791cb0ef41Sopenharmony_ci            isolate, GetShouldThrow(isolate, should_throw),
15801cb0ef41Sopenharmony_ci            NewTypeError(MessageTemplate::kRedefineDisallowed,
15811cb0ef41Sopenharmony_ci                         it != nullptr ? it->GetName() : property_name));
15821cb0ef41Sopenharmony_ci      }
15831cb0ef41Sopenharmony_ci    }
15841cb0ef41Sopenharmony_ci  } else {
15851cb0ef41Sopenharmony_ci    // 8. Else,
15861cb0ef41Sopenharmony_ci    // 8a. Assert: ! IsAccessorDescriptor(current) and
15871cb0ef41Sopenharmony_ci    // ! IsAccessorDescriptor(Desc) are both true.
15881cb0ef41Sopenharmony_ci    DCHECK(PropertyDescriptor::IsAccessorDescriptor(current) &&
15891cb0ef41Sopenharmony_ci           desc_is_accessor_descriptor);
15901cb0ef41Sopenharmony_ci    // 8b. If current.[[Configurable]] is false, then:
15911cb0ef41Sopenharmony_ci    if (!current->configurable()) {
15921cb0ef41Sopenharmony_ci      // 8a i. If Desc.[[Set]] is present and SameValue(Desc.[[Set]],
15931cb0ef41Sopenharmony_ci      // current.[[Set]]) is false, return false.
15941cb0ef41Sopenharmony_ci      if (desc->has_set() && !desc->set()->SameValue(*current->set())) {
15951cb0ef41Sopenharmony_ci        RETURN_FAILURE(
15961cb0ef41Sopenharmony_ci            isolate, GetShouldThrow(isolate, should_throw),
15971cb0ef41Sopenharmony_ci            NewTypeError(MessageTemplate::kRedefineDisallowed,
15981cb0ef41Sopenharmony_ci                         it != nullptr ? it->GetName() : property_name));
15991cb0ef41Sopenharmony_ci      }
16001cb0ef41Sopenharmony_ci      // 8a ii. If Desc.[[Get]] is present and SameValue(Desc.[[Get]],
16011cb0ef41Sopenharmony_ci      // current.[[Get]]) is false, return false.
16021cb0ef41Sopenharmony_ci      if (desc->has_get() && !desc->get()->SameValue(*current->get())) {
16031cb0ef41Sopenharmony_ci        RETURN_FAILURE(
16041cb0ef41Sopenharmony_ci            isolate, GetShouldThrow(isolate, should_throw),
16051cb0ef41Sopenharmony_ci            NewTypeError(MessageTemplate::kRedefineDisallowed,
16061cb0ef41Sopenharmony_ci                         it != nullptr ? it->GetName() : property_name));
16071cb0ef41Sopenharmony_ci      }
16081cb0ef41Sopenharmony_ci    }
16091cb0ef41Sopenharmony_ci  }
16101cb0ef41Sopenharmony_ci
16111cb0ef41Sopenharmony_ci  // 9. If O is not undefined, then:
16121cb0ef41Sopenharmony_ci  if (it != nullptr) {
16131cb0ef41Sopenharmony_ci    // 9a. For each field of Desc that is present, set the corresponding
16141cb0ef41Sopenharmony_ci    // attribute of the property named P of object O to the value of the field.
16151cb0ef41Sopenharmony_ci    PropertyAttributes attrs = NONE;
16161cb0ef41Sopenharmony_ci
16171cb0ef41Sopenharmony_ci    if (desc->has_enumerable()) {
16181cb0ef41Sopenharmony_ci      attrs = static_cast<PropertyAttributes>(
16191cb0ef41Sopenharmony_ci          attrs | (desc->enumerable() ? NONE : DONT_ENUM));
16201cb0ef41Sopenharmony_ci    } else {
16211cb0ef41Sopenharmony_ci      attrs = static_cast<PropertyAttributes>(
16221cb0ef41Sopenharmony_ci          attrs | (current->enumerable() ? NONE : DONT_ENUM));
16231cb0ef41Sopenharmony_ci    }
16241cb0ef41Sopenharmony_ci    if (desc->has_configurable()) {
16251cb0ef41Sopenharmony_ci      attrs = static_cast<PropertyAttributes>(
16261cb0ef41Sopenharmony_ci          attrs | (desc->configurable() ? NONE : DONT_DELETE));
16271cb0ef41Sopenharmony_ci    } else {
16281cb0ef41Sopenharmony_ci      attrs = static_cast<PropertyAttributes>(
16291cb0ef41Sopenharmony_ci          attrs | (current->configurable() ? NONE : DONT_DELETE));
16301cb0ef41Sopenharmony_ci    }
16311cb0ef41Sopenharmony_ci    if (desc_is_data_descriptor ||
16321cb0ef41Sopenharmony_ci        (desc_is_generic_descriptor && current_is_data_descriptor)) {
16331cb0ef41Sopenharmony_ci      if (desc->has_writable()) {
16341cb0ef41Sopenharmony_ci        attrs = static_cast<PropertyAttributes>(
16351cb0ef41Sopenharmony_ci            attrs | (desc->writable() ? NONE : READ_ONLY));
16361cb0ef41Sopenharmony_ci      } else {
16371cb0ef41Sopenharmony_ci        attrs = static_cast<PropertyAttributes>(
16381cb0ef41Sopenharmony_ci            attrs | (current->writable() ? NONE : READ_ONLY));
16391cb0ef41Sopenharmony_ci      }
16401cb0ef41Sopenharmony_ci      Handle<Object> value(
16411cb0ef41Sopenharmony_ci          desc->has_value() ? desc->value()
16421cb0ef41Sopenharmony_ci                            : current->has_value()
16431cb0ef41Sopenharmony_ci                                  ? current->value()
16441cb0ef41Sopenharmony_ci                                  : Handle<Object>::cast(
16451cb0ef41Sopenharmony_ci                                        isolate->factory()->undefined_value()));
16461cb0ef41Sopenharmony_ci      return JSObject::DefineOwnPropertyIgnoreAttributes(it, value, attrs,
16471cb0ef41Sopenharmony_ci                                                         should_throw);
16481cb0ef41Sopenharmony_ci    } else {
16491cb0ef41Sopenharmony_ci      DCHECK(desc_is_accessor_descriptor ||
16501cb0ef41Sopenharmony_ci             (desc_is_generic_descriptor &&
16511cb0ef41Sopenharmony_ci              PropertyDescriptor::IsAccessorDescriptor(current)));
16521cb0ef41Sopenharmony_ci      Handle<Object> getter(
16531cb0ef41Sopenharmony_ci          desc->has_get()
16541cb0ef41Sopenharmony_ci              ? desc->get()
16551cb0ef41Sopenharmony_ci              : current->has_get()
16561cb0ef41Sopenharmony_ci                    ? current->get()
16571cb0ef41Sopenharmony_ci                    : Handle<Object>::cast(isolate->factory()->null_value()));
16581cb0ef41Sopenharmony_ci      Handle<Object> setter(
16591cb0ef41Sopenharmony_ci          desc->has_set()
16601cb0ef41Sopenharmony_ci              ? desc->set()
16611cb0ef41Sopenharmony_ci              : current->has_set()
16621cb0ef41Sopenharmony_ci                    ? current->set()
16631cb0ef41Sopenharmony_ci                    : Handle<Object>::cast(isolate->factory()->null_value()));
16641cb0ef41Sopenharmony_ci      MaybeHandle<Object> result =
16651cb0ef41Sopenharmony_ci          JSObject::DefineAccessor(it, getter, setter, attrs);
16661cb0ef41Sopenharmony_ci      if (result.is_null()) return Nothing<bool>();
16671cb0ef41Sopenharmony_ci    }
16681cb0ef41Sopenharmony_ci  }
16691cb0ef41Sopenharmony_ci
16701cb0ef41Sopenharmony_ci  // 10. Return true.
16711cb0ef41Sopenharmony_ci  return Just(true);
16721cb0ef41Sopenharmony_ci}
16731cb0ef41Sopenharmony_ci
16741cb0ef41Sopenharmony_ci// static
16751cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::CreateDataProperty(Isolate* isolate,
16761cb0ef41Sopenharmony_ci                                           Handle<JSReceiver> object,
16771cb0ef41Sopenharmony_ci                                           Handle<Name> key,
16781cb0ef41Sopenharmony_ci                                           Handle<Object> value,
16791cb0ef41Sopenharmony_ci                                           Maybe<ShouldThrow> should_throw) {
16801cb0ef41Sopenharmony_ci  PropertyKey lookup_key(isolate, key);
16811cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, lookup_key, LookupIterator::OWN);
16821cb0ef41Sopenharmony_ci  return CreateDataProperty(&it, value, should_throw);
16831cb0ef41Sopenharmony_ci}
16841cb0ef41Sopenharmony_ci
16851cb0ef41Sopenharmony_ci// static
16861cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::CreateDataProperty(LookupIterator* it,
16871cb0ef41Sopenharmony_ci                                           Handle<Object> value,
16881cb0ef41Sopenharmony_ci                                           Maybe<ShouldThrow> should_throw) {
16891cb0ef41Sopenharmony_ci  DCHECK(!it->check_prototype_chain());
16901cb0ef41Sopenharmony_ci  Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
16911cb0ef41Sopenharmony_ci  Isolate* isolate = receiver->GetIsolate();
16921cb0ef41Sopenharmony_ci
16931cb0ef41Sopenharmony_ci  if (receiver->IsJSObject()) {
16941cb0ef41Sopenharmony_ci    return JSObject::CreateDataProperty(it, value, should_throw);  // Shortcut.
16951cb0ef41Sopenharmony_ci  }
16961cb0ef41Sopenharmony_ci
16971cb0ef41Sopenharmony_ci  PropertyDescriptor new_desc;
16981cb0ef41Sopenharmony_ci  new_desc.set_value(value);
16991cb0ef41Sopenharmony_ci  new_desc.set_writable(true);
17001cb0ef41Sopenharmony_ci  new_desc.set_enumerable(true);
17011cb0ef41Sopenharmony_ci  new_desc.set_configurable(true);
17021cb0ef41Sopenharmony_ci
17031cb0ef41Sopenharmony_ci  return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
17041cb0ef41Sopenharmony_ci                                       &new_desc, should_throw);
17051cb0ef41Sopenharmony_ci}
17061cb0ef41Sopenharmony_ci
17071cb0ef41Sopenharmony_ci// static
17081cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::AddPrivateField(LookupIterator* it,
17091cb0ef41Sopenharmony_ci                                        Handle<Object> value,
17101cb0ef41Sopenharmony_ci                                        Maybe<ShouldThrow> should_throw) {
17111cb0ef41Sopenharmony_ci  Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
17121cb0ef41Sopenharmony_ci  Isolate* isolate = receiver->GetIsolate();
17131cb0ef41Sopenharmony_ci  DCHECK(it->GetName()->IsPrivateName());
17141cb0ef41Sopenharmony_ci  Handle<Symbol> symbol = Handle<Symbol>::cast(it->GetName());
17151cb0ef41Sopenharmony_ci
17161cb0ef41Sopenharmony_ci  switch (it->state()) {
17171cb0ef41Sopenharmony_ci    case LookupIterator::JSPROXY: {
17181cb0ef41Sopenharmony_ci      PropertyDescriptor new_desc;
17191cb0ef41Sopenharmony_ci      new_desc.set_value(value);
17201cb0ef41Sopenharmony_ci      new_desc.set_writable(true);
17211cb0ef41Sopenharmony_ci      new_desc.set_enumerable(true);
17221cb0ef41Sopenharmony_ci      new_desc.set_configurable(true);
17231cb0ef41Sopenharmony_ci      return JSProxy::SetPrivateSymbol(isolate, Handle<JSProxy>::cast(receiver),
17241cb0ef41Sopenharmony_ci                                       symbol, &new_desc, should_throw);
17251cb0ef41Sopenharmony_ci    }
17261cb0ef41Sopenharmony_ci    case LookupIterator::DATA:
17271cb0ef41Sopenharmony_ci    case LookupIterator::INTERCEPTOR:
17281cb0ef41Sopenharmony_ci    case LookupIterator::ACCESSOR:
17291cb0ef41Sopenharmony_ci    case LookupIterator::INTEGER_INDEXED_EXOTIC:
17301cb0ef41Sopenharmony_ci      UNREACHABLE();
17311cb0ef41Sopenharmony_ci
17321cb0ef41Sopenharmony_ci    case LookupIterator::ACCESS_CHECK: {
17331cb0ef41Sopenharmony_ci      if (!it->HasAccess()) {
17341cb0ef41Sopenharmony_ci        it->isolate()->ReportFailedAccessCheck(it->GetHolder<JSObject>());
17351cb0ef41Sopenharmony_ci        RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
17361cb0ef41Sopenharmony_ci        return Just(true);
17371cb0ef41Sopenharmony_ci      }
17381cb0ef41Sopenharmony_ci      break;
17391cb0ef41Sopenharmony_ci    }
17401cb0ef41Sopenharmony_ci
17411cb0ef41Sopenharmony_ci    case LookupIterator::TRANSITION:
17421cb0ef41Sopenharmony_ci    case LookupIterator::NOT_FOUND:
17431cb0ef41Sopenharmony_ci      break;
17441cb0ef41Sopenharmony_ci  }
17451cb0ef41Sopenharmony_ci
17461cb0ef41Sopenharmony_ci  return Object::TransitionAndWriteDataProperty(it, value, NONE, should_throw,
17471cb0ef41Sopenharmony_ci                                                StoreOrigin::kMaybeKeyed);
17481cb0ef41Sopenharmony_ci}
17491cb0ef41Sopenharmony_ci
17501cb0ef41Sopenharmony_ci// static
17511cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate,
17521cb0ef41Sopenharmony_ci                                                 Handle<JSReceiver> object,
17531cb0ef41Sopenharmony_ci                                                 Handle<Object> key,
17541cb0ef41Sopenharmony_ci                                                 PropertyDescriptor* desc) {
17551cb0ef41Sopenharmony_ci  DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey.
17561cb0ef41Sopenharmony_ci  PropertyKey lookup_key(isolate, key);
17571cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, lookup_key, LookupIterator::OWN);
17581cb0ef41Sopenharmony_ci  return GetOwnPropertyDescriptor(&it, desc);
17591cb0ef41Sopenharmony_ci}
17601cb0ef41Sopenharmony_ci
17611cb0ef41Sopenharmony_cinamespace {
17621cb0ef41Sopenharmony_ci
17631cb0ef41Sopenharmony_ciMaybe<bool> GetPropertyDescriptorWithInterceptor(LookupIterator* it,
17641cb0ef41Sopenharmony_ci                                                 PropertyDescriptor* desc) {
17651cb0ef41Sopenharmony_ci  Handle<InterceptorInfo> interceptor;
17661cb0ef41Sopenharmony_ci
17671cb0ef41Sopenharmony_ci  if (it->state() == LookupIterator::ACCESS_CHECK) {
17681cb0ef41Sopenharmony_ci    if (it->HasAccess()) {
17691cb0ef41Sopenharmony_ci      it->Next();
17701cb0ef41Sopenharmony_ci    } else {
17711cb0ef41Sopenharmony_ci      interceptor = it->GetInterceptorForFailedAccessCheck();
17721cb0ef41Sopenharmony_ci      if (interceptor.is_null() &&
17731cb0ef41Sopenharmony_ci          (!JSObject::AllCanRead(it) ||
17741cb0ef41Sopenharmony_ci           it->state() != LookupIterator::INTERCEPTOR)) {
17751cb0ef41Sopenharmony_ci        it->Restart();
17761cb0ef41Sopenharmony_ci        return Just(false);
17771cb0ef41Sopenharmony_ci      }
17781cb0ef41Sopenharmony_ci    }
17791cb0ef41Sopenharmony_ci  }
17801cb0ef41Sopenharmony_ci
17811cb0ef41Sopenharmony_ci  if (it->state() == LookupIterator::INTERCEPTOR) {
17821cb0ef41Sopenharmony_ci    interceptor = it->GetInterceptor();
17831cb0ef41Sopenharmony_ci  }
17841cb0ef41Sopenharmony_ci  if (interceptor.is_null()) return Just(false);
17851cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
17861cb0ef41Sopenharmony_ci  if (interceptor->descriptor().IsUndefined(isolate)) return Just(false);
17871cb0ef41Sopenharmony_ci
17881cb0ef41Sopenharmony_ci  Handle<Object> result;
17891cb0ef41Sopenharmony_ci  Handle<JSObject> holder = it->GetHolder<JSObject>();
17901cb0ef41Sopenharmony_ci
17911cb0ef41Sopenharmony_ci  Handle<Object> receiver = it->GetReceiver();
17921cb0ef41Sopenharmony_ci  if (!receiver->IsJSReceiver()) {
17931cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
17941cb0ef41Sopenharmony_ci                                     Object::ConvertReceiver(isolate, receiver),
17951cb0ef41Sopenharmony_ci                                     Nothing<bool>());
17961cb0ef41Sopenharmony_ci  }
17971cb0ef41Sopenharmony_ci
17981cb0ef41Sopenharmony_ci  PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
17991cb0ef41Sopenharmony_ci                                 *holder, Just(kDontThrow));
18001cb0ef41Sopenharmony_ci  if (it->IsElement(*holder)) {
18011cb0ef41Sopenharmony_ci    result = args.CallIndexedDescriptor(interceptor, it->array_index());
18021cb0ef41Sopenharmony_ci  } else {
18031cb0ef41Sopenharmony_ci    result = args.CallNamedDescriptor(interceptor, it->name());
18041cb0ef41Sopenharmony_ci  }
18051cb0ef41Sopenharmony_ci  // An exception was thrown in the interceptor. Propagate.
18061cb0ef41Sopenharmony_ci  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
18071cb0ef41Sopenharmony_ci  if (!result.is_null()) {
18081cb0ef41Sopenharmony_ci    // Request successfully intercepted, try to set the property
18091cb0ef41Sopenharmony_ci    // descriptor.
18101cb0ef41Sopenharmony_ci    Utils::ApiCheck(
18111cb0ef41Sopenharmony_ci        PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
18121cb0ef41Sopenharmony_ci        it->IsElement(*holder) ? "v8::IndexedPropertyDescriptorCallback"
18131cb0ef41Sopenharmony_ci                               : "v8::NamedPropertyDescriptorCallback",
18141cb0ef41Sopenharmony_ci        "Invalid property descriptor.");
18151cb0ef41Sopenharmony_ci
18161cb0ef41Sopenharmony_ci    return Just(true);
18171cb0ef41Sopenharmony_ci  }
18181cb0ef41Sopenharmony_ci
18191cb0ef41Sopenharmony_ci  it->Next();
18201cb0ef41Sopenharmony_ci  return Just(false);
18211cb0ef41Sopenharmony_ci}
18221cb0ef41Sopenharmony_ci}  // namespace
18231cb0ef41Sopenharmony_ci
18241cb0ef41Sopenharmony_ci// ES6 9.1.5.1
18251cb0ef41Sopenharmony_ci// Returns true on success, false if the property didn't exist, nothing if
18261cb0ef41Sopenharmony_ci// an exception was thrown.
18271cb0ef41Sopenharmony_ci// static
18281cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it,
18291cb0ef41Sopenharmony_ci                                                 PropertyDescriptor* desc) {
18301cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
18311cb0ef41Sopenharmony_ci  // "Virtual" dispatch.
18321cb0ef41Sopenharmony_ci  if (it->IsFound() && it->GetHolder<JSReceiver>()->IsJSProxy()) {
18331cb0ef41Sopenharmony_ci    return JSProxy::GetOwnPropertyDescriptor(isolate, it->GetHolder<JSProxy>(),
18341cb0ef41Sopenharmony_ci                                             it->GetName(), desc);
18351cb0ef41Sopenharmony_ci  }
18361cb0ef41Sopenharmony_ci
18371cb0ef41Sopenharmony_ci  Maybe<bool> intercepted = GetPropertyDescriptorWithInterceptor(it, desc);
18381cb0ef41Sopenharmony_ci  MAYBE_RETURN(intercepted, Nothing<bool>());
18391cb0ef41Sopenharmony_ci  if (intercepted.FromJust()) {
18401cb0ef41Sopenharmony_ci    return Just(true);
18411cb0ef41Sopenharmony_ci  }
18421cb0ef41Sopenharmony_ci
18431cb0ef41Sopenharmony_ci  // Request was not intercepted, continue as normal.
18441cb0ef41Sopenharmony_ci  // 1. (Assert)
18451cb0ef41Sopenharmony_ci  // 2. If O does not have an own property with key P, return undefined.
18461cb0ef41Sopenharmony_ci  Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(it);
18471cb0ef41Sopenharmony_ci  MAYBE_RETURN(maybe, Nothing<bool>());
18481cb0ef41Sopenharmony_ci  PropertyAttributes attrs = maybe.FromJust();
18491cb0ef41Sopenharmony_ci  if (attrs == ABSENT) return Just(false);
18501cb0ef41Sopenharmony_ci  DCHECK(!isolate->has_pending_exception());
18511cb0ef41Sopenharmony_ci
18521cb0ef41Sopenharmony_ci  // 3. Let D be a newly created Property Descriptor with no fields.
18531cb0ef41Sopenharmony_ci  DCHECK(desc->is_empty());
18541cb0ef41Sopenharmony_ci  // 4. Let X be O's own property whose key is P.
18551cb0ef41Sopenharmony_ci  // 5. If X is a data property, then
18561cb0ef41Sopenharmony_ci  bool is_accessor_pair = it->state() == LookupIterator::ACCESSOR &&
18571cb0ef41Sopenharmony_ci                          it->GetAccessors()->IsAccessorPair();
18581cb0ef41Sopenharmony_ci  if (!is_accessor_pair) {
18591cb0ef41Sopenharmony_ci    // 5a. Set D.[[Value]] to the value of X's [[Value]] attribute.
18601cb0ef41Sopenharmony_ci    Handle<Object> value;
18611cb0ef41Sopenharmony_ci    if (!Object::GetProperty(it).ToHandle(&value)) {
18621cb0ef41Sopenharmony_ci      DCHECK(isolate->has_pending_exception());
18631cb0ef41Sopenharmony_ci      return Nothing<bool>();
18641cb0ef41Sopenharmony_ci    }
18651cb0ef41Sopenharmony_ci    desc->set_value(value);
18661cb0ef41Sopenharmony_ci    // 5b. Set D.[[Writable]] to the value of X's [[Writable]] attribute
18671cb0ef41Sopenharmony_ci    desc->set_writable((attrs & READ_ONLY) == 0);
18681cb0ef41Sopenharmony_ci  } else {
18691cb0ef41Sopenharmony_ci    // 6. Else X is an accessor property, so
18701cb0ef41Sopenharmony_ci    Handle<AccessorPair> accessors =
18711cb0ef41Sopenharmony_ci        Handle<AccessorPair>::cast(it->GetAccessors());
18721cb0ef41Sopenharmony_ci    Handle<NativeContext> native_context =
18731cb0ef41Sopenharmony_ci        it->GetHolder<JSReceiver>()->GetCreationContext().ToHandleChecked();
18741cb0ef41Sopenharmony_ci    // 6a. Set D.[[Get]] to the value of X's [[Get]] attribute.
18751cb0ef41Sopenharmony_ci    desc->set_get(AccessorPair::GetComponent(isolate, native_context, accessors,
18761cb0ef41Sopenharmony_ci                                             ACCESSOR_GETTER));
18771cb0ef41Sopenharmony_ci    // 6b. Set D.[[Set]] to the value of X's [[Set]] attribute.
18781cb0ef41Sopenharmony_ci    desc->set_set(AccessorPair::GetComponent(isolate, native_context, accessors,
18791cb0ef41Sopenharmony_ci                                             ACCESSOR_SETTER));
18801cb0ef41Sopenharmony_ci  }
18811cb0ef41Sopenharmony_ci
18821cb0ef41Sopenharmony_ci  // 7. Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute.
18831cb0ef41Sopenharmony_ci  desc->set_enumerable((attrs & DONT_ENUM) == 0);
18841cb0ef41Sopenharmony_ci  // 8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute.
18851cb0ef41Sopenharmony_ci  desc->set_configurable((attrs & DONT_DELETE) == 0);
18861cb0ef41Sopenharmony_ci  // 9. Return D.
18871cb0ef41Sopenharmony_ci  DCHECK(PropertyDescriptor::IsAccessorDescriptor(desc) !=
18881cb0ef41Sopenharmony_ci         PropertyDescriptor::IsDataDescriptor(desc));
18891cb0ef41Sopenharmony_ci  return Just(true);
18901cb0ef41Sopenharmony_ci}
18911cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver,
18921cb0ef41Sopenharmony_ci                                          IntegrityLevel level,
18931cb0ef41Sopenharmony_ci                                          ShouldThrow should_throw) {
18941cb0ef41Sopenharmony_ci  DCHECK(level == SEALED || level == FROZEN);
18951cb0ef41Sopenharmony_ci
18961cb0ef41Sopenharmony_ci  if (receiver->IsJSObject()) {
18971cb0ef41Sopenharmony_ci    Handle<JSObject> object = Handle<JSObject>::cast(receiver);
18981cb0ef41Sopenharmony_ci
18991cb0ef41Sopenharmony_ci    if (!object->HasSloppyArgumentsElements() &&
19001cb0ef41Sopenharmony_ci        !object->IsJSModuleNamespace()) {  // Fast path.
19011cb0ef41Sopenharmony_ci      // Prevent memory leaks by not adding unnecessary transitions.
19021cb0ef41Sopenharmony_ci      Maybe<bool> test = JSObject::TestIntegrityLevel(object, level);
19031cb0ef41Sopenharmony_ci      MAYBE_RETURN(test, Nothing<bool>());
19041cb0ef41Sopenharmony_ci      if (test.FromJust()) return test;
19051cb0ef41Sopenharmony_ci
19061cb0ef41Sopenharmony_ci      if (level == SEALED) {
19071cb0ef41Sopenharmony_ci        return JSObject::PreventExtensionsWithTransition<SEALED>(object,
19081cb0ef41Sopenharmony_ci                                                                 should_throw);
19091cb0ef41Sopenharmony_ci      } else {
19101cb0ef41Sopenharmony_ci        return JSObject::PreventExtensionsWithTransition<FROZEN>(object,
19111cb0ef41Sopenharmony_ci                                                                 should_throw);
19121cb0ef41Sopenharmony_ci      }
19131cb0ef41Sopenharmony_ci    }
19141cb0ef41Sopenharmony_ci  }
19151cb0ef41Sopenharmony_ci
19161cb0ef41Sopenharmony_ci  Isolate* isolate = receiver->GetIsolate();
19171cb0ef41Sopenharmony_ci
19181cb0ef41Sopenharmony_ci  MAYBE_RETURN(JSReceiver::PreventExtensions(receiver, should_throw),
19191cb0ef41Sopenharmony_ci               Nothing<bool>());
19201cb0ef41Sopenharmony_ci
19211cb0ef41Sopenharmony_ci  Handle<FixedArray> keys;
19221cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
19231cb0ef41Sopenharmony_ci      isolate, keys, JSReceiver::OwnPropertyKeys(receiver), Nothing<bool>());
19241cb0ef41Sopenharmony_ci
19251cb0ef41Sopenharmony_ci  PropertyDescriptor no_conf;
19261cb0ef41Sopenharmony_ci  no_conf.set_configurable(false);
19271cb0ef41Sopenharmony_ci
19281cb0ef41Sopenharmony_ci  PropertyDescriptor no_conf_no_write;
19291cb0ef41Sopenharmony_ci  no_conf_no_write.set_configurable(false);
19301cb0ef41Sopenharmony_ci  no_conf_no_write.set_writable(false);
19311cb0ef41Sopenharmony_ci
19321cb0ef41Sopenharmony_ci  if (level == SEALED) {
19331cb0ef41Sopenharmony_ci    for (int i = 0; i < keys->length(); ++i) {
19341cb0ef41Sopenharmony_ci      Handle<Object> key(keys->get(i), isolate);
19351cb0ef41Sopenharmony_ci      MAYBE_RETURN(DefineOwnProperty(isolate, receiver, key, &no_conf,
19361cb0ef41Sopenharmony_ci                                     Just(kThrowOnError)),
19371cb0ef41Sopenharmony_ci                   Nothing<bool>());
19381cb0ef41Sopenharmony_ci    }
19391cb0ef41Sopenharmony_ci    return Just(true);
19401cb0ef41Sopenharmony_ci  }
19411cb0ef41Sopenharmony_ci
19421cb0ef41Sopenharmony_ci  for (int i = 0; i < keys->length(); ++i) {
19431cb0ef41Sopenharmony_ci    Handle<Object> key(keys->get(i), isolate);
19441cb0ef41Sopenharmony_ci    PropertyDescriptor current_desc;
19451cb0ef41Sopenharmony_ci    Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
19461cb0ef41Sopenharmony_ci        isolate, receiver, key, &current_desc);
19471cb0ef41Sopenharmony_ci    MAYBE_RETURN(owned, Nothing<bool>());
19481cb0ef41Sopenharmony_ci    if (owned.FromJust()) {
19491cb0ef41Sopenharmony_ci      PropertyDescriptor desc =
19501cb0ef41Sopenharmony_ci          PropertyDescriptor::IsAccessorDescriptor(&current_desc)
19511cb0ef41Sopenharmony_ci              ? no_conf
19521cb0ef41Sopenharmony_ci              : no_conf_no_write;
19531cb0ef41Sopenharmony_ci      MAYBE_RETURN(
19541cb0ef41Sopenharmony_ci          DefineOwnProperty(isolate, receiver, key, &desc, Just(kThrowOnError)),
19551cb0ef41Sopenharmony_ci          Nothing<bool>());
19561cb0ef41Sopenharmony_ci    }
19571cb0ef41Sopenharmony_ci  }
19581cb0ef41Sopenharmony_ci  return Just(true);
19591cb0ef41Sopenharmony_ci}
19601cb0ef41Sopenharmony_ci
19611cb0ef41Sopenharmony_cinamespace {
19621cb0ef41Sopenharmony_ciMaybe<bool> GenericTestIntegrityLevel(Handle<JSReceiver> receiver,
19631cb0ef41Sopenharmony_ci                                      PropertyAttributes level) {
19641cb0ef41Sopenharmony_ci  DCHECK(level == SEALED || level == FROZEN);
19651cb0ef41Sopenharmony_ci
19661cb0ef41Sopenharmony_ci  Maybe<bool> extensible = JSReceiver::IsExtensible(receiver);
19671cb0ef41Sopenharmony_ci  MAYBE_RETURN(extensible, Nothing<bool>());
19681cb0ef41Sopenharmony_ci  if (extensible.FromJust()) return Just(false);
19691cb0ef41Sopenharmony_ci
19701cb0ef41Sopenharmony_ci  Isolate* isolate = receiver->GetIsolate();
19711cb0ef41Sopenharmony_ci
19721cb0ef41Sopenharmony_ci  Handle<FixedArray> keys;
19731cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
19741cb0ef41Sopenharmony_ci      isolate, keys, JSReceiver::OwnPropertyKeys(receiver), Nothing<bool>());
19751cb0ef41Sopenharmony_ci
19761cb0ef41Sopenharmony_ci  for (int i = 0; i < keys->length(); ++i) {
19771cb0ef41Sopenharmony_ci    Handle<Object> key(keys->get(i), isolate);
19781cb0ef41Sopenharmony_ci    PropertyDescriptor current_desc;
19791cb0ef41Sopenharmony_ci    Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
19801cb0ef41Sopenharmony_ci        isolate, receiver, key, &current_desc);
19811cb0ef41Sopenharmony_ci    MAYBE_RETURN(owned, Nothing<bool>());
19821cb0ef41Sopenharmony_ci    if (owned.FromJust()) {
19831cb0ef41Sopenharmony_ci      if (current_desc.configurable()) return Just(false);
19841cb0ef41Sopenharmony_ci      if (level == FROZEN &&
19851cb0ef41Sopenharmony_ci          PropertyDescriptor::IsDataDescriptor(&current_desc) &&
19861cb0ef41Sopenharmony_ci          current_desc.writable()) {
19871cb0ef41Sopenharmony_ci        return Just(false);
19881cb0ef41Sopenharmony_ci      }
19891cb0ef41Sopenharmony_ci    }
19901cb0ef41Sopenharmony_ci  }
19911cb0ef41Sopenharmony_ci  return Just(true);
19921cb0ef41Sopenharmony_ci}
19931cb0ef41Sopenharmony_ci
19941cb0ef41Sopenharmony_ci}  // namespace
19951cb0ef41Sopenharmony_ci
19961cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> receiver,
19971cb0ef41Sopenharmony_ci                                           IntegrityLevel level) {
19981cb0ef41Sopenharmony_ci  if (!receiver->map().IsCustomElementsReceiverMap()) {
19991cb0ef41Sopenharmony_ci    return JSObject::TestIntegrityLevel(Handle<JSObject>::cast(receiver),
20001cb0ef41Sopenharmony_ci                                        level);
20011cb0ef41Sopenharmony_ci  }
20021cb0ef41Sopenharmony_ci  return GenericTestIntegrityLevel(receiver, level);
20031cb0ef41Sopenharmony_ci}
20041cb0ef41Sopenharmony_ci
20051cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object,
20061cb0ef41Sopenharmony_ci                                          ShouldThrow should_throw) {
20071cb0ef41Sopenharmony_ci  if (object->IsJSProxy()) {
20081cb0ef41Sopenharmony_ci    return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object),
20091cb0ef41Sopenharmony_ci                                      should_throw);
20101cb0ef41Sopenharmony_ci  }
20111cb0ef41Sopenharmony_ci  DCHECK(object->IsJSObject());
20121cb0ef41Sopenharmony_ci  return JSObject::PreventExtensions(Handle<JSObject>::cast(object),
20131cb0ef41Sopenharmony_ci                                     should_throw);
20141cb0ef41Sopenharmony_ci}
20151cb0ef41Sopenharmony_ci
20161cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) {
20171cb0ef41Sopenharmony_ci  if (object->IsJSProxy()) {
20181cb0ef41Sopenharmony_ci    return JSProxy::IsExtensible(Handle<JSProxy>::cast(object));
20191cb0ef41Sopenharmony_ci  }
20201cb0ef41Sopenharmony_ci  return Just(JSObject::IsExtensible(Handle<JSObject>::cast(object)));
20211cb0ef41Sopenharmony_ci}
20221cb0ef41Sopenharmony_ci
20231cb0ef41Sopenharmony_ci// static
20241cb0ef41Sopenharmony_ciMaybeHandle<Object> JSReceiver::ToPrimitive(Isolate* isolate,
20251cb0ef41Sopenharmony_ci                                            Handle<JSReceiver> receiver,
20261cb0ef41Sopenharmony_ci                                            ToPrimitiveHint hint) {
20271cb0ef41Sopenharmony_ci  Handle<Object> exotic_to_prim;
20281cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION(
20291cb0ef41Sopenharmony_ci      isolate, exotic_to_prim,
20301cb0ef41Sopenharmony_ci      Object::GetMethod(receiver, isolate->factory()->to_primitive_symbol()),
20311cb0ef41Sopenharmony_ci      Object);
20321cb0ef41Sopenharmony_ci  if (!exotic_to_prim->IsUndefined(isolate)) {
20331cb0ef41Sopenharmony_ci    Handle<Object> hint_string =
20341cb0ef41Sopenharmony_ci        isolate->factory()->ToPrimitiveHintString(hint);
20351cb0ef41Sopenharmony_ci    Handle<Object> result;
20361cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION(
20371cb0ef41Sopenharmony_ci        isolate, result,
20381cb0ef41Sopenharmony_ci        Execution::Call(isolate, exotic_to_prim, receiver, 1, &hint_string),
20391cb0ef41Sopenharmony_ci        Object);
20401cb0ef41Sopenharmony_ci    if (result->IsPrimitive()) return result;
20411cb0ef41Sopenharmony_ci    THROW_NEW_ERROR(isolate,
20421cb0ef41Sopenharmony_ci                    NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
20431cb0ef41Sopenharmony_ci                    Object);
20441cb0ef41Sopenharmony_ci  }
20451cb0ef41Sopenharmony_ci  return OrdinaryToPrimitive(isolate, receiver,
20461cb0ef41Sopenharmony_ci                             (hint == ToPrimitiveHint::kString)
20471cb0ef41Sopenharmony_ci                                 ? OrdinaryToPrimitiveHint::kString
20481cb0ef41Sopenharmony_ci                                 : OrdinaryToPrimitiveHint::kNumber);
20491cb0ef41Sopenharmony_ci}
20501cb0ef41Sopenharmony_ci
20511cb0ef41Sopenharmony_ci// static
20521cb0ef41Sopenharmony_ciMaybeHandle<Object> JSReceiver::OrdinaryToPrimitive(
20531cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSReceiver> receiver,
20541cb0ef41Sopenharmony_ci    OrdinaryToPrimitiveHint hint) {
20551cb0ef41Sopenharmony_ci  Handle<String> method_names[2];
20561cb0ef41Sopenharmony_ci  switch (hint) {
20571cb0ef41Sopenharmony_ci    case OrdinaryToPrimitiveHint::kNumber:
20581cb0ef41Sopenharmony_ci      method_names[0] = isolate->factory()->valueOf_string();
20591cb0ef41Sopenharmony_ci      method_names[1] = isolate->factory()->toString_string();
20601cb0ef41Sopenharmony_ci      break;
20611cb0ef41Sopenharmony_ci    case OrdinaryToPrimitiveHint::kString:
20621cb0ef41Sopenharmony_ci      method_names[0] = isolate->factory()->toString_string();
20631cb0ef41Sopenharmony_ci      method_names[1] = isolate->factory()->valueOf_string();
20641cb0ef41Sopenharmony_ci      break;
20651cb0ef41Sopenharmony_ci  }
20661cb0ef41Sopenharmony_ci  for (Handle<String> name : method_names) {
20671cb0ef41Sopenharmony_ci    Handle<Object> method;
20681cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION(isolate, method,
20691cb0ef41Sopenharmony_ci                               JSReceiver::GetProperty(isolate, receiver, name),
20701cb0ef41Sopenharmony_ci                               Object);
20711cb0ef41Sopenharmony_ci    if (method->IsCallable()) {
20721cb0ef41Sopenharmony_ci      Handle<Object> result;
20731cb0ef41Sopenharmony_ci      ASSIGN_RETURN_ON_EXCEPTION(
20741cb0ef41Sopenharmony_ci          isolate, result,
20751cb0ef41Sopenharmony_ci          Execution::Call(isolate, method, receiver, 0, nullptr), Object);
20761cb0ef41Sopenharmony_ci      if (result->IsPrimitive()) return result;
20771cb0ef41Sopenharmony_ci    }
20781cb0ef41Sopenharmony_ci  }
20791cb0ef41Sopenharmony_ci  THROW_NEW_ERROR(isolate,
20801cb0ef41Sopenharmony_ci                  NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
20811cb0ef41Sopenharmony_ci                  Object);
20821cb0ef41Sopenharmony_ci}
20831cb0ef41Sopenharmony_ci
20841cb0ef41Sopenharmony_ciV8_WARN_UNUSED_RESULT Maybe<bool> FastGetOwnValuesOrEntries(
20851cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSReceiver> receiver, bool get_entries,
20861cb0ef41Sopenharmony_ci    Handle<FixedArray>* result) {
20871cb0ef41Sopenharmony_ci  Handle<Map> map(JSReceiver::cast(*receiver).map(), isolate);
20881cb0ef41Sopenharmony_ci
20891cb0ef41Sopenharmony_ci  if (!map->IsJSObjectMap()) return Just(false);
20901cb0ef41Sopenharmony_ci  if (!map->OnlyHasSimpleProperties()) return Just(false);
20911cb0ef41Sopenharmony_ci
20921cb0ef41Sopenharmony_ci  Handle<JSObject> object(JSObject::cast(*receiver), isolate);
20931cb0ef41Sopenharmony_ci  Handle<DescriptorArray> descriptors(map->instance_descriptors(isolate),
20941cb0ef41Sopenharmony_ci                                      isolate);
20951cb0ef41Sopenharmony_ci
20961cb0ef41Sopenharmony_ci  int number_of_own_descriptors = map->NumberOfOwnDescriptors();
20971cb0ef41Sopenharmony_ci  size_t number_of_own_elements =
20981cb0ef41Sopenharmony_ci      object->GetElementsAccessor()->GetCapacity(*object, object->elements());
20991cb0ef41Sopenharmony_ci
21001cb0ef41Sopenharmony_ci  if (number_of_own_elements >
21011cb0ef41Sopenharmony_ci      static_cast<size_t>(FixedArray::kMaxLength - number_of_own_descriptors)) {
21021cb0ef41Sopenharmony_ci    isolate->Throw(*isolate->factory()->NewRangeError(
21031cb0ef41Sopenharmony_ci        MessageTemplate::kInvalidArrayLength));
21041cb0ef41Sopenharmony_ci    return Nothing<bool>();
21051cb0ef41Sopenharmony_ci  }
21061cb0ef41Sopenharmony_ci  // The static cast is safe after the range check right above.
21071cb0ef41Sopenharmony_ci  Handle<FixedArray> values_or_entries = isolate->factory()->NewFixedArray(
21081cb0ef41Sopenharmony_ci      static_cast<int>(number_of_own_descriptors + number_of_own_elements));
21091cb0ef41Sopenharmony_ci  int count = 0;
21101cb0ef41Sopenharmony_ci
21111cb0ef41Sopenharmony_ci  if (object->elements() != ReadOnlyRoots(isolate).empty_fixed_array()) {
21121cb0ef41Sopenharmony_ci    MAYBE_RETURN(object->GetElementsAccessor()->CollectValuesOrEntries(
21131cb0ef41Sopenharmony_ci                     isolate, object, values_or_entries, get_entries, &count,
21141cb0ef41Sopenharmony_ci                     ENUMERABLE_STRINGS),
21151cb0ef41Sopenharmony_ci                 Nothing<bool>());
21161cb0ef41Sopenharmony_ci  }
21171cb0ef41Sopenharmony_ci
21181cb0ef41Sopenharmony_ci  // We may have already lost stability, if CollectValuesOrEntries had
21191cb0ef41Sopenharmony_ci  // side-effects.
21201cb0ef41Sopenharmony_ci  bool stable = *map == object->map();
21211cb0ef41Sopenharmony_ci  if (stable) {
21221cb0ef41Sopenharmony_ci    descriptors.PatchValue(map->instance_descriptors(isolate));
21231cb0ef41Sopenharmony_ci  }
21241cb0ef41Sopenharmony_ci
21251cb0ef41Sopenharmony_ci  for (InternalIndex index : InternalIndex::Range(number_of_own_descriptors)) {
21261cb0ef41Sopenharmony_ci    HandleScope inner_scope(isolate);
21271cb0ef41Sopenharmony_ci
21281cb0ef41Sopenharmony_ci    Handle<Name> next_key(descriptors->GetKey(index), isolate);
21291cb0ef41Sopenharmony_ci    if (!next_key->IsString()) continue;
21301cb0ef41Sopenharmony_ci    Handle<Object> prop_value;
21311cb0ef41Sopenharmony_ci
21321cb0ef41Sopenharmony_ci    // Directly decode from the descriptor array if |from| did not change shape.
21331cb0ef41Sopenharmony_ci    if (stable) {
21341cb0ef41Sopenharmony_ci      DCHECK_EQ(object->map(), *map);
21351cb0ef41Sopenharmony_ci      DCHECK_EQ(*descriptors, map->instance_descriptors(isolate));
21361cb0ef41Sopenharmony_ci
21371cb0ef41Sopenharmony_ci      PropertyDetails details = descriptors->GetDetails(index);
21381cb0ef41Sopenharmony_ci      if (!details.IsEnumerable()) continue;
21391cb0ef41Sopenharmony_ci      if (details.kind() == PropertyKind::kData) {
21401cb0ef41Sopenharmony_ci        if (details.location() == PropertyLocation::kDescriptor) {
21411cb0ef41Sopenharmony_ci          prop_value = handle(descriptors->GetStrongValue(index), isolate);
21421cb0ef41Sopenharmony_ci        } else {
21431cb0ef41Sopenharmony_ci          Representation representation = details.representation();
21441cb0ef41Sopenharmony_ci          FieldIndex field_index = FieldIndex::ForPropertyIndex(
21451cb0ef41Sopenharmony_ci              *map, details.field_index(), representation);
21461cb0ef41Sopenharmony_ci          prop_value = JSObject::FastPropertyAt(isolate, object, representation,
21471cb0ef41Sopenharmony_ci                                                field_index);
21481cb0ef41Sopenharmony_ci        }
21491cb0ef41Sopenharmony_ci      } else {
21501cb0ef41Sopenharmony_ci        LookupIterator it(isolate, object, next_key,
21511cb0ef41Sopenharmony_ci                          LookupIterator::OWN_SKIP_INTERCEPTOR);
21521cb0ef41Sopenharmony_ci        DCHECK_EQ(LookupIterator::ACCESSOR, it.state());
21531cb0ef41Sopenharmony_ci        ASSIGN_RETURN_ON_EXCEPTION_VALUE(
21541cb0ef41Sopenharmony_ci            isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
21551cb0ef41Sopenharmony_ci        stable = object->map() == *map;
21561cb0ef41Sopenharmony_ci        descriptors.PatchValue(map->instance_descriptors(isolate));
21571cb0ef41Sopenharmony_ci      }
21581cb0ef41Sopenharmony_ci    } else {
21591cb0ef41Sopenharmony_ci      // If the map did change, do a slower lookup. We are still guaranteed that
21601cb0ef41Sopenharmony_ci      // the object has a simple shape, and that the key is a name.
21611cb0ef41Sopenharmony_ci      LookupIterator it(isolate, object, next_key,
21621cb0ef41Sopenharmony_ci                        LookupIterator::OWN_SKIP_INTERCEPTOR);
21631cb0ef41Sopenharmony_ci      if (!it.IsFound()) continue;
21641cb0ef41Sopenharmony_ci      DCHECK(it.state() == LookupIterator::DATA ||
21651cb0ef41Sopenharmony_ci             it.state() == LookupIterator::ACCESSOR);
21661cb0ef41Sopenharmony_ci      if (!it.IsEnumerable()) continue;
21671cb0ef41Sopenharmony_ci      ASSIGN_RETURN_ON_EXCEPTION_VALUE(
21681cb0ef41Sopenharmony_ci          isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
21691cb0ef41Sopenharmony_ci    }
21701cb0ef41Sopenharmony_ci
21711cb0ef41Sopenharmony_ci    if (get_entries) {
21721cb0ef41Sopenharmony_ci      prop_value = MakeEntryPair(isolate, next_key, prop_value);
21731cb0ef41Sopenharmony_ci    }
21741cb0ef41Sopenharmony_ci
21751cb0ef41Sopenharmony_ci    values_or_entries->set(count, *prop_value);
21761cb0ef41Sopenharmony_ci    count++;
21771cb0ef41Sopenharmony_ci  }
21781cb0ef41Sopenharmony_ci
21791cb0ef41Sopenharmony_ci  DCHECK_LE(count, values_or_entries->length());
21801cb0ef41Sopenharmony_ci  *result = FixedArray::ShrinkOrEmpty(isolate, values_or_entries, count);
21811cb0ef41Sopenharmony_ci  return Just(true);
21821cb0ef41Sopenharmony_ci}
21831cb0ef41Sopenharmony_ci
21841cb0ef41Sopenharmony_ciMaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
21851cb0ef41Sopenharmony_ci                                              Handle<JSReceiver> object,
21861cb0ef41Sopenharmony_ci                                              PropertyFilter filter,
21871cb0ef41Sopenharmony_ci                                              bool try_fast_path,
21881cb0ef41Sopenharmony_ci                                              bool get_entries) {
21891cb0ef41Sopenharmony_ci  Handle<FixedArray> values_or_entries;
21901cb0ef41Sopenharmony_ci  if (try_fast_path && filter == ENUMERABLE_STRINGS) {
21911cb0ef41Sopenharmony_ci    Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries(
21921cb0ef41Sopenharmony_ci        isolate, object, get_entries, &values_or_entries);
21931cb0ef41Sopenharmony_ci    if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>();
21941cb0ef41Sopenharmony_ci    if (fast_values_or_entries.FromJust()) return values_or_entries;
21951cb0ef41Sopenharmony_ci  }
21961cb0ef41Sopenharmony_ci
21971cb0ef41Sopenharmony_ci  PropertyFilter key_filter =
21981cb0ef41Sopenharmony_ci      static_cast<PropertyFilter>(filter & ~ONLY_ENUMERABLE);
21991cb0ef41Sopenharmony_ci
22001cb0ef41Sopenharmony_ci  Handle<FixedArray> keys;
22011cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
22021cb0ef41Sopenharmony_ci      isolate, keys,
22031cb0ef41Sopenharmony_ci      KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, key_filter,
22041cb0ef41Sopenharmony_ci                              GetKeysConversion::kConvertToString),
22051cb0ef41Sopenharmony_ci      MaybeHandle<FixedArray>());
22061cb0ef41Sopenharmony_ci
22071cb0ef41Sopenharmony_ci  values_or_entries = isolate->factory()->NewFixedArray(keys->length());
22081cb0ef41Sopenharmony_ci  int length = 0;
22091cb0ef41Sopenharmony_ci
22101cb0ef41Sopenharmony_ci  for (int i = 0; i < keys->length(); ++i) {
22111cb0ef41Sopenharmony_ci    Handle<Name> key =
22121cb0ef41Sopenharmony_ci        Handle<Name>::cast(handle(keys->get(isolate, i), isolate));
22131cb0ef41Sopenharmony_ci
22141cb0ef41Sopenharmony_ci    if (filter & ONLY_ENUMERABLE) {
22151cb0ef41Sopenharmony_ci      PropertyDescriptor descriptor;
22161cb0ef41Sopenharmony_ci      Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
22171cb0ef41Sopenharmony_ci          isolate, object, key, &descriptor);
22181cb0ef41Sopenharmony_ci      MAYBE_RETURN(did_get_descriptor, MaybeHandle<FixedArray>());
22191cb0ef41Sopenharmony_ci      if (!did_get_descriptor.FromJust() || !descriptor.enumerable()) continue;
22201cb0ef41Sopenharmony_ci    }
22211cb0ef41Sopenharmony_ci
22221cb0ef41Sopenharmony_ci    Handle<Object> value;
22231cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION_VALUE(
22241cb0ef41Sopenharmony_ci        isolate, value, Object::GetPropertyOrElement(isolate, object, key),
22251cb0ef41Sopenharmony_ci        MaybeHandle<FixedArray>());
22261cb0ef41Sopenharmony_ci
22271cb0ef41Sopenharmony_ci    if (get_entries) {
22281cb0ef41Sopenharmony_ci      Handle<FixedArray> entry_storage = isolate->factory()->NewFixedArray(2);
22291cb0ef41Sopenharmony_ci      entry_storage->set(0, *key);
22301cb0ef41Sopenharmony_ci      entry_storage->set(1, *value);
22311cb0ef41Sopenharmony_ci      value = isolate->factory()->NewJSArrayWithElements(entry_storage,
22321cb0ef41Sopenharmony_ci                                                         PACKED_ELEMENTS, 2);
22331cb0ef41Sopenharmony_ci    }
22341cb0ef41Sopenharmony_ci
22351cb0ef41Sopenharmony_ci    values_or_entries->set(length, *value);
22361cb0ef41Sopenharmony_ci    length++;
22371cb0ef41Sopenharmony_ci  }
22381cb0ef41Sopenharmony_ci  DCHECK_LE(length, values_or_entries->length());
22391cb0ef41Sopenharmony_ci  return FixedArray::ShrinkOrEmpty(isolate, values_or_entries, length);
22401cb0ef41Sopenharmony_ci}
22411cb0ef41Sopenharmony_ci
22421cb0ef41Sopenharmony_ciMaybeHandle<FixedArray> JSReceiver::GetOwnValues(Handle<JSReceiver> object,
22431cb0ef41Sopenharmony_ci                                                 PropertyFilter filter,
22441cb0ef41Sopenharmony_ci                                                 bool try_fast_path) {
22451cb0ef41Sopenharmony_ci  return GetOwnValuesOrEntries(object->GetIsolate(), object, filter,
22461cb0ef41Sopenharmony_ci                               try_fast_path, false);
22471cb0ef41Sopenharmony_ci}
22481cb0ef41Sopenharmony_ci
22491cb0ef41Sopenharmony_ciMaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object,
22501cb0ef41Sopenharmony_ci                                                  PropertyFilter filter,
22511cb0ef41Sopenharmony_ci                                                  bool try_fast_path) {
22521cb0ef41Sopenharmony_ci  return GetOwnValuesOrEntries(object->GetIsolate(), object, filter,
22531cb0ef41Sopenharmony_ci                               try_fast_path, true);
22541cb0ef41Sopenharmony_ci}
22551cb0ef41Sopenharmony_ci
22561cb0ef41Sopenharmony_ciMaybe<bool> JSReceiver::SetPrototype(Isolate* isolate,
22571cb0ef41Sopenharmony_ci                                     Handle<JSReceiver> object,
22581cb0ef41Sopenharmony_ci                                     Handle<Object> value, bool from_javascript,
22591cb0ef41Sopenharmony_ci                                     ShouldThrow should_throw) {
22601cb0ef41Sopenharmony_ci  if (object->IsJSProxy()) {
22611cb0ef41Sopenharmony_ci    return JSProxy::SetPrototype(isolate, Handle<JSProxy>::cast(object), value,
22621cb0ef41Sopenharmony_ci                                 from_javascript, should_throw);
22631cb0ef41Sopenharmony_ci  }
22641cb0ef41Sopenharmony_ci  return JSObject::SetPrototype(isolate, Handle<JSObject>::cast(object), value,
22651cb0ef41Sopenharmony_ci                                from_javascript, should_throw);
22661cb0ef41Sopenharmony_ci}
22671cb0ef41Sopenharmony_ci
22681cb0ef41Sopenharmony_cibool JSReceiver::HasProxyInPrototype(Isolate* isolate) {
22691cb0ef41Sopenharmony_ci  for (PrototypeIterator iter(isolate, *this, kStartAtReceiver,
22701cb0ef41Sopenharmony_ci                              PrototypeIterator::END_AT_NULL);
22711cb0ef41Sopenharmony_ci       !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) {
22721cb0ef41Sopenharmony_ci    if (iter.GetCurrent().IsJSProxy()) return true;
22731cb0ef41Sopenharmony_ci  }
22741cb0ef41Sopenharmony_ci  return false;
22751cb0ef41Sopenharmony_ci}
22761cb0ef41Sopenharmony_ci
22771cb0ef41Sopenharmony_cibool JSReceiver::IsCodeLike(Isolate* isolate) const {
22781cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
22791cb0ef41Sopenharmony_ci  Object maybe_constructor = map().GetConstructor();
22801cb0ef41Sopenharmony_ci  if (!maybe_constructor.IsJSFunction()) return false;
22811cb0ef41Sopenharmony_ci  if (!JSFunction::cast(maybe_constructor).shared().IsApiFunction()) {
22821cb0ef41Sopenharmony_ci    return false;
22831cb0ef41Sopenharmony_ci  }
22841cb0ef41Sopenharmony_ci  Object instance_template = JSFunction::cast(maybe_constructor)
22851cb0ef41Sopenharmony_ci                                 .shared()
22861cb0ef41Sopenharmony_ci                                 .get_api_func_data()
22871cb0ef41Sopenharmony_ci                                 .GetInstanceTemplate();
22881cb0ef41Sopenharmony_ci  if (instance_template.IsUndefined(isolate)) return false;
22891cb0ef41Sopenharmony_ci  return ObjectTemplateInfo::cast(instance_template).code_like();
22901cb0ef41Sopenharmony_ci}
22911cb0ef41Sopenharmony_ci
22921cb0ef41Sopenharmony_ci// static
22931cb0ef41Sopenharmony_ciMaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
22941cb0ef41Sopenharmony_ci                                    Handle<JSReceiver> new_target,
22951cb0ef41Sopenharmony_ci                                    Handle<AllocationSite> site) {
22961cb0ef41Sopenharmony_ci  // If called through new, new.target can be:
22971cb0ef41Sopenharmony_ci  // - a subclass of constructor,
22981cb0ef41Sopenharmony_ci  // - a proxy wrapper around constructor, or
22991cb0ef41Sopenharmony_ci  // - the constructor itself.
23001cb0ef41Sopenharmony_ci  // If called through Reflect.construct, it's guaranteed to be a constructor.
23011cb0ef41Sopenharmony_ci  Isolate* const isolate = constructor->GetIsolate();
23021cb0ef41Sopenharmony_ci  DCHECK(constructor->IsConstructor());
23031cb0ef41Sopenharmony_ci  DCHECK(new_target->IsConstructor());
23041cb0ef41Sopenharmony_ci  DCHECK(!constructor->has_initial_map() ||
23051cb0ef41Sopenharmony_ci         !InstanceTypeChecker::IsJSFunction(
23061cb0ef41Sopenharmony_ci             constructor->initial_map().instance_type()));
23071cb0ef41Sopenharmony_ci
23081cb0ef41Sopenharmony_ci  Handle<Map> initial_map;
23091cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION(
23101cb0ef41Sopenharmony_ci      isolate, initial_map,
23111cb0ef41Sopenharmony_ci      JSFunction::GetDerivedMap(isolate, constructor, new_target), JSObject);
23121cb0ef41Sopenharmony_ci  int initial_capacity = V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
23131cb0ef41Sopenharmony_ci                             ? SwissNameDictionary::kInitialCapacity
23141cb0ef41Sopenharmony_ci                             : NameDictionary::kInitialCapacity;
23151cb0ef41Sopenharmony_ci  Handle<JSObject> result = isolate->factory()->NewFastOrSlowJSObjectFromMap(
23161cb0ef41Sopenharmony_ci      initial_map, initial_capacity, AllocationType::kYoung, site);
23171cb0ef41Sopenharmony_ci  isolate->counters()->constructed_objects()->Increment();
23181cb0ef41Sopenharmony_ci  isolate->counters()->constructed_objects_runtime()->Increment();
23191cb0ef41Sopenharmony_ci  return result;
23201cb0ef41Sopenharmony_ci}
23211cb0ef41Sopenharmony_ci
23221cb0ef41Sopenharmony_ci// 9.1.12 ObjectCreate ( proto [ , internalSlotsList ] )
23231cb0ef41Sopenharmony_ci// Notice: This is NOT 19.1.2.2 Object.create ( O, Properties )
23241cb0ef41Sopenharmony_ciMaybeHandle<JSObject> JSObject::ObjectCreate(Isolate* isolate,
23251cb0ef41Sopenharmony_ci                                             Handle<Object> prototype) {
23261cb0ef41Sopenharmony_ci  // Generate the map with the specified {prototype} based on the Object
23271cb0ef41Sopenharmony_ci  // function's initial map from the current native context.
23281cb0ef41Sopenharmony_ci  // TODO(bmeurer): Use a dedicated cache for Object.create; think about
23291cb0ef41Sopenharmony_ci  // slack tracking for Object.create.
23301cb0ef41Sopenharmony_ci  Handle<Map> map =
23311cb0ef41Sopenharmony_ci      Map::GetObjectCreateMap(isolate, Handle<HeapObject>::cast(prototype));
23321cb0ef41Sopenharmony_ci
23331cb0ef41Sopenharmony_ci  // Actually allocate the object.
23341cb0ef41Sopenharmony_ci  return isolate->factory()->NewFastOrSlowJSObjectFromMap(map);
23351cb0ef41Sopenharmony_ci}
23361cb0ef41Sopenharmony_ci
23371cb0ef41Sopenharmony_civoid JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
23381cb0ef41Sopenharmony_ci  DCHECK(object->HasSmiOrObjectElements() ||
23391cb0ef41Sopenharmony_ci         object->HasFastStringWrapperElements() ||
23401cb0ef41Sopenharmony_ci         object->HasAnyNonextensibleElements());
23411cb0ef41Sopenharmony_ci  FixedArray raw_elems = FixedArray::cast(object->elements());
23421cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
23431cb0ef41Sopenharmony_ci  if (raw_elems.map() != ReadOnlyRoots(isolate).fixed_cow_array_map()) return;
23441cb0ef41Sopenharmony_ci  Handle<FixedArray> elems(raw_elems, isolate);
23451cb0ef41Sopenharmony_ci  Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap(
23461cb0ef41Sopenharmony_ci      elems, isolate->factory()->fixed_array_map());
23471cb0ef41Sopenharmony_ci  object->set_elements(*writable_elems);
23481cb0ef41Sopenharmony_ci  isolate->counters()->cow_arrays_converted()->Increment();
23491cb0ef41Sopenharmony_ci}
23501cb0ef41Sopenharmony_ci
23511cb0ef41Sopenharmony_ciint JSObject::GetHeaderSize(InstanceType type,
23521cb0ef41Sopenharmony_ci                            bool function_has_prototype_slot) {
23531cb0ef41Sopenharmony_ci  switch (type) {
23541cb0ef41Sopenharmony_ci    case JS_API_OBJECT_TYPE:
23551cb0ef41Sopenharmony_ci    case JS_ITERATOR_PROTOTYPE_TYPE:
23561cb0ef41Sopenharmony_ci    case JS_MAP_ITERATOR_PROTOTYPE_TYPE:
23571cb0ef41Sopenharmony_ci    case JS_OBJECT_PROTOTYPE_TYPE:
23581cb0ef41Sopenharmony_ci    case JS_OBJECT_TYPE:
23591cb0ef41Sopenharmony_ci    case JS_PROMISE_PROTOTYPE_TYPE:
23601cb0ef41Sopenharmony_ci    case JS_REG_EXP_PROTOTYPE_TYPE:
23611cb0ef41Sopenharmony_ci    case JS_SET_ITERATOR_PROTOTYPE_TYPE:
23621cb0ef41Sopenharmony_ci    case JS_SET_PROTOTYPE_TYPE:
23631cb0ef41Sopenharmony_ci    case JS_SPECIAL_API_OBJECT_TYPE:
23641cb0ef41Sopenharmony_ci    case JS_STRING_ITERATOR_PROTOTYPE_TYPE:
23651cb0ef41Sopenharmony_ci    case JS_ARRAY_ITERATOR_PROTOTYPE_TYPE:
23661cb0ef41Sopenharmony_ci    case JS_TYPED_ARRAY_PROTOTYPE_TYPE:
23671cb0ef41Sopenharmony_ci      return JSObject::kHeaderSize;
23681cb0ef41Sopenharmony_ci    case JS_GENERATOR_OBJECT_TYPE:
23691cb0ef41Sopenharmony_ci      return JSGeneratorObject::kHeaderSize;
23701cb0ef41Sopenharmony_ci    case JS_ASYNC_FUNCTION_OBJECT_TYPE:
23711cb0ef41Sopenharmony_ci      return JSAsyncFunctionObject::kHeaderSize;
23721cb0ef41Sopenharmony_ci    case JS_ASYNC_GENERATOR_OBJECT_TYPE:
23731cb0ef41Sopenharmony_ci      return JSAsyncGeneratorObject::kHeaderSize;
23741cb0ef41Sopenharmony_ci    case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
23751cb0ef41Sopenharmony_ci      return JSAsyncFromSyncIterator::kHeaderSize;
23761cb0ef41Sopenharmony_ci    case JS_GLOBAL_PROXY_TYPE:
23771cb0ef41Sopenharmony_ci      return JSGlobalProxy::kHeaderSize;
23781cb0ef41Sopenharmony_ci    case JS_GLOBAL_OBJECT_TYPE:
23791cb0ef41Sopenharmony_ci      return JSGlobalObject::kHeaderSize;
23801cb0ef41Sopenharmony_ci    case JS_BOUND_FUNCTION_TYPE:
23811cb0ef41Sopenharmony_ci      return JSBoundFunction::kHeaderSize;
23821cb0ef41Sopenharmony_ci    case JS_FUNCTION_TYPE:
23831cb0ef41Sopenharmony_ci    case JS_CLASS_CONSTRUCTOR_TYPE:
23841cb0ef41Sopenharmony_ci    case JS_PROMISE_CONSTRUCTOR_TYPE:
23851cb0ef41Sopenharmony_ci    case JS_REG_EXP_CONSTRUCTOR_TYPE:
23861cb0ef41Sopenharmony_ci    case JS_ARRAY_CONSTRUCTOR_TYPE:
23871cb0ef41Sopenharmony_ci#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
23881cb0ef41Sopenharmony_ci  case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
23891cb0ef41Sopenharmony_ci      TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTORS_SWITCH)
23901cb0ef41Sopenharmony_ci#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
23911cb0ef41Sopenharmony_ci      return JSFunction::GetHeaderSize(function_has_prototype_slot);
23921cb0ef41Sopenharmony_ci    case JS_PRIMITIVE_WRAPPER_TYPE:
23931cb0ef41Sopenharmony_ci      return JSPrimitiveWrapper::kHeaderSize;
23941cb0ef41Sopenharmony_ci    case JS_DATE_TYPE:
23951cb0ef41Sopenharmony_ci      return JSDate::kHeaderSize;
23961cb0ef41Sopenharmony_ci    case JS_ARRAY_TYPE:
23971cb0ef41Sopenharmony_ci      return JSArray::kHeaderSize;
23981cb0ef41Sopenharmony_ci    case JS_ARRAY_BUFFER_TYPE:
23991cb0ef41Sopenharmony_ci      return JSArrayBuffer::kHeaderSize;
24001cb0ef41Sopenharmony_ci    case JS_ARRAY_ITERATOR_TYPE:
24011cb0ef41Sopenharmony_ci      return JSArrayIterator::kHeaderSize;
24021cb0ef41Sopenharmony_ci    case JS_TYPED_ARRAY_TYPE:
24031cb0ef41Sopenharmony_ci      return JSTypedArray::kHeaderSize;
24041cb0ef41Sopenharmony_ci    case JS_DATA_VIEW_TYPE:
24051cb0ef41Sopenharmony_ci      return JSDataView::kHeaderSize;
24061cb0ef41Sopenharmony_ci    case JS_SET_TYPE:
24071cb0ef41Sopenharmony_ci      return JSSet::kHeaderSize;
24081cb0ef41Sopenharmony_ci    case JS_MAP_TYPE:
24091cb0ef41Sopenharmony_ci      return JSMap::kHeaderSize;
24101cb0ef41Sopenharmony_ci    case JS_SET_KEY_VALUE_ITERATOR_TYPE:
24111cb0ef41Sopenharmony_ci    case JS_SET_VALUE_ITERATOR_TYPE:
24121cb0ef41Sopenharmony_ci      return JSSetIterator::kHeaderSize;
24131cb0ef41Sopenharmony_ci    case JS_MAP_KEY_ITERATOR_TYPE:
24141cb0ef41Sopenharmony_ci    case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
24151cb0ef41Sopenharmony_ci    case JS_MAP_VALUE_ITERATOR_TYPE:
24161cb0ef41Sopenharmony_ci      return JSMapIterator::kHeaderSize;
24171cb0ef41Sopenharmony_ci    case JS_WEAK_REF_TYPE:
24181cb0ef41Sopenharmony_ci      return JSWeakRef::kHeaderSize;
24191cb0ef41Sopenharmony_ci    case JS_FINALIZATION_REGISTRY_TYPE:
24201cb0ef41Sopenharmony_ci      return JSFinalizationRegistry::kHeaderSize;
24211cb0ef41Sopenharmony_ci    case JS_WEAK_MAP_TYPE:
24221cb0ef41Sopenharmony_ci      return JSWeakMap::kHeaderSize;
24231cb0ef41Sopenharmony_ci    case JS_WEAK_SET_TYPE:
24241cb0ef41Sopenharmony_ci      return JSWeakSet::kHeaderSize;
24251cb0ef41Sopenharmony_ci    case JS_PROMISE_TYPE:
24261cb0ef41Sopenharmony_ci      return JSPromise::kHeaderSize;
24271cb0ef41Sopenharmony_ci    case JS_REG_EXP_TYPE:
24281cb0ef41Sopenharmony_ci      return JSRegExp::kHeaderSize;
24291cb0ef41Sopenharmony_ci    case JS_REG_EXP_STRING_ITERATOR_TYPE:
24301cb0ef41Sopenharmony_ci      return JSRegExpStringIterator::kHeaderSize;
24311cb0ef41Sopenharmony_ci    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
24321cb0ef41Sopenharmony_ci      return JSObject::kHeaderSize;
24331cb0ef41Sopenharmony_ci    case JS_MESSAGE_OBJECT_TYPE:
24341cb0ef41Sopenharmony_ci      return JSMessageObject::kHeaderSize;
24351cb0ef41Sopenharmony_ci    case JS_ARGUMENTS_OBJECT_TYPE:
24361cb0ef41Sopenharmony_ci      return JSObject::kHeaderSize;
24371cb0ef41Sopenharmony_ci    case JS_ERROR_TYPE:
24381cb0ef41Sopenharmony_ci      return JSObject::kHeaderSize;
24391cb0ef41Sopenharmony_ci    case JS_EXTERNAL_OBJECT_TYPE:
24401cb0ef41Sopenharmony_ci      return JSExternalObject::kHeaderSize;
24411cb0ef41Sopenharmony_ci    case JS_SHADOW_REALM_TYPE:
24421cb0ef41Sopenharmony_ci      return JSShadowRealm::kHeaderSize;
24431cb0ef41Sopenharmony_ci    case JS_STRING_ITERATOR_TYPE:
24441cb0ef41Sopenharmony_ci      return JSStringIterator::kHeaderSize;
24451cb0ef41Sopenharmony_ci    case JS_MODULE_NAMESPACE_TYPE:
24461cb0ef41Sopenharmony_ci      return JSModuleNamespace::kHeaderSize;
24471cb0ef41Sopenharmony_ci    case JS_SHARED_STRUCT_TYPE:
24481cb0ef41Sopenharmony_ci      return JSSharedStruct::kHeaderSize;
24491cb0ef41Sopenharmony_ci    case JS_TEMPORAL_CALENDAR_TYPE:
24501cb0ef41Sopenharmony_ci      return JSTemporalCalendar::kHeaderSize;
24511cb0ef41Sopenharmony_ci    case JS_TEMPORAL_DURATION_TYPE:
24521cb0ef41Sopenharmony_ci      return JSTemporalDuration::kHeaderSize;
24531cb0ef41Sopenharmony_ci    case JS_TEMPORAL_INSTANT_TYPE:
24541cb0ef41Sopenharmony_ci      return JSTemporalInstant::kHeaderSize;
24551cb0ef41Sopenharmony_ci    case JS_TEMPORAL_PLAIN_DATE_TYPE:
24561cb0ef41Sopenharmony_ci      return JSTemporalPlainDate::kHeaderSize;
24571cb0ef41Sopenharmony_ci    case JS_TEMPORAL_PLAIN_DATE_TIME_TYPE:
24581cb0ef41Sopenharmony_ci      return JSTemporalPlainDateTime::kHeaderSize;
24591cb0ef41Sopenharmony_ci    case JS_TEMPORAL_PLAIN_MONTH_DAY_TYPE:
24601cb0ef41Sopenharmony_ci      return JSTemporalPlainMonthDay::kHeaderSize;
24611cb0ef41Sopenharmony_ci    case JS_TEMPORAL_PLAIN_TIME_TYPE:
24621cb0ef41Sopenharmony_ci      return JSTemporalPlainTime::kHeaderSize;
24631cb0ef41Sopenharmony_ci    case JS_TEMPORAL_PLAIN_YEAR_MONTH_TYPE:
24641cb0ef41Sopenharmony_ci      return JSTemporalPlainYearMonth::kHeaderSize;
24651cb0ef41Sopenharmony_ci    case JS_TEMPORAL_TIME_ZONE_TYPE:
24661cb0ef41Sopenharmony_ci      return JSTemporalTimeZone::kHeaderSize;
24671cb0ef41Sopenharmony_ci    case JS_TEMPORAL_ZONED_DATE_TIME_TYPE:
24681cb0ef41Sopenharmony_ci      return JSTemporalZonedDateTime::kHeaderSize;
24691cb0ef41Sopenharmony_ci    case JS_WRAPPED_FUNCTION_TYPE:
24701cb0ef41Sopenharmony_ci      return JSWrappedFunction::kHeaderSize;
24711cb0ef41Sopenharmony_ci#ifdef V8_INTL_SUPPORT
24721cb0ef41Sopenharmony_ci    case JS_V8_BREAK_ITERATOR_TYPE:
24731cb0ef41Sopenharmony_ci      return JSV8BreakIterator::kHeaderSize;
24741cb0ef41Sopenharmony_ci    case JS_COLLATOR_TYPE:
24751cb0ef41Sopenharmony_ci      return JSCollator::kHeaderSize;
24761cb0ef41Sopenharmony_ci    case JS_DATE_TIME_FORMAT_TYPE:
24771cb0ef41Sopenharmony_ci      return JSDateTimeFormat::kHeaderSize;
24781cb0ef41Sopenharmony_ci    case JS_DISPLAY_NAMES_TYPE:
24791cb0ef41Sopenharmony_ci      return JSDisplayNames::kHeaderSize;
24801cb0ef41Sopenharmony_ci    case JS_LIST_FORMAT_TYPE:
24811cb0ef41Sopenharmony_ci      return JSListFormat::kHeaderSize;
24821cb0ef41Sopenharmony_ci    case JS_LOCALE_TYPE:
24831cb0ef41Sopenharmony_ci      return JSLocale::kHeaderSize;
24841cb0ef41Sopenharmony_ci    case JS_NUMBER_FORMAT_TYPE:
24851cb0ef41Sopenharmony_ci      return JSNumberFormat::kHeaderSize;
24861cb0ef41Sopenharmony_ci    case JS_PLURAL_RULES_TYPE:
24871cb0ef41Sopenharmony_ci      return JSPluralRules::kHeaderSize;
24881cb0ef41Sopenharmony_ci    case JS_RELATIVE_TIME_FORMAT_TYPE:
24891cb0ef41Sopenharmony_ci      return JSRelativeTimeFormat::kHeaderSize;
24901cb0ef41Sopenharmony_ci    case JS_SEGMENT_ITERATOR_TYPE:
24911cb0ef41Sopenharmony_ci      return JSSegmentIterator::kHeaderSize;
24921cb0ef41Sopenharmony_ci    case JS_SEGMENTER_TYPE:
24931cb0ef41Sopenharmony_ci      return JSSegmenter::kHeaderSize;
24941cb0ef41Sopenharmony_ci    case JS_SEGMENTS_TYPE:
24951cb0ef41Sopenharmony_ci      return JSSegments::kHeaderSize;
24961cb0ef41Sopenharmony_ci#endif  // V8_INTL_SUPPORT
24971cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
24981cb0ef41Sopenharmony_ci    case WASM_GLOBAL_OBJECT_TYPE:
24991cb0ef41Sopenharmony_ci      return WasmGlobalObject::kHeaderSize;
25001cb0ef41Sopenharmony_ci    case WASM_INSTANCE_OBJECT_TYPE:
25011cb0ef41Sopenharmony_ci      return WasmInstanceObject::kHeaderSize;
25021cb0ef41Sopenharmony_ci    case WASM_MEMORY_OBJECT_TYPE:
25031cb0ef41Sopenharmony_ci      return WasmMemoryObject::kHeaderSize;
25041cb0ef41Sopenharmony_ci    case WASM_MODULE_OBJECT_TYPE:
25051cb0ef41Sopenharmony_ci      return WasmModuleObject::kHeaderSize;
25061cb0ef41Sopenharmony_ci    case WASM_SUSPENDER_OBJECT_TYPE:
25071cb0ef41Sopenharmony_ci      return WasmSuspenderObject::kHeaderSize;
25081cb0ef41Sopenharmony_ci    case WASM_TABLE_OBJECT_TYPE:
25091cb0ef41Sopenharmony_ci      return WasmTableObject::kHeaderSize;
25101cb0ef41Sopenharmony_ci    case WASM_VALUE_OBJECT_TYPE:
25111cb0ef41Sopenharmony_ci      return WasmValueObject::kHeaderSize;
25121cb0ef41Sopenharmony_ci    case WASM_TAG_OBJECT_TYPE:
25131cb0ef41Sopenharmony_ci      return WasmTagObject::kHeaderSize;
25141cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
25151cb0ef41Sopenharmony_ci    default: {
25161cb0ef41Sopenharmony_ci      // Special type check for API Objects because they are in a large variable
25171cb0ef41Sopenharmony_ci      // instance type range.
25181cb0ef41Sopenharmony_ci      if (InstanceTypeChecker::IsJSApiObject(type)) {
25191cb0ef41Sopenharmony_ci        return JSObject::kHeaderSize;
25201cb0ef41Sopenharmony_ci      }
25211cb0ef41Sopenharmony_ci      std::stringstream ss;
25221cb0ef41Sopenharmony_ci      ss << type;
25231cb0ef41Sopenharmony_ci      FATAL("unexpected instance type: %s\n", ss.str().c_str());
25241cb0ef41Sopenharmony_ci    }
25251cb0ef41Sopenharmony_ci  }
25261cb0ef41Sopenharmony_ci}
25271cb0ef41Sopenharmony_ci
25281cb0ef41Sopenharmony_ci// static
25291cb0ef41Sopenharmony_cibool JSObject::AllCanRead(LookupIterator* it) {
25301cb0ef41Sopenharmony_ci  // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
25311cb0ef41Sopenharmony_ci  // which have already been checked.
25321cb0ef41Sopenharmony_ci  DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
25331cb0ef41Sopenharmony_ci         it->state() == LookupIterator::INTERCEPTOR);
25341cb0ef41Sopenharmony_ci  for (it->Next(); it->IsFound(); it->Next()) {
25351cb0ef41Sopenharmony_ci    if (it->state() == LookupIterator::ACCESSOR) {
25361cb0ef41Sopenharmony_ci      auto accessors = it->GetAccessors();
25371cb0ef41Sopenharmony_ci      if (accessors->IsAccessorInfo()) {
25381cb0ef41Sopenharmony_ci        if (AccessorInfo::cast(*accessors).all_can_read()) return true;
25391cb0ef41Sopenharmony_ci      }
25401cb0ef41Sopenharmony_ci    } else if (it->state() == LookupIterator::INTERCEPTOR) {
25411cb0ef41Sopenharmony_ci      if (it->GetInterceptor()->all_can_read()) return true;
25421cb0ef41Sopenharmony_ci    } else if (it->state() == LookupIterator::JSPROXY) {
25431cb0ef41Sopenharmony_ci      // Stop lookupiterating. And no, AllCanNotRead.
25441cb0ef41Sopenharmony_ci      return false;
25451cb0ef41Sopenharmony_ci    }
25461cb0ef41Sopenharmony_ci  }
25471cb0ef41Sopenharmony_ci  return false;
25481cb0ef41Sopenharmony_ci}
25491cb0ef41Sopenharmony_ci
25501cb0ef41Sopenharmony_ciMaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
25511cb0ef41Sopenharmony_ci    LookupIterator* it) {
25521cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
25531cb0ef41Sopenharmony_ci  Handle<JSObject> checked = it->GetHolder<JSObject>();
25541cb0ef41Sopenharmony_ci  Handle<InterceptorInfo> interceptor =
25551cb0ef41Sopenharmony_ci      it->GetInterceptorForFailedAccessCheck();
25561cb0ef41Sopenharmony_ci  if (interceptor.is_null()) {
25571cb0ef41Sopenharmony_ci    while (AllCanRead(it)) {
25581cb0ef41Sopenharmony_ci      if (it->state() == LookupIterator::ACCESSOR) {
25591cb0ef41Sopenharmony_ci        return Object::GetPropertyWithAccessor(it);
25601cb0ef41Sopenharmony_ci      }
25611cb0ef41Sopenharmony_ci      DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
25621cb0ef41Sopenharmony_ci      bool done;
25631cb0ef41Sopenharmony_ci      Handle<Object> result;
25641cb0ef41Sopenharmony_ci      ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
25651cb0ef41Sopenharmony_ci                                 GetPropertyWithInterceptor(it, &done), Object);
25661cb0ef41Sopenharmony_ci      if (done) return result;
25671cb0ef41Sopenharmony_ci    }
25681cb0ef41Sopenharmony_ci
25691cb0ef41Sopenharmony_ci  } else {
25701cb0ef41Sopenharmony_ci    Handle<Object> result;
25711cb0ef41Sopenharmony_ci    bool done;
25721cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION(
25731cb0ef41Sopenharmony_ci        isolate, result,
25741cb0ef41Sopenharmony_ci        GetPropertyWithInterceptorInternal(it, interceptor, &done), Object);
25751cb0ef41Sopenharmony_ci    if (done) return result;
25761cb0ef41Sopenharmony_ci  }
25771cb0ef41Sopenharmony_ci
25781cb0ef41Sopenharmony_ci  // Cross-Origin [[Get]] of Well-Known Symbols does not throw, and returns
25791cb0ef41Sopenharmony_ci  // undefined.
25801cb0ef41Sopenharmony_ci  Handle<Name> name = it->GetName();
25811cb0ef41Sopenharmony_ci  if (name->IsSymbol() && Symbol::cast(*name).is_well_known_symbol()) {
25821cb0ef41Sopenharmony_ci    return it->factory()->undefined_value();
25831cb0ef41Sopenharmony_ci  }
25841cb0ef41Sopenharmony_ci
25851cb0ef41Sopenharmony_ci  isolate->ReportFailedAccessCheck(checked);
25861cb0ef41Sopenharmony_ci  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
25871cb0ef41Sopenharmony_ci  return it->factory()->undefined_value();
25881cb0ef41Sopenharmony_ci}
25891cb0ef41Sopenharmony_ci
25901cb0ef41Sopenharmony_ciMaybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
25911cb0ef41Sopenharmony_ci    LookupIterator* it) {
25921cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
25931cb0ef41Sopenharmony_ci  Handle<JSObject> checked = it->GetHolder<JSObject>();
25941cb0ef41Sopenharmony_ci  Handle<InterceptorInfo> interceptor =
25951cb0ef41Sopenharmony_ci      it->GetInterceptorForFailedAccessCheck();
25961cb0ef41Sopenharmony_ci  if (interceptor.is_null()) {
25971cb0ef41Sopenharmony_ci    while (AllCanRead(it)) {
25981cb0ef41Sopenharmony_ci      if (it->state() == LookupIterator::ACCESSOR) {
25991cb0ef41Sopenharmony_ci        return Just(it->property_attributes());
26001cb0ef41Sopenharmony_ci      }
26011cb0ef41Sopenharmony_ci      DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
26021cb0ef41Sopenharmony_ci      auto result = GetPropertyAttributesWithInterceptor(it);
26031cb0ef41Sopenharmony_ci      if (isolate->has_scheduled_exception()) break;
26041cb0ef41Sopenharmony_ci      if (result.IsJust() && result.FromJust() != ABSENT) return result;
26051cb0ef41Sopenharmony_ci    }
26061cb0ef41Sopenharmony_ci  } else {
26071cb0ef41Sopenharmony_ci    Maybe<PropertyAttributes> result =
26081cb0ef41Sopenharmony_ci        GetPropertyAttributesWithInterceptorInternal(it, interceptor);
26091cb0ef41Sopenharmony_ci    if (isolate->has_pending_exception()) return Nothing<PropertyAttributes>();
26101cb0ef41Sopenharmony_ci    if (result.FromMaybe(ABSENT) != ABSENT) return result;
26111cb0ef41Sopenharmony_ci  }
26121cb0ef41Sopenharmony_ci  isolate->ReportFailedAccessCheck(checked);
26131cb0ef41Sopenharmony_ci  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
26141cb0ef41Sopenharmony_ci  return Just(ABSENT);
26151cb0ef41Sopenharmony_ci}
26161cb0ef41Sopenharmony_ci
26171cb0ef41Sopenharmony_ci// static
26181cb0ef41Sopenharmony_cibool JSObject::AllCanWrite(LookupIterator* it) {
26191cb0ef41Sopenharmony_ci  for (; it->IsFound() && it->state() != LookupIterator::JSPROXY; it->Next()) {
26201cb0ef41Sopenharmony_ci    if (it->state() == LookupIterator::ACCESSOR) {
26211cb0ef41Sopenharmony_ci      Handle<Object> accessors = it->GetAccessors();
26221cb0ef41Sopenharmony_ci      if (accessors->IsAccessorInfo()) {
26231cb0ef41Sopenharmony_ci        if (AccessorInfo::cast(*accessors).all_can_write()) return true;
26241cb0ef41Sopenharmony_ci      }
26251cb0ef41Sopenharmony_ci    }
26261cb0ef41Sopenharmony_ci  }
26271cb0ef41Sopenharmony_ci  return false;
26281cb0ef41Sopenharmony_ci}
26291cb0ef41Sopenharmony_ci
26301cb0ef41Sopenharmony_ciMaybe<bool> JSObject::SetPropertyWithFailedAccessCheck(
26311cb0ef41Sopenharmony_ci    LookupIterator* it, Handle<Object> value, Maybe<ShouldThrow> should_throw) {
26321cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
26331cb0ef41Sopenharmony_ci  Handle<JSObject> checked = it->GetHolder<JSObject>();
26341cb0ef41Sopenharmony_ci  Handle<InterceptorInfo> interceptor =
26351cb0ef41Sopenharmony_ci      it->GetInterceptorForFailedAccessCheck();
26361cb0ef41Sopenharmony_ci  if (interceptor.is_null()) {
26371cb0ef41Sopenharmony_ci    if (AllCanWrite(it)) {
26381cb0ef41Sopenharmony_ci      return Object::SetPropertyWithAccessor(it, value, should_throw);
26391cb0ef41Sopenharmony_ci    }
26401cb0ef41Sopenharmony_ci  } else {
26411cb0ef41Sopenharmony_ci    Maybe<bool> result = SetPropertyWithInterceptorInternal(
26421cb0ef41Sopenharmony_ci        it, interceptor, should_throw, value);
26431cb0ef41Sopenharmony_ci    if (isolate->has_pending_exception()) return Nothing<bool>();
26441cb0ef41Sopenharmony_ci    if (result.IsJust()) return result;
26451cb0ef41Sopenharmony_ci  }
26461cb0ef41Sopenharmony_ci  isolate->ReportFailedAccessCheck(checked);
26471cb0ef41Sopenharmony_ci  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
26481cb0ef41Sopenharmony_ci  return Just(true);
26491cb0ef41Sopenharmony_ci}
26501cb0ef41Sopenharmony_ci
26511cb0ef41Sopenharmony_civoid JSObject::SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
26521cb0ef41Sopenharmony_ci                                     Handle<Object> value,
26531cb0ef41Sopenharmony_ci                                     PropertyDetails details) {
26541cb0ef41Sopenharmony_ci  DCHECK(!object->HasFastProperties());
26551cb0ef41Sopenharmony_ci  DCHECK(name->IsUniqueName());
26561cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
26571cb0ef41Sopenharmony_ci
26581cb0ef41Sopenharmony_ci  uint32_t hash = name->hash();
26591cb0ef41Sopenharmony_ci
26601cb0ef41Sopenharmony_ci  if (object->IsJSGlobalObject()) {
26611cb0ef41Sopenharmony_ci    Handle<JSGlobalObject> global_obj = Handle<JSGlobalObject>::cast(object);
26621cb0ef41Sopenharmony_ci    Handle<GlobalDictionary> dictionary(
26631cb0ef41Sopenharmony_ci        global_obj->global_dictionary(kAcquireLoad), isolate);
26641cb0ef41Sopenharmony_ci    ReadOnlyRoots roots(isolate);
26651cb0ef41Sopenharmony_ci    InternalIndex entry = dictionary->FindEntry(isolate, roots, name, hash);
26661cb0ef41Sopenharmony_ci
26671cb0ef41Sopenharmony_ci    if (entry.is_not_found()) {
26681cb0ef41Sopenharmony_ci      DCHECK_IMPLIES(global_obj->map().is_prototype_map(),
26691cb0ef41Sopenharmony_ci                     Map::IsPrototypeChainInvalidated(global_obj->map()));
26701cb0ef41Sopenharmony_ci      auto cell_type = value->IsUndefined(roots) ? PropertyCellType::kUndefined
26711cb0ef41Sopenharmony_ci                                                 : PropertyCellType::kConstant;
26721cb0ef41Sopenharmony_ci      details = details.set_cell_type(cell_type);
26731cb0ef41Sopenharmony_ci      auto cell = isolate->factory()->NewPropertyCell(name, details, value);
26741cb0ef41Sopenharmony_ci      dictionary =
26751cb0ef41Sopenharmony_ci          GlobalDictionary::Add(isolate, dictionary, name, cell, details);
26761cb0ef41Sopenharmony_ci      global_obj->set_global_dictionary(*dictionary, kReleaseStore);
26771cb0ef41Sopenharmony_ci    } else {
26781cb0ef41Sopenharmony_ci      PropertyCell::PrepareForAndSetValue(isolate, dictionary, entry, value,
26791cb0ef41Sopenharmony_ci                                          details);
26801cb0ef41Sopenharmony_ci      DCHECK_EQ(dictionary->CellAt(entry).value(), *value);
26811cb0ef41Sopenharmony_ci    }
26821cb0ef41Sopenharmony_ci  } else {
26831cb0ef41Sopenharmony_ci    if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
26841cb0ef41Sopenharmony_ci      Handle<SwissNameDictionary> dictionary(
26851cb0ef41Sopenharmony_ci          object->property_dictionary_swiss(), isolate);
26861cb0ef41Sopenharmony_ci      InternalIndex entry = dictionary->FindEntry(isolate, *name);
26871cb0ef41Sopenharmony_ci      if (entry.is_not_found()) {
26881cb0ef41Sopenharmony_ci        DCHECK_IMPLIES(object->map().is_prototype_map(),
26891cb0ef41Sopenharmony_ci                       Map::IsPrototypeChainInvalidated(object->map()));
26901cb0ef41Sopenharmony_ci        dictionary =
26911cb0ef41Sopenharmony_ci            SwissNameDictionary::Add(isolate, dictionary, name, value, details);
26921cb0ef41Sopenharmony_ci        object->SetProperties(*dictionary);
26931cb0ef41Sopenharmony_ci      } else {
26941cb0ef41Sopenharmony_ci        dictionary->ValueAtPut(entry, *value);
26951cb0ef41Sopenharmony_ci        dictionary->DetailsAtPut(entry, details);
26961cb0ef41Sopenharmony_ci      }
26971cb0ef41Sopenharmony_ci    } else {
26981cb0ef41Sopenharmony_ci      Handle<NameDictionary> dictionary(object->property_dictionary(), isolate);
26991cb0ef41Sopenharmony_ci      InternalIndex entry = dictionary->FindEntry(isolate, name);
27001cb0ef41Sopenharmony_ci      if (entry.is_not_found()) {
27011cb0ef41Sopenharmony_ci        DCHECK_IMPLIES(object->map().is_prototype_map(),
27021cb0ef41Sopenharmony_ci                       Map::IsPrototypeChainInvalidated(object->map()));
27031cb0ef41Sopenharmony_ci        dictionary =
27041cb0ef41Sopenharmony_ci            NameDictionary::Add(isolate, dictionary, name, value, details);
27051cb0ef41Sopenharmony_ci        object->SetProperties(*dictionary);
27061cb0ef41Sopenharmony_ci      } else {
27071cb0ef41Sopenharmony_ci        PropertyDetails original_details = dictionary->DetailsAt(entry);
27081cb0ef41Sopenharmony_ci        int enumeration_index = original_details.dictionary_index();
27091cb0ef41Sopenharmony_ci        DCHECK_GT(enumeration_index, 0);
27101cb0ef41Sopenharmony_ci        details = details.set_index(enumeration_index);
27111cb0ef41Sopenharmony_ci        dictionary->SetEntry(entry, *name, *value, details);
27121cb0ef41Sopenharmony_ci      }
27131cb0ef41Sopenharmony_ci    }
27141cb0ef41Sopenharmony_ci  }
27151cb0ef41Sopenharmony_ci}
27161cb0ef41Sopenharmony_ci
27171cb0ef41Sopenharmony_civoid JSObject::SetNormalizedElement(Handle<JSObject> object, uint32_t index,
27181cb0ef41Sopenharmony_ci                                    Handle<Object> value,
27191cb0ef41Sopenharmony_ci                                    PropertyDetails details) {
27201cb0ef41Sopenharmony_ci  DCHECK_EQ(object->GetElementsKind(), DICTIONARY_ELEMENTS);
27211cb0ef41Sopenharmony_ci
27221cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
27231cb0ef41Sopenharmony_ci
27241cb0ef41Sopenharmony_ci  Handle<NumberDictionary> dictionary =
27251cb0ef41Sopenharmony_ci      handle(NumberDictionary::cast(object->elements()), isolate);
27261cb0ef41Sopenharmony_ci  dictionary =
27271cb0ef41Sopenharmony_ci      NumberDictionary::Set(isolate, dictionary, index, value, object, details);
27281cb0ef41Sopenharmony_ci  object->set_elements(*dictionary);
27291cb0ef41Sopenharmony_ci}
27301cb0ef41Sopenharmony_ci
27311cb0ef41Sopenharmony_civoid JSObject::JSObjectShortPrint(StringStream* accumulator) {
27321cb0ef41Sopenharmony_ci  switch (map().instance_type()) {
27331cb0ef41Sopenharmony_ci    case JS_ARRAY_TYPE: {
27341cb0ef41Sopenharmony_ci      double length = JSArray::cast(*this).length().IsUndefined()
27351cb0ef41Sopenharmony_ci                          ? 0
27361cb0ef41Sopenharmony_ci                          : JSArray::cast(*this).length().Number();
27371cb0ef41Sopenharmony_ci      accumulator->Add("<JSArray[%u]>", static_cast<uint32_t>(length));
27381cb0ef41Sopenharmony_ci      break;
27391cb0ef41Sopenharmony_ci    }
27401cb0ef41Sopenharmony_ci    case JS_BOUND_FUNCTION_TYPE: {
27411cb0ef41Sopenharmony_ci      JSBoundFunction bound_function = JSBoundFunction::cast(*this);
27421cb0ef41Sopenharmony_ci      accumulator->Add("<JSBoundFunction");
27431cb0ef41Sopenharmony_ci      accumulator->Add(" (BoundTargetFunction %p)>",
27441cb0ef41Sopenharmony_ci                       reinterpret_cast<void*>(
27451cb0ef41Sopenharmony_ci                           bound_function.bound_target_function().ptr()));
27461cb0ef41Sopenharmony_ci      break;
27471cb0ef41Sopenharmony_ci    }
27481cb0ef41Sopenharmony_ci    case JS_WEAK_MAP_TYPE: {
27491cb0ef41Sopenharmony_ci      accumulator->Add("<JSWeakMap>");
27501cb0ef41Sopenharmony_ci      break;
27511cb0ef41Sopenharmony_ci    }
27521cb0ef41Sopenharmony_ci    case JS_WEAK_SET_TYPE: {
27531cb0ef41Sopenharmony_ci      accumulator->Add("<JSWeakSet>");
27541cb0ef41Sopenharmony_ci      break;
27551cb0ef41Sopenharmony_ci    }
27561cb0ef41Sopenharmony_ci    case JS_REG_EXP_TYPE: {
27571cb0ef41Sopenharmony_ci      accumulator->Add("<JSRegExp");
27581cb0ef41Sopenharmony_ci      JSRegExp regexp = JSRegExp::cast(*this);
27591cb0ef41Sopenharmony_ci      if (regexp.source().IsString()) {
27601cb0ef41Sopenharmony_ci        accumulator->Add(" ");
27611cb0ef41Sopenharmony_ci        String::cast(regexp.source()).StringShortPrint(accumulator);
27621cb0ef41Sopenharmony_ci      }
27631cb0ef41Sopenharmony_ci      accumulator->Add(">");
27641cb0ef41Sopenharmony_ci
27651cb0ef41Sopenharmony_ci      break;
27661cb0ef41Sopenharmony_ci    }
27671cb0ef41Sopenharmony_ci    case JS_PROMISE_CONSTRUCTOR_TYPE:
27681cb0ef41Sopenharmony_ci    case JS_REG_EXP_CONSTRUCTOR_TYPE:
27691cb0ef41Sopenharmony_ci    case JS_ARRAY_CONSTRUCTOR_TYPE:
27701cb0ef41Sopenharmony_ci#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
27711cb0ef41Sopenharmony_ci  case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
27721cb0ef41Sopenharmony_ci      TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTORS_SWITCH)
27731cb0ef41Sopenharmony_ci#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
27741cb0ef41Sopenharmony_ci    case JS_CLASS_CONSTRUCTOR_TYPE:
27751cb0ef41Sopenharmony_ci    case JS_FUNCTION_TYPE: {
27761cb0ef41Sopenharmony_ci      JSFunction function = JSFunction::cast(*this);
27771cb0ef41Sopenharmony_ci      std::unique_ptr<char[]> fun_name = function.shared().DebugNameCStr();
27781cb0ef41Sopenharmony_ci      if (fun_name[0] != '\0') {
27791cb0ef41Sopenharmony_ci        accumulator->Add("<JSFunction ");
27801cb0ef41Sopenharmony_ci        accumulator->Add(fun_name.get());
27811cb0ef41Sopenharmony_ci      } else {
27821cb0ef41Sopenharmony_ci        accumulator->Add("<JSFunction");
27831cb0ef41Sopenharmony_ci      }
27841cb0ef41Sopenharmony_ci      if (FLAG_trace_file_names) {
27851cb0ef41Sopenharmony_ci        Object source_name = Script::cast(function.shared().script()).name();
27861cb0ef41Sopenharmony_ci        if (source_name.IsString()) {
27871cb0ef41Sopenharmony_ci          String str = String::cast(source_name);
27881cb0ef41Sopenharmony_ci          if (str.length() > 0) {
27891cb0ef41Sopenharmony_ci            accumulator->Add(" <");
27901cb0ef41Sopenharmony_ci            accumulator->Put(str);
27911cb0ef41Sopenharmony_ci            accumulator->Add(">");
27921cb0ef41Sopenharmony_ci          }
27931cb0ef41Sopenharmony_ci        }
27941cb0ef41Sopenharmony_ci      }
27951cb0ef41Sopenharmony_ci      accumulator->Add(" (sfi = %p)",
27961cb0ef41Sopenharmony_ci                       reinterpret_cast<void*>(function.shared().ptr()));
27971cb0ef41Sopenharmony_ci      accumulator->Put('>');
27981cb0ef41Sopenharmony_ci      break;
27991cb0ef41Sopenharmony_ci    }
28001cb0ef41Sopenharmony_ci    case JS_GENERATOR_OBJECT_TYPE: {
28011cb0ef41Sopenharmony_ci      accumulator->Add("<JSGenerator>");
28021cb0ef41Sopenharmony_ci      break;
28031cb0ef41Sopenharmony_ci    }
28041cb0ef41Sopenharmony_ci    case JS_ASYNC_FUNCTION_OBJECT_TYPE: {
28051cb0ef41Sopenharmony_ci      accumulator->Add("<JSAsyncFunctionObject>");
28061cb0ef41Sopenharmony_ci      break;
28071cb0ef41Sopenharmony_ci    }
28081cb0ef41Sopenharmony_ci    case JS_ASYNC_GENERATOR_OBJECT_TYPE: {
28091cb0ef41Sopenharmony_ci      accumulator->Add("<JS AsyncGenerator>");
28101cb0ef41Sopenharmony_ci      break;
28111cb0ef41Sopenharmony_ci    }
28121cb0ef41Sopenharmony_ci
28131cb0ef41Sopenharmony_ci    // All other JSObjects are rather similar to each other (JSObject,
28141cb0ef41Sopenharmony_ci    // JSGlobalProxy, JSGlobalObject, JSUndetectable, JSPrimitiveWrapper).
28151cb0ef41Sopenharmony_ci    default: {
28161cb0ef41Sopenharmony_ci      Map map_of_this = map();
28171cb0ef41Sopenharmony_ci      Heap* heap = GetHeap();
28181cb0ef41Sopenharmony_ci      Object constructor = map_of_this.GetConstructor();
28191cb0ef41Sopenharmony_ci      bool printed = false;
28201cb0ef41Sopenharmony_ci      if (constructor.IsHeapObject() &&
28211cb0ef41Sopenharmony_ci          !heap->Contains(HeapObject::cast(constructor))) {
28221cb0ef41Sopenharmony_ci        accumulator->Add("!!!INVALID CONSTRUCTOR!!!");
28231cb0ef41Sopenharmony_ci      } else {
28241cb0ef41Sopenharmony_ci        bool is_global_proxy = IsJSGlobalProxy();
28251cb0ef41Sopenharmony_ci        if (constructor.IsJSFunction()) {
28261cb0ef41Sopenharmony_ci          if (!heap->Contains(JSFunction::cast(constructor).shared())) {
28271cb0ef41Sopenharmony_ci            accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!");
28281cb0ef41Sopenharmony_ci          } else {
28291cb0ef41Sopenharmony_ci            String constructor_name =
28301cb0ef41Sopenharmony_ci                JSFunction::cast(constructor).shared().Name();
28311cb0ef41Sopenharmony_ci            if (constructor_name.length() > 0) {
28321cb0ef41Sopenharmony_ci              accumulator->Add(is_global_proxy ? "<GlobalObject " : "<");
28331cb0ef41Sopenharmony_ci              accumulator->Put(constructor_name);
28341cb0ef41Sopenharmony_ci              accumulator->Add(" %smap = %p",
28351cb0ef41Sopenharmony_ci                               map_of_this.is_deprecated() ? "deprecated-" : "",
28361cb0ef41Sopenharmony_ci                               map_of_this);
28371cb0ef41Sopenharmony_ci              printed = true;
28381cb0ef41Sopenharmony_ci            }
28391cb0ef41Sopenharmony_ci          }
28401cb0ef41Sopenharmony_ci        } else if (constructor.IsFunctionTemplateInfo()) {
28411cb0ef41Sopenharmony_ci          accumulator->Add("<RemoteObject>");
28421cb0ef41Sopenharmony_ci          printed = true;
28431cb0ef41Sopenharmony_ci        }
28441cb0ef41Sopenharmony_ci        if (!printed) {
28451cb0ef41Sopenharmony_ci          accumulator->Add("<JS");
28461cb0ef41Sopenharmony_ci          if (is_global_proxy) {
28471cb0ef41Sopenharmony_ci            accumulator->Add("GlobalProxy");
28481cb0ef41Sopenharmony_ci          } else if (IsJSGlobalObject()) {
28491cb0ef41Sopenharmony_ci            accumulator->Add("GlobalObject");
28501cb0ef41Sopenharmony_ci          } else {
28511cb0ef41Sopenharmony_ci            accumulator->Add("Object");
28521cb0ef41Sopenharmony_ci          }
28531cb0ef41Sopenharmony_ci        }
28541cb0ef41Sopenharmony_ci      }
28551cb0ef41Sopenharmony_ci      if (IsJSPrimitiveWrapper()) {
28561cb0ef41Sopenharmony_ci        accumulator->Add(" value = ");
28571cb0ef41Sopenharmony_ci        JSPrimitiveWrapper::cast(*this).value().ShortPrint(accumulator);
28581cb0ef41Sopenharmony_ci      }
28591cb0ef41Sopenharmony_ci      accumulator->Put('>');
28601cb0ef41Sopenharmony_ci      break;
28611cb0ef41Sopenharmony_ci    }
28621cb0ef41Sopenharmony_ci  }
28631cb0ef41Sopenharmony_ci}
28641cb0ef41Sopenharmony_ci
28651cb0ef41Sopenharmony_civoid JSObject::PrintElementsTransition(FILE* file, Handle<JSObject> object,
28661cb0ef41Sopenharmony_ci                                       ElementsKind from_kind,
28671cb0ef41Sopenharmony_ci                                       Handle<FixedArrayBase> from_elements,
28681cb0ef41Sopenharmony_ci                                       ElementsKind to_kind,
28691cb0ef41Sopenharmony_ci                                       Handle<FixedArrayBase> to_elements) {
28701cb0ef41Sopenharmony_ci  if (from_kind != to_kind) {
28711cb0ef41Sopenharmony_ci    OFStream os(file);
28721cb0ef41Sopenharmony_ci    os << "elements transition [" << ElementsKindToString(from_kind) << " -> "
28731cb0ef41Sopenharmony_ci       << ElementsKindToString(to_kind) << "] in ";
28741cb0ef41Sopenharmony_ci    JavaScriptFrame::PrintTop(object->GetIsolate(), file, false, true);
28751cb0ef41Sopenharmony_ci    PrintF(file, " for ");
28761cb0ef41Sopenharmony_ci    object->ShortPrint(file);
28771cb0ef41Sopenharmony_ci    PrintF(file, " from ");
28781cb0ef41Sopenharmony_ci    from_elements->ShortPrint(file);
28791cb0ef41Sopenharmony_ci    PrintF(file, " to ");
28801cb0ef41Sopenharmony_ci    to_elements->ShortPrint(file);
28811cb0ef41Sopenharmony_ci    PrintF(file, "\n");
28821cb0ef41Sopenharmony_ci  }
28831cb0ef41Sopenharmony_ci}
28841cb0ef41Sopenharmony_ci
28851cb0ef41Sopenharmony_civoid JSObject::PrintInstanceMigration(FILE* file, Map original_map,
28861cb0ef41Sopenharmony_ci                                      Map new_map) {
28871cb0ef41Sopenharmony_ci  if (new_map.is_dictionary_map()) {
28881cb0ef41Sopenharmony_ci    PrintF(file, "[migrating to slow]\n");
28891cb0ef41Sopenharmony_ci    return;
28901cb0ef41Sopenharmony_ci  }
28911cb0ef41Sopenharmony_ci  PrintF(file, "[migrating]");
28921cb0ef41Sopenharmony_ci  Isolate* isolate = GetIsolate();
28931cb0ef41Sopenharmony_ci  DescriptorArray o = original_map.instance_descriptors(isolate);
28941cb0ef41Sopenharmony_ci  DescriptorArray n = new_map.instance_descriptors(isolate);
28951cb0ef41Sopenharmony_ci  for (InternalIndex i : original_map.IterateOwnDescriptors()) {
28961cb0ef41Sopenharmony_ci    Representation o_r = o.GetDetails(i).representation();
28971cb0ef41Sopenharmony_ci    Representation n_r = n.GetDetails(i).representation();
28981cb0ef41Sopenharmony_ci    if (!o_r.Equals(n_r)) {
28991cb0ef41Sopenharmony_ci      String::cast(o.GetKey(i)).PrintOn(file);
29001cb0ef41Sopenharmony_ci      PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic());
29011cb0ef41Sopenharmony_ci    } else if (o.GetDetails(i).location() == PropertyLocation::kDescriptor &&
29021cb0ef41Sopenharmony_ci               n.GetDetails(i).location() == PropertyLocation::kField) {
29031cb0ef41Sopenharmony_ci      Name name = o.GetKey(i);
29041cb0ef41Sopenharmony_ci      if (name.IsString()) {
29051cb0ef41Sopenharmony_ci        String::cast(name).PrintOn(file);
29061cb0ef41Sopenharmony_ci      } else {
29071cb0ef41Sopenharmony_ci        PrintF(file, "{symbol %p}", reinterpret_cast<void*>(name.ptr()));
29081cb0ef41Sopenharmony_ci      }
29091cb0ef41Sopenharmony_ci      PrintF(file, " ");
29101cb0ef41Sopenharmony_ci    }
29111cb0ef41Sopenharmony_ci  }
29121cb0ef41Sopenharmony_ci  if (original_map.elements_kind() != new_map.elements_kind()) {
29131cb0ef41Sopenharmony_ci    PrintF(file, "elements_kind[%i->%i]", original_map.elements_kind(),
29141cb0ef41Sopenharmony_ci           new_map.elements_kind());
29151cb0ef41Sopenharmony_ci  }
29161cb0ef41Sopenharmony_ci  PrintF(file, "\n");
29171cb0ef41Sopenharmony_ci}
29181cb0ef41Sopenharmony_ci
29191cb0ef41Sopenharmony_cibool JSObject::IsUnmodifiedApiObject(FullObjectSlot o) {
29201cb0ef41Sopenharmony_ci  Object object = *o;
29211cb0ef41Sopenharmony_ci  if (object.IsSmi()) return false;
29221cb0ef41Sopenharmony_ci  HeapObject heap_object = HeapObject::cast(object);
29231cb0ef41Sopenharmony_ci  if (!object.IsJSObject()) return false;
29241cb0ef41Sopenharmony_ci  JSObject js_object = JSObject::cast(object);
29251cb0ef41Sopenharmony_ci  if (!js_object.IsDroppableApiObject()) return false;
29261cb0ef41Sopenharmony_ci  Object maybe_constructor = js_object.map().GetConstructor();
29271cb0ef41Sopenharmony_ci  if (!maybe_constructor.IsJSFunction()) return false;
29281cb0ef41Sopenharmony_ci  JSFunction constructor = JSFunction::cast(maybe_constructor);
29291cb0ef41Sopenharmony_ci  if (js_object.elements().length() != 0) return false;
29301cb0ef41Sopenharmony_ci  // Check that the object is not a key in a WeakMap (over-approximation).
29311cb0ef41Sopenharmony_ci  if (!js_object.GetIdentityHash().IsUndefined()) return false;
29321cb0ef41Sopenharmony_ci
29331cb0ef41Sopenharmony_ci  return constructor.initial_map() == heap_object.map();
29341cb0ef41Sopenharmony_ci}
29351cb0ef41Sopenharmony_ci
29361cb0ef41Sopenharmony_ci// static
29371cb0ef41Sopenharmony_civoid JSObject::UpdatePrototypeUserRegistration(Handle<Map> old_map,
29381cb0ef41Sopenharmony_ci                                               Handle<Map> new_map,
29391cb0ef41Sopenharmony_ci                                               Isolate* isolate) {
29401cb0ef41Sopenharmony_ci  DCHECK(old_map->is_prototype_map());
29411cb0ef41Sopenharmony_ci  DCHECK(new_map->is_prototype_map());
29421cb0ef41Sopenharmony_ci  bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
29431cb0ef41Sopenharmony_ci  new_map->set_prototype_info(old_map->prototype_info(), kReleaseStore);
29441cb0ef41Sopenharmony_ci  old_map->set_prototype_info(Smi::zero(), kReleaseStore);
29451cb0ef41Sopenharmony_ci  if (FLAG_trace_prototype_users) {
29461cb0ef41Sopenharmony_ci    PrintF("Moving prototype_info %p from map %p to map %p.\n",
29471cb0ef41Sopenharmony_ci           reinterpret_cast<void*>(new_map->prototype_info().ptr()),
29481cb0ef41Sopenharmony_ci           reinterpret_cast<void*>(old_map->ptr()),
29491cb0ef41Sopenharmony_ci           reinterpret_cast<void*>(new_map->ptr()));
29501cb0ef41Sopenharmony_ci  }
29511cb0ef41Sopenharmony_ci  if (was_registered) {
29521cb0ef41Sopenharmony_ci    if (new_map->prototype_info().IsPrototypeInfo()) {
29531cb0ef41Sopenharmony_ci      // The new map isn't registered with its prototype yet; reflect this fact
29541cb0ef41Sopenharmony_ci      // in the PrototypeInfo it just inherited from the old map.
29551cb0ef41Sopenharmony_ci      PrototypeInfo::cast(new_map->prototype_info())
29561cb0ef41Sopenharmony_ci          .set_registry_slot(PrototypeInfo::UNREGISTERED);
29571cb0ef41Sopenharmony_ci    }
29581cb0ef41Sopenharmony_ci    JSObject::LazyRegisterPrototypeUser(new_map, isolate);
29591cb0ef41Sopenharmony_ci  }
29601cb0ef41Sopenharmony_ci}
29611cb0ef41Sopenharmony_ci
29621cb0ef41Sopenharmony_ci// static
29631cb0ef41Sopenharmony_civoid JSObject::NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
29641cb0ef41Sopenharmony_ci                               Isolate* isolate) {
29651cb0ef41Sopenharmony_ci  if (!old_map->is_prototype_map()) return;
29661cb0ef41Sopenharmony_ci
29671cb0ef41Sopenharmony_ci  InvalidatePrototypeChains(*old_map);
29681cb0ef41Sopenharmony_ci
29691cb0ef41Sopenharmony_ci  // If the map was registered with its prototype before, ensure that it
29701cb0ef41Sopenharmony_ci  // registers with its new prototype now. This preserves the invariant that
29711cb0ef41Sopenharmony_ci  // when a map on a prototype chain is registered with its prototype, then
29721cb0ef41Sopenharmony_ci  // all prototypes further up the chain are also registered with their
29731cb0ef41Sopenharmony_ci  // respective prototypes.
29741cb0ef41Sopenharmony_ci  UpdatePrototypeUserRegistration(old_map, new_map, isolate);
29751cb0ef41Sopenharmony_ci}
29761cb0ef41Sopenharmony_ci
29771cb0ef41Sopenharmony_cinamespace {
29781cb0ef41Sopenharmony_ci
29791cb0ef41Sopenharmony_ci// To migrate a fast instance to a fast map:
29801cb0ef41Sopenharmony_ci// - First check whether the instance needs to be rewritten. If not, simply
29811cb0ef41Sopenharmony_ci//   change the map.
29821cb0ef41Sopenharmony_ci// - Otherwise, allocate a fixed array large enough to hold all fields, in
29831cb0ef41Sopenharmony_ci//   addition to unused space.
29841cb0ef41Sopenharmony_ci// - Copy all existing properties in, in the following order: backing store
29851cb0ef41Sopenharmony_ci//   properties, unused fields, inobject properties.
29861cb0ef41Sopenharmony_ci// - If all allocation succeeded, commit the state atomically:
29871cb0ef41Sopenharmony_ci//   * Copy inobject properties from the backing store back into the object.
29881cb0ef41Sopenharmony_ci//   * Trim the difference in instance size of the object. This also cleanly
29891cb0ef41Sopenharmony_ci//     frees inobject properties that moved to the backing store.
29901cb0ef41Sopenharmony_ci//   * If there are properties left in the backing store, trim of the space used
29911cb0ef41Sopenharmony_ci//     to temporarily store the inobject properties.
29921cb0ef41Sopenharmony_ci//   * If there are properties left in the backing store, install the backing
29931cb0ef41Sopenharmony_ci//     store.
29941cb0ef41Sopenharmony_civoid MigrateFastToFast(Isolate* isolate, Handle<JSObject> object,
29951cb0ef41Sopenharmony_ci                       Handle<Map> new_map) {
29961cb0ef41Sopenharmony_ci  Handle<Map> old_map(object->map(), isolate);
29971cb0ef41Sopenharmony_ci  // In case of a regular transition.
29981cb0ef41Sopenharmony_ci  if (new_map->GetBackPointer(isolate) == *old_map) {
29991cb0ef41Sopenharmony_ci    // If the map does not add named properties, simply set the map.
30001cb0ef41Sopenharmony_ci    if (old_map->NumberOfOwnDescriptors() ==
30011cb0ef41Sopenharmony_ci        new_map->NumberOfOwnDescriptors()) {
30021cb0ef41Sopenharmony_ci      object->set_map(*new_map, kReleaseStore);
30031cb0ef41Sopenharmony_ci      return;
30041cb0ef41Sopenharmony_ci    }
30051cb0ef41Sopenharmony_ci
30061cb0ef41Sopenharmony_ci    // If the map adds a new kDescriptor property, simply set the map.
30071cb0ef41Sopenharmony_ci    PropertyDetails details = new_map->GetLastDescriptorDetails(isolate);
30081cb0ef41Sopenharmony_ci    if (details.location() == PropertyLocation::kDescriptor) {
30091cb0ef41Sopenharmony_ci      object->set_map(*new_map, kReleaseStore);
30101cb0ef41Sopenharmony_ci      return;
30111cb0ef41Sopenharmony_ci    }
30121cb0ef41Sopenharmony_ci
30131cb0ef41Sopenharmony_ci    // Check if we still have space in the {object}, in which case we
30141cb0ef41Sopenharmony_ci    // can also simply set the map (modulo a special case for mutable
30151cb0ef41Sopenharmony_ci    // double boxes).
30161cb0ef41Sopenharmony_ci    FieldIndex index =
30171cb0ef41Sopenharmony_ci        FieldIndex::ForDescriptor(isolate, *new_map, new_map->LastAdded());
30181cb0ef41Sopenharmony_ci    if (index.is_inobject() || index.outobject_array_index() <
30191cb0ef41Sopenharmony_ci                                   object->property_array(isolate).length()) {
30201cb0ef41Sopenharmony_ci      // Allocate HeapNumbers for double fields.
30211cb0ef41Sopenharmony_ci      if (index.is_double()) {
30221cb0ef41Sopenharmony_ci        auto value = isolate->factory()->NewHeapNumberWithHoleNaN();
30231cb0ef41Sopenharmony_ci        object->FastPropertyAtPut(index, *value);
30241cb0ef41Sopenharmony_ci      }
30251cb0ef41Sopenharmony_ci      object->set_map(*new_map, kReleaseStore);
30261cb0ef41Sopenharmony_ci      return;
30271cb0ef41Sopenharmony_ci    }
30281cb0ef41Sopenharmony_ci
30291cb0ef41Sopenharmony_ci    // This migration is a transition from a map that has run out of property
30301cb0ef41Sopenharmony_ci    // space. Extend the backing store.
30311cb0ef41Sopenharmony_ci    int grow_by = new_map->UnusedPropertyFields() + 1;
30321cb0ef41Sopenharmony_ci    Handle<PropertyArray> old_storage(object->property_array(isolate), isolate);
30331cb0ef41Sopenharmony_ci    Handle<PropertyArray> new_storage =
30341cb0ef41Sopenharmony_ci        isolate->factory()->CopyPropertyArrayAndGrow(old_storage, grow_by);
30351cb0ef41Sopenharmony_ci
30361cb0ef41Sopenharmony_ci    // Properly initialize newly added property.
30371cb0ef41Sopenharmony_ci    Handle<Object> value;
30381cb0ef41Sopenharmony_ci    if (details.representation().IsDouble()) {
30391cb0ef41Sopenharmony_ci      value = isolate->factory()->NewHeapNumberWithHoleNaN();
30401cb0ef41Sopenharmony_ci    } else {
30411cb0ef41Sopenharmony_ci      value = isolate->factory()->uninitialized_value();
30421cb0ef41Sopenharmony_ci    }
30431cb0ef41Sopenharmony_ci    DCHECK_EQ(PropertyLocation::kField, details.location());
30441cb0ef41Sopenharmony_ci    DCHECK_EQ(PropertyKind::kData, details.kind());
30451cb0ef41Sopenharmony_ci    DCHECK(!index.is_inobject());  // Must be a backing store index.
30461cb0ef41Sopenharmony_ci    new_storage->set(index.outobject_array_index(), *value);
30471cb0ef41Sopenharmony_ci
30481cb0ef41Sopenharmony_ci    // From here on we cannot fail and we shouldn't GC anymore.
30491cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_gc;
30501cb0ef41Sopenharmony_ci
30511cb0ef41Sopenharmony_ci    // Set the new property value and do the map transition.
30521cb0ef41Sopenharmony_ci    object->SetProperties(*new_storage);
30531cb0ef41Sopenharmony_ci    object->set_map(*new_map, kReleaseStore);
30541cb0ef41Sopenharmony_ci    return;
30551cb0ef41Sopenharmony_ci  }
30561cb0ef41Sopenharmony_ci
30571cb0ef41Sopenharmony_ci  int old_number_of_fields;
30581cb0ef41Sopenharmony_ci  int number_of_fields = new_map->NumberOfFields(ConcurrencyMode::kSynchronous);
30591cb0ef41Sopenharmony_ci  int inobject = new_map->GetInObjectProperties();
30601cb0ef41Sopenharmony_ci  int unused = new_map->UnusedPropertyFields();
30611cb0ef41Sopenharmony_ci
30621cb0ef41Sopenharmony_ci  // Nothing to do if no functions were converted to fields and no smis were
30631cb0ef41Sopenharmony_ci  // converted to doubles.
30641cb0ef41Sopenharmony_ci  if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields, inobject,
30651cb0ef41Sopenharmony_ci                                       unused, &old_number_of_fields,
30661cb0ef41Sopenharmony_ci                                       ConcurrencyMode::kSynchronous)) {
30671cb0ef41Sopenharmony_ci    object->set_map(*new_map, kReleaseStore);
30681cb0ef41Sopenharmony_ci    return;
30691cb0ef41Sopenharmony_ci  }
30701cb0ef41Sopenharmony_ci
30711cb0ef41Sopenharmony_ci  int total_size = number_of_fields + unused;
30721cb0ef41Sopenharmony_ci  int external = total_size - inobject;
30731cb0ef41Sopenharmony_ci  Handle<PropertyArray> array = isolate->factory()->NewPropertyArray(external);
30741cb0ef41Sopenharmony_ci
30751cb0ef41Sopenharmony_ci  // We use this array to temporarily store the inobject properties.
30761cb0ef41Sopenharmony_ci  Handle<FixedArray> inobject_props =
30771cb0ef41Sopenharmony_ci      isolate->factory()->NewFixedArray(inobject);
30781cb0ef41Sopenharmony_ci
30791cb0ef41Sopenharmony_ci  Handle<DescriptorArray> old_descriptors(
30801cb0ef41Sopenharmony_ci      old_map->instance_descriptors(isolate), isolate);
30811cb0ef41Sopenharmony_ci  Handle<DescriptorArray> new_descriptors(
30821cb0ef41Sopenharmony_ci      new_map->instance_descriptors(isolate), isolate);
30831cb0ef41Sopenharmony_ci  int old_nof = old_map->NumberOfOwnDescriptors();
30841cb0ef41Sopenharmony_ci  int new_nof = new_map->NumberOfOwnDescriptors();
30851cb0ef41Sopenharmony_ci
30861cb0ef41Sopenharmony_ci  // This method only supports generalizing instances to at least the same
30871cb0ef41Sopenharmony_ci  // number of properties.
30881cb0ef41Sopenharmony_ci  DCHECK(old_nof <= new_nof);
30891cb0ef41Sopenharmony_ci
30901cb0ef41Sopenharmony_ci  for (InternalIndex i : InternalIndex::Range(old_nof)) {
30911cb0ef41Sopenharmony_ci    PropertyDetails details = new_descriptors->GetDetails(i);
30921cb0ef41Sopenharmony_ci    if (details.location() != PropertyLocation::kField) continue;
30931cb0ef41Sopenharmony_ci    DCHECK_EQ(PropertyKind::kData, details.kind());
30941cb0ef41Sopenharmony_ci    PropertyDetails old_details = old_descriptors->GetDetails(i);
30951cb0ef41Sopenharmony_ci    Representation old_representation = old_details.representation();
30961cb0ef41Sopenharmony_ci    Representation representation = details.representation();
30971cb0ef41Sopenharmony_ci    Handle<Object> value;
30981cb0ef41Sopenharmony_ci    if (old_details.location() == PropertyLocation::kDescriptor) {
30991cb0ef41Sopenharmony_ci      if (old_details.kind() == PropertyKind::kAccessor) {
31001cb0ef41Sopenharmony_ci        // In case of kAccessor -> kData property reconfiguration, the property
31011cb0ef41Sopenharmony_ci        // must already be prepared for data of certain type.
31021cb0ef41Sopenharmony_ci        DCHECK(!details.representation().IsNone());
31031cb0ef41Sopenharmony_ci        if (details.representation().IsDouble()) {
31041cb0ef41Sopenharmony_ci          value = isolate->factory()->NewHeapNumberWithHoleNaN();
31051cb0ef41Sopenharmony_ci        } else {
31061cb0ef41Sopenharmony_ci          value = isolate->factory()->uninitialized_value();
31071cb0ef41Sopenharmony_ci        }
31081cb0ef41Sopenharmony_ci      } else {
31091cb0ef41Sopenharmony_ci        DCHECK_EQ(PropertyKind::kData, old_details.kind());
31101cb0ef41Sopenharmony_ci        value = handle(old_descriptors->GetStrongValue(isolate, i), isolate);
31111cb0ef41Sopenharmony_ci        DCHECK(!old_representation.IsDouble() && !representation.IsDouble());
31121cb0ef41Sopenharmony_ci      }
31131cb0ef41Sopenharmony_ci    } else {
31141cb0ef41Sopenharmony_ci      DCHECK_EQ(PropertyLocation::kField, old_details.location());
31151cb0ef41Sopenharmony_ci      FieldIndex index = FieldIndex::ForDescriptor(isolate, *old_map, i);
31161cb0ef41Sopenharmony_ci      value = handle(object->RawFastPropertyAt(isolate, index), isolate);
31171cb0ef41Sopenharmony_ci      if (!old_representation.IsDouble() && representation.IsDouble()) {
31181cb0ef41Sopenharmony_ci        DCHECK_IMPLIES(old_representation.IsNone(),
31191cb0ef41Sopenharmony_ci                       value->IsUninitialized(isolate));
31201cb0ef41Sopenharmony_ci        value = Object::NewStorageFor(isolate, value, representation);
31211cb0ef41Sopenharmony_ci      } else if (old_representation.IsDouble() && !representation.IsDouble()) {
31221cb0ef41Sopenharmony_ci        value = Object::WrapForRead(isolate, value, old_representation);
31231cb0ef41Sopenharmony_ci      }
31241cb0ef41Sopenharmony_ci    }
31251cb0ef41Sopenharmony_ci    DCHECK(!(representation.IsDouble() && value->IsSmi()));
31261cb0ef41Sopenharmony_ci    int target_index = new_descriptors->GetFieldIndex(i);
31271cb0ef41Sopenharmony_ci    if (target_index < inobject) {
31281cb0ef41Sopenharmony_ci      inobject_props->set(target_index, *value);
31291cb0ef41Sopenharmony_ci    } else {
31301cb0ef41Sopenharmony_ci      array->set(target_index - inobject, *value);
31311cb0ef41Sopenharmony_ci    }
31321cb0ef41Sopenharmony_ci  }
31331cb0ef41Sopenharmony_ci
31341cb0ef41Sopenharmony_ci  for (InternalIndex i : InternalIndex::Range(old_nof, new_nof)) {
31351cb0ef41Sopenharmony_ci    PropertyDetails details = new_descriptors->GetDetails(i);
31361cb0ef41Sopenharmony_ci    if (details.location() != PropertyLocation::kField) continue;
31371cb0ef41Sopenharmony_ci    DCHECK_EQ(PropertyKind::kData, details.kind());
31381cb0ef41Sopenharmony_ci    Handle<Object> value;
31391cb0ef41Sopenharmony_ci    if (details.representation().IsDouble()) {
31401cb0ef41Sopenharmony_ci      value = isolate->factory()->NewHeapNumberWithHoleNaN();
31411cb0ef41Sopenharmony_ci    } else {
31421cb0ef41Sopenharmony_ci      value = isolate->factory()->uninitialized_value();
31431cb0ef41Sopenharmony_ci    }
31441cb0ef41Sopenharmony_ci    int target_index = new_descriptors->GetFieldIndex(i);
31451cb0ef41Sopenharmony_ci    if (target_index < inobject) {
31461cb0ef41Sopenharmony_ci      inobject_props->set(target_index, *value);
31471cb0ef41Sopenharmony_ci    } else {
31481cb0ef41Sopenharmony_ci      array->set(target_index - inobject, *value);
31491cb0ef41Sopenharmony_ci    }
31501cb0ef41Sopenharmony_ci  }
31511cb0ef41Sopenharmony_ci
31521cb0ef41Sopenharmony_ci  // From here on we cannot fail and we shouldn't GC anymore.
31531cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
31541cb0ef41Sopenharmony_ci
31551cb0ef41Sopenharmony_ci  Heap* heap = isolate->heap();
31561cb0ef41Sopenharmony_ci
31571cb0ef41Sopenharmony_ci  // Copy (real) inobject properties. If necessary, stop at number_of_fields to
31581cb0ef41Sopenharmony_ci  // avoid overwriting |one_pointer_filler_map|.
31591cb0ef41Sopenharmony_ci  int limit = std::min(inobject, number_of_fields);
31601cb0ef41Sopenharmony_ci  for (int i = 0; i < limit; i++) {
31611cb0ef41Sopenharmony_ci    FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
31621cb0ef41Sopenharmony_ci    Object value = inobject_props->get(isolate, i);
31631cb0ef41Sopenharmony_ci    object->FastPropertyAtPut(index, value);
31641cb0ef41Sopenharmony_ci  }
31651cb0ef41Sopenharmony_ci
31661cb0ef41Sopenharmony_ci  object->SetProperties(*array);
31671cb0ef41Sopenharmony_ci
31681cb0ef41Sopenharmony_ci  // Create filler object past the new instance size.
31691cb0ef41Sopenharmony_ci  int old_instance_size = old_map->instance_size();
31701cb0ef41Sopenharmony_ci  int new_instance_size = new_map->instance_size();
31711cb0ef41Sopenharmony_ci  int instance_size_delta = old_instance_size - new_instance_size;
31721cb0ef41Sopenharmony_ci  DCHECK_GE(instance_size_delta, 0);
31731cb0ef41Sopenharmony_ci
31741cb0ef41Sopenharmony_ci  if (instance_size_delta > 0) {
31751cb0ef41Sopenharmony_ci    Address address = object->address();
31761cb0ef41Sopenharmony_ci    heap->CreateFillerObjectAt(address + new_instance_size, instance_size_delta,
31771cb0ef41Sopenharmony_ci                               ClearRecordedSlots::kYes);
31781cb0ef41Sopenharmony_ci  }
31791cb0ef41Sopenharmony_ci
31801cb0ef41Sopenharmony_ci  // We are storing the new map using release store after creating a filler for
31811cb0ef41Sopenharmony_ci  // the left-over space to avoid races with the sweeper thread.
31821cb0ef41Sopenharmony_ci  object->set_map(*new_map, kReleaseStore);
31831cb0ef41Sopenharmony_ci}
31841cb0ef41Sopenharmony_ci
31851cb0ef41Sopenharmony_civoid MigrateFastToSlow(Isolate* isolate, Handle<JSObject> object,
31861cb0ef41Sopenharmony_ci                       Handle<Map> new_map,
31871cb0ef41Sopenharmony_ci                       int expected_additional_properties) {
31881cb0ef41Sopenharmony_ci  // The global object is always normalized.
31891cb0ef41Sopenharmony_ci  DCHECK(!object->IsJSGlobalObject(isolate));
31901cb0ef41Sopenharmony_ci  // JSGlobalProxy must never be normalized
31911cb0ef41Sopenharmony_ci  DCHECK(!object->IsJSGlobalProxy(isolate));
31921cb0ef41Sopenharmony_ci
31931cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(new_map->is_prototype_map(),
31941cb0ef41Sopenharmony_ci                 Map::IsPrototypeChainInvalidated(*new_map));
31951cb0ef41Sopenharmony_ci
31961cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
31971cb0ef41Sopenharmony_ci  Handle<Map> map(object->map(isolate), isolate);
31981cb0ef41Sopenharmony_ci
31991cb0ef41Sopenharmony_ci  // Allocate new content.
32001cb0ef41Sopenharmony_ci  int real_size = map->NumberOfOwnDescriptors();
32011cb0ef41Sopenharmony_ci  int property_count = real_size;
32021cb0ef41Sopenharmony_ci  if (expected_additional_properties > 0) {
32031cb0ef41Sopenharmony_ci    property_count += expected_additional_properties;
32041cb0ef41Sopenharmony_ci  } else {
32051cb0ef41Sopenharmony_ci    // Make space for two more properties.
32061cb0ef41Sopenharmony_ci    int initial_capacity = V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
32071cb0ef41Sopenharmony_ci                               ? SwissNameDictionary::kInitialCapacity
32081cb0ef41Sopenharmony_ci                               : NameDictionary::kInitialCapacity;
32091cb0ef41Sopenharmony_ci    property_count += initial_capacity;
32101cb0ef41Sopenharmony_ci  }
32111cb0ef41Sopenharmony_ci
32121cb0ef41Sopenharmony_ci  Handle<NameDictionary> dictionary;
32131cb0ef41Sopenharmony_ci  Handle<SwissNameDictionary> ord_dictionary;
32141cb0ef41Sopenharmony_ci  if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
32151cb0ef41Sopenharmony_ci    ord_dictionary = isolate->factory()->NewSwissNameDictionary(property_count);
32161cb0ef41Sopenharmony_ci  } else {
32171cb0ef41Sopenharmony_ci    dictionary = isolate->factory()->NewNameDictionary(property_count);
32181cb0ef41Sopenharmony_ci  }
32191cb0ef41Sopenharmony_ci
32201cb0ef41Sopenharmony_ci  Handle<DescriptorArray> descs(map->instance_descriptors(isolate), isolate);
32211cb0ef41Sopenharmony_ci  for (InternalIndex i : InternalIndex::Range(real_size)) {
32221cb0ef41Sopenharmony_ci    PropertyDetails details = descs->GetDetails(i);
32231cb0ef41Sopenharmony_ci    Handle<Name> key(descs->GetKey(isolate, i), isolate);
32241cb0ef41Sopenharmony_ci    Handle<Object> value;
32251cb0ef41Sopenharmony_ci    if (details.location() == PropertyLocation::kField) {
32261cb0ef41Sopenharmony_ci      FieldIndex index = FieldIndex::ForDescriptor(isolate, *map, i);
32271cb0ef41Sopenharmony_ci      if (details.kind() == PropertyKind::kData) {
32281cb0ef41Sopenharmony_ci        value = handle(object->RawFastPropertyAt(isolate, index), isolate);
32291cb0ef41Sopenharmony_ci        if (details.representation().IsDouble()) {
32301cb0ef41Sopenharmony_ci          DCHECK(value->IsHeapNumber(isolate));
32311cb0ef41Sopenharmony_ci          double old_value = Handle<HeapNumber>::cast(value)->value();
32321cb0ef41Sopenharmony_ci          value = isolate->factory()->NewHeapNumber(old_value);
32331cb0ef41Sopenharmony_ci        }
32341cb0ef41Sopenharmony_ci      } else {
32351cb0ef41Sopenharmony_ci        DCHECK_EQ(PropertyKind::kAccessor, details.kind());
32361cb0ef41Sopenharmony_ci        value = handle(object->RawFastPropertyAt(isolate, index), isolate);
32371cb0ef41Sopenharmony_ci      }
32381cb0ef41Sopenharmony_ci
32391cb0ef41Sopenharmony_ci    } else {
32401cb0ef41Sopenharmony_ci      DCHECK_EQ(PropertyLocation::kDescriptor, details.location());
32411cb0ef41Sopenharmony_ci      value = handle(descs->GetStrongValue(isolate, i), isolate);
32421cb0ef41Sopenharmony_ci    }
32431cb0ef41Sopenharmony_ci    DCHECK(!value.is_null());
32441cb0ef41Sopenharmony_ci    PropertyConstness constness = V8_DICT_PROPERTY_CONST_TRACKING_BOOL
32451cb0ef41Sopenharmony_ci                                      ? details.constness()
32461cb0ef41Sopenharmony_ci                                      : PropertyConstness::kMutable;
32471cb0ef41Sopenharmony_ci    PropertyDetails d(details.kind(), details.attributes(), constness);
32481cb0ef41Sopenharmony_ci
32491cb0ef41Sopenharmony_ci    if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
32501cb0ef41Sopenharmony_ci      ord_dictionary =
32511cb0ef41Sopenharmony_ci          SwissNameDictionary::Add(isolate, ord_dictionary, key, value, d);
32521cb0ef41Sopenharmony_ci    } else {
32531cb0ef41Sopenharmony_ci      dictionary = NameDictionary::Add(isolate, dictionary, key, value, d);
32541cb0ef41Sopenharmony_ci    }
32551cb0ef41Sopenharmony_ci  }
32561cb0ef41Sopenharmony_ci
32571cb0ef41Sopenharmony_ci  if (!V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
32581cb0ef41Sopenharmony_ci    // Copy the next enumeration index from instance descriptor.
32591cb0ef41Sopenharmony_ci    dictionary->set_next_enumeration_index(real_size + 1);
32601cb0ef41Sopenharmony_ci  }
32611cb0ef41Sopenharmony_ci
32621cb0ef41Sopenharmony_ci  // From here on we cannot fail and we shouldn't GC anymore.
32631cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
32641cb0ef41Sopenharmony_ci
32651cb0ef41Sopenharmony_ci  Heap* heap = isolate->heap();
32661cb0ef41Sopenharmony_ci
32671cb0ef41Sopenharmony_ci  // Resize the object in the heap if necessary.
32681cb0ef41Sopenharmony_ci  int old_instance_size = map->instance_size();
32691cb0ef41Sopenharmony_ci  int new_instance_size = new_map->instance_size();
32701cb0ef41Sopenharmony_ci  int instance_size_delta = old_instance_size - new_instance_size;
32711cb0ef41Sopenharmony_ci  DCHECK_GE(instance_size_delta, 0);
32721cb0ef41Sopenharmony_ci
32731cb0ef41Sopenharmony_ci  if (instance_size_delta > 0) {
32741cb0ef41Sopenharmony_ci    heap->CreateFillerObjectAt(object->address() + new_instance_size,
32751cb0ef41Sopenharmony_ci                               instance_size_delta, ClearRecordedSlots::kYes);
32761cb0ef41Sopenharmony_ci  }
32771cb0ef41Sopenharmony_ci
32781cb0ef41Sopenharmony_ci  // We are storing the new map using release store after creating a filler for
32791cb0ef41Sopenharmony_ci  // the left-over space to avoid races with the sweeper thread.
32801cb0ef41Sopenharmony_ci  object->set_map(*new_map, kReleaseStore);
32811cb0ef41Sopenharmony_ci
32821cb0ef41Sopenharmony_ci  if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
32831cb0ef41Sopenharmony_ci    object->SetProperties(*ord_dictionary);
32841cb0ef41Sopenharmony_ci  } else {
32851cb0ef41Sopenharmony_ci    object->SetProperties(*dictionary);
32861cb0ef41Sopenharmony_ci  }
32871cb0ef41Sopenharmony_ci
32881cb0ef41Sopenharmony_ci  // Ensure that in-object space of slow-mode object does not contain random
32891cb0ef41Sopenharmony_ci  // garbage.
32901cb0ef41Sopenharmony_ci  int inobject_properties = new_map->GetInObjectProperties();
32911cb0ef41Sopenharmony_ci  if (inobject_properties) {
32921cb0ef41Sopenharmony_ci    for (int i = 0; i < inobject_properties; i++) {
32931cb0ef41Sopenharmony_ci      FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
32941cb0ef41Sopenharmony_ci      object->FastPropertyAtPut(index, Smi::zero());
32951cb0ef41Sopenharmony_ci    }
32961cb0ef41Sopenharmony_ci  }
32971cb0ef41Sopenharmony_ci
32981cb0ef41Sopenharmony_ci  isolate->counters()->props_to_dictionary()->Increment();
32991cb0ef41Sopenharmony_ci
33001cb0ef41Sopenharmony_ci#ifdef DEBUG
33011cb0ef41Sopenharmony_ci  if (FLAG_trace_normalization) {
33021cb0ef41Sopenharmony_ci    StdoutStream os;
33031cb0ef41Sopenharmony_ci    os << "Object properties have been normalized:\n";
33041cb0ef41Sopenharmony_ci    object->Print(os);
33051cb0ef41Sopenharmony_ci  }
33061cb0ef41Sopenharmony_ci#endif
33071cb0ef41Sopenharmony_ci}
33081cb0ef41Sopenharmony_ci
33091cb0ef41Sopenharmony_ci}  // namespace
33101cb0ef41Sopenharmony_ci
33111cb0ef41Sopenharmony_civoid JSObject::MigrateToMap(Isolate* isolate, Handle<JSObject> object,
33121cb0ef41Sopenharmony_ci                            Handle<Map> new_map,
33131cb0ef41Sopenharmony_ci                            int expected_additional_properties) {
33141cb0ef41Sopenharmony_ci  if (object->map(isolate) == *new_map) return;
33151cb0ef41Sopenharmony_ci  Handle<Map> old_map(object->map(isolate), isolate);
33161cb0ef41Sopenharmony_ci  NotifyMapChange(old_map, new_map, isolate);
33171cb0ef41Sopenharmony_ci
33181cb0ef41Sopenharmony_ci  if (old_map->is_dictionary_map()) {
33191cb0ef41Sopenharmony_ci    // For slow-to-fast migrations JSObject::MigrateSlowToFast()
33201cb0ef41Sopenharmony_ci    // must be used instead.
33211cb0ef41Sopenharmony_ci    CHECK(new_map->is_dictionary_map());
33221cb0ef41Sopenharmony_ci
33231cb0ef41Sopenharmony_ci    // Slow-to-slow migration is trivial.
33241cb0ef41Sopenharmony_ci    object->set_map(*new_map, kReleaseStore);
33251cb0ef41Sopenharmony_ci  } else if (!new_map->is_dictionary_map()) {
33261cb0ef41Sopenharmony_ci    MigrateFastToFast(isolate, object, new_map);
33271cb0ef41Sopenharmony_ci    if (old_map->is_prototype_map()) {
33281cb0ef41Sopenharmony_ci      DCHECK(!old_map->is_stable());
33291cb0ef41Sopenharmony_ci      DCHECK(new_map->is_stable());
33301cb0ef41Sopenharmony_ci      DCHECK(new_map->owns_descriptors());
33311cb0ef41Sopenharmony_ci      DCHECK(old_map->owns_descriptors());
33321cb0ef41Sopenharmony_ci      // Transfer ownership to the new map. Keep the descriptor pointer of the
33331cb0ef41Sopenharmony_ci      // old map intact because the concurrent marker might be iterating the
33341cb0ef41Sopenharmony_ci      // object with the old map.
33351cb0ef41Sopenharmony_ci      old_map->set_owns_descriptors(false);
33361cb0ef41Sopenharmony_ci      DCHECK(old_map->is_abandoned_prototype_map());
33371cb0ef41Sopenharmony_ci      // Ensure that no transition was inserted for prototype migrations.
33381cb0ef41Sopenharmony_ci      DCHECK_EQ(0,
33391cb0ef41Sopenharmony_ci                TransitionsAccessor(isolate, *old_map).NumberOfTransitions());
33401cb0ef41Sopenharmony_ci      DCHECK(new_map->GetBackPointer(isolate).IsUndefined(isolate));
33411cb0ef41Sopenharmony_ci      DCHECK(object->map(isolate) != *old_map);
33421cb0ef41Sopenharmony_ci    }
33431cb0ef41Sopenharmony_ci  } else {
33441cb0ef41Sopenharmony_ci    MigrateFastToSlow(isolate, object, new_map, expected_additional_properties);
33451cb0ef41Sopenharmony_ci  }
33461cb0ef41Sopenharmony_ci
33471cb0ef41Sopenharmony_ci  // Careful: Don't allocate here!
33481cb0ef41Sopenharmony_ci  // For some callers of this method, |object| might be in an inconsistent
33491cb0ef41Sopenharmony_ci  // state now: the new map might have a new elements_kind, but the object's
33501cb0ef41Sopenharmony_ci  // elements pointer hasn't been updated yet. Callers will fix this, but in
33511cb0ef41Sopenharmony_ci  // the meantime, (indirectly) calling JSObjectVerify() must be avoided.
33521cb0ef41Sopenharmony_ci  // When adding code here, add a DisallowGarbageCollection too.
33531cb0ef41Sopenharmony_ci}
33541cb0ef41Sopenharmony_ci
33551cb0ef41Sopenharmony_civoid JSObject::ForceSetPrototype(Isolate* isolate, Handle<JSObject> object,
33561cb0ef41Sopenharmony_ci                                 Handle<HeapObject> proto) {
33571cb0ef41Sopenharmony_ci  // object.__proto__ = proto;
33581cb0ef41Sopenharmony_ci  Handle<Map> old_map = Handle<Map>(object->map(), isolate);
33591cb0ef41Sopenharmony_ci  Handle<Map> new_map = Map::Copy(isolate, old_map, "ForceSetPrototype");
33601cb0ef41Sopenharmony_ci  Map::SetPrototype(isolate, new_map, proto);
33611cb0ef41Sopenharmony_ci  JSObject::MigrateToMap(isolate, object, new_map);
33621cb0ef41Sopenharmony_ci}
33631cb0ef41Sopenharmony_ci
33641cb0ef41Sopenharmony_ciMaybe<bool> JSObject::SetPropertyWithInterceptor(
33651cb0ef41Sopenharmony_ci    LookupIterator* it, Maybe<ShouldThrow> should_throw, Handle<Object> value) {
33661cb0ef41Sopenharmony_ci  DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
33671cb0ef41Sopenharmony_ci  return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(),
33681cb0ef41Sopenharmony_ci                                            should_throw, value);
33691cb0ef41Sopenharmony_ci}
33701cb0ef41Sopenharmony_ci
33711cb0ef41Sopenharmony_ciHandle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
33721cb0ef41Sopenharmony_ci                                               ElementsKind to_kind) {
33731cb0ef41Sopenharmony_ci  Handle<Map> map(object->map(), object->GetIsolate());
33741cb0ef41Sopenharmony_ci  return Map::TransitionElementsTo(object->GetIsolate(), map, to_kind);
33751cb0ef41Sopenharmony_ci}
33761cb0ef41Sopenharmony_ci
33771cb0ef41Sopenharmony_civoid JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
33781cb0ef41Sopenharmony_ci  DCHECK(object->map().GetInObjectProperties() == map->GetInObjectProperties());
33791cb0ef41Sopenharmony_ci  ElementsKind obj_kind = object->map().elements_kind();
33801cb0ef41Sopenharmony_ci  ElementsKind map_kind = map->elements_kind();
33811cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
33821cb0ef41Sopenharmony_ci  if (map_kind != obj_kind) {
33831cb0ef41Sopenharmony_ci    ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind);
33841cb0ef41Sopenharmony_ci    if (IsDictionaryElementsKind(obj_kind)) {
33851cb0ef41Sopenharmony_ci      to_kind = obj_kind;
33861cb0ef41Sopenharmony_ci    }
33871cb0ef41Sopenharmony_ci    if (IsDictionaryElementsKind(to_kind)) {
33881cb0ef41Sopenharmony_ci      NormalizeElements(object);
33891cb0ef41Sopenharmony_ci    } else {
33901cb0ef41Sopenharmony_ci      TransitionElementsKind(object, to_kind);
33911cb0ef41Sopenharmony_ci    }
33921cb0ef41Sopenharmony_ci    map = MapUpdater{isolate, map}.ReconfigureElementsKind(to_kind);
33931cb0ef41Sopenharmony_ci  }
33941cb0ef41Sopenharmony_ci  int number_of_fields = map->NumberOfFields(ConcurrencyMode::kSynchronous);
33951cb0ef41Sopenharmony_ci  int inobject = map->GetInObjectProperties();
33961cb0ef41Sopenharmony_ci  int unused = map->UnusedPropertyFields();
33971cb0ef41Sopenharmony_ci  int total_size = number_of_fields + unused;
33981cb0ef41Sopenharmony_ci  int external = total_size - inobject;
33991cb0ef41Sopenharmony_ci  // Allocate mutable double boxes if necessary. It is always necessary if we
34001cb0ef41Sopenharmony_ci  // have external properties, but is also necessary if we only have inobject
34011cb0ef41Sopenharmony_ci  // properties but don't unbox double fields.
34021cb0ef41Sopenharmony_ci
34031cb0ef41Sopenharmony_ci  Handle<DescriptorArray> descriptors(map->instance_descriptors(isolate),
34041cb0ef41Sopenharmony_ci                                      isolate);
34051cb0ef41Sopenharmony_ci  Handle<FixedArray> storage = isolate->factory()->NewFixedArray(inobject);
34061cb0ef41Sopenharmony_ci
34071cb0ef41Sopenharmony_ci  Handle<PropertyArray> array = isolate->factory()->NewPropertyArray(external);
34081cb0ef41Sopenharmony_ci
34091cb0ef41Sopenharmony_ci  for (InternalIndex i : map->IterateOwnDescriptors()) {
34101cb0ef41Sopenharmony_ci    PropertyDetails details = descriptors->GetDetails(i);
34111cb0ef41Sopenharmony_ci    Representation representation = details.representation();
34121cb0ef41Sopenharmony_ci    if (!representation.IsDouble()) continue;
34131cb0ef41Sopenharmony_ci    FieldIndex index = FieldIndex::ForDescriptor(*map, i);
34141cb0ef41Sopenharmony_ci    auto box = isolate->factory()->NewHeapNumberWithHoleNaN();
34151cb0ef41Sopenharmony_ci    if (index.is_inobject()) {
34161cb0ef41Sopenharmony_ci      storage->set(index.property_index(), *box);
34171cb0ef41Sopenharmony_ci    } else {
34181cb0ef41Sopenharmony_ci      array->set(index.outobject_array_index(), *box);
34191cb0ef41Sopenharmony_ci    }
34201cb0ef41Sopenharmony_ci  }
34211cb0ef41Sopenharmony_ci
34221cb0ef41Sopenharmony_ci  object->SetProperties(*array);
34231cb0ef41Sopenharmony_ci  for (int i = 0; i < inobject; i++) {
34241cb0ef41Sopenharmony_ci    FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
34251cb0ef41Sopenharmony_ci    Object value = storage->get(i);
34261cb0ef41Sopenharmony_ci    object->FastPropertyAtPut(index, value);
34271cb0ef41Sopenharmony_ci  }
34281cb0ef41Sopenharmony_ci  object->set_map(*map, kReleaseStore);
34291cb0ef41Sopenharmony_ci}
34301cb0ef41Sopenharmony_ci
34311cb0ef41Sopenharmony_civoid JSObject::MigrateInstance(Isolate* isolate, Handle<JSObject> object) {
34321cb0ef41Sopenharmony_ci  Handle<Map> original_map(object->map(), isolate);
34331cb0ef41Sopenharmony_ci  Handle<Map> map = Map::Update(isolate, original_map);
34341cb0ef41Sopenharmony_ci  map->set_is_migration_target(true);
34351cb0ef41Sopenharmony_ci  JSObject::MigrateToMap(isolate, object, map);
34361cb0ef41Sopenharmony_ci  if (FLAG_trace_migration) {
34371cb0ef41Sopenharmony_ci    object->PrintInstanceMigration(stdout, *original_map, *map);
34381cb0ef41Sopenharmony_ci  }
34391cb0ef41Sopenharmony_ci#if VERIFY_HEAP
34401cb0ef41Sopenharmony_ci  if (FLAG_verify_heap) {
34411cb0ef41Sopenharmony_ci    object->JSObjectVerify(isolate);
34421cb0ef41Sopenharmony_ci  }
34431cb0ef41Sopenharmony_ci#endif
34441cb0ef41Sopenharmony_ci}
34451cb0ef41Sopenharmony_ci
34461cb0ef41Sopenharmony_ci// static
34471cb0ef41Sopenharmony_cibool JSObject::TryMigrateInstance(Isolate* isolate, Handle<JSObject> object) {
34481cb0ef41Sopenharmony_ci  DisallowDeoptimization no_deoptimization(isolate);
34491cb0ef41Sopenharmony_ci  Handle<Map> original_map(object->map(), isolate);
34501cb0ef41Sopenharmony_ci  Handle<Map> new_map;
34511cb0ef41Sopenharmony_ci  if (!Map::TryUpdate(isolate, original_map).ToHandle(&new_map)) {
34521cb0ef41Sopenharmony_ci    return false;
34531cb0ef41Sopenharmony_ci  }
34541cb0ef41Sopenharmony_ci  JSObject::MigrateToMap(isolate, object, new_map);
34551cb0ef41Sopenharmony_ci  if (FLAG_trace_migration && *original_map != object->map()) {
34561cb0ef41Sopenharmony_ci    object->PrintInstanceMigration(stdout, *original_map, object->map());
34571cb0ef41Sopenharmony_ci  }
34581cb0ef41Sopenharmony_ci#if VERIFY_HEAP
34591cb0ef41Sopenharmony_ci  if (FLAG_verify_heap) {
34601cb0ef41Sopenharmony_ci    object->JSObjectVerify(isolate);
34611cb0ef41Sopenharmony_ci  }
34621cb0ef41Sopenharmony_ci#endif
34631cb0ef41Sopenharmony_ci  return true;
34641cb0ef41Sopenharmony_ci}
34651cb0ef41Sopenharmony_ci
34661cb0ef41Sopenharmony_civoid JSObject::AddProperty(Isolate* isolate, Handle<JSObject> object,
34671cb0ef41Sopenharmony_ci                           Handle<Name> name, Handle<Object> value,
34681cb0ef41Sopenharmony_ci                           PropertyAttributes attributes) {
34691cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, name, object,
34701cb0ef41Sopenharmony_ci                    LookupIterator::OWN_SKIP_INTERCEPTOR);
34711cb0ef41Sopenharmony_ci  CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
34721cb0ef41Sopenharmony_ci#ifdef DEBUG
34731cb0ef41Sopenharmony_ci  uint32_t index;
34741cb0ef41Sopenharmony_ci  DCHECK(!object->IsJSProxy());
34751cb0ef41Sopenharmony_ci  DCHECK(!name->AsArrayIndex(&index));
34761cb0ef41Sopenharmony_ci  Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
34771cb0ef41Sopenharmony_ci  DCHECK(maybe.IsJust());
34781cb0ef41Sopenharmony_ci  DCHECK(!it.IsFound());
34791cb0ef41Sopenharmony_ci  DCHECK(object->map().is_extensible() || name->IsPrivate());
34801cb0ef41Sopenharmony_ci#endif
34811cb0ef41Sopenharmony_ci  CHECK(Object::AddDataProperty(&it, value, attributes,
34821cb0ef41Sopenharmony_ci                                Just(ShouldThrow::kThrowOnError),
34831cb0ef41Sopenharmony_ci                                StoreOrigin::kNamed)
34841cb0ef41Sopenharmony_ci            .IsJust());
34851cb0ef41Sopenharmony_ci}
34861cb0ef41Sopenharmony_ci
34871cb0ef41Sopenharmony_civoid JSObject::AddProperty(Isolate* isolate, Handle<JSObject> object,
34881cb0ef41Sopenharmony_ci                           const char* name, Handle<Object> value,
34891cb0ef41Sopenharmony_ci                           PropertyAttributes attributes) {
34901cb0ef41Sopenharmony_ci  JSObject::AddProperty(isolate, object,
34911cb0ef41Sopenharmony_ci                        isolate->factory()->InternalizeUtf8String(name), value,
34921cb0ef41Sopenharmony_ci                        attributes);
34931cb0ef41Sopenharmony_ci}
34941cb0ef41Sopenharmony_ci
34951cb0ef41Sopenharmony_ci// Reconfigures a property to a data property with attributes, even if it is not
34961cb0ef41Sopenharmony_ci// reconfigurable.
34971cb0ef41Sopenharmony_ci// Requires a LookupIterator that does not look at the prototype chain beyond
34981cb0ef41Sopenharmony_ci// hidden prototypes.
34991cb0ef41Sopenharmony_ciMaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
35001cb0ef41Sopenharmony_ci    LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
35011cb0ef41Sopenharmony_ci    AccessorInfoHandling handling, EnforceDefineSemantics semantics) {
35021cb0ef41Sopenharmony_ci  MAYBE_RETURN_NULL(DefineOwnPropertyIgnoreAttributes(
35031cb0ef41Sopenharmony_ci      it, value, attributes, Just(ShouldThrow::kThrowOnError), handling,
35041cb0ef41Sopenharmony_ci      semantics));
35051cb0ef41Sopenharmony_ci  return value;
35061cb0ef41Sopenharmony_ci}
35071cb0ef41Sopenharmony_ci
35081cb0ef41Sopenharmony_ciMaybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
35091cb0ef41Sopenharmony_ci    LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
35101cb0ef41Sopenharmony_ci    Maybe<ShouldThrow> should_throw, AccessorInfoHandling handling,
35111cb0ef41Sopenharmony_ci    EnforceDefineSemantics semantics, StoreOrigin store_origin) {
35121cb0ef41Sopenharmony_ci  it->UpdateProtector();
35131cb0ef41Sopenharmony_ci
35141cb0ef41Sopenharmony_ci  for (; it->IsFound(); it->Next()) {
35151cb0ef41Sopenharmony_ci    switch (it->state()) {
35161cb0ef41Sopenharmony_ci      case LookupIterator::JSPROXY:
35171cb0ef41Sopenharmony_ci      case LookupIterator::TRANSITION:
35181cb0ef41Sopenharmony_ci      case LookupIterator::NOT_FOUND:
35191cb0ef41Sopenharmony_ci        UNREACHABLE();
35201cb0ef41Sopenharmony_ci
35211cb0ef41Sopenharmony_ci      case LookupIterator::ACCESS_CHECK:
35221cb0ef41Sopenharmony_ci        if (!it->HasAccess()) {
35231cb0ef41Sopenharmony_ci          it->isolate()->ReportFailedAccessCheck(it->GetHolder<JSObject>());
35241cb0ef41Sopenharmony_ci          RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
35251cb0ef41Sopenharmony_ci          return Just(true);
35261cb0ef41Sopenharmony_ci        }
35271cb0ef41Sopenharmony_ci        break;
35281cb0ef41Sopenharmony_ci
35291cb0ef41Sopenharmony_ci      // If there's an interceptor, try to store the property with the
35301cb0ef41Sopenharmony_ci      // interceptor.
35311cb0ef41Sopenharmony_ci      // In case of success, the attributes will have been reset to the default
35321cb0ef41Sopenharmony_ci      // attributes of the interceptor, rather than the incoming attributes.
35331cb0ef41Sopenharmony_ci      //
35341cb0ef41Sopenharmony_ci      // TODO(verwaest): JSProxy afterwards verify the attributes that the
35351cb0ef41Sopenharmony_ci      // JSProxy claims it has, and verifies that they are compatible. If not,
35361cb0ef41Sopenharmony_ci      // they throw. Here we should do the same.
35371cb0ef41Sopenharmony_ci      case LookupIterator::INTERCEPTOR: {
35381cb0ef41Sopenharmony_ci        Maybe<bool> result = Just(false);
35391cb0ef41Sopenharmony_ci        if (semantics == EnforceDefineSemantics::kDefine) {
35401cb0ef41Sopenharmony_ci          PropertyDescriptor descriptor;
35411cb0ef41Sopenharmony_ci          descriptor.set_configurable((attributes & DONT_DELETE) != 0);
35421cb0ef41Sopenharmony_ci          descriptor.set_enumerable((attributes & DONT_ENUM) != 0);
35431cb0ef41Sopenharmony_ci          descriptor.set_writable((attributes & READ_ONLY) != 0);
35441cb0ef41Sopenharmony_ci          descriptor.set_value(value);
35451cb0ef41Sopenharmony_ci          result = DefinePropertyWithInterceptorInternal(
35461cb0ef41Sopenharmony_ci              it, it->GetInterceptor(), should_throw, &descriptor);
35471cb0ef41Sopenharmony_ci        } else {
35481cb0ef41Sopenharmony_ci          DCHECK_EQ(semantics, EnforceDefineSemantics::kSet);
35491cb0ef41Sopenharmony_ci          if (handling == DONT_FORCE_FIELD) {
35501cb0ef41Sopenharmony_ci            result =
35511cb0ef41Sopenharmony_ci                JSObject::SetPropertyWithInterceptor(it, should_throw, value);
35521cb0ef41Sopenharmony_ci          }
35531cb0ef41Sopenharmony_ci        }
35541cb0ef41Sopenharmony_ci        if (result.IsNothing() || result.FromJust()) return result;
35551cb0ef41Sopenharmony_ci
35561cb0ef41Sopenharmony_ci        if (semantics == EnforceDefineSemantics::kDefine) {
35571cb0ef41Sopenharmony_ci          it->Restart();
35581cb0ef41Sopenharmony_ci          Maybe<bool> can_define = JSReceiver::CheckIfCanDefine(
35591cb0ef41Sopenharmony_ci              it->isolate(), it, value, should_throw);
35601cb0ef41Sopenharmony_ci          if (can_define.IsNothing() || !can_define.FromJust()) {
35611cb0ef41Sopenharmony_ci            return can_define;
35621cb0ef41Sopenharmony_ci          }
35631cb0ef41Sopenharmony_ci        }
35641cb0ef41Sopenharmony_ci
35651cb0ef41Sopenharmony_ci        // The interceptor declined to handle the operation, so proceed defining
35661cb0ef41Sopenharmony_ci        // own property without the interceptor.
35671cb0ef41Sopenharmony_ci        Isolate* isolate = it->isolate();
35681cb0ef41Sopenharmony_ci        Handle<Object> receiver = it->GetReceiver();
35691cb0ef41Sopenharmony_ci        LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
35701cb0ef41Sopenharmony_ci        LookupIterator own_lookup =
35711cb0ef41Sopenharmony_ci            it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
35721cb0ef41Sopenharmony_ci                            : LookupIterator(isolate, receiver, it->name(), c);
35731cb0ef41Sopenharmony_ci        return JSObject::DefineOwnPropertyIgnoreAttributes(
35741cb0ef41Sopenharmony_ci            &own_lookup, value, attributes, should_throw, handling, semantics,
35751cb0ef41Sopenharmony_ci            store_origin);
35761cb0ef41Sopenharmony_ci      }
35771cb0ef41Sopenharmony_ci
35781cb0ef41Sopenharmony_ci      case LookupIterator::ACCESSOR: {
35791cb0ef41Sopenharmony_ci        Handle<Object> accessors = it->GetAccessors();
35801cb0ef41Sopenharmony_ci
35811cb0ef41Sopenharmony_ci        // Special handling for AccessorInfo, which behaves like a data
35821cb0ef41Sopenharmony_ci        // property.
35831cb0ef41Sopenharmony_ci        if (accessors->IsAccessorInfo() && handling == DONT_FORCE_FIELD) {
35841cb0ef41Sopenharmony_ci          PropertyAttributes current_attributes = it->property_attributes();
35851cb0ef41Sopenharmony_ci          // Ensure the context isn't changed after calling into accessors.
35861cb0ef41Sopenharmony_ci          AssertNoContextChange ncc(it->isolate());
35871cb0ef41Sopenharmony_ci
35881cb0ef41Sopenharmony_ci          // Update the attributes before calling the setter. The setter may
35891cb0ef41Sopenharmony_ci          // later change the shape of the property.
35901cb0ef41Sopenharmony_ci          if (current_attributes != attributes) {
35911cb0ef41Sopenharmony_ci            it->TransitionToAccessorPair(accessors, attributes);
35921cb0ef41Sopenharmony_ci          }
35931cb0ef41Sopenharmony_ci
35941cb0ef41Sopenharmony_ci          return Object::SetPropertyWithAccessor(it, value, should_throw);
35951cb0ef41Sopenharmony_ci        }
35961cb0ef41Sopenharmony_ci
35971cb0ef41Sopenharmony_ci        it->ReconfigureDataProperty(value, attributes);
35981cb0ef41Sopenharmony_ci        return Just(true);
35991cb0ef41Sopenharmony_ci      }
36001cb0ef41Sopenharmony_ci      case LookupIterator::INTEGER_INDEXED_EXOTIC:
36011cb0ef41Sopenharmony_ci        return Object::RedefineIncompatibleProperty(
36021cb0ef41Sopenharmony_ci            it->isolate(), it->GetName(), value, should_throw);
36031cb0ef41Sopenharmony_ci
36041cb0ef41Sopenharmony_ci      case LookupIterator::DATA: {
36051cb0ef41Sopenharmony_ci        // Regular property update if the attributes match.
36061cb0ef41Sopenharmony_ci        if (it->property_attributes() == attributes) {
36071cb0ef41Sopenharmony_ci          return Object::SetDataProperty(it, value);
36081cb0ef41Sopenharmony_ci        }
36091cb0ef41Sopenharmony_ci
36101cb0ef41Sopenharmony_ci        // The non-matching attribute case for JSTypedArrays has already been
36111cb0ef41Sopenharmony_ci        // handled by JSTypedArray::DefineOwnProperty.
36121cb0ef41Sopenharmony_ci        DCHECK(!it->IsElement() ||
36131cb0ef41Sopenharmony_ci               !Handle<JSObject>::cast(it->GetReceiver())
36141cb0ef41Sopenharmony_ci                    ->HasTypedArrayOrRabGsabTypedArrayElements());
36151cb0ef41Sopenharmony_ci        // Reconfigure the data property if the attributes mismatch.
36161cb0ef41Sopenharmony_ci        it->ReconfigureDataProperty(value, attributes);
36171cb0ef41Sopenharmony_ci
36181cb0ef41Sopenharmony_ci        return Just(true);
36191cb0ef41Sopenharmony_ci      }
36201cb0ef41Sopenharmony_ci    }
36211cb0ef41Sopenharmony_ci  }
36221cb0ef41Sopenharmony_ci
36231cb0ef41Sopenharmony_ci  return Object::AddDataProperty(it, value, attributes, should_throw,
36241cb0ef41Sopenharmony_ci                                 store_origin, semantics);
36251cb0ef41Sopenharmony_ci}
36261cb0ef41Sopenharmony_ci
36271cb0ef41Sopenharmony_ciMaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
36281cb0ef41Sopenharmony_ci    Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
36291cb0ef41Sopenharmony_ci    PropertyAttributes attributes) {
36301cb0ef41Sopenharmony_ci  DCHECK(!value->IsTheHole());
36311cb0ef41Sopenharmony_ci  LookupIterator it(object->GetIsolate(), object, name, object,
36321cb0ef41Sopenharmony_ci                    LookupIterator::OWN);
36331cb0ef41Sopenharmony_ci  return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
36341cb0ef41Sopenharmony_ci}
36351cb0ef41Sopenharmony_ci
36361cb0ef41Sopenharmony_ciMaybeHandle<Object> JSObject::SetOwnElementIgnoreAttributes(
36371cb0ef41Sopenharmony_ci    Handle<JSObject> object, size_t index, Handle<Object> value,
36381cb0ef41Sopenharmony_ci    PropertyAttributes attributes) {
36391cb0ef41Sopenharmony_ci  DCHECK(!object->IsJSTypedArray());
36401cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
36411cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, index, object, LookupIterator::OWN);
36421cb0ef41Sopenharmony_ci  return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
36431cb0ef41Sopenharmony_ci}
36441cb0ef41Sopenharmony_ci
36451cb0ef41Sopenharmony_ciMaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes(
36461cb0ef41Sopenharmony_ci    Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
36471cb0ef41Sopenharmony_ci    PropertyAttributes attributes) {
36481cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
36491cb0ef41Sopenharmony_ci  PropertyKey key(isolate, name);
36501cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, key, object, LookupIterator::OWN);
36511cb0ef41Sopenharmony_ci  return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
36521cb0ef41Sopenharmony_ci}
36531cb0ef41Sopenharmony_ci
36541cb0ef41Sopenharmony_ciMaybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
36551cb0ef41Sopenharmony_ci    LookupIterator* it) {
36561cb0ef41Sopenharmony_ci  return GetPropertyAttributesWithInterceptorInternal(it, it->GetInterceptor());
36571cb0ef41Sopenharmony_ci}
36581cb0ef41Sopenharmony_ci
36591cb0ef41Sopenharmony_civoid JSObject::NormalizeProperties(Isolate* isolate, Handle<JSObject> object,
36601cb0ef41Sopenharmony_ci                                   PropertyNormalizationMode mode,
36611cb0ef41Sopenharmony_ci                                   int expected_additional_properties,
36621cb0ef41Sopenharmony_ci                                   const char* reason) {
36631cb0ef41Sopenharmony_ci  if (!object->HasFastProperties()) return;
36641cb0ef41Sopenharmony_ci
36651cb0ef41Sopenharmony_ci  Handle<Map> map(object->map(), isolate);
36661cb0ef41Sopenharmony_ci  Handle<Map> new_map =
36671cb0ef41Sopenharmony_ci      Map::Normalize(isolate, map, map->elements_kind(), mode, reason);
36681cb0ef41Sopenharmony_ci
36691cb0ef41Sopenharmony_ci  JSObject::MigrateToMap(isolate, object, new_map,
36701cb0ef41Sopenharmony_ci                         expected_additional_properties);
36711cb0ef41Sopenharmony_ci}
36721cb0ef41Sopenharmony_ci
36731cb0ef41Sopenharmony_civoid JSObject::MigrateSlowToFast(Handle<JSObject> object,
36741cb0ef41Sopenharmony_ci                                 int unused_property_fields,
36751cb0ef41Sopenharmony_ci                                 const char* reason) {
36761cb0ef41Sopenharmony_ci  if (object->HasFastProperties()) return;
36771cb0ef41Sopenharmony_ci  DCHECK(!object->IsJSGlobalObject());
36781cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
36791cb0ef41Sopenharmony_ci  Factory* factory = isolate->factory();
36801cb0ef41Sopenharmony_ci
36811cb0ef41Sopenharmony_ci  Handle<NameDictionary> dictionary;
36821cb0ef41Sopenharmony_ci  Handle<SwissNameDictionary> swiss_dictionary;
36831cb0ef41Sopenharmony_ci  int number_of_elements;
36841cb0ef41Sopenharmony_ci  if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
36851cb0ef41Sopenharmony_ci    swiss_dictionary = handle(object->property_dictionary_swiss(), isolate);
36861cb0ef41Sopenharmony_ci    number_of_elements = swiss_dictionary->NumberOfElements();
36871cb0ef41Sopenharmony_ci  } else {
36881cb0ef41Sopenharmony_ci    dictionary = handle(object->property_dictionary(), isolate);
36891cb0ef41Sopenharmony_ci    number_of_elements = dictionary->NumberOfElements();
36901cb0ef41Sopenharmony_ci  }
36911cb0ef41Sopenharmony_ci
36921cb0ef41Sopenharmony_ci  // Make sure we preserve dictionary representation if there are too many
36931cb0ef41Sopenharmony_ci  // descriptors.
36941cb0ef41Sopenharmony_ci  if (number_of_elements > kMaxNumberOfDescriptors) return;
36951cb0ef41Sopenharmony_ci
36961cb0ef41Sopenharmony_ci  Handle<FixedArray> iteration_order;
36971cb0ef41Sopenharmony_ci  int iteration_length;
36981cb0ef41Sopenharmony_ci  if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
36991cb0ef41Sopenharmony_ci    // |iteration_order| remains empty handle, we don't need it.
37001cb0ef41Sopenharmony_ci    iteration_length = swiss_dictionary->UsedCapacity();
37011cb0ef41Sopenharmony_ci  } else {
37021cb0ef41Sopenharmony_ci    iteration_order = NameDictionary::IterationIndices(isolate, dictionary);
37031cb0ef41Sopenharmony_ci    iteration_length = dictionary->NumberOfElements();
37041cb0ef41Sopenharmony_ci  }
37051cb0ef41Sopenharmony_ci
37061cb0ef41Sopenharmony_ci  int number_of_fields = 0;
37071cb0ef41Sopenharmony_ci
37081cb0ef41Sopenharmony_ci  // Compute the length of the instance descriptor.
37091cb0ef41Sopenharmony_ci  ReadOnlyRoots roots(isolate);
37101cb0ef41Sopenharmony_ci  for (int i = 0; i < iteration_length; i++) {
37111cb0ef41Sopenharmony_ci    PropertyKind kind;
37121cb0ef41Sopenharmony_ci    if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
37131cb0ef41Sopenharmony_ci      InternalIndex index(swiss_dictionary->EntryForEnumerationIndex(i));
37141cb0ef41Sopenharmony_ci      Object key = swiss_dictionary->KeyAt(index);
37151cb0ef41Sopenharmony_ci      if (!SwissNameDictionary::IsKey(roots, key)) {
37161cb0ef41Sopenharmony_ci        // Ignore deleted entries.
37171cb0ef41Sopenharmony_ci        continue;
37181cb0ef41Sopenharmony_ci      }
37191cb0ef41Sopenharmony_ci      kind = swiss_dictionary->DetailsAt(index).kind();
37201cb0ef41Sopenharmony_ci    } else {
37211cb0ef41Sopenharmony_ci      InternalIndex index(Smi::ToInt(iteration_order->get(i)));
37221cb0ef41Sopenharmony_ci      DCHECK(dictionary->IsKey(roots, dictionary->KeyAt(isolate, index)));
37231cb0ef41Sopenharmony_ci      kind = dictionary->DetailsAt(index).kind();
37241cb0ef41Sopenharmony_ci    }
37251cb0ef41Sopenharmony_ci
37261cb0ef41Sopenharmony_ci    if (kind == PropertyKind::kData) {
37271cb0ef41Sopenharmony_ci      number_of_fields += 1;
37281cb0ef41Sopenharmony_ci    }
37291cb0ef41Sopenharmony_ci  }
37301cb0ef41Sopenharmony_ci
37311cb0ef41Sopenharmony_ci  Handle<Map> old_map(object->map(), isolate);
37321cb0ef41Sopenharmony_ci
37331cb0ef41Sopenharmony_ci  int inobject_props = old_map->GetInObjectProperties();
37341cb0ef41Sopenharmony_ci
37351cb0ef41Sopenharmony_ci  // Allocate new map.
37361cb0ef41Sopenharmony_ci  Handle<Map> new_map = Map::CopyDropDescriptors(isolate, old_map);
37371cb0ef41Sopenharmony_ci  // We should not only set this bit if we need to. We should not retain the
37381cb0ef41Sopenharmony_ci  // old bit because turning a map into dictionary always sets this bit.
37391cb0ef41Sopenharmony_ci  new_map->set_may_have_interesting_symbols(new_map->has_named_interceptor() ||
37401cb0ef41Sopenharmony_ci                                            new_map->is_access_check_needed());
37411cb0ef41Sopenharmony_ci  new_map->set_is_dictionary_map(false);
37421cb0ef41Sopenharmony_ci
37431cb0ef41Sopenharmony_ci  NotifyMapChange(old_map, new_map, isolate);
37441cb0ef41Sopenharmony_ci
37451cb0ef41Sopenharmony_ci  if (number_of_elements == 0) {
37461cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_gc;
37471cb0ef41Sopenharmony_ci    DCHECK_LE(unused_property_fields, inobject_props);
37481cb0ef41Sopenharmony_ci    // Transform the object.
37491cb0ef41Sopenharmony_ci    new_map->SetInObjectUnusedPropertyFields(inobject_props);
37501cb0ef41Sopenharmony_ci    object->set_map(*new_map, kReleaseStore);
37511cb0ef41Sopenharmony_ci    object->SetProperties(ReadOnlyRoots(isolate).empty_fixed_array());
37521cb0ef41Sopenharmony_ci    // Check that it really works.
37531cb0ef41Sopenharmony_ci    DCHECK(object->HasFastProperties());
37541cb0ef41Sopenharmony_ci    if (FLAG_log_maps) {
37551cb0ef41Sopenharmony_ci      LOG(isolate, MapEvent("SlowToFast", old_map, new_map, reason));
37561cb0ef41Sopenharmony_ci    }
37571cb0ef41Sopenharmony_ci    return;
37581cb0ef41Sopenharmony_ci  }
37591cb0ef41Sopenharmony_ci
37601cb0ef41Sopenharmony_ci  // Allocate the instance descriptor.
37611cb0ef41Sopenharmony_ci  Handle<DescriptorArray> descriptors =
37621cb0ef41Sopenharmony_ci      DescriptorArray::Allocate(isolate, number_of_elements, 0);
37631cb0ef41Sopenharmony_ci
37641cb0ef41Sopenharmony_ci  int number_of_allocated_fields =
37651cb0ef41Sopenharmony_ci      number_of_fields + unused_property_fields - inobject_props;
37661cb0ef41Sopenharmony_ci  if (number_of_allocated_fields < 0) {
37671cb0ef41Sopenharmony_ci    // There is enough inobject space for all fields (including unused).
37681cb0ef41Sopenharmony_ci    number_of_allocated_fields = 0;
37691cb0ef41Sopenharmony_ci    unused_property_fields = inobject_props - number_of_fields;
37701cb0ef41Sopenharmony_ci  }
37711cb0ef41Sopenharmony_ci
37721cb0ef41Sopenharmony_ci  // Allocate the property array for the fields.
37731cb0ef41Sopenharmony_ci  Handle<PropertyArray> fields =
37741cb0ef41Sopenharmony_ci      factory->NewPropertyArray(number_of_allocated_fields);
37751cb0ef41Sopenharmony_ci
37761cb0ef41Sopenharmony_ci  bool is_transitionable_elements_kind =
37771cb0ef41Sopenharmony_ci      IsTransitionableFastElementsKind(old_map->elements_kind());
37781cb0ef41Sopenharmony_ci
37791cb0ef41Sopenharmony_ci  // Fill in the instance descriptor and the fields.
37801cb0ef41Sopenharmony_ci  int current_offset = 0;
37811cb0ef41Sopenharmony_ci  int descriptor_index = 0;
37821cb0ef41Sopenharmony_ci  for (int i = 0; i < iteration_length; i++) {
37831cb0ef41Sopenharmony_ci    Name k;
37841cb0ef41Sopenharmony_ci    Object value;
37851cb0ef41Sopenharmony_ci    PropertyDetails details = PropertyDetails::Empty();
37861cb0ef41Sopenharmony_ci
37871cb0ef41Sopenharmony_ci    if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
37881cb0ef41Sopenharmony_ci      InternalIndex index(swiss_dictionary->EntryForEnumerationIndex(i));
37891cb0ef41Sopenharmony_ci      Object key_obj = swiss_dictionary->KeyAt(index);
37901cb0ef41Sopenharmony_ci      if (!SwissNameDictionary::IsKey(roots, key_obj)) {
37911cb0ef41Sopenharmony_ci        continue;
37921cb0ef41Sopenharmony_ci      }
37931cb0ef41Sopenharmony_ci      k = Name::cast(key_obj);
37941cb0ef41Sopenharmony_ci
37951cb0ef41Sopenharmony_ci      value = swiss_dictionary->ValueAt(index);
37961cb0ef41Sopenharmony_ci      details = swiss_dictionary->DetailsAt(index);
37971cb0ef41Sopenharmony_ci    } else {
37981cb0ef41Sopenharmony_ci      InternalIndex index(Smi::ToInt(iteration_order->get(i)));
37991cb0ef41Sopenharmony_ci      k = dictionary->NameAt(index);
38001cb0ef41Sopenharmony_ci
38011cb0ef41Sopenharmony_ci      value = dictionary->ValueAt(index);
38021cb0ef41Sopenharmony_ci      details = dictionary->DetailsAt(index);
38031cb0ef41Sopenharmony_ci    }
38041cb0ef41Sopenharmony_ci
38051cb0ef41Sopenharmony_ci    // Dictionary keys are internalized upon insertion.
38061cb0ef41Sopenharmony_ci    // TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild.
38071cb0ef41Sopenharmony_ci    CHECK(k.IsUniqueName());
38081cb0ef41Sopenharmony_ci    Handle<Name> key(k, isolate);
38091cb0ef41Sopenharmony_ci
38101cb0ef41Sopenharmony_ci    // Properly mark the {new_map} if the {key} is an "interesting symbol".
38111cb0ef41Sopenharmony_ci    if (key->IsInterestingSymbol()) {
38121cb0ef41Sopenharmony_ci      new_map->set_may_have_interesting_symbols(true);
38131cb0ef41Sopenharmony_ci    }
38141cb0ef41Sopenharmony_ci
38151cb0ef41Sopenharmony_ci    DCHECK_EQ(PropertyLocation::kField, details.location());
38161cb0ef41Sopenharmony_ci    DCHECK_IMPLIES(!V8_DICT_PROPERTY_CONST_TRACKING_BOOL,
38171cb0ef41Sopenharmony_ci                   details.constness() == PropertyConstness::kMutable);
38181cb0ef41Sopenharmony_ci
38191cb0ef41Sopenharmony_ci    Descriptor d;
38201cb0ef41Sopenharmony_ci    if (details.kind() == PropertyKind::kData) {
38211cb0ef41Sopenharmony_ci      // Ensure that we make constant field only when elements kind is not
38221cb0ef41Sopenharmony_ci      // transitionable.
38231cb0ef41Sopenharmony_ci      PropertyConstness constness = is_transitionable_elements_kind
38241cb0ef41Sopenharmony_ci                                        ? PropertyConstness::kMutable
38251cb0ef41Sopenharmony_ci                                        : PropertyConstness::kConst;
38261cb0ef41Sopenharmony_ci      // TODO(v8:11248): Consider always setting constness to kMutable
38271cb0ef41Sopenharmony_ci      // once all prototypes stay in dictionary mode and we are not interested
38281cb0ef41Sopenharmony_ci      // in tracking constness for fast mode properties anymore.
38291cb0ef41Sopenharmony_ci
38301cb0ef41Sopenharmony_ci      d = Descriptor::DataField(
38311cb0ef41Sopenharmony_ci          key, current_offset, details.attributes(), constness,
38321cb0ef41Sopenharmony_ci          // TODO(verwaest): value->OptimalRepresentation();
38331cb0ef41Sopenharmony_ci          Representation::Tagged(), MaybeObjectHandle(FieldType::Any(isolate)));
38341cb0ef41Sopenharmony_ci    } else {
38351cb0ef41Sopenharmony_ci      DCHECK_EQ(PropertyKind::kAccessor, details.kind());
38361cb0ef41Sopenharmony_ci      d = Descriptor::AccessorConstant(key, handle(value, isolate),
38371cb0ef41Sopenharmony_ci                                       details.attributes());
38381cb0ef41Sopenharmony_ci    }
38391cb0ef41Sopenharmony_ci    details = d.GetDetails();
38401cb0ef41Sopenharmony_ci    if (details.location() == PropertyLocation::kField) {
38411cb0ef41Sopenharmony_ci      if (current_offset < inobject_props) {
38421cb0ef41Sopenharmony_ci        object->InObjectPropertyAtPut(current_offset, value,
38431cb0ef41Sopenharmony_ci                                      UPDATE_WRITE_BARRIER);
38441cb0ef41Sopenharmony_ci      } else {
38451cb0ef41Sopenharmony_ci        int offset = current_offset - inobject_props;
38461cb0ef41Sopenharmony_ci        fields->set(offset, value);
38471cb0ef41Sopenharmony_ci      }
38481cb0ef41Sopenharmony_ci      current_offset += details.field_width_in_words();
38491cb0ef41Sopenharmony_ci    }
38501cb0ef41Sopenharmony_ci    descriptors->Set(InternalIndex(descriptor_index++), &d);
38511cb0ef41Sopenharmony_ci  }
38521cb0ef41Sopenharmony_ci  DCHECK_EQ(current_offset, number_of_fields);
38531cb0ef41Sopenharmony_ci  DCHECK_EQ(descriptor_index, number_of_elements);
38541cb0ef41Sopenharmony_ci
38551cb0ef41Sopenharmony_ci  descriptors->Sort();
38561cb0ef41Sopenharmony_ci
38571cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
38581cb0ef41Sopenharmony_ci  new_map->InitializeDescriptors(isolate, *descriptors);
38591cb0ef41Sopenharmony_ci  if (number_of_allocated_fields == 0) {
38601cb0ef41Sopenharmony_ci    new_map->SetInObjectUnusedPropertyFields(unused_property_fields);
38611cb0ef41Sopenharmony_ci  } else {
38621cb0ef41Sopenharmony_ci    new_map->SetOutOfObjectUnusedPropertyFields(unused_property_fields);
38631cb0ef41Sopenharmony_ci  }
38641cb0ef41Sopenharmony_ci
38651cb0ef41Sopenharmony_ci  if (FLAG_log_maps) {
38661cb0ef41Sopenharmony_ci    LOG(isolate, MapEvent("SlowToFast", old_map, new_map, reason));
38671cb0ef41Sopenharmony_ci  }
38681cb0ef41Sopenharmony_ci  // Transform the object.
38691cb0ef41Sopenharmony_ci  object->set_map(*new_map, kReleaseStore);
38701cb0ef41Sopenharmony_ci
38711cb0ef41Sopenharmony_ci  object->SetProperties(*fields);
38721cb0ef41Sopenharmony_ci  DCHECK(object->IsJSObject());
38731cb0ef41Sopenharmony_ci
38741cb0ef41Sopenharmony_ci  // Check that it really works.
38751cb0ef41Sopenharmony_ci  DCHECK(object->HasFastProperties());
38761cb0ef41Sopenharmony_ci}
38771cb0ef41Sopenharmony_ci
38781cb0ef41Sopenharmony_civoid JSObject::RequireSlowElements(NumberDictionary dictionary) {
38791cb0ef41Sopenharmony_ci  DCHECK_NE(dictionary,
38801cb0ef41Sopenharmony_ci            ReadOnlyRoots(GetIsolate()).empty_slow_element_dictionary());
38811cb0ef41Sopenharmony_ci  if (dictionary.requires_slow_elements()) return;
38821cb0ef41Sopenharmony_ci  dictionary.set_requires_slow_elements();
38831cb0ef41Sopenharmony_ci  if (map().is_prototype_map()) {
38841cb0ef41Sopenharmony_ci    // If this object is a prototype (the callee will check), invalidate any
38851cb0ef41Sopenharmony_ci    // prototype chains involving it.
38861cb0ef41Sopenharmony_ci    InvalidatePrototypeChains(map());
38871cb0ef41Sopenharmony_ci  }
38881cb0ef41Sopenharmony_ci}
38891cb0ef41Sopenharmony_ci
38901cb0ef41Sopenharmony_ciHandle<NumberDictionary> JSObject::NormalizeElements(Handle<JSObject> object) {
38911cb0ef41Sopenharmony_ci  DCHECK(!object->HasTypedArrayOrRabGsabTypedArrayElements());
38921cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
38931cb0ef41Sopenharmony_ci  bool is_sloppy_arguments = object->HasSloppyArgumentsElements();
38941cb0ef41Sopenharmony_ci  {
38951cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_gc;
38961cb0ef41Sopenharmony_ci    FixedArrayBase elements = object->elements();
38971cb0ef41Sopenharmony_ci
38981cb0ef41Sopenharmony_ci    if (is_sloppy_arguments) {
38991cb0ef41Sopenharmony_ci      elements = SloppyArgumentsElements::cast(elements).arguments();
39001cb0ef41Sopenharmony_ci    }
39011cb0ef41Sopenharmony_ci
39021cb0ef41Sopenharmony_ci    if (elements.IsNumberDictionary()) {
39031cb0ef41Sopenharmony_ci      return handle(NumberDictionary::cast(elements), isolate);
39041cb0ef41Sopenharmony_ci    }
39051cb0ef41Sopenharmony_ci  }
39061cb0ef41Sopenharmony_ci
39071cb0ef41Sopenharmony_ci  DCHECK(object->HasSmiOrObjectElements() || object->HasDoubleElements() ||
39081cb0ef41Sopenharmony_ci         object->HasFastArgumentsElements() ||
39091cb0ef41Sopenharmony_ci         object->HasFastStringWrapperElements() ||
39101cb0ef41Sopenharmony_ci         object->HasSealedElements() || object->HasNonextensibleElements());
39111cb0ef41Sopenharmony_ci
39121cb0ef41Sopenharmony_ci  Handle<NumberDictionary> dictionary =
39131cb0ef41Sopenharmony_ci      object->GetElementsAccessor()->Normalize(object);
39141cb0ef41Sopenharmony_ci
39151cb0ef41Sopenharmony_ci  // Switch to using the dictionary as the backing storage for elements.
39161cb0ef41Sopenharmony_ci  ElementsKind target_kind = is_sloppy_arguments
39171cb0ef41Sopenharmony_ci                                 ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS
39181cb0ef41Sopenharmony_ci                                 : object->HasFastStringWrapperElements()
39191cb0ef41Sopenharmony_ci                                       ? SLOW_STRING_WRAPPER_ELEMENTS
39201cb0ef41Sopenharmony_ci                                       : DICTIONARY_ELEMENTS;
39211cb0ef41Sopenharmony_ci  Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind);
39221cb0ef41Sopenharmony_ci  // Set the new map first to satify the elements type assert in set_elements().
39231cb0ef41Sopenharmony_ci  JSObject::MigrateToMap(isolate, object, new_map);
39241cb0ef41Sopenharmony_ci
39251cb0ef41Sopenharmony_ci  if (is_sloppy_arguments) {
39261cb0ef41Sopenharmony_ci    SloppyArgumentsElements::cast(object->elements())
39271cb0ef41Sopenharmony_ci        .set_arguments(*dictionary);
39281cb0ef41Sopenharmony_ci  } else {
39291cb0ef41Sopenharmony_ci    object->set_elements(*dictionary);
39301cb0ef41Sopenharmony_ci  }
39311cb0ef41Sopenharmony_ci
39321cb0ef41Sopenharmony_ci  isolate->counters()->elements_to_dictionary()->Increment();
39331cb0ef41Sopenharmony_ci
39341cb0ef41Sopenharmony_ci#ifdef DEBUG
39351cb0ef41Sopenharmony_ci  if (FLAG_trace_normalization) {
39361cb0ef41Sopenharmony_ci    StdoutStream os;
39371cb0ef41Sopenharmony_ci    os << "Object elements have been normalized:\n";
39381cb0ef41Sopenharmony_ci    object->Print(os);
39391cb0ef41Sopenharmony_ci  }
39401cb0ef41Sopenharmony_ci#endif
39411cb0ef41Sopenharmony_ci
39421cb0ef41Sopenharmony_ci  DCHECK(object->HasDictionaryElements() ||
39431cb0ef41Sopenharmony_ci         object->HasSlowArgumentsElements() ||
39441cb0ef41Sopenharmony_ci         object->HasSlowStringWrapperElements());
39451cb0ef41Sopenharmony_ci  return dictionary;
39461cb0ef41Sopenharmony_ci}
39471cb0ef41Sopenharmony_ci
39481cb0ef41Sopenharmony_ciMaybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
39491cb0ef41Sopenharmony_ci                                                    ShouldThrow should_throw) {
39501cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
39511cb0ef41Sopenharmony_ci  // Make sure that the top context does not change when doing callbacks or
39521cb0ef41Sopenharmony_ci  // interceptor calls.
39531cb0ef41Sopenharmony_ci  AssertNoContextChange ncc(isolate);
39541cb0ef41Sopenharmony_ci
39551cb0ef41Sopenharmony_ci  DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
39561cb0ef41Sopenharmony_ci  Handle<InterceptorInfo> interceptor(it->GetInterceptor());
39571cb0ef41Sopenharmony_ci  if (interceptor->deleter().IsUndefined(isolate)) return Nothing<bool>();
39581cb0ef41Sopenharmony_ci
39591cb0ef41Sopenharmony_ci  Handle<JSObject> holder = it->GetHolder<JSObject>();
39601cb0ef41Sopenharmony_ci  Handle<Object> receiver = it->GetReceiver();
39611cb0ef41Sopenharmony_ci  if (!receiver->IsJSReceiver()) {
39621cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
39631cb0ef41Sopenharmony_ci                                     Object::ConvertReceiver(isolate, receiver),
39641cb0ef41Sopenharmony_ci                                     Nothing<bool>());
39651cb0ef41Sopenharmony_ci  }
39661cb0ef41Sopenharmony_ci
39671cb0ef41Sopenharmony_ci  PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
39681cb0ef41Sopenharmony_ci                                 *holder, Just(should_throw));
39691cb0ef41Sopenharmony_ci  Handle<Object> result;
39701cb0ef41Sopenharmony_ci  if (it->IsElement(*holder)) {
39711cb0ef41Sopenharmony_ci    result = args.CallIndexedDeleter(interceptor, it->array_index());
39721cb0ef41Sopenharmony_ci  } else {
39731cb0ef41Sopenharmony_ci    result = args.CallNamedDeleter(interceptor, it->name());
39741cb0ef41Sopenharmony_ci  }
39751cb0ef41Sopenharmony_ci
39761cb0ef41Sopenharmony_ci  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
39771cb0ef41Sopenharmony_ci  if (result.is_null()) return Nothing<bool>();
39781cb0ef41Sopenharmony_ci
39791cb0ef41Sopenharmony_ci  DCHECK(result->IsBoolean());
39801cb0ef41Sopenharmony_ci  // Rebox CustomArguments::kReturnValueOffset before returning.
39811cb0ef41Sopenharmony_ci  return Just(result->IsTrue(isolate));
39821cb0ef41Sopenharmony_ci}
39831cb0ef41Sopenharmony_ci
39841cb0ef41Sopenharmony_ciMaybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
39851cb0ef41Sopenharmony_ci                                         Handle<Object> value,
39861cb0ef41Sopenharmony_ci                                         Maybe<ShouldThrow> should_throw) {
39871cb0ef41Sopenharmony_ci  DCHECK(it->GetReceiver()->IsJSObject());
39881cb0ef41Sopenharmony_ci  MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>());
39891cb0ef41Sopenharmony_ci  Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
39901cb0ef41Sopenharmony_ci  Isolate* isolate = receiver->GetIsolate();
39911cb0ef41Sopenharmony_ci
39921cb0ef41Sopenharmony_ci  Maybe<bool> can_define =
39931cb0ef41Sopenharmony_ci      JSReceiver::CheckIfCanDefine(isolate, it, value, should_throw);
39941cb0ef41Sopenharmony_ci  if (can_define.IsNothing() || !can_define.FromJust()) {
39951cb0ef41Sopenharmony_ci    return can_define;
39961cb0ef41Sopenharmony_ci  }
39971cb0ef41Sopenharmony_ci
39981cb0ef41Sopenharmony_ci  RETURN_ON_EXCEPTION_VALUE(it->isolate(),
39991cb0ef41Sopenharmony_ci                            DefineOwnPropertyIgnoreAttributes(it, value, NONE),
40001cb0ef41Sopenharmony_ci                            Nothing<bool>());
40011cb0ef41Sopenharmony_ci
40021cb0ef41Sopenharmony_ci  return Just(true);
40031cb0ef41Sopenharmony_ci}
40041cb0ef41Sopenharmony_ci
40051cb0ef41Sopenharmony_cinamespace {
40061cb0ef41Sopenharmony_ci
40071cb0ef41Sopenharmony_citemplate <typename Dictionary>
40081cb0ef41Sopenharmony_cibool TestDictionaryPropertiesIntegrityLevel(Dictionary dict,
40091cb0ef41Sopenharmony_ci                                            ReadOnlyRoots roots,
40101cb0ef41Sopenharmony_ci                                            PropertyAttributes level) {
40111cb0ef41Sopenharmony_ci  DCHECK(level == SEALED || level == FROZEN);
40121cb0ef41Sopenharmony_ci
40131cb0ef41Sopenharmony_ci  for (InternalIndex i : dict.IterateEntries()) {
40141cb0ef41Sopenharmony_ci    Object key;
40151cb0ef41Sopenharmony_ci    if (!dict.ToKey(roots, i, &key)) continue;
40161cb0ef41Sopenharmony_ci    if (key.FilterKey(ALL_PROPERTIES)) continue;
40171cb0ef41Sopenharmony_ci    PropertyDetails details = dict.DetailsAt(i);
40181cb0ef41Sopenharmony_ci    if (details.IsConfigurable()) return false;
40191cb0ef41Sopenharmony_ci    if (level == FROZEN && details.kind() == PropertyKind::kData &&
40201cb0ef41Sopenharmony_ci        !details.IsReadOnly()) {
40211cb0ef41Sopenharmony_ci      return false;
40221cb0ef41Sopenharmony_ci    }
40231cb0ef41Sopenharmony_ci  }
40241cb0ef41Sopenharmony_ci  return true;
40251cb0ef41Sopenharmony_ci}
40261cb0ef41Sopenharmony_ci
40271cb0ef41Sopenharmony_cibool TestFastPropertiesIntegrityLevel(Map map, PropertyAttributes level) {
40281cb0ef41Sopenharmony_ci  DCHECK(level == SEALED || level == FROZEN);
40291cb0ef41Sopenharmony_ci  DCHECK(!map.IsCustomElementsReceiverMap());
40301cb0ef41Sopenharmony_ci  DCHECK(!map.is_dictionary_map());
40311cb0ef41Sopenharmony_ci
40321cb0ef41Sopenharmony_ci  DescriptorArray descriptors = map.instance_descriptors();
40331cb0ef41Sopenharmony_ci  for (InternalIndex i : map.IterateOwnDescriptors()) {
40341cb0ef41Sopenharmony_ci    if (descriptors.GetKey(i).IsPrivate()) continue;
40351cb0ef41Sopenharmony_ci    PropertyDetails details = descriptors.GetDetails(i);
40361cb0ef41Sopenharmony_ci    if (details.IsConfigurable()) return false;
40371cb0ef41Sopenharmony_ci    if (level == FROZEN && details.kind() == PropertyKind::kData &&
40381cb0ef41Sopenharmony_ci        !details.IsReadOnly()) {
40391cb0ef41Sopenharmony_ci      return false;
40401cb0ef41Sopenharmony_ci    }
40411cb0ef41Sopenharmony_ci  }
40421cb0ef41Sopenharmony_ci  return true;
40431cb0ef41Sopenharmony_ci}
40441cb0ef41Sopenharmony_ci
40451cb0ef41Sopenharmony_cibool TestPropertiesIntegrityLevel(JSObject object, PropertyAttributes level) {
40461cb0ef41Sopenharmony_ci  DCHECK(!object.map().IsCustomElementsReceiverMap());
40471cb0ef41Sopenharmony_ci
40481cb0ef41Sopenharmony_ci  if (object.HasFastProperties()) {
40491cb0ef41Sopenharmony_ci    return TestFastPropertiesIntegrityLevel(object.map(), level);
40501cb0ef41Sopenharmony_ci  }
40511cb0ef41Sopenharmony_ci
40521cb0ef41Sopenharmony_ci  if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
40531cb0ef41Sopenharmony_ci    return TestDictionaryPropertiesIntegrityLevel(
40541cb0ef41Sopenharmony_ci        object.property_dictionary_swiss(), object.GetReadOnlyRoots(), level);
40551cb0ef41Sopenharmony_ci  } else {
40561cb0ef41Sopenharmony_ci    return TestDictionaryPropertiesIntegrityLevel(
40571cb0ef41Sopenharmony_ci        object.property_dictionary(), object.GetReadOnlyRoots(), level);
40581cb0ef41Sopenharmony_ci  }
40591cb0ef41Sopenharmony_ci}
40601cb0ef41Sopenharmony_ci
40611cb0ef41Sopenharmony_cibool TestElementsIntegrityLevel(JSObject object, PropertyAttributes level) {
40621cb0ef41Sopenharmony_ci  DCHECK(!object.HasSloppyArgumentsElements());
40631cb0ef41Sopenharmony_ci
40641cb0ef41Sopenharmony_ci  ElementsKind kind = object.GetElementsKind();
40651cb0ef41Sopenharmony_ci
40661cb0ef41Sopenharmony_ci  if (IsDictionaryElementsKind(kind)) {
40671cb0ef41Sopenharmony_ci    return TestDictionaryPropertiesIntegrityLevel(
40681cb0ef41Sopenharmony_ci        NumberDictionary::cast(object.elements()), object.GetReadOnlyRoots(),
40691cb0ef41Sopenharmony_ci        level);
40701cb0ef41Sopenharmony_ci  }
40711cb0ef41Sopenharmony_ci  if (IsTypedArrayElementsKind(kind)) {
40721cb0ef41Sopenharmony_ci    if (level == FROZEN && JSArrayBufferView::cast(object).byte_length() > 0) {
40731cb0ef41Sopenharmony_ci      return false;  // TypedArrays with elements can't be frozen.
40741cb0ef41Sopenharmony_ci    }
40751cb0ef41Sopenharmony_ci    return TestPropertiesIntegrityLevel(object, level);
40761cb0ef41Sopenharmony_ci  }
40771cb0ef41Sopenharmony_ci  if (IsFrozenElementsKind(kind)) return true;
40781cb0ef41Sopenharmony_ci  if (IsSealedElementsKind(kind) && level != FROZEN) return true;
40791cb0ef41Sopenharmony_ci  if (IsNonextensibleElementsKind(kind) && level == NONE) return true;
40801cb0ef41Sopenharmony_ci
40811cb0ef41Sopenharmony_ci  ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
40821cb0ef41Sopenharmony_ci  // Only DICTIONARY_ELEMENTS and SLOW_SLOPPY_ARGUMENTS_ELEMENTS have
40831cb0ef41Sopenharmony_ci  // PropertyAttributes so just test if empty
40841cb0ef41Sopenharmony_ci  return accessor->NumberOfElements(object) == 0;
40851cb0ef41Sopenharmony_ci}
40861cb0ef41Sopenharmony_ci
40871cb0ef41Sopenharmony_cibool FastTestIntegrityLevel(JSObject object, PropertyAttributes level) {
40881cb0ef41Sopenharmony_ci  DCHECK(!object.map().IsCustomElementsReceiverMap());
40891cb0ef41Sopenharmony_ci
40901cb0ef41Sopenharmony_ci  return !object.map().is_extensible() &&
40911cb0ef41Sopenharmony_ci         TestElementsIntegrityLevel(object, level) &&
40921cb0ef41Sopenharmony_ci         TestPropertiesIntegrityLevel(object, level);
40931cb0ef41Sopenharmony_ci}
40941cb0ef41Sopenharmony_ci
40951cb0ef41Sopenharmony_ci}  // namespace
40961cb0ef41Sopenharmony_ci
40971cb0ef41Sopenharmony_ciMaybe<bool> JSObject::TestIntegrityLevel(Handle<JSObject> object,
40981cb0ef41Sopenharmony_ci                                         IntegrityLevel level) {
40991cb0ef41Sopenharmony_ci  if (!object->map().IsCustomElementsReceiverMap() &&
41001cb0ef41Sopenharmony_ci      !object->HasSloppyArgumentsElements()) {
41011cb0ef41Sopenharmony_ci    return Just(FastTestIntegrityLevel(*object, level));
41021cb0ef41Sopenharmony_ci  }
41031cb0ef41Sopenharmony_ci  return GenericTestIntegrityLevel(Handle<JSReceiver>::cast(object), level);
41041cb0ef41Sopenharmony_ci}
41051cb0ef41Sopenharmony_ci
41061cb0ef41Sopenharmony_ciMaybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
41071cb0ef41Sopenharmony_ci                                        ShouldThrow should_throw) {
41081cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
41091cb0ef41Sopenharmony_ci
41101cb0ef41Sopenharmony_ci  if (!object->HasSloppyArgumentsElements()) {
41111cb0ef41Sopenharmony_ci    return PreventExtensionsWithTransition<NONE>(object, should_throw);
41121cb0ef41Sopenharmony_ci  }
41131cb0ef41Sopenharmony_ci
41141cb0ef41Sopenharmony_ci  if (object->IsAccessCheckNeeded() &&
41151cb0ef41Sopenharmony_ci      !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
41161cb0ef41Sopenharmony_ci    isolate->ReportFailedAccessCheck(object);
41171cb0ef41Sopenharmony_ci    RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
41181cb0ef41Sopenharmony_ci    RETURN_FAILURE(isolate, should_throw,
41191cb0ef41Sopenharmony_ci                   NewTypeError(MessageTemplate::kNoAccess));
41201cb0ef41Sopenharmony_ci  }
41211cb0ef41Sopenharmony_ci
41221cb0ef41Sopenharmony_ci  if (!object->map().is_extensible()) return Just(true);
41231cb0ef41Sopenharmony_ci
41241cb0ef41Sopenharmony_ci  if (object->IsJSGlobalProxy()) {
41251cb0ef41Sopenharmony_ci    PrototypeIterator iter(isolate, object);
41261cb0ef41Sopenharmony_ci    if (iter.IsAtEnd()) return Just(true);
41271cb0ef41Sopenharmony_ci    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
41281cb0ef41Sopenharmony_ci    return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter),
41291cb0ef41Sopenharmony_ci                             should_throw);
41301cb0ef41Sopenharmony_ci  }
41311cb0ef41Sopenharmony_ci
41321cb0ef41Sopenharmony_ci  if (object->map().has_named_interceptor() ||
41331cb0ef41Sopenharmony_ci      object->map().has_indexed_interceptor()) {
41341cb0ef41Sopenharmony_ci    RETURN_FAILURE(isolate, should_throw,
41351cb0ef41Sopenharmony_ci                   NewTypeError(MessageTemplate::kCannotPreventExt));
41361cb0ef41Sopenharmony_ci  }
41371cb0ef41Sopenharmony_ci
41381cb0ef41Sopenharmony_ci  DCHECK(!object->HasTypedArrayOrRabGsabTypedArrayElements());
41391cb0ef41Sopenharmony_ci
41401cb0ef41Sopenharmony_ci  // Normalize fast elements.
41411cb0ef41Sopenharmony_ci  Handle<NumberDictionary> dictionary = NormalizeElements(object);
41421cb0ef41Sopenharmony_ci  DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements());
41431cb0ef41Sopenharmony_ci
41441cb0ef41Sopenharmony_ci  // Make sure that we never go back to fast case.
41451cb0ef41Sopenharmony_ci  if (*dictionary != ReadOnlyRoots(isolate).empty_slow_element_dictionary()) {
41461cb0ef41Sopenharmony_ci    object->RequireSlowElements(*dictionary);
41471cb0ef41Sopenharmony_ci  }
41481cb0ef41Sopenharmony_ci
41491cb0ef41Sopenharmony_ci  // Do a map transition, other objects with this map may still
41501cb0ef41Sopenharmony_ci  // be extensible.
41511cb0ef41Sopenharmony_ci  // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
41521cb0ef41Sopenharmony_ci  Handle<Map> new_map =
41531cb0ef41Sopenharmony_ci      Map::Copy(isolate, handle(object->map(), isolate), "PreventExtensions");
41541cb0ef41Sopenharmony_ci
41551cb0ef41Sopenharmony_ci  new_map->set_is_extensible(false);
41561cb0ef41Sopenharmony_ci  JSObject::MigrateToMap(isolate, object, new_map);
41571cb0ef41Sopenharmony_ci  DCHECK(!object->map().is_extensible());
41581cb0ef41Sopenharmony_ci
41591cb0ef41Sopenharmony_ci  return Just(true);
41601cb0ef41Sopenharmony_ci}
41611cb0ef41Sopenharmony_ci
41621cb0ef41Sopenharmony_cibool JSObject::IsExtensible(Handle<JSObject> object) {
41631cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
41641cb0ef41Sopenharmony_ci  if (object->IsAccessCheckNeeded() &&
41651cb0ef41Sopenharmony_ci      !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
41661cb0ef41Sopenharmony_ci    return true;
41671cb0ef41Sopenharmony_ci  }
41681cb0ef41Sopenharmony_ci  if (object->IsJSGlobalProxy()) {
41691cb0ef41Sopenharmony_ci    PrototypeIterator iter(isolate, *object);
41701cb0ef41Sopenharmony_ci    if (iter.IsAtEnd()) return false;
41711cb0ef41Sopenharmony_ci    DCHECK(iter.GetCurrent().IsJSGlobalObject());
41721cb0ef41Sopenharmony_ci    return iter.GetCurrent<JSObject>().map().is_extensible();
41731cb0ef41Sopenharmony_ci  }
41741cb0ef41Sopenharmony_ci  return object->map().is_extensible();
41751cb0ef41Sopenharmony_ci}
41761cb0ef41Sopenharmony_ci
41771cb0ef41Sopenharmony_ci// static
41781cb0ef41Sopenharmony_ciMaybeHandle<Object> JSObject::ReadFromOptionsBag(Handle<Object> options,
41791cb0ef41Sopenharmony_ci                                                 Handle<String> option_name,
41801cb0ef41Sopenharmony_ci                                                 Isolate* isolate) {
41811cb0ef41Sopenharmony_ci  if (options->IsJSReceiver()) {
41821cb0ef41Sopenharmony_ci    Handle<JSReceiver> js_options = Handle<JSReceiver>::cast(options);
41831cb0ef41Sopenharmony_ci    return JSObject::GetProperty(isolate, js_options, option_name);
41841cb0ef41Sopenharmony_ci  }
41851cb0ef41Sopenharmony_ci  return MaybeHandle<Object>(isolate->factory()->undefined_value());
41861cb0ef41Sopenharmony_ci}
41871cb0ef41Sopenharmony_ci
41881cb0ef41Sopenharmony_citemplate <typename Dictionary>
41891cb0ef41Sopenharmony_civoid JSObject::ApplyAttributesToDictionary(
41901cb0ef41Sopenharmony_ci    Isolate* isolate, ReadOnlyRoots roots, Handle<Dictionary> dictionary,
41911cb0ef41Sopenharmony_ci    const PropertyAttributes attributes) {
41921cb0ef41Sopenharmony_ci  for (InternalIndex i : dictionary->IterateEntries()) {
41931cb0ef41Sopenharmony_ci    Object k;
41941cb0ef41Sopenharmony_ci    if (!dictionary->ToKey(roots, i, &k)) continue;
41951cb0ef41Sopenharmony_ci    if (k.FilterKey(ALL_PROPERTIES)) continue;
41961cb0ef41Sopenharmony_ci    PropertyDetails details = dictionary->DetailsAt(i);
41971cb0ef41Sopenharmony_ci    int attrs = attributes;
41981cb0ef41Sopenharmony_ci    // READ_ONLY is an invalid attribute for JS setters/getters.
41991cb0ef41Sopenharmony_ci    if ((attributes & READ_ONLY) && details.kind() == PropertyKind::kAccessor) {
42001cb0ef41Sopenharmony_ci      Object v = dictionary->ValueAt(i);
42011cb0ef41Sopenharmony_ci      if (v.IsAccessorPair()) attrs &= ~READ_ONLY;
42021cb0ef41Sopenharmony_ci    }
42031cb0ef41Sopenharmony_ci    details = details.CopyAddAttributes(PropertyAttributesFromInt(attrs));
42041cb0ef41Sopenharmony_ci    dictionary->DetailsAtPut(i, details);
42051cb0ef41Sopenharmony_ci  }
42061cb0ef41Sopenharmony_ci}
42071cb0ef41Sopenharmony_ci
42081cb0ef41Sopenharmony_citemplate void JSObject::ApplyAttributesToDictionary(
42091cb0ef41Sopenharmony_ci    Isolate* isolate, ReadOnlyRoots roots, Handle<NumberDictionary> dictionary,
42101cb0ef41Sopenharmony_ci    const PropertyAttributes attributes);
42111cb0ef41Sopenharmony_ci
42121cb0ef41Sopenharmony_ciHandle<NumberDictionary> CreateElementDictionary(Isolate* isolate,
42131cb0ef41Sopenharmony_ci                                                 Handle<JSObject> object) {
42141cb0ef41Sopenharmony_ci  Handle<NumberDictionary> new_element_dictionary;
42151cb0ef41Sopenharmony_ci  if (!object->HasTypedArrayOrRabGsabTypedArrayElements() &&
42161cb0ef41Sopenharmony_ci      !object->HasDictionaryElements() &&
42171cb0ef41Sopenharmony_ci      !object->HasSlowStringWrapperElements()) {
42181cb0ef41Sopenharmony_ci    int length = object->IsJSArray()
42191cb0ef41Sopenharmony_ci                     ? Smi::ToInt(Handle<JSArray>::cast(object)->length())
42201cb0ef41Sopenharmony_ci                     : object->elements().length();
42211cb0ef41Sopenharmony_ci    new_element_dictionary =
42221cb0ef41Sopenharmony_ci        length == 0 ? isolate->factory()->empty_slow_element_dictionary()
42231cb0ef41Sopenharmony_ci                    : object->GetElementsAccessor()->Normalize(object);
42241cb0ef41Sopenharmony_ci  }
42251cb0ef41Sopenharmony_ci  return new_element_dictionary;
42261cb0ef41Sopenharmony_ci}
42271cb0ef41Sopenharmony_ci
42281cb0ef41Sopenharmony_citemplate <PropertyAttributes attrs>
42291cb0ef41Sopenharmony_ciMaybe<bool> JSObject::PreventExtensionsWithTransition(
42301cb0ef41Sopenharmony_ci    Handle<JSObject> object, ShouldThrow should_throw) {
42311cb0ef41Sopenharmony_ci  STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN);
42321cb0ef41Sopenharmony_ci
42331cb0ef41Sopenharmony_ci  // Sealing/freezing sloppy arguments or namespace objects should be handled
42341cb0ef41Sopenharmony_ci  // elsewhere.
42351cb0ef41Sopenharmony_ci  DCHECK(!object->HasSloppyArgumentsElements());
42361cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(object->IsJSModuleNamespace(), attrs == NONE);
42371cb0ef41Sopenharmony_ci
42381cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
42391cb0ef41Sopenharmony_ci  if (object->IsAccessCheckNeeded() &&
42401cb0ef41Sopenharmony_ci      !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
42411cb0ef41Sopenharmony_ci    isolate->ReportFailedAccessCheck(object);
42421cb0ef41Sopenharmony_ci    RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
42431cb0ef41Sopenharmony_ci    RETURN_FAILURE(isolate, should_throw,
42441cb0ef41Sopenharmony_ci                   NewTypeError(MessageTemplate::kNoAccess));
42451cb0ef41Sopenharmony_ci  }
42461cb0ef41Sopenharmony_ci
42471cb0ef41Sopenharmony_ci  if (attrs == NONE && !object->map().is_extensible()) {
42481cb0ef41Sopenharmony_ci    return Just(true);
42491cb0ef41Sopenharmony_ci  }
42501cb0ef41Sopenharmony_ci
42511cb0ef41Sopenharmony_ci  {
42521cb0ef41Sopenharmony_ci    ElementsKind old_elements_kind = object->map().elements_kind();
42531cb0ef41Sopenharmony_ci    if (IsFrozenElementsKind(old_elements_kind)) return Just(true);
42541cb0ef41Sopenharmony_ci    if (attrs != FROZEN && IsSealedElementsKind(old_elements_kind)) {
42551cb0ef41Sopenharmony_ci      return Just(true);
42561cb0ef41Sopenharmony_ci    }
42571cb0ef41Sopenharmony_ci  }
42581cb0ef41Sopenharmony_ci
42591cb0ef41Sopenharmony_ci  if (object->IsJSGlobalProxy()) {
42601cb0ef41Sopenharmony_ci    PrototypeIterator iter(isolate, object);
42611cb0ef41Sopenharmony_ci    if (iter.IsAtEnd()) return Just(true);
42621cb0ef41Sopenharmony_ci    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
42631cb0ef41Sopenharmony_ci    return PreventExtensionsWithTransition<attrs>(
42641cb0ef41Sopenharmony_ci        PrototypeIterator::GetCurrent<JSObject>(iter), should_throw);
42651cb0ef41Sopenharmony_ci  }
42661cb0ef41Sopenharmony_ci
42671cb0ef41Sopenharmony_ci  if (object->map().has_named_interceptor() ||
42681cb0ef41Sopenharmony_ci      object->map().has_indexed_interceptor()) {
42691cb0ef41Sopenharmony_ci    MessageTemplate message = MessageTemplate::kNone;
42701cb0ef41Sopenharmony_ci    switch (attrs) {
42711cb0ef41Sopenharmony_ci      case NONE:
42721cb0ef41Sopenharmony_ci        message = MessageTemplate::kCannotPreventExt;
42731cb0ef41Sopenharmony_ci        break;
42741cb0ef41Sopenharmony_ci
42751cb0ef41Sopenharmony_ci      case SEALED:
42761cb0ef41Sopenharmony_ci        message = MessageTemplate::kCannotSeal;
42771cb0ef41Sopenharmony_ci        break;
42781cb0ef41Sopenharmony_ci
42791cb0ef41Sopenharmony_ci      case FROZEN:
42801cb0ef41Sopenharmony_ci        message = MessageTemplate::kCannotFreeze;
42811cb0ef41Sopenharmony_ci        break;
42821cb0ef41Sopenharmony_ci    }
42831cb0ef41Sopenharmony_ci    RETURN_FAILURE(isolate, should_throw, NewTypeError(message));
42841cb0ef41Sopenharmony_ci  }
42851cb0ef41Sopenharmony_ci
42861cb0ef41Sopenharmony_ci  Handle<Symbol> transition_marker;
42871cb0ef41Sopenharmony_ci  if (attrs == NONE) {
42881cb0ef41Sopenharmony_ci    transition_marker = isolate->factory()->nonextensible_symbol();
42891cb0ef41Sopenharmony_ci  } else if (attrs == SEALED) {
42901cb0ef41Sopenharmony_ci    transition_marker = isolate->factory()->sealed_symbol();
42911cb0ef41Sopenharmony_ci  } else {
42921cb0ef41Sopenharmony_ci    DCHECK(attrs == FROZEN);
42931cb0ef41Sopenharmony_ci    transition_marker = isolate->factory()->frozen_symbol();
42941cb0ef41Sopenharmony_ci  }
42951cb0ef41Sopenharmony_ci
42961cb0ef41Sopenharmony_ci  // Currently, there are only have sealed/frozen Object element kinds and
42971cb0ef41Sopenharmony_ci  // Map::MigrateToMap doesn't handle properties' attributes reconfiguring and
42981cb0ef41Sopenharmony_ci  // elements kind change in one go. If seal or freeze with Smi or Double
42991cb0ef41Sopenharmony_ci  // elements kind, we will transition to Object elements kind first to make
43001cb0ef41Sopenharmony_ci  // sure of valid element access.
43011cb0ef41Sopenharmony_ci  if (FLAG_enable_sealed_frozen_elements_kind) {
43021cb0ef41Sopenharmony_ci    switch (object->map().elements_kind()) {
43031cb0ef41Sopenharmony_ci      case PACKED_SMI_ELEMENTS:
43041cb0ef41Sopenharmony_ci      case PACKED_DOUBLE_ELEMENTS:
43051cb0ef41Sopenharmony_ci        JSObject::TransitionElementsKind(object, PACKED_ELEMENTS);
43061cb0ef41Sopenharmony_ci        break;
43071cb0ef41Sopenharmony_ci      case HOLEY_SMI_ELEMENTS:
43081cb0ef41Sopenharmony_ci      case HOLEY_DOUBLE_ELEMENTS:
43091cb0ef41Sopenharmony_ci        JSObject::TransitionElementsKind(object, HOLEY_ELEMENTS);
43101cb0ef41Sopenharmony_ci        break;
43111cb0ef41Sopenharmony_ci      default:
43121cb0ef41Sopenharmony_ci        break;
43131cb0ef41Sopenharmony_ci    }
43141cb0ef41Sopenharmony_ci  }
43151cb0ef41Sopenharmony_ci
43161cb0ef41Sopenharmony_ci  // Make sure we only use this element dictionary in case we can't transition
43171cb0ef41Sopenharmony_ci  // to sealed, frozen elements kind.
43181cb0ef41Sopenharmony_ci  Handle<NumberDictionary> new_element_dictionary;
43191cb0ef41Sopenharmony_ci
43201cb0ef41Sopenharmony_ci  Handle<Map> old_map(object->map(), isolate);
43211cb0ef41Sopenharmony_ci  old_map = Map::Update(isolate, old_map);
43221cb0ef41Sopenharmony_ci  Handle<Map> transition_map;
43231cb0ef41Sopenharmony_ci  MaybeHandle<Map> maybe_transition_map =
43241cb0ef41Sopenharmony_ci      TransitionsAccessor::SearchSpecial(isolate, old_map, *transition_marker);
43251cb0ef41Sopenharmony_ci  if (maybe_transition_map.ToHandle(&transition_map)) {
43261cb0ef41Sopenharmony_ci    DCHECK(transition_map->has_dictionary_elements() ||
43271cb0ef41Sopenharmony_ci           transition_map->has_typed_array_or_rab_gsab_typed_array_elements() ||
43281cb0ef41Sopenharmony_ci           transition_map->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS ||
43291cb0ef41Sopenharmony_ci           transition_map->has_any_nonextensible_elements());
43301cb0ef41Sopenharmony_ci    DCHECK(!transition_map->is_extensible());
43311cb0ef41Sopenharmony_ci    if (!transition_map->has_any_nonextensible_elements()) {
43321cb0ef41Sopenharmony_ci      new_element_dictionary = CreateElementDictionary(isolate, object);
43331cb0ef41Sopenharmony_ci    }
43341cb0ef41Sopenharmony_ci    JSObject::MigrateToMap(isolate, object, transition_map);
43351cb0ef41Sopenharmony_ci  } else if (TransitionsAccessor::CanHaveMoreTransitions(isolate, old_map)) {
43361cb0ef41Sopenharmony_ci    // Create a new descriptor array with the appropriate property attributes
43371cb0ef41Sopenharmony_ci    Handle<Map> new_map = Map::CopyForPreventExtensions(
43381cb0ef41Sopenharmony_ci        isolate, old_map, attrs, transition_marker, "CopyForPreventExtensions");
43391cb0ef41Sopenharmony_ci    if (!new_map->has_any_nonextensible_elements()) {
43401cb0ef41Sopenharmony_ci      new_element_dictionary = CreateElementDictionary(isolate, object);
43411cb0ef41Sopenharmony_ci    }
43421cb0ef41Sopenharmony_ci    JSObject::MigrateToMap(isolate, object, new_map);
43431cb0ef41Sopenharmony_ci  } else {
43441cb0ef41Sopenharmony_ci    DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map());
43451cb0ef41Sopenharmony_ci    // Slow path: need to normalize properties for safety
43461cb0ef41Sopenharmony_ci    NormalizeProperties(isolate, object, CLEAR_INOBJECT_PROPERTIES, 0,
43471cb0ef41Sopenharmony_ci                        "SlowPreventExtensions");
43481cb0ef41Sopenharmony_ci
43491cb0ef41Sopenharmony_ci    // Create a new map, since other objects with this map may be extensible.
43501cb0ef41Sopenharmony_ci    // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
43511cb0ef41Sopenharmony_ci    Handle<Map> new_map = Map::Copy(isolate, handle(object->map(), isolate),
43521cb0ef41Sopenharmony_ci                                    "SlowCopyForPreventExtensions");
43531cb0ef41Sopenharmony_ci    new_map->set_is_extensible(false);
43541cb0ef41Sopenharmony_ci    new_element_dictionary = CreateElementDictionary(isolate, object);
43551cb0ef41Sopenharmony_ci    if (!new_element_dictionary.is_null()) {
43561cb0ef41Sopenharmony_ci      ElementsKind new_kind =
43571cb0ef41Sopenharmony_ci          IsStringWrapperElementsKind(old_map->elements_kind())
43581cb0ef41Sopenharmony_ci              ? SLOW_STRING_WRAPPER_ELEMENTS
43591cb0ef41Sopenharmony_ci              : DICTIONARY_ELEMENTS;
43601cb0ef41Sopenharmony_ci      new_map->set_elements_kind(new_kind);
43611cb0ef41Sopenharmony_ci    }
43621cb0ef41Sopenharmony_ci    JSObject::MigrateToMap(isolate, object, new_map);
43631cb0ef41Sopenharmony_ci
43641cb0ef41Sopenharmony_ci    if (attrs != NONE) {
43651cb0ef41Sopenharmony_ci      ReadOnlyRoots roots(isolate);
43661cb0ef41Sopenharmony_ci      if (object->IsJSGlobalObject()) {
43671cb0ef41Sopenharmony_ci        Handle<GlobalDictionary> dictionary(
43681cb0ef41Sopenharmony_ci            JSGlobalObject::cast(*object).global_dictionary(kAcquireLoad),
43691cb0ef41Sopenharmony_ci            isolate);
43701cb0ef41Sopenharmony_ci        JSObject::ApplyAttributesToDictionary(isolate, roots, dictionary,
43711cb0ef41Sopenharmony_ci                                              attrs);
43721cb0ef41Sopenharmony_ci      } else if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
43731cb0ef41Sopenharmony_ci        Handle<SwissNameDictionary> dictionary(
43741cb0ef41Sopenharmony_ci            object->property_dictionary_swiss(), isolate);
43751cb0ef41Sopenharmony_ci        JSObject::ApplyAttributesToDictionary(isolate, roots, dictionary,
43761cb0ef41Sopenharmony_ci                                              attrs);
43771cb0ef41Sopenharmony_ci      } else {
43781cb0ef41Sopenharmony_ci        Handle<NameDictionary> dictionary(object->property_dictionary(),
43791cb0ef41Sopenharmony_ci                                          isolate);
43801cb0ef41Sopenharmony_ci        JSObject::ApplyAttributesToDictionary(isolate, roots, dictionary,
43811cb0ef41Sopenharmony_ci                                              attrs);
43821cb0ef41Sopenharmony_ci      }
43831cb0ef41Sopenharmony_ci    }
43841cb0ef41Sopenharmony_ci  }
43851cb0ef41Sopenharmony_ci
43861cb0ef41Sopenharmony_ci  if (object->map().has_any_nonextensible_elements()) {
43871cb0ef41Sopenharmony_ci    DCHECK(new_element_dictionary.is_null());
43881cb0ef41Sopenharmony_ci    return Just(true);
43891cb0ef41Sopenharmony_ci  }
43901cb0ef41Sopenharmony_ci
43911cb0ef41Sopenharmony_ci  // Both seal and preventExtensions always go through without modifications to
43921cb0ef41Sopenharmony_ci  // typed array elements. Freeze works only if there are no actual elements.
43931cb0ef41Sopenharmony_ci  if (object->HasTypedArrayOrRabGsabTypedArrayElements()) {
43941cb0ef41Sopenharmony_ci    DCHECK(new_element_dictionary.is_null());
43951cb0ef41Sopenharmony_ci    if (attrs == FROZEN && JSTypedArray::cast(*object).GetLength() > 0) {
43961cb0ef41Sopenharmony_ci      isolate->Throw(*isolate->factory()->NewTypeError(
43971cb0ef41Sopenharmony_ci          MessageTemplate::kCannotFreezeArrayBufferView));
43981cb0ef41Sopenharmony_ci      return Nothing<bool>();
43991cb0ef41Sopenharmony_ci    }
44001cb0ef41Sopenharmony_ci    return Just(true);
44011cb0ef41Sopenharmony_ci  }
44021cb0ef41Sopenharmony_ci
44031cb0ef41Sopenharmony_ci  DCHECK(object->map().has_dictionary_elements() ||
44041cb0ef41Sopenharmony_ci         object->map().elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
44051cb0ef41Sopenharmony_ci  if (!new_element_dictionary.is_null()) {
44061cb0ef41Sopenharmony_ci    object->set_elements(*new_element_dictionary);
44071cb0ef41Sopenharmony_ci  }
44081cb0ef41Sopenharmony_ci
44091cb0ef41Sopenharmony_ci  if (object->elements() !=
44101cb0ef41Sopenharmony_ci      ReadOnlyRoots(isolate).empty_slow_element_dictionary()) {
44111cb0ef41Sopenharmony_ci    Handle<NumberDictionary> dictionary(object->element_dictionary(), isolate);
44121cb0ef41Sopenharmony_ci    // Make sure we never go back to the fast case
44131cb0ef41Sopenharmony_ci    object->RequireSlowElements(*dictionary);
44141cb0ef41Sopenharmony_ci    if (attrs != NONE) {
44151cb0ef41Sopenharmony_ci      JSObject::ApplyAttributesToDictionary(isolate, ReadOnlyRoots(isolate),
44161cb0ef41Sopenharmony_ci                                            dictionary, attrs);
44171cb0ef41Sopenharmony_ci    }
44181cb0ef41Sopenharmony_ci  }
44191cb0ef41Sopenharmony_ci
44201cb0ef41Sopenharmony_ci  return Just(true);
44211cb0ef41Sopenharmony_ci}
44221cb0ef41Sopenharmony_ci
44231cb0ef41Sopenharmony_ciHandle<Object> JSObject::FastPropertyAt(Isolate* isolate,
44241cb0ef41Sopenharmony_ci                                        Handle<JSObject> object,
44251cb0ef41Sopenharmony_ci                                        Representation representation,
44261cb0ef41Sopenharmony_ci                                        FieldIndex index) {
44271cb0ef41Sopenharmony_ci  Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate);
44281cb0ef41Sopenharmony_ci  return Object::WrapForRead(isolate, raw_value, representation);
44291cb0ef41Sopenharmony_ci}
44301cb0ef41Sopenharmony_ci
44311cb0ef41Sopenharmony_ciHandle<Object> JSObject::FastPropertyAt(Isolate* isolate,
44321cb0ef41Sopenharmony_ci                                        Handle<JSObject> object,
44331cb0ef41Sopenharmony_ci                                        Representation representation,
44341cb0ef41Sopenharmony_ci                                        FieldIndex index, SeqCstAccessTag tag) {
44351cb0ef41Sopenharmony_ci  Handle<Object> raw_value(object->RawFastPropertyAt(index, tag), isolate);
44361cb0ef41Sopenharmony_ci  return Object::WrapForRead(isolate, raw_value, representation);
44371cb0ef41Sopenharmony_ci}
44381cb0ef41Sopenharmony_ci
44391cb0ef41Sopenharmony_ci// static
44401cb0ef41Sopenharmony_ciHandle<Object> JSObject::DictionaryPropertyAt(Isolate* isolate,
44411cb0ef41Sopenharmony_ci                                              Handle<JSObject> object,
44421cb0ef41Sopenharmony_ci                                              InternalIndex dict_index) {
44431cb0ef41Sopenharmony_ci  DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
44441cb0ef41Sopenharmony_ci  if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
44451cb0ef41Sopenharmony_ci    SwissNameDictionary dict = object->property_dictionary_swiss();
44461cb0ef41Sopenharmony_ci    return handle(dict.ValueAt(dict_index), isolate);
44471cb0ef41Sopenharmony_ci  } else {
44481cb0ef41Sopenharmony_ci    NameDictionary dict = object->property_dictionary();
44491cb0ef41Sopenharmony_ci    return handle(dict.ValueAt(dict_index), isolate);
44501cb0ef41Sopenharmony_ci  }
44511cb0ef41Sopenharmony_ci}
44521cb0ef41Sopenharmony_ci
44531cb0ef41Sopenharmony_ci// static
44541cb0ef41Sopenharmony_cibase::Optional<Object> JSObject::DictionaryPropertyAt(Handle<JSObject> object,
44551cb0ef41Sopenharmony_ci                                                      InternalIndex dict_index,
44561cb0ef41Sopenharmony_ci                                                      Heap* heap) {
44571cb0ef41Sopenharmony_ci  Object backing_store = object->raw_properties_or_hash(kRelaxedLoad);
44581cb0ef41Sopenharmony_ci  if (!backing_store.IsHeapObject()) return {};
44591cb0ef41Sopenharmony_ci  if (heap->IsPendingAllocation(HeapObject::cast(backing_store))) return {};
44601cb0ef41Sopenharmony_ci
44611cb0ef41Sopenharmony_ci  base::Optional<Object> maybe_obj;
44621cb0ef41Sopenharmony_ci  if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
44631cb0ef41Sopenharmony_ci    if (!backing_store.IsSwissNameDictionary()) return {};
44641cb0ef41Sopenharmony_ci    maybe_obj = SwissNameDictionary::cast(backing_store).TryValueAt(dict_index);
44651cb0ef41Sopenharmony_ci  } else {
44661cb0ef41Sopenharmony_ci    if (!backing_store.IsNameDictionary()) return {};
44671cb0ef41Sopenharmony_ci    maybe_obj = NameDictionary::cast(backing_store).TryValueAt(dict_index);
44681cb0ef41Sopenharmony_ci  }
44691cb0ef41Sopenharmony_ci
44701cb0ef41Sopenharmony_ci  if (!maybe_obj) return {};
44711cb0ef41Sopenharmony_ci  return maybe_obj.value();
44721cb0ef41Sopenharmony_ci}
44731cb0ef41Sopenharmony_ci
44741cb0ef41Sopenharmony_ci// TODO(cbruni/jkummerow): Consider moving this into elements.cc.
44751cb0ef41Sopenharmony_cibool JSObject::HasEnumerableElements() {
44761cb0ef41Sopenharmony_ci  // TODO(cbruni): cleanup
44771cb0ef41Sopenharmony_ci  JSObject object = *this;
44781cb0ef41Sopenharmony_ci  switch (object.GetElementsKind()) {
44791cb0ef41Sopenharmony_ci    case PACKED_SMI_ELEMENTS:
44801cb0ef41Sopenharmony_ci    case PACKED_ELEMENTS:
44811cb0ef41Sopenharmony_ci    case PACKED_FROZEN_ELEMENTS:
44821cb0ef41Sopenharmony_ci    case PACKED_SEALED_ELEMENTS:
44831cb0ef41Sopenharmony_ci    case PACKED_NONEXTENSIBLE_ELEMENTS:
44841cb0ef41Sopenharmony_ci    case PACKED_DOUBLE_ELEMENTS: {
44851cb0ef41Sopenharmony_ci      int length = object.IsJSArray()
44861cb0ef41Sopenharmony_ci                       ? Smi::ToInt(JSArray::cast(object).length())
44871cb0ef41Sopenharmony_ci                       : object.elements().length();
44881cb0ef41Sopenharmony_ci      return length > 0;
44891cb0ef41Sopenharmony_ci    }
44901cb0ef41Sopenharmony_ci    case HOLEY_SMI_ELEMENTS:
44911cb0ef41Sopenharmony_ci    case HOLEY_FROZEN_ELEMENTS:
44921cb0ef41Sopenharmony_ci    case HOLEY_SEALED_ELEMENTS:
44931cb0ef41Sopenharmony_ci    case HOLEY_NONEXTENSIBLE_ELEMENTS:
44941cb0ef41Sopenharmony_ci    case HOLEY_ELEMENTS: {
44951cb0ef41Sopenharmony_ci      FixedArray elements = FixedArray::cast(object.elements());
44961cb0ef41Sopenharmony_ci      int length = object.IsJSArray()
44971cb0ef41Sopenharmony_ci                       ? Smi::ToInt(JSArray::cast(object).length())
44981cb0ef41Sopenharmony_ci                       : elements.length();
44991cb0ef41Sopenharmony_ci      Isolate* isolate = GetIsolate();
45001cb0ef41Sopenharmony_ci      for (int i = 0; i < length; i++) {
45011cb0ef41Sopenharmony_ci        if (!elements.is_the_hole(isolate, i)) return true;
45021cb0ef41Sopenharmony_ci      }
45031cb0ef41Sopenharmony_ci      return false;
45041cb0ef41Sopenharmony_ci    }
45051cb0ef41Sopenharmony_ci    case HOLEY_DOUBLE_ELEMENTS: {
45061cb0ef41Sopenharmony_ci      int length = object.IsJSArray()
45071cb0ef41Sopenharmony_ci                       ? Smi::ToInt(JSArray::cast(object).length())
45081cb0ef41Sopenharmony_ci                       : object.elements().length();
45091cb0ef41Sopenharmony_ci      // Zero-length arrays would use the empty FixedArray...
45101cb0ef41Sopenharmony_ci      if (length == 0) return false;
45111cb0ef41Sopenharmony_ci      // ...so only cast to FixedDoubleArray otherwise.
45121cb0ef41Sopenharmony_ci      FixedDoubleArray elements = FixedDoubleArray::cast(object.elements());
45131cb0ef41Sopenharmony_ci      for (int i = 0; i < length; i++) {
45141cb0ef41Sopenharmony_ci        if (!elements.is_the_hole(i)) return true;
45151cb0ef41Sopenharmony_ci      }
45161cb0ef41Sopenharmony_ci      return false;
45171cb0ef41Sopenharmony_ci    }
45181cb0ef41Sopenharmony_ci#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
45191cb0ef41Sopenharmony_ci
45201cb0ef41Sopenharmony_ci      TYPED_ARRAYS(TYPED_ARRAY_CASE) {
45211cb0ef41Sopenharmony_ci        size_t length = JSTypedArray::cast(object).length();
45221cb0ef41Sopenharmony_ci        return length > 0;
45231cb0ef41Sopenharmony_ci      }
45241cb0ef41Sopenharmony_ci
45251cb0ef41Sopenharmony_ci      RAB_GSAB_TYPED_ARRAYS(TYPED_ARRAY_CASE)
45261cb0ef41Sopenharmony_ci#undef TYPED_ARRAY_CASE
45271cb0ef41Sopenharmony_ci      {
45281cb0ef41Sopenharmony_ci        size_t length = JSTypedArray::cast(object).GetLength();
45291cb0ef41Sopenharmony_ci        return length > 0;
45301cb0ef41Sopenharmony_ci      }
45311cb0ef41Sopenharmony_ci    case DICTIONARY_ELEMENTS: {
45321cb0ef41Sopenharmony_ci      NumberDictionary elements = NumberDictionary::cast(object.elements());
45331cb0ef41Sopenharmony_ci      return elements.NumberOfEnumerableProperties() > 0;
45341cb0ef41Sopenharmony_ci    }
45351cb0ef41Sopenharmony_ci    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
45361cb0ef41Sopenharmony_ci    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
45371cb0ef41Sopenharmony_ci      // We're approximating non-empty arguments objects here.
45381cb0ef41Sopenharmony_ci      return true;
45391cb0ef41Sopenharmony_ci    case FAST_STRING_WRAPPER_ELEMENTS:
45401cb0ef41Sopenharmony_ci    case SLOW_STRING_WRAPPER_ELEMENTS:
45411cb0ef41Sopenharmony_ci      if (String::cast(JSPrimitiveWrapper::cast(object).value()).length() > 0) {
45421cb0ef41Sopenharmony_ci        return true;
45431cb0ef41Sopenharmony_ci      }
45441cb0ef41Sopenharmony_ci      return object.elements().length() > 0;
45451cb0ef41Sopenharmony_ci    case WASM_ARRAY_ELEMENTS:
45461cb0ef41Sopenharmony_ci      UNIMPLEMENTED();
45471cb0ef41Sopenharmony_ci
45481cb0ef41Sopenharmony_ci    case NO_ELEMENTS:
45491cb0ef41Sopenharmony_ci      return false;
45501cb0ef41Sopenharmony_ci  }
45511cb0ef41Sopenharmony_ci  UNREACHABLE();
45521cb0ef41Sopenharmony_ci}
45531cb0ef41Sopenharmony_ci
45541cb0ef41Sopenharmony_ciMaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
45551cb0ef41Sopenharmony_ci                                             Handle<Name> name,
45561cb0ef41Sopenharmony_ci                                             Handle<Object> getter,
45571cb0ef41Sopenharmony_ci                                             Handle<Object> setter,
45581cb0ef41Sopenharmony_ci                                             PropertyAttributes attributes) {
45591cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
45601cb0ef41Sopenharmony_ci
45611cb0ef41Sopenharmony_ci  PropertyKey key(isolate, name);
45621cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
45631cb0ef41Sopenharmony_ci  return DefineAccessor(&it, getter, setter, attributes);
45641cb0ef41Sopenharmony_ci}
45651cb0ef41Sopenharmony_ci
45661cb0ef41Sopenharmony_ciMaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it,
45671cb0ef41Sopenharmony_ci                                             Handle<Object> getter,
45681cb0ef41Sopenharmony_ci                                             Handle<Object> setter,
45691cb0ef41Sopenharmony_ci                                             PropertyAttributes attributes) {
45701cb0ef41Sopenharmony_ci  Isolate* isolate = it->isolate();
45711cb0ef41Sopenharmony_ci
45721cb0ef41Sopenharmony_ci  it->UpdateProtector();
45731cb0ef41Sopenharmony_ci
45741cb0ef41Sopenharmony_ci  if (it->state() == LookupIterator::ACCESS_CHECK) {
45751cb0ef41Sopenharmony_ci    if (!it->HasAccess()) {
45761cb0ef41Sopenharmony_ci      isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
45771cb0ef41Sopenharmony_ci      RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
45781cb0ef41Sopenharmony_ci      return isolate->factory()->undefined_value();
45791cb0ef41Sopenharmony_ci    }
45801cb0ef41Sopenharmony_ci    it->Next();
45811cb0ef41Sopenharmony_ci  }
45821cb0ef41Sopenharmony_ci
45831cb0ef41Sopenharmony_ci  Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
45841cb0ef41Sopenharmony_ci  // Ignore accessors on typed arrays.
45851cb0ef41Sopenharmony_ci  if (it->IsElement() && object->HasTypedArrayOrRabGsabTypedArrayElements()) {
45861cb0ef41Sopenharmony_ci    return it->factory()->undefined_value();
45871cb0ef41Sopenharmony_ci  }
45881cb0ef41Sopenharmony_ci
45891cb0ef41Sopenharmony_ci  DCHECK(getter->IsCallable() || getter->IsUndefined(isolate) ||
45901cb0ef41Sopenharmony_ci         getter->IsNull(isolate) || getter->IsFunctionTemplateInfo());
45911cb0ef41Sopenharmony_ci  DCHECK(setter->IsCallable() || setter->IsUndefined(isolate) ||
45921cb0ef41Sopenharmony_ci         setter->IsNull(isolate) || setter->IsFunctionTemplateInfo());
45931cb0ef41Sopenharmony_ci  it->TransitionToAccessorProperty(getter, setter, attributes);
45941cb0ef41Sopenharmony_ci
45951cb0ef41Sopenharmony_ci  return isolate->factory()->undefined_value();
45961cb0ef41Sopenharmony_ci}
45971cb0ef41Sopenharmony_ci
45981cb0ef41Sopenharmony_ciMaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
45991cb0ef41Sopenharmony_ci                                          Handle<Name> name,
46001cb0ef41Sopenharmony_ci                                          Handle<AccessorInfo> info,
46011cb0ef41Sopenharmony_ci                                          PropertyAttributes attributes) {
46021cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
46031cb0ef41Sopenharmony_ci
46041cb0ef41Sopenharmony_ci  PropertyKey key(isolate, name);
46051cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
46061cb0ef41Sopenharmony_ci
46071cb0ef41Sopenharmony_ci  // Duplicate ACCESS_CHECK outside of GetPropertyAttributes for the case that
46081cb0ef41Sopenharmony_ci  // the FailedAccessCheckCallbackFunction doesn't throw an exception.
46091cb0ef41Sopenharmony_ci  //
46101cb0ef41Sopenharmony_ci  // TODO(verwaest): Force throw an exception if the callback doesn't, so we can
46111cb0ef41Sopenharmony_ci  // remove reliance on default return values.
46121cb0ef41Sopenharmony_ci  if (it.state() == LookupIterator::ACCESS_CHECK) {
46131cb0ef41Sopenharmony_ci    if (!it.HasAccess()) {
46141cb0ef41Sopenharmony_ci      isolate->ReportFailedAccessCheck(object);
46151cb0ef41Sopenharmony_ci      RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
46161cb0ef41Sopenharmony_ci      return it.factory()->undefined_value();
46171cb0ef41Sopenharmony_ci    }
46181cb0ef41Sopenharmony_ci    it.Next();
46191cb0ef41Sopenharmony_ci  }
46201cb0ef41Sopenharmony_ci
46211cb0ef41Sopenharmony_ci  // Ignore accessors on typed arrays.
46221cb0ef41Sopenharmony_ci  if (it.IsElement() && object->HasTypedArrayOrRabGsabTypedArrayElements()) {
46231cb0ef41Sopenharmony_ci    return it.factory()->undefined_value();
46241cb0ef41Sopenharmony_ci  }
46251cb0ef41Sopenharmony_ci
46261cb0ef41Sopenharmony_ci  CHECK(GetPropertyAttributes(&it).IsJust());
46271cb0ef41Sopenharmony_ci
46281cb0ef41Sopenharmony_ci  // ES5 forbids turning a property into an accessor if it's not
46291cb0ef41Sopenharmony_ci  // configurable. See 8.6.1 (Table 5).
46301cb0ef41Sopenharmony_ci  if (it.IsFound() && !it.IsConfigurable()) {
46311cb0ef41Sopenharmony_ci    return it.factory()->undefined_value();
46321cb0ef41Sopenharmony_ci  }
46331cb0ef41Sopenharmony_ci
46341cb0ef41Sopenharmony_ci  it.TransitionToAccessorPair(info, attributes);
46351cb0ef41Sopenharmony_ci
46361cb0ef41Sopenharmony_ci  return object;
46371cb0ef41Sopenharmony_ci}
46381cb0ef41Sopenharmony_ci
46391cb0ef41Sopenharmony_ciObject JSObject::SlowReverseLookup(Object value) {
46401cb0ef41Sopenharmony_ci  if (HasFastProperties()) {
46411cb0ef41Sopenharmony_ci    DescriptorArray descs = map().instance_descriptors();
46421cb0ef41Sopenharmony_ci    bool value_is_number = value.IsNumber();
46431cb0ef41Sopenharmony_ci    for (InternalIndex i : map().IterateOwnDescriptors()) {
46441cb0ef41Sopenharmony_ci      PropertyDetails details = descs.GetDetails(i);
46451cb0ef41Sopenharmony_ci      if (details.location() == PropertyLocation::kField) {
46461cb0ef41Sopenharmony_ci        DCHECK_EQ(PropertyKind::kData, details.kind());
46471cb0ef41Sopenharmony_ci        FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
46481cb0ef41Sopenharmony_ci        Object property = RawFastPropertyAt(field_index);
46491cb0ef41Sopenharmony_ci        if (field_index.is_double()) {
46501cb0ef41Sopenharmony_ci          DCHECK(property.IsHeapNumber());
46511cb0ef41Sopenharmony_ci          if (value_is_number && property.Number() == value.Number()) {
46521cb0ef41Sopenharmony_ci            return descs.GetKey(i);
46531cb0ef41Sopenharmony_ci          }
46541cb0ef41Sopenharmony_ci        } else if (property == value) {
46551cb0ef41Sopenharmony_ci          return descs.GetKey(i);
46561cb0ef41Sopenharmony_ci        }
46571cb0ef41Sopenharmony_ci      } else {
46581cb0ef41Sopenharmony_ci        DCHECK_EQ(PropertyLocation::kDescriptor, details.location());
46591cb0ef41Sopenharmony_ci        if (details.kind() == PropertyKind::kData) {
46601cb0ef41Sopenharmony_ci          if (descs.GetStrongValue(i) == value) {
46611cb0ef41Sopenharmony_ci            return descs.GetKey(i);
46621cb0ef41Sopenharmony_ci          }
46631cb0ef41Sopenharmony_ci        }
46641cb0ef41Sopenharmony_ci      }
46651cb0ef41Sopenharmony_ci    }
46661cb0ef41Sopenharmony_ci    return GetReadOnlyRoots().undefined_value();
46671cb0ef41Sopenharmony_ci  } else if (IsJSGlobalObject()) {
46681cb0ef41Sopenharmony_ci    return JSGlobalObject::cast(*this)
46691cb0ef41Sopenharmony_ci        .global_dictionary(kAcquireLoad)
46701cb0ef41Sopenharmony_ci        .SlowReverseLookup(value);
46711cb0ef41Sopenharmony_ci  } else if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
46721cb0ef41Sopenharmony_ci    return property_dictionary_swiss().SlowReverseLookup(GetIsolate(), value);
46731cb0ef41Sopenharmony_ci  } else {
46741cb0ef41Sopenharmony_ci    return property_dictionary().SlowReverseLookup(value);
46751cb0ef41Sopenharmony_ci  }
46761cb0ef41Sopenharmony_ci}
46771cb0ef41Sopenharmony_ci
46781cb0ef41Sopenharmony_civoid JSObject::PrototypeRegistryCompactionCallback(HeapObject value,
46791cb0ef41Sopenharmony_ci                                                   int old_index,
46801cb0ef41Sopenharmony_ci                                                   int new_index) {
46811cb0ef41Sopenharmony_ci  DCHECK(value.IsMap() && Map::cast(value).is_prototype_map());
46821cb0ef41Sopenharmony_ci  Map map = Map::cast(value);
46831cb0ef41Sopenharmony_ci  DCHECK(map.prototype_info().IsPrototypeInfo());
46841cb0ef41Sopenharmony_ci  PrototypeInfo proto_info = PrototypeInfo::cast(map.prototype_info());
46851cb0ef41Sopenharmony_ci  DCHECK_EQ(old_index, proto_info.registry_slot());
46861cb0ef41Sopenharmony_ci  proto_info.set_registry_slot(new_index);
46871cb0ef41Sopenharmony_ci}
46881cb0ef41Sopenharmony_ci
46891cb0ef41Sopenharmony_ci// static
46901cb0ef41Sopenharmony_civoid JSObject::MakePrototypesFast(Handle<Object> receiver,
46911cb0ef41Sopenharmony_ci                                  WhereToStart where_to_start,
46921cb0ef41Sopenharmony_ci                                  Isolate* isolate) {
46931cb0ef41Sopenharmony_ci  if (!receiver->IsJSReceiver()) return;
46941cb0ef41Sopenharmony_ci  for (PrototypeIterator iter(isolate, Handle<JSReceiver>::cast(receiver),
46951cb0ef41Sopenharmony_ci                              where_to_start);
46961cb0ef41Sopenharmony_ci       !iter.IsAtEnd(); iter.Advance()) {
46971cb0ef41Sopenharmony_ci    Handle<Object> current = PrototypeIterator::GetCurrent(iter);
46981cb0ef41Sopenharmony_ci    if (!current->IsJSObject()) return;
46991cb0ef41Sopenharmony_ci    Handle<JSObject> current_obj = Handle<JSObject>::cast(current);
47001cb0ef41Sopenharmony_ci    Map current_map = current_obj->map();
47011cb0ef41Sopenharmony_ci    if (current_map.is_prototype_map()) {
47021cb0ef41Sopenharmony_ci      // If the map is already marked as should be fast, we're done. Its
47031cb0ef41Sopenharmony_ci      // prototypes will have been marked already as well.
47041cb0ef41Sopenharmony_ci      if (current_map.should_be_fast_prototype_map()) return;
47051cb0ef41Sopenharmony_ci      Handle<Map> map(current_map, isolate);
47061cb0ef41Sopenharmony_ci      Map::SetShouldBeFastPrototypeMap(map, true, isolate);
47071cb0ef41Sopenharmony_ci      JSObject::OptimizeAsPrototype(current_obj);
47081cb0ef41Sopenharmony_ci    }
47091cb0ef41Sopenharmony_ci  }
47101cb0ef41Sopenharmony_ci}
47111cb0ef41Sopenharmony_ci
47121cb0ef41Sopenharmony_cistatic bool PrototypeBenefitsFromNormalization(Handle<JSObject> object) {
47131cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
47141cb0ef41Sopenharmony_ci  if (!object->HasFastProperties()) return false;
47151cb0ef41Sopenharmony_ci  if (object->IsJSGlobalProxy()) return false;
47161cb0ef41Sopenharmony_ci  // TODO(v8:11248) make bootstrapper create dict mode prototypes, too?
47171cb0ef41Sopenharmony_ci  if (object->GetIsolate()->bootstrapper()->IsActive()) return false;
47181cb0ef41Sopenharmony_ci  if (V8_DICT_PROPERTY_CONST_TRACKING_BOOL) return true;
47191cb0ef41Sopenharmony_ci  return !object->map().is_prototype_map() ||
47201cb0ef41Sopenharmony_ci         !object->map().should_be_fast_prototype_map();
47211cb0ef41Sopenharmony_ci}
47221cb0ef41Sopenharmony_ci
47231cb0ef41Sopenharmony_ci// static
47241cb0ef41Sopenharmony_civoid JSObject::OptimizeAsPrototype(Handle<JSObject> object,
47251cb0ef41Sopenharmony_ci                                   bool enable_setup_mode) {
47261cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
47271cb0ef41Sopenharmony_ci  if (object->IsJSGlobalObject()) return;
47281cb0ef41Sopenharmony_ci  if (enable_setup_mode && PrototypeBenefitsFromNormalization(object)) {
47291cb0ef41Sopenharmony_ci    // First normalize to ensure all JSFunctions are DATA_CONSTANT.
47301cb0ef41Sopenharmony_ci    JSObject::NormalizeProperties(isolate, object, KEEP_INOBJECT_PROPERTIES, 0,
47311cb0ef41Sopenharmony_ci                                  "NormalizeAsPrototype");
47321cb0ef41Sopenharmony_ci  }
47331cb0ef41Sopenharmony_ci  if (object->map().is_prototype_map()) {
47341cb0ef41Sopenharmony_ci    if (!V8_DICT_PROPERTY_CONST_TRACKING_BOOL &&
47351cb0ef41Sopenharmony_ci        object->map().should_be_fast_prototype_map() &&
47361cb0ef41Sopenharmony_ci        !object->HasFastProperties()) {
47371cb0ef41Sopenharmony_ci      JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype");
47381cb0ef41Sopenharmony_ci    }
47391cb0ef41Sopenharmony_ci  } else {
47401cb0ef41Sopenharmony_ci    Handle<Map> new_map =
47411cb0ef41Sopenharmony_ci        Map::Copy(isolate, handle(object->map(), isolate), "CopyAsPrototype");
47421cb0ef41Sopenharmony_ci    new_map->set_is_prototype_map(true);
47431cb0ef41Sopenharmony_ci
47441cb0ef41Sopenharmony_ci    // Replace the pointer to the exact constructor with the Object function
47451cb0ef41Sopenharmony_ci    // from the same context if undetectable from JS. This is to avoid keeping
47461cb0ef41Sopenharmony_ci    // memory alive unnecessarily.
47471cb0ef41Sopenharmony_ci    Object maybe_constructor = new_map->GetConstructor();
47481cb0ef41Sopenharmony_ci    if (maybe_constructor.IsJSFunction()) {
47491cb0ef41Sopenharmony_ci      JSFunction constructor = JSFunction::cast(maybe_constructor);
47501cb0ef41Sopenharmony_ci      if (!constructor.shared().IsApiFunction()) {
47511cb0ef41Sopenharmony_ci        Context context = constructor.native_context();
47521cb0ef41Sopenharmony_ci        JSFunction object_function = context.object_function();
47531cb0ef41Sopenharmony_ci        new_map->SetConstructor(object_function);
47541cb0ef41Sopenharmony_ci      }
47551cb0ef41Sopenharmony_ci    }
47561cb0ef41Sopenharmony_ci    JSObject::MigrateToMap(isolate, object, new_map);
47571cb0ef41Sopenharmony_ci
47581cb0ef41Sopenharmony_ci    if (V8_DICT_PROPERTY_CONST_TRACKING_BOOL && !object->HasFastProperties()) {
47591cb0ef41Sopenharmony_ci      ReadOnlyRoots roots(isolate);
47601cb0ef41Sopenharmony_ci      DisallowHeapAllocation no_gc;
47611cb0ef41Sopenharmony_ci
47621cb0ef41Sopenharmony_ci      auto make_constant = [&](auto dict) {
47631cb0ef41Sopenharmony_ci        for (InternalIndex index : dict.IterateEntries()) {
47641cb0ef41Sopenharmony_ci          Object k;
47651cb0ef41Sopenharmony_ci          if (!dict.ToKey(roots, index, &k)) continue;
47661cb0ef41Sopenharmony_ci
47671cb0ef41Sopenharmony_ci          PropertyDetails details = dict.DetailsAt(index);
47681cb0ef41Sopenharmony_ci          details = details.CopyWithConstness(PropertyConstness::kConst);
47691cb0ef41Sopenharmony_ci          dict.DetailsAtPut(index, details);
47701cb0ef41Sopenharmony_ci        }
47711cb0ef41Sopenharmony_ci      };
47721cb0ef41Sopenharmony_ci      if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
47731cb0ef41Sopenharmony_ci        make_constant(object->property_dictionary_swiss());
47741cb0ef41Sopenharmony_ci      } else {
47751cb0ef41Sopenharmony_ci        make_constant(object->property_dictionary());
47761cb0ef41Sopenharmony_ci      }
47771cb0ef41Sopenharmony_ci    }
47781cb0ef41Sopenharmony_ci  }
47791cb0ef41Sopenharmony_ci#ifdef DEBUG
47801cb0ef41Sopenharmony_ci  bool should_be_dictionary = V8_DICT_PROPERTY_CONST_TRACKING_BOOL &&
47811cb0ef41Sopenharmony_ci                              enable_setup_mode && !object->IsJSGlobalProxy() &&
47821cb0ef41Sopenharmony_ci                              !object->GetIsolate()->bootstrapper()->IsActive();
47831cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(should_be_dictionary, object->map().is_dictionary_map());
47841cb0ef41Sopenharmony_ci#endif
47851cb0ef41Sopenharmony_ci}
47861cb0ef41Sopenharmony_ci
47871cb0ef41Sopenharmony_ci// static
47881cb0ef41Sopenharmony_civoid JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) {
47891cb0ef41Sopenharmony_ci  if (!object->map().is_prototype_map()) return;
47901cb0ef41Sopenharmony_ci  if (!object->map().should_be_fast_prototype_map()) return;
47911cb0ef41Sopenharmony_ci  OptimizeAsPrototype(object);
47921cb0ef41Sopenharmony_ci}
47931cb0ef41Sopenharmony_ci
47941cb0ef41Sopenharmony_ci// static
47951cb0ef41Sopenharmony_civoid JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
47961cb0ef41Sopenharmony_ci  // Contract: In line with InvalidatePrototypeChains()'s requirements,
47971cb0ef41Sopenharmony_ci  // leaf maps don't need to register as users, only prototypes do.
47981cb0ef41Sopenharmony_ci  DCHECK(user->is_prototype_map());
47991cb0ef41Sopenharmony_ci
48001cb0ef41Sopenharmony_ci  Handle<Map> current_user = user;
48011cb0ef41Sopenharmony_ci  Handle<PrototypeInfo> current_user_info =
48021cb0ef41Sopenharmony_ci      Map::GetOrCreatePrototypeInfo(user, isolate);
48031cb0ef41Sopenharmony_ci  for (PrototypeIterator iter(isolate, user); !iter.IsAtEnd(); iter.Advance()) {
48041cb0ef41Sopenharmony_ci    // Walk up the prototype chain as far as links haven't been registered yet.
48051cb0ef41Sopenharmony_ci    if (current_user_info->registry_slot() != PrototypeInfo::UNREGISTERED) {
48061cb0ef41Sopenharmony_ci      break;
48071cb0ef41Sopenharmony_ci    }
48081cb0ef41Sopenharmony_ci    Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter);
48091cb0ef41Sopenharmony_ci    // Proxies on the prototype chain are not supported. They make it
48101cb0ef41Sopenharmony_ci    // impossible to make any assumptions about the prototype chain anyway.
48111cb0ef41Sopenharmony_ci    if (maybe_proto->IsJSProxy()) return;
48121cb0ef41Sopenharmony_ci    Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto);
48131cb0ef41Sopenharmony_ci    Handle<PrototypeInfo> proto_info =
48141cb0ef41Sopenharmony_ci        Map::GetOrCreatePrototypeInfo(proto, isolate);
48151cb0ef41Sopenharmony_ci    Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
48161cb0ef41Sopenharmony_ci    Handle<WeakArrayList> registry =
48171cb0ef41Sopenharmony_ci        maybe_registry->IsSmi()
48181cb0ef41Sopenharmony_ci            ? handle(ReadOnlyRoots(isolate->heap()).empty_weak_array_list(),
48191cb0ef41Sopenharmony_ci                     isolate)
48201cb0ef41Sopenharmony_ci            : Handle<WeakArrayList>::cast(maybe_registry);
48211cb0ef41Sopenharmony_ci    int slot = 0;
48221cb0ef41Sopenharmony_ci    Handle<WeakArrayList> new_array =
48231cb0ef41Sopenharmony_ci        PrototypeUsers::Add(isolate, registry, current_user, &slot);
48241cb0ef41Sopenharmony_ci    current_user_info->set_registry_slot(slot);
48251cb0ef41Sopenharmony_ci    if (!maybe_registry.is_identical_to(new_array)) {
48261cb0ef41Sopenharmony_ci      proto_info->set_prototype_users(*new_array);
48271cb0ef41Sopenharmony_ci    }
48281cb0ef41Sopenharmony_ci    if (FLAG_trace_prototype_users) {
48291cb0ef41Sopenharmony_ci      PrintF("Registering %p as a user of prototype %p (map=%p).\n",
48301cb0ef41Sopenharmony_ci             reinterpret_cast<void*>(current_user->ptr()),
48311cb0ef41Sopenharmony_ci             reinterpret_cast<void*>(proto->ptr()),
48321cb0ef41Sopenharmony_ci             reinterpret_cast<void*>(proto->map().ptr()));
48331cb0ef41Sopenharmony_ci    }
48341cb0ef41Sopenharmony_ci
48351cb0ef41Sopenharmony_ci    current_user = handle(proto->map(), isolate);
48361cb0ef41Sopenharmony_ci    current_user_info = proto_info;
48371cb0ef41Sopenharmony_ci  }
48381cb0ef41Sopenharmony_ci}
48391cb0ef41Sopenharmony_ci
48401cb0ef41Sopenharmony_ci// Can be called regardless of whether |user| was actually registered with
48411cb0ef41Sopenharmony_ci// |prototype|. Returns true when there was a registration.
48421cb0ef41Sopenharmony_ci// static
48431cb0ef41Sopenharmony_cibool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
48441cb0ef41Sopenharmony_ci  DCHECK(user->is_prototype_map());
48451cb0ef41Sopenharmony_ci  // If it doesn't have a PrototypeInfo, it was never registered.
48461cb0ef41Sopenharmony_ci  if (!user->prototype_info().IsPrototypeInfo()) return false;
48471cb0ef41Sopenharmony_ci  // If it had no prototype before, see if it had users that might expect
48481cb0ef41Sopenharmony_ci  // registration.
48491cb0ef41Sopenharmony_ci  if (!user->prototype().IsJSObject()) {
48501cb0ef41Sopenharmony_ci    Object users =
48511cb0ef41Sopenharmony_ci        PrototypeInfo::cast(user->prototype_info()).prototype_users();
48521cb0ef41Sopenharmony_ci    return users.IsWeakArrayList();
48531cb0ef41Sopenharmony_ci  }
48541cb0ef41Sopenharmony_ci  Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate);
48551cb0ef41Sopenharmony_ci  Handle<PrototypeInfo> user_info =
48561cb0ef41Sopenharmony_ci      Map::GetOrCreatePrototypeInfo(user, isolate);
48571cb0ef41Sopenharmony_ci  int slot = user_info->registry_slot();
48581cb0ef41Sopenharmony_ci  if (slot == PrototypeInfo::UNREGISTERED) return false;
48591cb0ef41Sopenharmony_ci  DCHECK(prototype->map().is_prototype_map());
48601cb0ef41Sopenharmony_ci  Object maybe_proto_info = prototype->map().prototype_info();
48611cb0ef41Sopenharmony_ci  // User knows its registry slot, prototype info and user registry must exist.
48621cb0ef41Sopenharmony_ci  DCHECK(maybe_proto_info.IsPrototypeInfo());
48631cb0ef41Sopenharmony_ci  Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info),
48641cb0ef41Sopenharmony_ci                                   isolate);
48651cb0ef41Sopenharmony_ci  Handle<WeakArrayList> prototype_users(
48661cb0ef41Sopenharmony_ci      WeakArrayList::cast(proto_info->prototype_users()), isolate);
48671cb0ef41Sopenharmony_ci  DCHECK_EQ(prototype_users->Get(slot), HeapObjectReference::Weak(*user));
48681cb0ef41Sopenharmony_ci  PrototypeUsers::MarkSlotEmpty(*prototype_users, slot);
48691cb0ef41Sopenharmony_ci  if (FLAG_trace_prototype_users) {
48701cb0ef41Sopenharmony_ci    PrintF("Unregistering %p as a user of prototype %p.\n",
48711cb0ef41Sopenharmony_ci           reinterpret_cast<void*>(user->ptr()),
48721cb0ef41Sopenharmony_ci           reinterpret_cast<void*>(prototype->ptr()));
48731cb0ef41Sopenharmony_ci  }
48741cb0ef41Sopenharmony_ci  return true;
48751cb0ef41Sopenharmony_ci}
48761cb0ef41Sopenharmony_ci
48771cb0ef41Sopenharmony_cinamespace {
48781cb0ef41Sopenharmony_ci
48791cb0ef41Sopenharmony_ci// This function must be kept in sync with
48801cb0ef41Sopenharmony_ci// AccessorAssembler::InvalidateValidityCellIfPrototype() which does pre-checks
48811cb0ef41Sopenharmony_ci// before jumping here.
48821cb0ef41Sopenharmony_civoid InvalidateOnePrototypeValidityCellInternal(Map map) {
48831cb0ef41Sopenharmony_ci  DCHECK(map.is_prototype_map());
48841cb0ef41Sopenharmony_ci  if (FLAG_trace_prototype_users) {
48851cb0ef41Sopenharmony_ci    PrintF("Invalidating prototype map %p 's cell\n",
48861cb0ef41Sopenharmony_ci           reinterpret_cast<void*>(map.ptr()));
48871cb0ef41Sopenharmony_ci  }
48881cb0ef41Sopenharmony_ci  Object maybe_cell = map.prototype_validity_cell();
48891cb0ef41Sopenharmony_ci  if (maybe_cell.IsCell()) {
48901cb0ef41Sopenharmony_ci    // Just set the value; the cell will be replaced lazily.
48911cb0ef41Sopenharmony_ci    Cell cell = Cell::cast(maybe_cell);
48921cb0ef41Sopenharmony_ci    cell.set_value(Smi::FromInt(Map::kPrototypeChainInvalid));
48931cb0ef41Sopenharmony_ci  }
48941cb0ef41Sopenharmony_ci  Object maybe_prototype_info = map.prototype_info();
48951cb0ef41Sopenharmony_ci  if (maybe_prototype_info.IsPrototypeInfo()) {
48961cb0ef41Sopenharmony_ci    PrototypeInfo prototype_info = PrototypeInfo::cast(maybe_prototype_info);
48971cb0ef41Sopenharmony_ci    prototype_info.set_prototype_chain_enum_cache(Object());
48981cb0ef41Sopenharmony_ci  }
48991cb0ef41Sopenharmony_ci
49001cb0ef41Sopenharmony_ci  // We may inline accesses to constants stored in dictionary mode protoypes in
49011cb0ef41Sopenharmony_ci  // optimized code. When doing so, we install depenendies of group
49021cb0ef41Sopenharmony_ci  // |kPrototypeCheckGroup| on each prototype between the receiver's immediate
49031cb0ef41Sopenharmony_ci  // prototype and the holder of the constant property. This dependency is used
49041cb0ef41Sopenharmony_ci  // both to detect changes to the constant value itself, and other changes to
49051cb0ef41Sopenharmony_ci  // the prototype chain that invalidate the access to the given property from
49061cb0ef41Sopenharmony_ci  // the given receiver (like adding the property to another prototype between
49071cb0ef41Sopenharmony_ci  // the receiver and the (previous) holder). This works by de-opting this group
49081cb0ef41Sopenharmony_ci  // whenever the validity cell would be invalidated. However, the actual value
49091cb0ef41Sopenharmony_ci  // of the validity cell is not used. Therefore, we always trigger the de-opt
49101cb0ef41Sopenharmony_ci  // here, even if the cell was already invalid.
49111cb0ef41Sopenharmony_ci  if (V8_DICT_PROPERTY_CONST_TRACKING_BOOL && map.is_dictionary_map()) {
49121cb0ef41Sopenharmony_ci    // TODO(11527): pass Isolate as an argument.
49131cb0ef41Sopenharmony_ci    Isolate* isolate = GetIsolateFromWritableObject(map);
49141cb0ef41Sopenharmony_ci    map.dependent_code().DeoptimizeDependentCodeGroup(
49151cb0ef41Sopenharmony_ci        isolate, DependentCode::kPrototypeCheckGroup);
49161cb0ef41Sopenharmony_ci  }
49171cb0ef41Sopenharmony_ci}
49181cb0ef41Sopenharmony_ci
49191cb0ef41Sopenharmony_civoid InvalidatePrototypeChainsInternal(Map map) {
49201cb0ef41Sopenharmony_ci  // We handle linear prototype chains by looping, and multiple children
49211cb0ef41Sopenharmony_ci  // by recursion, in order to reduce the likelihood of running into stack
49221cb0ef41Sopenharmony_ci  // overflows. So, conceptually, the outer loop iterates the depth of the
49231cb0ef41Sopenharmony_ci  // prototype tree, and the inner loop iterates the breadth of a node.
49241cb0ef41Sopenharmony_ci  Map next_map;
49251cb0ef41Sopenharmony_ci  for (; !map.is_null(); map = next_map, next_map = Map()) {
49261cb0ef41Sopenharmony_ci    InvalidateOnePrototypeValidityCellInternal(map);
49271cb0ef41Sopenharmony_ci
49281cb0ef41Sopenharmony_ci    Object maybe_proto_info = map.prototype_info();
49291cb0ef41Sopenharmony_ci    if (!maybe_proto_info.IsPrototypeInfo()) return;
49301cb0ef41Sopenharmony_ci    PrototypeInfo proto_info = PrototypeInfo::cast(maybe_proto_info);
49311cb0ef41Sopenharmony_ci    if (!proto_info.prototype_users().IsWeakArrayList()) {
49321cb0ef41Sopenharmony_ci      return;
49331cb0ef41Sopenharmony_ci    }
49341cb0ef41Sopenharmony_ci    WeakArrayList prototype_users =
49351cb0ef41Sopenharmony_ci        WeakArrayList::cast(proto_info.prototype_users());
49361cb0ef41Sopenharmony_ci    // For now, only maps register themselves as users.
49371cb0ef41Sopenharmony_ci    for (int i = PrototypeUsers::kFirstIndex; i < prototype_users.length();
49381cb0ef41Sopenharmony_ci         ++i) {
49391cb0ef41Sopenharmony_ci      HeapObject heap_object;
49401cb0ef41Sopenharmony_ci      if (prototype_users.Get(i)->GetHeapObjectIfWeak(&heap_object) &&
49411cb0ef41Sopenharmony_ci          heap_object.IsMap()) {
49421cb0ef41Sopenharmony_ci        // Walk the prototype chain (backwards, towards leaf objects) if
49431cb0ef41Sopenharmony_ci        // necessary.
49441cb0ef41Sopenharmony_ci        if (next_map.is_null()) {
49451cb0ef41Sopenharmony_ci          next_map = Map::cast(heap_object);
49461cb0ef41Sopenharmony_ci        } else {
49471cb0ef41Sopenharmony_ci          InvalidatePrototypeChainsInternal(Map::cast(heap_object));
49481cb0ef41Sopenharmony_ci        }
49491cb0ef41Sopenharmony_ci      }
49501cb0ef41Sopenharmony_ci    }
49511cb0ef41Sopenharmony_ci  }
49521cb0ef41Sopenharmony_ci}
49531cb0ef41Sopenharmony_ci
49541cb0ef41Sopenharmony_ci}  // namespace
49551cb0ef41Sopenharmony_ci
49561cb0ef41Sopenharmony_ci// static
49571cb0ef41Sopenharmony_ciMap JSObject::InvalidatePrototypeChains(Map map) {
49581cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
49591cb0ef41Sopenharmony_ci  InvalidatePrototypeChainsInternal(map);
49601cb0ef41Sopenharmony_ci  return map;
49611cb0ef41Sopenharmony_ci}
49621cb0ef41Sopenharmony_ci
49631cb0ef41Sopenharmony_ci// We also invalidate global objects validity cell when a new lexical
49641cb0ef41Sopenharmony_ci// environment variable is added. This is necessary to ensure that
49651cb0ef41Sopenharmony_ci// Load/StoreGlobalIC handlers that load/store from global object's prototype
49661cb0ef41Sopenharmony_ci// get properly invalidated.
49671cb0ef41Sopenharmony_ci// Note, that the normal Load/StoreICs that load/store through the global object
49681cb0ef41Sopenharmony_ci// in the prototype chain are not affected by appearance of a new lexical
49691cb0ef41Sopenharmony_ci// variable and therefore we don't propagate invalidation down.
49701cb0ef41Sopenharmony_ci// static
49711cb0ef41Sopenharmony_civoid JSObject::InvalidatePrototypeValidityCell(JSGlobalObject global) {
49721cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
49731cb0ef41Sopenharmony_ci  InvalidateOnePrototypeValidityCellInternal(global.map());
49741cb0ef41Sopenharmony_ci}
49751cb0ef41Sopenharmony_ci
49761cb0ef41Sopenharmony_ciMaybe<bool> JSObject::SetPrototype(Isolate* isolate, Handle<JSObject> object,
49771cb0ef41Sopenharmony_ci                                   Handle<Object> value, bool from_javascript,
49781cb0ef41Sopenharmony_ci                                   ShouldThrow should_throw) {
49791cb0ef41Sopenharmony_ci#ifdef DEBUG
49801cb0ef41Sopenharmony_ci  int size = object->Size();
49811cb0ef41Sopenharmony_ci#endif
49821cb0ef41Sopenharmony_ci
49831cb0ef41Sopenharmony_ci  if (from_javascript) {
49841cb0ef41Sopenharmony_ci    if (object->IsAccessCheckNeeded() &&
49851cb0ef41Sopenharmony_ci        !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
49861cb0ef41Sopenharmony_ci      isolate->ReportFailedAccessCheck(object);
49871cb0ef41Sopenharmony_ci      RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
49881cb0ef41Sopenharmony_ci      RETURN_FAILURE(isolate, should_throw,
49891cb0ef41Sopenharmony_ci                     NewTypeError(MessageTemplate::kNoAccess));
49901cb0ef41Sopenharmony_ci    }
49911cb0ef41Sopenharmony_ci  } else {
49921cb0ef41Sopenharmony_ci    DCHECK(!object->IsAccessCheckNeeded());
49931cb0ef41Sopenharmony_ci  }
49941cb0ef41Sopenharmony_ci
49951cb0ef41Sopenharmony_ci  // Silently ignore the change if value is not a JSObject or null.
49961cb0ef41Sopenharmony_ci  // SpiderMonkey behaves this way.
49971cb0ef41Sopenharmony_ci  if (!value->IsJSReceiver() && !value->IsNull(isolate)) return Just(true);
49981cb0ef41Sopenharmony_ci
49991cb0ef41Sopenharmony_ci  bool all_extensible = object->map().is_extensible();
50001cb0ef41Sopenharmony_ci  Handle<JSObject> real_receiver = object;
50011cb0ef41Sopenharmony_ci  if (from_javascript) {
50021cb0ef41Sopenharmony_ci    // Find the first object in the chain whose prototype object is not
50031cb0ef41Sopenharmony_ci    // hidden.
50041cb0ef41Sopenharmony_ci    PrototypeIterator iter(isolate, real_receiver, kStartAtPrototype,
50051cb0ef41Sopenharmony_ci                           PrototypeIterator::END_AT_NON_HIDDEN);
50061cb0ef41Sopenharmony_ci    while (!iter.IsAtEnd()) {
50071cb0ef41Sopenharmony_ci      // Casting to JSObject is fine because hidden prototypes are never
50081cb0ef41Sopenharmony_ci      // JSProxies.
50091cb0ef41Sopenharmony_ci      real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
50101cb0ef41Sopenharmony_ci      iter.Advance();
50111cb0ef41Sopenharmony_ci      all_extensible = all_extensible && real_receiver->map().is_extensible();
50121cb0ef41Sopenharmony_ci    }
50131cb0ef41Sopenharmony_ci  }
50141cb0ef41Sopenharmony_ci  Handle<Map> map(real_receiver->map(), isolate);
50151cb0ef41Sopenharmony_ci
50161cb0ef41Sopenharmony_ci  // Nothing to do if prototype is already set.
50171cb0ef41Sopenharmony_ci  if (map->prototype() == *value) return Just(true);
50181cb0ef41Sopenharmony_ci
50191cb0ef41Sopenharmony_ci  bool immutable_proto = map->is_immutable_proto();
50201cb0ef41Sopenharmony_ci  if (immutable_proto) {
50211cb0ef41Sopenharmony_ci    RETURN_FAILURE(
50221cb0ef41Sopenharmony_ci        isolate, should_throw,
50231cb0ef41Sopenharmony_ci        NewTypeError(MessageTemplate::kImmutablePrototypeSet, object));
50241cb0ef41Sopenharmony_ci  }
50251cb0ef41Sopenharmony_ci
50261cb0ef41Sopenharmony_ci  // From 6.1.7.3 Invariants of the Essential Internal Methods
50271cb0ef41Sopenharmony_ci  //
50281cb0ef41Sopenharmony_ci  // [[SetPrototypeOf]] ( V )
50291cb0ef41Sopenharmony_ci  // * ...
50301cb0ef41Sopenharmony_ci  // * If target is non-extensible, [[SetPrototypeOf]] must return false,
50311cb0ef41Sopenharmony_ci  //   unless V is the SameValue as the target's observed [[GetPrototypeOf]]
50321cb0ef41Sopenharmony_ci  //   value.
50331cb0ef41Sopenharmony_ci  if (!all_extensible) {
50341cb0ef41Sopenharmony_ci    RETURN_FAILURE(isolate, should_throw,
50351cb0ef41Sopenharmony_ci                   NewTypeError(MessageTemplate::kNonExtensibleProto, object));
50361cb0ef41Sopenharmony_ci  }
50371cb0ef41Sopenharmony_ci
50381cb0ef41Sopenharmony_ci  // Before we can set the prototype we need to be sure prototype cycles are
50391cb0ef41Sopenharmony_ci  // prevented.  It is sufficient to validate that the receiver is not in the
50401cb0ef41Sopenharmony_ci  // new prototype chain.
50411cb0ef41Sopenharmony_ci  if (value->IsJSReceiver()) {
50421cb0ef41Sopenharmony_ci    for (PrototypeIterator iter(isolate, JSReceiver::cast(*value),
50431cb0ef41Sopenharmony_ci                                kStartAtReceiver);
50441cb0ef41Sopenharmony_ci         !iter.IsAtEnd(); iter.Advance()) {
50451cb0ef41Sopenharmony_ci      if (iter.GetCurrent<JSReceiver>() == *object) {
50461cb0ef41Sopenharmony_ci        // Cycle detected.
50471cb0ef41Sopenharmony_ci        RETURN_FAILURE(isolate, should_throw,
50481cb0ef41Sopenharmony_ci                       NewTypeError(MessageTemplate::kCyclicProto));
50491cb0ef41Sopenharmony_ci      }
50501cb0ef41Sopenharmony_ci    }
50511cb0ef41Sopenharmony_ci  }
50521cb0ef41Sopenharmony_ci
50531cb0ef41Sopenharmony_ci  // Set the new prototype of the object.
50541cb0ef41Sopenharmony_ci
50551cb0ef41Sopenharmony_ci  isolate->UpdateNoElementsProtectorOnSetPrototype(real_receiver);
50561cb0ef41Sopenharmony_ci
50571cb0ef41Sopenharmony_ci  Handle<Map> new_map =
50581cb0ef41Sopenharmony_ci      Map::TransitionToPrototype(isolate, map, Handle<HeapObject>::cast(value));
50591cb0ef41Sopenharmony_ci  DCHECK(new_map->prototype() == *value);
50601cb0ef41Sopenharmony_ci  JSObject::MigrateToMap(isolate, real_receiver, new_map);
50611cb0ef41Sopenharmony_ci
50621cb0ef41Sopenharmony_ci  DCHECK(size == object->Size());
50631cb0ef41Sopenharmony_ci  return Just(true);
50641cb0ef41Sopenharmony_ci}
50651cb0ef41Sopenharmony_ci
50661cb0ef41Sopenharmony_ci// static
50671cb0ef41Sopenharmony_civoid JSObject::SetImmutableProto(Handle<JSObject> object) {
50681cb0ef41Sopenharmony_ci  Handle<Map> map(object->map(), object->GetIsolate());
50691cb0ef41Sopenharmony_ci
50701cb0ef41Sopenharmony_ci  // Nothing to do if prototype is already set.
50711cb0ef41Sopenharmony_ci  if (map->is_immutable_proto()) return;
50721cb0ef41Sopenharmony_ci
50731cb0ef41Sopenharmony_ci  Handle<Map> new_map =
50741cb0ef41Sopenharmony_ci      Map::TransitionToImmutableProto(object->GetIsolate(), map);
50751cb0ef41Sopenharmony_ci  object->set_map(*new_map, kReleaseStore);
50761cb0ef41Sopenharmony_ci}
50771cb0ef41Sopenharmony_ci
50781cb0ef41Sopenharmony_civoid JSObject::EnsureCanContainElements(Handle<JSObject> object,
50791cb0ef41Sopenharmony_ci                                        JavaScriptArguments* args,
50801cb0ef41Sopenharmony_ci                                        uint32_t arg_count,
50811cb0ef41Sopenharmony_ci                                        EnsureElementsMode mode) {
50821cb0ef41Sopenharmony_ci  return EnsureCanContainElements(object, args->first_slot(), arg_count, mode);
50831cb0ef41Sopenharmony_ci}
50841cb0ef41Sopenharmony_ci
50851cb0ef41Sopenharmony_civoid JSObject::ValidateElements(JSObject object) {
50861cb0ef41Sopenharmony_ci#ifdef ENABLE_SLOW_DCHECKS
50871cb0ef41Sopenharmony_ci  if (FLAG_enable_slow_asserts) {
50881cb0ef41Sopenharmony_ci    object.GetElementsAccessor()->Validate(object);
50891cb0ef41Sopenharmony_ci  }
50901cb0ef41Sopenharmony_ci#endif
50911cb0ef41Sopenharmony_ci}
50921cb0ef41Sopenharmony_ci
50931cb0ef41Sopenharmony_cibool JSObject::WouldConvertToSlowElements(uint32_t index) {
50941cb0ef41Sopenharmony_ci  if (!HasFastElements()) return false;
50951cb0ef41Sopenharmony_ci  uint32_t capacity = static_cast<uint32_t>(elements().length());
50961cb0ef41Sopenharmony_ci  uint32_t new_capacity;
50971cb0ef41Sopenharmony_ci  return ShouldConvertToSlowElements(*this, capacity, index, &new_capacity);
50981cb0ef41Sopenharmony_ci}
50991cb0ef41Sopenharmony_ci
51001cb0ef41Sopenharmony_cistatic bool ShouldConvertToFastElements(JSObject object,
51011cb0ef41Sopenharmony_ci                                        NumberDictionary dictionary,
51021cb0ef41Sopenharmony_ci                                        uint32_t index,
51031cb0ef41Sopenharmony_ci                                        uint32_t* new_capacity) {
51041cb0ef41Sopenharmony_ci  // If properties with non-standard attributes or accessors were added, we
51051cb0ef41Sopenharmony_ci  // cannot go back to fast elements.
51061cb0ef41Sopenharmony_ci  if (dictionary.requires_slow_elements()) return false;
51071cb0ef41Sopenharmony_ci
51081cb0ef41Sopenharmony_ci  // Adding a property with this index will require slow elements.
51091cb0ef41Sopenharmony_ci  if (index >= static_cast<uint32_t>(Smi::kMaxValue)) return false;
51101cb0ef41Sopenharmony_ci
51111cb0ef41Sopenharmony_ci  if (object.IsJSArray()) {
51121cb0ef41Sopenharmony_ci    Object length = JSArray::cast(object).length();
51131cb0ef41Sopenharmony_ci    if (!length.IsSmi()) return false;
51141cb0ef41Sopenharmony_ci    *new_capacity = static_cast<uint32_t>(Smi::ToInt(length));
51151cb0ef41Sopenharmony_ci  } else if (object.IsJSArgumentsObject()) {
51161cb0ef41Sopenharmony_ci    return false;
51171cb0ef41Sopenharmony_ci  } else {
51181cb0ef41Sopenharmony_ci    *new_capacity = dictionary.max_number_key() + 1;
51191cb0ef41Sopenharmony_ci  }
51201cb0ef41Sopenharmony_ci  *new_capacity = std::max(index + 1, *new_capacity);
51211cb0ef41Sopenharmony_ci
51221cb0ef41Sopenharmony_ci  uint32_t dictionary_size = static_cast<uint32_t>(dictionary.Capacity()) *
51231cb0ef41Sopenharmony_ci                             NumberDictionary::kEntrySize;
51241cb0ef41Sopenharmony_ci
51251cb0ef41Sopenharmony_ci  // Turn fast if the dictionary only saves 50% space.
51261cb0ef41Sopenharmony_ci  return 2 * dictionary_size >= *new_capacity;
51271cb0ef41Sopenharmony_ci}
51281cb0ef41Sopenharmony_ci
51291cb0ef41Sopenharmony_cistatic ElementsKind BestFittingFastElementsKind(JSObject object) {
51301cb0ef41Sopenharmony_ci  if (!object.map().CanHaveFastTransitionableElementsKind()) {
51311cb0ef41Sopenharmony_ci    return HOLEY_ELEMENTS;
51321cb0ef41Sopenharmony_ci  }
51331cb0ef41Sopenharmony_ci  if (object.HasSloppyArgumentsElements()) {
51341cb0ef41Sopenharmony_ci    return FAST_SLOPPY_ARGUMENTS_ELEMENTS;
51351cb0ef41Sopenharmony_ci  }
51361cb0ef41Sopenharmony_ci  if (object.HasStringWrapperElements()) {
51371cb0ef41Sopenharmony_ci    return FAST_STRING_WRAPPER_ELEMENTS;
51381cb0ef41Sopenharmony_ci  }
51391cb0ef41Sopenharmony_ci  DCHECK(object.HasDictionaryElements());
51401cb0ef41Sopenharmony_ci  NumberDictionary dictionary = object.element_dictionary();
51411cb0ef41Sopenharmony_ci  ElementsKind kind = HOLEY_SMI_ELEMENTS;
51421cb0ef41Sopenharmony_ci  for (InternalIndex i : dictionary.IterateEntries()) {
51431cb0ef41Sopenharmony_ci    Object key = dictionary.KeyAt(i);
51441cb0ef41Sopenharmony_ci    if (key.IsNumber()) {
51451cb0ef41Sopenharmony_ci      Object value = dictionary.ValueAt(i);
51461cb0ef41Sopenharmony_ci      if (!value.IsNumber()) return HOLEY_ELEMENTS;
51471cb0ef41Sopenharmony_ci      if (!value.IsSmi()) {
51481cb0ef41Sopenharmony_ci        if (!FLAG_unbox_double_arrays) return HOLEY_ELEMENTS;
51491cb0ef41Sopenharmony_ci        kind = HOLEY_DOUBLE_ELEMENTS;
51501cb0ef41Sopenharmony_ci      }
51511cb0ef41Sopenharmony_ci    }
51521cb0ef41Sopenharmony_ci  }
51531cb0ef41Sopenharmony_ci  return kind;
51541cb0ef41Sopenharmony_ci}
51551cb0ef41Sopenharmony_ci
51561cb0ef41Sopenharmony_ci// static
51571cb0ef41Sopenharmony_ciMaybe<bool> JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
51581cb0ef41Sopenharmony_ci                                     Handle<Object> value,
51591cb0ef41Sopenharmony_ci                                     PropertyAttributes attributes) {
51601cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
51611cb0ef41Sopenharmony_ci
51621cb0ef41Sopenharmony_ci  DCHECK(object->map(isolate).is_extensible());
51631cb0ef41Sopenharmony_ci
51641cb0ef41Sopenharmony_ci  uint32_t old_length = 0;
51651cb0ef41Sopenharmony_ci  uint32_t new_capacity = 0;
51661cb0ef41Sopenharmony_ci
51671cb0ef41Sopenharmony_ci  if (object->IsJSArray(isolate)) {
51681cb0ef41Sopenharmony_ci    CHECK(JSArray::cast(*object).length().ToArrayLength(&old_length));
51691cb0ef41Sopenharmony_ci  }
51701cb0ef41Sopenharmony_ci
51711cb0ef41Sopenharmony_ci  ElementsKind kind = object->GetElementsKind(isolate);
51721cb0ef41Sopenharmony_ci  FixedArrayBase elements = object->elements(isolate);
51731cb0ef41Sopenharmony_ci  ElementsKind dictionary_kind = DICTIONARY_ELEMENTS;
51741cb0ef41Sopenharmony_ci  if (IsSloppyArgumentsElementsKind(kind)) {
51751cb0ef41Sopenharmony_ci    elements = SloppyArgumentsElements::cast(elements).arguments(isolate);
51761cb0ef41Sopenharmony_ci    dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
51771cb0ef41Sopenharmony_ci  } else if (IsStringWrapperElementsKind(kind)) {
51781cb0ef41Sopenharmony_ci    dictionary_kind = SLOW_STRING_WRAPPER_ELEMENTS;
51791cb0ef41Sopenharmony_ci  }
51801cb0ef41Sopenharmony_ci
51811cb0ef41Sopenharmony_ci  if (attributes != NONE) {
51821cb0ef41Sopenharmony_ci    kind = dictionary_kind;
51831cb0ef41Sopenharmony_ci  } else if (elements.IsNumberDictionary(isolate)) {
51841cb0ef41Sopenharmony_ci    kind = ShouldConvertToFastElements(
51851cb0ef41Sopenharmony_ci               *object, NumberDictionary::cast(elements), index, &new_capacity)
51861cb0ef41Sopenharmony_ci               ? BestFittingFastElementsKind(*object)
51871cb0ef41Sopenharmony_ci               : dictionary_kind;
51881cb0ef41Sopenharmony_ci  } else if (ShouldConvertToSlowElements(
51891cb0ef41Sopenharmony_ci                 *object, static_cast<uint32_t>(elements.length()), index,
51901cb0ef41Sopenharmony_ci                 &new_capacity)) {
51911cb0ef41Sopenharmony_ci    kind = dictionary_kind;
51921cb0ef41Sopenharmony_ci  }
51931cb0ef41Sopenharmony_ci
51941cb0ef41Sopenharmony_ci  ElementsKind to = value->OptimalElementsKind(isolate);
51951cb0ef41Sopenharmony_ci  if (IsHoleyElementsKind(kind) || !object->IsJSArray(isolate) ||
51961cb0ef41Sopenharmony_ci      index > old_length) {
51971cb0ef41Sopenharmony_ci    to = GetHoleyElementsKind(to);
51981cb0ef41Sopenharmony_ci    kind = GetHoleyElementsKind(kind);
51991cb0ef41Sopenharmony_ci  }
52001cb0ef41Sopenharmony_ci  to = GetMoreGeneralElementsKind(kind, to);
52011cb0ef41Sopenharmony_ci  ElementsAccessor* accessor = ElementsAccessor::ForKind(to);
52021cb0ef41Sopenharmony_ci  MAYBE_RETURN(accessor->Add(object, index, value, attributes, new_capacity),
52031cb0ef41Sopenharmony_ci               Nothing<bool>());
52041cb0ef41Sopenharmony_ci
52051cb0ef41Sopenharmony_ci  if (object->IsJSArray(isolate) && index >= old_length) {
52061cb0ef41Sopenharmony_ci    Handle<Object> new_length =
52071cb0ef41Sopenharmony_ci        isolate->factory()->NewNumberFromUint(index + 1);
52081cb0ef41Sopenharmony_ci    JSArray::cast(*object).set_length(*new_length);
52091cb0ef41Sopenharmony_ci  }
52101cb0ef41Sopenharmony_ci  return Just(true);
52111cb0ef41Sopenharmony_ci}
52121cb0ef41Sopenharmony_ci
52131cb0ef41Sopenharmony_citemplate <AllocationSiteUpdateMode update_or_check>
52141cb0ef41Sopenharmony_cibool JSObject::UpdateAllocationSite(Handle<JSObject> object,
52151cb0ef41Sopenharmony_ci                                    ElementsKind to_kind) {
52161cb0ef41Sopenharmony_ci  if (!object->IsJSArray()) return false;
52171cb0ef41Sopenharmony_ci
52181cb0ef41Sopenharmony_ci  if (!Heap::InYoungGeneration(*object)) return false;
52191cb0ef41Sopenharmony_ci
52201cb0ef41Sopenharmony_ci  if (Heap::IsLargeObject(*object)) return false;
52211cb0ef41Sopenharmony_ci
52221cb0ef41Sopenharmony_ci  Handle<AllocationSite> site;
52231cb0ef41Sopenharmony_ci  {
52241cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_gc;
52251cb0ef41Sopenharmony_ci
52261cb0ef41Sopenharmony_ci    Heap* heap = object->GetHeap();
52271cb0ef41Sopenharmony_ci    AllocationMemento memento =
52281cb0ef41Sopenharmony_ci        heap->FindAllocationMemento<Heap::kForRuntime>(object->map(), *object);
52291cb0ef41Sopenharmony_ci    if (memento.is_null()) return false;
52301cb0ef41Sopenharmony_ci
52311cb0ef41Sopenharmony_ci    // Walk through to the Allocation Site
52321cb0ef41Sopenharmony_ci    site = handle(memento.GetAllocationSite(), heap->isolate());
52331cb0ef41Sopenharmony_ci  }
52341cb0ef41Sopenharmony_ci  return AllocationSite::DigestTransitionFeedback<update_or_check>(site,
52351cb0ef41Sopenharmony_ci                                                                   to_kind);
52361cb0ef41Sopenharmony_ci}
52371cb0ef41Sopenharmony_ci
52381cb0ef41Sopenharmony_citemplate bool
52391cb0ef41Sopenharmony_ciJSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kCheckOnly>(
52401cb0ef41Sopenharmony_ci    Handle<JSObject> object, ElementsKind to_kind);
52411cb0ef41Sopenharmony_ci
52421cb0ef41Sopenharmony_citemplate bool JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kUpdate>(
52431cb0ef41Sopenharmony_ci    Handle<JSObject> object, ElementsKind to_kind);
52441cb0ef41Sopenharmony_ci
52451cb0ef41Sopenharmony_civoid JSObject::TransitionElementsKind(Handle<JSObject> object,
52461cb0ef41Sopenharmony_ci                                      ElementsKind to_kind) {
52471cb0ef41Sopenharmony_ci  ElementsKind from_kind = object->GetElementsKind();
52481cb0ef41Sopenharmony_ci
52491cb0ef41Sopenharmony_ci  if (IsHoleyElementsKind(from_kind)) {
52501cb0ef41Sopenharmony_ci    to_kind = GetHoleyElementsKind(to_kind);
52511cb0ef41Sopenharmony_ci  }
52521cb0ef41Sopenharmony_ci
52531cb0ef41Sopenharmony_ci  if (from_kind == to_kind) return;
52541cb0ef41Sopenharmony_ci
52551cb0ef41Sopenharmony_ci  // This method should never be called for any other case.
52561cb0ef41Sopenharmony_ci  DCHECK(IsFastElementsKind(from_kind) ||
52571cb0ef41Sopenharmony_ci         IsNonextensibleElementsKind(from_kind));
52581cb0ef41Sopenharmony_ci  DCHECK(IsFastElementsKind(to_kind) || IsNonextensibleElementsKind(to_kind));
52591cb0ef41Sopenharmony_ci  DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind);
52601cb0ef41Sopenharmony_ci
52611cb0ef41Sopenharmony_ci  UpdateAllocationSite(object, to_kind);
52621cb0ef41Sopenharmony_ci  Isolate* isolate = object->GetIsolate();
52631cb0ef41Sopenharmony_ci  if (object->elements() == ReadOnlyRoots(isolate).empty_fixed_array() ||
52641cb0ef41Sopenharmony_ci      IsDoubleElementsKind(from_kind) == IsDoubleElementsKind(to_kind)) {
52651cb0ef41Sopenharmony_ci    // No change is needed to the elements() buffer, the transition
52661cb0ef41Sopenharmony_ci    // only requires a map change.
52671cb0ef41Sopenharmony_ci    Handle<Map> new_map = GetElementsTransitionMap(object, to_kind);
52681cb0ef41Sopenharmony_ci    JSObject::MigrateToMap(isolate, object, new_map);
52691cb0ef41Sopenharmony_ci    if (FLAG_trace_elements_transitions) {
52701cb0ef41Sopenharmony_ci      Handle<FixedArrayBase> elms(object->elements(), isolate);
52711cb0ef41Sopenharmony_ci      PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms);
52721cb0ef41Sopenharmony_ci    }
52731cb0ef41Sopenharmony_ci  } else {
52741cb0ef41Sopenharmony_ci    DCHECK((IsSmiElementsKind(from_kind) && IsDoubleElementsKind(to_kind)) ||
52751cb0ef41Sopenharmony_ci           (IsDoubleElementsKind(from_kind) && IsObjectElementsKind(to_kind)));
52761cb0ef41Sopenharmony_ci    uint32_t c = static_cast<uint32_t>(object->elements().length());
52771cb0ef41Sopenharmony_ci    if (ElementsAccessor::ForKind(to_kind)
52781cb0ef41Sopenharmony_ci            ->GrowCapacityAndConvert(object, c)
52791cb0ef41Sopenharmony_ci            .IsNothing()) {
52801cb0ef41Sopenharmony_ci      // TODO(victorgomes): Temporarily forcing a fatal error here in case of
52811cb0ef41Sopenharmony_ci      // overflow, until all users of TransitionElementsKind can handle
52821cb0ef41Sopenharmony_ci      // exceptions.
52831cb0ef41Sopenharmony_ci      FATAL(
52841cb0ef41Sopenharmony_ci          "Fatal JavaScript invalid size error when transitioning elements "
52851cb0ef41Sopenharmony_ci          "kind");
52861cb0ef41Sopenharmony_ci      UNREACHABLE();
52871cb0ef41Sopenharmony_ci    }
52881cb0ef41Sopenharmony_ci  }
52891cb0ef41Sopenharmony_ci}
52901cb0ef41Sopenharmony_ci
52911cb0ef41Sopenharmony_citemplate <typename BackingStore>
52921cb0ef41Sopenharmony_cistatic int HoleyElementsUsage(JSObject object, BackingStore store) {
52931cb0ef41Sopenharmony_ci  Isolate* isolate = object.GetIsolate();
52941cb0ef41Sopenharmony_ci  int limit = object.IsJSArray() ? Smi::ToInt(JSArray::cast(object).length())
52951cb0ef41Sopenharmony_ci                                 : store.length();
52961cb0ef41Sopenharmony_ci  int used = 0;
52971cb0ef41Sopenharmony_ci  for (int i = 0; i < limit; ++i) {
52981cb0ef41Sopenharmony_ci    if (!store.is_the_hole(isolate, i)) ++used;
52991cb0ef41Sopenharmony_ci  }
53001cb0ef41Sopenharmony_ci  return used;
53011cb0ef41Sopenharmony_ci}
53021cb0ef41Sopenharmony_ci
53031cb0ef41Sopenharmony_ciint JSObject::GetFastElementsUsage() {
53041cb0ef41Sopenharmony_ci  FixedArrayBase store = elements();
53051cb0ef41Sopenharmony_ci  switch (GetElementsKind()) {
53061cb0ef41Sopenharmony_ci    case PACKED_SMI_ELEMENTS:
53071cb0ef41Sopenharmony_ci    case PACKED_DOUBLE_ELEMENTS:
53081cb0ef41Sopenharmony_ci    case PACKED_ELEMENTS:
53091cb0ef41Sopenharmony_ci    case PACKED_FROZEN_ELEMENTS:
53101cb0ef41Sopenharmony_ci    case PACKED_SEALED_ELEMENTS:
53111cb0ef41Sopenharmony_ci    case PACKED_NONEXTENSIBLE_ELEMENTS:
53121cb0ef41Sopenharmony_ci      return IsJSArray() ? Smi::ToInt(JSArray::cast(*this).length())
53131cb0ef41Sopenharmony_ci                         : store.length();
53141cb0ef41Sopenharmony_ci    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
53151cb0ef41Sopenharmony_ci      store = SloppyArgumentsElements::cast(store).arguments();
53161cb0ef41Sopenharmony_ci      V8_FALLTHROUGH;
53171cb0ef41Sopenharmony_ci    case HOLEY_SMI_ELEMENTS:
53181cb0ef41Sopenharmony_ci    case HOLEY_ELEMENTS:
53191cb0ef41Sopenharmony_ci    case HOLEY_FROZEN_ELEMENTS:
53201cb0ef41Sopenharmony_ci    case HOLEY_SEALED_ELEMENTS:
53211cb0ef41Sopenharmony_ci    case HOLEY_NONEXTENSIBLE_ELEMENTS:
53221cb0ef41Sopenharmony_ci    case FAST_STRING_WRAPPER_ELEMENTS:
53231cb0ef41Sopenharmony_ci      return HoleyElementsUsage(*this, FixedArray::cast(store));
53241cb0ef41Sopenharmony_ci    case HOLEY_DOUBLE_ELEMENTS:
53251cb0ef41Sopenharmony_ci      if (elements().length() == 0) return 0;
53261cb0ef41Sopenharmony_ci      return HoleyElementsUsage(*this, FixedDoubleArray::cast(store));
53271cb0ef41Sopenharmony_ci
53281cb0ef41Sopenharmony_ci    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
53291cb0ef41Sopenharmony_ci    case SLOW_STRING_WRAPPER_ELEMENTS:
53301cb0ef41Sopenharmony_ci    case DICTIONARY_ELEMENTS:
53311cb0ef41Sopenharmony_ci    case WASM_ARRAY_ELEMENTS:
53321cb0ef41Sopenharmony_ci    case NO_ELEMENTS:
53331cb0ef41Sopenharmony_ci#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
53341cb0ef41Sopenharmony_ci
53351cb0ef41Sopenharmony_ci      TYPED_ARRAYS(TYPED_ARRAY_CASE)
53361cb0ef41Sopenharmony_ci      RAB_GSAB_TYPED_ARRAYS(TYPED_ARRAY_CASE)
53371cb0ef41Sopenharmony_ci#undef TYPED_ARRAY_CASE
53381cb0ef41Sopenharmony_ci      UNREACHABLE();
53391cb0ef41Sopenharmony_ci  }
53401cb0ef41Sopenharmony_ci  return 0;
53411cb0ef41Sopenharmony_ci}
53421cb0ef41Sopenharmony_ci
53431cb0ef41Sopenharmony_ciMaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
53441cb0ef41Sopenharmony_ci                                                         bool* done) {
53451cb0ef41Sopenharmony_ci  DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
53461cb0ef41Sopenharmony_ci  return GetPropertyWithInterceptorInternal(it, it->GetInterceptor(), done);
53471cb0ef41Sopenharmony_ci}
53481cb0ef41Sopenharmony_ci
53491cb0ef41Sopenharmony_ciMaybe<bool> JSObject::HasRealNamedProperty(Isolate* isolate,
53501cb0ef41Sopenharmony_ci                                           Handle<JSObject> object,
53511cb0ef41Sopenharmony_ci                                           Handle<Name> name) {
53521cb0ef41Sopenharmony_ci  PropertyKey key(isolate, name);
53531cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
53541cb0ef41Sopenharmony_ci  return HasProperty(&it);
53551cb0ef41Sopenharmony_ci}
53561cb0ef41Sopenharmony_ci
53571cb0ef41Sopenharmony_ciMaybe<bool> JSObject::HasRealElementProperty(Isolate* isolate,
53581cb0ef41Sopenharmony_ci                                             Handle<JSObject> object,
53591cb0ef41Sopenharmony_ci                                             uint32_t index) {
53601cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, index, object,
53611cb0ef41Sopenharmony_ci                    LookupIterator::OWN_SKIP_INTERCEPTOR);
53621cb0ef41Sopenharmony_ci  return HasProperty(&it);
53631cb0ef41Sopenharmony_ci}
53641cb0ef41Sopenharmony_ci
53651cb0ef41Sopenharmony_ciMaybe<bool> JSObject::HasRealNamedCallbackProperty(Isolate* isolate,
53661cb0ef41Sopenharmony_ci                                                   Handle<JSObject> object,
53671cb0ef41Sopenharmony_ci                                                   Handle<Name> name) {
53681cb0ef41Sopenharmony_ci  PropertyKey key(isolate, name);
53691cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
53701cb0ef41Sopenharmony_ci  Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
53711cb0ef41Sopenharmony_ci  return maybe_result.IsJust() ? Just(it.state() == LookupIterator::ACCESSOR)
53721cb0ef41Sopenharmony_ci                               : Nothing<bool>();
53731cb0ef41Sopenharmony_ci}
53741cb0ef41Sopenharmony_ci
53751cb0ef41Sopenharmony_cibool JSGlobalProxy::IsDetached() const {
53761cb0ef41Sopenharmony_ci  return native_context().IsNull(GetIsolate());
53771cb0ef41Sopenharmony_ci}
53781cb0ef41Sopenharmony_ci
53791cb0ef41Sopenharmony_civoid JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
53801cb0ef41Sopenharmony_ci                                            Handle<Name> name) {
53811cb0ef41Sopenharmony_ci  Isolate* isolate = global->GetIsolate();
53821cb0ef41Sopenharmony_ci  // Regardless of whether the property is there or not invalidate
53831cb0ef41Sopenharmony_ci  // Load/StoreGlobalICs that load/store through global object's prototype.
53841cb0ef41Sopenharmony_ci  JSObject::InvalidatePrototypeValidityCell(*global);
53851cb0ef41Sopenharmony_ci  DCHECK(!global->HasFastProperties());
53861cb0ef41Sopenharmony_ci  auto dictionary = handle(global->global_dictionary(kAcquireLoad), isolate);
53871cb0ef41Sopenharmony_ci  InternalIndex entry = dictionary->FindEntry(isolate, name);
53881cb0ef41Sopenharmony_ci  if (entry.is_not_found()) return;
53891cb0ef41Sopenharmony_ci
53901cb0ef41Sopenharmony_ci  Handle<PropertyCell> cell(dictionary->CellAt(entry), isolate);
53911cb0ef41Sopenharmony_ci  Handle<Object> value(cell->value(), isolate);
53921cb0ef41Sopenharmony_ci  PropertyDetails details = cell->property_details();
53931cb0ef41Sopenharmony_ci  details = details.set_cell_type(PropertyCellType::kMutable);
53941cb0ef41Sopenharmony_ci  PropertyCell::InvalidateAndReplaceEntry(isolate, dictionary, entry, details,
53951cb0ef41Sopenharmony_ci                                          value);
53961cb0ef41Sopenharmony_ci}
53971cb0ef41Sopenharmony_ci
53981cb0ef41Sopenharmony_ci// static
53991cb0ef41Sopenharmony_ciMaybeHandle<JSDate> JSDate::New(Handle<JSFunction> constructor,
54001cb0ef41Sopenharmony_ci                                Handle<JSReceiver> new_target, double tv) {
54011cb0ef41Sopenharmony_ci  Isolate* const isolate = constructor->GetIsolate();
54021cb0ef41Sopenharmony_ci  Handle<JSObject> result;
54031cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION(
54041cb0ef41Sopenharmony_ci      isolate, result,
54051cb0ef41Sopenharmony_ci      JSObject::New(constructor, new_target, Handle<AllocationSite>::null()),
54061cb0ef41Sopenharmony_ci      JSDate);
54071cb0ef41Sopenharmony_ci  if (-DateCache::kMaxTimeInMs <= tv && tv <= DateCache::kMaxTimeInMs) {
54081cb0ef41Sopenharmony_ci    tv = DoubleToInteger(tv) + 0.0;
54091cb0ef41Sopenharmony_ci  } else {
54101cb0ef41Sopenharmony_ci    tv = std::numeric_limits<double>::quiet_NaN();
54111cb0ef41Sopenharmony_ci  }
54121cb0ef41Sopenharmony_ci  Handle<Object> value = isolate->factory()->NewNumber(tv);
54131cb0ef41Sopenharmony_ci  Handle<JSDate>::cast(result)->SetValue(*value, std::isnan(tv));
54141cb0ef41Sopenharmony_ci  return Handle<JSDate>::cast(result);
54151cb0ef41Sopenharmony_ci}
54161cb0ef41Sopenharmony_ci
54171cb0ef41Sopenharmony_ci// static
54181cb0ef41Sopenharmony_cidouble JSDate::CurrentTimeValue(Isolate* isolate) {
54191cb0ef41Sopenharmony_ci  if (FLAG_log_internal_timer_events) LOG(isolate, CurrentTimeEvent());
54201cb0ef41Sopenharmony_ci  if (FLAG_correctness_fuzzer_suppressions) return 4.2;
54211cb0ef41Sopenharmony_ci
54221cb0ef41Sopenharmony_ci  // According to ECMA-262, section 15.9.1, page 117, the precision of
54231cb0ef41Sopenharmony_ci  // the number in a Date object representing a particular instant in
54241cb0ef41Sopenharmony_ci  // time is milliseconds. Therefore, we floor the result of getting
54251cb0ef41Sopenharmony_ci  // the OS time.
54261cb0ef41Sopenharmony_ci  return std::floor(V8::GetCurrentPlatform()->CurrentClockTimeMillis());
54271cb0ef41Sopenharmony_ci}
54281cb0ef41Sopenharmony_ci
54291cb0ef41Sopenharmony_ci// static
54301cb0ef41Sopenharmony_ciAddress JSDate::GetField(Isolate* isolate, Address raw_object,
54311cb0ef41Sopenharmony_ci                         Address smi_index) {
54321cb0ef41Sopenharmony_ci  // Called through CallCFunction.
54331cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
54341cb0ef41Sopenharmony_ci  DisallowHandleAllocation no_handles;
54351cb0ef41Sopenharmony_ci  DisallowJavascriptExecution no_js(isolate);
54361cb0ef41Sopenharmony_ci
54371cb0ef41Sopenharmony_ci  Object object(raw_object);
54381cb0ef41Sopenharmony_ci  Smi index(smi_index);
54391cb0ef41Sopenharmony_ci  return JSDate::cast(object)
54401cb0ef41Sopenharmony_ci      .DoGetField(isolate, static_cast<FieldIndex>(index.value()))
54411cb0ef41Sopenharmony_ci      .ptr();
54421cb0ef41Sopenharmony_ci}
54431cb0ef41Sopenharmony_ci
54441cb0ef41Sopenharmony_ciObject JSDate::DoGetField(Isolate* isolate, FieldIndex index) {
54451cb0ef41Sopenharmony_ci  DCHECK_NE(index, kDateValue);
54461cb0ef41Sopenharmony_ci
54471cb0ef41Sopenharmony_ci  DateCache* date_cache = isolate->date_cache();
54481cb0ef41Sopenharmony_ci
54491cb0ef41Sopenharmony_ci  if (index < kFirstUncachedField) {
54501cb0ef41Sopenharmony_ci    Object stamp = cache_stamp();
54511cb0ef41Sopenharmony_ci    if (stamp != date_cache->stamp() && stamp.IsSmi()) {
54521cb0ef41Sopenharmony_ci      // Since the stamp is not NaN, the value is also not NaN.
54531cb0ef41Sopenharmony_ci      int64_t local_time_ms =
54541cb0ef41Sopenharmony_ci          date_cache->ToLocal(static_cast<int64_t>(value().Number()));
54551cb0ef41Sopenharmony_ci      SetCachedFields(local_time_ms, date_cache);
54561cb0ef41Sopenharmony_ci    }
54571cb0ef41Sopenharmony_ci    switch (index) {
54581cb0ef41Sopenharmony_ci      case kYear:
54591cb0ef41Sopenharmony_ci        return year();
54601cb0ef41Sopenharmony_ci      case kMonth:
54611cb0ef41Sopenharmony_ci        return month();
54621cb0ef41Sopenharmony_ci      case kDay:
54631cb0ef41Sopenharmony_ci        return day();
54641cb0ef41Sopenharmony_ci      case kWeekday:
54651cb0ef41Sopenharmony_ci        return weekday();
54661cb0ef41Sopenharmony_ci      case kHour:
54671cb0ef41Sopenharmony_ci        return hour();
54681cb0ef41Sopenharmony_ci      case kMinute:
54691cb0ef41Sopenharmony_ci        return min();
54701cb0ef41Sopenharmony_ci      case kSecond:
54711cb0ef41Sopenharmony_ci        return sec();
54721cb0ef41Sopenharmony_ci      default:
54731cb0ef41Sopenharmony_ci        UNREACHABLE();
54741cb0ef41Sopenharmony_ci    }
54751cb0ef41Sopenharmony_ci  }
54761cb0ef41Sopenharmony_ci
54771cb0ef41Sopenharmony_ci  if (index >= kFirstUTCField) {
54781cb0ef41Sopenharmony_ci    return GetUTCField(index, value().Number(), date_cache);
54791cb0ef41Sopenharmony_ci  }
54801cb0ef41Sopenharmony_ci
54811cb0ef41Sopenharmony_ci  double time = value().Number();
54821cb0ef41Sopenharmony_ci  if (std::isnan(time)) return GetReadOnlyRoots().nan_value();
54831cb0ef41Sopenharmony_ci
54841cb0ef41Sopenharmony_ci  int64_t local_time_ms = date_cache->ToLocal(static_cast<int64_t>(time));
54851cb0ef41Sopenharmony_ci  int days = DateCache::DaysFromTime(local_time_ms);
54861cb0ef41Sopenharmony_ci
54871cb0ef41Sopenharmony_ci  if (index == kDays) return Smi::FromInt(days);
54881cb0ef41Sopenharmony_ci
54891cb0ef41Sopenharmony_ci  int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
54901cb0ef41Sopenharmony_ci  if (index == kMillisecond) return Smi::FromInt(time_in_day_ms % 1000);
54911cb0ef41Sopenharmony_ci  DCHECK_EQ(index, kTimeInDay);
54921cb0ef41Sopenharmony_ci  return Smi::FromInt(time_in_day_ms);
54931cb0ef41Sopenharmony_ci}
54941cb0ef41Sopenharmony_ci
54951cb0ef41Sopenharmony_ciObject JSDate::GetUTCField(FieldIndex index, double value,
54961cb0ef41Sopenharmony_ci                           DateCache* date_cache) {
54971cb0ef41Sopenharmony_ci  DCHECK_GE(index, kFirstUTCField);
54981cb0ef41Sopenharmony_ci
54991cb0ef41Sopenharmony_ci  if (std::isnan(value)) return GetReadOnlyRoots().nan_value();
55001cb0ef41Sopenharmony_ci
55011cb0ef41Sopenharmony_ci  int64_t time_ms = static_cast<int64_t>(value);
55021cb0ef41Sopenharmony_ci
55031cb0ef41Sopenharmony_ci  if (index == kTimezoneOffset) {
55041cb0ef41Sopenharmony_ci    return Smi::FromInt(date_cache->TimezoneOffset(time_ms));
55051cb0ef41Sopenharmony_ci  }
55061cb0ef41Sopenharmony_ci
55071cb0ef41Sopenharmony_ci  int days = DateCache::DaysFromTime(time_ms);
55081cb0ef41Sopenharmony_ci
55091cb0ef41Sopenharmony_ci  if (index == kWeekdayUTC) return Smi::FromInt(date_cache->Weekday(days));
55101cb0ef41Sopenharmony_ci
55111cb0ef41Sopenharmony_ci  if (index <= kDayUTC) {
55121cb0ef41Sopenharmony_ci    int year, month, day;
55131cb0ef41Sopenharmony_ci    date_cache->YearMonthDayFromDays(days, &year, &month, &day);
55141cb0ef41Sopenharmony_ci    if (index == kYearUTC) return Smi::FromInt(year);
55151cb0ef41Sopenharmony_ci    if (index == kMonthUTC) return Smi::FromInt(month);
55161cb0ef41Sopenharmony_ci    DCHECK_EQ(index, kDayUTC);
55171cb0ef41Sopenharmony_ci    return Smi::FromInt(day);
55181cb0ef41Sopenharmony_ci  }
55191cb0ef41Sopenharmony_ci
55201cb0ef41Sopenharmony_ci  int time_in_day_ms = DateCache::TimeInDay(time_ms, days);
55211cb0ef41Sopenharmony_ci  switch (index) {
55221cb0ef41Sopenharmony_ci    case kHourUTC:
55231cb0ef41Sopenharmony_ci      return Smi::FromInt(time_in_day_ms / (60 * 60 * 1000));
55241cb0ef41Sopenharmony_ci    case kMinuteUTC:
55251cb0ef41Sopenharmony_ci      return Smi::FromInt((time_in_day_ms / (60 * 1000)) % 60);
55261cb0ef41Sopenharmony_ci    case kSecondUTC:
55271cb0ef41Sopenharmony_ci      return Smi::FromInt((time_in_day_ms / 1000) % 60);
55281cb0ef41Sopenharmony_ci    case kMillisecondUTC:
55291cb0ef41Sopenharmony_ci      return Smi::FromInt(time_in_day_ms % 1000);
55301cb0ef41Sopenharmony_ci    case kDaysUTC:
55311cb0ef41Sopenharmony_ci      return Smi::FromInt(days);
55321cb0ef41Sopenharmony_ci    case kTimeInDayUTC:
55331cb0ef41Sopenharmony_ci      return Smi::FromInt(time_in_day_ms);
55341cb0ef41Sopenharmony_ci    default:
55351cb0ef41Sopenharmony_ci      UNREACHABLE();
55361cb0ef41Sopenharmony_ci  }
55371cb0ef41Sopenharmony_ci
55381cb0ef41Sopenharmony_ci  UNREACHABLE();
55391cb0ef41Sopenharmony_ci}
55401cb0ef41Sopenharmony_ci
55411cb0ef41Sopenharmony_ci// static
55421cb0ef41Sopenharmony_ciHandle<Object> JSDate::SetValue(Handle<JSDate> date, double v) {
55431cb0ef41Sopenharmony_ci  Isolate* const isolate = date->GetIsolate();
55441cb0ef41Sopenharmony_ci  Handle<Object> value = isolate->factory()->NewNumber(v);
55451cb0ef41Sopenharmony_ci  bool value_is_nan = std::isnan(v);
55461cb0ef41Sopenharmony_ci  date->SetValue(*value, value_is_nan);
55471cb0ef41Sopenharmony_ci  return value;
55481cb0ef41Sopenharmony_ci}
55491cb0ef41Sopenharmony_ci
55501cb0ef41Sopenharmony_civoid JSDate::SetValue(Object value, bool is_value_nan) {
55511cb0ef41Sopenharmony_ci  set_value(value);
55521cb0ef41Sopenharmony_ci  if (is_value_nan) {
55531cb0ef41Sopenharmony_ci    HeapNumber nan = GetReadOnlyRoots().nan_value();
55541cb0ef41Sopenharmony_ci    set_cache_stamp(nan, SKIP_WRITE_BARRIER);
55551cb0ef41Sopenharmony_ci    set_year(nan, SKIP_WRITE_BARRIER);
55561cb0ef41Sopenharmony_ci    set_month(nan, SKIP_WRITE_BARRIER);
55571cb0ef41Sopenharmony_ci    set_day(nan, SKIP_WRITE_BARRIER);
55581cb0ef41Sopenharmony_ci    set_hour(nan, SKIP_WRITE_BARRIER);
55591cb0ef41Sopenharmony_ci    set_min(nan, SKIP_WRITE_BARRIER);
55601cb0ef41Sopenharmony_ci    set_sec(nan, SKIP_WRITE_BARRIER);
55611cb0ef41Sopenharmony_ci    set_weekday(nan, SKIP_WRITE_BARRIER);
55621cb0ef41Sopenharmony_ci  } else {
55631cb0ef41Sopenharmony_ci    set_cache_stamp(Smi::FromInt(DateCache::kInvalidStamp), SKIP_WRITE_BARRIER);
55641cb0ef41Sopenharmony_ci  }
55651cb0ef41Sopenharmony_ci}
55661cb0ef41Sopenharmony_ci
55671cb0ef41Sopenharmony_civoid JSDate::SetCachedFields(int64_t local_time_ms, DateCache* date_cache) {
55681cb0ef41Sopenharmony_ci  int days = DateCache::DaysFromTime(local_time_ms);
55691cb0ef41Sopenharmony_ci  int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
55701cb0ef41Sopenharmony_ci  int year, month, day;
55711cb0ef41Sopenharmony_ci  date_cache->YearMonthDayFromDays(days, &year, &month, &day);
55721cb0ef41Sopenharmony_ci  int weekday = date_cache->Weekday(days);
55731cb0ef41Sopenharmony_ci  int hour = time_in_day_ms / (60 * 60 * 1000);
55741cb0ef41Sopenharmony_ci  int min = (time_in_day_ms / (60 * 1000)) % 60;
55751cb0ef41Sopenharmony_ci  int sec = (time_in_day_ms / 1000) % 60;
55761cb0ef41Sopenharmony_ci  set_cache_stamp(date_cache->stamp());
55771cb0ef41Sopenharmony_ci  set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
55781cb0ef41Sopenharmony_ci  set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
55791cb0ef41Sopenharmony_ci  set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
55801cb0ef41Sopenharmony_ci  set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
55811cb0ef41Sopenharmony_ci  set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
55821cb0ef41Sopenharmony_ci  set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
55831cb0ef41Sopenharmony_ci  set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
55841cb0ef41Sopenharmony_ci}
55851cb0ef41Sopenharmony_ci
55861cb0ef41Sopenharmony_ci// static
55871cb0ef41Sopenharmony_civoid JSMessageObject::EnsureSourcePositionsAvailable(
55881cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSMessageObject> message) {
55891cb0ef41Sopenharmony_ci  if (!message->DidEnsureSourcePositionsAvailable()) {
55901cb0ef41Sopenharmony_ci    DCHECK_EQ(message->start_position(), -1);
55911cb0ef41Sopenharmony_ci    DCHECK_GE(message->bytecode_offset().value(), kFunctionEntryBytecodeOffset);
55921cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared_info(
55931cb0ef41Sopenharmony_ci        SharedFunctionInfo::cast(message->shared_info()), isolate);
55941cb0ef41Sopenharmony_ci    IsCompiledScope is_compiled_scope;
55951cb0ef41Sopenharmony_ci    SharedFunctionInfo::EnsureBytecodeArrayAvailable(
55961cb0ef41Sopenharmony_ci        isolate, shared_info, &is_compiled_scope, CreateSourcePositions::kYes);
55971cb0ef41Sopenharmony_ci    SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate, shared_info);
55981cb0ef41Sopenharmony_ci    DCHECK(shared_info->HasBytecodeArray());
55991cb0ef41Sopenharmony_ci    int position = shared_info->abstract_code(isolate).SourcePosition(
56001cb0ef41Sopenharmony_ci        message->bytecode_offset().value());
56011cb0ef41Sopenharmony_ci    DCHECK_GE(position, 0);
56021cb0ef41Sopenharmony_ci    message->set_start_position(position);
56031cb0ef41Sopenharmony_ci    message->set_end_position(position + 1);
56041cb0ef41Sopenharmony_ci    message->set_shared_info(ReadOnlyRoots(isolate).undefined_value());
56051cb0ef41Sopenharmony_ci  }
56061cb0ef41Sopenharmony_ci}
56071cb0ef41Sopenharmony_ci
56081cb0ef41Sopenharmony_ciint JSMessageObject::GetLineNumber() const {
56091cb0ef41Sopenharmony_ci  DCHECK(DidEnsureSourcePositionsAvailable());
56101cb0ef41Sopenharmony_ci  if (start_position() == -1) return Message::kNoLineNumberInfo;
56111cb0ef41Sopenharmony_ci
56121cb0ef41Sopenharmony_ci  Handle<Script> the_script(script(), GetIsolate());
56131cb0ef41Sopenharmony_ci
56141cb0ef41Sopenharmony_ci  Script::PositionInfo info;
56151cb0ef41Sopenharmony_ci  const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
56161cb0ef41Sopenharmony_ci  if (!Script::GetPositionInfo(the_script, start_position(), &info,
56171cb0ef41Sopenharmony_ci                               offset_flag)) {
56181cb0ef41Sopenharmony_ci    return Message::kNoLineNumberInfo;
56191cb0ef41Sopenharmony_ci  }
56201cb0ef41Sopenharmony_ci
56211cb0ef41Sopenharmony_ci  return info.line + 1;
56221cb0ef41Sopenharmony_ci}
56231cb0ef41Sopenharmony_ci
56241cb0ef41Sopenharmony_ciint JSMessageObject::GetColumnNumber() const {
56251cb0ef41Sopenharmony_ci  DCHECK(DidEnsureSourcePositionsAvailable());
56261cb0ef41Sopenharmony_ci  if (start_position() == -1) return -1;
56271cb0ef41Sopenharmony_ci
56281cb0ef41Sopenharmony_ci  Handle<Script> the_script(script(), GetIsolate());
56291cb0ef41Sopenharmony_ci
56301cb0ef41Sopenharmony_ci  Script::PositionInfo info;
56311cb0ef41Sopenharmony_ci  const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
56321cb0ef41Sopenharmony_ci  if (!Script::GetPositionInfo(the_script, start_position(), &info,
56331cb0ef41Sopenharmony_ci                               offset_flag)) {
56341cb0ef41Sopenharmony_ci    return -1;
56351cb0ef41Sopenharmony_ci  }
56361cb0ef41Sopenharmony_ci
56371cb0ef41Sopenharmony_ci  return info.column;  // Note: No '+1' in contrast to GetLineNumber.
56381cb0ef41Sopenharmony_ci}
56391cb0ef41Sopenharmony_ci
56401cb0ef41Sopenharmony_ciString JSMessageObject::GetSource() const {
56411cb0ef41Sopenharmony_ci  Script script_object = script();
56421cb0ef41Sopenharmony_ci  if (script_object.HasValidSource()) {
56431cb0ef41Sopenharmony_ci    Object source = script_object.source();
56441cb0ef41Sopenharmony_ci    if (source.IsString()) return String::cast(source);
56451cb0ef41Sopenharmony_ci  }
56461cb0ef41Sopenharmony_ci  return ReadOnlyRoots(GetIsolate()).empty_string();
56471cb0ef41Sopenharmony_ci}
56481cb0ef41Sopenharmony_ci
56491cb0ef41Sopenharmony_ciHandle<String> JSMessageObject::GetSourceLine() const {
56501cb0ef41Sopenharmony_ci  Isolate* isolate = GetIsolate();
56511cb0ef41Sopenharmony_ci  Handle<Script> the_script(script(), isolate);
56521cb0ef41Sopenharmony_ci
56531cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
56541cb0ef41Sopenharmony_ci  if (the_script->type() == Script::TYPE_WASM) {
56551cb0ef41Sopenharmony_ci    return isolate->factory()->empty_string();
56561cb0ef41Sopenharmony_ci  }
56571cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
56581cb0ef41Sopenharmony_ci
56591cb0ef41Sopenharmony_ci  Script::PositionInfo info;
56601cb0ef41Sopenharmony_ci  const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
56611cb0ef41Sopenharmony_ci  DCHECK(DidEnsureSourcePositionsAvailable());
56621cb0ef41Sopenharmony_ci  if (!Script::GetPositionInfo(the_script, start_position(), &info,
56631cb0ef41Sopenharmony_ci                               offset_flag)) {
56641cb0ef41Sopenharmony_ci    return isolate->factory()->empty_string();
56651cb0ef41Sopenharmony_ci  }
56661cb0ef41Sopenharmony_ci
56671cb0ef41Sopenharmony_ci  Handle<String> src = handle(String::cast(the_script->source()), isolate);
56681cb0ef41Sopenharmony_ci  return isolate->factory()->NewSubString(src, info.line_start, info.line_end);
56691cb0ef41Sopenharmony_ci}
56701cb0ef41Sopenharmony_ci
56711cb0ef41Sopenharmony_ci}  // namespace internal
56721cb0ef41Sopenharmony_ci}  // namespace v8
5673