| 1 |
/** |
|---|
| 2 |
* Copyright: Copyright (c) 2009 Jacob Carlborg. |
|---|
| 3 |
* Authors: Jacob Carlborg |
|---|
| 4 |
* Version: Initial created: Feb 1, 2009 |
|---|
| 5 |
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) |
|---|
| 6 |
*/ |
|---|
| 7 |
module dstep.objc.message; |
|---|
| 8 |
|
|---|
| 9 |
import dstep.internal.Version; |
|---|
| 10 |
import bindings = dstep.objc.bindings; |
|---|
| 11 |
import dstep.objc.objc; |
|---|
| 12 |
import dstep.objc.runtime; |
|---|
| 13 |
|
|---|
| 14 |
alias void* marg_list; |
|---|
| 15 |
|
|---|
| 16 |
version (X86) |
|---|
| 17 |
const int STRUCT_SIZE_LIMIT = 8; |
|---|
| 18 |
|
|---|
| 19 |
else version (PPC) |
|---|
| 20 |
const int STRUCT_SIZE_LIMIT = 4; |
|---|
| 21 |
|
|---|
| 22 |
else version (X86_64) |
|---|
| 23 |
const int STRUCT_SIZE_LIMIT = 16; |
|---|
| 24 |
|
|---|
| 25 |
else version (PPC64) // Not sure about this |
|---|
| 26 |
const int STRUCT_SIZE_LIMIT = 16; |
|---|
| 27 |
|
|---|
| 28 |
/** |
|---|
| 29 |
* Specifies the superclass of an instance. |
|---|
| 30 |
* |
|---|
| 31 |
* The compiler generates an objc_super data structure when it encounters the super |
|---|
| 32 |
* keyword as the receiver of a message. It specifies the class definition of the |
|---|
| 33 |
* particular superclass that should be messaged. |
|---|
| 34 |
*/ |
|---|
| 35 |
struct objc_super |
|---|
| 36 |
{ |
|---|
| 37 |
/** |
|---|
| 38 |
* A pointer of type $(DSTEP_EXTERNAL_SYMBOL dstep.objc.objc, id). |
|---|
| 39 |
* Specifies an instance of a class. |
|---|
| 40 |
*/ |
|---|
| 41 |
id receiver; |
|---|
| 42 |
|
|---|
| 43 |
/** |
|---|
| 44 |
* A pointer to an $(DIL_EXTERNAL_SYMBOL dstep.objc.objc, Class) data |
|---|
| 45 |
* structure. Specifies the particular superclass of the instance to message. |
|---|
| 46 |
*/ |
|---|
| 47 |
Class super_class; |
|---|
| 48 |
|
|---|
| 49 |
// for dwt compatibility |
|---|
| 50 |
alias super_class cls; |
|---|
| 51 |
|
|---|
| 52 |
R msgSendSuper (R = id, ARGS...) (SEL op, ARGS args) |
|---|
| 53 |
{ |
|---|
| 54 |
alias extern (C) R function (objc_super*, SEL, ARGS) fp; |
|---|
| 55 |
return (cast(fp)&bindings.objc_msgSendSuper)(this, op, args); |
|---|
| 56 |
} |
|---|
| 57 |
|
|---|
| 58 |
void msgSendSuper_stret (T, ARGS...) (out T stretAddr, id self, SEL op, ARGS args) |
|---|
| 59 |
{ |
|---|
| 60 |
if (T.sizeof > STRUCT_SIZE_LIMIT) |
|---|
| 61 |
{ |
|---|
| 62 |
alias extern (C) void function (T*, objc_super*, SEL, ARGS) fp; |
|---|
| 63 |
(cast(fp)&bindings.objc_msgSendSuper_stret)(&stretAddr, self, op, args); |
|---|
| 64 |
} |
|---|
| 65 |
|
|---|
| 66 |
else |
|---|
| 67 |
{ |
|---|
| 68 |
alias extern (C) T function (objc_super*, SEL, ARGS) fp; |
|---|
| 69 |
stretAddr = (*cast(fp)&bindings.objc_msgSendSuper)(self, op, args); |
|---|
| 70 |
} |
|---|
| 71 |
} |
|---|
| 72 |
} |
|---|
| 73 |
|
|---|
| 74 |
R objc_msgSend (R = id, ARGS...) (id self, SEL op, ARGS args) |
|---|
| 75 |
{ |
|---|
| 76 |
alias extern (C) R function (id, SEL, ARGS) fp; |
|---|
| 77 |
return (cast(fp)&bindings.objc_msgSend)(self, op, args); |
|---|
| 78 |
} |
|---|
| 79 |
|
|---|
| 80 |
R objc_msgSendSuper (R = id, ARGS...) (objc_super* super_, SEL op, ARGS args) |
|---|
| 81 |
{ |
|---|
| 82 |
alias extern (C) R function (objc_super*, SEL, ARGS) fp; |
|---|
| 83 |
return (cast(fp)&bindings.objc_msgSendSuper)(super_, op, args); |
|---|
| 84 |
} |
|---|
| 85 |
|
|---|
| 86 |
void objc_msgSend_stret (T, ARGS...) (out T stretAddr, id self, SEL op, ARGS args) |
|---|
| 87 |
{ |
|---|
| 88 |
if (T.sizeof > STRUCT_SIZE_LIMIT) |
|---|
| 89 |
{ |
|---|
| 90 |
alias extern (C) void function (T*, id, SEL, ARGS) fp; |
|---|
| 91 |
(cast(void function (fp))&bindings.objc_msgSend_stret)(&stretAddr, self, op, args); |
|---|
| 92 |
} |
|---|
| 93 |
|
|---|
| 94 |
else |
|---|
| 95 |
{ |
|---|
| 96 |
alias extern (C) T function (id, SEL, ARGS) fp; |
|---|
| 97 |
stretAddr = (*cast(fp)&bindings.objc_msgSend)(self, op, args); |
|---|
| 98 |
} |
|---|
| 99 |
} |
|---|
| 100 |
|
|---|
| 101 |
static if (X86 || X86_64) |
|---|
| 102 |
{ |
|---|
| 103 |
R objc_msgSend_fpret (R = id, ARGS...) (id self, SEL op, ARGS args) |
|---|
| 104 |
{ |
|---|
| 105 |
version (X86_64) |
|---|
| 106 |
static assert(!is(R : real), "Only real are legal return value for objc_msgSend_fpret"); |
|---|
| 107 |
|
|---|
| 108 |
else |
|---|
| 109 |
static assert(!is(R : double) && !is(R : float), "Only double and float are legal return values for objc_msgSend_fpret"); |
|---|
| 110 |
|
|---|
| 111 |
alias extern (C) R function (id, SEL, ARGS) fp; |
|---|
| 112 |
return (cast(fp)&bindings.objc_msgSend_fpret)(self, op, args); |
|---|
| 113 |
} |
|---|
| 114 |
} |
|---|
| 115 |
|
|---|
| 116 |
R method_invoke (R = id, ARGS...) (id receiver, Method m, ARGS args) |
|---|
| 117 |
{ |
|---|
| 118 |
alias extern (C) R function (id, SEL, ARGS) fp; |
|---|
| 119 |
return (cast(fp)&bindings.method_invoke)(receiver, m, args); |
|---|
| 120 |
} |
|---|
| 121 |
|
|---|
| 122 |
void method_invoke_stret (ARGS...) (id receiver, Method m, ARGS args) |
|---|
| 123 |
{ |
|---|
| 124 |
alias extern (C) R function (id, SEL, ARGS) fp; |
|---|
| 125 |
return (cast(fp)&bindings.method_invoke_stret)(receiver, m, args); |
|---|
| 126 |
} |
|---|
| 127 |
|
|---|
| 128 |
R objc_msgSendv (R = id, T) (id self, SEL op, size_t arg_size, T arg_frame) |
|---|
| 129 |
{ |
|---|
| 130 |
alias extern (C) R function (id, SEL, size_t, T) fp; |
|---|
| 131 |
(cast(fp)&bindings.objc_msgSendv)(self, op, arg_size, arg_frame); |
|---|
| 132 |
} |
|---|
| 133 |
|
|---|
| 134 |
void objc_msgSendv_stret (R = id, T) (out T stretAddr, id self, SEL op, size_t arg_size, T arg_frame) |
|---|
| 135 |
{ |
|---|
| 136 |
if (R.sizeof > STRUCT_SIZE_LIMIT) |
|---|
| 137 |
{ |
|---|
| 138 |
alias extern (C) void function (R*, id, SEL, size_t, T) fp; |
|---|
| 139 |
(cast(fp)&bindings.objc_msgSendv_stret)(&stretAddr, self, op, arg_size, arg_frame); |
|---|
| 140 |
} |
|---|
| 141 |
|
|---|
| 142 |
else |
|---|
| 143 |
{ |
|---|
| 144 |
alias extern (C) R function (id, SEL, size_t, T) fp; |
|---|
| 145 |
stretAddr = (*cast(fp)&bindings.objc_msgSendv)(self, op, arg_size, arg_frame); |
|---|
| 146 |
} |
|---|
| 147 |
} |
|---|
| 148 |
|
|---|
| 149 |
version (X86) |
|---|
| 150 |
{ |
|---|
| 151 |
R objc_msgSendv_fpret (R = id, T) (id self, SEL op, uint arg_size, T arg_frame) |
|---|
| 152 |
{ |
|---|
| 153 |
static assert(!is(R : double) && !is(R : float), "Only double and float are legal return values for objc_msgSendv_fpret"); |
|---|
| 154 |
alias extern (C) R function (id, SEL, uint, T) fp; |
|---|
| 155 |
return (cast(fp)&bindings.objc_msgSendv_fpret)(self, op, arg_size, arg_frame); |
|---|
| 156 |
} |
|---|
| 157 |
} |
|---|