Repository navigation
@cppvtable: methods returning a record through MSVC's hidden pointer - #551
Merged
Merged
Conversation
MSVC returns a record (struct or class, RefCountPtr<T> included) from a C++ instance method through a hidden pointer. The pointer is passed after `this` and returned as well (clang's MicrosoftCXXABI::classifyReturnType). A @cppvtable method declared to return a tuple now uses that convention: - its slot is called as (this, Ref<T>, args...) -> Ref<T>; - a call passes a local of T and reads it back, so the call's value is the record; - DeclarationPrinter keeps the declared type, so an importing module lowers it again. Before this, the hidden pointer had to be declared as a parameter. The Itanium ABI passes the pointer before `this`, and only for some records, so on a non-MSVC target such a method is an error (TargetInfo::hiddenReturnPointerAfterThis). Tests: - 00cppvtable_hidden_return.ts covers 8- and 24-byte records and a scalar slot next to them, compiled and JIT; - export/import_cppvtable_class cover a record returned across modules; - cppvtable/hidden_return_target.ts checks the non-MSVC error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ved class Co-Authored-By: Claude Opus 5.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.
Summary
A
@cppvtablemethod can now be declared to return a struct by value, such as NVRHI'sRefCountPtr<T>ornvrhi::Object. You declare the return type as a tuple with the struct's layout:MSVC returns any struct or class from a C++ instance method through a hidden pointer. The pointer is passed after
this, and the method returns it as well (clang'sMicrosoftCXXABI::classifyReturnType). Until now, tslang code had to declare that pointer as a parameter itself:createBuffer(ret: Ref<Opaque | null>, desc: Ref<BufferDesc>): Opaque.How it works
mlirGenClassCppVTableHiddenReturnchanges the slot type to(this, Ref<T>, args...) -> Ref<T>. The method's info still records the declared type, soDeclarationPrinterprints that and an importing module lowers it again.Tand passes it afterthis. The call's value is that local, read back. The arguments' contextual types are shifted by one.this, and only for some structs. On a target withoutTargetInfo::hiddenReturnPointerAfterThis(any non-MSVC target), such a method is a compile error.Tests
00cppvtable_hidden_return.ts(compiled and JIT): returns an 8-byte and a 24-byte struct, with a plain scalar method in the same vtable. It also calls a base class's struct-returning method through a derived@cppvtableclass.export_cppvtable_hidden_return.ts/import_cppvtable_hidden_return.ts(compiled and JIT): a method declared in the exporting module returns a struct, called from both modules.These tests run on Windows only (
if (WIN32)), because on any other target such a method is an error.cppvtable/hidden_return_target.ts: checks the compile error onx86_64-unknown-linux-gnu.Full suite: 3999/3999 pass (
ctest -C Release, windows-msbuild-2026-release).Real NVRHI: in a temporary copy of native_ts_graphics'
core/nvrhi.ts, I switched these to the new form:IDevice::createBufferandIDevice::createCommandList, returningRefCountPtr;IResource::getNativeObject, returningnvrhi::Object.examples/nvrhi_direct.tspassed on D3D12 and on Vulkan, with the debug layers on (-debug).After this is in a release
native_ts_graphics'
core/nvrhi.tscan drop the explicitretparameters:createBuffer,createTexture,createCommandList,createComputePipeline,getNativeObjectandgetNativeQueuecan returnRefCountPtrorNativeObjecttuples.🤖 Generated with Claude Code