@@ -11409,7 +11409,8 @@ void CodeStubAssembler::ForEachEnumerableOwnProperty(
1140911409
1141011410 var_value = CallGetterIfAccessor(
1141111411 value_or_accessor, object, var_details.value(), context,
11412- object, next_key, &slow_load, kCallJSGetterUseCachedName);
11412+ object, kExpectingJSReceiver, next_key, &slow_load,
11413+ kCallJSGetterUseCachedName);
1141311414 Goto(&value_ready);
1141411415
1141511416 BIND(&slow_load);
@@ -11905,15 +11906,11 @@ template void CodeStubAssembler::LoadPropertyFromDictionary(
1190511906 TNode<SwissNameDictionary> dictionary, TNode<IntPtrT> name_index,
1190611907 TVariable<Uint32T>* var_details, TVariable<Object>* var_value);
1190711908
11908- // |value| is the property backing store's contents, which is either a value or
11909- // an accessor pair, as specified by |details|. |holder| is a JSReceiver or a
11910- // PropertyCell. Returns either the original value, or the result of the getter
11911- // call.
1191211909TNode<Object> CodeStubAssembler::CallGetterIfAccessor(
11913- TNode<Object> value, TNode<Union< JSReceiver, PropertyCell >> holder,
11910+ TNode<Object> value, std::optional< TNode<JSReceiver>> holder,
1191411911 TNode<Uint32T> details, TNode<Context> context, TNode<JSAny> receiver,
11915- TNode<Object> name, Label* if_bailout, GetOwnPropertyMode mode ,
11916- ExpectedReceiverMode expected_receiver_mode ) {
11912+ ExpectedReceiverMode expected_receiver_mode, TNode<Object> name,
11913+ Label* if_bailout, GetOwnPropertyMode mode ) {
1191711914 TVARIABLE(Object, var_value, value);
1191811915 Label done(this), if_accessor_info(this, Label::kDeferred);
1191911916
@@ -11954,44 +11951,51 @@ TNode<Object> CodeStubAssembler::CallGetterIfAccessor(
1195411951
1195511952 BIND(&if_function_template_info);
1195611953 {
11957- Label use_cached_property(this);
11958- TNode<HeapObject> cached_property_name = LoadObjectField<HeapObject>(
11959- getter, FunctionTemplateInfo::kCachedPropertyNameOffset);
11960-
11961- Label* has_cached_property = mode == kCallJSGetterUseCachedName
11962- ? &use_cached_property
11963- : if_bailout;
11964- GotoIfNot(IsTheHole(cached_property_name), has_cached_property);
11965-
11966- TNode<JSReceiver> js_receiver;
11967- switch (expected_receiver_mode) {
11968- case kExpectingJSReceiver:
11969- js_receiver = CAST(receiver);
11970- break;
11971- case kExpectingAnyReceiver:
11972- // TODO(ishell): in case the function template info has a signature
11973- // and receiver is not a JSReceiver the signature check in
11974- // CallFunctionTemplate builtin will fail anyway, so we can short
11975- // cut it here and throw kIllegalInvocation immediately.
11976- js_receiver = ToObject_Inline(context, receiver);
11977- break;
11978- }
11979- TNode<JSReceiver> holder_receiver = CAST(holder);
11980- TNode<NativeContext> creation_context =
11981- GetCreationContext(holder_receiver, if_bailout);
11982- TNode<Context> caller_context = context;
11983- var_value = CallBuiltin(
11984- Builtin::kCallFunctionTemplate_Generic, creation_context, getter,
11985- Int32Constant(i::JSParameterCount(0)), caller_context, js_receiver);
11986- Goto(&done);
11954+ if (holder.has_value()) {
11955+ Label use_cached_property(this);
11956+ TNode<HeapObject> cached_property_name = LoadObjectField<HeapObject>(
11957+ getter, FunctionTemplateInfo::kCachedPropertyNameOffset);
11958+
11959+ Label* has_cached_property = mode == kCallJSGetterUseCachedName
11960+ ? &use_cached_property
11961+ : if_bailout;
11962+ GotoIfNot(IsTheHole(cached_property_name), has_cached_property);
11963+
11964+ TNode<JSReceiver> js_receiver;
11965+ switch (expected_receiver_mode) {
11966+ case kExpectingJSReceiver:
11967+ js_receiver = CAST(receiver);
11968+ break;
11969+ case kExpectingAnyReceiver:
11970+ // TODO(ishell): in case the function template info has a
11971+ // signature and receiver is not a JSReceiver the signature check
11972+ // in CallFunctionTemplate builtin will fail anyway, so we can
11973+ // short cut it here and throw kIllegalInvocation immediately.
11974+ js_receiver = ToObject_Inline(context, receiver);
11975+ break;
11976+ }
11977+ TNode<JSReceiver> holder_receiver = *holder;
11978+ TNode<NativeContext> creation_context =
11979+ GetCreationContext(holder_receiver, if_bailout);
11980+ TNode<Context> caller_context = context;
11981+ var_value = CallBuiltin(Builtin::kCallFunctionTemplate_Generic,
11982+ creation_context, getter,
11983+ Int32Constant(i::JSParameterCount(0)),
11984+ caller_context, js_receiver);
11985+ Goto(&done);
1198711986
11988- if (mode == kCallJSGetterUseCachedName) {
11989- Bind(&use_cached_property);
11987+ if (mode == kCallJSGetterUseCachedName) {
11988+ Bind(&use_cached_property);
1199011989
11991- var_value =
11992- GetProperty(context, holder_receiver, cached_property_name);
11990+ var_value =
11991+ GetProperty(context, holder_receiver, cached_property_name);
1199311992
11994- Goto(&done);
11993+ Goto(&done);
11994+ }
11995+ } else {
11996+ // |holder| must be available in order to handle lazy AccessorPair
11997+ // case (we need it for computing the function's context).
11998+ Unreachable();
1199511999 }
1199612000 }
1199712001 } else {
@@ -12003,56 +12007,61 @@ TNode<Object> CodeStubAssembler::CallGetterIfAccessor(
1200312007 // AccessorInfo case.
1200412008 BIND(&if_accessor_info);
1200512009 {
12006- TNode<AccessorInfo> accessor_info = CAST(value);
12007- Label if_array(this), if_function(this), if_wrapper(this);
12008-
12009- // Dispatch based on {holder} instance type.
12010- TNode<Map> holder_map = LoadMap(holder);
12011- TNode<Uint16T> holder_instance_type = LoadMapInstanceType(holder_map);
12012- GotoIf(IsJSArrayInstanceType(holder_instance_type), &if_array);
12013- GotoIf(IsJSFunctionInstanceType(holder_instance_type), &if_function);
12014- Branch(IsJSPrimitiveWrapperInstanceType(holder_instance_type), &if_wrapper,
12015- if_bailout);
12016-
12017- // JSArray AccessorInfo case.
12018- BIND(&if_array);
12019- {
12020- // We only deal with the "length" accessor on JSArray.
12021- GotoIfNot(IsLengthString(
12022- LoadObjectField(accessor_info, AccessorInfo::kNameOffset)),
12023- if_bailout);
12024- TNode<JSArray> array = CAST(holder);
12025- var_value = LoadJSArrayLength(array);
12026- Goto(&done);
12027- }
12028-
12029- // JSFunction AccessorInfo case.
12030- BIND(&if_function);
12031- {
12032- // We only deal with the "prototype" accessor on JSFunction here.
12033- GotoIfNot(IsPrototypeString(
12034- LoadObjectField(accessor_info, AccessorInfo::kNameOffset)),
12035- if_bailout);
12010+ if (holder.has_value()) {
12011+ TNode<AccessorInfo> accessor_info = CAST(value);
12012+ Label if_array(this), if_function(this), if_wrapper(this);
12013+ // Dispatch based on {holder} instance type.
12014+ TNode<Map> holder_map = LoadMap(*holder);
12015+ TNode<Uint16T> holder_instance_type = LoadMapInstanceType(holder_map);
12016+ GotoIf(IsJSArrayInstanceType(holder_instance_type), &if_array);
12017+ GotoIf(IsJSFunctionInstanceType(holder_instance_type), &if_function);
12018+ Branch(IsJSPrimitiveWrapperInstanceType(holder_instance_type),
12019+ &if_wrapper, if_bailout);
12020+
12021+ // JSArray AccessorInfo case.
12022+ BIND(&if_array);
12023+ {
12024+ // We only deal with the "length" accessor on JSArray.
12025+ GotoIfNot(IsLengthString(LoadObjectField(accessor_info,
12026+ AccessorInfo::kNameOffset)),
12027+ if_bailout);
12028+ TNode<JSArray> array = CAST(*holder);
12029+ var_value = LoadJSArrayLength(array);
12030+ Goto(&done);
12031+ }
1203612032
12037- TNode<JSFunction> function = CAST(holder);
12038- GotoIfPrototypeRequiresRuntimeLookup(function, holder_map, if_bailout);
12039- var_value = LoadJSFunctionPrototype(function, if_bailout);
12040- Goto(&done);
12041- }
12033+ // JSFunction AccessorInfo case.
12034+ BIND(&if_function);
12035+ {
12036+ // We only deal with the "prototype" accessor on JSFunction here.
12037+ GotoIfNot(IsPrototypeString(LoadObjectField(accessor_info,
12038+ AccessorInfo::kNameOffset)),
12039+ if_bailout);
12040+
12041+ TNode<JSFunction> function = CAST(*holder);
12042+ GotoIfPrototypeRequiresRuntimeLookup(function, holder_map, if_bailout);
12043+ var_value = LoadJSFunctionPrototype(function, if_bailout);
12044+ Goto(&done);
12045+ }
1204212046
12043- // JSPrimitiveWrapper AccessorInfo case.
12044- BIND(&if_wrapper);
12045- {
12046- // We only deal with the "length" accessor on JSPrimitiveWrapper string
12047- // wrappers.
12048- GotoIfNot(IsLengthString(
12049- LoadObjectField(accessor_info, AccessorInfo::kNameOffset)),
12050- if_bailout);
12051- TNode<Object> holder_value = LoadJSPrimitiveWrapperValue(CAST(holder));
12052- GotoIfNot(TaggedIsNotSmi(holder_value), if_bailout);
12053- GotoIfNot(IsString(CAST(holder_value)), if_bailout);
12054- var_value = LoadStringLengthAsSmi(CAST(holder_value));
12055- Goto(&done);
12047+ // JSPrimitiveWrapper AccessorInfo case.
12048+ BIND(&if_wrapper);
12049+ {
12050+ // We only deal with the "length" accessor on JSPrimitiveWrapper string
12051+ // wrappers.
12052+ GotoIfNot(IsLengthString(LoadObjectField(accessor_info,
12053+ AccessorInfo::kNameOffset)),
12054+ if_bailout);
12055+ TNode<Object> holder_value = LoadJSPrimitiveWrapperValue(CAST(*holder));
12056+ GotoIfNot(TaggedIsNotSmi(holder_value), if_bailout);
12057+ GotoIfNot(IsString(CAST(holder_value)), if_bailout);
12058+ var_value = LoadStringLengthAsSmi(CAST(holder_value));
12059+ Goto(&done);
12060+ }
12061+ } else {
12062+ // |holder| must be available in order to handle AccessorInfo case (we
12063+ // need to pass it to the callback).
12064+ Unreachable();
1205612065 }
1205712066 }
1205812067
@@ -12137,7 +12146,7 @@ void CodeStubAssembler::TryGetOwnProperty(
1213712146 }
1213812147 TNode<Object> value = CallGetterIfAccessor(
1213912148 var_value->value(), object, var_details->value(), context, receiver,
12140- unique_name, if_bailout, mode, expected_receiver_mode );
12149+ expected_receiver_mode, unique_name, if_bailout, mode);
1214112150 *var_value = value;
1214212151 Goto(if_found_value);
1214312152 }
0 commit comments