diff --git a/main/gbx/gb.jit.h b/main/gbx/gb.jit.h index e18c36523..212b6deec 100644 --- a/main/gbx/gb.jit.h +++ b/main/gbx/gb.jit.h @@ -113,6 +113,7 @@ typedef void (*add_string_global)(char **str, GB_STRING val); void (*value_class_write)(void *class, GB_VALUE *value, void *addr, JIT_CTYPE ctype); void (*subr_poke)(ushort code); + void *(*get_object_addr)(void *ob); } JIT_INTERFACE; diff --git a/main/gbx/gbx_api.c b/main/gbx/gbx_api.c index 4bc9153a1..9bcbf5561 100644 --- a/main/gbx/gbx_api.c +++ b/main/gbx/gbx_api.c @@ -391,6 +391,7 @@ const void *const GAMBAS_JitApi[] = (void *)JIT_add_string_global, (void *)VALUE_class_write, (void *)SUBR_poke, + (void *)OBJECT_get_addr, NULL }; diff --git a/main/gbx/gbx_extern.c b/main/gbx/gbx_extern.c index 812b929d1..ecf5317f3 100644 --- a/main/gbx/gbx_extern.c +++ b/main/gbx/gbx_extern.c @@ -331,32 +331,7 @@ void EXTERN_call(void) continue; __OBJECT: - { - void *ob = value->_object.object; - void *addr; - CLASS *class; - - if (!ob) - goto __NULL; - - class = OBJECT_class(ob); - - if (class == CLASS_Class && !CLASS_is_native((CLASS *)ob)) - addr = ((CLASS *)ob)->stat; - else if (CLASS_is_array(class)) - addr = ((CARRAY *)ob)->data; - else if (CLASS_is_struct(class)) - { - if (((CSTRUCT *)ob)->ref) - addr = (char *)((CSTATICSTRUCT *)ob)->addr; - else - addr = (char *)ob + sizeof(CSTRUCT); - } - else - addr = (char *)ob + sizeof(OBJECT); - - *((void **)tmp) = addr; - } + *((void **)tmp) = OBJECT_get_addr(value->_object.object); continue; __POINTER: diff --git a/main/gbx/gbx_object.c b/main/gbx/gbx_object.c index 06a618fa2..0ea48277e 100644 --- a/main/gbx/gbx_object.c +++ b/main/gbx/gbx_object.c @@ -520,3 +520,30 @@ int OBJECT_check_valid(void *object) { return *((char *)object + OBJECT_class(object)->special[SPEC_INVALID]); } + +void *OBJECT_get_addr(void *ob) +{ + CLASS *class; + void *addr; + + if (!ob) + return NULL; + + class = OBJECT_class(ob); + + if (class == CLASS_Class && !CLASS_is_native((CLASS *)ob)) + addr = ((CLASS *)ob)->stat; + else if (CLASS_is_array(class)) + addr = ((CARRAY *)ob)->data; + else if (CLASS_is_struct(class)) + { + if (((CSTRUCT *)ob)->ref) + addr = (char *)((CSTATICSTRUCT *)ob)->addr; + else + addr = (char *)ob + sizeof(CSTRUCT); + } + else + addr = (char *)ob + sizeof(OBJECT); + + return addr; +} diff --git a/main/gbx/gbx_object.h b/main/gbx/gbx_object.h index c44921ffc..f25f8e66b 100644 --- a/main/gbx/gbx_object.h +++ b/main/gbx/gbx_object.h @@ -89,6 +89,8 @@ OBJECT *OBJECT_active_parent(void *object); int OBJECT_check_valid(void *object); +void *OBJECT_get_addr(void *ob); + /* static INLINE CLASS *OBJECT_class(void *object) { diff --git a/main/lib/jit/gb.jit/jit.h b/main/lib/jit/gb.jit/jit.h index b5135802c..56d4be95e 100644 --- a/main/lib/jit/gb.jit/jit.h +++ b/main/lib/jit/gb.jit/jit.h @@ -326,8 +326,8 @@ enum #define GET_FUNCTION(_pc) ({ CALL_UNKNOWN(_pc); POP_u(); }) #define GET_STRING_ADDR(_val) ({ \ - GB_STRING *temp = &(_val); \ - temp->value.addr + temp->value.start; \ + GB_STRING temp = (_val); \ + temp.value.addr + temp.value.start; \ }) // TODO: automatic class diff --git a/main/lib/jit/jit_body.c b/main/lib/jit/jit_body.c index 7b8e6abb4..38e5509b0 100644 --- a/main/lib/jit/jit_body.c +++ b/main/lib/jit/jit_body.c @@ -2343,12 +2343,22 @@ static void push_call(ushort code) } else { + TYPE type; + char *expr; + STR_add(&call,"SP = sp;(*(%s (*)())%p)(", JIT_get_ctype(ext->type), JIT.get_extern(ext)); for (i = 0; i < ext->n_param; i++) { if (i) STR_add(&call, ","); - STR_add(&call, "%s", peek(i - narg, ext->param[i].type)); + type = ext->param[i].type; + expr = peek(i - narg, type); + if (type == T_STRING || type == T_CSTRING) + STR_add(&call, "GET_STRING_ADDR(%s)", expr); + else if (type >= T_OBJECT) + STR_add(&call, "JIT.get_object_addr((%s)._object.value)", expr); + else + STR_add(&call, "%s", expr); } STR_add(&call, ");");