Skip to content

Fix dynamic array parameters and results on the Rtti.Invoke call path#301

Open
TetzkatLipHoka wants to merge 1 commit into
remobjects:masterfrom
TetzkatLipHoka:fix/invokecall-dynarrays
Open

Fix dynamic array parameters and results on the Rtti.Invoke call path#301
TetzkatLipHoka wants to merge 1 commit into
remobjects:masterfrom
TetzkatLipHoka:fix/invokecall-dynarrays

Conversation

@TetzkatLipHoka

Copy link
Copy Markdown

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: #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

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant