11cb0ef41Sopenharmony_ci// Copyright 2015 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/api/api-natives.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/api/api-inl.h"
81cb0ef41Sopenharmony_ci#include "src/common/message-template.h"
91cb0ef41Sopenharmony_ci#include "src/execution/isolate-inl.h"
101cb0ef41Sopenharmony_ci#include "src/heap/heap-inl.h"
111cb0ef41Sopenharmony_ci#include "src/logging/runtime-call-stats-scope.h"
121cb0ef41Sopenharmony_ci#include "src/objects/api-callbacks.h"
131cb0ef41Sopenharmony_ci#include "src/objects/hash-table-inl.h"
141cb0ef41Sopenharmony_ci#include "src/objects/lookup.h"
151cb0ef41Sopenharmony_ci#include "src/objects/property-cell.h"
161cb0ef41Sopenharmony_ci#include "src/objects/templates.h"
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_cinamespace v8 {
191cb0ef41Sopenharmony_cinamespace internal {
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_cinamespace {
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ciclass V8_NODISCARD InvokeScope {
241cb0ef41Sopenharmony_ci public:
251cb0ef41Sopenharmony_ci  explicit InvokeScope(Isolate* isolate)
261cb0ef41Sopenharmony_ci      : isolate_(isolate), save_context_(isolate) {}
271cb0ef41Sopenharmony_ci  ~InvokeScope() {
281cb0ef41Sopenharmony_ci    bool has_exception = isolate_->has_pending_exception();
291cb0ef41Sopenharmony_ci    if (has_exception) {
301cb0ef41Sopenharmony_ci      isolate_->ReportPendingMessages();
311cb0ef41Sopenharmony_ci    } else {
321cb0ef41Sopenharmony_ci      isolate_->clear_pending_message();
331cb0ef41Sopenharmony_ci    }
341cb0ef41Sopenharmony_ci  }
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci private:
371cb0ef41Sopenharmony_ci  Isolate* isolate_;
381cb0ef41Sopenharmony_ci  SaveContext save_context_;
391cb0ef41Sopenharmony_ci};
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ciMaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
421cb0ef41Sopenharmony_ci                                        Handle<ObjectTemplateInfo> data,
431cb0ef41Sopenharmony_ci                                        Handle<JSReceiver> new_target,
441cb0ef41Sopenharmony_ci                                        bool is_prototype);
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ciMaybeHandle<JSFunction> InstantiateFunction(
471cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<NativeContext> native_context,
481cb0ef41Sopenharmony_ci    Handle<FunctionTemplateInfo> data,
491cb0ef41Sopenharmony_ci    MaybeHandle<Name> maybe_name = MaybeHandle<Name>());
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ciMaybeHandle<JSFunction> InstantiateFunction(
521cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<FunctionTemplateInfo> data,
531cb0ef41Sopenharmony_ci    MaybeHandle<Name> maybe_name = MaybeHandle<Name>()) {
541cb0ef41Sopenharmony_ci  return InstantiateFunction(isolate, isolate->native_context(), data,
551cb0ef41Sopenharmony_ci                             maybe_name);
561cb0ef41Sopenharmony_ci}
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ciMaybeHandle<Object> Instantiate(
591cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<Object> data,
601cb0ef41Sopenharmony_ci    MaybeHandle<Name> maybe_name = MaybeHandle<Name>()) {
611cb0ef41Sopenharmony_ci  if (data->IsFunctionTemplateInfo()) {
621cb0ef41Sopenharmony_ci    return InstantiateFunction(
631cb0ef41Sopenharmony_ci        isolate, Handle<FunctionTemplateInfo>::cast(data), maybe_name);
641cb0ef41Sopenharmony_ci  } else if (data->IsObjectTemplateInfo()) {
651cb0ef41Sopenharmony_ci    return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data),
661cb0ef41Sopenharmony_ci                             Handle<JSReceiver>(), false);
671cb0ef41Sopenharmony_ci  } else {
681cb0ef41Sopenharmony_ci    return data;
691cb0ef41Sopenharmony_ci  }
701cb0ef41Sopenharmony_ci}
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ciMaybeHandle<Object> DefineAccessorProperty(Isolate* isolate,
731cb0ef41Sopenharmony_ci                                           Handle<JSObject> object,
741cb0ef41Sopenharmony_ci                                           Handle<Name> name,
751cb0ef41Sopenharmony_ci                                           Handle<Object> getter,
761cb0ef41Sopenharmony_ci                                           Handle<Object> setter,
771cb0ef41Sopenharmony_ci                                           PropertyAttributes attributes) {
781cb0ef41Sopenharmony_ci  DCHECK(!getter->IsFunctionTemplateInfo() ||
791cb0ef41Sopenharmony_ci         FunctionTemplateInfo::cast(*getter).should_cache());
801cb0ef41Sopenharmony_ci  DCHECK(!setter->IsFunctionTemplateInfo() ||
811cb0ef41Sopenharmony_ci         FunctionTemplateInfo::cast(*setter).should_cache());
821cb0ef41Sopenharmony_ci  if (getter->IsFunctionTemplateInfo() &&
831cb0ef41Sopenharmony_ci      FunctionTemplateInfo::cast(*getter).BreakAtEntry()) {
841cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION(
851cb0ef41Sopenharmony_ci        isolate, getter,
861cb0ef41Sopenharmony_ci        InstantiateFunction(isolate,
871cb0ef41Sopenharmony_ci                            Handle<FunctionTemplateInfo>::cast(getter)),
881cb0ef41Sopenharmony_ci        Object);
891cb0ef41Sopenharmony_ci  }
901cb0ef41Sopenharmony_ci  if (setter->IsFunctionTemplateInfo() &&
911cb0ef41Sopenharmony_ci      FunctionTemplateInfo::cast(*setter).BreakAtEntry()) {
921cb0ef41Sopenharmony_ci    ASSIGN_RETURN_ON_EXCEPTION(
931cb0ef41Sopenharmony_ci        isolate, setter,
941cb0ef41Sopenharmony_ci        InstantiateFunction(isolate,
951cb0ef41Sopenharmony_ci                            Handle<FunctionTemplateInfo>::cast(setter)),
961cb0ef41Sopenharmony_ci        Object);
971cb0ef41Sopenharmony_ci  }
981cb0ef41Sopenharmony_ci  RETURN_ON_EXCEPTION(
991cb0ef41Sopenharmony_ci      isolate,
1001cb0ef41Sopenharmony_ci      JSObject::DefineAccessor(object, name, getter, setter, attributes),
1011cb0ef41Sopenharmony_ci      Object);
1021cb0ef41Sopenharmony_ci  return object;
1031cb0ef41Sopenharmony_ci}
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ciMaybeHandle<Object> DefineDataProperty(Isolate* isolate,
1061cb0ef41Sopenharmony_ci                                       Handle<JSObject> object,
1071cb0ef41Sopenharmony_ci                                       Handle<Name> name,
1081cb0ef41Sopenharmony_ci                                       Handle<Object> prop_data,
1091cb0ef41Sopenharmony_ci                                       PropertyAttributes attributes) {
1101cb0ef41Sopenharmony_ci  Handle<Object> value;
1111cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
1121cb0ef41Sopenharmony_ci                             Instantiate(isolate, prop_data, name), Object);
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci  PropertyKey key(isolate, name);
1151cb0ef41Sopenharmony_ci  LookupIterator it(isolate, object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci#ifdef DEBUG
1181cb0ef41Sopenharmony_ci  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
1191cb0ef41Sopenharmony_ci  DCHECK(maybe.IsJust());
1201cb0ef41Sopenharmony_ci  if (it.IsFound()) {
1211cb0ef41Sopenharmony_ci    THROW_NEW_ERROR(
1221cb0ef41Sopenharmony_ci        isolate,
1231cb0ef41Sopenharmony_ci        NewTypeError(MessageTemplate::kDuplicateTemplateProperty, name),
1241cb0ef41Sopenharmony_ci        Object);
1251cb0ef41Sopenharmony_ci  }
1261cb0ef41Sopenharmony_ci#endif
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  MAYBE_RETURN_NULL(Object::AddDataProperty(&it, value, attributes,
1291cb0ef41Sopenharmony_ci                                            Just(ShouldThrow::kThrowOnError),
1301cb0ef41Sopenharmony_ci                                            StoreOrigin::kNamed));
1311cb0ef41Sopenharmony_ci  return value;
1321cb0ef41Sopenharmony_ci}
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_civoid DisableAccessChecks(Isolate* isolate, Handle<JSObject> object) {
1351cb0ef41Sopenharmony_ci  Handle<Map> old_map(object->map(), isolate);
1361cb0ef41Sopenharmony_ci  // Copy map so it won't interfere constructor's initial map.
1371cb0ef41Sopenharmony_ci  Handle<Map> new_map = Map::Copy(isolate, old_map, "DisableAccessChecks");
1381cb0ef41Sopenharmony_ci  new_map->set_is_access_check_needed(false);
1391cb0ef41Sopenharmony_ci  JSObject::MigrateToMap(isolate, Handle<JSObject>::cast(object), new_map);
1401cb0ef41Sopenharmony_ci}
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_civoid EnableAccessChecks(Isolate* isolate, Handle<JSObject> object) {
1431cb0ef41Sopenharmony_ci  Handle<Map> old_map(object->map(), isolate);
1441cb0ef41Sopenharmony_ci  // Copy map so it won't interfere constructor's initial map.
1451cb0ef41Sopenharmony_ci  Handle<Map> new_map = Map::Copy(isolate, old_map, "EnableAccessChecks");
1461cb0ef41Sopenharmony_ci  new_map->set_is_access_check_needed(true);
1471cb0ef41Sopenharmony_ci  new_map->set_may_have_interesting_symbols(true);
1481cb0ef41Sopenharmony_ci  JSObject::MigrateToMap(isolate, object, new_map);
1491cb0ef41Sopenharmony_ci}
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ciclass V8_NODISCARD AccessCheckDisableScope {
1521cb0ef41Sopenharmony_ci public:
1531cb0ef41Sopenharmony_ci  AccessCheckDisableScope(Isolate* isolate, Handle<JSObject> obj)
1541cb0ef41Sopenharmony_ci      : isolate_(isolate),
1551cb0ef41Sopenharmony_ci        disabled_(obj->map().is_access_check_needed()),
1561cb0ef41Sopenharmony_ci        obj_(obj) {
1571cb0ef41Sopenharmony_ci    if (disabled_) {
1581cb0ef41Sopenharmony_ci      DisableAccessChecks(isolate_, obj_);
1591cb0ef41Sopenharmony_ci    }
1601cb0ef41Sopenharmony_ci  }
1611cb0ef41Sopenharmony_ci  ~AccessCheckDisableScope() {
1621cb0ef41Sopenharmony_ci    if (disabled_) {
1631cb0ef41Sopenharmony_ci      EnableAccessChecks(isolate_, obj_);
1641cb0ef41Sopenharmony_ci    }
1651cb0ef41Sopenharmony_ci  }
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci private:
1681cb0ef41Sopenharmony_ci  Isolate* isolate_;
1691cb0ef41Sopenharmony_ci  const bool disabled_;
1701cb0ef41Sopenharmony_ci  Handle<JSObject> obj_;
1711cb0ef41Sopenharmony_ci};
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ciObject GetIntrinsic(Isolate* isolate, v8::Intrinsic intrinsic) {
1741cb0ef41Sopenharmony_ci  Handle<Context> native_context = isolate->native_context();
1751cb0ef41Sopenharmony_ci  DCHECK(!native_context.is_null());
1761cb0ef41Sopenharmony_ci  switch (intrinsic) {
1771cb0ef41Sopenharmony_ci#define GET_INTRINSIC_VALUE(name, iname) \
1781cb0ef41Sopenharmony_ci  case v8::k##name:                      \
1791cb0ef41Sopenharmony_ci    return native_context->iname();
1801cb0ef41Sopenharmony_ci    V8_INTRINSICS_LIST(GET_INTRINSIC_VALUE)
1811cb0ef41Sopenharmony_ci#undef GET_INTRINSIC_VALUE
1821cb0ef41Sopenharmony_ci  }
1831cb0ef41Sopenharmony_ci  return Object();
1841cb0ef41Sopenharmony_ci}
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_citemplate <typename TemplateInfoT>
1871cb0ef41Sopenharmony_ciMaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj,
1881cb0ef41Sopenharmony_ci                                        Handle<TemplateInfoT> data) {
1891cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kConfigureInstance);
1901cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
1911cb0ef41Sopenharmony_ci  // Disable access checks while instantiating the object.
1921cb0ef41Sopenharmony_ci  AccessCheckDisableScope access_check_scope(isolate, obj);
1931cb0ef41Sopenharmony_ci
1941cb0ef41Sopenharmony_ci  // Walk the inheritance chain and copy all accessors to current object.
1951cb0ef41Sopenharmony_ci  int max_number_of_properties = 0;
1961cb0ef41Sopenharmony_ci  TemplateInfoT info = *data;
1971cb0ef41Sopenharmony_ci  while (!info.is_null()) {
1981cb0ef41Sopenharmony_ci    Object props = info.property_accessors();
1991cb0ef41Sopenharmony_ci    if (!props.IsUndefined(isolate)) {
2001cb0ef41Sopenharmony_ci      max_number_of_properties += TemplateList::cast(props).length();
2011cb0ef41Sopenharmony_ci    }
2021cb0ef41Sopenharmony_ci    info = info.GetParent(isolate);
2031cb0ef41Sopenharmony_ci  }
2041cb0ef41Sopenharmony_ci
2051cb0ef41Sopenharmony_ci  if (max_number_of_properties > 0) {
2061cb0ef41Sopenharmony_ci    int valid_descriptors = 0;
2071cb0ef41Sopenharmony_ci    // Use a temporary FixedArray to accumulate unique accessors.
2081cb0ef41Sopenharmony_ci    Handle<FixedArray> array =
2091cb0ef41Sopenharmony_ci        isolate->factory()->NewFixedArray(max_number_of_properties);
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_ci    for (Handle<TemplateInfoT> temp(*data, isolate); !temp->is_null();
2121cb0ef41Sopenharmony_ci         temp = handle(temp->GetParent(isolate), isolate)) {
2131cb0ef41Sopenharmony_ci      // Accumulate accessors.
2141cb0ef41Sopenharmony_ci      Object maybe_properties = temp->property_accessors();
2151cb0ef41Sopenharmony_ci      if (!maybe_properties.IsUndefined(isolate)) {
2161cb0ef41Sopenharmony_ci        valid_descriptors = AccessorInfo::AppendUnique(
2171cb0ef41Sopenharmony_ci            isolate, handle(maybe_properties, isolate), array,
2181cb0ef41Sopenharmony_ci            valid_descriptors);
2191cb0ef41Sopenharmony_ci      }
2201cb0ef41Sopenharmony_ci    }
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_ci    // Install accumulated accessors.
2231cb0ef41Sopenharmony_ci    for (int i = 0; i < valid_descriptors; i++) {
2241cb0ef41Sopenharmony_ci      Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i)), isolate);
2251cb0ef41Sopenharmony_ci      Handle<Name> name(Name::cast(accessor->name()), isolate);
2261cb0ef41Sopenharmony_ci      JSObject::SetAccessor(obj, name, accessor,
2271cb0ef41Sopenharmony_ci                            accessor->initial_property_attributes())
2281cb0ef41Sopenharmony_ci          .Assert();
2291cb0ef41Sopenharmony_ci    }
2301cb0ef41Sopenharmony_ci  }
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci  Object maybe_property_list = data->property_list();
2331cb0ef41Sopenharmony_ci  if (maybe_property_list.IsUndefined(isolate)) return obj;
2341cb0ef41Sopenharmony_ci  Handle<TemplateList> properties(TemplateList::cast(maybe_property_list),
2351cb0ef41Sopenharmony_ci                                  isolate);
2361cb0ef41Sopenharmony_ci  if (properties->length() == 0) return obj;
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_ci  int i = 0;
2391cb0ef41Sopenharmony_ci  for (int c = 0; c < data->number_of_properties(); c++) {
2401cb0ef41Sopenharmony_ci    auto name = handle(Name::cast(properties->get(i++)), isolate);
2411cb0ef41Sopenharmony_ci    Object bit = properties->get(i++);
2421cb0ef41Sopenharmony_ci    if (bit.IsSmi()) {
2431cb0ef41Sopenharmony_ci      PropertyDetails details(Smi::cast(bit));
2441cb0ef41Sopenharmony_ci      PropertyAttributes attributes = details.attributes();
2451cb0ef41Sopenharmony_ci      PropertyKind kind = details.kind();
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci      if (kind == PropertyKind::kData) {
2481cb0ef41Sopenharmony_ci        auto prop_data = handle(properties->get(i++), isolate);
2491cb0ef41Sopenharmony_ci        RETURN_ON_EXCEPTION(
2501cb0ef41Sopenharmony_ci            isolate,
2511cb0ef41Sopenharmony_ci            DefineDataProperty(isolate, obj, name, prop_data, attributes),
2521cb0ef41Sopenharmony_ci            JSObject);
2531cb0ef41Sopenharmony_ci      } else {
2541cb0ef41Sopenharmony_ci        auto getter = handle(properties->get(i++), isolate);
2551cb0ef41Sopenharmony_ci        auto setter = handle(properties->get(i++), isolate);
2561cb0ef41Sopenharmony_ci        RETURN_ON_EXCEPTION(isolate,
2571cb0ef41Sopenharmony_ci                            DefineAccessorProperty(isolate, obj, name, getter,
2581cb0ef41Sopenharmony_ci                                                   setter, attributes),
2591cb0ef41Sopenharmony_ci                            JSObject);
2601cb0ef41Sopenharmony_ci      }
2611cb0ef41Sopenharmony_ci    } else {
2621cb0ef41Sopenharmony_ci      // Intrinsic data property --- Get appropriate value from the current
2631cb0ef41Sopenharmony_ci      // context.
2641cb0ef41Sopenharmony_ci      PropertyDetails details(Smi::cast(properties->get(i++)));
2651cb0ef41Sopenharmony_ci      PropertyAttributes attributes = details.attributes();
2661cb0ef41Sopenharmony_ci      DCHECK_EQ(PropertyKind::kData, details.kind());
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci      v8::Intrinsic intrinsic =
2691cb0ef41Sopenharmony_ci          static_cast<v8::Intrinsic>(Smi::ToInt(properties->get(i++)));
2701cb0ef41Sopenharmony_ci      auto prop_data = handle(GetIntrinsic(isolate, intrinsic), isolate);
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ci      RETURN_ON_EXCEPTION(
2731cb0ef41Sopenharmony_ci          isolate,
2741cb0ef41Sopenharmony_ci          DefineDataProperty(isolate, obj, name, prop_data, attributes),
2751cb0ef41Sopenharmony_ci          JSObject);
2761cb0ef41Sopenharmony_ci    }
2771cb0ef41Sopenharmony_ci  }
2781cb0ef41Sopenharmony_ci  return obj;
2791cb0ef41Sopenharmony_ci}
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci// Whether or not to cache every instance: when we materialize a getter or
2821cb0ef41Sopenharmony_ci// setter from an lazy AccessorPair, we rely on this cache to be able to always
2831cb0ef41Sopenharmony_ci// return the same getter or setter. However, objects will be cloned anyways,
2841cb0ef41Sopenharmony_ci// so it's not observable if we didn't cache an instance. Furthermore, a badly
2851cb0ef41Sopenharmony_ci// behaved embedder might create an unlimited number of objects, so we limit
2861cb0ef41Sopenharmony_ci// the cache for those cases.
2871cb0ef41Sopenharmony_cienum class CachingMode { kLimited, kUnlimited };
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ciMaybeHandle<JSObject> ProbeInstantiationsCache(
2901cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<NativeContext> native_context, int serial_number,
2911cb0ef41Sopenharmony_ci    CachingMode caching_mode) {
2921cb0ef41Sopenharmony_ci  DCHECK_NE(serial_number, TemplateInfo::kDoNotCache);
2931cb0ef41Sopenharmony_ci  if (serial_number == TemplateInfo::kUncached) {
2941cb0ef41Sopenharmony_ci    return {};
2951cb0ef41Sopenharmony_ci  }
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci  if (serial_number < TemplateInfo::kFastTemplateInstantiationsCacheSize) {
2981cb0ef41Sopenharmony_ci    FixedArray fast_cache =
2991cb0ef41Sopenharmony_ci        native_context->fast_template_instantiations_cache();
3001cb0ef41Sopenharmony_ci    Handle<Object> object{fast_cache.get(serial_number), isolate};
3011cb0ef41Sopenharmony_ci    if (object->IsTheHole(isolate)) return {};
3021cb0ef41Sopenharmony_ci    return Handle<JSObject>::cast(object);
3031cb0ef41Sopenharmony_ci  }
3041cb0ef41Sopenharmony_ci  if (caching_mode == CachingMode::kUnlimited ||
3051cb0ef41Sopenharmony_ci      (serial_number < TemplateInfo::kSlowTemplateInstantiationsCacheSize)) {
3061cb0ef41Sopenharmony_ci    SimpleNumberDictionary slow_cache =
3071cb0ef41Sopenharmony_ci        native_context->slow_template_instantiations_cache();
3081cb0ef41Sopenharmony_ci    InternalIndex entry = slow_cache.FindEntry(isolate, serial_number);
3091cb0ef41Sopenharmony_ci    if (entry.is_found()) {
3101cb0ef41Sopenharmony_ci      return handle(JSObject::cast(slow_cache.ValueAt(entry)), isolate);
3111cb0ef41Sopenharmony_ci    }
3121cb0ef41Sopenharmony_ci  }
3131cb0ef41Sopenharmony_ci  return {};
3141cb0ef41Sopenharmony_ci}
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_civoid CacheTemplateInstantiation(Isolate* isolate,
3171cb0ef41Sopenharmony_ci                                Handle<NativeContext> native_context,
3181cb0ef41Sopenharmony_ci                                Handle<TemplateInfo> data,
3191cb0ef41Sopenharmony_ci                                CachingMode caching_mode,
3201cb0ef41Sopenharmony_ci                                Handle<JSObject> object) {
3211cb0ef41Sopenharmony_ci  DCHECK_NE(TemplateInfo::kDoNotCache, data->serial_number());
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci  int serial_number = data->serial_number();
3241cb0ef41Sopenharmony_ci  if (serial_number == TemplateInfo::kUncached) {
3251cb0ef41Sopenharmony_ci    serial_number = isolate->heap()->GetNextTemplateSerialNumber();
3261cb0ef41Sopenharmony_ci  }
3271cb0ef41Sopenharmony_ci
3281cb0ef41Sopenharmony_ci  if (serial_number < TemplateInfo::kFastTemplateInstantiationsCacheSize) {
3291cb0ef41Sopenharmony_ci    Handle<FixedArray> fast_cache =
3301cb0ef41Sopenharmony_ci        handle(native_context->fast_template_instantiations_cache(), isolate);
3311cb0ef41Sopenharmony_ci    Handle<FixedArray> new_cache =
3321cb0ef41Sopenharmony_ci        FixedArray::SetAndGrow(isolate, fast_cache, serial_number, object);
3331cb0ef41Sopenharmony_ci    if (*new_cache != *fast_cache) {
3341cb0ef41Sopenharmony_ci      native_context->set_fast_template_instantiations_cache(*new_cache);
3351cb0ef41Sopenharmony_ci    }
3361cb0ef41Sopenharmony_ci    data->set_serial_number(serial_number);
3371cb0ef41Sopenharmony_ci  } else if (caching_mode == CachingMode::kUnlimited ||
3381cb0ef41Sopenharmony_ci             (serial_number <
3391cb0ef41Sopenharmony_ci              TemplateInfo::kSlowTemplateInstantiationsCacheSize)) {
3401cb0ef41Sopenharmony_ci    Handle<SimpleNumberDictionary> cache =
3411cb0ef41Sopenharmony_ci        handle(native_context->slow_template_instantiations_cache(), isolate);
3421cb0ef41Sopenharmony_ci    auto new_cache =
3431cb0ef41Sopenharmony_ci        SimpleNumberDictionary::Set(isolate, cache, serial_number, object);
3441cb0ef41Sopenharmony_ci    if (*new_cache != *cache) {
3451cb0ef41Sopenharmony_ci      native_context->set_slow_template_instantiations_cache(*new_cache);
3461cb0ef41Sopenharmony_ci    }
3471cb0ef41Sopenharmony_ci    data->set_serial_number(serial_number);
3481cb0ef41Sopenharmony_ci  } else {
3491cb0ef41Sopenharmony_ci    // we've overflowed the cache limit, no more caching
3501cb0ef41Sopenharmony_ci    data->set_serial_number(TemplateInfo::kDoNotCache);
3511cb0ef41Sopenharmony_ci  }
3521cb0ef41Sopenharmony_ci}
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_civoid UncacheTemplateInstantiation(Isolate* isolate,
3551cb0ef41Sopenharmony_ci                                  Handle<NativeContext> native_context,
3561cb0ef41Sopenharmony_ci                                  Handle<TemplateInfo> data,
3571cb0ef41Sopenharmony_ci                                  CachingMode caching_mode) {
3581cb0ef41Sopenharmony_ci  int serial_number = data->serial_number();
3591cb0ef41Sopenharmony_ci  if (serial_number < 0) return;
3601cb0ef41Sopenharmony_ci
3611cb0ef41Sopenharmony_ci  if (serial_number < TemplateInfo::kFastTemplateInstantiationsCacheSize) {
3621cb0ef41Sopenharmony_ci    FixedArray fast_cache =
3631cb0ef41Sopenharmony_ci        native_context->fast_template_instantiations_cache();
3641cb0ef41Sopenharmony_ci    DCHECK(!fast_cache.get(serial_number).IsUndefined(isolate));
3651cb0ef41Sopenharmony_ci    fast_cache.set_undefined(serial_number);
3661cb0ef41Sopenharmony_ci    data->set_serial_number(TemplateInfo::kUncached);
3671cb0ef41Sopenharmony_ci  } else if (caching_mode == CachingMode::kUnlimited ||
3681cb0ef41Sopenharmony_ci             (serial_number <
3691cb0ef41Sopenharmony_ci              TemplateInfo::kSlowTemplateInstantiationsCacheSize)) {
3701cb0ef41Sopenharmony_ci    Handle<SimpleNumberDictionary> cache =
3711cb0ef41Sopenharmony_ci        handle(native_context->slow_template_instantiations_cache(), isolate);
3721cb0ef41Sopenharmony_ci    InternalIndex entry = cache->FindEntry(isolate, serial_number);
3731cb0ef41Sopenharmony_ci    DCHECK(entry.is_found());
3741cb0ef41Sopenharmony_ci    cache = SimpleNumberDictionary::DeleteEntry(isolate, cache, entry);
3751cb0ef41Sopenharmony_ci    native_context->set_slow_template_instantiations_cache(*cache);
3761cb0ef41Sopenharmony_ci    data->set_serial_number(TemplateInfo::kUncached);
3771cb0ef41Sopenharmony_ci  }
3781cb0ef41Sopenharmony_ci}
3791cb0ef41Sopenharmony_ci
3801cb0ef41Sopenharmony_cibool IsSimpleInstantiation(Isolate* isolate, ObjectTemplateInfo info,
3811cb0ef41Sopenharmony_ci                           JSReceiver new_target) {
3821cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
3831cb0ef41Sopenharmony_ci
3841cb0ef41Sopenharmony_ci  if (!new_target.IsJSFunction()) return false;
3851cb0ef41Sopenharmony_ci  JSFunction fun = JSFunction::cast(new_target);
3861cb0ef41Sopenharmony_ci  if (fun.shared().function_data(kAcquireLoad) != info.constructor())
3871cb0ef41Sopenharmony_ci    return false;
3881cb0ef41Sopenharmony_ci  if (info.immutable_proto()) return false;
3891cb0ef41Sopenharmony_ci  return fun.native_context() == isolate->raw_native_context();
3901cb0ef41Sopenharmony_ci}
3911cb0ef41Sopenharmony_ci
3921cb0ef41Sopenharmony_ciMaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
3931cb0ef41Sopenharmony_ci                                        Handle<ObjectTemplateInfo> info,
3941cb0ef41Sopenharmony_ci                                        Handle<JSReceiver> new_target,
3951cb0ef41Sopenharmony_ci                                        bool is_prototype) {
3961cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kInstantiateObject);
3971cb0ef41Sopenharmony_ci  Handle<JSFunction> constructor;
3981cb0ef41Sopenharmony_ci  bool should_cache = info->should_cache();
3991cb0ef41Sopenharmony_ci  if (!new_target.is_null()) {
4001cb0ef41Sopenharmony_ci    if (IsSimpleInstantiation(isolate, *info, *new_target)) {
4011cb0ef41Sopenharmony_ci      constructor = Handle<JSFunction>::cast(new_target);
4021cb0ef41Sopenharmony_ci    } else {
4031cb0ef41Sopenharmony_ci      // Disable caching for subclass instantiation.
4041cb0ef41Sopenharmony_ci      should_cache = false;
4051cb0ef41Sopenharmony_ci    }
4061cb0ef41Sopenharmony_ci  }
4071cb0ef41Sopenharmony_ci  // Fast path.
4081cb0ef41Sopenharmony_ci  Handle<JSObject> result;
4091cb0ef41Sopenharmony_ci  if (should_cache && info->is_cached()) {
4101cb0ef41Sopenharmony_ci    if (ProbeInstantiationsCache(isolate, isolate->native_context(),
4111cb0ef41Sopenharmony_ci                                 info->serial_number(), CachingMode::kLimited)
4121cb0ef41Sopenharmony_ci            .ToHandle(&result)) {
4131cb0ef41Sopenharmony_ci      return isolate->factory()->CopyJSObject(result);
4141cb0ef41Sopenharmony_ci    }
4151cb0ef41Sopenharmony_ci  }
4161cb0ef41Sopenharmony_ci
4171cb0ef41Sopenharmony_ci  if (constructor.is_null()) {
4181cb0ef41Sopenharmony_ci    Object maybe_constructor_info = info->constructor();
4191cb0ef41Sopenharmony_ci    if (maybe_constructor_info.IsUndefined(isolate)) {
4201cb0ef41Sopenharmony_ci      constructor = isolate->object_function();
4211cb0ef41Sopenharmony_ci    } else {
4221cb0ef41Sopenharmony_ci      // Enter a new scope.  Recursion could otherwise create a lot of handles.
4231cb0ef41Sopenharmony_ci      HandleScope scope(isolate);
4241cb0ef41Sopenharmony_ci      Handle<FunctionTemplateInfo> cons_templ(
4251cb0ef41Sopenharmony_ci          FunctionTemplateInfo::cast(maybe_constructor_info), isolate);
4261cb0ef41Sopenharmony_ci      Handle<JSFunction> tmp_constructor;
4271cb0ef41Sopenharmony_ci      ASSIGN_RETURN_ON_EXCEPTION(isolate, tmp_constructor,
4281cb0ef41Sopenharmony_ci                                 InstantiateFunction(isolate, cons_templ),
4291cb0ef41Sopenharmony_ci                                 JSObject);
4301cb0ef41Sopenharmony_ci      constructor = scope.CloseAndEscape(tmp_constructor);
4311cb0ef41Sopenharmony_ci    }
4321cb0ef41Sopenharmony_ci
4331cb0ef41Sopenharmony_ci    if (new_target.is_null()) new_target = constructor;
4341cb0ef41Sopenharmony_ci  }
4351cb0ef41Sopenharmony_ci
4361cb0ef41Sopenharmony_ci  Handle<JSObject> object;
4371cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION(
4381cb0ef41Sopenharmony_ci      isolate, object,
4391cb0ef41Sopenharmony_ci      JSObject::New(constructor, new_target, Handle<AllocationSite>::null()),
4401cb0ef41Sopenharmony_ci      JSObject);
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci  if (is_prototype) JSObject::OptimizeAsPrototype(object);
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION(
4451cb0ef41Sopenharmony_ci      isolate, result, ConfigureInstance(isolate, object, info), JSObject);
4461cb0ef41Sopenharmony_ci  if (info->immutable_proto()) {
4471cb0ef41Sopenharmony_ci    JSObject::SetImmutableProto(object);
4481cb0ef41Sopenharmony_ci  }
4491cb0ef41Sopenharmony_ci  if (!is_prototype) {
4501cb0ef41Sopenharmony_ci    // Keep prototypes in slow-mode. Let them be lazily turned fast later on.
4511cb0ef41Sopenharmony_ci    // TODO(dcarney): is this necessary?
4521cb0ef41Sopenharmony_ci    JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject");
4531cb0ef41Sopenharmony_ci    // Don't cache prototypes.
4541cb0ef41Sopenharmony_ci    if (should_cache) {
4551cb0ef41Sopenharmony_ci      CacheTemplateInstantiation(isolate, isolate->native_context(), info,
4561cb0ef41Sopenharmony_ci                                 CachingMode::kLimited, result);
4571cb0ef41Sopenharmony_ci      result = isolate->factory()->CopyJSObject(result);
4581cb0ef41Sopenharmony_ci    }
4591cb0ef41Sopenharmony_ci  }
4601cb0ef41Sopenharmony_ci
4611cb0ef41Sopenharmony_ci  return result;
4621cb0ef41Sopenharmony_ci}
4631cb0ef41Sopenharmony_ci
4641cb0ef41Sopenharmony_cinamespace {
4651cb0ef41Sopenharmony_ciMaybeHandle<Object> GetInstancePrototype(Isolate* isolate,
4661cb0ef41Sopenharmony_ci                                         Handle<Object> function_template) {
4671cb0ef41Sopenharmony_ci  // Enter a new scope.  Recursion could otherwise create a lot of handles.
4681cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
4691cb0ef41Sopenharmony_ci  Handle<JSFunction> parent_instance;
4701cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION(
4711cb0ef41Sopenharmony_ci      isolate, parent_instance,
4721cb0ef41Sopenharmony_ci      InstantiateFunction(
4731cb0ef41Sopenharmony_ci          isolate, Handle<FunctionTemplateInfo>::cast(function_template)),
4741cb0ef41Sopenharmony_ci      JSFunction);
4751cb0ef41Sopenharmony_ci  Handle<Object> instance_prototype;
4761cb0ef41Sopenharmony_ci  // TODO(cbruni): decide what to do here.
4771cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION(
4781cb0ef41Sopenharmony_ci      isolate, instance_prototype,
4791cb0ef41Sopenharmony_ci      JSObject::GetProperty(isolate, parent_instance,
4801cb0ef41Sopenharmony_ci                            isolate->factory()->prototype_string()),
4811cb0ef41Sopenharmony_ci      JSFunction);
4821cb0ef41Sopenharmony_ci  return scope.CloseAndEscape(instance_prototype);
4831cb0ef41Sopenharmony_ci}
4841cb0ef41Sopenharmony_ci}  // namespace
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ciMaybeHandle<JSFunction> InstantiateFunction(
4871cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<NativeContext> native_context,
4881cb0ef41Sopenharmony_ci    Handle<FunctionTemplateInfo> data, MaybeHandle<Name> maybe_name) {
4891cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kInstantiateFunction);
4901cb0ef41Sopenharmony_ci  bool should_cache = data->should_cache();
4911cb0ef41Sopenharmony_ci  if (should_cache && data->is_cached()) {
4921cb0ef41Sopenharmony_ci    Handle<JSObject> result;
4931cb0ef41Sopenharmony_ci    if (ProbeInstantiationsCache(isolate, native_context, data->serial_number(),
4941cb0ef41Sopenharmony_ci                                 CachingMode::kUnlimited)
4951cb0ef41Sopenharmony_ci            .ToHandle(&result)) {
4961cb0ef41Sopenharmony_ci      return Handle<JSFunction>::cast(result);
4971cb0ef41Sopenharmony_ci    }
4981cb0ef41Sopenharmony_ci  }
4991cb0ef41Sopenharmony_ci  Handle<Object> prototype;
5001cb0ef41Sopenharmony_ci  if (!data->remove_prototype()) {
5011cb0ef41Sopenharmony_ci    Handle<Object> prototype_templ(data->GetPrototypeTemplate(), isolate);
5021cb0ef41Sopenharmony_ci    if (prototype_templ->IsUndefined(isolate)) {
5031cb0ef41Sopenharmony_ci      Handle<Object> protoype_provider_templ(
5041cb0ef41Sopenharmony_ci          data->GetPrototypeProviderTemplate(), isolate);
5051cb0ef41Sopenharmony_ci      if (protoype_provider_templ->IsUndefined(isolate)) {
5061cb0ef41Sopenharmony_ci        prototype = isolate->factory()->NewJSObject(isolate->object_function());
5071cb0ef41Sopenharmony_ci      } else {
5081cb0ef41Sopenharmony_ci        ASSIGN_RETURN_ON_EXCEPTION(
5091cb0ef41Sopenharmony_ci            isolate, prototype,
5101cb0ef41Sopenharmony_ci            GetInstancePrototype(isolate, protoype_provider_templ), JSFunction);
5111cb0ef41Sopenharmony_ci      }
5121cb0ef41Sopenharmony_ci    } else {
5131cb0ef41Sopenharmony_ci      ASSIGN_RETURN_ON_EXCEPTION(
5141cb0ef41Sopenharmony_ci          isolate, prototype,
5151cb0ef41Sopenharmony_ci          InstantiateObject(isolate,
5161cb0ef41Sopenharmony_ci                            Handle<ObjectTemplateInfo>::cast(prototype_templ),
5171cb0ef41Sopenharmony_ci                            Handle<JSReceiver>(), true),
5181cb0ef41Sopenharmony_ci          JSFunction);
5191cb0ef41Sopenharmony_ci    }
5201cb0ef41Sopenharmony_ci    Handle<Object> parent(data->GetParentTemplate(), isolate);
5211cb0ef41Sopenharmony_ci    if (!parent->IsUndefined(isolate)) {
5221cb0ef41Sopenharmony_ci      Handle<Object> parent_prototype;
5231cb0ef41Sopenharmony_ci      ASSIGN_RETURN_ON_EXCEPTION(isolate, parent_prototype,
5241cb0ef41Sopenharmony_ci                                 GetInstancePrototype(isolate, parent),
5251cb0ef41Sopenharmony_ci                                 JSFunction);
5261cb0ef41Sopenharmony_ci      CHECK(parent_prototype->IsHeapObject());
5271cb0ef41Sopenharmony_ci      JSObject::ForceSetPrototype(isolate, Handle<JSObject>::cast(prototype),
5281cb0ef41Sopenharmony_ci                                  Handle<HeapObject>::cast(parent_prototype));
5291cb0ef41Sopenharmony_ci    }
5301cb0ef41Sopenharmony_ci  }
5311cb0ef41Sopenharmony_ci  InstanceType function_type = JS_SPECIAL_API_OBJECT_TYPE;
5321cb0ef41Sopenharmony_ci  if (!data->needs_access_check() &&
5331cb0ef41Sopenharmony_ci      data->GetNamedPropertyHandler().IsUndefined(isolate) &&
5341cb0ef41Sopenharmony_ci      data->GetIndexedPropertyHandler().IsUndefined(isolate)) {
5351cb0ef41Sopenharmony_ci    function_type = FLAG_embedder_instance_types && data->HasInstanceType()
5361cb0ef41Sopenharmony_ci                        ? static_cast<InstanceType>(data->InstanceType())
5371cb0ef41Sopenharmony_ci                        : JS_API_OBJECT_TYPE;
5381cb0ef41Sopenharmony_ci  }
5391cb0ef41Sopenharmony_ci
5401cb0ef41Sopenharmony_ci  Handle<JSFunction> function = ApiNatives::CreateApiFunction(
5411cb0ef41Sopenharmony_ci      isolate, native_context, data, prototype, function_type, maybe_name);
5421cb0ef41Sopenharmony_ci  if (should_cache) {
5431cb0ef41Sopenharmony_ci    // Cache the function.
5441cb0ef41Sopenharmony_ci    CacheTemplateInstantiation(isolate, native_context, data,
5451cb0ef41Sopenharmony_ci                               CachingMode::kUnlimited, function);
5461cb0ef41Sopenharmony_ci  }
5471cb0ef41Sopenharmony_ci  MaybeHandle<JSObject> result = ConfigureInstance(isolate, function, data);
5481cb0ef41Sopenharmony_ci  if (result.is_null()) {
5491cb0ef41Sopenharmony_ci    // Uncache on error.
5501cb0ef41Sopenharmony_ci    UncacheTemplateInstantiation(isolate, native_context, data,
5511cb0ef41Sopenharmony_ci                                 CachingMode::kUnlimited);
5521cb0ef41Sopenharmony_ci    return MaybeHandle<JSFunction>();
5531cb0ef41Sopenharmony_ci  }
5541cb0ef41Sopenharmony_ci  data->set_published(true);
5551cb0ef41Sopenharmony_ci  return function;
5561cb0ef41Sopenharmony_ci}
5571cb0ef41Sopenharmony_ci
5581cb0ef41Sopenharmony_civoid AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ,
5591cb0ef41Sopenharmony_ci                               int length, Handle<Object>* data) {
5601cb0ef41Sopenharmony_ci  Object maybe_list = templ->property_list();
5611cb0ef41Sopenharmony_ci  Handle<TemplateList> list;
5621cb0ef41Sopenharmony_ci  if (maybe_list.IsUndefined(isolate)) {
5631cb0ef41Sopenharmony_ci    list = TemplateList::New(isolate, length);
5641cb0ef41Sopenharmony_ci  } else {
5651cb0ef41Sopenharmony_ci    list = handle(TemplateList::cast(maybe_list), isolate);
5661cb0ef41Sopenharmony_ci  }
5671cb0ef41Sopenharmony_ci  templ->set_number_of_properties(templ->number_of_properties() + 1);
5681cb0ef41Sopenharmony_ci  for (int i = 0; i < length; i++) {
5691cb0ef41Sopenharmony_ci    Handle<Object> value =
5701cb0ef41Sopenharmony_ci        data[i].is_null()
5711cb0ef41Sopenharmony_ci            ? Handle<Object>::cast(isolate->factory()->undefined_value())
5721cb0ef41Sopenharmony_ci            : data[i];
5731cb0ef41Sopenharmony_ci    list = TemplateList::Add(isolate, list, value);
5741cb0ef41Sopenharmony_ci  }
5751cb0ef41Sopenharmony_ci  templ->set_property_list(*list);
5761cb0ef41Sopenharmony_ci}
5771cb0ef41Sopenharmony_ci
5781cb0ef41Sopenharmony_ci}  // namespace
5791cb0ef41Sopenharmony_ci
5801cb0ef41Sopenharmony_ciMaybeHandle<JSFunction> ApiNatives::InstantiateFunction(
5811cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<NativeContext> native_context,
5821cb0ef41Sopenharmony_ci    Handle<FunctionTemplateInfo> data, MaybeHandle<Name> maybe_name) {
5831cb0ef41Sopenharmony_ci  InvokeScope invoke_scope(isolate);
5841cb0ef41Sopenharmony_ci  return ::v8::internal::InstantiateFunction(isolate, native_context, data,
5851cb0ef41Sopenharmony_ci                                             maybe_name);
5861cb0ef41Sopenharmony_ci}
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_ciMaybeHandle<JSFunction> ApiNatives::InstantiateFunction(
5891cb0ef41Sopenharmony_ci    Handle<FunctionTemplateInfo> data, MaybeHandle<Name> maybe_name) {
5901cb0ef41Sopenharmony_ci  Isolate* isolate = data->GetIsolate();
5911cb0ef41Sopenharmony_ci  InvokeScope invoke_scope(isolate);
5921cb0ef41Sopenharmony_ci  return ::v8::internal::InstantiateFunction(isolate, data, maybe_name);
5931cb0ef41Sopenharmony_ci}
5941cb0ef41Sopenharmony_ci
5951cb0ef41Sopenharmony_ciMaybeHandle<JSObject> ApiNatives::InstantiateObject(
5961cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<ObjectTemplateInfo> data,
5971cb0ef41Sopenharmony_ci    Handle<JSReceiver> new_target) {
5981cb0ef41Sopenharmony_ci  InvokeScope invoke_scope(isolate);
5991cb0ef41Sopenharmony_ci  return ::v8::internal::InstantiateObject(isolate, data, new_target, false);
6001cb0ef41Sopenharmony_ci}
6011cb0ef41Sopenharmony_ci
6021cb0ef41Sopenharmony_ciMaybeHandle<JSObject> ApiNatives::InstantiateRemoteObject(
6031cb0ef41Sopenharmony_ci    Handle<ObjectTemplateInfo> data) {
6041cb0ef41Sopenharmony_ci  Isolate* isolate = data->GetIsolate();
6051cb0ef41Sopenharmony_ci  InvokeScope invoke_scope(isolate);
6061cb0ef41Sopenharmony_ci
6071cb0ef41Sopenharmony_ci  Handle<FunctionTemplateInfo> constructor(
6081cb0ef41Sopenharmony_ci      FunctionTemplateInfo::cast(data->constructor()), isolate);
6091cb0ef41Sopenharmony_ci  Handle<Map> object_map = isolate->factory()->NewMap(
6101cb0ef41Sopenharmony_ci      JS_SPECIAL_API_OBJECT_TYPE,
6111cb0ef41Sopenharmony_ci      JSObject::kHeaderSize +
6121cb0ef41Sopenharmony_ci          data->embedder_field_count() * kEmbedderDataSlotSize,
6131cb0ef41Sopenharmony_ci      TERMINAL_FAST_ELEMENTS_KIND);
6141cb0ef41Sopenharmony_ci  object_map->SetConstructor(*constructor);
6151cb0ef41Sopenharmony_ci  object_map->set_is_access_check_needed(true);
6161cb0ef41Sopenharmony_ci  object_map->set_may_have_interesting_symbols(true);
6171cb0ef41Sopenharmony_ci
6181cb0ef41Sopenharmony_ci  Handle<JSObject> object = isolate->factory()->NewJSObjectFromMap(object_map);
6191cb0ef41Sopenharmony_ci  JSObject::ForceSetPrototype(isolate, object,
6201cb0ef41Sopenharmony_ci                              isolate->factory()->null_value());
6211cb0ef41Sopenharmony_ci
6221cb0ef41Sopenharmony_ci  return object;
6231cb0ef41Sopenharmony_ci}
6241cb0ef41Sopenharmony_ci
6251cb0ef41Sopenharmony_civoid ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
6261cb0ef41Sopenharmony_ci                                 Handle<Name> name, Handle<Object> value,
6271cb0ef41Sopenharmony_ci                                 PropertyAttributes attributes) {
6281cb0ef41Sopenharmony_ci  PropertyDetails details(PropertyKind::kData, attributes,
6291cb0ef41Sopenharmony_ci                          PropertyConstness::kMutable);
6301cb0ef41Sopenharmony_ci  auto details_handle = handle(details.AsSmi(), isolate);
6311cb0ef41Sopenharmony_ci  Handle<Object> data[] = {name, details_handle, value};
6321cb0ef41Sopenharmony_ci  AddPropertyToPropertyList(isolate, info, arraysize(data), data);
6331cb0ef41Sopenharmony_ci}
6341cb0ef41Sopenharmony_ci
6351cb0ef41Sopenharmony_civoid ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
6361cb0ef41Sopenharmony_ci                                 Handle<Name> name, v8::Intrinsic intrinsic,
6371cb0ef41Sopenharmony_ci                                 PropertyAttributes attributes) {
6381cb0ef41Sopenharmony_ci  auto value = handle(Smi::FromInt(intrinsic), isolate);
6391cb0ef41Sopenharmony_ci  auto intrinsic_marker = isolate->factory()->true_value();
6401cb0ef41Sopenharmony_ci  PropertyDetails details(PropertyKind::kData, attributes,
6411cb0ef41Sopenharmony_ci                          PropertyConstness::kMutable);
6421cb0ef41Sopenharmony_ci  auto details_handle = handle(details.AsSmi(), isolate);
6431cb0ef41Sopenharmony_ci  Handle<Object> data[] = {name, intrinsic_marker, details_handle, value};
6441cb0ef41Sopenharmony_ci  AddPropertyToPropertyList(isolate, info, arraysize(data), data);
6451cb0ef41Sopenharmony_ci}
6461cb0ef41Sopenharmony_ci
6471cb0ef41Sopenharmony_civoid ApiNatives::AddAccessorProperty(Isolate* isolate,
6481cb0ef41Sopenharmony_ci                                     Handle<TemplateInfo> info,
6491cb0ef41Sopenharmony_ci                                     Handle<Name> name,
6501cb0ef41Sopenharmony_ci                                     Handle<FunctionTemplateInfo> getter,
6511cb0ef41Sopenharmony_ci                                     Handle<FunctionTemplateInfo> setter,
6521cb0ef41Sopenharmony_ci                                     PropertyAttributes attributes) {
6531cb0ef41Sopenharmony_ci  if (!getter.is_null()) getter->set_published(true);
6541cb0ef41Sopenharmony_ci  if (!setter.is_null()) setter->set_published(true);
6551cb0ef41Sopenharmony_ci  PropertyDetails details(PropertyKind::kAccessor, attributes,
6561cb0ef41Sopenharmony_ci                          PropertyConstness::kMutable);
6571cb0ef41Sopenharmony_ci  auto details_handle = handle(details.AsSmi(), isolate);
6581cb0ef41Sopenharmony_ci  Handle<Object> data[] = {name, details_handle, getter, setter};
6591cb0ef41Sopenharmony_ci  AddPropertyToPropertyList(isolate, info, arraysize(data), data);
6601cb0ef41Sopenharmony_ci}
6611cb0ef41Sopenharmony_ci
6621cb0ef41Sopenharmony_civoid ApiNatives::AddNativeDataProperty(Isolate* isolate,
6631cb0ef41Sopenharmony_ci                                       Handle<TemplateInfo> info,
6641cb0ef41Sopenharmony_ci                                       Handle<AccessorInfo> property) {
6651cb0ef41Sopenharmony_ci  Object maybe_list = info->property_accessors();
6661cb0ef41Sopenharmony_ci  Handle<TemplateList> list;
6671cb0ef41Sopenharmony_ci  if (maybe_list.IsUndefined(isolate)) {
6681cb0ef41Sopenharmony_ci    list = TemplateList::New(isolate, 1);
6691cb0ef41Sopenharmony_ci  } else {
6701cb0ef41Sopenharmony_ci    list = handle(TemplateList::cast(maybe_list), isolate);
6711cb0ef41Sopenharmony_ci  }
6721cb0ef41Sopenharmony_ci  list = TemplateList::Add(isolate, list, property);
6731cb0ef41Sopenharmony_ci  info->set_property_accessors(*list);
6741cb0ef41Sopenharmony_ci}
6751cb0ef41Sopenharmony_ci
6761cb0ef41Sopenharmony_ciHandle<JSFunction> ApiNatives::CreateApiFunction(
6771cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<NativeContext> native_context,
6781cb0ef41Sopenharmony_ci    Handle<FunctionTemplateInfo> obj, Handle<Object> prototype,
6791cb0ef41Sopenharmony_ci    InstanceType type, MaybeHandle<Name> maybe_name) {
6801cb0ef41Sopenharmony_ci  RCS_SCOPE(isolate, RuntimeCallCounterId::kCreateApiFunction);
6811cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared =
6821cb0ef41Sopenharmony_ci      FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate, obj,
6831cb0ef41Sopenharmony_ci                                                          maybe_name);
6841cb0ef41Sopenharmony_ci  // To simplify things, API functions always have shared name.
6851cb0ef41Sopenharmony_ci  DCHECK(shared->HasSharedName());
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_ci  Handle<JSFunction> result =
6881cb0ef41Sopenharmony_ci      Factory::JSFunctionBuilder{isolate, shared, native_context}.Build();
6891cb0ef41Sopenharmony_ci
6901cb0ef41Sopenharmony_ci  if (obj->remove_prototype()) {
6911cb0ef41Sopenharmony_ci    DCHECK(prototype.is_null());
6921cb0ef41Sopenharmony_ci    DCHECK(result->shared().IsApiFunction());
6931cb0ef41Sopenharmony_ci    DCHECK(!result->IsConstructor());
6941cb0ef41Sopenharmony_ci    DCHECK(!result->has_prototype_slot());
6951cb0ef41Sopenharmony_ci    return result;
6961cb0ef41Sopenharmony_ci  }
6971cb0ef41Sopenharmony_ci
6981cb0ef41Sopenharmony_ci  // Down from here is only valid for API functions that can be used as a
6991cb0ef41Sopenharmony_ci  // constructor (don't set the "remove prototype" flag).
7001cb0ef41Sopenharmony_ci  DCHECK(result->has_prototype_slot());
7011cb0ef41Sopenharmony_ci
7021cb0ef41Sopenharmony_ci  if (obj->read_only_prototype()) {
7031cb0ef41Sopenharmony_ci    result->set_map(*isolate->sloppy_function_with_readonly_prototype_map());
7041cb0ef41Sopenharmony_ci  }
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_ci  if (prototype->IsTheHole(isolate)) {
7071cb0ef41Sopenharmony_ci    prototype = isolate->factory()->NewFunctionPrototype(result);
7081cb0ef41Sopenharmony_ci  } else if (obj->GetPrototypeProviderTemplate().IsUndefined(isolate)) {
7091cb0ef41Sopenharmony_ci    JSObject::AddProperty(isolate, Handle<JSObject>::cast(prototype),
7101cb0ef41Sopenharmony_ci                          isolate->factory()->constructor_string(), result,
7111cb0ef41Sopenharmony_ci                          DONT_ENUM);
7121cb0ef41Sopenharmony_ci  }
7131cb0ef41Sopenharmony_ci
7141cb0ef41Sopenharmony_ci  int embedder_field_count = 0;
7151cb0ef41Sopenharmony_ci  bool immutable_proto = false;
7161cb0ef41Sopenharmony_ci  if (!obj->GetInstanceTemplate().IsUndefined(isolate)) {
7171cb0ef41Sopenharmony_ci    Handle<ObjectTemplateInfo> GetInstanceTemplate = Handle<ObjectTemplateInfo>(
7181cb0ef41Sopenharmony_ci        ObjectTemplateInfo::cast(obj->GetInstanceTemplate()), isolate);
7191cb0ef41Sopenharmony_ci    embedder_field_count = GetInstanceTemplate->embedder_field_count();
7201cb0ef41Sopenharmony_ci    immutable_proto = GetInstanceTemplate->immutable_proto();
7211cb0ef41Sopenharmony_ci  }
7221cb0ef41Sopenharmony_ci
7231cb0ef41Sopenharmony_ci  // JSFunction requires information about the prototype slot.
7241cb0ef41Sopenharmony_ci  DCHECK(!InstanceTypeChecker::IsJSFunction(type));
7251cb0ef41Sopenharmony_ci  int instance_size = JSObject::GetHeaderSize(type) +
7261cb0ef41Sopenharmony_ci                      kEmbedderDataSlotSize * embedder_field_count;
7271cb0ef41Sopenharmony_ci
7281cb0ef41Sopenharmony_ci  Handle<Map> map = isolate->factory()->NewMap(type, instance_size,
7291cb0ef41Sopenharmony_ci                                               TERMINAL_FAST_ELEMENTS_KIND);
7301cb0ef41Sopenharmony_ci
7311cb0ef41Sopenharmony_ci  // Mark as undetectable if needed.
7321cb0ef41Sopenharmony_ci  if (obj->undetectable()) {
7331cb0ef41Sopenharmony_ci    // We only allow callable undetectable receivers here, since this whole
7341cb0ef41Sopenharmony_ci    // undetectable business is only to support document.all, which is both
7351cb0ef41Sopenharmony_ci    // undetectable and callable. If we ever see the need to have an object
7361cb0ef41Sopenharmony_ci    // that is undetectable but not callable, we need to update the types.h
7371cb0ef41Sopenharmony_ci    // to allow encoding this.
7381cb0ef41Sopenharmony_ci    CHECK(!obj->GetInstanceCallHandler().IsUndefined(isolate));
7391cb0ef41Sopenharmony_ci    map->set_is_undetectable(true);
7401cb0ef41Sopenharmony_ci  }
7411cb0ef41Sopenharmony_ci
7421cb0ef41Sopenharmony_ci  // Mark as needs_access_check if needed.
7431cb0ef41Sopenharmony_ci  if (obj->needs_access_check()) {
7441cb0ef41Sopenharmony_ci    map->set_is_access_check_needed(true);
7451cb0ef41Sopenharmony_ci    map->set_may_have_interesting_symbols(true);
7461cb0ef41Sopenharmony_ci  }
7471cb0ef41Sopenharmony_ci
7481cb0ef41Sopenharmony_ci  // Set interceptor information in the map.
7491cb0ef41Sopenharmony_ci  if (!obj->GetNamedPropertyHandler().IsUndefined(isolate)) {
7501cb0ef41Sopenharmony_ci    map->set_has_named_interceptor(true);
7511cb0ef41Sopenharmony_ci    map->set_may_have_interesting_symbols(true);
7521cb0ef41Sopenharmony_ci  }
7531cb0ef41Sopenharmony_ci  if (!obj->GetIndexedPropertyHandler().IsUndefined(isolate)) {
7541cb0ef41Sopenharmony_ci    map->set_has_indexed_interceptor(true);
7551cb0ef41Sopenharmony_ci  }
7561cb0ef41Sopenharmony_ci
7571cb0ef41Sopenharmony_ci  // Mark instance as callable in the map.
7581cb0ef41Sopenharmony_ci  if (!obj->GetInstanceCallHandler().IsUndefined(isolate)) {
7591cb0ef41Sopenharmony_ci    map->set_is_callable(true);
7601cb0ef41Sopenharmony_ci    map->set_is_constructor(!obj->undetectable());
7611cb0ef41Sopenharmony_ci  }
7621cb0ef41Sopenharmony_ci
7631cb0ef41Sopenharmony_ci  if (immutable_proto) map->set_is_immutable_proto(true);
7641cb0ef41Sopenharmony_ci
7651cb0ef41Sopenharmony_ci  JSFunction::SetInitialMap(isolate, result, map,
7661cb0ef41Sopenharmony_ci                            Handle<JSObject>::cast(prototype));
7671cb0ef41Sopenharmony_ci  return result;
7681cb0ef41Sopenharmony_ci}
7691cb0ef41Sopenharmony_ci
7701cb0ef41Sopenharmony_ci}  // namespace internal
7711cb0ef41Sopenharmony_ci}  // namespace v8
772