Fix dynamic array parameters and results on the Rtti.Invoke call path#301
Open
TetzkatLipHoka wants to merge 1 commit into
Open
Fix dynamic array parameters and results on the Rtti.Invoke call path#301TetzkatLipHoka wants to merge 1 commit into
TetzkatLipHoka wants to merge 1 commit into
Conversation
Imported (host) functions called through the Rtti.Invoke path (the default since XE2; PS_USECLASSICINVOKE was not affected) mishandled dynamic arrays in two ways: 1. By-value dynamic array parameters passed the address of the script's variable slot instead of the array pointer stored in it. The callee then interpreted the slot address as an array reference and crashed with an access violation (reproducible on Win32 and Win64). 2. Dynamic array results were only retrieved when a host RTTI type could be located whose name ends with the script type's exported name. Script types are usually not name-exported, so the lookup found nothing - and because the Invoke call sat inside the search loop, the imported function was then never called at all: the script silently received an empty array (and none of the function's side effects). The empty-result path additionally corrupted the result IFC record by setting res.dta to nil. The parameter case now passes the dereferenced array pointer. The result case selects a type info matching the managed kind of the element type (Invoke only needs it for the - universally identical - dynamic array result ABI and for releasing the TValue's reference; the element-wise transfer into the script slot goes through the script's own type record). The host-type name lookup remains as the path for nested container elements, and a failed lookup now fails the call instead of faking an empty result. Empty results clear the script slot properly via CopyArrayContents. Related: remobjects#198 (the FPC report covers the classic x86 path, but the same symptom class exists here on the default path). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Imported (host) functions called through the Rtti.Invoke path (the
default since XE2; PS_USECLASSICINVOKE was not affected) mishandled
dynamic arrays in two ways:
By-value dynamic array parameters passed the address of the script's
variable slot instead of the array pointer stored in it. The callee
then interpreted the slot address as an array reference and crashed
with an access violation (reproducible on Win32 and Win64).
Dynamic array results were only retrieved when a host RTTI type
could be located whose name ends with the script type's exported
name. Script types are usually not name-exported, so the lookup
found nothing - and because the Invoke call sat inside the search
loop, the imported function was then never called at all: the script
silently received an empty array (and none of the function's side
effects). The empty-result path additionally corrupted the result
IFC record by setting res.dta to nil.
The parameter case now passes the dereferenced array pointer. The
result case selects a type info matching the managed kind of the
element type (Invoke only needs it for the - universally identical -
dynamic array result ABI and for releasing the TValue's reference;
the element-wise transfer into the script slot goes through the
script's own type record). The host-type name lookup remains as the
path for nested container elements, and a failed lookup now fails the
call instead of faking an empty result. Empty results clear the script
slot properly via CopyArrayContents.
Related: #198 (the FPC report covers the classic x86 path, but the
same symptom class exists here on the default path).
Related: #198 (same symptom class on the Rtti invoke path).
🤖 Generated with Claude Code