@@ -565,7 +565,7 @@ inline uintptr_t normalizeRuntimePointer(uintptr_t pointer) {
565565 std::shared_ptr<Value> value;
566566 bool stringLikeNative = false ;
567567 bool persistBeyondFrame = true ;
568- uintptr_t objectClassKey = 0 ;
568+ uintptr_t validationKey = 0 ;
569569 };
570570 using NativeApiRoundTripReleaseList =
571571 std::vector<NativeApiRoundTripValue>;
@@ -657,9 +657,20 @@ explicit NativeApiBridge(const NativeApiConfig& config)
657657 return it != functionSymbolsByName_.end () ? &it->second : nullptr ;
658658 }
659659
660+ static uintptr_t callbackRoundTripValidationKey (
661+ const NativeApiType& type) {
662+ if (type.signatureOffset == 0 ||
663+ type.signatureOffset == MD_SECTION_OFFSET_NULL ) {
664+ return 0 ;
665+ }
666+ return (static_cast <uintptr_t >(type.signatureOffset ) << 8 ) |
667+ (static_cast <uintptr_t >(type.kind ) & 0xff );
668+ }
669+
660670 void rememberRoundTripValue (Runtime& runtime, const void * native,
661671 const Value& value,
662- bool stringLikeNative = false ) {
672+ bool stringLikeNative = false ,
673+ uintptr_t validationKey = 0 ) {
663674 if (native == nullptr ) {
664675 return ;
665676 }
@@ -672,7 +683,7 @@ void rememberRoundTripValue(Runtime& runtime, const void* native,
672683 roundTripValues_, key,
673684 NativeApiRoundTripValue{
674685 std::make_shared<Value>(runtime, value), stringLikeNative, true ,
675- 0 },
686+ validationKey },
676687 releaseAfterUnlock);
677688 roundTripValuesGeneration_.fetch_add (1 , std::memory_order_release);
678689 }
@@ -685,7 +696,7 @@ void rememberScopedRoundTripValue(Runtime& runtime, const void* native,
685696 const Value& value,
686697 bool stringLikeNative = false ,
687698 bool persistBeyondFrame = true ) {
688- rememberScopedRoundTripValueWithClassKey (
699+ rememberScopedRoundTripValueWithValidationKey (
689700 runtime, native, value, stringLikeNative, persistBeyondFrame,
690701 nativeObjectClassKey (native));
691702 }
@@ -694,26 +705,26 @@ void rememberScopedRawRoundTripValue(Runtime& runtime, const void* native,
694705 const Value& value,
695706 bool stringLikeNative = false ,
696707 bool persistBeyondFrame = true ) {
697- rememberScopedRoundTripValueWithClassKey (runtime, native, value,
698- stringLikeNative,
699- persistBeyondFrame, 0 );
708+ rememberScopedRoundTripValueWithValidationKey (runtime, native, value,
709+ stringLikeNative,
710+ persistBeyondFrame, 0 );
700711 }
701712
702- void rememberScopedRoundTripValueWithClassKey (Runtime& runtime,
703- const void * native,
704- const Value& value,
705- bool stringLikeNative,
706- bool persistBeyondFrame,
707- uintptr_t objectClassKey ) {
713+ void rememberScopedRoundTripValueWithValidationKey (Runtime& runtime,
714+ const void * native,
715+ const Value& value,
716+ bool stringLikeNative,
717+ bool persistBeyondFrame,
718+ uintptr_t validationKey ) {
708719 if (native == nullptr ) {
709720 return ;
710721 }
711722 uintptr_t key =
712723 normalizeRuntimePointer (reinterpret_cast <uintptr_t >(native));
713724 NativeApiRoundTripValue entry{
714725 std::make_shared<Value>(runtime, value), stringLikeNative,
715- persistBeyondFrame, objectClassKey };
716- NativeApiRoundTripReleaseList releaseAfterUnlock;
726+ persistBeyondFrame, validationKey };
727+ NativeApiRoundTripReleaseList releaseAfterUnlock;
717728 {
718729 std::lock_guard<std::mutex> lock (roundTripValuesMutex_);
719730 auto framesIt =
@@ -732,7 +743,8 @@ void rememberScopedRoundTripValueWithClassKey(Runtime& runtime,
732743
733744 Value findRoundTripValue (Runtime& runtime, const void * native,
734745 bool * stringLikeNative = nullptr ,
735- bool nativeIsObject = false ) {
746+ bool nativeIsObject = false ,
747+ uintptr_t validationKey = 0 ) {
736748 if (stringLikeNative != nullptr ) {
737749 *stringLikeNative = false ;
738750 }
@@ -741,13 +753,18 @@ Value findRoundTripValue(Runtime& runtime, const void* native,
741753 }
742754 uintptr_t key =
743755 normalizeRuntimePointer (reinterpret_cast <uintptr_t >(native));
756+ const uintptr_t expectedValidationKey =
757+ validationKey != 0
758+ ? validationKey
759+ : (nativeIsObject ? nativeObjectClassKey (native) : 0 );
744760 struct RoundTripCacheEntry {
745761 const NativeApiBridge* bridge = nullptr ;
746762 uintptr_t key = 0 ;
747763 uint64_t generation = 0 ;
748764 std::weak_ptr<Value> value;
749765 bool miss = false ;
750766 bool stringLikeNative = false ;
767+ uintptr_t validationKey = 0 ;
751768 };
752769 static thread_local RoundTripCacheEntry cache[4 ];
753770 const uint64_t generation =
@@ -757,6 +774,9 @@ Value findRoundTripValue(Runtime& runtime, const void* native,
757774 RoundTripCacheEntry& entry = cache[(firstSlot + i) & 3 ];
758775 if (entry.bridge == this && entry.key == key &&
759776 entry.generation == generation) {
777+ if (entry.validationKey != expectedValidationKey) {
778+ break ;
779+ }
760780 if (entry.miss ) {
761781 return Value::undefined ();
762782 }
@@ -782,11 +802,8 @@ Value findRoundTripValue(Runtime& runtime, const void* native,
782802 if (it == map.end () || it->second .value == nullptr ) {
783803 return nullptr ;
784804 }
785- if (it->second .objectClassKey != 0 ) {
786- if (!nativeIsObject ||
787- it->second .objectClassKey != nativeObjectClassKey (native)) {
788- return nullptr ;
789- }
805+ if (it->second .validationKey != expectedValidationKey) {
806+ return nullptr ;
790807 }
791808 return &it->second ;
792809 };
@@ -809,14 +826,15 @@ Value findRoundTripValue(Runtime& runtime, const void* native,
809826 entry = findEntry (recentRoundTripValues_);
810827 }
811828 if (entry == nullptr ) {
812- cache[firstSlot] =
813- RoundTripCacheEntry{ this , key, generation, {}, true , false };
829+ cache[firstSlot] = RoundTripCacheEntry{
830+ this , key, generation, {}, true , false , expectedValidationKey };
814831 return Value::undefined ();
815832 }
816833 storedValue = entry->value ;
817834 cachedStringLike = entry->stringLikeNative ;
818835 cache[firstSlot] = RoundTripCacheEntry{
819- this , key, generation, storedValue, false , cachedStringLike};
836+ this , key, generation, storedValue, false , cachedStringLike,
837+ entry->validationKey };
820838 }
821839 if (stringLikeNative != nullptr ) {
822840 *stringLikeNative = cachedStringLike;
0 commit comments