29 isolate, NewReferenceError(MessageTemplate::kUnsupportedSuper));
40 DCHECK(IsNativeContext(*context));
44 if (name->length() == 0) {
46 isolate, NewError(realm_type_error_function,
47 MessageTemplate::kAnonymousConstructorNonCallable));
50 isolate, NewError(realm_type_error_function,
51 MessageTemplate::kConstructorNonCallable, name));
59 isolate, NewTypeError(MessageTemplate::kStaticPrototype));
66 isolate, NewReferenceError(MessageTemplate::kSuperAlreadyCalled));
73 isolate, NewReferenceError(MessageTemplate::kSuperNotCalled));
79 DirectHandle<Object> constructor,
80 DirectHandle<JSFunction> function) {
81 DirectHandle<String> super_name;
82 if (IsJSFunction(*constructor)) {
85 }
else if (IsOddball(*constructor)) {
87 super_name = isolate->factory()->null_string();
92 if (super_name->length() == 0) {
93 super_name = isolate->factory()->null_string();
95 Handle<String> function_name(function->shared()->Name(), isolate);
97 if (function_name->length() == 0) {
100 NewTypeError(MessageTemplate::kNotSuperConstructorAnonymousClass,
104 isolate, NewTypeError(MessageTemplate::kNotSuperConstructor, super_name,
115 return ThrowNotSuperConstructor(isolate, constructor, function);
120template <
typename Dictionary>
122 static_assert((std::is_same_v<Dictionary, SwissNameDictionary> ||
123 std::is_same_v<Dictionary, NameDictionary>));
129Handle<Name> KeyToName<NumberDictionary>(Isolate* isolate, Handle<Object>
key) {
131 return isolate->factory()->NumberToString(
key);
140template <
typename Dictionary>
141MaybeDirectHandle<Object> GetMethodAndSetName(Isolate* isolate,
144 DirectHandle<String> name_prefix,
145 Handle<Object>
key) {
146 int int_index = index.value();
150 return args.at<Object>(int_index);
153 DirectHandle<JSFunction>
method =
args.at<JSFunction>(int_index);
155 if (!
method->shared()->HasSharedName()) {
161 DirectHandle<Name> name = KeyToName<Dictionary>(isolate,
key);
163 return MaybeDirectHandle<Object>();
181 return args[int_index];
184 DirectHandle<JSFunction>
method =
args.at<JSFunction>(int_index);
189template <
typename Dictionary>
191 Isolate* isolate, DirectHandle<Dictionary> dictionary_template) {
193 Dictionary::ShallowCopy(isolate, dictionary_template);
195 for (InternalIndex
i : dictionary->IterateEntries()) {
197 if (IsAccessorPair(value)) {
200 dictionary->ValueAtPut(
i, *pair);
206template <
typename Dictionary>
207bool SubstituteValues(Isolate* isolate, DirectHandle<Dictionary> dictionary,
210 ReadOnlyRoots roots(isolate);
211 for (InternalIndex
i : dictionary->IterateEntries()) {
213 if (!Dictionary::IsKey(roots, maybe_key))
continue;
214 Handle<Object>
key(maybe_key, isolate);
215 Handle<Object>
value(dictionary->ValueAt(
i), isolate);
216 if (IsAccessorPair(*value)) {
220 DirectHandle<Object>
result;
223 GetMethodAndSetName<Dictionary>(isolate,
args,
Cast<Smi>(tmp),
224 isolate->factory()->get_string(),
227 pair->set_getter(*
result);
229 tmp = pair->setter();
231 DirectHandle<Object>
result;
234 GetMethodAndSetName<Dictionary>(isolate,
args,
Cast<Smi>(tmp),
235 isolate->factory()->set_string(),
238 pair->set_setter(*
result);
240 }
else if (
IsSmi(*value)) {
241 DirectHandle<Object>
result;
244 GetMethodAndSetName<Dictionary>(isolate,
args,
Cast<Smi>(*value),
245 isolate->factory()->empty_string(),
248 dictionary->ValueAtPut(
i, *
result);
254template <
typename Dictionary>
255void UpdateProtectors(Isolate* isolate, DirectHandle<JSObject>
receiver,
256 DirectHandle<Dictionary> properties_dictionary) {
257 ReadOnlyRoots roots(isolate);
258 for (InternalIndex
i : properties_dictionary->IterateEntries()) {
260 if (!Dictionary::IsKey(roots, maybe_key))
continue;
266void UpdateProtectors(Isolate* isolate, DirectHandle<JSObject>
receiver,
267 DirectHandle<DescriptorArray> properties_template) {
268 int nof_descriptors = properties_template->number_of_descriptors();
269 for (InternalIndex
i : InternalIndex::Range(nof_descriptors)) {
270 DirectHandle<Name>
name(properties_template->GetKey(
i), isolate);
275bool AddDescriptorsByTemplate(
276 Isolate* isolate, DirectHandle<Map> map,
277 DirectHandle<DescriptorArray> descriptors_template,
278 DirectHandle<NumberDictionary> elements_dictionary_template,
280 int nof_descriptors = descriptors_template->number_of_descriptors();
282 DirectHandle<DescriptorArray> descriptors =
285 DirectHandle<NumberDictionary> elements_dictionary =
286 *elements_dictionary_template ==
287 ReadOnlyRoots(isolate).empty_slow_element_dictionary()
288 ? elements_dictionary_template
289 : ShallowCopyDictionaryTemplate(isolate,
290 elements_dictionary_template);
295 for (InternalIndex
i : InternalIndex::Range(nof_descriptors)) {
296 PropertyDetails details = descriptors_template->GetDetails(
i);
302 DirectHandle<PropertyArray> property_array =
303 isolate->factory()->NewPropertyArray(count);
308 for (InternalIndex
i : InternalIndex::Range(nof_descriptors)) {
310 if (IsAccessorPair(value)) {
319 if (name->IsInteresting(isolate)) {
320 map->set_may_have_interesting_properties(
true);
323 PropertyDetails details = descriptors_template->GetDetails(
i);
327 value = GetMethodWithSharedName(isolate,
args, value);
329 details = details.CopyWithRepresentation(
333 if (IsAccessorPair(value)) {
337 pair->set_getter(GetMethodWithSharedName(isolate,
args, tmp));
339 tmp = pair->setter();
341 pair->set_setter(GetMethodWithSharedName(isolate,
args, tmp));
352 PropertyDetails(details.kind(), details.attributes(),
354 details.representation(), field_index)
355 .set_pointer(details.pointer());
357 property_array->set(field_index, value);
361 descriptors->Set(
i, name, value, details);
365 UpdateProtectors(isolate,
receiver, descriptors_template);
367 map->InitializeDescriptors(isolate, *descriptors);
368 if (elements_dictionary->NumberOfElements() > 0) {
369 if (!SubstituteValues<NumberDictionary>(isolate, elements_dictionary,
378 if (elements_dictionary->NumberOfElements() > 0) {
379 receiver->set_elements(*elements_dictionary);
381 if (property_array->length() > 0) {
382 receiver->SetProperties(*property_array);
392DirectHandle<T> ToHandle(Handle<T> h) {
396DirectHandle<T> ToHandle(MaybeHandle<T> h) {
397 return h.ToHandleChecked();
400template <
typename Dictionary>
401bool AddDescriptorsByTemplate(
402 Isolate* isolate, DirectHandle<Map> map,
403 DirectHandle<Dictionary> properties_dictionary_template,
404 DirectHandle<NumberDictionary> elements_dictionary_template,
405 DirectHandle<FixedArray> computed_properties,
407 int computed_properties_length = computed_properties->length();
411 ShallowCopyDictionaryTemplate(isolate, properties_dictionary_template);
413 ShallowCopyDictionaryTemplate(isolate, elements_dictionary_template);
416 using ComputedEntryFlags = ClassBoilerplate::ComputedEntryFlags;
421 while (
i < computed_properties_length) {
422 int flags =
Smi::ToInt(computed_properties->get(
i++));
424 ValueKind value_kind = ComputedEntryFlags::ValueKindBits::decode(flags);
425 int key_index = ComputedEntryFlags::KeyIndexBits::decode(flags);
428 Handle<Object>
key =
args.at(key_index);
432 if (name->AsArrayIndex(&element)) {
434 isolate, elements_dictionary, element, key_index, value_kind, value);
437 name = isolate->factory()->InternalizeName(name);
439 isolate, properties_dictionary, name, key_index, value_kind, value);
440 if (name->IsInteresting(isolate)) {
443 properties_dictionary->set_may_have_interesting_properties(
true);
450 if (!SubstituteValues<Dictionary>(isolate, properties_dictionary,
args)) {
455 DirectHandle<Dictionary>(properties_dictionary));
457 if (elements_dictionary->NumberOfElements() > 0) {
458 if (!SubstituteValues<NumberDictionary>(isolate, elements_dictionary,
468 if (elements_dictionary->NumberOfElements() > 0) {
469 receiver->set_elements(*elements_dictionary);
474DirectHandle<JSObject> CreateClassPrototype(Isolate* isolate) {
482 return isolate->factory()->NewJSObjectFromMap(map);
485bool InitClassPrototype(Isolate* isolate,
486 DirectHandle<ClassBoilerplate> class_boilerplate,
487 DirectHandle<JSObject> prototype,
488 DirectHandle<JSPrototype> prototype_parent,
489 DirectHandle<JSFunction> constructor,
491 DirectHandle<Map>
map(prototype->map(), isolate);
493 map->set_is_prototype_map(
true);
495 isolate->UpdateProtectorsOnSetPrototype(prototype, prototype_parent);
496 constructor->set_prototype_or_initial_map(*prototype,
kReleaseStore);
497 map->SetConstructor(*constructor);
498 DirectHandle<FixedArray> computed_properties(
499 class_boilerplate->instance_computed_properties(), isolate);
500 DirectHandle<NumberDictionary> elements_dictionary_template(
504 Handle<Object> properties_template(
505 class_boilerplate->instance_properties_template(), isolate);
507 if (IsDescriptorArray(*properties_template)) {
513 return AddDescriptorsByTemplate(isolate, map, descriptors_template,
514 elements_dictionary_template, prototype,
517 map->set_is_dictionary_map(
true);
518 map->set_is_migration_target(
false);
519 map->set_may_have_interesting_properties(
true);
522 DirectHandle<PropertyDictionary> properties_dictionary_template =
524 return AddDescriptorsByTemplate(
525 isolate, map, properties_dictionary_template,
526 elements_dictionary_template, computed_properties, prototype,
args);
530bool InitClassConstructor(Isolate* isolate,
531 DirectHandle<ClassBoilerplate> class_boilerplate,
532 DirectHandle<JSPrototype> constructor_parent,
533 DirectHandle<JSFunction> constructor,
535 DirectHandle<Map>
map(constructor->map(), isolate);
537 DCHECK(map->is_prototype_map());
539 if (!constructor_parent.is_null()) {
547 DirectHandle<NumberDictionary> elements_dictionary_template(
550 DirectHandle<FixedArray> computed_properties(
551 class_boilerplate->static_computed_properties(), isolate);
553 Handle<Object> properties_template(
554 class_boilerplate->static_properties_template(), isolate);
556 if (IsDescriptorArray(*properties_template)) {
559 return AddDescriptorsByTemplate(isolate, map, descriptors_template,
560 elements_dictionary_template, constructor,
563 map->set_is_dictionary_map(
true);
564 map->InitializeDescriptors(isolate,
565 ReadOnlyRoots(isolate).empty_descriptor_array());
566 map->set_is_migration_target(
false);
567 map->set_may_have_interesting_properties(
true);
571 DirectHandle<SwissNameDictionary> properties_dictionary_template =
574 return AddDescriptorsByTemplate(
575 isolate, map, properties_dictionary_template,
576 elements_dictionary_template, computed_properties, constructor,
args);
578 DirectHandle<NameDictionary> properties_dictionary_template =
580 return AddDescriptorsByTemplate(
581 isolate, map, properties_dictionary_template,
582 elements_dictionary_template, computed_properties, constructor,
args);
587MaybeDirectHandle<Object> DefineClass(
588 Isolate* isolate, DirectHandle<ClassBoilerplate> class_boilerplate,
589 DirectHandle<Object> super_class, DirectHandle<JSFunction> constructor,
591 DirectHandle<JSPrototype> prototype_parent;
592 DirectHandle<JSPrototype> constructor_parent;
594 if (IsTheHole(*super_class, isolate)) {
595 prototype_parent = isolate->initial_object_prototype();
597 if (
IsNull(*super_class, isolate)) {
598 prototype_parent = isolate->factory()->null_value();
599 }
else if (IsConstructor(*super_class)) {
600 DCHECK(!IsJSFunction(*super_class) ||
603 DirectHandle<Object> maybe_prototype_parent;
605 isolate, maybe_prototype_parent,
607 isolate->factory()->prototype_string()));
608 if (!
TryCast(maybe_prototype_parent, &prototype_parent)) {
610 isolate, NewTypeError(MessageTemplate::kPrototypeParentNotAnObject,
611 maybe_prototype_parent));
620 NewTypeError(MessageTemplate::kExtendsValueNotConstructor,
625 DirectHandle<JSObject> prototype = CreateClassPrototype(isolate);
631 RuntimeArguments::ChangeValueScope set_prototype_value_scope(
634 if (!InitClassConstructor(isolate, class_boilerplate, constructor_parent,
635 constructor,
args) ||
636 !InitClassPrototype(isolate, class_boilerplate, prototype,
637 prototype_parent, constructor,
args)) {
638 DCHECK(isolate->has_exception());
639 return MaybeDirectHandle<Object>();
642 DirectHandle<Map> empty_map;
644 MapEvent(
"InitialMap", empty_map,
646 "init class constructor",
649 LOG(isolate, MapEvent(
"InitialMap", empty_map,
651 "init class prototype"));
666 DCHECK_EQ(class_boilerplate->arguments_count(),
args.length());
670 DefineClass(isolate, class_boilerplate, super_class, constructor,
args));
675enum class SuperMode { kLoad, kStore };
677MaybeDirectHandle<JSReceiver> GetSuperHolder(Isolate* isolate,
678 DirectHandle<JSObject> home_object,
679 SuperMode mode, PropertyKey*
key) {
680 if (IsAccessCheckNeeded(*home_object) &&
681 !isolate->MayAccess(isolate->native_context(), home_object)) {
686 PrototypeIterator iter(isolate, home_object);
688 if (!IsJSReceiver(*proto)) {
690 mode == SuperMode::kLoad
691 ? MessageTemplate::kNonObjectPropertyLoadWithProperty
692 : MessageTemplate::kNonObjectPropertyStoreWithProperty;
693 DirectHandle<Name> name =
key->GetName(isolate);
699MaybeDirectHandle<Object> LoadFromSuper(Isolate* isolate,
701 DirectHandle<JSObject> home_object,
703 DirectHandle<JSReceiver> holder;
706 GetSuperHolder(isolate, home_object, SuperMode::kLoad,
key));
707 LookupIterator it(isolate,
receiver, *
key, holder);
708 DirectHandle<Object>
result;
725 LoadFromSuper(isolate,
receiver, home_object, &
key));
743 isolate, LoadFromSuper(isolate,
receiver, home_object, &lookup_key));
748MaybeDirectHandle<Object> StoreToSuper(
Isolate* isolate,
749 DirectHandle<JSObject> home_object,
752 DirectHandle<Object> value,
754 DirectHandle<JSReceiver> holder;
757 GetSuperHolder(isolate, home_object, SuperMode::kStore,
key));
758 LookupIterator it(isolate,
receiver, *
key, holder);
760 MaybeDirectHandle<Object>());
777 isolate, StoreToSuper(isolate, home_object,
receiver, &
key, value,
796 isolate, StoreToSuper(isolate, home_object,
receiver, &lookup_key, value,
static NEVER_READ_ONLY_SPACE DirectHandle< AccessorPair > Copy(Isolate *isolate, DirectHandle< AccessorPair > pair)
static void AddToPropertiesTemplate(IsolateT *isolate, Handle< Dictionary > dictionary, Handle< Name > name, int key_index, ValueKind value_kind, Tagged< Smi > value)
static void AddToElementsTemplate(IsolateT *isolate, Handle< NumberDictionary > dictionary, uint32_t key, int key_index, ValueKind value_kind, Tagged< Smi > value)
@ kPrototypeArgumentIndex
@ kFirstDynamicArgumentIndex
@ kConstructorArgumentIndex
static V8_EXPORT_PRIVATE Handle< DescriptorArray > Allocate(IsolateT *isolate, int nof_descriptors, int slack, AllocationType allocation=AllocationType::kYoung)
static V8_EXPORT_PRIVATE Tagged< FieldType > Any()
static V8_WARN_UNUSED_RESULT bool SetName(DirectHandle< JSFunction > function, DirectHandle< Name > name, DirectHandle< String > prefix)
static void MakePrototypesFast(DirectHandle< Object > receiver, WhereToStart where_to_start, Isolate *isolate)
static V8_EXPORT_PRIVATE Handle< Map > Create(Isolate *isolate, int inobject_properties)
static const int kNoSlackTracking
static Handle< Map > CopyDropDescriptors(Isolate *isolate, DirectHandle< Map > map)
static V8_EXPORT_PRIVATE void SetPrototype(Isolate *isolate, DirectHandle< Map > map, DirectHandle< JSPrototype > prototype, bool enable_prototype_setup_mode=true)
static V8_EXPORT_PRIVATE DirectHandle< String > NoSideEffectsToString(Isolate *isolate, DirectHandle< Object > input)
static Representation OptimalRepresentation(Tagged< Object > obj, PtrComprCageBase cage_base)
static V8_WARN_UNUSED_RESULT Maybe< bool > SetSuperProperty(LookupIterator *it, DirectHandle< Object > value, StoreOrigin store_origin, Maybe< ShouldThrow > should_throw=Nothing< ShouldThrow >())
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetProperty(LookupIterator *it, bool is_global_reference=false)
static bool FitsRepresentation(Tagged< Object > obj, Representation representation, bool allow_coercion=true)
Tagged< T > GetCurrent() const
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > GetObjectProperty(Isolate *isolate, DirectHandle< JSAny > lookup_start_object, DirectHandle< Object > key, DirectHandle< JSAny > receiver={}, bool *is_found=nullptr)
static Handle< String > DebugName(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared)
static constexpr int ToInt(const Tagged< Object > object)
static constexpr Tagged< Smi > FromInt(int value)
#define V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
#define RUNTIME_FUNCTION(Name)
#define RETURN_ON_EXCEPTION(isolate, call)
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)
#define THROW_NEW_ERROR(isolate, call)
#define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)
#define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call)
#define MAYBE_RETURN(call, value)
#define RETURN_RESULT_OR_FAILURE(isolate, call)
base::Vector< const DirectHandle< Object > > args
SharedFunctionInfoRef shared
ZoneVector< RpoNumber > & result
#define LOG(isolate, Call)
bool TryCast(Tagged< From > value, Tagged< To > *out)
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
bool IsNumber(Tagged< Object > obj)
Tagged(T object) -> Tagged< T >
bool IsResumableFunction(FunctionKind kind)
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
return Cast< NumberDictionary >(elements(cage_base))
V8_EXPORT_PRIVATE FlagValues v8_flags
bool IsUniqueName(Tagged< Name > obj)
Arguments< ArgumentsType::kRuntime > RuntimeArguments
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset IsNull(value)||IsJSProxy(value)||IsWasmObject(value)||(IsJSObject(value) &&(HeapLayout
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset prototype
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
static constexpr ReleaseStoreTag kReleaseStore
static constexpr RelaxedStoreTag kRelaxedStore
#define DCHECK_LE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)