@@ -819,8 +819,11 @@ pub(crate) fn ordinary_set(
819819// OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc )
820820// https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html#sec-ordinarysetwithowndescriptor
821821
822+ let mut has_own_desc =false ;
823+
822824// 1. Assert: IsPropertyKey(P) is true.
823825let own_desc =if let Some ( desc) = obj. __get_own_property__ ( & key, context) ?{
826+ has_own_desc =true ;
824827 desc
825828}
826829// 2. If ownDesc is undefined, then
@@ -863,15 +866,25 @@ pub(crate) fn ordinary_set(
863866return Ok ( false ) ;
864867} ;
865868
869+ let obj_is_receiver =JsObject :: equals ( obj, & receiver) ;
870+
866871// NOTE(HaledOdat): If the object and receiver are not the same then it's not inline cacheable for now.
867- context. slot ( ) . attributes . set (
868- SlotAttributes :: NOT_CACHEABLE ,
869- !JsObject :: equals ( obj, & receiver) ,
870- ) ;
872+ context
873+ . slot ( )
874+ . attributes
875+ . set ( SlotAttributes :: NOT_CACHEABLE , !obj_is_receiver) ;
876+
877+ // OPTIMIZATION: If obj and receiver are the same, there's no need to call [[GetOwnProperty]](P)
878+ // again because it was already performed above.
879+ let existing_descriptor =if has_own_desc && obj_is_receiver{
880+ Some ( own_desc)
881+ } else {
882+ // c. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P).
883+ receiver. __get_own_property__ ( & key, context) ?
884+ } ;
871885
872- // c. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P).
873886// d. If existingDescriptor is not undefined, then
874- if let Some ( ref existing_desc) =receiver . __get_own_property__ ( & key , context ) ? {
887+ if let Some ( ref existing_desc) =existing_descriptor {
875888// i. If IsAccessorDescriptor(existingDescriptor) is true, return false.
876889if existing_desc. is_accessor_descriptor ( ) {
877890return Ok ( false ) ;