From 710d7ef5c47336cae86f770ff1faca13a624474e Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Tue, 15 Jun 2021 16:57:57 +0200 Subject: [PATCH] :art: Update and fix machine.remove --- Makefile | 36 ++++++++++--------- ast | 2 +- fmt | 2 +- include/clean.h | 4 +-- include/emit.h | 31 +++++++++++------ include/env/envset.h | 2 +- include/operator.h | 1 + include/vm.h | 14 ++++---- plug | 2 +- src/compile.c | 3 ++ src/emit/emit.c | 69 ++++++++++++++++++++++++------------- src/emit/emitter.c | 9 +++-- src/env/func.c | 2 +- src/gwion.c | 3 +- src/import/import_cdef.c | 3 +- src/import/import_special.c | 2 +- src/lib/array.c | 5 +-- src/lib/ptr.c | 3 +- src/lib/string.c | 2 +- src/lib/union.c | 4 +-- src/parse/check.c | 19 +++++----- src/parse/scan1.c | 6 +++- src/vm/vm.c | 25 +++++++++++--- src/vm/vm_code.c | 21 ++++++----- util | 2 +- 25 files changed, 171 insertions(+), 101 deletions(-) diff --git a/Makefile b/Makefile index 18f4f632..ce5a1275 100644 --- a/Makefile +++ b/Makefile @@ -11,15 +11,14 @@ include config.mk SEVERITY ?= 10 GWION_TEST_DIR ?= /tmp - -src := $(wildcard src/*.c) -src += $(wildcard src/*/*.c) - test_dir_all := $(wildcard tests/*) test_ignore = tests/plug test/driver tests/module test_dir := $(filter-out $(test_ignore), $(test_dir_all)) test_dir += examples +src := $(wildcard src/*.c) +src += $(wildcard src/*/*.c) + CFLAGS += -Iutil/include -Iast/include -Ilibcmdapp/src -D_GNU_SOURCE CFLAGS += -Iast/libprettyerr/src -Ifmt/include @@ -38,6 +37,7 @@ src_obj := $(src:.c=.o) gcda := $(src:.c=.gcda) gcno := $(src:.c=.gcno) lib_obj := $(filter-out src/main.o, ${src_obj}) +almost_obj := $(filter-out src/vm/vm.o, ${src_obj}) CFLAGS += -Iinclude @@ -45,25 +45,31 @@ ifeq ($(shell uname), Linux) LDFLAGS += -lrt endif -CFLAGS += -DGWION_BUILTIN - -_GWLIBS = util/libgwion_util.a ast/libgwion_ast.a libcmdapp/libcmdapp.a lib${PRG}.a util/libtermcolor/libtermcolor.a ast/libprettyerr/libprettyerr.a fmt/libgwion-fmt.a -GWLIBS := lib${PRG}.a libcmdapp/libcmdapp.a ast/libgwion_ast.a -GWLIBS += util/libgwion_util.a ast/libprettyerr/libprettyerr.a util/libtermcolor/libtermcolor.a -GWLIBS += fmt/libgwion-fmt.a -_LDFLAGS = ${GWLIBS} ${LDFLAGS} +ALMOST_LIBS := libcmdapp/libcmdapp.a fmt/libgwion-fmt.a +ALMOST_LIBS += ast/libgwion_ast.a ast/libprettyerr/libprettyerr.a +ALMOST_LIBS += util/libgwion_util.a util/libtermcolor/libtermcolor.a +GWLIBS := lib${PRG}.a ${ALMOST_LIBS} +LDFLAGS := ${GWLIBS} ${LDFLAGS} # we are not pedantic CFLAGS += -Wno-pedantic -all: options-show ${_GWLIBS} src/main.o +CFLAGS += -DGWION_BUILTIN + +all: options-show ${GWLIBS} src/main.o @$(info link ${PRG}) - @${CC} src/main.o -o ${PRG} ${_LDFLAGS} ${LIBS} + @${CC} src/main.o -o ${PRG} ${LDFLAGS} ${LIBS} options-show: @$(call _options) @$(info libs: ${GWLIBS}) +almost_gwion: ${almost_obj} ${ALMOST_LIBS} + +lto: + @${MAKE} USE_LTO=1 almost_gwion + @${MAKE} USE_LTO=0 + lib${PRG}.a: ${lib_obj} @${AR} ${AR_OPT} @@ -114,8 +120,6 @@ update: clean-all git submodule update --recursive --init make -.PHONY: .afl - clean: clean_core $(info cleaning ...) @rm -f src/*.o src/*/*.o gwion lib${PRG}.a ${gcno} ${gcda} @@ -148,7 +152,7 @@ test: scan: @rm -rf scan_output - @scan-build -o ./scan_output make + @scan-build -o ./scan_output make USE_DEBUG=1 @scan-view ./scan_output/* include $(wildcard .d/*.d) diff --git a/ast b/ast index 6d965961..5796cf89 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 6d965961163bf32e912acd09d6cda41b93e24ff7 +Subproject commit 5796cf89170539636d4f1405c59bc938e055acb0 diff --git a/fmt b/fmt index 14d746b2..260f2565 160000 --- a/fmt +++ b/fmt @@ -1 +1 @@ -Subproject commit 14d746b2d31b99395d8035c8450353afc059eac5 +Subproject commit 260f256586cbd65f0e5c74484dbe71d26b6db62e diff --git a/include/clean.h b/include/clean.h index 40b2e8c4..2fda18fd 100644 --- a/include/clean.h +++ b/include/clean.h @@ -6,8 +6,8 @@ void class_def_cleaner(const Gwion, Class_Def); void func_def_cleaner(const Gwion, Func_Def); #ifdef __CLEAN_IMPL typedef struct { - m_uint scope; - Gwion gwion; + Gwion gwion; + uint16_t scope; } Clean; ANN static void clean_array_sub(Clean *a, Array_Sub b); diff --git a/include/emit.h b/include/emit.h index 1b90044a..2d6a7770 100644 --- a/include/emit.h +++ b/include/emit.h @@ -3,20 +3,29 @@ typedef struct Frame_ { struct Vector_ stack; - size_t curr_offset; struct Map_ handlers; struct Vector_ defer; - m_uint try_top; + m_uint value_count; + uint16_t curr_offset; + uint16_t try_top; } Frame; +typedef struct VMValue_ { + Type t; + uint16_t offset; + uint16_t start; + uint16_t end; +} VMValue; + typedef struct Code_ { - Frame * frame; - struct Vector_ instr; - size_t stack_depth; - struct Vector_ stack_cont; - struct Vector_ stack_break; - struct Vector_ stack_return; - m_str name; + Frame * frame; + struct Vector_ instr; + struct Vector_ stack_cont; + struct Vector_ stack_break; + struct Vector_ stack_return; + struct M_Vector_ live_values; + m_str name; + uint16_t stack_depth; } Code; struct EmitterInfo_ { @@ -36,8 +45,8 @@ struct Emitter_ { struct Gwion_ * gwion; struct EmitterInfo_ *info; struct Vector_ stack; - m_uint this_offset; // reset - m_uint vararg_offset; // reset + uint16_t this_offset; // reset + uint16_t vararg_offset; // reset }; ANEW ANN Emitter new_emitter(MemPool); diff --git a/include/env/envset.h b/include/env/envset.h index 63f4da4e..2c02d912 100644 --- a/include/env/envset.h +++ b/include/env/envset.h @@ -6,10 +6,10 @@ struct EnvSet { const Env env; const envset_func func; const void * data; - const m_int scope; const enum tflag flag; Context _ctx; m_str _filename; + const uint16_t scope; bool run; }; diff --git a/include/operator.h b/include/operator.h index a75fa009..6dadf873 100644 --- a/include/operator.h +++ b/include/operator.h @@ -85,6 +85,7 @@ ANN void free_op_map(Map map, struct Gwion_ *gwion); ANN void operator_suspend(const Nspc, struct Op_Import *); ANN static inline void operator_resume(struct Op_Import *opi) { + assert(opi->ret); *(uintptr_t *)opi->ret = opi->data; } diff --git a/include/vm.h b/include/vm.h index 6ab8a31f..ab824db1 100644 --- a/include/vm.h +++ b/include/vm.h @@ -16,16 +16,16 @@ struct VM_Code_ { struct Vector_ instr; m_uint native_func; }; - size_t stack_depth; Type ret_type; // could be `struct Vector_ tmpl_types;` union { void * memoize; Closure *closure; }; - struct Map_ handlers; m_str name; + struct Map_ handlers; + struct M_Vector_ live_values; + uint16_t stack_depth; uint16_t ref; - ae_flag flag; bool builtin; bool callback; bool is_memoize; @@ -97,9 +97,9 @@ struct VM_Shred_ { struct ShredInfo_ *info; }; REF_FUNC(VM_Code, vmcode) -ANN2(1, 5) -ANEW VM_Code new_vmcode(MemPool p, const Vector instr, const m_uint stack_depth, - const int builtin, const m_str name); +ANN2(1,4) +ANEW VM_Code new_vmcode(MemPool p, const Vector instr, const M_Vector live_values, const m_str name, + const uint16_t stack_depth, const bool builtin); ANN ANEW VM_Code vmcode_callback(MemPool p, const VM_Code code); ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot)); @@ -129,7 +129,7 @@ ANN bool vm_running(VM const *); ANN void free_vm(VM *vm); ANN void vm_ini_shred(const VM *vm, const VM_Shred shred) __attribute__((hot)); ANN void vm_add_shred(const VM *vm, const VM_Shred shred) __attribute__((hot)); -ANN void vm_remove(const VM *vm, const m_uint index) __attribute__((hot)); +ANN bool vm_remove(const VM *vm, const m_uint index) __attribute__((hot)); ANN m_str code_name_set(MemPool p, const m_str, const m_str); ANN m_str code_name(const m_str, const bool); ANN uint32_t gw_rand(uint32_t s[2]); diff --git a/plug b/plug index a853cfd9..857e0e59 160000 --- a/plug +++ b/plug @@ -1 +1 @@ -Subproject commit a853cfd9bbaf47604202dda4ecd168a62091b13e +Subproject commit 857e0e59f0bb00b6de35ad770814960c3e442d6a diff --git a/src/compile.c b/src/compile.c index 34744434..b4a96702 100644 --- a/src/compile.c +++ b/src/compile.c @@ -174,6 +174,7 @@ ANN m_uint compile_filename_xid(struct Gwion_ *gwion, const m_str filename, const m_uint xid) { struct Compiler c = {.base = filename, .type = COMPILE_NAME}; if (!compile(gwion, &c)) return 0; + assert(c.shred); return c.shred->tick->xid = xid; } @@ -181,6 +182,7 @@ ANN m_uint compile_string_xid(struct Gwion_ *gwion, const m_str filename, const m_str data, const m_uint xid) { struct Compiler c = {.base = filename, .type = COMPILE_MSTR, .data = data}; if (!compile(gwion, &c)) return 0; + assert(c.shred); return c.shred->tick->xid = xid; } @@ -188,5 +190,6 @@ ANN m_uint compile_file_xid(struct Gwion_ *gwion, const m_str filename, FILE *file, const m_uint xid) { struct Compiler c = {.base = filename, .type = COMPILE_FILE, .file = file}; if (!compile(gwion, &c)) return 0; + assert(c.shred); return c.shred->tick->xid = xid; } diff --git a/src/emit/emit.c b/src/emit/emit.c index f5df1413..28418664 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -38,6 +38,7 @@ typedef struct Local_ { Type type; m_uint offset; bool skip; + bool is_compound; } Local; static inline void emit_pop(const Emitter emit, const m_uint scope) { @@ -84,14 +85,12 @@ ANN static Local *new_local(MemPool p, const Type type) { return local; } -ANN static m_uint frame_local(MemPool p, Frame *frame, const Type t, - const bool skip) { - Local *local = new_local(p, t); - local->offset = frame->curr_offset; - local->skip = skip; +ANN static Local *frame_local(MemPool p, Frame *frame, const Type t) { + Local *const l = new_local(p, t); + l->offset = frame->curr_offset; frame->curr_offset += t->size; - vector_add(&frame->stack, (vtype)local); - return local->offset; + vector_add(&frame->stack, (vtype)l); + return l; } ANN static inline void frame_push(Frame *frame) { @@ -204,12 +203,13 @@ ANN static m_int _frame_pop(const Emitter emit) { DECL_OB(const Local *, l, = (Local *)vector_pop(&frame->stack)); frame->curr_offset -= l->type->size; if (l->skip) return _frame_pop(emit); - if (tflag(l->type, tflag_struct)) { - struct_pop(emit, l->type, l->offset); - return _frame_pop(emit); - } - return isa(l->type, emit->gwion->type[et_object]) > 0 ? (m_int)l->offset - : _frame_pop(emit); + if (!l->is_compound) return _frame_pop(emit); + VMValue *vmval = + (VMValue *)m_vector_addr(&emit->code->live_values, --frame->value_count); + vmval->end = emit_code_size(emit); + if (!tflag(l->type, tflag_struct)) return (m_int)l->offset; + struct_pop(emit, l->type, l->offset); + return _frame_pop(emit); } ANN static m_int frame_pop(const Emitter emit) { @@ -230,6 +230,7 @@ ANEW static Code *new_code(const Emitter emit, const m_str name) { vector_init(&code->stack_break); vector_init(&code->stack_cont); vector_init(&code->stack_return); + m_vector_init(&code->live_values, sizeof(VMValue), 0); code->frame = new_frame(emit->gwion->mp); return code; } @@ -239,6 +240,7 @@ ANN static void free_code(MemPool p, Code *code) { vector_release(&code->stack_break); vector_release(&code->stack_cont); vector_release(&code->stack_return); + if (code->live_values.ptr) m_vector_release(&code->live_values); free_frame(p, code->frame); free_mstr(p, code->name); mp_free(p, Code, code); @@ -275,11 +277,21 @@ ANN m_uint emit_code_offset(const Emitter emit) { } ANN m_uint emit_local(const Emitter emit, const Type t) { - return frame_local(emit->gwion->mp, emit->code->frame, t, false); + Local *const l = frame_local(emit->gwion->mp, emit->code->frame, t); + if (isa(t, emit->gwion->type[et_compound]) > 0) { + l->is_compound = true; + VMValue vmval = { + .t = t, .offset = l->offset, .start = emit_code_size(emit)}; + m_vector_add(&emit->code->live_values, &vmval); + ++emit->code->frame->value_count; + } + return l->offset; } ANN m_uint emit_localn(const Emitter emit, const Type t) { - return frame_local(emit->gwion->mp, emit->code->frame, t, true); + Local *const l = frame_local(emit->gwion->mp, emit->code->frame, t); + l->skip = true; + return l->offset; } ANN void emit_ext_ctor(const Emitter emit, const Type t); @@ -289,9 +301,11 @@ ANN static inline void maybe_ctor(const Emitter emit, const Type t) { } ANN static void emit_pre_ctor(const Emitter emit, const Type type) { - if (type->info->parent) emit_pre_ctor(emit, type->info->parent); - if (tflag(type, tflag_typedef) && type->info->parent->array_depth) - emit_array_extend(emit, type, type->info->cdef->base.ext->array->exp); + if (type->info->parent) { + emit_pre_ctor(emit, type->info->parent); + if (tflag(type, tflag_typedef) && type->info->parent->array_depth) + emit_array_extend(emit, type, type->info->cdef->base.ext->array->exp); + } maybe_ctor(emit, type); } @@ -585,8 +599,9 @@ ANN static m_bool emit_range(const Emitter emit, Range *range) { ANN static m_bool emit_prim_range(const Emitter emit, Range **data) { Range *range = *data; CHECK_BB(emit_range(emit, range)); - const Exp e = range->start ?: range->end; - const Symbol sym = insert_symbol("@range"); + const Exp e = range->start ?: range->end; + const Symbol sym = insert_symbol("@range"); + assert(e); struct Op_Import opi = {.op = sym, .rhs = e->type, .pos = e->pos, @@ -625,8 +640,9 @@ ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array *array) { ANN static m_bool emit_exp_slice(const Emitter emit, const Exp_Slice *range) { CHECK_BB(emit_exp(emit, range->base)); CHECK_BB(emit_range(emit, range->range)); - const Symbol sym = insert_symbol("@slice"); - const Exp e = range->range->start ?: range->range->end; + const Symbol sym = insert_symbol("@slice"); + const Exp e = range->range->start ?: range->range->end; + assert(e); struct Op_Import opi = {.op = sym, .lhs = e->type, .rhs = range->base->type, @@ -1250,7 +1266,8 @@ static inline m_bool push_func_code(const Emitter emit, const Func f) { const Instr instr = (Instr)vector_back(&emit->code->instr); if (instr->opcode == eDotTmplVal) { size_t len = strlen(f->name); - size_t sz = len - strlen(f->value_ref->from->owner_class->name); + assert(f->value_ref->from->owner_class); + size_t sz = len - strlen(f->value_ref->from->owner_class->name); char c[sz + 1]; memcpy(c, f->name, sz); c[sz] = '\0'; @@ -1546,6 +1563,7 @@ ANN static m_bool spork_prepare_code(const Emitter emit, emit_add_instr(emit, RegPushImm); push_spork_code(emit, sp->is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, sp->code->pos); + if (emit->env->class_def) stack_alloc(emit); if (emit->env->func && vflag(emit->env->func->value_ref, vflag_member)) stack_alloc(emit); return scoped_stmt(emit, sp->code, 0); @@ -1560,7 +1578,10 @@ ANN static m_bool spork_prepare_func(const Emitter emit, } ANN static VM_Code spork_prepare(const Emitter emit, const struct Sporker *sp) { - if (!sp->code) CHECK_BO(prepare_call(emit, &sp->exp->d.exp_call)); + if (!sp->code) { + assert(sp->exp); + CHECK_BO(prepare_call(emit, &sp->exp->d.exp_call)); + } if ((sp->code ? spork_prepare_code : spork_prepare_func)(emit, sp) > 0) return finalyze(emit, EOC); emit_pop_code(emit); diff --git a/src/emit/emitter.c b/src/emit/emitter.c index 95350b2d..7f6c9075 100644 --- a/src/emit/emitter.c +++ b/src/emit/emitter.c @@ -8,9 +8,12 @@ #include "escape.h" static ANEW ANN VM_Code emit_code(const Emitter emit) { - Code *const c = emit->code; - const VM_Code code = - new_vmcode(emit->gwion->mp, &c->instr, c->stack_depth, 0, c->name); + Code *const c = emit->code; + const bool has_values = m_vector_size(&c->live_values); + const VM_Code code = new_vmcode(emit->gwion->mp, &c->instr, + has_values ? &c->live_values : NULL, c->name, + c->stack_depth, false); + if (has_values) c->live_values.ptr = NULL; return code; } diff --git a/src/env/func.c b/src/env/func.c index 5f6e7242..1073c5eb 100644 --- a/src/env/func.c +++ b/src/env/func.c @@ -37,6 +37,6 @@ Symbol func_symbol(const Env env, const m_str nspc, const m_str base, ANN void builtin_func(const MemPool mp, const Func f, void *func_ptr) { set_vflag(f->value_ref, vflag_builtin); - f->code = new_vmcode(mp, NULL, f->def->stack_depth, 1, f->name); + f->code = new_vmcode(mp, NULL, NULL, f->name, f->def->stack_depth, true); f->code->native_func = (m_uint)func_ptr; } diff --git a/src/gwion.c b/src/gwion.c index d39cccdb..adbd7f89 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -33,7 +33,8 @@ ANN static inline m_bool gwion_engine(const Gwion gwion) { } ANN static void gwion_cleaner(const Gwion gwion) { - const VM_Code code = new_vmcode(gwion->mp, NULL, 0, 1, "in code dtor"); + const VM_Code code = + new_vmcode(gwion->mp, NULL, NULL, "in code dtor", 0, true); gwion->vm->cleaner_shred = new_vm_shred(gwion->mp, code); vm_ini_shred(gwion->vm, gwion->vm->cleaner_shred); } diff --git a/src/import/import_cdef.c b/src/import/import_cdef.c index 93469d3f..05daf682 100644 --- a/src/import/import_cdef.c +++ b/src/import/import_cdef.c @@ -21,7 +21,7 @@ ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const enum tflag e) { VM_Code *code = e == tflag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor; const m_str name = type->name; - *code = new_vmcode(p, NULL, SZ_INT, 1, name); + *code = new_vmcode(p, NULL, NULL, name, SZ_INT, true); (*code)->native_func = (m_uint)d; type->tflag |= e; return GW_OK; @@ -66,6 +66,7 @@ ANN static Type type_finish(const Gwi gwi, const Type t) { if (gwi->gwion->data->cdoc) { lint_indent(gwi->lint); gwi->lint->indent++; + assert(t->info->cdef); lint_class_def(gwi->lint, t->info->cdef); } return t; diff --git a/src/import/import_special.c b/src/import/import_special.c index b57b2a21..d0586769 100644 --- a/src/import/import_special.c +++ b/src/import/import_special.c @@ -45,7 +45,7 @@ ANN void gwi_set_loc(const Gwi gwi, const m_str file, const uint line) { } ANN static m_bool mk_gack(MemPool p, const Type type, const f_gack d) { - const VM_Code code = new_vmcode(p, NULL, SZ_INT, 1, "@gack"); + const VM_Code code = new_vmcode(p, NULL, NULL, "@gack", SZ_INT, true); code->native_func = (m_uint)d; type->info->gack = code; return GW_OK; diff --git a/src/lib/array.c b/src/lib/array.c index c47f760a..042dc928 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -703,8 +703,8 @@ static OP_CHECK(opck_array_scan) { builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->vtable, 11), vm_vector_foldr); if (isa(base, env->gwion->type[et_compound]) > 0) { - t->nspc->dtor = - new_vmcode(env->gwion->mp, NULL, SZ_INT, 1, "array component dtor"); + t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, NULL, + "array component dtor", SZ_INT, true); set_tflag(t, tflag_dtor); t->nspc->dtor->native_func = (m_uint)( !tflag(base, tflag_struct) ? array_dtor_obj : array_dtor_struct); @@ -947,6 +947,7 @@ INSTR(ArrayAlloc) { gw_err("[Gwion](VM): (note: in shred[id=%" UINT_F ":%s])\n", shred->tick->xid, shred->code->name); vm_shred_exit(shred); + if (info->is_obj) free(aai.data); return; // TODO make exception vararg } *(void **)(ref->data + SZ_INT) = aai.data; diff --git a/src/lib/ptr.c b/src/lib/ptr.c index a0693e65..b7b1ea7b 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -158,7 +158,8 @@ static OP_CHECK(opck_ptr_scan) { env_pop(env, scope); nspc_add_type_front(t->info->value->from->owner, info.name, t); if (isa(base, env->gwion->type[et_compound]) > 0) { - t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, SZ_INT, 1, "@PtrDtor"); + t->nspc->dtor = + new_vmcode(env->gwion->mp, NULL, NULL, "@PtrDtor", SZ_INT, true); if (!tflag(base, tflag_struct)) t->nspc->dtor->native_func = (m_uint)ptr_object_dtor; else diff --git a/src/lib/string.c b/src/lib/string.c index b094c2b4..dd6c827a 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -247,7 +247,7 @@ static MFUN(string_replaceN) { } char insert[strlen(STRING(arg)) + 1]; const m_uint len = strlen(str); - memset(insert, 0, len + 1); + // memset(insert, 0, len + 1); strcpy(insert, STRING(arg)); str[len] = '\0'; if (index > (m_int)len) index = len - 1; diff --git a/src/lib/union.c b/src/lib/union.c index 66bcb05d..c48178d7 100644 --- a/src/lib/union.c +++ b/src/lib/union.c @@ -107,8 +107,8 @@ static OP_CHECK(opck_union_ctor) { Exp_Call *call = (Exp_Call *)data; const Exp name = call->args; if (!name || !name->next || name->next->next) - ERR_N(name->pos, "Union constructor takes two arguments, " - "'id' and 'value'"); + ERR_N(call->func->pos, "Union constructor takes two arguments, " + "'id' and 'value'"); if (name->exp_type != ae_exp_primary || name->d.prim.prim_type != ae_prim_id) return NULL; const Exp val = name->next; diff --git a/src/parse/check.c b/src/parse/check.c index 7b4678c9..b451914f 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -182,7 +182,7 @@ ANN static m_bool prim_array_inner(const Env env, Type type, const Exp e, gwerr_basic(_("literal contains incompatible types"), fst, NULL, env->name, loc, 0); // suggested fix: rewrite int 2 as float 2.0" - char sec[12 + strlen(e->type->name)]; + char sec[16 + strlen(e->type->name)]; sprintf(sec, "got `{+/}%s{0}`", e->type->name); gwerr_secondary(sec, env->name, e->pos); @@ -223,7 +223,8 @@ ANN static m_bool check_range(const Env env, Range *range) { ANN static Type check_prim_range(const Env env, Range **data) { Range *range = *data; CHECK_BO(check_range(env, range)); - const Exp e = range->start ?: range->end; + const Exp e = range->start ?: range->end; + assert(e); const Symbol sym = insert_symbol("@range"); struct Op_Import opi = {.op = sym, .rhs = e->type, @@ -443,8 +444,9 @@ static ANN Type check_exp_array(const Env env, const Exp_Array *array) { static ANN Type check_exp_slice(const Env env, const Exp_Slice *range) { CHECK_OO(check_exp(env, range->base)); CHECK_BO(check_range(env, range->range)); - const Symbol sym = insert_symbol("@slice"); - const Exp e = range->range->start ?: range->range->end; + const Symbol sym = insert_symbol("@slice"); + const Exp e = range->range->start ?: range->range->end; + assert(e); struct Op_Import opi = {.op = sym, .lhs = e->type, .rhs = range->base->type, @@ -744,10 +746,10 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) { free_scope(env->gwion->mp, env->curr->info->value); env->curr->info->value = l->def->base->values; if (env->class_def) set_vflag(l->def->base->func->value_ref, vflag_member); + exp->func->type = l->def->base->func->value_ref->type; + if (!l->def->base->ret_type) + l->def->base->ret_type = env->gwion->type[et_void]; } - exp->func->type = l->def->base->func->value_ref->type; - if (!l->def->base->ret_type) - l->def->base->ret_type = env->gwion->type[et_void]; return ret > 0 ? l->def->base->ret_type : NULL; } @@ -1573,7 +1575,8 @@ ANN m_bool check_func_def(const Env env, const Func_Def f) { if (ret > 0) { set_fflag(fdef->base->func, fflag_valid); if (env->class_def && fdef->base->effects.ptr && - !check_effect_overload(&fdef->base->effects, override->d.func_ref)) + (override && + !check_effect_overload(&fdef->base->effects, override->d.func_ref))) ERR_B(fdef->base->pos, _("too much effects in override."), s_name(fdef->base->xid)) } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index b3309684..63fd2aab 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -404,12 +404,13 @@ ANN static m_bool scan1_args(const Env env, Arg_List list) { UNSET_FLAG(list->td, late); } var->value = arg_value(env, list); - nspc_add_value(env->curr, var->xid, var->value); + if (var->xid) nspc_add_value(env->curr, var->xid, var->value); } while ((list = list->next)); return GW_OK; } ANN static Type scan1_noret(const Env env, const Func_Base *base) { + assert(base->td); DECL_OO(const Type, t, = known_type(env, base->td)); if (!tflag(t, tflag_noret)) return t; ERR_O(base->pos, _("Can't use type `{+G}%s{0}` for return"), t->name); @@ -542,6 +543,7 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) { } ANN static m_bool class_internal(const Env env, const Func_Base *base) { + assert(base->td); if (!env->class_def) ERR_B(base->td->pos, _("'%s' must be in class def!!"), s_name(base->xid)) if (base->args) @@ -554,12 +556,14 @@ ANN static m_bool class_internal(const Env env, const Func_Base *base) { ANN static inline m_bool scan_internal_arg(const Env env, const Func_Base *base) { if (base->args && !base->args->next) return GW_OK; + assert(base->td); ERR_B(base->td->pos, _("'%s' must have one (and only one) argument"), s_name(base->xid)) } ANN static inline m_bool scan_internal_int(const Env env, const Func_Base *base) { + assert(base->td); CHECK_BB(scan_internal_arg(env, base)); if (isa(base->ret_type, env->gwion->type[et_int]) > 0) return GW_OK; ERR_B(base->td->pos, _("'%s' must return 'int'"), s_name(base->xid)) diff --git a/src/vm/vm.c b/src/vm/vm.c index edd08535..5075d114 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -48,17 +48,28 @@ ANN static inline void shred_unwind(const VM_Shred shred) { } ANN static bool unwind(VM_Shred shred, const Symbol effect, const m_uint size) { + const VM_Code code = shred->code; + if (code->live_values.ptr) { + const uint16_t pc = shred->pc; + for (m_uint i = 0; i < m_vector_size(&code->live_values); i++) { + VMValue *vmval = (VMValue *)m_vector_addr(&code->live_values, i); + if (pc < vmval->start) break; + if (pc > vmval->end) continue; + m_bit *const data = &*(m_bit *)(shred->mem + vmval->offset); + compound_release(shred, vmval->t, data); + } + } if (!size) return true; - if (shred->code->handlers.ptr) { + if (code->handlers.ptr) { const m_uint start = VKEY(&shred->info->frame, size - 1); if (start > shred->pc) return true; - const Map m = &shred->code->handlers; + const Map m = &code->handlers; m_uint pc = 0; for (m_uint i = 0; i < map_size(m); i++) { if (start > shred->pc) break; if (start < shred->pc && VKEY(m, i) > shred->pc) { const m_uint next = VKEY(m, i); - const Instr instr = (Instr)vector_at(&shred->code->instr, next + 1); + const Instr instr = (Instr)vector_at(&code->instr, next + 1); if (!instr->m_val2 || (Symbol)instr->m_val2 == effect) { pc = next + 1; break; @@ -124,13 +135,17 @@ ANN void handle(VM_Shred shred, const m_str effect) { vm_shred_exit(shred); } -void vm_remove(const VM *vm, const m_uint index) { +ANN bool vm_remove(const VM *vm, const m_uint index) { const Vector v = (Vector)&vm->shreduler->shreds; LOOP_OPTIM for (m_uint i = vector_size(v) + 1; --i;) { const VM_Shred sh = (VM_Shred)vector_at(v, i - 1); - if (sh && sh->tick->xid == index) handle(sh, "MsgRemove"); + if (sh && sh->tick->xid == index) { + handle(sh, "MsgRemove"); + return true; + } } + return false; } ANN void free_vm(VM *vm) { diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index 956f4708..b8233412 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -34,6 +34,7 @@ ANN void free_vmcode(VM_Code a, Gwion gwion) { free_code_instr(&a->instr, gwion); } if (a->handlers.ptr) map_release(&a->handlers); + if (a->live_values.ptr) m_vector_release(&a->live_values); vector_release(&a->instr); } free_mstr(gwion->mp, a->name); @@ -151,8 +152,9 @@ ANN static m_bit *tobytecode(MemPool p, const VM_Code code) { return final; } -VM_Code new_vmcode(MemPool p, const Vector instr, const m_uint stack_depth, - const int builtin, const m_str name) { +VM_Code new_vmcode(MemPool p, const Vector instr, const M_Vector live_values, + const m_str name, const uint16_t stack_depth, + const bool builtin) { VM_Code code = mp_calloc(p, VM_Code); code->name = mstrdup(p, name); if (instr) { @@ -160,6 +162,7 @@ VM_Code new_vmcode(MemPool p, const Vector instr, const m_uint stack_depth, vector_copy2(instr, &code->instr); code->bytecode = tobytecode(p, code); } + if (live_values) code->live_values.ptr = live_values->ptr; code->stack_depth = stack_depth; code->builtin = builtin; code->ref = 1; @@ -171,12 +174,12 @@ VM_Code new_vmcode(MemPool p, const Vector instr, const m_uint stack_depth, VM_Code vmcode_callback(MemPool mp, VM_Code base) { char name[strlen(base->name) + 11]; sprintf(name, "%s(callback)", base->name); - const Instr instr = (Instr)vector_back(&base->instr); - instr->opcode = eEOC; - const VM_Code code = - new_vmcode(mp, &base->instr, base->stack_depth, base->builtin, name); - code->closure = base->closure; - code->callback = 1; - instr->opcode = eFuncReturn; + const Instr instr = (Instr)vector_back(&base->instr); + instr->opcode = eEOC; + const VM_Code code = new_vmcode(mp, &base->instr, &base->live_values, name, + base->stack_depth, base->builtin); + code->closure = base->closure; + code->callback = 1; + instr->opcode = eFuncReturn; return code; } diff --git a/util b/util index 7364841e..f194f414 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 7364841ef46d456037eec97cdcb3ff3abb41289d +Subproject commit f194f41413c7591d952e1abb399f60ca1da0715c -- 2.43.0