diff --git a/main/gbx/gb.jit.h b/main/gbx/gb.jit.h index b69198f19..d61a45ad8 100644 --- a/main/gbx/gb.jit.h +++ b/main/gbx/gb.jit.h @@ -40,6 +40,14 @@ typedef typedef ushort JIT_PCODE; +typedef + struct { + unsigned char flag; + unsigned char id; + short value; + } + JIT_CTYPE; + typedef struct { void *next; @@ -96,6 +104,9 @@ typedef void *(*get_extern)(void *ext); const char *(*get_position)(void *cp, void *fp, ushort *pc); void (*release_many)(GB_VALUE *, int); + void *(*static_struct)(void *ref, GB_CLASS type, char *addr); + void *(*static_array)(void *cp, void *ref, GB_CLASS type, char *addr); + void *(*get_array_class)(void *cp, JIT_CTYPE ctype); } JIT_INTERFACE; diff --git a/main/gbx/gbx_api.c b/main/gbx/gbx_api.c index e117d2c2f..1ba8b43c5 100644 --- a/main/gbx/gbx_api.c +++ b/main/gbx/gbx_api.c @@ -373,6 +373,9 @@ const void *const GAMBAS_JitApi[] = (void *)EXTERN_get_addr, (void *)DEBUG_get_position, (void *)RELEASE_many, + (void *)CSTRUCT_create_static, + (void *)CARRAY_create_static, + (void *)CARRAY_get_array_class, NULL }; diff --git a/main/lib/jit/gb.jit/jit.h b/main/lib/jit/gb.jit/jit.h index d923bc7d3..0a9dfb042 100644 --- a/main/lib/jit/gb.jit/jit.h +++ b/main/lib/jit/gb.jit/jit.h @@ -164,7 +164,7 @@ typedef #define PUSH_b(_val) ({ char _v = -(_val); sp->_boolean.value = _v; sp->type = GB_T_BOOLEAN; sp++; }) #define PUSH_c(_val) ({ uchar _v = (_val); sp->_integer.value = _v; sp->type = GB_T_BYTE; sp++; }) #define PUSH_h(_val) ({ short _v = (_val); sp->_integer.value = _v; sp->type = GB_T_SHORT; sp++; }) -#define PUSH_i(_val) ({ int _v = (_val); sp->_integer.value = _v; sp->type = GB_T_INTEGER; sp++; }) +#define PUSH_i(_val) ({ sp->_integer.value = (_val); sp->type = GB_T_INTEGER; sp++; }) #define PUSH_l(_val) ({ int64_t _v = (_val); sp->_long.value = _v; sp->type = GB_T_LONG; sp++; }) #define PUSH_g(_val) ({ float _v = (_val); sp->_single.value = _v; sp->type = GB_T_SINGLE; sp++; }) #define PUSH_f(_val) ({ double _v = (_val); sp->_float.value = _v; sp->type = GB_T_FLOAT; sp++; }) @@ -308,6 +308,14 @@ enum #define GET_s(_addr) GET_STRING((*(char **)(_addr)), 0, GB.StringLength(temp.value.addr)) #define GET_o(_addr, _type) GET_OBJECT((*(char **)(_addr)), _type) #define GET_v(_addr) GET_VARIANT((*(GB_VARIANT_VALUE *)(_addr))) +#define GET_S(_ref, _addr, _type) GET_OBJECT(JIT.static_struct((_ref), (_type), (_addr)), _type) + +#define GET_A(_class, _ref, _addr, _type, _desc) ({ \ + SP = sp; \ + GB.Unref(&ra); \ + ra = JIT.static_array((_class), (_ref), (void *)(_desc), (_addr)); \ + GET_OBJECT(ra, _type); \ +}) #define SET_b(_addr, _val) (GET_b(_addr) = (_val)) #define SET_c(_addr, _val) (GET_c(_addr) = (_val)) diff --git a/main/lib/jit/jit.c b/main/lib/jit/jit.c index c04535813..daf76d564 100644 --- a/main/lib/jit/jit.c +++ b/main/lib/jit/jit.c @@ -104,8 +104,10 @@ TYPE JIT_ctype_to_type(CTYPE ctype) if (ctype.id == T_OBJECT && ctype.value >= 0) return (TYPE)(JIT_class->load->class_ref[ctype.value]); else if (ctype.id == TC_ARRAY) - JIT_panic("Static array not implemented"); - //return (TYPE)CARRAY_get_array_class(class, class->load->array[ctype.value]->ctype); + { + CLASS_ARRAY *desc = JIT_class->load->array[ctype.value]; + return (TYPE)JIT.get_array_class(JIT_class, *(JIT_CTYPE *)&desc->ctype); + } else if (ctype.id == TC_STRUCT) return (TYPE)(JIT_class->load->class_ref[ctype.value]); else diff --git a/main/lib/jit/jit_body.c b/main/lib/jit/jit_body.c index 5c1663161..b87e836bd 100644 --- a/main/lib/jit/jit_body.c +++ b/main/lib/jit/jit_body.c @@ -83,6 +83,7 @@ static bool _decl_rs; static bool _decl_ro; static bool _decl_rv; static bool _decl_tp; +static bool _decl_ra; static ushort _pc; @@ -117,6 +118,8 @@ static void enter_function(FUNCTION *func, int index) _decl_ro = FALSE; _decl_rv = FALSE; _decl_tp = FALSE; + _decl_ra = FALSE; + _has_gosub = FALSE; _loop_count = 0; _has_just_dup = FALSE; @@ -207,6 +210,9 @@ static bool leave_function(FUNCTION *func, int index) for (i = 0; i < GB.Count(_dup_type); i++) RELEASE_FAST(" RELEASE_FAST_%s(d%d);\n", _dup_type[i], i); + if (_decl_ra) + JIT_print(" GB.Unref(&ra);\n"); + if (!_has_catch && !_has_finally) JIT_print(" if (error) GB.Propagate();\n"); @@ -742,7 +748,8 @@ static int add_ctrl(int index, TYPE type, const char *expr) else info->expr = NULL; - _ctrl_index[index] = index_ctrl; + if (index >= 0) + _ctrl_index[index] = index_ctrl; //JIT_print_decl(" %s c%d;\n", JIT_get_ctype(type), index_ctrl); JIT_declare(type, "c%d", index_ctrl); @@ -2528,6 +2535,7 @@ bool JIT_translate_body(FUNCTION *func, int ind) CLASS *class = JIT_class; TYPE type; + CTYPE ctype; uint p = 0; ushort code; int index; @@ -2657,18 +2665,31 @@ _PUSH_INTEGER: _PUSH_STATIC: index = GET_7XX(); - type = JIT_ctype_to_type(class->load->stat[index].type); + ctype = class->load->stat[index].type; + type = JIT_ctype_to_type(ctype); addr = &class->stat[class->load->stat[index].pos]; - if (TYPE_is_object(type)) + switch(ctype.id) { - if (TYPE_is_pure_object(type)) - push(type, "GET_o(%p, CLASS(%p))", addr, (CLASS *)type); - else - push(type, "GET_o(%p, GB_T_OBJECT)", addr); + case TC_STRUCT: + push(type, "GET_S(CP, %p, CLASS(%p))", addr, (CLASS *)type); + break; + + case TC_ARRAY: + declare(&_decl_ra, "void *ra = NULL"); + push(type, "GET_A(CP, CP, %p, CLASS(%p), %p)", addr, (CLASS *)type, JIT_class->load->array[ctype.value]); + break; + + case T_OBJECT: + if (TYPE_is_pure_object(type)) + push(type, "GET_o(%p, CLASS(%p))", addr, (CLASS *)type); + else + push(type, "GET_o(%p, GB_T_OBJECT)", addr); + break; + + default: + push(type, "GET_%s(%p)", JIT_get_type(type), addr); } - else - push(type, "GET_%s(%p)", JIT_get_type(type), addr); goto _MAIN; @@ -2688,19 +2709,31 @@ _POP_STATIC: _PUSH_DYNAMIC: index = GET_7XX(); - type = JIT_ctype_to_type(class->load->dyn[index].type); pos = class->load->dyn[index].pos; - - if (TYPE_is_object(type)) - { - if (TYPE_is_pure_object(type)) - push(type, "GET_o(&OP[%d], CLASS(%p))", pos, (CLASS *)type); - else - push(type, "GET_o(&OP[%d], GB_T_OBJECT)", pos); - } - else - push(type, "GET_%s(&OP[%d])", JIT_get_type(type), pos); + ctype = class->load->dyn[index].type; + type = JIT_ctype_to_type(ctype); + switch(ctype.id) + { + case TC_STRUCT: + push(type, "GET_S(OP, &OP[%d], CLASS(%p))", pos, (CLASS *)type); + break; + + case TC_ARRAY: + push(type, "GET_A(CP, OP, &OP[%d], CLASS(%p), %p)", pos, (CLASS *)type, JIT_class->load->array[ctype.value]); + break; + + case T_OBJECT: + if (TYPE_is_pure_object(type)) + push(type, "GET_o(&OP[%d], CLASS(%p))", pos, (CLASS *)type); + else + push(type, "GET_o(&OP[%d], GB_T_OBJECT)", pos); + break; + + default: + push(type, "GET_%s(&OP[%d])", JIT_get_type(type), pos); + } + goto _MAIN; _POP_DYNAMIC: