From: fennecdjay Date: Mon, 29 Jan 2024 22:36:22 +0000 (+0100) Subject: :art: compile time utility X-Git-Tag: nightly~121 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=639d22691bc4ff340085a86cd7c218d257ed455e;p=gwion.git :art: compile time utility --- diff --git a/ast b/ast index 6477df11..9250ae0e 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 6477df1118c1c7b011583f14cae9e7d185f2cbeb +Subproject commit 9250ae0ec3f65a9be684a5dfb66ca13c7916883f diff --git a/include/emit.h b/include/emit.h index 5656c156..11aaf61d 100644 --- a/include/emit.h +++ b/include/emit.h @@ -151,4 +151,19 @@ mk_emit_instr(regtomem4, Reg2Mem4); mk_emit_instr(regpushmem4, RegPushMem4); ANN void emit_struct_release(const Emitter, const Type , const m_uint offset); + +ANN void comptime_ini(const Emitter emit, const m_str name); +ANN2(1) void comptime_end(const Emitter emit, const size_t size, void*); + +ANEW Code *new_code(const Emitter emit, const m_str name); +ANN VM_Code finalyze(const Emitter emit, const f_instr exec); +ANN static inline void emit_push_code(const Emitter emit, const m_str name) { + vector_add(&emit->stack, (vtype)emit->code); + emit->code = new_code(emit, name); + if (emit->info->debug) emit_add_instr(emit, DebugLine); +} + +ANN static inline void emit_pop_code(const Emitter emit) { + emit->code = (Code *)vector_pop(&emit->stack); +} #endif diff --git a/include/opcode.h b/include/opcode.h index e21ff243..d0704e44 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -149,6 +149,7 @@ enum { eRegMove, eReg2Mem, eReg2Mem4, + e_staticmemcpy_, eOverflow, eFuncUsrEnd, eFuncUsrEnd2, @@ -368,6 +369,7 @@ enum { #define RegMove (f_instr)eRegMove #define Reg2Mem (f_instr)eReg2Mem #define Reg2Mem4 (f_instr)eReg2Mem4 +#define _staticmemcpy_ (f_instr)e_staticmemcpy_ #define Overflow (f_instr)eOverflow #define FuncUsrEnd (f_instr)eFuncUsrEnd #define FuncUsrEnd2 (f_instr)eFuncUsrEnd2 @@ -1113,6 +1115,10 @@ ANN static inline void dump_opcodes(const VM_Code code) { gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2); gw_out("\n"); break; + case e_staticmemcpy_: + gw_out("{Y}┃{0}{-}% 4lu{0}: _staticmemcpy_", j); + gw_out("\n"); + break; case eOverflow: gw_out("{Y}┃{0}{-}% 4lu{0}: Overflow ", j); gw_out("\n"); diff --git a/opcode.txt b/opcode.txt index 4a63a5da..4bd9f83b 100644 --- a/opcode.txt +++ b/opcode.txt @@ -146,6 +146,7 @@ SetCode~i~i RegMove~i Reg2Mem~u~i Reg2Mem4~u~u +_staticmemcpy_ Overflow FuncUsrEnd FuncUsrEnd2 diff --git a/src/emit/comptime.c b/src/emit/comptime.c new file mode 100644 index 00000000..feb8877c --- /dev/null +++ b/src/emit/comptime.c @@ -0,0 +1,33 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "gwion_env.h" +#include "vm.h" +#include "gwion.h" +#include "instr.h" +#include "emit.h" +#include "object.h" +#include "shreduler_private.h" + +ANN void comptime_ini(const Emitter emit, const m_str name) { + emit_push_code(emit, name); // new code { +} + +ANN2(1) void comptime_end(const Emitter emit, const size_t size, void *data) { + if (size) { + emit_regmove(emit, -size); + const Instr instr = emit_add_instr(emit, _staticmemcpy_); + instr->m_val = (m_uint)data; + instr->m_val2 = size; + } + const VM *vm = emit->gwion->vm; + const VM_Code code = finalyze(emit, EOC); // } new code + const VM_Shred shred = vm->cleaner_shred; + shred->code = code; + shred->info->me->ref++; + shredule(vm->shreduler, shred, 0); + const bool loop = vm->shreduler->loop; + vm_run(vm); + shred->code = NULL; + vm->bbq->is_running = true; + vm->shreduler->loop = loop; +} diff --git a/src/emit/emit.c b/src/emit/emit.c index eb09a332..a8131760 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -214,7 +214,7 @@ ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt); ANN static m_bool emit_stmt_list(const Emitter emit, Stmt_List list); ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot *member); -ANEW static Code *new_code(const Emitter emit, const m_str name) { +ANEW Code *new_code(const Emitter emit, const m_str name) { Code *code = mp_calloc(emit->gwion->mp, Code); code->name = code_name_set(emit->gwion->mp, name, emit->env->name); vector_init(&code->instr); @@ -257,16 +257,6 @@ ANN void emit_pop_scope(const Emitter emit) { if (emit->info->debug) emit_add_instr(emit, DebugPop); } -ANN static inline void emit_push_code(const Emitter emit, const m_str name) { - vector_add(&emit->stack, (vtype)emit->code); - emit->code = new_code(emit, name); - if (emit->info->debug) emit_add_instr(emit, DebugLine); -} - -ANN static inline void emit_pop_code(const Emitter emit) { - emit->code = (Code *)vector_pop(&emit->stack); -} - ANN void emit_push_scope(const Emitter emit) { frame_push(emit->code->frame); vector_add(&emit->info->pure, 0); @@ -523,7 +513,7 @@ ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary *prim) { return _emit_symbol(emit, &prim->d.var); } -ANN static VM_Code finalyze(const Emitter emit, const f_instr exec) { +ANN VM_Code finalyze(const Emitter emit, const f_instr exec) { emit_add_instr(emit, exec); const VM_Code code = emit->info->emit_code(emit); free_code(emit->gwion->mp, emit->code); @@ -857,20 +847,13 @@ ANN static m_bool emit_prim_locale(const Emitter emit, const Symbol *id) { CHECK_OB(emit_ensure_func(emit, f)); } CHECK_OB(emit_ensure_func(emit, emit->locale)); - emit_push_code(emit, "locale"); // new code { + comptime_ini(emit, "locale"); const M_Object string = new_string(emit->gwion, s_name(*id)); emit_pushimm(emit, (m_uint)string); emit_pushimm(emit, (m_uint)emit->locale->code); CHECK_BB(emit_exp_call1(emit, emit->locale, SZ_FLOAT, true)); - emit_regmove(emit, -emit->locale->def->base->ret_type->size); - const VM_Code code = finalyze(emit, EOC); - const VM_Shred shred = new_vm_shred(emit->gwion->mp, code); - vm_add_shred(emit->gwion->vm, shred); - shred->info->me->ref++; - vm_run(emit->gwion->vm); - emit->gwion->vm->bbq->is_running = true; - const m_float ret = *(m_float*)shred->reg; - release(shred->info->me, shred); + m_float ret; + comptime_end(emit, SZ_FLOAT, &ret); if(ret == -1.0) ERR_B(prim_pos(id), "error in locale"); const Instr instr = emit_add_instr(emit, RegPushImm2); @@ -2819,11 +2802,6 @@ ANN static void emit_lambda_capture(const Emitter emit, const Func_Def fdef) { emit_regtomem4(emit, fdef->stack_depth, offset); } -static INSTR(ConstGenericEOC) { - shred->reg -= instr->m_val; - memcpy((void*)instr->m_val2, shred->reg, instr->m_val); -//a exit(12); -} ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) { if (tmpl_base(f->base->tmpl) && fbflag(f->base, fbflag_op)) return GW_OK; const Func func = f->base->func; @@ -2849,7 +2827,7 @@ ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) { !global ? emit->env->scope->depth : env_push_global(emit->env); if(fdef->base->tmpl) { // check is call? if(tmplarg_ntypes(fdef->base->tmpl->call) != fdef->base->tmpl->call->len) { -emit_push_code(emit, "const-generic"); // better name? + emit_push_code(emit, "function const generic"); uint32_t size = 0; // create new code here for(uint32_t i = 0; i < fdef->base->tmpl->call->len; i++) { @@ -2869,27 +2847,17 @@ size += targ->d.exp->type->size; //emit_regmove(emit, -size); fdef->base->func->value_ref->type->nspc->class_data_size = size; fdef->base->func->value_ref->type->nspc->class_data = _mp_malloc(emit->gwion->mp, size); -const Instr instr = emit_add_instr(emit, ConstGenericEOC); -instr->m_val = size; -instr->m_val2 = (m_uint)fdef->base->func->value_ref->type->nspc->class_data; -const VM_Code code = finalyze(emit, EOC); -//const VM_Code code = finalyze(emit, ConstGenericEOC); -const VM_Shred shred = new_vm_shred(emit->gwion->mp, code); -vm_add_shred(emit->gwion->vm, shred); -//shred->info->me->ref++; +comptime_end(emit, size, fdef->base->func->value_ref->type->nspc->class_data); +//const Instr instr = emit_add_instr(emit, ConstGenericEOC); +//instr->m_val = size; +//instr->m_val2 = (m_uint)fdef->base->func->value_ref->type->nspc->class_data; +//const VM_Code code = finalyze(emit, EOC); +//const VM_Shred shred = new_vm_shred(emit->gwion->mp, code); +//vm_add_shred(emit->gwion->vm, shred); +//const bool loop = emit->gwion->vm->shreduler->loop; //vm_run(emit->gwion->vm); -//emit->gwion->vm-> -const bool loop = emit->gwion->vm->shreduler->loop; -vm_run(emit->gwion->vm); -// alloc space -//fdef->base->func->value_ref->type->nspc->class_data_size = size; -//fdef->base->func->value_ref->type->nspc->class_data = _mp_malloc(emit->gwion->mp, size); -//memcpy(fdef->base->func->value_ref->type->nspc->class_data, shred->reg, size); -// => copy data -emit->gwion->vm->bbq->is_running = true; -emit->gwion->vm->shreduler->loop = loop; -//release(shred->info->me, emit->gwion->vm->cleaner_shred); -//} +//emit->gwion->vm->bbq->is_running = true; +//emit->gwion->vm->shreduler->loop = loop; } } emit_func_def_init(emit, func); @@ -2971,7 +2939,7 @@ static INSTR(set) { ANN static m_bool emit_class_tmpl(const Emitter emit, const Tmpl *tmpl, const Nspc nspc) { if(tmplarg_ntypes(tmpl->list) != tmpl->list->len) { - emit_push_code(emit, "tmpl"); // make better name + comptime_ini(emit, "class tmpl"); for(uint32_t i = 0; i < tmpl->list->len; i++) { const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i); if(likely(targ.type == tmplarg_td)) continue; @@ -2983,13 +2951,7 @@ ANN static m_bool emit_class_tmpl(const Emitter emit, const Tmpl *tmpl, const Ns instr->m_val2 = targ.d.exp->type->size; instr->m_val = instr->m_val2 + SZ_INT; } - VM_Code code = finalyze(emit, EOC); - VM_Shred shred = new_vm_shred(emit->gwion->mp, code); - vm_add_shred(emit->gwion->vm, shred); - const bool loop = emit->gwion->vm->shreduler->loop; - vm_run(emit->gwion->vm); - emit->gwion->vm->bbq->is_running = true; - emit->gwion->vm->shreduler->loop = loop; + comptime_end(emit, 0, NULL); } return GW_OK; } diff --git a/src/vm/vm.c b/src/vm/vm.c index 0b85d57b..ae3009f5 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -454,7 +454,7 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] &&fimul, &&fidiv, &&fiand, &&fior, &&fieq, &&fine, &&figt, &&fige, &&filt, &&file, &&firassign, &&firadd, &&firsub, &&firmul, &&firdiv, &&itof, &&ftoi, &&timeadv, &&recurs, &&setcode, &®move, - &®tomem, &®tomemother, + &®tomem, &®tomemother, &&staticmemcpy, &&overflow, &&funcusrend, &&funcusrend2, &&funcmemberend, &&sporkini, &&forkini, &&sporkfunc, &&sporkexp, &&sporkcode, @@ -939,6 +939,9 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] regtomemother: memcpy(mem + VAL, reg, VAL2); DISPATCH() + staticmemcpy: + memcpy((void*)VAL, reg, VAL2); + DISPATCH() overflow: if (overflow_(mem + VAL2, shred)) { handle(shred, "StackOverflow"); @@ -1335,7 +1338,7 @@ static void *_dispatch[] = { &&_fimul, &&_fidiv, &&_fiand, &&_fior, &&_fieq, &&_fine, &&_figt, &&_fige, &&_filt, &&_file, &&_firassign, &&_firadd, &&_firsub, &&_firmul, &&_firdiv, &&_itof, &&_ftoi, &&_timeadv, &&_recurs, &&_setcode, &&_regmove, - &&_regtomem, &&_regtomemother, + &&_regtomem, &&_regtomemother, &&_staticmemcpy, &&_overflow, &&_funcusrend, &&_funcusrend2, &&_funcmemberend, &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkexp, &&_sporkcode, &&_forkend, @@ -1536,6 +1539,7 @@ return; PREPARE(regmove); PREPARE(regtomem); PREPARE(regtomemother); + PREPARE(staticmemcpy); PREPARE(overflow); PREPARE(funcusrend); PREPARE(funcusrend2);