@@ -617,24 +617,46 @@ fn validate_and_apply_property_descriptor(
617617/// ### [10.1.7.1 OrdinaryHasProperty ( O, P )](https://tc39.es/ecma262/#sec-ordinaryhasproperty)
618618pub ( crate ) fn ordinary_try_has_property (
619619 agent : & mut Agent ,
620- object : OrdinaryObject ,
620+ object : Object ,
621+ backing_object : OrdinaryObject ,
621622 property_key : PropertyKey ,
622623 gc : NoGcScope ,
623624) -> TryResult < bool > {
624625 // 1. Let hasOwn be ? O.[[GetOwnProperty]](P).
625- // Note: ? means that if we'd call a Proxy's GetOwnProperty trap then we'll
626- // instead return None.
627- let has_own = object. try_get_own_property ( agent, property_key, gc) ?;
626+ let has_own = backing_object
627+ . object_shape ( agent)
628+ . keys ( & agent. heap . object_shapes , & agent. heap . elements )
629+ . iter ( )
630+ . enumerate ( )
631+ . find ( |( _, p) | * p == & property_key)
632+ . map ( |( i, _) | i as u32 ) ;
628633
629634 // 2. If hasOwn is not undefined, return true.
630- if has_own. is_some ( ) {
635+ if let Some ( offset) = has_own {
636+ if let Some ( CacheToPopulate {
637+ receiver,
638+ cache,
639+ key : _,
640+ shape,
641+ } ) = agent
642+ . heap
643+ . caches
644+ . take_current_cache_to_populate ( property_key)
645+ {
646+ let is_receiver = object. into_value ( ) == receiver;
647+ if is_receiver {
648+ cache. insert_lookup_offset ( agent, shape, offset) ;
649+ } else {
650+ cache. insert_prototype_lookup_offset ( agent, shape, offset, object) ;
651+ }
652+ }
631653 return TryResult :: Continue ( true ) ;
632- }
654+ } ;
633655
634656 // 3. Let parent be ? O.[[GetPrototypeOf]]().
635657 // Note: ? means that if we'd call a Proxy's GetPrototypeOf trap then we'll
636658 // instead return None.
637- let parent = object . try_get_prototype_of ( agent, gc) ?;
659+ let parent = backing_object . try_get_prototype_of ( agent, gc) ?;
638660
639661 // 4. If parent is not null, then
640662 if let Some ( parent) = parent {
@@ -644,6 +666,19 @@ pub(crate) fn ordinary_try_has_property(
644666 return parent. try_has_property ( agent, property_key, gc) ;
645667 }
646668
669+ if let Some ( CacheToPopulate {
670+ receiver : _,
671+ cache,
672+ key : _,
673+ shape,
674+ } ) = agent
675+ . heap
676+ . caches
677+ . take_current_cache_to_populate ( property_key)
678+ {
679+ cache. insert_unset ( agent, shape) ;
680+ }
681+
647682 // 5. Return false.
648683 TryResult :: Continue ( false )
649684}
@@ -655,7 +690,13 @@ pub(crate) fn ordinary_try_has_property_entry<'a>(
655690 gc : NoGcScope ,
656691) -> TryResult < bool > {
657692 match object. get_backing_object ( agent) {
658- Some ( backing_object) => ordinary_try_has_property ( agent, backing_object, property_key, gc) ,
693+ Some ( backing_object) => ordinary_try_has_property (
694+ agent,
695+ object. into_object ( ) ,
696+ backing_object,
697+ property_key,
698+ gc,
699+ ) ,
659700 None => {
660701 // 3. Let parent be ? O.[[GetPrototypeOf]]().
661702 let parent = unwrap_try ( object. try_get_prototype_of ( agent, gc) ) ;
@@ -665,6 +706,18 @@ pub(crate) fn ordinary_try_has_property_entry<'a>(
665706 // a. Return ? parent.[[HasProperty]](P).
666707 parent. try_has_property ( agent, property_key, gc)
667708 } else {
709+ if let Some ( CacheToPopulate {
710+ receiver : _,
711+ cache,
712+ key : _,
713+ shape,
714+ } ) = agent
715+ . heap
716+ . caches
717+ . take_current_cache_to_populate ( property_key)
718+ {
719+ cache. insert_unset ( agent, shape) ;
720+ }
668721 // 5. Return false.
669722 TryResult :: Continue ( false )
670723 }
@@ -675,26 +728,47 @@ pub(crate) fn ordinary_try_has_property_entry<'a>(
675728/// ### [10.1.7.1 OrdinaryHasProperty ( O, P )](https://tc39.es/ecma262/#sec-ordinaryhasproperty)
676729pub ( crate ) fn ordinary_has_property < ' a > (
677730 agent : & mut Agent ,
678- object : OrdinaryObject ,
731+ object : Object ,
732+ backing_object : OrdinaryObject ,
679733 property_key : PropertyKey ,
680734 gc : GcScope < ' a , ' _ > ,
681735) -> JsResult < ' a , bool > {
682- let object = object . bind ( gc. nogc ( ) ) ;
736+ let backing_object = backing_object . bind ( gc. nogc ( ) ) ;
683737 let property_key = property_key. bind ( gc. nogc ( ) ) ;
684738 // 1. Let hasOwn be ? O.[[GetOwnProperty]](P).
685739
686- let has_own = object
740+ let has_own = backing_object
687741 . object_shape ( agent)
688742 . keys ( & agent. heap . object_shapes , & agent. heap . elements )
689- . contains ( & property_key) ;
743+ . iter ( )
744+ . enumerate ( )
745+ . find ( |( _, p) | * p == & property_key)
746+ . map ( |( i, _) | i as u32 ) ;
690747
691748 // 2. If hasOwn is not undefined, return true.
692- if has_own {
749+ if let Some ( offset) = has_own {
750+ if let Some ( CacheToPopulate {
751+ receiver,
752+ cache,
753+ key : _,
754+ shape,
755+ } ) = agent
756+ . heap
757+ . caches
758+ . take_current_cache_to_populate ( property_key)
759+ {
760+ let is_receiver = object. into_value ( ) == receiver;
761+ if is_receiver {
762+ cache. insert_lookup_offset ( agent, shape, offset) ;
763+ } else {
764+ cache. insert_prototype_lookup_offset ( agent, shape, offset, object) ;
765+ }
766+ }
693767 return Ok ( true ) ;
694- }
768+ } ;
695769
696770 // 3. Let parent be ? O.[[GetPrototypeOf]]().
697- let parent = object . internal_prototype ( agent) . bind ( gc. nogc ( ) ) ;
771+ let parent = backing_object . internal_prototype ( agent) . bind ( gc. nogc ( ) ) ;
698772
699773 // 4. If parent is not null, then
700774 if let Some ( parent) = parent {
@@ -704,6 +778,19 @@ pub(crate) fn ordinary_has_property<'a>(
704778 . internal_has_property ( agent, property_key. unbind ( ) , gc) ;
705779 }
706780
781+ if let Some ( CacheToPopulate {
782+ receiver : _,
783+ cache,
784+ key : _,
785+ shape,
786+ } ) = agent
787+ . heap
788+ . caches
789+ . take_current_cache_to_populate ( property_key)
790+ {
791+ cache. insert_unset ( agent, shape) ;
792+ }
793+
707794 // 5. Return false.
708795 Ok ( false )
709796}
@@ -716,9 +803,13 @@ pub(crate) fn ordinary_has_property_entry<'a, 'gc>(
716803) -> JsResult < ' gc , bool > {
717804 let property_key = property_key. bind ( gc. nogc ( ) ) ;
718805 match object. get_backing_object ( agent) {
719- Some ( backing_object) => {
720- ordinary_has_property ( agent, backing_object, property_key. unbind ( ) , gc)
721- }
806+ Some ( backing_object) => ordinary_has_property (
807+ agent,
808+ object. into_object ( ) ,
809+ backing_object,
810+ property_key. unbind ( ) ,
811+ gc,
812+ ) ,
722813 None => {
723814 // 3. Let parent be ? O.[[GetPrototypeOf]]().
724815 let parent = unwrap_try ( object. try_get_prototype_of ( agent, gc. nogc ( ) ) ) ;
0 commit comments