fixes for ffi calls on method dispatch: float param and return values in particular
3 files changed, 48 insertions(+), 27 deletions(-)

M dynamic_class.m
M method_dispatch.m
M util.m
M dynamic_class.m +38 -22
@@ 56,7 56,7 @@ void f_objc_dynamic_create(Class cls, IN
            for wrapping. In this case, we don't free up the alloced object, and have other odd behavior. */
 
   THIS->obj = [cls alloc];
-// [THIS->obj retain];
+ [THIS->obj retain];
   THIS->is_instance = 1;
 // LOG("finished  object.\n");
 	LOG("created: %s(%p/%p)\n", class_getName(object_getClass(THIS->obj)), Pike_fp->current_object, THIS);

          
@@ 191,7 191,7 @@ void f_call_objc_method(INT32 args, int 
     struct svalue * o_retval;
 	int num_float_arguments = 0;
 	int num_pointer_return_arguments = 0;
-    ffi_arg msgResult;
+    void * msgResult;
     ffi_cif * cif;
     SEL sel;    
     pool = [global_autorelease_pool getAutoreleasePool];

          
@@ 266,15 266,20 @@ void f_call_objc_method(INT32 args, int 
         case 'd':
            if(TYPEOF(*sv)!=T_FLOAT)
              Pike_error("Type mismatch for method argument.");
-           argumentList[x] = &(sv->u.float_number);
+           argumentList[x] = (double *)&((sv->u.float_number));
   	 break;
 
         case 'f':
+	{
+           float f;
            if(TYPEOF(*sv)!=T_FLOAT)
              Pike_error("Type mismatch for method argument.");
-             argumentList[x] = &(sv->u.float_number);
+		f = (float)sv->u.float_number;
+		printf("float arg: %f\n", f);
+             argumentList[x] = (float *)(&f);
+	 }
   	 break;
-
+    
         case 'i': 
            if(TYPEOF(*sv)!=T_INT)
              Pike_error("Type mismatch for method argument.");

          
@@ 356,7 361,11 @@ LOG("wrapping obj%s\n", "");
 			    id rv;
 LOG("encoding array as OC_Array%s\n", "");
 			    rv = [OC_Array newWithPikeArray: sv->u.array];
-//LOG("obj: %s\n",	[[obj description] UTF8String]);
+
+// suspect we may have an over-optimization situation here, 
+// as we get segfaults because obj goes away without doing something to it
+[obj hash];
+
 		//	rv =  [@"foo bar gazonk" componentsSeparatedByString: @" "];
 
 //LOG("obj: %s\n",	[[rv description] UTF8String]);

          
@@ 475,7 484,8 @@ LOG("encoding array as OC_Array%s\n", ""
         
        case 'd':
        case 'f':
-        ffi_call(cif, FFI_FN(objc_msgSend), msgResult, argumentList);
+	msgResult = malloc(sizeof(double));
+        ffi_call(cif,  FFI_FN(objc_msgSend_fpret), msgResult, argumentList);
         break;  
 
        

          
@@ 491,7 501,8 @@ LOG("encoding array as OC_Array%s\n", ""
      default:
         THREADS_ALLOW();
 		LOG("calling%s\n", "");
-        ffi_call(cif, FFI_FN(objc_msgSend), &msgResult, argumentList);
+	msgResult = malloc(sizeof(ffi_arg));
+        ffi_call(cif, FFI_FN(objc_msgSend), msgResult, argumentList);
     	  THREADS_DISALLOW();
   		LOG("calling2%s\n", "");
         break;

          
@@ 503,55 514,55 @@ printf("whoo\n");
       
 	switch(*type){
         case 'c':
-          push_int((INT_TYPE)msgResult);
+          push_int(*(INT_TYPE*)msgResult);
           break;
 
        case 'C':
-         push_int((INT_TYPE)msgResult);
+         push_int(*(INT_TYPE*)msgResult);
          break;
 
        case 'i':
-        push_int((INT_TYPE)msgResult);
+        push_int(*(INT_TYPE*)msgResult);
         break;
       // TODO: fix the casting... should we support auto objectize for bignums?
 
       case 'l':
-        push_int((INT_TYPE)msgResult);
-		free(result);
+        push_int(*(INT_TYPE*)msgResult);
         break;
 
       case 'L':
-        push_int((INT_TYPE)msgResult);
+        push_int(*(INT_TYPE*)msgResult);
         break;
 
       case 'I':
-        push_int((INT_TYPE)msgResult);
+        push_int(*(INT_TYPE*)msgResult);
         break;
 
       case 'd':
-        push_float((FLOAT_TYPE)msgResult);
+        push_float(*(double*)msgResult);
         break;
 
       case 'f':
-        push_float((FLOAT_TYPE)msgResult);
+printf("Float result: %f\n",*(float*) msgResult);
+        push_float(*(float*)msgResult);
         break;
 
 /* TODO we need to make sure we're not losing data here if the return size
    is larger than INT_TYPE */
       case 'q':
-        push_int((INT_TYPE)msgResult);
+        push_int(*(INT_TYPE*)msgResult);
         break;
 
       case 'Q':
-        push_int((INT_TYPE)msgResult);
+        push_int(*(INT_TYPE*)msgResult);
         break;
 
       case 's':
-        push_int((INT_TYPE)msgResult);
+        push_int(*(INT_TYPE*)msgResult);
         break;
 
       case 'S':
-        push_int((INT_TYPE)msgResult);
+        push_int(*(INT_TYPE*)msgResult);
         break;
 
       case 'v':

          
@@ 613,7 624,12 @@ printf("whoo\n");
       [pool release];
     }
 
-
+    switch(*type) {
+      case '@':
+	break;
+      default:
+	free(msgResult);
+   }
     // now, the fun begins. if we have "pointer return" parameters, we need to get that sorted out here.
     if(num_pointer_return_arguments)
     {

          
M method_dispatch.m +6 -4
@@ 221,9 221,9 @@ static ffi_type* objc_signature_to_ffi_t
         argtype = skip_type_qualifiers(argtype);
         switch (*argtype) {
         case _C_VOID: return &ffi_type_void;
-        case _C_ID: return &ffi_type_pointer;
+        case _C_ID: printf("arg type is id\n"); return &ffi_type_pointer;
         case _C_CLASS: return &ffi_type_pointer;
-        case _C_SEL: return &ffi_type_pointer;
+        case _C_SEL: printf("arg type is sel\n"); return &ffi_type_pointer;
         case _C_CHR: return &ffi_type_schar;
         case _C_CHAR_AS_INT: return &ffi_type_schar;
         case _C_CHAR_AS_TEXT: return &ffi_type_schar;

          
@@ 252,8 252,8 @@ static ffi_type* objc_signature_to_ffi_t
         #endif
                 case _C_LNG_LNG: return &ffi_type_sint64;
                 case _C_ULNG_LNG: return &ffi_type_uint64;
-                case _C_FLT: return &ffi_type_float;
-                case _C_DBL: return &ffi_type_double;
+                case _C_FLT: printf("return type is float\n"); return &ffi_type_float;
+                case _C_DBL: printf("return type is double\n"); return &ffi_type_double;
                 case _C_CHARPTR: return &ffi_type_pointer;
                 case _C_PTR: return &ffi_type_pointer;
 /*

          
@@ 320,6 320,7 @@ static const char ulong_type[] = { _C_UL
     free(rettype);
 
     if (cl_ret_type == NULL) {
+	printf("null return type!\n");
       return NULL;
     }
             

          
@@ 337,6 338,7 @@ static const char ulong_type[] = { _C_UL
       cl_arg_types[i] = objc_signature_to_ffi_type(arg);
       free(arg);
       if (cl_arg_types[i] == NULL) {
+printf("arg type %d is null\n", i);
         free(cl_arg_types);
         return NULL;
       }

          
M util.m +4 -1
@@ 157,11 157,13 @@ NSMapTableValueCallBacks PiObjCUtil_Poin
 
 static void
 nsmaptable_objc_retain(NSMapTable *table __attribute__((__unused__)), const void *datum) {
+LOG("nsmaptable_retain %p\n", datum);
 	[(id)datum retain];
 }
 
 static void
 nsmaptable_objc_release(NSMapTable *table __attribute__((__unused__)), void *datum) {
+LOG("nsmaptable_release %p\n", datum);
 	[(id)datum release];
 }
 

          
@@ 1450,8 1452,9 @@ struct svalue * get_func_by_selector(str
   // do we need to do this?
   push_text(funname);
   free(funname);
-
+LOG("whoo%s", "");
   // FIXME: is zero the right answer?
+  printf("pobject: %p\n", pobject);
   object_index_no_free(sv2, pobject, 0, Pike_sp-1);
   pop_stack();