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