@@ -180,7 +180,7 @@ fobj_klass_method_search(fobj_klass_handle_t klass, fobj_method_handle_t meth) {
180180
181181
182182fobj__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 ) {
184184 fobj_header_t * h ;
185185 fobj_klass_handle_t klass ;
186186 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
191191 ft_assert (meth != fobj__nm_mhandle (fobjDispose )());
192192 }
193193
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+
194200 h = ((fobj_header_t * )self - 1 );
195201 assert (h -> magic == FOBJ_HEADER_MAGIC );
196202 klass = h -> klass ;
197203 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 );
198206
199207 if (ft_unlikely (for_child != 0 )) {
200208 if (ft_unlikely (ft_dbg_enabled ())) {
@@ -224,6 +232,9 @@ fobj_method_implements(const fobj_t self, fobj_method_handle_t meth) {
224232 fobj_header_t * h ;
225233 fobj_klass_handle_t klass ;
226234
235+ if (self == NULL )
236+ return false;
237+
227238 ft_assert (fobj_global_state != FOBJ_RT_NOT_INITIALIZED );
228239 if (ft_dbg_enabled ()) {
229240 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) {
244255 return false;
245256}
246257
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+
247286const char *
248287fobj_klass_name (fobj_klass_handle_t klass ) {
249288 fobj_klass_registration_t * reg ;
0 commit comments