java.m
上传用户:shenzhenrh
上传日期:2013-05-12
资源大小:2904k
文件大小:65k
源码类别:

信息检索与抽取

开发平台:

Unix_Linux

  1. #include <swarmconfig.h>
  2. #ifdef HAVE_JDK
  3. #import "java.h"
  4. #import <defobj/JavaProxy.h>
  5. #import <defobj/JavaClassProxy.h>
  6. #import <defobj/JavaCollection.h>
  7. #import <defobj/defalloc.h>
  8. #include <misc.h>
  9. // mframe_build_signature
  10. #ifdef GNUSTEP
  11. #include <Foundation/NSMethodSignature.h>
  12. #include <mframe.h>
  13. #else
  14. #ifdef USE_MFRAME
  15. #include <objc/mframe.h>
  16. #endif
  17. #endif
  18. #import "internal.h" // FCALL_TYPE_COUNT, objc_type_for_fcall_type
  19. #define extern
  20. #import "javavars.h"
  21. #undef extern
  22. #include <misc.h> // stpcpy
  23. static BOOL initFlag = NO;
  24. static jobject proxyClassLoader = 0;
  25. static const char *java_type_signature[FCALL_TYPE_COUNT] = {
  26.   "V", "C", "C", "C", "S", "S",
  27.   "I", "I", "J", "J", 
  28.   /* bogus */
  29.   "J", "J",
  30.   "F", "D",
  31.   "D", // long double
  32.   "X", // Object
  33.   "X", // Class
  34.   "Ljava/lang/String;", 
  35.   "Lswarm/Selector;",
  36.   "Ljava/lang/Object;",
  37.   "Ljava/lang/String;",
  38.   "Lswarm/Selector;",
  39.   "X" // iid
  40. };
  41. externvar id id_JavaClassProxy;
  42. const char *
  43. java_signature_for_fcall_type (fcall_type_t type)
  44. {
  45.   return java_type_signature[type];
  46. }
  47. static BOOL
  48. fcall_type_for_java_signature (const char *signature, fcall_type_t *typeptr)
  49. {
  50.   unsigned i;
  51.   for (i = 0; i < FCALL_TYPE_COUNT; i++)
  52.     if (strcmp (signature, java_type_signature[i]) == 0)
  53.       {
  54.         if (i == fcall_type_uint || i == fcall_type_ushort)
  55.           continue;
  56.         *typeptr = i;
  57.         return YES;
  58.       }
  59.   return NO;
  60. }
  61. static void
  62. fill_signature (char *buf, const char *className)
  63. {
  64.   char *bp = buf;
  65.   const char *cp = className;
  66.   *bp++ = 'L';
  67.   while (*cp)
  68.     {
  69.       *bp = (*cp == '.') ? '/' : *cp;
  70.       bp++;
  71.       cp++;
  72.     }
  73.   *bp++ = ';';
  74.   *bp = '';
  75. }
  76. static BOOL
  77. exactclassp (jclass class, jclass matchClass)
  78. {
  79.   return (*jniEnv)->IsSameObject (jniEnv, class, matchClass);
  80. }
  81. static BOOL
  82. classp (jclass class, jclass matchClass)
  83. {
  84.   jobject clazz;
  85.   
  86.   if ((*jniEnv)->IsSameObject (jniEnv, class, matchClass))
  87.     return YES;
  88.   else
  89.     {
  90.       jclass nextClass;
  91.       
  92.       for (clazz = (*jniEnv)->GetSuperclass (jniEnv, class);
  93.            clazz;
  94.            nextClass = (*jniEnv)->GetSuperclass (jniEnv, clazz), 
  95.              (*jniEnv)->DeleteLocalRef (jniEnv, clazz),
  96.              clazz = nextClass)
  97.         if ((*jniEnv)->IsSameObject (jniEnv, clazz, matchClass))
  98.           {
  99.             (*jniEnv)->DeleteLocalRef (jniEnv, clazz);
  100.             return YES;
  101.           }
  102.       return NO;
  103.     }
  104. }
  105. static const char *
  106. java_signature_for_class (jclass class)
  107. {
  108.   const char *type;
  109.   if (classp (class, c_Selector))
  110.     type = "Lswarm/Selector;";
  111.   else if (classp (class, c_String))
  112.     type = "Ljava/lang/String;";
  113.   else if (classp (class, c_Class))
  114.     type = "Ljava/lang/Class;";
  115.   else if (exactclassp (class, c_int))
  116.     type = "I";
  117.   else if (exactclassp (class, c_short))
  118.     type = "S";
  119.   else if (exactclassp (class, c_long))
  120.     type = "J";
  121.   else if (exactclassp (class, c_boolean))
  122.     type = "Z";
  123.   else if (exactclassp (class, c_byte))
  124.     type = "B";
  125.   else if (exactclassp (class, c_char))
  126.     type = "C";
  127.   else if (exactclassp (class, c_float))
  128.     type = "F";
  129.   else if (exactclassp (class, c_double))
  130.     type = "D";
  131.   else if (exactclassp (class, c_void))
  132.     type = "V";
  133.   else if ((*jniEnv)->CallBooleanMethod (jniEnv, class, m_ClassIsArray))
  134.     {
  135.       char *cp;
  136.       type = java_get_class_name (class);
  137.       
  138.       for (cp = (char *) type; *cp; cp++)
  139.         if (*cp == '.')
  140.           *cp = '/';
  141.       return type;
  142.     }
  143.   else
  144.     {
  145.       const char *name = java_get_class_name (class);
  146.       char *buf = [scratchZone alloc: 1 + strlen (name) + 1 + 1];
  147.       fill_signature (buf, name);
  148.       FREECLASSNAME (name);
  149.       return buf;
  150.     }
  151.   return SSTRDUP (type);
  152. }
  153. BOOL
  154. java_objc_proxy_p (jclass class)
  155. {
  156.   return classp (class, c_ObjCProxy);
  157. }
  158. static fcall_type_t
  159. java_getTypeInfo (jobject javaObj, unsigned *rankptr, unsigned *dims)
  160. {
  161.   unsigned rank = 0;
  162.   fcall_type_t elementType = fcall_type_void;
  163.   void checkArray (jobject obj)
  164.     {
  165.       jclass class = (*jniEnv)->GetObjectClass (jniEnv, obj);
  166.       jboolean isArray =
  167.         (*jniEnv)->CallBooleanMethod (jniEnv, class, m_ClassIsArray);
  168.       unsigned len;
  169.       
  170.       if (isArray)
  171.         {
  172.           const char *sig = java_signature_for_class (class);
  173.           len = (*jniEnv)->GetArrayLength (jniEnv, obj);
  174.           
  175.           if (dims)
  176.             dims[rank] = len;
  177.           rank++;
  178.           
  179.           if (len > 0 && sig[1] == '[')
  180.             {
  181.               jobject subobj =
  182.                 (*jniEnv)->GetObjectArrayElement (jniEnv, obj, 0);
  183.               
  184.               checkArray (subobj);
  185.               (*jniEnv)->DeleteLocalRef (jniEnv, subobj);
  186.             }
  187.           else if (!fcall_type_for_java_signature (&sig[1], &elementType))
  188.             abort ();
  189.           
  190.           SFREEBLOCK (sig);
  191.         }
  192.       else
  193.         elementType = fcall_type_for_java_class (class);
  194.           
  195.       (*jniEnv)->DeleteLocalRef (jniEnv, class);
  196.     }
  197.   checkArray (javaObj);
  198.   *rankptr = rank;
  199.   return elementType;
  200. }
  201. static void
  202. java_expandArray (jobject fullary, void *inbuf)
  203. {
  204.   unsigned char *buf = inbuf;
  205.   unsigned offset = 0;
  206.   
  207.   void permute (jobject obj)
  208.     {
  209.       jclass lref = (*jniEnv)->GetObjectClass (jniEnv, obj);
  210.       const char *sig = java_signature_for_class (lref);
  211.       jsize len = (*jniEnv)->GetArrayLength (jniEnv, obj);
  212.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  213.       
  214.       if (sig[1] == '[')
  215.         {
  216.           int i;
  217.           for (i = 0; i < len; i++)
  218.             {
  219.               jobject subobj =
  220.                 (*jniEnv)->GetObjectArrayElement (jniEnv, obj, i);
  221.               permute (subobj);
  222.               (*jniEnv)->DeleteLocalRef (jniEnv, subobj);
  223.             }
  224.         }
  225.       else if (sig[1] == 'L')
  226.         {
  227.           *((id *) &buf[offset]) = SD_JAVA_ENSURE_OBJECT_OBJC (obj);
  228.           offset += sizeof (id);
  229.         }
  230.       else
  231.         {
  232.           fcall_type_t type;
  233.           jboolean isCopy;
  234.           size_t size;
  235.           void *ptr;
  236.           if (!fcall_type_for_java_signature (&sig[1], &type))
  237.             abort ();
  238.           size = fcall_type_size (type) * len;
  239.           switch (type)
  240.             {
  241.             case fcall_type_boolean:
  242.               ptr = (*jniEnv)->GetBooleanArrayElements (jniEnv, obj, &isCopy);
  243.               memcpy (&buf[offset], ptr, size);
  244.               (*jniEnv)->ReleaseBooleanArrayElements (jniEnv, obj, ptr,
  245.                                                       JNI_ABORT);
  246.               break;
  247.             case fcall_type_uchar:
  248.               ptr = (*jniEnv)->GetByteArrayElements (jniEnv, obj, &isCopy);
  249.               memcpy (&buf[offset], ptr, size);
  250.               (*jniEnv)->ReleaseByteArrayElements (jniEnv, obj, ptr,
  251.                                                    JNI_ABORT);
  252.               break;
  253.             case fcall_type_schar:
  254.               ptr = (*jniEnv)->GetCharArrayElements (jniEnv, obj, &isCopy);
  255.               memcpy (&buf[offset], ptr, size);
  256.               (*jniEnv)->ReleaseCharArrayElements (jniEnv, obj, ptr,
  257.                                                    JNI_ABORT);
  258.               break;
  259.             case fcall_type_sshort:
  260.               ptr = (*jniEnv)->GetShortArrayElements (jniEnv, obj, &isCopy);
  261.               memcpy (&buf[offset], ptr, size);
  262.               (*jniEnv)->ReleaseShortArrayElements (jniEnv, obj, ptr,
  263.                                                     JNI_ABORT);
  264.               break;
  265.             case fcall_type_sint:
  266.               ptr = (*jniEnv)->GetIntArrayElements (jniEnv, obj, &isCopy);
  267.               memcpy (&buf[offset], ptr, size);
  268.               (*jniEnv)->ReleaseIntArrayElements (jniEnv, obj, ptr,
  269.                                                   JNI_ABORT);
  270.               break;
  271.             case fcall_type_slonglong:
  272.               ptr = (*jniEnv)->GetLongArrayElements (jniEnv, obj, &isCopy);
  273.               memcpy (&buf[offset], ptr, size);
  274.               (*jniEnv)->ReleaseLongArrayElements (jniEnv, obj, ptr,
  275.                                                    JNI_ABORT);
  276.               break;
  277.             case fcall_type_float:
  278.               ptr = (*jniEnv)->GetFloatArrayElements (jniEnv, obj, &isCopy);
  279.               memcpy (&buf[offset], ptr, size);
  280.               (*jniEnv)->ReleaseFloatArrayElements (jniEnv, obj, ptr,
  281.                                                     JNI_ABORT);
  282.               break;
  283.             case fcall_type_double:
  284.               ptr = (*jniEnv)->GetDoubleArrayElements (jniEnv, obj, &isCopy);
  285.               memcpy (&buf[offset], ptr, size);
  286.               (*jniEnv)->ReleaseDoubleArrayElements (jniEnv, obj, ptr,
  287.                                                      JNI_ABORT);
  288.               break;
  289.             default:
  290.               abort ();
  291.             }
  292.           offset += size;
  293.         }
  294.       SFREEBLOCK (sig);
  295.     }
  296.   permute (fullary);
  297. }
  298. static BOOL
  299. java_modifier_usable_p (int modifier)
  300. {
  301.   return (((*jniEnv)->CallStaticBooleanMethod (jniEnv,
  302.        c_Modifier,
  303.        m_ModifierIsPublic,
  304.        modifier)
  305.    == JNI_TRUE)
  306.   &&
  307.   ((*jniEnv)->CallStaticBooleanMethod (jniEnv,
  308.        c_Modifier,
  309.        m_ModifierIsStatic,
  310.        modifier))
  311.   == JNI_FALSE);
  312. }
  313. BOOL
  314. java_field_usable_p (jobject field)
  315. {
  316.   return
  317.     java_modifier_usable_p ((*jniEnv)->CallIntMethod (jniEnv,
  318.       field,
  319.       m_FieldGetModifiers));
  320. }
  321. BOOL
  322. java_method_usable_p (jobject method)
  323. {
  324.   return
  325.     java_modifier_usable_p ((*jniEnv)->CallIntMethod (jniEnv,
  326.     method,
  327.     m_MethodGetModifiers));
  328. }
  329. #define _GETVALUE(uptype) 
  330.     (*jniEnv)->Get##uptype##Field (jniEnv, 
  331.                                    javaObject, 
  332.                                    fid)
  333. #define GETVALUE(uptype) _GETVALUE(uptype)
  334. static void
  335. map_java_class_ivars_internal (jclass class,
  336.                                void (*process_array_ivar) (const char *name, jfieldID fid),
  337.                                void (*process_ivar) (const char *name, jfieldID fid, fcall_type_t type))
  338. {
  339.   jclass superClass = (*jniEnv)->GetSuperclass (jniEnv, class);
  340.   jarray fields;
  341.   jsize count;
  342.   int fi;
  343.   
  344.   if (superClass)
  345.     {
  346.       map_java_class_ivars_internal (superClass,
  347.                                      process_array_ivar, process_ivar);
  348.       (*jniEnv)->DeleteLocalRef (jniEnv, superClass);
  349.     }
  350.   
  351.   if (!(fields = (*jniEnv)->CallObjectMethod (jniEnv,
  352.                                               class,
  353.                                               m_ClassGetDeclaredFields)))
  354.     abort();
  355.       
  356.   count = (*jniEnv)->GetArrayLength (jniEnv, fields);
  357.       
  358.   for (fi = 0; fi < count; fi++)
  359.     {
  360.       jobject name, field;
  361.       jboolean isCopy;
  362.       const char *namestr;
  363.           
  364.       field = (*jniEnv)->GetObjectArrayElement (jniEnv, fields, fi);
  365.       if (!field)
  366.         raiseEvent (SourceMessage, "field %u unavailable", fi);
  367.       if (java_field_usable_p (field))
  368. {
  369.   name = (*jniEnv)->CallObjectMethod (jniEnv, field, m_FieldGetName);
  370.   namestr = (*jniEnv)->GetStringUTFChars (jniEnv, name, &isCopy);
  371.   {
  372.     jobject lref =
  373.       (*jniEnv)->CallObjectMethod (jniEnv,
  374.    field,
  375.    m_FieldGetType);
  376.     fcall_type_t type = fcall_type_for_java_class (lref);
  377.     const char *sig = java_signature_for_class (lref);
  378.     jboolean isArray = 
  379.       (*jniEnv)->CallBooleanMethod (jniEnv, lref, m_ClassIsArray);
  380.     jfieldID fid =
  381.       (*jniEnv)->GetFieldID (jniEnv, class, namestr, sig);
  382.             
  383.     (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  384.     if (!fid)
  385.       abort ();
  386.             
  387.     SFREEBLOCK (sig);
  388.     if (isArray)
  389.               process_array_ivar (namestr, fid);
  390.     else
  391.               process_ivar (namestr, fid, type);
  392.     if (isCopy)
  393.       (*jniEnv)->ReleaseStringUTFChars (jniEnv, name, namestr);
  394.     (*jniEnv)->DeleteLocalRef (jniEnv, name);
  395.   }
  396. }
  397.       (*jniEnv)->DeleteLocalRef (jniEnv, field);
  398.     }
  399.   (*jniEnv)->DeleteLocalRef (jniEnv, fields);
  400. }
  401. void
  402. map_java_class_ivars (jclass class,
  403.                       void (*process_ivar) (const char *name,
  404.                                             fcall_type_t type))
  405. {
  406.   void process_array_ivar (const char *name, jfieldID fid)
  407.     {
  408.       // skip (unknown until there is an object)
  409.     }
  410.   void process_simple_ivar (const char *name, jfieldID fid, fcall_type_t type)
  411.     {
  412.       process_ivar (name, type);
  413.     }
  414.   map_java_class_ivars_internal (class,
  415.                                  process_array_ivar,
  416.                                  process_simple_ivar);
  417. }
  418. void
  419. map_java_ivars (jobject javaObject,
  420.                 void (*process_object) (const char *name,
  421.                                         fcall_type_t type,
  422.                                         void *ptr,
  423.                                         unsigned rank,
  424.                                         unsigned *dims))
  425. {
  426.   void process_array_ivar (const char *name, jfieldID fid)
  427.     {
  428.       jobject obj = GETVALUE (Object);
  429.       fcall_type_t type;
  430.       unsigned rank;
  431.       
  432.       java_getTypeInfo (obj, &rank, NULL);
  433.       {
  434.         unsigned dims[rank], i;
  435.         unsigned count = 1;
  436.         
  437.         type = java_getTypeInfo (obj, &rank, dims);
  438.         
  439.         for (i = 0; i < rank; i++)
  440.           count *= dims[i];
  441.         {
  442.           unsigned buf[fcall_type_size (type) * count];
  443.           
  444.           java_expandArray (obj, buf);
  445.           process_object (name, type, buf, rank, dims);
  446.         }
  447.       }
  448.       (*jniEnv)->DeleteLocalRef (jniEnv, obj);
  449.     }
  450.   
  451.   void process_simple_ivar (const char *name, jfieldID fid, fcall_type_t type)
  452.     {
  453.       types_t val;
  454.       
  455.       switch (type)
  456.         {
  457.         case fcall_type_boolean:
  458.           val.boolean = GETVALUE (Boolean);
  459.           break;
  460.         case fcall_type_schar:
  461.           val.schar = GETVALUE (Char);
  462.           break;
  463.         case fcall_type_uchar:
  464.           val.uchar = GETVALUE (Byte);
  465.           break;
  466.         case fcall_type_sshort:
  467.           val.sshort = GETVALUE (Short);
  468.           break;
  469.         case fcall_type_sint:
  470.           val.sint = GETVALUE (Int);
  471.           break;
  472.         case fcall_type_slonglong:
  473.           val.slonglong = GETVALUE (Long);
  474.           break;
  475.         case fcall_type_float:
  476.           val._float = GETVALUE (Float);
  477.           break;
  478.         case fcall_type_double:
  479.           val._double = GETVALUE (Double);
  480.           break;
  481.         case fcall_type_object:
  482.           {
  483.             jobject obj = GETVALUE (Object);
  484.             
  485.             val.object = SD_JAVA_ENSURE_OBJECT_OBJC (obj);
  486.             if (obj)
  487.               (*jniEnv)->DeleteLocalRef (jniEnv, obj);
  488.           }
  489.           break;
  490.         case fcall_type_string:
  491.           {
  492.             BOOL isCopy;
  493.             jobject string = GETVALUE (Object);
  494.             const char *utf =
  495.               (*jniEnv)->GetStringUTFChars (jniEnv, string, &isCopy);
  496.             
  497.             val.string = SSTRDUP (utf);
  498.             if (isCopy)
  499.               (*jniEnv)->ReleaseStringUTFChars (jniEnv, string, utf);
  500.             (*jniEnv)->DeleteLocalRef (jniEnv, string);
  501.           }
  502.           break;
  503.         case fcall_type_selector:
  504.           {
  505.             jobject sel = GETVALUE (Object);
  506.             
  507.             val.object = SD_JAVA_FIND_OBJECT_OBJC (sel);
  508.             (*jniEnv)->DeleteLocalRef (jniEnv, sel);
  509.           }
  510.           break;
  511.         case fcall_type_void:
  512.         case fcall_type_ushort:
  513.         case fcall_type_uint:
  514.         case fcall_type_ulong:
  515.         case fcall_type_slong:
  516.         case fcall_type_ulonglong:
  517.         case fcall_type_long_double:
  518.         case fcall_type_class:
  519.         case fcall_type_jobject:
  520.         case fcall_type_jstring:
  521.         case fcall_type_jselector:
  522.         case fcall_type_iid:
  523.           abort ();
  524.         }
  525.       process_object (name, type, &val, 0, NULL);
  526.     }
  527.   jclass class = (*jniEnv)->GetObjectClass (jniEnv, javaObject);
  528.   map_java_class_ivars_internal (class,
  529.                                  process_array_ivar,
  530.                                  process_simple_ivar);
  531.   (*jniEnv)->DeleteLocalRef (jniEnv, class);
  532. }
  533.                         
  534. static jfieldID
  535. class_java_find_field (jclass javaClass, const char *fieldName,
  536.                        fcall_type_t *typePtr, BOOL *isArrayPtr)
  537. {
  538.   jarray fields;
  539.   jsize count;
  540.   int i;
  541.   BOOL match = NO;
  542.   jobject field = NULL;
  543.   jobject name;
  544.   const char *namestr;
  545.   jboolean isCopy;
  546.   void release (void)
  547.     {
  548.       if (isCopy)
  549.         (*jniEnv)->ReleaseStringUTFChars (jniEnv, name, namestr);
  550.       (*jniEnv)->DeleteLocalRef (jniEnv, name);
  551.       (*jniEnv)->DeleteLocalRef (jniEnv, field);
  552.     }
  553.   if (!(fields = (*jniEnv)->CallObjectMethod (jniEnv,
  554.                                               javaClass,
  555.                                               m_ClassGetFields)))
  556.     abort();
  557.   
  558.   count = (*jniEnv)->GetArrayLength (jniEnv, fields);
  559.   for (i = 0; i < count; i++)
  560.     {
  561.       field = (*jniEnv)->GetObjectArrayElement (jniEnv, fields, i);
  562.       if (!field)
  563.         raiseEvent (SourceMessage, "field %u unavailable", i);
  564.       name = (*jniEnv)->CallObjectMethod (jniEnv, field, m_FieldGetName);
  565.       namestr = (*jniEnv)->GetStringUTFChars (jniEnv, name, &isCopy);
  566.       match = (strcmp (namestr, fieldName) == 0);
  567.       if (match)
  568.         break;
  569.       else
  570.         release ();
  571.     }
  572.   (*jniEnv)->DeleteLocalRef (jniEnv, fields);
  573.   if (match)
  574.     {
  575.       jobject lref = (*jniEnv)->CallObjectMethod (jniEnv,
  576.                                                   field,
  577.                                                   m_FieldGetType);
  578.       const char *sig = java_signature_for_class (lref);
  579.       fcall_type_t type = fcall_type_for_java_class (lref);
  580.       jfieldID fid;
  581.       jboolean isArray =
  582.         (*jniEnv)->CallBooleanMethod (jniEnv, lref, m_ClassIsArray);
  583.       
  584.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  585.       fid = (*jniEnv)->GetFieldID (jniEnv, javaClass, namestr, sig);
  586.       if (!fid)
  587.         abort ();
  588.       SFREEBLOCK (sig);
  589.       release ();
  590.       if (typePtr)
  591.         *typePtr = type;
  592.       if (isArrayPtr)
  593.         *isArrayPtr = isArray;
  594.       return fid;
  595.     }
  596.   else
  597.     return NULL;
  598. }
  599. static void
  600. java_storeArray (jobject javaObject,
  601.                  fcall_type_t type, unsigned rank, unsigned *dims, void *buf)
  602. {
  603.   jobject values[rank];
  604.   unsigned vec[rank];
  605.   unsigned di;
  606.     
  607.   void start_dim (unsigned dimnum)
  608.     {
  609.       di = dimnum;
  610.       vec[di] = 0;
  611.       if (dimnum > 0)
  612.         values[di] =
  613.           (*jniEnv)->GetObjectArrayElement (jniEnv,
  614.                                             values[di - 1],
  615.                                             vec[di - 1]);
  616.     }
  617.   void end_dim (void)
  618.     {
  619.       if (di == rank - 1)
  620.         {
  621.           unsigned len = vec[di];
  622.           switch (type)
  623.             {
  624.             case fcall_type_boolean:
  625.               (*jniEnv)->SetBooleanArrayRegion (jniEnv,
  626.                                                 values[di],
  627.                                                 0, len,
  628.                                                 (jboolean *) buf);
  629.               break;
  630.             case fcall_type_uchar:
  631.               (*jniEnv)->SetByteArrayRegion (jniEnv,
  632.                                              values[di],
  633.                                              0, len,
  634.                                              (jbyte *) buf);
  635.               break;
  636.             case fcall_type_schar:
  637.               (*jniEnv)->SetCharArrayRegion (jniEnv,
  638.                                              values[di],
  639.                                              0, len,
  640.                                              (jchar *) buf);
  641.               break;
  642.             case fcall_type_sshort:
  643.               (*jniEnv)->SetShortArrayRegion (jniEnv,
  644.                                               values[di],
  645.                                               0, len,
  646.                                               (jshort *) buf);
  647.               break;
  648.             case fcall_type_sint:
  649.               (*jniEnv)->SetIntArrayRegion (jniEnv,
  650.                                             values[di],
  651.                                             0, len,
  652.                                             (jint *) buf);
  653.               break;
  654.             case fcall_type_slonglong:
  655.               (*jniEnv)->SetLongArrayRegion (jniEnv,
  656.                                              values[di],
  657.                                              0, len,
  658.                                              (jlong *) buf);
  659.               break;
  660.             case fcall_type_float:
  661.               (*jniEnv)->SetFloatArrayRegion (jniEnv,
  662.                                               values[di],
  663.                                               0, len,
  664.                                               (jfloat *) buf);
  665.               break;
  666.             case fcall_type_double:
  667.               (*jniEnv)->SetDoubleArrayRegion (jniEnv,
  668.                                                values[di],
  669.                                                0, len,
  670.                                                (jdouble *) buf);
  671.               break;
  672.             default:
  673.               abort ();
  674.             }
  675.         }
  676.     }
  677.   void end_element (void)
  678.     {
  679.       vec[di]++;
  680.     }
  681.     
  682.   values[0] = javaObject;
  683.   process_array (rank, dims, type,
  684.                  start_dim, end_dim, NULL, end_element, NULL,
  685.                  buf, NULL);
  686. }
  687. const char *
  688. java_ensure_selector_type_signature (jobject jsel)
  689. {
  690.   unsigned argCount, typeSigLen = 0;
  691.   jobject typeSignature =
  692.     (*jniEnv)->GetObjectField (jniEnv, jsel, f_typeSignatureFid);
  693.   if (!typeSignature)
  694.     {
  695.       jobject argTypes = 
  696.         (*jniEnv)->GetObjectField (jniEnv, jsel, f_argTypesFid);
  697.       argCount = (*jniEnv)->GetArrayLength (jniEnv, argTypes);
  698.       {
  699.         const char *argSigs[argCount];
  700.         const char *retSig;
  701.         char *sig, *p;
  702.         unsigned ai;
  703.         
  704.         typeSigLen = 1;
  705.         for (ai = 0; ai < argCount; ai++)
  706.           {
  707.             jclass member =
  708.               (*jniEnv)->GetObjectArrayElement (jniEnv, argTypes, ai);
  709.             
  710.             argSigs[ai] = java_signature_for_class (member);
  711.             typeSigLen += strlen (argSigs[ai]);
  712.             (*jniEnv)->DeleteLocalRef (jniEnv, member);
  713.           }
  714.         typeSigLen++;
  715.         {
  716.           jobject retType =
  717.             (*jniEnv)->GetObjectField (jniEnv, jsel, f_retTypeFid);
  718.           
  719.           retSig = java_signature_for_class (retType);
  720.           (*jniEnv)->DeleteLocalRef (jniEnv, retType);
  721.         }
  722.         typeSigLen += strlen (retSig);
  723.         
  724.         sig = [scratchZone alloc: typeSigLen + 1];
  725.         
  726.         p = sig;
  727.         *p++ = '(';
  728.         for (ai = 0; ai < argCount; ai++)
  729.           p = stpcpy (p, argSigs[ai]);
  730.         *p++ = ')';
  731.         p = stpcpy (p, retSig);
  732.         for (ai = 0; ai < argCount; ai++)
  733.           [scratchZone free: (void *) argSigs[ai]];
  734. [scratchZone free: (void *) retSig];
  735.         {
  736.           jobject str = (*jniEnv)->NewStringUTF (jniEnv, sig);
  737.           (*jniEnv)->SetObjectField (jniEnv,
  738.                                      jsel,
  739.                                      f_typeSignatureFid,
  740.                                      str);
  741.           (*jniEnv)->DeleteLocalRef (jniEnv, str);
  742.         }
  743.         (*jniEnv)->DeleteLocalRef (jniEnv, argTypes);
  744.         return sig;
  745.       }
  746.     }
  747.   else
  748.     {
  749.       jboolean copyFlag;
  750.       const char *sig;
  751.       const char *utf =
  752.         (*jniEnv)->GetStringUTFChars (jniEnv, typeSignature, &copyFlag);
  753.       sig = SSTRDUP (utf);
  754.       if (copyFlag)
  755.         (*jniEnv)->ReleaseStringUTFChars (jniEnv, typeSignature, utf);
  756.       (*jniEnv)->DeleteLocalRef (jniEnv, typeSignature);
  757.       return sig;
  758.     }
  759. }
  760. fcall_type_t
  761. fcall_type_for_java_class (jclass class)
  762. {
  763.   fcall_type_t type;
  764.   if (classp (class, c_Selector))
  765.     type = fcall_type_selector;
  766.   else if (classp (class, c_String))
  767.     type = fcall_type_string;
  768.   else if (classp (class, c_Class))
  769.     type = fcall_type_class;
  770.   else if (exactclassp (class, c_int))
  771.     type = fcall_type_sint;
  772.   else if (exactclassp (class, c_short))
  773.     type = fcall_type_sshort;
  774.   else if (exactclassp (class, c_long))
  775.     type = fcall_type_slong;
  776.   else if (exactclassp (class, c_boolean))
  777.     type = fcall_type_boolean;
  778.   else if (exactclassp (class, c_byte))
  779.     type = fcall_type_uchar;
  780.   else if (exactclassp (class, c_char))
  781.     type = fcall_type_schar;
  782.   else if (exactclassp (class, c_float))
  783.     type = fcall_type_float;
  784.   else if (exactclassp (class, c_double))
  785.     type = fcall_type_double;
  786.   else if (exactclassp (class, c_void))
  787.     type = fcall_type_void;
  788.   else
  789.     type = fcall_type_object;
  790.   return type;
  791. }
  792. const char *
  793. java_get_class_name (jclass class)
  794. {
  795.   jobject string;
  796.   const char *ret;
  797.   if (!(string = (*jniEnv)->CallObjectMethod (jniEnv, class, m_ClassGetName)))
  798.     abort ();
  799.   ret = JAVA_COPY_STRING (string);
  800.   (*jniEnv)->DeleteLocalRef (jniEnv, string);
  801.   return ret;
  802. }
  803. void
  804. java_object_setVariable (jobject javaObject, const char *ivarName,
  805.                          fcall_type_t dataType, unsigned rank, unsigned *dims,
  806.                          void *inbuf)
  807. {
  808.   if (!javaObject)
  809.     abort ();
  810.   {
  811.     jclass javaClass = (*jniEnv)->GetObjectClass (jniEnv, javaObject);
  812.     jfieldID fid;
  813.     fcall_type_t type;
  814.     BOOL isArray;
  815.     
  816.     if (!javaClass)
  817.       abort ();
  818.     fid = class_java_find_field (javaClass, ivarName, &type, &isArray);
  819.     if (!fid)
  820.       raiseEvent (WarningMessage,
  821.                   "field `%s' was not found in java class `%s'n",
  822.                   ivarName,
  823.                   java_get_class_name (javaClass));
  824.     else
  825.       {
  826.         if (isArray)
  827.           {
  828.             jobject ary = 0;
  829.             if (rank > 1)
  830.               abort ();
  831.             switch (dataType)
  832.               {
  833.               case fcall_type_boolean:
  834.                 ary = (*jniEnv)->NewBooleanArray (jniEnv, dims[0]);
  835.                 break;
  836.               case fcall_type_uchar:
  837.                 ary = (*jniEnv)->NewByteArray (jniEnv, dims[0]);
  838.                 break;
  839.               case fcall_type_schar:
  840.                 ary = (*jniEnv)->NewCharArray (jniEnv, dims[0]);
  841.                 break;
  842.               case fcall_type_sshort:
  843.                 ary = (*jniEnv)->NewShortArray (jniEnv, dims[0]);
  844.                 break;
  845.               case fcall_type_sint:
  846.                 ary = (*jniEnv)->NewIntArray (jniEnv, dims[0]);
  847.                 break;
  848.               case fcall_type_slong:
  849.                 ary = (*jniEnv)->NewLongArray (jniEnv, dims[0]);
  850.                 break;
  851.               case fcall_type_float:
  852.                 ary = (*jniEnv)->NewFloatArray (jniEnv, dims[0]);
  853.                 break;
  854.               case fcall_type_double:
  855.                 ary = (*jniEnv)->NewDoubleArray (jniEnv, dims[0]);
  856.                 break;
  857.               default:
  858.                 abort ();
  859.               }
  860.             java_storeArray (ary, dataType, rank, dims, inbuf);
  861.             (*jniEnv)->SetObjectField (jniEnv, javaObject, fid, ary);
  862.             (*jniEnv)->DeleteLocalRef (jniEnv, ary);
  863.           }
  864.         else if (rank == 0 || (rank == 1 && dims[0] == 1))
  865.           {
  866. #define _SETVALUE(uptype,value) 
  867.     (*jniEnv)->Set##uptype##Field (jniEnv, javaObject, fid, value)
  868. #define SETVALUE(uptype, value) _SETVALUE(uptype, value)
  869.         
  870.             types_t *buf = inbuf;
  871.             // dataType of void means unspecified
  872.             // (e.g. from object_setVariable)
  873.             if (dataType != fcall_type_void && type != dataType)
  874.               raiseEvent (InvalidArgument,
  875.                           "Type mismatch setting `%s' data %u ivar %u",
  876.                           ivarName,
  877.                           (unsigned) dataType, (unsigned) type);
  878.             switch (type)
  879.               {
  880.               case fcall_type_object:
  881.                 SETVALUE (Object, SD_JAVA_ENSURE_OBJECT_JAVA (buf->object));
  882.                 break;
  883.               case fcall_type_class:
  884.                 SETVALUE (Object, SD_JAVA_FIND_CLASS_JAVA (buf->_class));
  885.                 break;
  886.               case fcall_type_string:
  887.                 {
  888.                   jobject lref = (*jniEnv)->NewStringUTF (jniEnv, buf->string);
  889.                   
  890.                   SETVALUE (Object, lref);
  891.                   (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  892.                 }
  893.                 break;
  894.               case fcall_type_long_double:
  895.                 abort ();
  896.               case fcall_type_double:
  897.                 SETVALUE (Double, buf->_double);
  898.                 break;
  899.               case fcall_type_float:
  900.                 SETVALUE (Float, buf->_float);
  901.                 break;
  902.               case fcall_type_boolean:
  903.                 SETVALUE (Boolean, buf->boolean);
  904.                 break;
  905.               case fcall_type_sint:
  906.                 SETVALUE (Int, buf->sint);
  907.                 break;
  908.               case fcall_type_sshort:
  909.                 SETVALUE (Short, buf->sshort);
  910.                 break;
  911.               case fcall_type_slonglong:
  912.                 SETVALUE (Long, buf->slonglong);
  913.                 break;
  914.               case fcall_type_uchar:
  915.                 SETVALUE (Byte, buf->uchar);
  916.                 break;
  917.               case fcall_type_schar:
  918.                 SETVALUE (Char, buf->schar);
  919.               case fcall_type_void:
  920.               case fcall_type_ushort:
  921.               case fcall_type_uint:
  922.               case fcall_type_ulong:
  923.               case fcall_type_slong:
  924.               case fcall_type_ulonglong:
  925.               case fcall_type_selector:
  926.               case fcall_type_jobject:
  927.               case fcall_type_jstring:
  928.               case fcall_type_jselector:
  929.               case fcall_type_iid:
  930.                 abort ();
  931.               }
  932. #undef SETVALUE
  933. #undef _SETVALUE
  934.           }
  935.         else
  936.           raiseEvent (InvalidArgument,
  937.                       "ivar %s fcall_type: %u rank: %u dims[0]: %un",
  938.                       ivarName, type, rank, dims[0]);
  939.       }
  940.     (*jniEnv)->DeleteLocalRef (jniEnv, javaClass);
  941.   }
  942. }
  943. fcall_type_t
  944. java_object_ivar_type (jobject javaObject, const char *ivarName, BOOL *isArrayPtr)
  945. {
  946.   jclass javaClass;
  947.   fcall_type_t type;
  948.   if (!javaObject)
  949.     abort ();
  950.   javaClass = (*jniEnv)->GetObjectClass (jniEnv, javaObject);
  951.   if (!class_java_find_field (javaClass, ivarName, &type, isArrayPtr))
  952.     abort ();
  953.   (*jniEnv)->DeleteLocalRef (jniEnv, javaClass);
  954.   return type;
  955. }
  956. static jobject
  957. get_swarmEnvironment_field (jobject swarmEnvironment,
  958.     const char *fieldName)
  959. {
  960.   jobject fieldObject, ret;
  961.   jstring str = (*jniEnv)->NewStringUTF (jniEnv, fieldName);
  962.   if (!(fieldObject =
  963. (*jniEnv)->CallObjectMethod (jniEnv,
  964.                                      c_SwarmEnvironmentImpl,
  965.                                      m_ClassGetDeclaredField,
  966.                                      str)))
  967.     raiseEvent (InternalError, "Could not find field `%s'n", fieldName);
  968.   (*jniEnv)->DeleteLocalRef (jniEnv, str);
  969.   
  970.   ret = (*jniEnv)->CallObjectMethod (jniEnv,
  971.                                      fieldObject,
  972.                                      m_FieldGetObject,
  973.                                      swarmEnvironment);
  974.   (*jniEnv)->DeleteLocalRef (jniEnv, fieldObject);
  975.   return ret;
  976. }
  977. static void
  978. create_bootstrap_refs (void)
  979. {
  980.   jclass lref;
  981.   if (!(lref = (*jniEnv)->FindClass (jniEnv, "swarm/Primitives")))
  982.     abort ();
  983.   c_Primitives = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  984.   (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  985.   
  986.   if (!(m_PrimitivesGetTypeMethod =
  987.         (*jniEnv)->GetStaticMethodID (jniEnv, c_Primitives, "getTypeMethod",
  988.                                       "(Ljava/lang/String;)Ljava/lang/reflect/Method;")))
  989.     abort ();
  990.   
  991.   if (!(lref = (*jniEnv)->FindClass (jniEnv, "java/lang/reflect/Method")))
  992.     abort ();
  993.   c_Method = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  994.   (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  995.   if (!(m_MethodGetReturnType =
  996.         (*jniEnv)->GetMethodID (jniEnv, c_Method, "getReturnType",
  997.                                 "()Ljava/lang/Class;")))
  998.     abort();
  999. }
  1000. static jclass
  1001. get_java_lang_class (const char *name)
  1002. {
  1003.   char class_name_buf[10 + strlen (name) + 1];
  1004.   char *p;
  1005.   jclass ret, clazz;
  1006.   
  1007.   p = stpcpy (class_name_buf, "java/lang/");
  1008.   p = stpcpy (p, name);
  1009.   if (!(clazz = (*jniEnv)->FindClass (jniEnv, class_name_buf)))
  1010.     abort ();
  1011.   
  1012.   ret = (*jniEnv)->NewGlobalRef (jniEnv, clazz);
  1013.   (*jniEnv)->DeleteLocalRef (jniEnv, clazz);
  1014.   return ret;
  1015. }
  1016. static void
  1017. create_class_refs (void)
  1018. {
  1019.   jobject lref;
  1020.   jclass get_primitive (const char *name)
  1021.     {
  1022. #if 0
  1023.       return get_type_field_for_class (get_java_lang_class (name));
  1024. #else
  1025.       jobject nameString = (*jniEnv)->NewStringUTF (jniEnv, name);
  1026.       jobject method;
  1027.       jclass lref, returnType;
  1028.       
  1029.       if (!(method = (*jniEnv)->CallStaticObjectMethod (jniEnv,
  1030.                                                         c_Primitives,
  1031.                                                         m_PrimitivesGetTypeMethod,
  1032.                                                         nameString)))
  1033.         abort ();
  1034.       (*jniEnv)->DeleteLocalRef (jniEnv, nameString);
  1035.       if (!(lref = (*jniEnv)->CallObjectMethod (jniEnv,
  1036.                                                 method,
  1037.                                                 m_MethodGetReturnType,
  1038.                                                 method)))
  1039.         abort ();
  1040.       returnType = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1041.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1042.       return returnType;
  1043. #endif
  1044.     }
  1045.   if (!initFlag)
  1046.    {
  1047.       c_char = get_primitive ("Character");
  1048.       c_byte = get_primitive ("Byte");
  1049.       c_int = get_primitive ("Integer");
  1050.       c_short = get_primitive ("Short");
  1051.       c_long = get_primitive ("Long");
  1052.       c_float = get_primitive ("Float");
  1053.       c_double = get_primitive ("Double");
  1054.       c_void = get_primitive ("Void");
  1055.       c_boolean = get_primitive ("Boolean");
  1056.       c_Boolean = get_java_lang_class ("Boolean");
  1057.       c_Char = get_java_lang_class ("Character");
  1058.       c_Byte= get_java_lang_class ("Byte");
  1059.       c_Integer = get_java_lang_class ("Integer");
  1060.       c_Short = get_java_lang_class ("Short");
  1061.       c_Long = get_java_lang_class ("Long");
  1062.       c_Float = get_java_lang_class ("Float");
  1063.       c_Double = get_java_lang_class ("Double");
  1064.      
  1065.       c_String = get_java_lang_class ("String");
  1066.       c_Object = get_java_lang_class ("Object");
  1067.       c_Class = get_java_lang_class ("Class");
  1068.       if (!(lref = (*jniEnv)->FindClass (jniEnv, "java/lang/reflect/Field")))
  1069.         abort ();
  1070.       c_Field = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1071.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1072.       if (!(lref = (*jniEnv)->FindClass (jniEnv,
  1073.                                          "java/lang/reflect/Modifier")))
  1074. abort ();
  1075.       c_Modifier = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1076.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1077.       if (!(lref = (*jniEnv)->FindClass (jniEnv, "java/util/Collection")))
  1078.         abort ();
  1079.       c_Collection = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1080.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1081.       if (!(lref = (*jniEnv)->FindClass (jniEnv, "swarm/BaseImpl")))
  1082.         abort ();
  1083.       c_Base = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1084.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1085.       if (!(lref = (*jniEnv)->FindClass (jniEnv, "swarm/Selector")))
  1086.         abort ();
  1087.       c_Selector = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1088.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1089.       
  1090.       if (!(lref = (*jniEnv)->FindClass (jniEnv, "swarm/PhaseCImpl")))
  1091.         abort ();
  1092.       c_PhaseCImpl = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1093.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1094.       if (!(lref = (*jniEnv)->FindClass (jniEnv,
  1095.                                          "swarm/SwarmEnvironmentImpl")))
  1096. abort ();
  1097.       c_SwarmEnvironmentImpl = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1098.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1099.       if ((lref = (*jniEnv)->FindClass (jniEnv,
  1100.                                         "swarm/ProxyClassLoader")))
  1101.         {
  1102.           c_ProxyClassLoader = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1103.           (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1104.           
  1105.           if (!(lref = (*jniEnv)->FindClass (jniEnv,
  1106.                                              "swarm/ObjCProxy")))
  1107.             abort ();
  1108.           c_ObjCProxy = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1109.           (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1110.         }
  1111.       else
  1112.         (*jniEnv)->ExceptionClear (jniEnv);
  1113.       initFlag = YES;
  1114.    }
  1115. }
  1116. static void 
  1117. create_method_refs (void)
  1118. {
  1119.   jmethodID findMethodID (const char *name, jclass clazz)
  1120.     {
  1121.       char sig[31 + strlen (name) + 1 + 1];
  1122.       char *p;
  1123.       jmethodID res;
  1124.       p = stpcpy (sig, "(Ljava/lang/String;)Ljava/lang/");
  1125.       p = stpcpy (p, name);
  1126.       p = stpcpy (p, ";");
  1127.       if (!(res = (*jniEnv)->GetStaticMethodID (jniEnv, clazz, "valueOf", sig)))
  1128. abort ();
  1129.       return res;
  1130.     }   
  1131.   
  1132.   m_BooleanValueOf = findMethodID ("Boolean", c_Boolean);
  1133.   
  1134.   m_ByteValueOf = findMethodID ("Byte", c_Byte);
  1135.   
  1136.   m_IntegerValueOf = findMethodID ("Integer", c_Integer);
  1137.   
  1138.   m_ShortValueOf = findMethodID ("Short", c_Short);
  1139.   
  1140.   m_LongValueOf = findMethodID ("Long", c_Long);
  1141.   
  1142.   m_FloatValueOf = findMethodID ("Float", c_Float);
  1143.   
  1144.   m_DoubleValueOf = findMethodID ("Double", c_Double);
  1145.   
  1146.   if (!(m_StringValueOfBoolean = 
  1147.       (*jniEnv)->GetStaticMethodID (jniEnv, c_String, "valueOf", 
  1148.                                     "(Z)Ljava/lang/String;")))
  1149.     abort ();
  1150.   
  1151.   if (!(m_StringValueOfChar = 
  1152.         (*jniEnv)->GetStaticMethodID (jniEnv, c_String, "valueOf", 
  1153.                                       "(C)Ljava/lang/String;")))
  1154.     abort ();
  1155.   if (!(m_StringValueOfInt = 
  1156.       (*jniEnv)->GetStaticMethodID (jniEnv, c_String, "valueOf", 
  1157.                                     "(I)Ljava/lang/String;")))
  1158.     abort ();
  1159.   if (!(m_StringValueOfLong = 
  1160.       (*jniEnv)->GetStaticMethodID (jniEnv, c_String, "valueOf", 
  1161.                                     "(J)Ljava/lang/String;")))
  1162.     abort ();
  1163.   
  1164.   if (!(m_StringValueOfFloat = 
  1165.         (*jniEnv)->GetStaticMethodID (jniEnv, c_String, "valueOf", 
  1166.                                       "(F)Ljava/lang/String;")))
  1167.     abort ();
  1168.   
  1169.   if (!(m_StringValueOfDouble = 
  1170.         (*jniEnv)->GetStaticMethodID (jniEnv, c_String, "valueOf", 
  1171.                                       "(D)Ljava/lang/String;")))
  1172.     abort ();
  1173.   
  1174.   if (!(m_StringValueOfObject = 
  1175.         (*jniEnv)->GetStaticMethodID (jniEnv, c_String, "valueOf", 
  1176.                                       "(Ljava/lang/Object;)Ljava/lang/String;")))
  1177.     abort ();
  1178.   
  1179.   if (!(m_FieldSet = 
  1180. (*jniEnv)->GetMethodID (jniEnv, c_Field, "set", 
  1181.                                 "(Ljava/lang/Object;Ljava/lang/Object;)V")))
  1182.     abort ();
  1183.   
  1184.   if (!(m_FieldSetChar = 
  1185. (*jniEnv)->GetMethodID (jniEnv, c_Field, "setChar", 
  1186.                                 "(Ljava/lang/Object;C)V")))
  1187.     abort ();
  1188.   if (!(m_FieldSetFloat = 
  1189. (*jniEnv)->GetMethodID (jniEnv, c_Field, "setFloat", 
  1190.                                 "(Ljava/lang/Object;F)V")))
  1191.     abort ();
  1192.   
  1193.   if (!(m_FieldSetDouble = 
  1194. (*jniEnv)->GetMethodID (jniEnv, c_Field, "setDouble", 
  1195.                                 "(Ljava/lang/Object;D)V")))
  1196.     abort ();
  1197.   if (!(m_ClassGetField =
  1198.       (*jniEnv)->GetMethodID (jniEnv, c_Class, "getField",
  1199.                               "(Ljava/lang/String;)Ljava/lang/reflect/Field;")))
  1200.     abort ();
  1201.   if (!(m_ClassGetDeclaredField =
  1202.       (*jniEnv)->GetMethodID (jniEnv, c_Class, "getDeclaredField",
  1203.                               "(Ljava/lang/String;)Ljava/lang/reflect/Field;")))
  1204.     abort ();
  1205.   
  1206.   if (!(m_ClassGetDeclaredFields =
  1207.    (*jniEnv)->GetMethodID (jniEnv, c_Class, "getDeclaredFields",
  1208.                                 "()[Ljava/lang/reflect/Field;")))
  1209.     abort ();
  1210.   
  1211.   if (!(m_ClassGetDeclaredMethods =
  1212.    (*jniEnv)->GetMethodID (jniEnv, c_Class, "getDeclaredMethods",
  1213.                                 "()[Ljava/lang/reflect/Method;")))
  1214.     abort ();
  1215.   if (!(m_ClassGetFields =
  1216.    (*jniEnv)->GetMethodID (jniEnv, c_Class, "getFields",
  1217.                                 "()[Ljava/lang/reflect/Field;")))
  1218.     abort ();
  1219.   
  1220.   if (!(m_ClassGetName = 
  1221. (*jniEnv)->GetMethodID (jniEnv, c_Class, "getName", "()Ljava/lang/String;")))
  1222.     abort ();
  1223.   
  1224.   if (!(m_ClassIsArray =
  1225. (*jniEnv)->GetMethodID (jniEnv, c_Class, "isArray", "()Z")))
  1226.     abort ();
  1227.   if (!(m_FieldGetName = 
  1228. (*jniEnv)->GetMethodID (jniEnv, c_Field, "getName", "()Ljava/lang/String;")))
  1229.     abort ();
  1230.   if (!(m_FieldGetType =
  1231. (*jniEnv)->GetMethodID (jniEnv, c_Field, "getType", "()Ljava/lang/Class;")))
  1232.     abort ();
  1233.   
  1234.   if (!(m_FieldGetBoolean =
  1235.       (*jniEnv)->GetMethodID (jniEnv, c_Field, "getBoolean", 
  1236.                               "(Ljava/lang/Object;)Z")))
  1237.     abort ();
  1238.   
  1239.   if (!(m_FieldGetChar =
  1240.       (*jniEnv)->GetMethodID (jniEnv, c_Field, "getChar", 
  1241.                               "(Ljava/lang/Object;)C")))
  1242.     abort ();
  1243.   if (!(m_FieldGetShort =
  1244.       (*jniEnv)->GetMethodID (jniEnv, c_Field, "getShort", 
  1245.                               "(Ljava/lang/Object;)S")))
  1246.     abort ();
  1247.   if (!(m_FieldGetInt =
  1248.       (*jniEnv)->GetMethodID (jniEnv, c_Field, "getInt", 
  1249.                               "(Ljava/lang/Object;)I")))
  1250.     abort ();
  1251.   if (!(m_FieldGetLong =
  1252.       (*jniEnv)->GetMethodID (jniEnv, c_Field, "getLong", 
  1253.                               "(Ljava/lang/Object;)J")))
  1254.     abort ();
  1255.   
  1256.   if (!(m_FieldGetFloat =
  1257.       (*jniEnv)->GetMethodID (jniEnv, c_Field, "getFloat", 
  1258.                               "(Ljava/lang/Object;)F")))
  1259.     abort ();
  1260.   if (!(m_FieldGetDouble =
  1261.       (*jniEnv)->GetMethodID (jniEnv, c_Field, "getDouble", 
  1262.                               "(Ljava/lang/Object;)D")))
  1263.     abort ();
  1264.   if (!(m_FieldGetObject =
  1265.         (*jniEnv)->GetMethodID (jniEnv, c_Field, "get",
  1266.                                 "(Ljava/lang/Object;)Ljava/lang/Object;")))
  1267.     abort ();
  1268.   if (!(m_FieldGetModifiers =
  1269. (*jniEnv)->GetMethodID (jniEnv, c_Field, "getModifiers", "()I")))
  1270.     abort ();
  1271.   if (!(m_MethodGetName =
  1272. (*jniEnv)->GetMethodID (jniEnv, c_Method, "getName",
  1273.                                 "()Ljava/lang/String;")))
  1274.     abort ();
  1275.   if (!(m_MethodGetModifiers =
  1276.         (*jniEnv)->GetMethodID (jniEnv, c_Method, "getModifiers", "()I")))
  1277.     abort ();
  1278.   if (!(m_ModifierIsPublic = 
  1279.         (*jniEnv)->GetStaticMethodID (jniEnv, c_Modifier, "isPublic", "(I)Z")))
  1280.     abort ();
  1281.   if (!(m_ModifierIsStatic = 
  1282.         (*jniEnv)->GetStaticMethodID (jniEnv, c_Modifier, "isStatic", "(I)Z")))
  1283.     abort ();
  1284.   
  1285.   if (!(m_SelectorConstructor =
  1286. (*jniEnv)->GetMethodID (jniEnv, c_Selector, "<init>", 
  1287.                                 "(Ljava/lang/Class;Ljava/lang/String;Z)V")))
  1288.     abort ();
  1289.   if (!(m_HashCode =
  1290.         (*jniEnv)->GetMethodID (jniEnv, c_Object, "hashCode", "()I")))
  1291.     abort ();
  1292.   
  1293.   if (!(m_Equals =
  1294.         (*jniEnv)->GetMethodID (jniEnv, c_Object, "equals",
  1295.                                 "(Ljava/lang/Object;)Z")))
  1296.     abort ();
  1297.   
  1298.   if (!(m_PhaseCImpl_copy_creating_phase_to_using_phase = 
  1299.         (*jniEnv)->GetMethodID (jniEnv,
  1300.                                 c_PhaseCImpl,
  1301.                                 "_copy_creating_phase_to_using_phase",
  1302.                                 "()V")))
  1303.     abort ();
  1304.   if (c_ProxyClassLoader)
  1305.     if (!(m_ProxyClassLoaderLoadClass =
  1306.           (*jniEnv)->GetMethodID (jniEnv, c_ProxyClassLoader, "loadClass",
  1307.                                   "(Ljava/lang/String;)Ljava/lang/Class;")))
  1308.       abort ();
  1309. }
  1310. static void
  1311. create_field_refs (void)
  1312. {
  1313.   if (!(f_objcPtrFid = (*jniEnv)->GetFieldID (jniEnv, c_Base, "objcPtr", "I")))
  1314.     abort ();
  1315.   if (!(f_nameFid = (*jniEnv)->GetFieldID (jniEnv, c_Selector, "signature", "Ljava/lang/String;")))
  1316.     abort ();
  1317.   if (!(f_retTypeFid = (*jniEnv)->GetFieldID (jniEnv, c_Selector, "retType", "Ljava/lang/Class;")))
  1318.     abort ();
  1319.   if (!(f_argTypesFid = (*jniEnv)->GetFieldID (jniEnv, c_Selector, "argTypes", "[Ljava/lang/Class;")))
  1320.     abort ();
  1321.   if (!(f_typeSignatureFid = (*jniEnv)->GetFieldID (jniEnv, c_Selector, "typeSignature", "Ljava/lang/String;")))
  1322.     abort ();
  1323.   if (!(f_objcFlagFid = (*jniEnv)->GetFieldID (jniEnv, c_Selector, "objcFlag", "Z")))
  1324.     abort ();
  1325.   
  1326.   if (!(f_nextPhase = (*jniEnv)->GetFieldID (jniEnv, c_PhaseCImpl, "nextPhase", 
  1327.                                              "Ljava/lang/Object;")))
  1328.     abort();
  1329. }
  1330. static void
  1331. create_object_refs ()
  1332. {
  1333.   jmethodID mid;
  1334.   jobject lref;
  1335.   
  1336.   if (c_ProxyClassLoader)
  1337.     {
  1338.       if (!(mid = (*jniEnv)->GetMethodID (jniEnv, c_ProxyClassLoader,
  1339.                                           "<init>", "()V")))
  1340.         abort ();
  1341.       lref = (*jniEnv)->NewObject (jniEnv, c_ProxyClassLoader, mid);
  1342.       proxyClassLoader = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1343.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1344.     }
  1345. }
  1346. void
  1347. java_create_refs (void)
  1348. {
  1349.   create_bootstrap_refs ();
  1350.   create_class_refs ();
  1351.   create_method_refs ();
  1352.   create_field_refs ();
  1353.   create_object_refs ();
  1354. }
  1355. static void
  1356. associate (jobject swarmEnvironment, const char *fieldName, id objcObject)
  1357. {
  1358.   jobject lref;
  1359.   
  1360.   lref = get_swarmEnvironment_field (swarmEnvironment, fieldName);
  1361.   if (!lref)
  1362.     raiseEvent (InternalError, "Could not find field name `%s'n",
  1363.                 fieldName);
  1364.   SD_JAVA_ADD_OBJECT (lref, objcObject);
  1365.   (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1366. }
  1367. #define ASSOCIATE(fieldName) associate (swarmEnvironment, #fieldName, fieldName)
  1368. void
  1369. swarm_directory_java_associate_objects_startup (jobject swarmEnvironment)
  1370. {
  1371.   ASSOCIATE (scratchZone);
  1372.   ASSOCIATE (globalZone);
  1373. }
  1374. void
  1375. swarm_directory_java_associate_objects (jobject swarmEnvironment)
  1376. {
  1377.   extern BOOL swarmGUIMode;
  1378.   ASSOCIATE (arguments);
  1379.   if (hdf5Archiver)
  1380.     ASSOCIATE (hdf5Archiver);
  1381.   ASSOCIATE (lispArchiver);
  1382.   if (hdf5AppArchiver)
  1383.     ASSOCIATE (hdf5AppArchiver);
  1384.   ASSOCIATE (lispAppArchiver);
  1385.   {
  1386.     extern id <Symbol> LanguageCOM, LanguageJava, LanguageObjc;
  1387.     ASSOCIATE (LanguageCOM);
  1388.     ASSOCIATE (LanguageJava);
  1389.     ASSOCIATE (LanguageObjc);
  1390.   }
  1391.   {
  1392.     extern id <Symbol> Start, Member, End;
  1393.     ASSOCIATE (Start);
  1394.     ASSOCIATE (Member);
  1395.     ASSOCIATE (End);
  1396.   }
  1397.   {
  1398.     extern id <Symbol> Randomized;
  1399.     extern id <Symbol> Sequential;
  1400.     
  1401.     ASSOCIATE (Randomized);
  1402.     ASSOCIATE (Sequential);
  1403.   }
  1404.   {
  1405.     extern id probeLibrary;
  1406.     
  1407.     ASSOCIATE (probeLibrary);
  1408.   }
  1409.    
  1410.   {
  1411.     extern id randomGenerator, uniformIntRand, uniformDblRand;
  1412.     
  1413.     ASSOCIATE (randomGenerator);
  1414.     ASSOCIATE (uniformIntRand);
  1415.     ASSOCIATE (uniformDblRand);
  1416.   }
  1417. #ifndef DISABLE_GUI
  1418.   if (swarmGUIMode)
  1419.     {
  1420.       extern id probeDisplayManager;
  1421.       
  1422.       extern id <Symbol> ControlStateRunning, ControlStateStopped,
  1423.         ControlStateStepping, ControlStateQuit,ControlStateNextTime;
  1424.       
  1425.       ASSOCIATE (probeDisplayManager);
  1426.       
  1427.       ASSOCIATE (ControlStateRunning);
  1428.       ASSOCIATE (ControlStateStopped);
  1429.       ASSOCIATE (ControlStateStepping);
  1430.       ASSOCIATE (ControlStateQuit);
  1431.       ASSOCIATE (ControlStateNextTime);
  1432.     }
  1433. #endif
  1434.   
  1435.   {
  1436.     extern id <Symbol> Initialized, Running, Stopped, Holding, Released, 
  1437.       Terminated, Completed;
  1438.     ASSOCIATE (Initialized);
  1439.     ASSOCIATE (Running);
  1440.     ASSOCIATE (Stopped);
  1441.     ASSOCIATE (Holding);
  1442.     ASSOCIATE (Released);
  1443.     ASSOCIATE (Terminated);
  1444.     ASSOCIATE (Completed);
  1445.   }
  1446.   {
  1447.     jfieldID fid;
  1448.     
  1449.     if (!(fid = (*jniEnv)->GetFieldID (jniEnv, c_SwarmEnvironmentImpl, "guiFlag", "Z")))
  1450.       abort ();
  1451.     
  1452.     (*jniEnv)->SetBooleanField (jniEnv, swarmEnvironment, fid, (jboolean) swarmGUIMode);
  1453.   }
  1454. }
  1455. unsigned
  1456. swarm_directory_java_hash_code (jobject javaObject)
  1457. {
  1458.   int hashCode;
  1459.   hashCode = (*jniEnv)->CallIntMethod (jniEnv, javaObject, m_HashCode);
  1460.   return (hashCode < 0 ? - hashCode : hashCode) % DIRECTORY_SIZE;
  1461. }
  1462. static ObjectEntry *
  1463. swarm_directory_java_find (jobject javaObject)
  1464. {
  1465.   if (javaObject)
  1466.     {
  1467.       id ret;
  1468.       unsigned index = swarm_directory_java_hash_code (javaObject);
  1469.       id <Map> m = swarmDirectory->javaTable[index];
  1470.       ObjectEntry *findEntry = JAVA_FIND_OBJECT_ENTRY (javaObject);
  1471.       ret = m ? [m at: findEntry] : nil;
  1472.       return ret;
  1473.     }
  1474.   return nil;
  1475. }
  1476. id
  1477. swarm_directory_java_find_swarm_objc (jobject javaObject)
  1478. {
  1479.   return (id) (*jniEnv)->GetIntField (jniEnv, javaObject, f_objcPtrFid);
  1480. }
  1481. static id
  1482. find_swarm_objc_safe (jobject javaObject)
  1483. {
  1484.   id result;
  1485.   if (javaObject)
  1486.     {
  1487.       jclass class = (*jniEnv)->GetObjectClass (jniEnv, javaObject);
  1488.       result = (classp (class, c_Base)
  1489.                 ? swarm_directory_java_find_swarm_objc (javaObject)
  1490.                 : nil);
  1491.       (*jniEnv)->DeleteLocalRef (jniEnv, class);
  1492.     }
  1493.   else
  1494.     result = nil;
  1495.   return result;
  1496. }
  1497. id
  1498. swarm_directory_java_ensure_objc (jobject javaObject)
  1499. {
  1500.   id result;
  1501.   if (!javaObject)
  1502.     result = nil;
  1503.   else if(!(result = find_swarm_objc_safe (javaObject)))
  1504.     {
  1505.       ObjectEntry *resultEntry; 
  1506.       
  1507.       resultEntry = swarm_directory_java_find (javaObject);
  1508.       
  1509.       if ((*jniEnv)->IsInstanceOf (jniEnv, javaObject, c_String))
  1510.         {
  1511.           jboolean isCopy;
  1512.           const char *utf, *str;
  1513.           
  1514.           utf = (*jniEnv)->GetStringUTFChars (jniEnv, javaObject, &isCopy);
  1515.           str = ZSTRDUP (getZone (swarmDirectory), utf);
  1516.           if (isCopy)
  1517.             (*jniEnv)->ReleaseStringUTFChars (jniEnv, javaObject, utf);
  1518.           
  1519.           if (resultEntry)
  1520.             {
  1521.               const char *last = (const char *) resultEntry->object;
  1522.               resultEntry = SD_JAVA_SWITCHOBJC (resultEntry->foreignObject.java, (id) str);
  1523.       ZFREEBLOCK (getZone (swarmDirectory), (void *) last);
  1524.             }
  1525.           else
  1526.             resultEntry = SD_JAVA_ADD_STRING (javaObject, str);
  1527.         }
  1528.       else if (!resultEntry)
  1529.         resultEntry =
  1530.           SD_JAVA_ADD_OBJECT (javaObject, 
  1531.                               ((*jniEnv)->IsInstanceOf (jniEnv, javaObject, c_Collection)
  1532.                                ? [JavaCollection create: globalZone]
  1533.                                : [JavaProxy create: globalZone]));
  1534.       
  1535.       result = resultEntry->object;
  1536.     }
  1537.   return result;
  1538. }
  1539. static jobject
  1540. java_instantiate (jclass clazz)
  1541. {
  1542.   jmethodID mid;
  1543.   if (!(mid = (*jniEnv)->GetMethodID (jniEnv, clazz, "<init>", "()V")))
  1544.     abort ();
  1545.   return (*jniEnv)->NewObject (jniEnv, clazz, mid);
  1546. }
  1547. ObjectEntry *
  1548. java_instantiate_pair (jclass clazz)
  1549. {
  1550.   id proxy;
  1551.   ObjectEntry *entry;
  1552.   jobject lref = java_instantiate (clazz);
  1553.   
  1554.   proxy = [JavaProxy create: globalZone];
  1555.   entry = SD_JAVA_ADD_OBJECT (lref, proxy);
  1556.   (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1557.   return entry;
  1558. }
  1559. jclass
  1560. java_find_class (const char *javaClassName, BOOL failFlag)
  1561. {
  1562.   jobject ret;
  1563.   jobject throwable;
  1564.   size_t i, len = strlen (javaClassName);
  1565.   char buf[len + 1];
  1566.   for (i = 0; i < len; i++)
  1567.     buf[i] = (javaClassName[i] == '.') ? '/' : javaClassName[i];
  1568.   buf[len] = '';
  1569.   
  1570.   (*jniEnv)->ExceptionClear (jniEnv);
  1571.   ret = (*jniEnv)->FindClass (jniEnv, buf);
  1572.   
  1573.   if (failFlag)
  1574.     {
  1575.       if ((throwable = (*jniEnv)->ExceptionOccurred (jniEnv)) != NULL)
  1576.         (*jniEnv)->ExceptionDescribe (jniEnv);
  1577.     }
  1578.   else
  1579.     (*jniEnv)->ExceptionClear (jniEnv);
  1580.   return ret;
  1581. }
  1582. static jclass
  1583. find_java_wrapper_class (Class class)
  1584. {
  1585.   const char *name = language_independent_class_name_for_objc_class (class);
  1586.   jclass ret = 0;
  1587.   if (name)
  1588.     {
  1589.       ret = java_find_class (name, YES);
  1590.       FREECLASSNAME (name);
  1591.     }
  1592.   else if (proxyClassLoader)
  1593.     {
  1594.       jstring str = (*jniEnv)->NewStringUTF (jniEnv, class->name);
  1595.       ret = (*jniEnv)->CallObjectMethod (jniEnv,
  1596.                                          proxyClassLoader,
  1597.                                          m_ProxyClassLoaderLoadClass,
  1598.                                          str);
  1599.       (*jniEnv)->DeleteLocalRef (jniEnv, str);
  1600.     }
  1601.   return ret;
  1602. }
  1603. jobject
  1604. swarm_directory_objc_ensure_java (id object)
  1605. {
  1606.   jobject jobj;
  1607.   if (!object)
  1608.     return 0;
  1609.   jobj = SD_JAVA_FIND_OBJECT_JAVA (object);
  1610.   if (!jobj)
  1611.     {
  1612.       Class class = getClass (object);
  1613.       jclass javaClass = SD_JAVA_FIND_CLASS_JAVA (class);
  1614.       jobject lref;
  1615.       if (!javaClass) // e.g., a native class and no class loader (no kawa.jar)
  1616.         abort ();
  1617.       lref = java_instantiate (javaClass);
  1618.       jobj = SD_JAVA_ADD_OBJECT_JAVA (lref, object);
  1619.       (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1620.     }
  1621.   return jobj;
  1622. }
  1623. id
  1624. swarm_directory_java_find_objc (jobject javaObject)
  1625. {
  1626.   if (!javaObject)
  1627.     return nil;
  1628.   else
  1629.     {
  1630.       id swarmObj = find_swarm_objc_safe (javaObject);
  1631.       if (swarmObj)
  1632.         return swarmObj;
  1633.       else
  1634.         {
  1635.           ObjectEntry *entry = swarm_directory_java_find (javaObject);
  1636.           
  1637.           return entry ? entry->object : nil;
  1638.         }
  1639.     }
  1640. }
  1641. jobject
  1642. swarm_directory_java_next_phase (jobject jobj)
  1643. {
  1644.   (*jniEnv)->CallVoidMethod (jniEnv, jobj, 
  1645.                              m_PhaseCImpl_copy_creating_phase_to_using_phase);
  1646.   return (*jniEnv)->GetObjectField (jniEnv, jobj, f_nextPhase);
  1647. }
  1648. static int
  1649. java_compareDirectoryEntries (DirectoryEntry *obj1, DirectoryEntry* obj2)
  1650. {
  1651. #if 0
  1652.   return (int) !(*jniEnv)->CallBooleanMethod (jniEnv,
  1653.                                               obj1->foreignObject.java,
  1654.                                               m_Equals,
  1655.                                               obj2->foreignObject.java);
  1656. #else
  1657.   return (int) !(*jniEnv)->IsSameObject (jniEnv,
  1658.                                          obj1->foreignObject.java,
  1659.                                          obj2->foreignObject.java);
  1660. #endif
  1661. }
  1662. static id <Map>
  1663. createDirectoryEntryMap (void)
  1664. {
  1665.   return [[[Map createBegin: getZone (swarmDirectory)]
  1666.             setCompareFunction: java_compareDirectoryEntries]
  1667.            createEnd];
  1668. }
  1669. static void
  1670. swarm_directory_switch_java_entry (ObjectEntry *entry, jobject javaObject)
  1671. {
  1672.   jclass class = (*jniEnv)->GetObjectClass (jniEnv, javaObject);
  1673.   if (classp (class, c_Base))
  1674.     {
  1675.       (*jniEnv)->SetIntField (jniEnv, javaObject, f_objcPtrFid,
  1676.                               (jint) entry->object);
  1677.       entry->foreignObject.java = javaObject;
  1678.     }
  1679.  else
  1680.    {
  1681.       unsigned index;
  1682.       id <Map> m;
  1683.       id <Map> *javaTable = swarmDirectory->javaTable;
  1684.       
  1685.       index = swarm_directory_java_hash_code (entry->foreignObject.java);
  1686.       m = javaTable[index];
  1687.       [m remove: entry];
  1688.       (*jniEnv)->DeleteGlobalRef (jniEnv, entry->foreignObject.java);
  1689.       
  1690.       index = swarm_directory_java_hash_code (javaObject);
  1691.       entry->foreignObject.java = javaObject;
  1692.       if (!javaTable[index])
  1693.         javaTable[index] = createDirectoryEntryMap ();
  1694.       
  1695.       [javaTable[index] at: entry insert: entry];
  1696.     }
  1697.   (*jniEnv)->DeleteLocalRef (jniEnv, class);
  1698. }
  1699. ObjectEntry *
  1700. swarm_directory_java_switch_phase (Object_s *nextPhase,
  1701.                                    jobject currentJavaPhase)
  1702. {
  1703.   jobject lref = SD_JAVA_NEXTPHASE (currentJavaPhase);
  1704.   Object_s *currentPhase = SD_JAVA_FIND_OBJECT_OBJC (currentJavaPhase);
  1705.   ObjectEntry *retEntry;
  1706.   jobject nextJavaPhase = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1707.   (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1708.   if (currentPhase != nextPhase)
  1709.     {
  1710.       id entry = JAVA_OBJECT_ENTRY (currentJavaPhase, nextPhase);
  1711.       nextPhase->foreignEntry = entry;
  1712.       swarm_directory_switch_java_entry (entry, nextJavaPhase);
  1713.       swarm_directory_entry_drop (currentPhase->foreignEntry);
  1714.       currentPhase->foreignEntry = NULL;
  1715.       retEntry = entry;
  1716.     }
  1717.   else
  1718.     {
  1719.       swarm_directory_switch_java_entry (nextPhase->foreignEntry,
  1720.                                          nextJavaPhase);
  1721.       retEntry = nextPhase->foreignEntry;
  1722.     }
  1723.   return retEntry;
  1724. }
  1725. SEL
  1726. swarm_directory_java_ensure_selector (jobject jsel)
  1727. {
  1728.   SEL sel;
  1729.   if (!jsel)
  1730.     sel = NULL;
  1731.   else if (!(sel = (SEL) SD_JAVA_FIND_OBJECT_OBJC (jsel)))
  1732.     {
  1733.       char *name, *p;
  1734.       int i;
  1735.       jboolean copyFlag;
  1736.       jboolean objcFlag;
  1737.       jarray argTypes;
  1738.       jsize argCount;
  1739.         
  1740.       objcFlag = (*jniEnv)->GetBooleanField (jniEnv, jsel, f_objcFlagFid);
  1741.       argTypes = (*jniEnv)->GetObjectField (jniEnv, jsel, f_argTypesFid);
  1742.       argCount = (*jniEnv)->GetArrayLength (jniEnv, argTypes);
  1743.       {
  1744.         jstring string;
  1745.         const char *utf;
  1746.         
  1747.         string = (*jniEnv)->GetObjectField (jniEnv, jsel, f_nameFid);
  1748.         utf = (*jniEnv)->GetStringUTFChars (jniEnv, string, &copyFlag);
  1749.         
  1750.         if (objcFlag)
  1751.           {
  1752.             size_t len = strlen (utf);
  1753.             BOOL needTrailingColon = argCount > 0 && utf[len - 1] != '$';
  1754.             
  1755.             p = name = [scratchZone alloc: len + (int) needTrailingColon + 1];
  1756.             strcpy (name, utf);
  1757.             while (*p)
  1758.               {
  1759.                 if (*p == '$')
  1760.                   *p = ':';
  1761.                 p++;
  1762.               }
  1763.             if (needTrailingColon)
  1764.     {
  1765.               *p++ = ':';
  1766.               *p = '';
  1767.             }
  1768.           }
  1769.         else
  1770.           {
  1771.             name = [scratchZone alloc: strlen (utf) + argCount + 1];
  1772.             p = stpcpy (name, utf);
  1773.             for (i = 0; i < argCount; i++)
  1774.               *p++ = ':';
  1775.             *p = '';
  1776.           }
  1777.         if (copyFlag)
  1778.           (*jniEnv)->ReleaseStringUTFChars (jniEnv, string, utf);
  1779.         (*jniEnv)->DeleteLocalRef (jniEnv, string);
  1780.       }
  1781.       {
  1782.         jsize ti;
  1783.         char signatureBuf[(argCount + 3) * 3 + 1], *p = signatureBuf;
  1784.           
  1785.         void add_type (fcall_type_t type)
  1786.           {
  1787.             const char *objctype =  objc_type_for_fcall_type (type);
  1788.             p = stpcpy (p, objctype);
  1789.             *p++ = '0';
  1790.             *p = '';
  1791.             [globalZone free: (void *) objctype];
  1792.           }
  1793.         void add (jclass class)
  1794.           {
  1795.             add_type (fcall_type_for_java_class (class));
  1796.           }
  1797.         {
  1798.           jobject retType = (*jniEnv)->GetObjectField (jniEnv, jsel, f_retTypeFid);
  1799.           
  1800.           add (retType);
  1801.           (*jniEnv)->DeleteLocalRef (jniEnv, retType);
  1802.         }
  1803.         add_type (fcall_type_object);
  1804.         add_type (fcall_type_selector);
  1805.         for (ti = 0; ti < argCount; ti++)
  1806.           {
  1807.             jobject lref = (*jniEnv)->GetObjectArrayElement (jniEnv, argTypes, ti);
  1808.             add (lref);
  1809.             (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1810.           }
  1811.       
  1812.         sel = sel_get_any_typed_uid (name);
  1813.         {
  1814.           BOOL needSelector = NO;
  1815.           
  1816.           if (sel)
  1817.             {
  1818.               if (!sel_get_typed_uid (name, signatureBuf))
  1819.                 {
  1820. #if 1
  1821.                   raiseEvent (WarningMessage,
  1822.                               "Method `%s' type (%s) differs from Swarm "
  1823.                               "method's type (%s)n",
  1824.                             name, signatureBuf, sel->sel_types);
  1825. #endif
  1826.                   needSelector = YES;
  1827.                 }
  1828.               
  1829.             }
  1830.           else
  1831.             needSelector = YES;
  1832.           
  1833.           if (needSelector)
  1834.             {
  1835.               const char *type =
  1836.                 mframe_build_signature (signatureBuf, NULL, NULL, NULL);
  1837.               
  1838.               sel = sel_register_typed_name (name, type);
  1839.             }
  1840.         }
  1841.       }
  1842.       
  1843.       SD_JAVA_ADD_SELECTOR (jsel, sel);
  1844.       (*jniEnv)->DeleteLocalRef (jniEnv, argTypes);
  1845.       SFREEBLOCK (name);
  1846.     }
  1847.   return sel;
  1848. }
  1849. jclass
  1850. swarm_directory_objc_find_class_java (Class class)
  1851. {
  1852.   if (swarmDirectory)
  1853.     {
  1854.       ObjectEntry *entry = swarm_directory_objc_find_class (class);
  1855.       
  1856.       if (!entry)
  1857.         {
  1858.           if (![class respondsTo: M(isJavaProxy)])
  1859.             {
  1860.               jclass lref, javaClass;
  1861.               
  1862.               lref = find_java_wrapper_class (class);
  1863.               javaClass = (jclass) SD_JAVA_ADD_CLASS_JAVA (lref, class);
  1864.               (*jniEnv)->DeleteLocalRef (jniEnv, lref);
  1865.               return javaClass;
  1866.             }
  1867.           else
  1868.             abort ();
  1869.         } 
  1870.       else
  1871.         return entry->foreignObject.java;
  1872.     }
  1873.   else
  1874.     return 0;
  1875. }
  1876. Class
  1877. swarm_directory_java_ensure_class (jclass javaClass)
  1878. {
  1879.   Class objcClass;
  1880.   if (!(objcClass = SD_JAVA_FIND_OBJECT_OBJC (javaClass)))
  1881.     {
  1882.       const char *className = java_get_class_name (javaClass);
  1883.       objcClass = objc_class_for_class_name (className);
  1884.       
  1885.       // if the corresponding class does not exist create new Java Proxy
  1886.       
  1887.       if (objcClass == nil)
  1888.         {
  1889.           objcClass = [JavaClassProxy create: globalZone];
  1890.           
  1891.           (void) SD_JAVA_ADD_CLASS_JAVA (javaClass, objcClass);
  1892.         }
  1893.       FREECLASSNAME (className);
  1894.     }
  1895.   return objcClass;
  1896. }
  1897. jobject
  1898. swarm_directory_objc_find_object_java (id object)
  1899. {
  1900.   ObjectEntry *entry = swarm_directory_objc_find_object (object);
  1901.   
  1902.   if (entry)
  1903.     {
  1904.       if (entry->type == foreign_java)
  1905.         return entry->foreignObject.java;
  1906.     }
  1907.   return NULL;
  1908. }
  1909. jobject
  1910. swarm_directory_objc_find_selector_java (SEL sel)
  1911. {
  1912.   SelectorEntry *entry = swarm_directory_objc_find_selector (sel);
  1913.   if (entry)
  1914.     {
  1915.       if (entry->type == foreign_java)
  1916.         return entry->foreignObject.java;
  1917.     }
  1918.   return NULL;
  1919. }
  1920. jobject
  1921. swarm_directory_objc_ensure_selector_java (jclass jClass, SEL sel)
  1922. {
  1923.   SelectorEntry *entry = swarm_directory_objc_find_selector (sel);
  1924.   if (entry && entry->type == foreign_java)
  1925.     return entry->foreignObject.java;
  1926.   else
  1927.     {
  1928.       jobject jSelName = (*jniEnv)->NewStringUTF (jniEnv, sel_get_name (sel));
  1929.       jobject jSel, ret;
  1930.       jSel =
  1931.         (*jniEnv)->NewObject (jniEnv, c_Selector, m_SelectorConstructor,
  1932.                               jClass,
  1933.                               jSelName, 
  1934.                               JNI_TRUE);
  1935.       if (jSel)
  1936.         {
  1937.           ret = SD_JAVA_ADD_SELECTOR (jSel, sel)->foreignObject.java;
  1938.           (*jniEnv)->DeleteLocalRef (jniEnv, jSelName);
  1939.           (*jniEnv)->DeleteLocalRef (jniEnv, jSel);
  1940.         }
  1941.       else
  1942.         {
  1943.           (*jniEnv)->ExceptionClear (jniEnv);
  1944.           ret = 0;
  1945.         }
  1946.       return ret;
  1947.     }
  1948. }
  1949. static void
  1950. add (ObjectEntry *entry)
  1951. {
  1952.   unsigned index;
  1953.   id <Map> m;
  1954.   id *javaTable = swarmDirectory->javaTable;
  1955.   
  1956.   index = swarm_directory_java_hash_code (entry->foreignObject.java);
  1957.   m = javaTable[index];
  1958.   
  1959.   if (m == nil)
  1960.     {
  1961.       m = createDirectoryEntryMap ();
  1962.       javaTable[index] = m;
  1963.     }
  1964.   [m at: entry insert: entry];
  1965. }
  1966. ObjectEntry *
  1967. swarm_directory_java_add_object (jobject lref, Object_s *object)
  1968. {
  1969.   jclass class = (*jniEnv)->GetObjectClass (jniEnv, lref);
  1970.   jobject javaObject = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1971.   ObjectEntry *entry;
  1972.   entry = JAVA_OBJECT_ENTRY (javaObject, object);
  1973.   if (classp (class, c_Base))
  1974.     (*jniEnv)->SetIntField (jniEnv, lref, f_objcPtrFid, (jint) object);
  1975.   else
  1976.     add (entry);
  1977.   (*jniEnv)->DeleteLocalRef (jniEnv, class);
  1978.   object->foreignEntry = entry;
  1979.   return entry;
  1980. }
  1981. ObjectEntry *
  1982. swarm_directory_java_add_class (jobject lref, Class oClass)
  1983. {
  1984.   ObjectEntry *entry;
  1985.   jclass jClass = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1986.   entry = JAVA_OBJECT_ENTRY (jClass, (id) oClass);
  1987.   add (entry);
  1988.   avl_probe (swarmDirectory->class_tree, entry);
  1989.   return entry;
  1990. }
  1991. SelectorEntry *
  1992. swarm_directory_java_add_selector (jobject lref, SEL sel)
  1993. {
  1994.   unsigned index;
  1995.   id <Map> m;
  1996.   SelectorEntry *entry;
  1997.   jobject javaObject = (*jniEnv)->NewGlobalRef (jniEnv, lref);
  1998.   id *javaTable = swarmDirectory->javaTable;
  1999.   
  2000.   entry = JAVA_SELECTOR_ENTRY (javaObject, sel);
  2001.   index = swarm_directory_java_hash_code (javaObject);
  2002.   m = javaTable[index];
  2003.   if (m == nil)
  2004.     {
  2005.       m = createDirectoryEntryMap ();
  2006.       javaTable[index] = m;
  2007.     }
  2008.   [m at: entry insert: entry];
  2009.   avl_probe (swarmDirectory->selector_tree, entry);
  2010.   return entry;
  2011. }
  2012. ObjectEntry *
  2013. swarm_directory_java_switch_objc (Object_s *object, jobject javaObject)
  2014. {
  2015.   jclass class = (*jniEnv)->GetObjectClass (jniEnv, javaObject);
  2016.   ObjectEntry *entry;
  2017.   if (classp (class, c_Base))
  2018.     {
  2019.       id prev = (id) (*jniEnv)->GetIntField (jniEnv, javaObject, f_objcPtrFid);
  2020.       (*jniEnv)->SetIntField (jniEnv, javaObject, f_objcPtrFid, (jint) object);
  2021.       
  2022.       entry = JAVA_OBJECT_ENTRY (javaObject, prev);
  2023.     }
  2024.   else
  2025.     {
  2026.       unsigned index;
  2027.       id <Map> m;
  2028.       id *javaTable = swarmDirectory->javaTable;
  2029.       
  2030.       index = swarm_directory_java_hash_code (javaObject);
  2031.       m = javaTable[index];
  2032.       entry = [javaTable[index] at: JAVA_FIND_OBJECT_ENTRY (javaObject)];
  2033.     }
  2034.   if (entry)
  2035.     {
  2036.       entry->object->foreignEntry = NULL;
  2037.       entry->object = object;
  2038.     }
  2039.   else
  2040.     SD_JAVA_ADD_STRING (javaObject, object);
  2041.   return entry;
  2042. }
  2043. Class
  2044. swarm_directory_java_find_class_named_objc (const char *className)
  2045. {
  2046.   jclass javaClass = java_find_class (className, NO);
  2047.   
  2048.   if (javaClass)
  2049.     {
  2050.       Class objcClass = swarm_directory_java_ensure_class (javaClass);
  2051.       (*jniEnv)->DeleteLocalRef (jniEnv, javaClass);
  2052.       return objcClass;
  2053.     }
  2054.   return Nil;
  2055. }
  2056. Class
  2057. swarm_directory_java_class_for_object_objc (jobject jobj)
  2058. {
  2059.   jclass jcls;
  2060.   const char *className;
  2061.   Class result;
  2062.   
  2063.   jcls = (*jniEnv)->GetObjectClass (jniEnv, jobj);
  2064.   className = java_class_name (jobj);
  2065.   result = objc_class_for_class_name (className);
  2066.   FREECLASSNAME (className);
  2067.   if (!result)
  2068.     if (!(result = SD_JAVA_FIND_OBJECT_OBJC (jcls)))
  2069.       result = SD_JAVA_ENSURE_CLASS_OBJC (jcls);
  2070.   (*jniEnv)->DeleteLocalRef (jniEnv, jcls);
  2071.   return result;
  2072. }
  2073. const char *
  2074. java_class_name (jobject obj)
  2075. {
  2076.   jclass class;
  2077.   const char *ret;
  2078.   if (!(class = (*jniEnv)->GetObjectClass (jniEnv, obj)))
  2079.     abort ();
  2080.   ret = java_get_class_name (class);
  2081.   (*jniEnv)->DeleteLocalRef (jniEnv, class);
  2082.   return ret;
  2083. }
  2084. const char *
  2085. java_copy_string (jstring javaString)
  2086. {
  2087.   if (javaString)
  2088.     {
  2089.       jboolean isCopy;
  2090.       const char *str =
  2091.         (*jniEnv)->GetStringUTFChars (jniEnv, javaString, &isCopy);
  2092.       const char *ret = SSTRDUP (str);
  2093.       
  2094.       if (isCopy)
  2095.         (*jniEnv)->ReleaseStringUTFChars (jniEnv, javaString, str);
  2096.       return ret;
  2097.     }
  2098.   return 0;
  2099. }
  2100. void
  2101. java_cleanup_strings (const char **stringArray, size_t count)
  2102. {
  2103.   size_t i;
  2104.   for (i = 0; i < count; i++)
  2105.     if (stringArray[i])
  2106.       SFREEBLOCK (stringArray[i]);
  2107. }
  2108. const char **
  2109. java_convert_string_array (jobjectArray ary)
  2110. {
  2111.   jsize size = (*jniEnv)->GetArrayLength (jniEnv, ary);
  2112.   jsize i;
  2113.   const char **ret = [scratchZone alloc: sizeof (const char *) * (size + 1)];
  2114.   
  2115.   for (i = 0; i < size; i++)
  2116.     {
  2117.       jstring string = (*jniEnv)->GetObjectArrayElement (jniEnv, ary, i);
  2118.       
  2119.       ret[i] = JAVA_COPY_STRING (string);
  2120.       (*jniEnv)->DeleteLocalRef (jniEnv, string);
  2121.     }
  2122.   ret[size] = NULL;
  2123.   return ret;
  2124. }
  2125. void
  2126. java_drop (jobject jobj)
  2127. {
  2128.   (*jniEnv)->DeleteGlobalRef (jniEnv, jobj);
  2129. }
  2130. #endif