From: fennecdjay Date: Wed, 25 Sep 2019 16:40:42 +0000 (+0200) Subject: :art: Use defined Gack X-Git-Tag: nightly~2199^2~17 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=447dbd26d540b10b5afbd5f743a2c78636163da1;p=gwion.git :art: Use defined Gack --- diff --git a/ast b/ast index 37f69271..bf16ee54 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 37f69271d28e0e167e888b1e341b0000ff768641 +Subproject commit bf16ee540da76d94a7d633a1419014a8b597efa1 diff --git a/include/gack.h b/include/gack.h index bafbba27..d8a72e88 100644 --- a/include/gack.h +++ b/include/gack.h @@ -1,4 +1,4 @@ #ifndef __GACK #define __GACK -ANN void gack(const Gwion, const m_bit*, const Instr); +ANN void gack(const VM_Shred, const Instr); #endif diff --git a/include/import.h b/include/import.h index d3bc83e9..d1d5285a 100644 --- a/include/import.h +++ b/include/import.h @@ -2,9 +2,10 @@ #define __IMPORT #define DLARG_MAX 6 -typedef void (*f_xtor)(const M_Object o, const m_bit*, const VM_Shred); -typedef void (*f_mfun)(const M_Object o, const m_bit* RETURN, const VM_Shred sh); -typedef void (*f_sfun)(const m_bit*, const m_bit* RETURN, const VM_Shred sh); +typedef void (*f_xtor)(const M_Object, const m_bit*, const VM_Shred); +typedef void (*f_mfun)(const M_Object, const m_bit*, const VM_Shred); +typedef void (*f_sfun)(const m_bit*, const m_bit*, const VM_Shred); +typedef void (*f_gack)(const Type, const m_bit*, const VM_Shred); typedef void (*f_xfun)(); typedef struct Gwi_* Gwi; @@ -12,6 +13,7 @@ typedef struct Gwi_* Gwi; #define SFUN(a) ANN void a(const M_Object o NUSED, const m_bit* RETURN NUSED, const VM_Shred shred NUSED) #define CTOR(a) ANN void a(const M_Object o NUSED, const m_bit* _ NUSED, const VM_Shred shred NUSED) #define DTOR(a) ANN void a(const M_Object o NUSED, const m_bit* _ NUSED, const VM_Shred shred NUSED) +#define GACK(a) ANN2(2) void a(const Type t NUSED, const m_bit* VALUE NUSED, const VM_Shred shred NUSED) #define OP_CHECK(a) ANN Type a(const Env env NUSED, void* data NUSED, m_bool* mut NUSED) #define OP_EMIT(a) ANN Instr a(const Emitter emit NUSED, void* data NUSED) #ifdef GWION_BUILTIN @@ -34,6 +36,7 @@ ANN VM* gwi_vm(const Gwi); ANN2(1,2) ANEW Type gwi_mk_type(const Gwi, const m_str, const m_uint, const Type); ANN m_int gwi_add_type(const Gwi gwi, Type type); ANN m_int gwi_set_global_type(const Gwi gwi, const Type type, const type_enum te); +ANN m_bool gwi_gack(const Gwi gwi, const Type type, const f_gack d); ANN2(1,2)m_int gwi_class_ini(const Gwi gwi, const Type type, const f_xtor pre_ctor, const f_xtor dtor); ANN m_int gwi_class_ext(const Gwi gwi, Type_Decl* td); ANN m_int gwi_class_end(const Gwi gwi); diff --git a/include/opcode.h b/include/opcode.h index 49fd830a..bda88115 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -171,6 +171,7 @@ enum { eGcAdd, eGcEnd, eGack, + eGack3, eDotTmplVal, eOP_MAX, eEOC, @@ -346,6 +347,7 @@ enum { #define GcAdd (f_instr)eGcAdd #define GcEnd (f_instr)eGcEnd #define Gack (f_instr)eGack +#define Gack3 (f_instr)eGack3 #define DotTmplVal (f_instr)eDotTmplVal #define OP_MAX (f_instr)eOP_MAX #define EOC (f_instr)eEOC diff --git a/include/type.h b/include/type.h index eb989a43..0b67d08a 100644 --- a/include/type.h +++ b/include/type.h @@ -11,6 +11,7 @@ struct TypeInfo_ { } d; struct Vector_ contains; struct TupleForm_* tuple; + struct VM_Code_ *gack; }; struct Type_ { diff --git a/opcode.txt b/opcode.txt index eb027efe..be86352c 100644 --- a/opcode.txt +++ b/opcode.txt @@ -168,6 +168,7 @@ GcIni GcAdd GcEnd Gack +Gack3 DotTmplVal OP_MAX EOC diff --git a/src/emit/emit.c b/src/emit/emit.c index 1f38acfa..f1940cd4 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -560,17 +560,17 @@ ANN static m_bool prim_str(const Emitter emit, const Exp_Primary* prim) { ANN static m_bool prim_gack(const Emitter emit, const Exp_Primary* primary) { const Exp exp = primary->d.exp; - CHECK_BB(emit_exp(emit, exp, 0)) - const Vector v = new_vector(emit->gwion->mp); - m_uint offset = 0; - Exp e = exp; + Exp e = exp, next = NULL; do { - vector_add(v, (vtype)e->type); - offset += e->type->size; - } while((e = e->next)); - const Instr instr = emit_add_instr(emit, Gack); - instr->m_val = offset; - instr->m_val2 = (m_uint)v; + next = e->next; + e->next = NULL; + CHECK_BB(emit_exp(emit, e, 0)) + const Instr instr = emit_add_instr(emit, Gack); + instr->m_val = (m_uint)e->type; + instr->m_val2 = emit_code_offset(emit); + } while((e = e->next = next)); + if(!(emit->env->func && emit->env->func->def->base->xid == insert_symbol("@gack"))) + emit_add_instr(emit, Gack3); return GW_OK; } @@ -1747,6 +1747,9 @@ ANN static void emit_func_def_code(const Emitter emit, const Func func) { if(GET_FLAG(func->def, dtor)) { emit->env->class_def->nspc->dtor = func->code; ADD_REF(func->code) + } else if(func->def->base->xid == insert_symbol("@gack")) { + emit->env->class_def->e->gack = func->code; + ADD_REF(func->code) } } diff --git a/src/lib/engine.c b/src/lib/engine.c index 42a45fc1..128d2c39 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -20,10 +20,47 @@ #include "lang_private.h" #include "specialid.h" -static FREEARG(freearg_gack) { - free_vector(((Gwion)gwion)->mp, (Vector)instr->m_val2); +static GACK(gack_class) { + printf("class(%p)", (*(Type*)VALUE)->e->d.base_type); } +static GACK(gack_function) { + printf("%s", t->name); +} + +static GACK(gack_fptr) { + const VM_Code code = *(VM_Code*)VALUE; + if(code) + printf("%s", code ? code->name : NULL); + else + printf("%s", t->name); +} + +static GACK(gack_void) { + printf("(void)"); +} + +static GACK(gack_int) { + printf("%li", *(m_uint*)VALUE); +} + +static GACK(gack_float) { + printf("%.4f", *(m_float*)VALUE); +} + +// we where using m_complex +static GACK(gack_complex) { + printf("#(%.4f, %.4f)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT)); +} +static GACK(gack_polar) { + printf("%%(%.4f, %.4f*pi)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT) / M_PI); +} +static GACK(gack_vec3) { + printf("%%(%.4f, %.4f, %.4f)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT), *(m_float*)(VALUE + SZ_FLOAT*2)); +} +static GACK(gack_vec4) { + printf("%%(%.4f, %.4f, %.4f, %.4f)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT), *(m_float*)(VALUE + SZ_FLOAT*2), *(m_float*)(VALUE + SZ_FLOAT*3)); +} #define mk_class_instr(op, arg0, arg1, ...) \ static INSTR(instr_class_##op) { \ @@ -38,33 +75,42 @@ mk_class_instr(le, r, l) mk_class_instr(lt, r, l, && l != r) ANN static m_bool import_core_libs(const Gwi gwi) { - const Type t_class = gwi_mk_type(gwi, "Class", SZ_INT, NULL); + const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL); gwi->gwion->type[et_class] = t_class; GWI_BB(gwi_add_type(gwi, t_class)) + CHECK_BB(gwi_gack(gwi, gwi->gwion->type[et_class], gack_class)) // not working yet + gwi->gwion->type[et_class] = t_class; const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL); GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined)) const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL); GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto)) SET_FLAG(t_class, abstract); const Type t_void = gwi_mk_type(gwi, "void", 0, NULL); + CHECK_BB(gwi_gack(gwi, t_void, gack_void)) GWI_BB(gwi_set_global_type(gwi, t_void, et_void)) const Type t_null = gwi_mk_type(gwi, "@null", SZ_INT, NULL); GWI_BB(gwi_set_global_type(gwi, t_null, et_null)) const Type t_function = gwi_mk_type(gwi, "@function", SZ_INT, NULL); + GWI_BB(gwi_gack(gwi, t_function, gack_function)) GWI_BB(gwi_set_global_type(gwi, t_function, et_function)) const Type t_fptr = gwi_mk_type(gwi, "@func_ptr", SZ_INT, t_function); + GWI_BB(gwi_gack(gwi, t_fptr, gack_fptr)) GWI_BB(gwi_set_global_type(gwi, t_fptr, et_fptr)) const Type t_lambda = gwi_mk_type(gwi, "@lambda", SZ_INT, t_function); GWI_BB(gwi_set_global_type(gwi, t_lambda, et_lambda)) const Type t_gack = gwi_mk_type(gwi, "@Gack", SZ_INT, NULL); GWI_BB(gwi_set_global_type(gwi, t_gack, et_gack)) const Type t_int = gwi_mk_type(gwi, "int", SZ_INT, NULL); + CHECK_BB(gwi_gack(gwi, t_int, gack_int)) GWI_BB(gwi_set_global_type(gwi, t_int, et_int)) const Type t_float = gwi_mk_type(gwi, "float", SZ_FLOAT, NULL); + CHECK_BB(gwi_gack(gwi, t_float, gack_float)) GWI_BB(gwi_set_global_type(gwi, t_float, et_float)) const Type t_dur = gwi_mk_type(gwi, "dur", SZ_FLOAT, NULL); + CHECK_BB(gwi_gack(gwi, t_dur, gack_float)) GWI_BB(gwi_add_type(gwi, t_dur)) const Type t_time = gwi_mk_type(gwi, "time", SZ_FLOAT, NULL); + CHECK_BB(gwi_gack(gwi, t_time, gack_float)) GWI_BB(gwi_add_type(gwi, t_time)) const Type t_now = gwi_mk_type(gwi, "@now", SZ_FLOAT, t_time); GWI_BB(gwi_add_type(gwi, t_now)) @@ -73,12 +119,16 @@ ANN static m_bool import_core_libs(const Gwi gwi) { gwi_reserve(gwi, "now"); const Type t_complex = gwi_mk_type(gwi, "complex", SZ_COMPLEX , NULL); gwi->gwion->type[et_complex] = t_complex; + CHECK_BB(gwi_gack(gwi, t_complex, gack_complex)) const Type t_polar = gwi_mk_type(gwi, "polar", SZ_COMPLEX , NULL); gwi->gwion->type[et_polar] = t_polar; + CHECK_BB(gwi_gack(gwi, t_polar, gack_polar)) const Type t_vec3 = gwi_mk_type(gwi, "Vec3", SZ_VEC3, NULL); gwi->gwion->type[et_vec3] = t_vec3; + CHECK_BB(gwi_gack(gwi, t_vec3, gack_vec3)) const Type t_vec4 = gwi_mk_type(gwi, "Vec4", SZ_VEC4, NULL); gwi->gwion->type[et_vec4] = t_vec4; + CHECK_BB(gwi_gack(gwi, t_vec4, gack_vec4)) GWI_BB(import_object(gwi)) const Type t_union = gwi_mk_type(gwi, "@Union", SZ_INT, gwi->gwion->type[et_object]); gwi->gwion->type[et_union] = t_union; @@ -110,17 +160,13 @@ ANN static m_bool import_core_libs(const Gwi gwi) { GWI_BB(gwi_oper_end(gwi, ">", instr_class_gt)) GWI_BB(gwi_oper_end(gwi, "<=", instr_class_le)) GWI_BB(gwi_oper_end(gwi, "<", instr_class_lt)) - - register_freearg(gwi, Gack, freearg_gack); return GW_OK; } ANN m_bool type_engine_init(VM* vm, const Vector plug_dirs) { vm->gwion->env->name = "[builtin]"; - struct Gwi_ gwi; - memset(&gwi, 0, sizeof(struct Gwi_)); - gwi.gwion = vm->gwion; - gwi.loc = new_loc(vm->gwion->mp, 0); + struct YYLTYPE loc = {}; + struct Gwi_ gwi = { .gwion=vm->gwion, .loc=&loc }; GWI_BB(import_core_libs(&gwi)) vm->gwion->env->name = "[imported]"; for(m_uint i = 0; i < vector_size(plug_dirs); ++i) { @@ -128,6 +174,5 @@ ANN m_bool type_engine_init(VM* vm, const Vector plug_dirs) { if(import && import(&gwi) < 0) env_reset(gwi.gwion->env); } - free_loc(vm->gwion->mp, gwi.loc); return GW_OK; } diff --git a/src/lib/gack.c b/src/lib/gack.c index 55c1fbf0..4d07a03c 100644 --- a/src/lib/gack.c +++ b/src/lib/gack.c @@ -11,122 +11,28 @@ #include "object.h" #include "instr.h" #include "gwion.h" +#include "operator.h" +#include "import.h" #include "gack.h" -static void print_type(const Gwion gwion, const Type type) { - const m_bool is_func = isa(type, gwion->type[et_function]) > 0 && !is_fptr(gwion, type); - gw_out("(%s) ", is_func ? "@function" : type->name); - if(GET_FLAG(type, typedef)) { - gw_out(" aka "); - print_type(gwion, type->e->parent); - } -} - -static inline void print_bool(const m_int i) { - gw_out("%s", i ? "true" : "false"); -} - -static inline void print_int(const m_int i) { - gw_out("%" INT_F "", i); -} - -static inline void print_float(const m_float f) { - gw_out("%.4f", f); -} - -static inline void print_complex(const m_complex c) { - gw_out("#("); - print_float(creal(c)); - gw_out(", "); - print_float(cimag(c)); - gw_out(")"); -} - -static inline void print_polar(const m_complex c) { - gw_out("%%("); - print_float(creal(c)); - gw_out(", "); - print_float((m_float)cimag(c) / (m_float)M_PI); - gw_out("*pi)"); -} - -ANN static inline void print_vec(const m_bit* f, const m_uint size) { - gw_out("@("); - for(m_uint i = 0; i < size; i++) { - print_float(*(m_float*)(f + i * SZ_FLOAT)); - if(i < size - 1) - gw_out(", "); - } - gw_out(")"); -} - -static inline void print_string1(const m_str str) { - gw_out("%s", str); -} - -static inline void print_string(const M_Object obj) { - print_string1(obj ? STRING(obj) : "(null string)"); -} - -ANN2(1) static inline void print_object(const Gwion gwion, const Type type, const M_Object obj) { - if(isa(type, gwion->type[et_string]) > 0) - print_string(obj); - else - gw_out("%p", (void*)obj); -} - -ANN static inline void print_func(const Gwion gwion,const Type type, const m_bit* stack) { - if(is_fptr(gwion, type) > 0 && type->e->d.func->def->base->tmpl) { - const Func f = *(Func*)stack; - gw_out("%s", f ? f->name : "(nil)"); - return; - } - if(type->e->d.func) { - const VM_Code code = is_fptr(gwion, type) ? - *(VM_Code*)stack : type->e->d.func->code; - gw_out("%s %s %p", type->name, (void*)code ? code->name : NULL, code); - } else // uncalled lambda - gw_out("%p", NULL); -} - -ANN static void print_prim(const Gwion gwion, const Type type, const m_bit* stack) { - if(isa(type, gwion->type[et_bool]) > 0) - print_bool(*(m_int*)stack); - else if(isa(type, gwion->type[et_int]) > 0) - print_int(*(m_int*)stack); - else if(isa(type, gwion->type[et_complex]) > 0) - print_complex(*(m_complex*)stack); - else if(isa(type, gwion->type[et_polar]) > 0) - print_polar(*(m_complex*)stack); - else if(isa(type, gwion->type[et_vec3]) > 0) - print_vec(stack, 3); - else if(isa(type, gwion->type[et_vec4]) > 0) - print_vec(stack, 4); - else - print_float(*(m_float*)stack); -} - -ANN void gack(const Gwion gwion, const m_bit* reg, const Instr instr) { - m_uint offset = instr->m_val; - const Vector v = (Vector)instr->m_val2; - const m_uint size = vector_size(v); - for(m_uint i = size + 1; --i;) { - const Type type = (Type)vector_at(v, size - i); - if(size == 1) - print_type(gwion, type); - if(isa(type, gwion->type[et_object]) > 0) - print_object(gwion, type, *(M_Object*)(reg-offset)); - else if(isa(type, gwion->type[et_function]) > 0) - print_func(gwion, type, (reg-offset)); - else if(type == gwion->type[et_class]) - print_type(gwion, type); - else if(isa(type, gwion->type[et_class]) > 0) - print_type(gwion, type->e->d.base_type); - else if(isa(type, gwion->type[et_void]) > 0) - print_string1("void"); - else - print_prim(gwion, type, (reg-offset)); - offset -= type->size; - } - gw_out("\n"); +ANN void gack(const VM_Shred shred, const Instr instr) { + Type t = (Type)instr->m_val; + do { + if(t->e->gack) { + if(GET_FLAG(t->e->gack, builtin)) + ((f_gack)t->e->gack->native_func)(t, (shred->reg - t->size), shred); + else { + shred->mem += instr->m_val2; + *(m_uint*)(shred->mem+ SZ_INT) = instr->m_val2 + SZ_INT; + *(VM_Code*)(shred->mem+ SZ_INT*2) = shred->code; + *(m_uint*)(shred->mem+ SZ_INT*3) = shred->pc; + *(m_uint*)(shred->mem+ SZ_INT*4) = SZ_INT; + shred->mem += SZ_INT*5; + *(M_Object*)(shred->mem)= *(M_Object*)(shred->reg - SZ_INT); + shred->code = t->e->gack; + shred->pc = 0; + } + return; + } + } while((t = t->e->parent)); } diff --git a/src/lib/import.c b/src/lib/import.c index 25b19b63..37601216 100644 --- a/src/lib/import.c +++ b/src/lib/import.c @@ -176,6 +176,17 @@ ANN /* static */ ID_List str2list(const Env env, const m_str path, m_uint* array return list; } +ANN static m_bool mk_gack(MemPool p, const Type type, const f_gack d) { + const VM_Code code = new_vm_code(p, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@gack"); + code->native_func = (m_uint)d; + type->e->gack = code; + return GW_OK; +} + +ANN m_bool gwi_gack(const Gwi gwi, const Type type, const f_gack d) { + return mk_gack(gwi->gwion->mp, type, d); +} + ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const ae_flag e) { VM_Code* code = e == ae_flag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor; const m_str name = type->name; diff --git a/src/lib/object.c b/src/lib/object.c index d916859c..daf0aad0 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -221,8 +221,13 @@ static ID_CHECK(check_this) { return env->class_def; } +static GACK(gack_object) { + printf("%p", *(M_Object*)VALUE); +} + GWION_IMPORT(object) { const Type t_object = gwi_mk_type(gwi, "Object", SZ_INT, NULL); + GWI_BB(gwi_gack(gwi, t_object, gack_object)) gwi->gwion->type[et_object] = t_object; GWI_BB(gwi_class_ini(gwi, t_object, NULL, NULL)) GWI_BB(gwi_class_end(gwi)) diff --git a/src/lib/prim.c b/src/lib/prim.c index 3cd9745f..d7dbf2a6 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -71,12 +71,16 @@ static GWION_IMPORT(int_unary) { GWI_BB(gwi_oper_end(gwi, "--", int_post_dec)) return GW_OK; } +static GACK(gack_bool) { + printf("%s", *(m_uint*)VALUE ? "true" : "false"); +} static GWION_IMPORT(int_values) { GWI_BB(gwi_enum_ini(gwi, "bool")) GWI_BB(gwi_enum_add(gwi, "false", 0)) GWI_BB(gwi_enum_add(gwi, "true", 1)) const Type t_bool = gwi_enum_end(gwi); + GWI_BB(gwi_gack(gwi, t_bool, gack_bool)) gwi->gwion->type[et_bool] = t_bool; GWI_BB(gwi_oper_ini(gwi, NULL, "int", "bool")) GWI_BB(gwi_oper_end(gwi, "!", IntNot)) diff --git a/src/lib/string.c b/src/lib/string.c index 2ba94e2d..cb6aeb93 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -181,8 +181,13 @@ ID_CHECK(check_funcpp) { return prim_str(env, (Exp_Primary * const)prim); } +static GACK(gack_string) { + const M_Object obj = *(M_Object*)VALUE; + printf("%s", obj ? STRING(obj) : "(null string)"); +} GWION_IMPORT(string) { const Type t_string = gwi_mk_type(gwi, "string", SZ_INT, gwi->gwion->type[et_object]); + GWI_BB(gwi_gack(gwi, t_string, gack_string)) GWI_BB(gwi_class_ini(gwi, t_string, string_ctor, NULL)) gwi->gwion->type[et_string] = t_string; gwi_item_ini(gwi, "int", "@data"); diff --git a/src/lib/tuple.c b/src/lib/tuple.c index 403ba60f..c1df7b3e 100644 --- a/src/lib/tuple.c +++ b/src/lib/tuple.c @@ -94,6 +94,7 @@ ANN static void unpack_instr_decl(const Emitter emit, struct TupleEmit *te) { te->sz += value->type->size; sz += value->type->size; value->offset = emit_local(emit, value->type->size, 0); +printf("value->offset %lu\n", value->offset); } else { sz += ((Type)vector_at(te->v, te->idx))->size; break; @@ -202,7 +203,7 @@ static OP_EMIT(opem_at_tuple) { const Exp_Binary *bin = (Exp_Binary*)data; if(!(bin->rhs->exp_type == ae_exp_primary && bin->rhs->d.exp_primary.primary_type == ae_primary_unpack)) { - return emit_add_instr(emit, ObjectAssign); + return emit_add_instr(emit, ObjectAssign); } const Exp e = bin->rhs->d.exp_primary.d.tuple.exp; const Vector v = &bin->lhs->type->e->tuple->types; diff --git a/src/oo/type.c b/src/oo/type.c index 0038bcb9..d2274bea 100644 --- a/src/oo/type.c +++ b/src/oo/type.c @@ -60,6 +60,7 @@ ANN Type type_copy(MemPool p, const Type type) { a->e->d.base_type = type->e->d.base_type; a->array_depth = type->array_depth; a->e->def = type->e->def; + a->e->gack = type->e->gack; return a; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index c03be21f..3c11b152 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -357,8 +357,8 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { CHECK_BB(env_storage(env, fdef->flag, td_pos(fdef->base->td))) if(tmpl_base(fdef->base->tmpl)) return GW_OK; - if(GET_FLAG(fdef, dtor) && !env->class_def) - ERR_B(td_pos(fdef->base->td), _("dtor must be in class def!!")) + if(!env->class_def && (GET_FLAG(fdef, dtor) || fdef->base->xid == insert_symbol("@gack"))) + ERR_B(td_pos(fdef->base->td), _("'%s' must be in class def!!"), s_name(fdef->base->xid)) if(GET_FLAG(fdef, op) && env->class_def) SET_FLAG(fdef, static); struct Func_ fake = { .name=s_name(fdef->base->xid) }, *const former = env->func; diff --git a/src/vm/vm.c b/src/vm/vm.c index 1f05477e..4da59501 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -259,6 +259,8 @@ _Pragma(STRINGIFY(COMPILER diagnostic ignored UNINITIALIZED) else ADVANCE(); \ IDISPATCH(); +#define VM_OUT shred->code = code; shred->reg = reg; shred->mem = mem; shred->pc = PC; + __attribute__ ((hot, optimize("-O2"))) ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] static const void* dispatch[] = { @@ -308,7 +310,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] &&staticint, &&staticfloat, &&staticother, &&dotfunc, &&dotstaticfunc, &&pushstaticcode, &&pushstr, &&gcini, &&gcadd, &&gcend, - &&gack, &®pushimm, &&other, &&eoc + &&gack, &&gack3, &®pushimm, &&other, &&eoc }; const Shreduler s = vm->shreduler; register VM_Shred shred; @@ -567,10 +569,7 @@ timeadv: reg -= SZ_FLOAT; shredule(s, shred, *(m_float*)(reg-SZ_FLOAT)); *(m_float*)(reg-SZ_FLOAT) += vm->bbq->pos; - shred->code = code; - shred->reg = reg; - shred->mem = mem; - shred->pc = PC; + VM_OUT break; setcode: a.code = *(VM_Code*)(reg-SZ_INT); @@ -623,10 +622,7 @@ funcusrend: byte = bytecode = (code = a.code)->bytecode; SDISPATCH(); funcmemberend: - shred->mem = mem; - shred->reg = reg; - shred->pc = PC; - shred->code = code; + VM_OUT { register const m_uint val = VAL; register const m_uint val2 = VAL2; @@ -702,11 +698,9 @@ arrayaccess: if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) { gw_err(_(" ... at index [%" INT_F "]\n"), idx); gw_err(_(" ... at dimension [%" INT_F "]\n"), VAL); - shred->code = code; - shred->mem = mem; - shred->pc = PC; + VM_OUT exception(shred, "ArrayOutofBounds"); - continue; + continue; // or break ? } DISPATCH() } @@ -729,7 +723,7 @@ addref: ++a.obj->ref; DISPATCH() objassign: -{ +{ // use a.obj ? register const M_Object tgt = **(M_Object**)(reg -SZ_INT); if(tgt) { --tgt->ref; @@ -821,22 +815,24 @@ gcend: _release(a.obj, shred); DISPATCH() gack: - gack(vm->gwion, reg, (Instr)VAL); - DISPATCH() + VM_OUT + gack(shred, (Instr)VAL); + goto in; +gack3: + gw_out("\n"); + DISPATCH(); other: -shred->code = code; -shred->reg = reg; -shred->mem = mem; -shred->pc = PC; - ((f_instr)VAL2)(shred, (Instr)VAL); -if(!s->curr)break; + VM_OUT + ((f_instr)VAL2)(shred, (Instr)VAL); +in: + if(!s->curr) + break; bytecode = (code = shred->code)->bytecode; reg = shred->reg; mem = shred->mem; PC_DISPATCH(shred->pc) eoc: - shred->code = code; - shred->mem = mem; + VM_OUT vm_shred_exit(shred); } while(s->curr); MUTEX_UNLOCK(s->mutex); diff --git a/tests/error/dtor_outside_class.gw b/tests/error/dtor_outside_class.gw index e5324905..612a8474 100644 --- a/tests/error/dtor_outside_class.gw +++ b/tests/error/dtor_outside_class.gw @@ -1,2 +1,2 @@ -#! [contains] dtor must be in class def!! +#! [contains] 'dtor' must be in class def!! dtor {}