@@ -11662,7 +11662,8 @@ void CodeStubAssembler::ForEachEnumerableOwnProperty(
1166211662
1166311663 var_value = CallGetterIfAccessor(
1166411664 value_or_accessor, object, var_details.value(), context,
11665- object, next_key, &slow_load, kCallJSGetterUseCachedName);
11665+ object, kExpectingJSReceiver, next_key, &slow_load,
11666+ kCallJSGetterUseCachedName);
1166611667 Goto(&value_ready);
1166711668
1166811669 BIND(&slow_load);
@@ -12158,15 +12159,11 @@ template void CodeStubAssembler::LoadPropertyFromDictionary(
1215812159 TNode<SwissNameDictionary> dictionary, TNode<IntPtrT> name_index,
1215912160 TVariable<Uint32T>* var_details, TVariable<Object>* var_value);
1216012161
12161- // |value| is the property backing store's contents, which is either a value or
12162- // an accessor pair, as specified by |details|. |holder| is a JSReceiver or a
12163- // PropertyCell. Returns either the original value, or the result of the getter
12164- // call.
1216512162TNode<Object> CodeStubAssembler::CallGetterIfAccessor(
12166- TNode<Object> value, TNode<Union< JSReceiver, PropertyCell >> holder,
12163+ TNode<Object> value, std::optional< TNode<JSReceiver>> holder,
1216712164 TNode<Uint32T> details, TNode<Context> context, TNode<JSAny> receiver,
12168- TNode<Object> name, Label* if_bailout, GetOwnPropertyMode mode ,
12169- ExpectedReceiverMode expected_receiver_mode ) {
12165+ ExpectedReceiverMode expected_receiver_mode, TNode<Object> name,
12166+ Label* if_bailout, GetOwnPropertyMode mode ) {
1217012167 TVARIABLE(Object, var_value, value);
1217112168 Label done(this), if_accessor_info(this, Label::kDeferred);
1217212169
@@ -12207,44 +12204,51 @@ TNode<Object> CodeStubAssembler::CallGetterIfAccessor(
1220712204
1220812205 BIND(&if_function_template_info);
1220912206 {
12210- Label use_cached_property(this);
12211- TNode<HeapObject> cached_property_name = LoadObjectField<HeapObject>(
12212- getter, FunctionTemplateInfo::kCachedPropertyNameOffset);
12213-
12214- Label* has_cached_property = mode == kCallJSGetterUseCachedName
12215- ? &use_cached_property
12216- : if_bailout;
12217- GotoIfNot(IsTheHole(cached_property_name), has_cached_property);
12218-
12219- TNode<JSReceiver> js_receiver;
12220- switch (expected_receiver_mode) {
12221- case kExpectingJSReceiver:
12222- js_receiver = CAST(receiver);
12223- break;
12224- case kExpectingAnyReceiver:
12225- // TODO(ishell): in case the function template info has a signature
12226- // and receiver is not a JSReceiver the signature check in
12227- // CallFunctionTemplate builtin will fail anyway, so we can short
12228- // cut it here and throw kIllegalInvocation immediately.
12229- js_receiver = ToObject_Inline(context, receiver);
12230- break;
12231- }
12232- TNode<JSReceiver> holder_receiver = CAST(holder);
12233- TNode<NativeContext> creation_context =
12234- GetCreationContext(holder_receiver, if_bailout);
12235- TNode<Context> caller_context = context;
12236- var_value = CallBuiltin(
12237- Builtin::kCallFunctionTemplate_Generic, creation_context, getter,
12238- Int32Constant(i::JSParameterCount(0)), caller_context, js_receiver);
12239- Goto(&done);
12207+ if (holder.has_value()) {
12208+ Label use_cached_property(this);
12209+ TNode<HeapObject> cached_property_name = LoadObjectField<HeapObject>(
12210+ getter, FunctionTemplateInfo::kCachedPropertyNameOffset);
12211+
12212+ Label* has_cached_property = mode == kCallJSGetterUseCachedName
12213+ ? &use_cached_property
12214+ : if_bailout;
12215+ GotoIfNot(IsTheHole(cached_property_name), has_cached_property);
12216+
12217+ TNode<JSReceiver> js_receiver;
12218+ switch (expected_receiver_mode) {
12219+ case kExpectingJSReceiver:
12220+ js_receiver = CAST(receiver);
12221+ break;
12222+ case kExpectingAnyReceiver:
12223+ // TODO(ishell): in case the function template info has a
12224+ // signature and receiver is not a JSReceiver the signature check
12225+ // in CallFunctionTemplate builtin will fail anyway, so we can
12226+ // short cut it here and throw kIllegalInvocation immediately.
12227+ js_receiver = ToObject_Inline(context, receiver);
12228+ break;
12229+ }
12230+ TNode<JSReceiver> holder_receiver = *holder;
12231+ TNode<NativeContext> creation_context =
12232+ GetCreationContext(holder_receiver, if_bailout);
12233+ TNode<Context> caller_context = context;
12234+ var_value = CallBuiltin(Builtin::kCallFunctionTemplate_Generic,
12235+ creation_context, getter,
12236+ Int32Constant(i::JSParameterCount(0)),
12237+ caller_context, js_receiver);
12238+ Goto(&done);
1224012239
12241- if (mode == kCallJSGetterUseCachedName) {
12242- Bind(&use_cached_property);
12240+ if (mode == kCallJSGetterUseCachedName) {
12241+ Bind(&use_cached_property);
1224312242
12244- var_value =
12245- GetProperty(context, holder_receiver, cached_property_name);
12243+ var_value =
12244+ GetProperty(context, holder_receiver, cached_property_name);
1224612245
12247- Goto(&done);
12246+ Goto(&done);
12247+ }
12248+ } else {
12249+ // |holder| must be available in order to handle lazy AccessorPair
12250+ // case (we need it for computing the function's context).
12251+ Unreachable();
1224812252 }
1224912253 }
1225012254 } else {
@@ -12256,56 +12260,61 @@ TNode<Object> CodeStubAssembler::CallGetterIfAccessor(
1225612260 // AccessorInfo case.
1225712261 BIND(&if_accessor_info);
1225812262 {
12259- TNode<AccessorInfo> accessor_info = CAST(value);
12260- Label if_array(this), if_function(this), if_wrapper(this);
12261-
12262- // Dispatch based on {holder} instance type.
12263- TNode<Map> holder_map = LoadMap(holder);
12264- TNode<Uint16T> holder_instance_type = LoadMapInstanceType(holder_map);
12265- GotoIf(IsJSArrayInstanceType(holder_instance_type), &if_array);
12266- GotoIf(IsJSFunctionInstanceType(holder_instance_type), &if_function);
12267- Branch(IsJSPrimitiveWrapperInstanceType(holder_instance_type), &if_wrapper,
12268- if_bailout);
12269-
12270- // JSArray AccessorInfo case.
12271- BIND(&if_array);
12272- {
12273- // We only deal with the "length" accessor on JSArray.
12274- GotoIfNot(IsLengthString(
12275- LoadObjectField(accessor_info, AccessorInfo::kNameOffset)),
12276- if_bailout);
12277- TNode<JSArray> array = CAST(holder);
12278- var_value = LoadJSArrayLength(array);
12279- Goto(&done);
12280- }
12281-
12282- // JSFunction AccessorInfo case.
12283- BIND(&if_function);
12284- {
12285- // We only deal with the "prototype" accessor on JSFunction here.
12286- GotoIfNot(IsPrototypeString(
12287- LoadObjectField(accessor_info, AccessorInfo::kNameOffset)),
12288- if_bailout);
12263+ if (holder.has_value()) {
12264+ TNode<AccessorInfo> accessor_info = CAST(value);
12265+ Label if_array(this), if_function(this), if_wrapper(this);
12266+ // Dispatch based on {holder} instance type.
12267+ TNode<Map> holder_map = LoadMap(*holder);
12268+ TNode<Uint16T> holder_instance_type = LoadMapInstanceType(holder_map);
12269+ GotoIf(IsJSArrayInstanceType(holder_instance_type), &if_array);
12270+ GotoIf(IsJSFunctionInstanceType(holder_instance_type), &if_function);
12271+ Branch(IsJSPrimitiveWrapperInstanceType(holder_instance_type),
12272+ &if_wrapper, if_bailout);
12273+
12274+ // JSArray AccessorInfo case.
12275+ BIND(&if_array);
12276+ {
12277+ // We only deal with the "length" accessor on JSArray.
12278+ GotoIfNot(IsLengthString(LoadObjectField(accessor_info,
12279+ AccessorInfo::kNameOffset)),
12280+ if_bailout);
12281+ TNode<JSArray> array = CAST(*holder);
12282+ var_value = LoadJSArrayLength(array);
12283+ Goto(&done);
12284+ }
1228912285
12290- TNode<JSFunction> function = CAST(holder);
12291- GotoIfPrototypeRequiresRuntimeLookup(function, holder_map, if_bailout);
12292- var_value = LoadJSFunctionPrototype(function, if_bailout);
12293- Goto(&done);
12294- }
12286+ // JSFunction AccessorInfo case.
12287+ BIND(&if_function);
12288+ {
12289+ // We only deal with the "prototype" accessor on JSFunction here.
12290+ GotoIfNot(IsPrototypeString(LoadObjectField(accessor_info,
12291+ AccessorInfo::kNameOffset)),
12292+ if_bailout);
12293+
12294+ TNode<JSFunction> function = CAST(*holder);
12295+ GotoIfPrototypeRequiresRuntimeLookup(function, holder_map, if_bailout);
12296+ var_value = LoadJSFunctionPrototype(function, if_bailout);
12297+ Goto(&done);
12298+ }
1229512299
12296- // JSPrimitiveWrapper AccessorInfo case.
12297- BIND(&if_wrapper);
12298- {
12299- // We only deal with the "length" accessor on JSPrimitiveWrapper string
12300- // wrappers.
12301- GotoIfNot(IsLengthString(
12302- LoadObjectField(accessor_info, AccessorInfo::kNameOffset)),
12303- if_bailout);
12304- TNode<Object> holder_value = LoadJSPrimitiveWrapperValue(CAST(holder));
12305- GotoIfNot(TaggedIsNotSmi(holder_value), if_bailout);
12306- GotoIfNot(IsString(CAST(holder_value)), if_bailout);
12307- var_value = LoadStringLengthAsSmi(CAST(holder_value));
12308- Goto(&done);
12300+ // JSPrimitiveWrapper AccessorInfo case.
12301+ BIND(&if_wrapper);
12302+ {
12303+ // We only deal with the "length" accessor on JSPrimitiveWrapper string
12304+ // wrappers.
12305+ GotoIfNot(IsLengthString(LoadObjectField(accessor_info,
12306+ AccessorInfo::kNameOffset)),
12307+ if_bailout);
12308+ TNode<Object> holder_value = LoadJSPrimitiveWrapperValue(CAST(*holder));
12309+ GotoIfNot(TaggedIsNotSmi(holder_value), if_bailout);
12310+ GotoIfNot(IsString(CAST(holder_value)), if_bailout);
12311+ var_value = LoadStringLengthAsSmi(CAST(holder_value));
12312+ Goto(&done);
12313+ }
12314+ } else {
12315+ // |holder| must be available in order to handle AccessorInfo case (we
12316+ // need to pass it to the callback).
12317+ Unreachable();
1230912318 }
1231012319 }
1231112320
@@ -12390,7 +12399,7 @@ void CodeStubAssembler::TryGetOwnProperty(
1239012399 }
1239112400 TNode<Object> value = CallGetterIfAccessor(
1239212401 var_value->value(), object, var_details->value(), context, receiver,
12393- unique_name, if_bailout, mode, expected_receiver_mode );
12402+ expected_receiver_mode, unique_name, if_bailout, mode);
1239412403 *var_value = value;
1239512404 Goto(if_found_value);
1239612405 }
0 commit comments