@@ -154,6 +154,14 @@ STATIC const mp_obj_type_t jobject_type = {
154154// .locals_dict = (mp_obj_t)&jobject_locals_dict,
155155};
156156
157+ STATIC mp_obj_t new_jobject (jobject jo ) {
158+ mp_obj_jobject_t * o = m_new_obj (mp_obj_jobject_t );
159+ o -> base .type = & jobject_type ;
160+ o -> obj = jo ;
161+ return o ;
162+ }
163+
164+
157165// jmethod
158166
159167STATIC void jmethod_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
@@ -199,6 +207,34 @@ STATIC bool py2jvalue(const char **jtypesig, mp_obj_t arg, jvalue *out) {
199207 return true;
200208}
201209
210+ // jvalue is known to be union of jobject and friends. And yet from C's
211+ // perspective, it's aggregate object which may require passing via stack
212+ // instead of registers. Work that around by passing jobject and typecasting
213+ // it.
214+ #define MATCH (s , static ) (!strncmp(s, static, sizeof(static) - 1))
215+ STATIC mp_obj_t jvalue2py (const char * jtypesig , jobject arg ) {
216+ mp_obj_t ret ;
217+ if (MATCH (jtypesig , "void" )) {
218+ return mp_const_none ;
219+ } else if (MATCH (jtypesig , "int" )) {
220+ return mp_obj_new_int ((mp_int_t )arg );
221+ } else if (MATCH (jtypesig , "java.lang.String" )) {
222+ ret_string :;
223+ const char * s = JJ (GetStringUTFChars , arg , NULL );
224+ ret = mp_obj_new_str (s , strlen (s ), false);
225+ JJ (ReleaseStringUTFChars , arg , s );
226+ return ret ;
227+ } else if (MATCH (jtypesig , "java.lang.Object" )) {
228+ if (JJ (IsInstanceOf , arg , String_class )) {
229+ goto ret_string ;
230+ } else {
231+ return new_jobject (arg );
232+ }
233+ }
234+
235+ return MP_OBJ_NULL ;
236+ }
237+
202238STATIC mp_obj_t call_method (jobject obj , const char * name , jarray methods , bool is_constr , mp_uint_t n_args , const mp_obj_t * args ) {
203239 jvalue jargs [n_args ];
204240// printf("methods=%p\n", methods);
@@ -244,31 +280,11 @@ STATIC mp_obj_t call_method(jobject obj, const char *name, jarray methods, bool
244280 jobject res ;
245281 if (is_constr ) {
246282 res = JJ (NewObjectA , obj , method_id , jargs );
247- mp_obj_jobject_t * o ;
248- ret_object :
249- o = m_new_obj (mp_obj_jobject_t );
250- o -> base .type = & jobject_type ;
251- o -> obj = res ;
252- return o ;
283+ JJ (ReleaseStringUTFChars , name_o , decl );
284+ return new_jobject (res );
253285 } else {
254286 res = JJ (CallObjectMethodA , obj , method_id , jargs );
255- mp_obj_t ret = MP_OBJ_NULL ;
256- if (strncmp (ret_type , "void" , 4 ) == 0 ) {
257- ret = mp_const_none ;
258- } else if (strncmp (ret_type , "int" , sizeof ("int" ) - 1 ) == 0 ) {
259- ret = mp_obj_new_int ((mp_int_t )res );
260- } else if (strncmp (ret_type , "java.lang.String" , sizeof ("java.lang.String" ) - 1 ) == 0 ) {
261- ret_string :;
262- const char * s = JJ (GetStringUTFChars , res , NULL );
263- ret = mp_obj_new_str (s , strlen (s ), false);
264- JJ (ReleaseStringUTFChars , res , s );
265- } else if (strncmp (ret_type , "java.lang.Object" , sizeof ("java.lang.Object" ) - 1 ) == 0 ) {
266- if (JJ (IsInstanceOf , res , String_class )) {
267- goto ret_string ;
268- } else {
269- goto ret_object ;
270- }
271- }
287+ mp_obj_t ret = jvalue2py (ret_type , res );
272288 JJ (ReleaseStringUTFChars , name_o , decl );
273289 if (ret != MP_OBJ_NULL ) {
274290 return ret ;
0 commit comments