Skip to content

[mono] interpreter doesn't extend smaller integer values to register size upon return for arm64 #110649

@rolfbjarne

Description

@rolfbjarne

Description

The interpreter doesn't zero-extend smaller integer values to register size for x0 upon return to native code from functions for arm64.

The test case in question creates an NSPredicate using a block, which is implemented in managed code. The block callback is internally implemented like this:

[UnmanagedCallersOnly]
static unsafe byte Invoke (IntPtr block, NativeHandle evaluatedObject, NativeHandle bindings) {
	var retval = /* call the Evaluator function from the test case */
	return retval ? (byte) 1 : (byte) 0;
}

Upon return from this function, lldb says x0 isn't 0:

(lldb) p/x $x0
(unsigned long) 0x0000600001d64000

while it's 0 when not using the interpreter.

This is the equivalent Objective-C code:

NSPredicate* p = [NSPredicate predicateWithBlock:^BOOL(id item, NSDictionary *bindings)
{
    return FALSE;
}];

which is compiled into:

(lldb) disassemble
iosapitest`__57-[AppDelegate application:didFinishLaunchingWithOptions:]_block_invoke:
->  0x100a2e250 <+0>: mov    w0, #0x0                  ; =0 
    0x100a2e254 <+4>: ret    

Reproduction Steps

Test project: maccatalyst-plain-8d667e2.zip

Do this:

dotnet build
./bin/Debug/net9.0-maccatalyst/maccatalyst-arm64/maccatalyst-plain.app/Contents/MacOS/maccatalyst-plain

Expected behavior

It should print:

✅ SUCCESS

Actual behavior

Prints:

❌ FAIL

Regression?

Not sure

Known Workarounds

Don't use the interpreter

Configuration

.NET 9

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions