5 #include "src/runtime/runtime-utils.h" 10 #include "src/accessors.h" 11 #include "src/arguments-inl.h" 12 #include "src/counters.h" 13 #include "src/debug/debug.h" 14 #include "src/elements.h" 15 #include "src/isolate-inl.h" 16 #include "src/message-template.h" 17 #include "src/objects/hash-table-inl.h" 18 #include "src/objects/literal-objects-inl.h" 19 #include "src/objects/smi.h" 20 #include "src/runtime/runtime.h" 26 RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) {
27 HandleScope scope(isolate);
28 DCHECK_EQ(0, args.length());
29 THROW_NEW_ERROR_RETURN_FAILURE(
30 isolate, NewReferenceError(MessageTemplate::kUnsupportedSuper));
34 RUNTIME_FUNCTION(Runtime_ThrowConstructorNonCallableError) {
35 HandleScope scope(isolate);
36 DCHECK_EQ(1, args.length());
37 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
38 Handle<String> name(constructor->shared()->Name(), isolate);
39 THROW_NEW_ERROR_RETURN_FAILURE(
40 isolate, NewTypeError(MessageTemplate::kConstructorNonCallable, name));
44 RUNTIME_FUNCTION(Runtime_ThrowStaticPrototypeError) {
45 HandleScope scope(isolate);
46 DCHECK_EQ(0, args.length());
47 THROW_NEW_ERROR_RETURN_FAILURE(
48 isolate, NewTypeError(MessageTemplate::kStaticPrototype));
51 RUNTIME_FUNCTION(Runtime_ThrowSuperAlreadyCalledError) {
52 HandleScope scope(isolate);
53 DCHECK_EQ(0, args.length());
54 THROW_NEW_ERROR_RETURN_FAILURE(
55 isolate, NewReferenceError(MessageTemplate::kSuperAlreadyCalled));
58 RUNTIME_FUNCTION(Runtime_ThrowSuperNotCalled) {
59 HandleScope scope(isolate);
60 DCHECK_EQ(0, args.length());
61 THROW_NEW_ERROR_RETURN_FAILURE(
62 isolate, NewReferenceError(MessageTemplate::kSuperNotCalled));
67 Object* ThrowNotSuperConstructor(Isolate* isolate, Handle<Object> constructor,
68 Handle<JSFunction>
function) {
69 Handle<String> super_name;
70 if (constructor->IsJSFunction()) {
71 super_name = handle(Handle<JSFunction>::cast(constructor)->shared()->Name(),
73 }
else if (constructor->IsOddball()) {
74 DCHECK(constructor->IsNull(isolate));
75 super_name = isolate->factory()->null_string();
77 super_name = Object::NoSideEffectsToString(isolate, constructor);
80 if (super_name->length() == 0) {
81 super_name = isolate->factory()->null_string();
83 Handle<String> function_name(function->shared()->Name(), isolate);
85 if (function_name->length() == 0) {
86 THROW_NEW_ERROR_RETURN_FAILURE(
88 NewTypeError(MessageTemplate::kNotSuperConstructorAnonymousClass,
91 THROW_NEW_ERROR_RETURN_FAILURE(
92 isolate, NewTypeError(MessageTemplate::kNotSuperConstructor, super_name,
98 RUNTIME_FUNCTION(Runtime_ThrowNotSuperConstructor) {
99 HandleScope scope(isolate);
100 DCHECK_EQ(2, args.length());
101 CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
102 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 1);
103 return ThrowNotSuperConstructor(isolate, constructor,
function);
106 RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
107 DCHECK_EQ(0, args.length());
108 return ReadOnlyRoots(isolate).home_object_symbol();
113 template <
typename Dictionary>
114 Handle<Name> KeyToName(Isolate* isolate, Handle<Object> key);
117 Handle<Name> KeyToName<NameDictionary>(Isolate* isolate, Handle<Object> key) {
118 DCHECK(key->IsName());
119 return Handle<Name>::cast(key);
123 Handle<Name> KeyToName<NumberDictionary>(Isolate* isolate, Handle<Object> key) {
124 DCHECK(key->IsNumber());
125 return isolate->factory()->NumberToString(key);
128 inline void SetHomeObject(Isolate* isolate, JSFunction* method,
129 JSObject* home_object) {
130 if (method->shared()->needs_home_object()) {
131 const int kPropertyIndex = JSFunction::kMaybeHomeObjectDescriptorIndex;
132 CHECK_EQ(method->map()->instance_descriptors()->GetKey(kPropertyIndex),
133 ReadOnlyRoots(isolate).home_object_symbol());
135 FieldIndex field_index =
136 FieldIndex::ForDescriptor(method->map(), kPropertyIndex);
137 method->RawFastPropertyAtPut(field_index, home_object);
149 template <
typename Dictionary>
150 MaybeHandle<Object> GetMethodAndSetHomeObjectAndName(
151 Isolate* isolate, Arguments& args, Smi index, Handle<JSObject> home_object,
152 Handle<String> name_prefix, Handle<Object> key) {
153 int int_index = index.value();
156 if (int_index < ClassBoilerplate::kFirstDynamicArgumentIndex) {
157 return args.at<Object>(int_index);
160 Handle<JSFunction> method = args.at<JSFunction>(int_index);
162 SetHomeObject(isolate, *method, *home_object);
164 if (!method->shared()->HasSharedName()) {
170 Handle<Name> name = KeyToName<Dictionary>(isolate, key);
171 if (!JSFunction::SetName(method, name, name_prefix)) {
172 return MaybeHandle<Object>();
186 Object* GetMethodWithSharedNameAndSetHomeObject(Isolate* isolate,
187 Arguments& args, Object* index,
188 JSObject* home_object) {
189 DisallowHeapAllocation no_gc;
190 int int_index = Smi::ToInt(index);
193 if (int_index < ClassBoilerplate::kFirstDynamicArgumentIndex) {
194 return args[int_index];
197 Handle<JSFunction> method = args.at<JSFunction>(int_index);
199 SetHomeObject(isolate, *method, home_object);
201 DCHECK(method->shared()->HasSharedName());
205 template <
typename Dictionary>
206 Handle<Dictionary> ShallowCopyDictionaryTemplate(
207 Isolate* isolate, Handle<Dictionary> dictionary_template) {
208 Handle<Map> dictionary_map(dictionary_template->map(), isolate);
209 Handle<Dictionary> dictionary =
210 Handle<Dictionary>::cast(isolate->factory()->CopyFixedArrayWithMap(
211 dictionary_template, dictionary_map));
213 int capacity = dictionary->Capacity();
214 for (
int i = 0;
i < capacity;
i++) {
215 Object* value = dictionary->ValueAt(
i);
216 if (value->IsAccessorPair()) {
217 Handle<AccessorPair> pair(AccessorPair::cast(value), isolate);
218 pair = AccessorPair::Copy(isolate, pair);
219 dictionary->ValueAtPut(
i, *pair);
225 template <
typename Dictionary>
226 bool SubstituteValues(Isolate* isolate, Handle<Dictionary> dictionary,
227 Handle<JSObject> receiver, Arguments& args,
228 bool* install_name_accessor =
nullptr) {
229 Handle<Name> name_string = isolate->factory()->name_string();
232 int capacity = dictionary->Capacity();
233 ReadOnlyRoots roots(isolate);
234 for (
int i = 0;
i < capacity;
i++) {
235 Object* maybe_key = dictionary->KeyAt(
i);
236 if (!Dictionary::IsKey(roots, maybe_key))
continue;
237 if (install_name_accessor && *install_name_accessor &&
238 (maybe_key == *name_string)) {
239 *install_name_accessor =
false;
241 Handle<Object> key(maybe_key, isolate);
242 Handle<Object> value(dictionary->ValueAt(
i), isolate);
243 if (value->IsAccessorPair()) {
244 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(value);
245 Object* tmp = pair->getter();
247 Handle<Object> result;
248 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
250 GetMethodAndSetHomeObjectAndName<Dictionary>(
251 isolate, args, Smi::cast(tmp), receiver,
252 isolate->factory()->get_string(), key),
254 pair->set_getter(*result);
256 tmp = pair->setter();
258 Handle<Object> result;
259 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
261 GetMethodAndSetHomeObjectAndName<Dictionary>(
262 isolate, args, Smi::cast(tmp), receiver,
263 isolate->factory()->set_string(), key),
265 pair->set_setter(*result);
267 }
else if (value->IsSmi()) {
268 Handle<Object> result;
269 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
271 GetMethodAndSetHomeObjectAndName<Dictionary>(
272 isolate, args, Smi::cast(*value), receiver,
273 isolate->factory()->empty_string(), key),
275 dictionary->ValueAtPut(
i, *result);
281 bool AddDescriptorsByTemplate(
282 Isolate* isolate, Handle<Map> map,
283 Handle<DescriptorArray> descriptors_template,
284 Handle<NumberDictionary> elements_dictionary_template,
285 Handle<JSObject> receiver, Arguments& args) {
286 int nof_descriptors = descriptors_template->number_of_descriptors();
288 Handle<DescriptorArray> descriptors =
289 DescriptorArray::Allocate(isolate, nof_descriptors, 0);
291 Handle<NumberDictionary> elements_dictionary =
292 *elements_dictionary_template ==
293 ReadOnlyRoots(isolate).empty_slow_element_dictionary()
294 ? elements_dictionary_template
295 : ShallowCopyDictionaryTemplate(isolate,
296 elements_dictionary_template);
298 Handle<PropertyArray> property_array =
299 isolate->factory()->empty_property_array();
300 if (FLAG_track_constant_fields) {
305 for (
int i = 0;
i < nof_descriptors;
i++) {
306 PropertyDetails details = descriptors_template->GetDetails(
i);
307 if (details.location() == kDescriptor && details.kind() == kData) {
311 property_array = isolate->factory()->NewPropertyArray(count);
317 for (
int i = 0;
i < nof_descriptors;
i++) {
318 Object* value = descriptors_template->GetStrongValue(
i);
319 if (value->IsAccessorPair()) {
320 Handle<AccessorPair> pair = AccessorPair::Copy(
321 isolate, handle(AccessorPair::cast(value), isolate));
324 DisallowHeapAllocation no_gc;
325 Name name = descriptors_template->GetKey(
i);
326 DCHECK(name->IsUniqueName());
327 PropertyDetails details = descriptors_template->GetDetails(
i);
328 if (details.location() == kDescriptor) {
329 if (details.kind() == kData) {
330 if (value->IsSmi()) {
331 value = GetMethodWithSharedNameAndSetHomeObject(isolate, args, value,
335 details.CopyWithRepresentation(value->OptimalRepresentation());
337 DCHECK_EQ(kAccessor, details.kind());
338 if (value->IsAccessorPair()) {
339 AccessorPair* pair = AccessorPair::cast(value);
340 Object* tmp = pair->getter();
342 pair->set_getter(GetMethodWithSharedNameAndSetHomeObject(
343 isolate, args, tmp, *receiver));
345 tmp = pair->setter();
347 pair->set_setter(GetMethodWithSharedNameAndSetHomeObject(
348 isolate, args, tmp, *receiver));
355 DCHECK(value->FitsRepresentation(details.representation()));
357 if (FLAG_track_constant_fields && details.location() == kDescriptor &&
358 details.kind() == kData) {
359 details = PropertyDetails(details.kind(), details.attributes(), kField,
360 PropertyConstness::kConst,
361 details.representation(), field_index)
362 .set_pointer(details.pointer());
364 property_array->set(field_index, value);
366 descriptors->Set(
i, name, MaybeObject::FromObject(FieldType::Any()),
369 descriptors->Set(
i, name, MaybeObject::FromObject(value), details);
373 map->InitializeDescriptors(*descriptors,
374 LayoutDescriptor::FastPointerLayout());
375 if (elements_dictionary->NumberOfElements() > 0) {
376 if (!SubstituteValues<NumberDictionary>(isolate, elements_dictionary,
380 map->set_elements_kind(DICTIONARY_ELEMENTS);
384 receiver->synchronized_set_map(*map);
385 if (elements_dictionary->NumberOfElements() > 0) {
386 receiver->set_elements(*elements_dictionary);
388 if (property_array->length() > 0) {
389 receiver->SetProperties(*property_array);
394 bool AddDescriptorsByTemplate(
395 Isolate* isolate, Handle<Map> map,
396 Handle<NameDictionary> properties_dictionary_template,
397 Handle<NumberDictionary> elements_dictionary_template,
398 Handle<FixedArray> computed_properties, Handle<JSObject> receiver,
399 bool install_name_accessor, Arguments& args) {
400 int computed_properties_length = computed_properties->length();
403 Handle<NameDictionary> properties_dictionary =
404 ShallowCopyDictionaryTemplate(isolate, properties_dictionary_template);
405 Handle<NumberDictionary> elements_dictionary =
406 ShallowCopyDictionaryTemplate(isolate, elements_dictionary_template);
408 typedef ClassBoilerplate::ValueKind ValueKind;
409 typedef ClassBoilerplate::ComputedEntryFlags ComputedEntryFlags;
414 while (
i < computed_properties_length) {
415 int flags = Smi::ToInt(computed_properties->get(
i++));
417 ValueKind value_kind = ComputedEntryFlags::ValueKindBits::decode(flags);
418 int key_index = ComputedEntryFlags::KeyIndexBits::decode(flags);
419 Object* value = Smi::FromInt(key_index + 1);
421 Handle<Object> key = args.at<Object>(key_index);
422 DCHECK(key->IsName());
424 Handle<Name> name = Handle<Name>::cast(key);
425 if (name->AsArrayIndex(&element)) {
426 ClassBoilerplate::AddToElementsTemplate(
427 isolate, elements_dictionary, element, key_index, value_kind, value);
430 name = isolate->factory()->InternalizeName(name);
431 ClassBoilerplate::AddToPropertiesTemplate(
432 isolate, properties_dictionary, name, key_index, value_kind, value);
437 if (!SubstituteValues<NameDictionary>(isolate, properties_dictionary,
439 &install_name_accessor)) {
442 if (install_name_accessor) {
443 PropertyAttributes attribs =
444 static_cast<PropertyAttributes
>(DONT_ENUM | READ_ONLY);
445 PropertyDetails details(kAccessor, attribs, PropertyCellType::kNoCell);
446 Handle<NameDictionary> dict = NameDictionary::Add(
447 isolate, properties_dictionary, isolate->factory()->name_string(),
448 isolate->factory()->function_name_accessor(), details);
449 CHECK_EQ(*dict, *properties_dictionary);
452 if (elements_dictionary->NumberOfElements() > 0) {
453 if (!SubstituteValues<NumberDictionary>(isolate, elements_dictionary,
457 map->set_elements_kind(DICTIONARY_ELEMENTS);
461 receiver->synchronized_set_map(*map);
462 receiver->set_raw_properties_or_hash(*properties_dictionary);
463 if (elements_dictionary->NumberOfElements() > 0) {
464 receiver->set_elements(*elements_dictionary);
469 Handle<JSObject> CreateClassPrototype(Isolate* isolate) {
470 Factory* factory = isolate->factory();
472 const int kInobjectFields = 0;
475 if (FLAG_track_constant_fields) {
482 map = Map::Create(isolate, 0);
485 map = factory->ObjectLiteralMapFromCache(isolate->native_context(),
489 return factory->NewJSObjectFromMap(map);
492 bool InitClassPrototype(Isolate* isolate,
493 Handle<ClassBoilerplate> class_boilerplate,
494 Handle<JSObject> prototype,
495 Handle<Object> prototype_parent,
496 Handle<JSFunction> constructor, Arguments& args) {
497 Handle<Map> map(prototype->map(), isolate);
498 map = Map::CopyDropDescriptors(isolate, map);
499 map->set_is_prototype_map(
true);
500 Map::SetPrototype(isolate, map, prototype_parent);
501 constructor->set_prototype_or_initial_map(*prototype);
502 map->SetConstructor(*constructor);
503 Handle<FixedArray> computed_properties(
504 class_boilerplate->instance_computed_properties(), isolate);
505 Handle<NumberDictionary> elements_dictionary_template(
506 NumberDictionary::cast(class_boilerplate->instance_elements_template()),
509 Handle<Object> properties_template(
510 class_boilerplate->instance_properties_template(), isolate);
511 if (properties_template->IsNameDictionary()) {
512 Handle<NameDictionary> properties_dictionary_template =
513 Handle<NameDictionary>::cast(properties_template);
515 map->set_is_dictionary_map(
true);
516 map->set_is_migration_target(
false);
517 map->set_may_have_interesting_symbols(
true);
518 map->set_construction_counter(Map::kNoSlackTracking);
521 const bool install_name_accessor =
false;
523 return AddDescriptorsByTemplate(
524 isolate, map, properties_dictionary_template,
525 elements_dictionary_template, computed_properties, prototype,
526 install_name_accessor, args);
528 Handle<DescriptorArray> descriptors_template =
529 Handle<DescriptorArray>::cast(properties_template);
534 return AddDescriptorsByTemplate(isolate, map, descriptors_template,
535 elements_dictionary_template, prototype,
540 bool InitClassConstructor(Isolate* isolate,
541 Handle<ClassBoilerplate> class_boilerplate,
542 Handle<Object> constructor_parent,
543 Handle<JSFunction> constructor, Arguments& args) {
544 Handle<Map> map(constructor->map(), isolate);
545 map = Map::CopyDropDescriptors(isolate, map);
546 DCHECK(map->is_prototype_map());
548 if (!constructor_parent.is_null()) {
551 Map::SetPrototype(isolate, map, constructor_parent,
false);
554 Handle<NumberDictionary> elements_dictionary_template(
555 NumberDictionary::cast(class_boilerplate->static_elements_template()),
557 Handle<FixedArray> computed_properties(
558 class_boilerplate->static_computed_properties(), isolate);
560 Handle<Object> properties_template(
561 class_boilerplate->static_properties_template(), isolate);
563 if (properties_template->IsNameDictionary()) {
564 Handle<NameDictionary> properties_dictionary_template =
565 Handle<NameDictionary>::cast(properties_template);
567 map->set_is_dictionary_map(
true);
568 map->InitializeDescriptors(ReadOnlyRoots(isolate).empty_descriptor_array(),
569 LayoutDescriptor::FastPointerLayout());
570 map->set_is_migration_target(
false);
571 map->set_may_have_interesting_symbols(
true);
572 map->set_construction_counter(Map::kNoSlackTracking);
574 bool install_name_accessor =
575 class_boilerplate->install_class_name_accessor() != 0;
577 return AddDescriptorsByTemplate(
578 isolate, map, properties_dictionary_template,
579 elements_dictionary_template, computed_properties, constructor,
580 install_name_accessor, args);
582 Handle<DescriptorArray> descriptors_template =
583 Handle<DescriptorArray>::cast(properties_template);
585 return AddDescriptorsByTemplate(isolate, map, descriptors_template,
586 elements_dictionary_template, constructor,
591 MaybeHandle<Object> DefineClass(Isolate* isolate,
592 Handle<ClassBoilerplate> class_boilerplate,
593 Handle<Object> super_class,
594 Handle<JSFunction> constructor,
596 Handle<Object> prototype_parent;
597 Handle<Object> constructor_parent;
599 if (super_class->IsTheHole(isolate)) {
600 prototype_parent = isolate->initial_object_prototype();
602 if (super_class->IsNull(isolate)) {
603 prototype_parent = isolate->factory()->null_value();
604 }
else if (super_class->IsConstructor()) {
605 DCHECK(!super_class->IsJSFunction() ||
606 !IsResumableFunction(
607 Handle<JSFunction>::cast(super_class)->shared()->kind()));
608 ASSIGN_RETURN_ON_EXCEPTION(
609 isolate, prototype_parent,
610 Runtime::GetObjectProperty(isolate, super_class,
611 isolate->factory()->prototype_string()),
613 if (!prototype_parent->IsNull(isolate) &&
614 !prototype_parent->IsJSReceiver()) {
616 isolate, NewTypeError(MessageTemplate::kPrototypeParentNotAnObject,
623 constructor_parent = handle(*super_class, isolate);
625 THROW_NEW_ERROR(isolate,
626 NewTypeError(MessageTemplate::kExtendsValueNotConstructor,
632 Handle<JSObject> prototype = CreateClassPrototype(isolate);
633 DCHECK_EQ(*constructor, args[ClassBoilerplate::kConstructorArgumentIndex]);
634 args.set_at(ClassBoilerplate::kPrototypeArgumentIndex, *prototype);
636 if (!InitClassConstructor(isolate, class_boilerplate, constructor_parent,
637 constructor, args) ||
638 !InitClassPrototype(isolate, class_boilerplate, prototype,
639 prototype_parent, constructor, args)) {
640 DCHECK(isolate->has_pending_exception());
641 return MaybeHandle<Object>();
643 if (FLAG_trace_maps) {
645 MapEvent(
"InitialMap", Map(), constructor->map(),
646 "init class constructor", constructor->shared()->DebugName()));
647 LOG(isolate, MapEvent(
"InitialMap", Map(), prototype->map(),
648 "init class prototype"));
656 RUNTIME_FUNCTION(Runtime_DefineClass) {
657 HandleScope scope(isolate);
658 DCHECK_LE(ClassBoilerplate::kFirstDynamicArgumentIndex, args.length());
659 CONVERT_ARG_HANDLE_CHECKED(ClassBoilerplate, class_boilerplate, 0);
660 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1);
661 CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 2);
662 DCHECK_EQ(class_boilerplate->arguments_count(), args.length());
664 RETURN_RESULT_OR_FAILURE(
666 DefineClass(isolate, class_boilerplate, super_class, constructor, args));
671 enum class SuperMode { kLoad, kStore };
673 MaybeHandle<JSReceiver> GetSuperHolder(
674 Isolate* isolate, Handle<Object> receiver, Handle<JSObject> home_object,
675 SuperMode mode, MaybeHandle<Name> maybe_name,
uint32_t index) {
676 if (home_object->IsAccessCheckNeeded() &&
677 !isolate->MayAccess(handle(isolate->context(), isolate), home_object)) {
678 isolate->ReportFailedAccessCheck(home_object);
679 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, JSReceiver);
682 PrototypeIterator iter(isolate, home_object);
683 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
684 if (!proto->IsJSReceiver()) {
685 MessageTemplate message = mode == SuperMode::kLoad
686 ? MessageTemplate::kNonObjectPropertyLoad
687 : MessageTemplate::kNonObjectPropertyStore;
689 if (!maybe_name.ToHandle(&name)) {
690 name = isolate->factory()->Uint32ToString(index);
692 THROW_NEW_ERROR(isolate, NewTypeError(message, name, proto), JSReceiver);
694 return Handle<JSReceiver>::cast(proto);
697 MaybeHandle<Object> LoadFromSuper(Isolate* isolate, Handle<Object> receiver,
698 Handle<JSObject> home_object,
700 Handle<JSReceiver> holder;
701 ASSIGN_RETURN_ON_EXCEPTION(
703 GetSuperHolder(isolate, receiver, home_object, SuperMode::kLoad, name, 0),
705 LookupIterator it(receiver, name, holder);
706 Handle<Object> result;
707 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object);
711 MaybeHandle<Object> LoadElementFromSuper(Isolate* isolate,
712 Handle<Object> receiver,
713 Handle<JSObject> home_object,
715 Handle<JSReceiver> holder;
716 ASSIGN_RETURN_ON_EXCEPTION(
718 GetSuperHolder(isolate, receiver, home_object, SuperMode::kLoad,
719 MaybeHandle<Name>(), index),
721 LookupIterator it(isolate, receiver, index, holder);
722 Handle<Object> result;
723 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object);
729 RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
730 HandleScope scope(isolate);
731 DCHECK_EQ(3, args.length());
732 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
733 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
734 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
736 RETURN_RESULT_OR_FAILURE(isolate,
737 LoadFromSuper(isolate, receiver, home_object, name));
741 RUNTIME_FUNCTION(Runtime_LoadKeyedFromSuper) {
742 HandleScope scope(isolate);
743 DCHECK_EQ(3, args.length());
744 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
745 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
746 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
750 if (key->ToArrayIndex(&index)) {
751 RETURN_RESULT_OR_FAILURE(
752 isolate, LoadElementFromSuper(isolate, receiver, home_object, index));
756 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
757 Object::ToName(isolate, key));
759 if (name->AsArrayIndex(&index)) {
760 RETURN_RESULT_OR_FAILURE(
761 isolate, LoadElementFromSuper(isolate, receiver, home_object, index));
763 RETURN_RESULT_OR_FAILURE(isolate,
764 LoadFromSuper(isolate, receiver, home_object, name));
769 MaybeHandle<Object> StoreToSuper(Isolate* isolate, Handle<JSObject> home_object,
770 Handle<Object> receiver, Handle<Name> name,
771 Handle<Object> value,
772 LanguageMode language_mode) {
773 Handle<JSReceiver> holder;
774 ASSIGN_RETURN_ON_EXCEPTION(isolate, holder,
775 GetSuperHolder(isolate, receiver, home_object,
776 SuperMode::kStore, name, 0),
778 LookupIterator it(receiver, name, holder);
780 Object::SetSuperProperty(&it, value, language_mode, StoreOrigin::kNamed),
781 MaybeHandle<Object>());
785 MaybeHandle<Object> StoreElementToSuper(Isolate* isolate,
786 Handle<JSObject> home_object,
787 Handle<Object> receiver,
uint32_t index,
788 Handle<Object> value,
789 LanguageMode language_mode) {
790 Handle<JSReceiver> holder;
791 ASSIGN_RETURN_ON_EXCEPTION(
793 GetSuperHolder(isolate, receiver, home_object, SuperMode::kStore,
794 MaybeHandle<Name>(), index),
796 LookupIterator it(isolate, receiver, index, holder);
797 MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode,
798 StoreOrigin::kMaybeKeyed),
799 MaybeHandle<Object>());
805 RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) {
806 HandleScope scope(isolate);
807 DCHECK_EQ(4, args.length());
808 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
809 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
810 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
811 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
813 RETURN_RESULT_OR_FAILURE(
814 isolate, StoreToSuper(isolate, home_object, receiver, name, value,
815 LanguageMode::kStrict));
819 RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) {
820 HandleScope scope(isolate);
821 DCHECK_EQ(4, args.length());
822 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
823 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
824 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
825 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
827 RETURN_RESULT_OR_FAILURE(
828 isolate, StoreToSuper(isolate, home_object, receiver, name, value,
829 LanguageMode::kSloppy));
832 static MaybeHandle<Object> StoreKeyedToSuper(
833 Isolate* isolate, Handle<JSObject> home_object, Handle<Object> receiver,
834 Handle<Object> key, Handle<Object> value, LanguageMode language_mode) {
837 if (key->ToArrayIndex(&index)) {
838 return StoreElementToSuper(isolate, home_object, receiver, index, value,
842 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
845 if (name->AsArrayIndex(&index)) {
846 return StoreElementToSuper(isolate, home_object, receiver, index, value,
849 return StoreToSuper(isolate, home_object, receiver, name, value,
854 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) {
855 HandleScope scope(isolate);
856 DCHECK_EQ(4, args.length());
857 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
858 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
859 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
860 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
862 RETURN_RESULT_OR_FAILURE(
863 isolate, StoreKeyedToSuper(isolate, home_object, receiver, key, value,
864 LanguageMode::kStrict));
868 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) {
869 HandleScope scope(isolate);
870 DCHECK_EQ(4, args.length());
871 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
872 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
873 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
874 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
876 RETURN_RESULT_OR_FAILURE(
877 isolate, StoreKeyedToSuper(isolate, home_object, receiver, key, value,
878 LanguageMode::kSloppy));