@@ -180,7 +180,7 @@ fobj_klass_method_search(fobj_klass_handle_t klass, fobj_method_handle_t meth) {
180
180
181
181
182
182
fobj__method_callback_t
183
- fobj_method_search (const fobj_t self , fobj_method_handle_t meth , fobj_klass_handle_t for_child ) {
183
+ fobj_method_search (const fobj_t self , fobj_method_handle_t meth , fobj_klass_handle_t for_child , bool validate ) {
184
184
fobj_header_t * h ;
185
185
fobj_klass_handle_t klass ;
186
186
fobj__method_callback_t cb = {self , NULL };
@@ -191,10 +191,18 @@ fobj_method_search(const fobj_t self, fobj_method_handle_t meth, fobj_klass_hand
191
191
ft_assert (meth != fobj__nm_mhandle (fobjDispose )());
192
192
}
193
193
194
+ if (self == NULL ) {
195
+ if (validate )
196
+ ft_assert (self != NULL , "Call '%s' on NULL object" , fobj_methods [meth ].name );
197
+ return cb ;
198
+ }
199
+
194
200
h = ((fobj_header_t * )self - 1 );
195
201
assert (h -> magic == FOBJ_HEADER_MAGIC );
196
202
klass = h -> klass ;
197
203
ft_dbg_assert (klass > 0 && klass <= atload (& fobj_klasses_n ));
204
+ ft_assert ((h -> flags & FOBJ_DISPOSED ) == 0 , "Call '%s' on disposed object '%s'" ,
205
+ fobj_methods [meth ].name , fobj_klasses [klass ].name );
198
206
199
207
if (ft_unlikely (for_child != 0 )) {
200
208
if (ft_unlikely (ft_dbg_enabled ())) {
@@ -224,6 +232,9 @@ fobj_method_implements(const fobj_t self, fobj_method_handle_t meth) {
224
232
fobj_header_t * h ;
225
233
fobj_klass_handle_t klass ;
226
234
235
+ if (self == NULL )
236
+ return false;
237
+
227
238
ft_assert (fobj_global_state != FOBJ_RT_NOT_INITIALIZED );
228
239
if (ft_dbg_enabled ()) {
229
240
ft_assert (meth > 0 && meth <= atload (& fobj_methods_n ));
@@ -244,6 +255,34 @@ fobj_method_implements(const fobj_t self, fobj_method_handle_t meth) {
244
255
return false;
245
256
}
246
257
258
+ extern void
259
+ fobj__validate_args (fobj_method_handle_t meth ,
260
+ fobj_t self ,
261
+ const char * * paramnames ,
262
+ const char * set ,
263
+ size_t cnt ) {
264
+ fobj_header_t * h ;
265
+ fobj_klass_handle_t klass ;
266
+ size_t i ;
267
+
268
+ ft_assert (fobj_global_state != FOBJ_RT_NOT_INITIALIZED );
269
+ ft_assert (meth > 0 && meth <= atload (& fobj_methods_n ));
270
+ ft_assert (meth != fobj__nm_mhandle (fobjDispose )());
271
+ ft_assert (self != NULL , "call '%s' on NULL object" , fobj_methods [meth ].name );
272
+
273
+ h = ((fobj_header_t * )self - 1 );
274
+ assert (h -> magic == FOBJ_HEADER_MAGIC );
275
+ klass = h -> klass ;
276
+ ft_dbg_assert (klass > 0 && klass <= atload (& fobj_klasses_n ));
277
+
278
+ for (i = 0 ; i < cnt ; i ++ ) {
279
+ ft_assert (set [i ] != 0 , "Calling '%s' on '%s' miss argument '%s'" ,
280
+ fobj_methods [meth ].name ,
281
+ fobj_klasses [klass ].name ,
282
+ paramnames [i ]);
283
+ }
284
+ }
285
+
247
286
const char *
248
287
fobj_klass_name (fobj_klass_handle_t klass ) {
249
288
fobj_klass_registration_t * reg ;
0 commit comments