* [runtime] Make debug spew compile. * [tests] Add test case for bug #58367. https://bugzilla.xamarin.com/show_bug.cgi?id=58367 * [runtime] Parameters passed on the stack use at least 8 bytes on x86-64. Fixes #58367. https://bugzilla.xamarin.com/show_bug.cgi?id=58367
This commit is contained in:
Родитель
336087ff59
Коммит
f2d0a80699
|
@ -241,7 +241,7 @@ param_iter_next (enum IteratorAction action, void *context, const char *type, si
|
|||
it->byte_count = (it->state->type & Tramp_Stret) == Tramp_Stret ? 24 : 16;
|
||||
it->float_count = 0;
|
||||
it->stack_next = (uint8_t *) (2 + (uint64_t *) it->state->rbp);
|
||||
LOGZ("initialized parameter iterator to %p stret to %p\n", it->stack_next, it->stret);
|
||||
LOGZ("initialized parameter iterator. byte count: %i stack next: %p\n", it->byte_count, it->stack_next);
|
||||
return;
|
||||
} else if (action == IteratorEnd) {
|
||||
return;
|
||||
|
@ -294,7 +294,12 @@ param_iter_next (enum IteratorAction action, void *context, const char *type, si
|
|||
it->float_count++;
|
||||
if (it->byte_count % 8 != 0)
|
||||
it->byte_count += 8 - it->byte_count % 8;
|
||||
// CHECK: do we need to round the stack pointer to?
|
||||
// All arguments use at least 8 bytes, so round up.
|
||||
uintptr_t stack_next = (uintptr_t) it->stack_next;
|
||||
if ((stack_next % 8) != 0) {
|
||||
stack_next += 8 - stack_next % 8;
|
||||
it->stack_next = (uint8_t *) stack_next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -203,6 +203,11 @@ namespace Bindings.Test {
|
|||
[Export ("idAsIntPtr:")]
|
||||
void IdAsIntPtr (IntPtr id);
|
||||
|
||||
[Export ("outNSErrorOnStack:i:i:i:i:i:err:")]
|
||||
void OutNSErrorOnStack (int i1, int i2, int i3, int i4, int i5, int i6, out NSError error);
|
||||
|
||||
[Export ("outNSErrorOnStack:obj:obj:int64:i:err:")]
|
||||
void OutNSErrorOnStack (NSObject i1, NSObject i2, NSObject i3, long i4, int i5, out NSError error);
|
||||
}
|
||||
|
||||
[BaseType (typeof (NSObject))]
|
||||
|
|
|
@ -75,6 +75,12 @@ namespace MonoTouch.ObjCRuntime
|
|||
[DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
|
||||
public extern static void void_objc_msgSend_int (IntPtr receiver, IntPtr selector, int value);
|
||||
|
||||
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
|
||||
public extern static void void_objc_msgSend_int_int_int_int_int_int_IntPtr (IntPtr receiver, IntPtr selector, int p1, int p2, int p3, int p4, int p5, int p6, IntPtr p7);
|
||||
|
||||
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
|
||||
public extern static void void_objc_msgSend_IntPtr_IntPtr_IntPtr_long_int_IntPtr (IntPtr receiver, IntPtr selector, IntPtr p1, IntPtr p2, IntPtr p3, long p4, int p5, IntPtr p7);
|
||||
|
||||
[DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
|
||||
public extern static void void_objc_msgSend_long (IntPtr receiver, IntPtr selector, long value);
|
||||
|
||||
|
|
|
@ -1736,6 +1736,68 @@ namespace MonoTouchFixtures.ObjCRuntime {
|
|||
Assert.AreEqual (IntPtr.Zero, id, "Zero");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutNSErrorOnStack1 ()
|
||||
{
|
||||
using (var obj = new OutNSErrorOnStackClass ()) {
|
||||
Messaging.void_objc_msgSend_int_int_int_int_int_int_IntPtr (obj.Handle, Selector.GetHandle ("outNSErrorOnStack:i:i:i:i:i:err:"), 0, 0, 0, 0, 0, 0, IntPtr.Zero);
|
||||
|
||||
var ptr = Marshal.AllocHGlobal (IntPtr.Size);
|
||||
Marshal.WriteIntPtr (ptr, IntPtr.Zero);
|
||||
Console.WriteLine ("ptr: 0x{0} = 0x{1}", ptr.ToString ("x"), Marshal.ReadIntPtr (ptr));
|
||||
Messaging.void_objc_msgSend_int_int_int_int_int_int_IntPtr (obj.Handle, Selector.GetHandle ("outNSErrorOnStack:i:i:i:i:i:err:"), 0, 0, 0, 0, 0, 0, ptr);
|
||||
Assert.AreEqual (IntPtr.Zero, Marshal.ReadIntPtr (ptr), "#1");
|
||||
Marshal.FreeHGlobal (ptr);
|
||||
|
||||
ptr = IntPtr.Zero;
|
||||
unsafe {
|
||||
IntPtr* ptrFixed = &ptr;
|
||||
Console.WriteLine ("ptr: 0x{0}", ptr.ToString ("x"));
|
||||
Messaging.void_objc_msgSend_int_int_int_int_int_int_IntPtr (obj.Handle, Selector.GetHandle ("outNSErrorOnStack:i:i:i:i:i:err:"), 0, 0, 0, 0, 0, 0, (IntPtr) ptrFixed);
|
||||
Assert.AreEqual (IntPtr.Zero, ptr, "#2");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutNSErrorOnStack2 ()
|
||||
{
|
||||
using (var obj = new OutNSErrorOnStackClass ()) {
|
||||
Messaging.void_objc_msgSend_IntPtr_IntPtr_IntPtr_long_int_IntPtr (obj.Handle, Selector.GetHandle ("outNSErrorOnStack:obj:obj:int64:i:err:"), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 1, 2, IntPtr.Zero);
|
||||
|
||||
var ptr = Marshal.AllocHGlobal (IntPtr.Size);
|
||||
Marshal.WriteIntPtr (ptr, IntPtr.Zero);
|
||||
Console.WriteLine ("ptr: 0x{0} = 0x{1}", ptr.ToString ("x"), Marshal.ReadIntPtr (ptr));
|
||||
Messaging.void_objc_msgSend_IntPtr_IntPtr_IntPtr_long_int_IntPtr (obj.Handle, Selector.GetHandle ("outNSErrorOnStack:obj:obj:int64:i:err:"), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 1, 2, ptr);
|
||||
Assert.AreEqual (IntPtr.Zero, Marshal.ReadIntPtr (ptr), "#1");
|
||||
Marshal.FreeHGlobal (ptr);
|
||||
|
||||
ptr = IntPtr.Zero;
|
||||
unsafe {
|
||||
IntPtr* ptrFixed = &ptr;
|
||||
Console.WriteLine ("ptr: 0x{0}", ptr.ToString ("x"));
|
||||
Messaging.void_objc_msgSend_IntPtr_IntPtr_IntPtr_long_int_IntPtr (obj.Handle, Selector.GetHandle ("outNSErrorOnStack:obj:obj:int64:i:err:"), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 1, 2, (IntPtr) ptrFixed);
|
||||
Assert.AreEqual (IntPtr.Zero, ptr, "#2");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class OutNSErrorOnStackClass : ObjCRegistrarTest
|
||||
{
|
||||
public override void OutNSErrorOnStack (int i1, int i2, int i3, int i4, int i5, int i6, out NSError error)
|
||||
{
|
||||
error = null;
|
||||
}
|
||||
|
||||
public override void OutNSErrorOnStack (NSObject i1, NSObject i2, NSObject i3, long i4, int i5, out NSError error)
|
||||
{
|
||||
Assert.AreEqual (i4, 1, "#long");
|
||||
Assert.AreEqual (i5, 2, "#int");
|
||||
error = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !__TVOS__ && !__WATCHOS__ && !MONOMAC
|
||||
|
|
|
@ -85,6 +85,8 @@ typedef unsigned int (^RegistrarTestBlock) (unsigned int magic);
|
|||
-(bool) testBlocks;
|
||||
|
||||
-(void) idAsIntPtr: (id)p1;
|
||||
-(void) outNSErrorOnStack:(int)i1 i:(int)i2 i:(int)i3 i:(int)i4 i:(int)i5 i:(int)i6 err:(NSError **)err; // 6 in regs, 7th (out) in mem (on all architectures)
|
||||
-(void) outNSErrorOnStack:(id)obj1 obj:(id)obj2 obj:(id)obj3 int64:(long long)l4 i:(int)i5 err:(NSError **)err; // 5 in regs, 6th (out) in mem (on at least x86-64)
|
||||
@end
|
||||
|
||||
/*
|
||||
|
|
|
@ -199,6 +199,17 @@ static UltimateMachine *shared;
|
|||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
-(void) outNSErrorOnStack:(int)i1 i:(int)i2 i:(int)i3 i:(int)i4 i:(int)i5 i:(int)i6 err:(NSError **)err
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
|
||||
-(void) outNSErrorOnStack:(id)obj1 obj:(id)obj2 obj:(id)obj3 int64:(long long)l4 i:(int)i5 err:(NSError **)err
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ObjCExceptionTest
|
||||
|
|
Загрузка…
Ссылка в новой задаче