objc-js 0.0.14 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.gyp +2 -1
- package/build/Release/nobjc_native.node +0 -0
- package/package.json +2 -1
- package/src/native/ObjcObject.mm +2 -14
- package/src/native/bridge.h +20 -0
- package/src/native/constants.h +42 -0
- package/src/native/ffi-utils.h +103 -1
- package/src/native/forwarding-common.h +87 -0
- package/src/native/forwarding-common.mm +155 -0
- package/src/native/memory-utils.h +197 -0
- package/src/native/method-forwarding.mm +137 -208
- package/src/native/nobjc.mm +7 -31
- package/src/native/pointer-utils.h +63 -0
- package/src/native/protocol-impl.mm +7 -27
- package/src/native/protocol-manager.h +145 -0
- package/src/native/protocol-storage.h +12 -33
- package/src/native/runtime-detection.h +54 -0
- package/src/native/subclass-impl.mm +232 -566
- package/src/native/subclass-manager.h +170 -0
- package/src/native/super-call-helpers.h +361 -0
- package/src/native/type-conversion.h +200 -252
- package/src/native/type-dispatch.h +241 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
#ifndef TYPE_DISPATCH_H
|
|
2
|
+
#define TYPE_DISPATCH_H
|
|
3
|
+
|
|
4
|
+
#include <Foundation/Foundation.h>
|
|
5
|
+
#include <type_traits>
|
|
6
|
+
|
|
7
|
+
// MARK: - Type Code to C++ Type Mapping
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Maps Objective-C type encoding characters to C++ types.
|
|
11
|
+
*
|
|
12
|
+
* Type codes:
|
|
13
|
+
* 'c' = char 'C' = unsigned char
|
|
14
|
+
* 'i' = int 'I' = unsigned int
|
|
15
|
+
* 's' = short 'S' = unsigned short
|
|
16
|
+
* 'l' = long 'L' = unsigned long
|
|
17
|
+
* 'q' = long long 'Q' = unsigned long long
|
|
18
|
+
* 'f' = float 'd' = double
|
|
19
|
+
* 'B' = bool
|
|
20
|
+
* '*' = char* '@' = id '#' = Class
|
|
21
|
+
* ':' = SEL '^' = pointer 'v' = void
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// Tag types for special ObjC types
|
|
25
|
+
struct ObjCIdTag {};
|
|
26
|
+
struct ObjCClassTag {};
|
|
27
|
+
struct ObjCSELTag {};
|
|
28
|
+
struct ObjCCStringTag {};
|
|
29
|
+
struct ObjCPointerTag {};
|
|
30
|
+
struct ObjCVoidTag {};
|
|
31
|
+
|
|
32
|
+
// Type trait to get C++ type from type code (compile-time)
|
|
33
|
+
template <char TypeCode> struct TypeCodeToType;
|
|
34
|
+
|
|
35
|
+
template <> struct TypeCodeToType<'c'> { using type = char; };
|
|
36
|
+
template <> struct TypeCodeToType<'i'> { using type = int; };
|
|
37
|
+
template <> struct TypeCodeToType<'s'> { using type = short; };
|
|
38
|
+
template <> struct TypeCodeToType<'l'> { using type = long; };
|
|
39
|
+
template <> struct TypeCodeToType<'q'> { using type = long long; };
|
|
40
|
+
template <> struct TypeCodeToType<'C'> { using type = unsigned char; };
|
|
41
|
+
template <> struct TypeCodeToType<'I'> { using type = unsigned int; };
|
|
42
|
+
template <> struct TypeCodeToType<'S'> { using type = unsigned short; };
|
|
43
|
+
template <> struct TypeCodeToType<'L'> { using type = unsigned long; };
|
|
44
|
+
template <> struct TypeCodeToType<'Q'> { using type = unsigned long long; };
|
|
45
|
+
template <> struct TypeCodeToType<'f'> { using type = float; };
|
|
46
|
+
template <> struct TypeCodeToType<'d'> { using type = double; };
|
|
47
|
+
template <> struct TypeCodeToType<'B'> { using type = bool; };
|
|
48
|
+
template <> struct TypeCodeToType<'*'> { using type = ObjCCStringTag; };
|
|
49
|
+
template <> struct TypeCodeToType<'@'> { using type = ObjCIdTag; };
|
|
50
|
+
template <> struct TypeCodeToType<'#'> { using type = ObjCClassTag; };
|
|
51
|
+
template <> struct TypeCodeToType<':'> { using type = ObjCSELTag; };
|
|
52
|
+
template <> struct TypeCodeToType<'^'> { using type = ObjCPointerTag; };
|
|
53
|
+
template <> struct TypeCodeToType<'v'> { using type = ObjCVoidTag; };
|
|
54
|
+
|
|
55
|
+
template <char TypeCode>
|
|
56
|
+
using TypeCodeToType_t = typename TypeCodeToType<TypeCode>::type;
|
|
57
|
+
|
|
58
|
+
// MARK: - Type Traits for Categories
|
|
59
|
+
|
|
60
|
+
template <typename T>
|
|
61
|
+
struct is_signed_integer : std::bool_constant<
|
|
62
|
+
std::is_same_v<T, char> || std::is_same_v<T, short> ||
|
|
63
|
+
std::is_same_v<T, int> || std::is_same_v<T, long> ||
|
|
64
|
+
std::is_same_v<T, long long>> {};
|
|
65
|
+
|
|
66
|
+
template <typename T>
|
|
67
|
+
struct is_unsigned_integer : std::bool_constant<
|
|
68
|
+
std::is_same_v<T, unsigned char> || std::is_same_v<T, unsigned short> ||
|
|
69
|
+
std::is_same_v<T, unsigned int> || std::is_same_v<T, unsigned long> ||
|
|
70
|
+
std::is_same_v<T, unsigned long long>> {};
|
|
71
|
+
|
|
72
|
+
template <typename T>
|
|
73
|
+
struct is_floating_point : std::bool_constant<
|
|
74
|
+
std::is_same_v<T, float> || std::is_same_v<T, double>> {};
|
|
75
|
+
|
|
76
|
+
template <typename T>
|
|
77
|
+
inline constexpr bool is_signed_integer_v = is_signed_integer<T>::value;
|
|
78
|
+
|
|
79
|
+
template <typename T>
|
|
80
|
+
inline constexpr bool is_unsigned_integer_v = is_unsigned_integer<T>::value;
|
|
81
|
+
|
|
82
|
+
template <typename T>
|
|
83
|
+
inline constexpr bool is_floating_point_v = is_floating_point<T>::value;
|
|
84
|
+
|
|
85
|
+
template <typename T>
|
|
86
|
+
inline constexpr bool is_numeric_v =
|
|
87
|
+
is_signed_integer_v<T> || is_unsigned_integer_v<T> ||
|
|
88
|
+
is_floating_point_v<T> || std::is_same_v<T, bool>;
|
|
89
|
+
|
|
90
|
+
// MARK: - Runtime Type Dispatch
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Dispatches to a visitor based on runtime type code.
|
|
94
|
+
*
|
|
95
|
+
* The visitor must implement operator() for each type:
|
|
96
|
+
* - Numeric types: char, short, int, long, long long (signed/unsigned), float, double, bool
|
|
97
|
+
* - ObjC types: ObjCIdTag, ObjCClassTag, ObjCSELTag, ObjCCStringTag, ObjCPointerTag, ObjCVoidTag
|
|
98
|
+
*
|
|
99
|
+
* Example:
|
|
100
|
+
* struct MyVisitor {
|
|
101
|
+
* template <typename T>
|
|
102
|
+
* auto operator()(std::type_identity<T>) { ... }
|
|
103
|
+
* };
|
|
104
|
+
*
|
|
105
|
+
* auto result = DispatchByTypeCode(typeCode, MyVisitor{});
|
|
106
|
+
*/
|
|
107
|
+
template <typename Visitor>
|
|
108
|
+
auto DispatchByTypeCode(char typeCode, Visitor&& visitor)
|
|
109
|
+
-> decltype(visitor(std::type_identity<int>{})) {
|
|
110
|
+
switch (typeCode) {
|
|
111
|
+
case 'c': return visitor(std::type_identity<char>{});
|
|
112
|
+
case 'i': return visitor(std::type_identity<int>{});
|
|
113
|
+
case 's': return visitor(std::type_identity<short>{});
|
|
114
|
+
case 'l': return visitor(std::type_identity<long>{});
|
|
115
|
+
case 'q': return visitor(std::type_identity<long long>{});
|
|
116
|
+
case 'C': return visitor(std::type_identity<unsigned char>{});
|
|
117
|
+
case 'I': return visitor(std::type_identity<unsigned int>{});
|
|
118
|
+
case 'S': return visitor(std::type_identity<unsigned short>{});
|
|
119
|
+
case 'L': return visitor(std::type_identity<unsigned long>{});
|
|
120
|
+
case 'Q': return visitor(std::type_identity<unsigned long long>{});
|
|
121
|
+
case 'f': return visitor(std::type_identity<float>{});
|
|
122
|
+
case 'd': return visitor(std::type_identity<double>{});
|
|
123
|
+
case 'B': return visitor(std::type_identity<bool>{});
|
|
124
|
+
case '*': return visitor(std::type_identity<ObjCCStringTag>{});
|
|
125
|
+
case '@': return visitor(std::type_identity<ObjCIdTag>{});
|
|
126
|
+
case '#': return visitor(std::type_identity<ObjCClassTag>{});
|
|
127
|
+
case ':': return visitor(std::type_identity<ObjCSELTag>{});
|
|
128
|
+
case '^': return visitor(std::type_identity<ObjCPointerTag>{});
|
|
129
|
+
case 'v': return visitor(std::type_identity<ObjCVoidTag>{});
|
|
130
|
+
default: return visitor(std::type_identity<ObjCVoidTag>{}); // Fallback
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Dispatches only for numeric types (including bool).
|
|
136
|
+
* Returns the default value if type is not numeric.
|
|
137
|
+
*/
|
|
138
|
+
template <typename Visitor, typename DefaultValue>
|
|
139
|
+
auto DispatchNumericType(char typeCode, Visitor&& visitor, DefaultValue&& defaultVal)
|
|
140
|
+
-> decltype(visitor(std::type_identity<int>{})) {
|
|
141
|
+
switch (typeCode) {
|
|
142
|
+
case 'c': return visitor(std::type_identity<char>{});
|
|
143
|
+
case 'i': return visitor(std::type_identity<int>{});
|
|
144
|
+
case 's': return visitor(std::type_identity<short>{});
|
|
145
|
+
case 'l': return visitor(std::type_identity<long>{});
|
|
146
|
+
case 'q': return visitor(std::type_identity<long long>{});
|
|
147
|
+
case 'C': return visitor(std::type_identity<unsigned char>{});
|
|
148
|
+
case 'I': return visitor(std::type_identity<unsigned int>{});
|
|
149
|
+
case 'S': return visitor(std::type_identity<unsigned short>{});
|
|
150
|
+
case 'L': return visitor(std::type_identity<unsigned long>{});
|
|
151
|
+
case 'Q': return visitor(std::type_identity<unsigned long long>{});
|
|
152
|
+
case 'f': return visitor(std::type_identity<float>{});
|
|
153
|
+
case 'd': return visitor(std::type_identity<double>{});
|
|
154
|
+
case 'B': return visitor(std::type_identity<bool>{});
|
|
155
|
+
default: return std::forward<DefaultValue>(defaultVal);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// MARK: - Size Lookup
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Returns the size of a type given its type code.
|
|
163
|
+
*/
|
|
164
|
+
inline size_t GetTypeSize(char typeCode) {
|
|
165
|
+
switch (typeCode) {
|
|
166
|
+
case 'c': return sizeof(char);
|
|
167
|
+
case 'i': return sizeof(int);
|
|
168
|
+
case 's': return sizeof(short);
|
|
169
|
+
case 'l': return sizeof(long);
|
|
170
|
+
case 'q': return sizeof(long long);
|
|
171
|
+
case 'C': return sizeof(unsigned char);
|
|
172
|
+
case 'I': return sizeof(unsigned int);
|
|
173
|
+
case 'S': return sizeof(unsigned short);
|
|
174
|
+
case 'L': return sizeof(unsigned long);
|
|
175
|
+
case 'Q': return sizeof(unsigned long long);
|
|
176
|
+
case 'f': return sizeof(float);
|
|
177
|
+
case 'd': return sizeof(double);
|
|
178
|
+
case 'B': return sizeof(bool);
|
|
179
|
+
case '*': return sizeof(char*);
|
|
180
|
+
case '@': return sizeof(id);
|
|
181
|
+
case '#': return sizeof(Class);
|
|
182
|
+
case ':': return sizeof(SEL);
|
|
183
|
+
case '^': return sizeof(void*);
|
|
184
|
+
case 'v': return 0;
|
|
185
|
+
default: return 0;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Returns true if the type code represents a numeric type.
|
|
191
|
+
*/
|
|
192
|
+
inline bool IsNumericTypeCode(char typeCode) {
|
|
193
|
+
switch (typeCode) {
|
|
194
|
+
case 'c': case 'i': case 's': case 'l': case 'q':
|
|
195
|
+
case 'C': case 'I': case 'S': case 'L': case 'Q':
|
|
196
|
+
case 'f': case 'd': case 'B':
|
|
197
|
+
return true;
|
|
198
|
+
default:
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Returns true if the type code represents a signed integer.
|
|
205
|
+
*/
|
|
206
|
+
inline bool IsSignedIntegerTypeCode(char typeCode) {
|
|
207
|
+
switch (typeCode) {
|
|
208
|
+
case 'c': case 'i': case 's': case 'l': case 'q':
|
|
209
|
+
return true;
|
|
210
|
+
default:
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Returns true if the type code represents an unsigned integer.
|
|
217
|
+
*/
|
|
218
|
+
inline bool IsUnsignedIntegerTypeCode(char typeCode) {
|
|
219
|
+
switch (typeCode) {
|
|
220
|
+
case 'C': case 'I': case 'S': case 'L': case 'Q':
|
|
221
|
+
return true;
|
|
222
|
+
default:
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Returns true if the type code represents a floating point type.
|
|
229
|
+
*/
|
|
230
|
+
inline bool IsFloatingPointTypeCode(char typeCode) {
|
|
231
|
+
return typeCode == 'f' || typeCode == 'd';
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Returns true if the type code represents an object type (@, #).
|
|
236
|
+
*/
|
|
237
|
+
inline bool IsObjectTypeCode(char typeCode) {
|
|
238
|
+
return typeCode == '@' || typeCode == '#';
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
#endif // TYPE_DISPATCH_H
|