Skip to content

Calling an Objective C IMP with two (or more) parameters

Nat! edited this page Mar 11, 2017 · 1 revision

Your old code looked like this, but it doesn't compile with mulle-objc, because IMPs only take one parameter besides self and _cmd:

static void   perform_imp( NSArray *self, SEL sel, IMP method, id arg1, id arg2)
{
   id           *objects;
   id           *sentinel;   
   NSUInteger   n;

   n       = [self count];
   objects = alloca( n * sizeof( id));
   sentinel = &objects[ n];

   [self getObjects:objects];

   while( objects < sentinel)
      (*method)( *objects++, sel, arg1, arg2);
}

Fix it like this:

static void   perform_imp( NSArray *self, SEL sel, IMP method, id arg1, id arg2)
{
   id           *objects;
   id           *sentinel;   
   NSUInteger   n;
#ifdef __MULLE_OBJC__
   mulle_objc_metaabi_param_block( struct
                                   {
                                     id   arg1;
                                     id   arg2;
                                   },
                                   void *)   param;
#endif

   n        = [self count];
   objects  = alloca( n * sizeof( id));
   sentinel = &objects[ n];

   [self getObjects:objects];

   while( objects < sentinel)
   {
#ifdef __MULLE_OBJC__
      param.p.arg1 = arg1;  // don't move this outside of the loop
      param.p.arg2 = arg2;  // parameter space can be clobbered 
      (*method)( *objects++, sel, &param);
#else
      (*method)( *objects++, sel, arg1, arg2);
#endif
   }
}

This can be expanded to three or more parameters.