#include "func.h"
#include "nspc.h"
#include "operator.h"
+#include "gwion.h"
struct Path {
m_str path, curr;
}
ANN VM* gwi_vm(const Gwi gwi) {
- return gwi->vm;
+ return gwi->gwion->vm;
}
ANN m_int gwi_tmpl_end(const Gwi gwi) {
ANN m_int gwi_add_type(const Gwi gwi, const Type type) {
if(type->name[0] != '@')
CHECK_BB(name_valid(type->name));
- env_add_type(gwi->env, type);
+ env_add_type(gwi->gwion->env, type);
return (m_int)type->xid;
}
} else
SET_FLAG(type, scan1 | ae_flag_scan2 | ae_flag_check | ae_flag_emit);
gwi_add_type(gwi, type);
- import_class_ini(gwi->env, type, pre_ctor, dtor);
+ import_class_ini(gwi->gwion->env, type, pre_ctor, dtor);
return (m_int)type->xid;
}
ANN m_int gwi_class_ext(const Gwi gwi, Type_Decl* td) {
- if(!gwi->env->class_def)
+ if(!gwi->gwion->env->class_def)
ERR_B(0, "gwi_class_ext invoked before gwi_class_ini")
- const VM_Code ctor = gwi->env->class_def->nspc->pre_ctor;
- if(gwi->env->class_def->parent ||
- (gwi->env->class_def->def && gwi->env->class_def->def->ext))
+ const VM_Code ctor = gwi->gwion->env->class_def->nspc->pre_ctor;
+ if(gwi->gwion->env->class_def->parent ||
+ (gwi->gwion->env->class_def->def && gwi->gwion->env->class_def->def->ext))
ERR_B(0, "class extend already set")
if(td->array && !td->array->exp)
ERR_B(0, "class extend array can't be empty")
- if(!gwi->env->class_def->def) {
- const Type t = known_type(gwi->env, td);
+ if(!gwi->gwion->env->class_def->def) {
+ const Type t = known_type(gwi->gwion->env, td);
CHECK_OB(t)
if(td->array)
- SET_FLAG(gwi->env->class_def, typedef);
- gwi->env->class_def->parent = t;
- gwi->env->class_def->nspc->info->offset = t->nspc->info->offset;
+ SET_FLAG(gwi->gwion->env->class_def, typedef);
+ gwi->gwion->env->class_def->parent = t;
+ gwi->gwion->env->class_def->nspc->info->offset = t->nspc->info->offset;
if(t->nspc->info->vtable.ptr)
- vector_copy2(&t->nspc->info->vtable, &gwi->env->class_def->nspc->info->vtable);
- CHECK_OB((gwi->emit->code = emit_class_code(gwi->emit,
- gwi->env->class_def->name)))
+ vector_copy2(&t->nspc->info->vtable, &gwi->gwion->env->class_def->nspc->info->vtable);
+ CHECK_OB((gwi->gwion->emit->code = emit_class_code(gwi->gwion->emit,
+ gwi->gwion->env->class_def->name)))
if(td->array)
- CHECK_BB(emit_array_extend(gwi->emit, t, td->array->exp))
+ CHECK_BB(emit_array_extend(gwi->gwion->emit, t, td->array->exp))
if(ctor)
- emit_ext_ctor(gwi->emit, ctor);
- emit_class_finish(gwi->emit, gwi->env->class_def->nspc);
+ emit_ext_ctor(gwi->gwion->emit, ctor);
+ emit_class_finish(gwi->gwion->emit, gwi->gwion->env->class_def->nspc);
free_type_decl(td);
} else {
SET_FLAG(td, typedef);
- gwi->env->class_def->def->ext = td;
+ gwi->gwion->env->class_def->def->ext = td;
}
return GW_OK;
}
#include "mpool.h"
ANN m_int gwi_class_end(const Gwi gwi) {
- if(!gwi->env->class_def)return GW_ERROR;
- const Type t = gwi->env->class_def;
+ if(!gwi->gwion->env->class_def)return GW_ERROR;
+ const Type t = gwi->gwion->env->class_def;
if(t->nspc && t->nspc->info->offset)
t->p = mp_ini((uint32_t)t->nspc->info->offset);
- return import_class_end(gwi->env);
+ return import_class_end(gwi->gwion->env);
}
ANN static void dl_var_new_exp_array(DL_Var* v) {
memset(v, 0, sizeof(DL_Var));
if(!(v->t.xid = str2list(type, &v->array_depth)))
ERR_B(0, "\t...\tduring var import '%s.%s'.",
- gwi->env->class_def->name, name)
+ gwi->gwion->env->class_def->name, name)
v->var.xid = insert_symbol(name);
return GW_OK;
}
#undef gwi_item_end
static void gwi_body(const Gwi gwi, const Class_Body body) {
- if(!gwi->env->class_def->def->body)
- gwi->env->class_def->def->body = body;
+ if(!gwi->gwion->env->class_def->def->body)
+ gwi->gwion->env->class_def->def->body = body;
else
gwi->body->next = body;
gwi->body = body;
DL_Var* v = &gwi->var;
dl_var_set(v, flag | ae_flag_builtin);
v->var.addr = (void*)addr;
- if(gwi->env->class_def && GET_FLAG(gwi->env->class_def, template)) {
+ if(gwi->gwion->env->class_def && GET_FLAG(gwi->gwion->env->class_def, template)) {
Type_Decl *type_decl = new_type_decl(v->t.xid, flag);
const Var_Decl var_decl = new_var_decl(v->var.xid, v->var.array, 0);
const Var_Decl_List var_decl_list = new_var_decl_list(var_decl, NULL);
gwi_body(gwi, body);
return GW_OK;
}
- CHECK_BB(traverse_decl(gwi->env, &v->exp.d.exp_decl))
+ CHECK_BB(traverse_decl(gwi->gwion->env, &v->exp.d.exp_decl))
SET_FLAG(v->var.value, builtin);
dl_var_release(v);
return (m_int)v->var.value->offset;
}
ANN m_int gwi_func_end(const Gwi gwi, const ae_flag flag) {
- Func_Def def = import_fun(gwi->env, &gwi->func, flag);
+ Func_Def def = import_fun(gwi->gwion->env, &gwi->func, flag);
CHECK_OB(def)
if(gwi->templater.n) {
def = new_func_def(NULL, NULL, NULL, NULL, 0);
def->tmpl = new_tmpl_list(list, -1);
SET_FLAG(def, template);
}
- if(gwi->env->class_def && GET_FLAG(gwi->env->class_def, template)) {
+ if(gwi->gwion->env->class_def && GET_FLAG(gwi->gwion->env->class_def, template)) {
Section* section = new_section_func_def(def);
Class_Body body = new_class_body(section, NULL);
gwi_body(gwi, body);
return GW_OK;
}
- if(traverse_func_def(gwi->env, def) < 0) {
+ if(traverse_func_def(gwi->gwion->env, def) < 0) {
free_func_def(def);
return GW_ERROR;
}
ANN m_int gwi_oper_end(const Gwi gwi, const Operator op, const f_instr f) {
gwi->oper.op = op;
- const m_bool ret = import_op(gwi->env, &gwi->oper, f);
+ const m_bool ret = import_op(gwi->gwion->env, &gwi->oper, f);
gwi->oper.ck = NULL;
gwi->oper.em = NULL;
return ret;
}
ANN m_int gwi_fptr_end(const Gwi gwi, const ae_flag flag) {
- const Stmt stmt = import_fptr(gwi->env, &gwi->func, flag);
+ const Stmt stmt = import_fptr(gwi->gwion->env, &gwi->func, flag);
- CHECK_BB(traverse_stmt_fptr(gwi->env, &stmt->d.stmt_fptr))
- if(gwi->env->class_def)
+ CHECK_BB(traverse_stmt_fptr(gwi->gwion->env, &stmt->d.stmt_fptr))
+ if(gwi->gwion->env->class_def)
SET_FLAG(stmt->d.stmt_fptr.func->def, builtin);
else
SET_FLAG(stmt->d.stmt_fptr.func, builtin);
ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type, const restrict m_str name) {
const Exp exp = make_exp(type, name);
CHECK_OB(exp);
- const Type t = type_decl_resolve(gwi->env, exp->d.exp_decl.td);
+ const Type t = type_decl_resolve(gwi->gwion->env, exp->d.exp_decl.td);
if(!t)
ERR_B(0, "type '%s' unknown in union declaration.", type)
if(isa(t, t_object) > 0)
ERR_B(0, "union is empty");
const Stmt stmt = new_stmt_union(gwi->union_data.list, 0);
stmt->d.stmt_union.flag = flag;
- CHECK_BB(traverse_stmt_union(gwi->env, &stmt->d.stmt_union))
+ CHECK_BB(traverse_stmt_union(gwi->gwion->env, &stmt->d.stmt_union))
emit_union_offset(stmt->d.stmt_union.l, stmt->d.stmt_union.o);
if(GET_FLAG((&stmt->d.stmt_union), member))
- gwi->env->class_def->nspc->info->offset =
+ gwi->gwion->env->class_def->nspc->info->offset =
stmt->d.stmt_union.o + stmt->d.stmt_union.s;
free_stmt(stmt);
gwi->union_data.list = NULL;
Value value = (Value)vector_at(v, i);
const m_uint addr = vector_at(&d->addr, i);
SET_FLAG(value, builtin);
- if(!gwi->env->class_def)
+ if(!gwi->gwion->env->class_def)
value->d.ptr = (m_uint*)(addr ? addr : i);
else
value->d.ptr = (m_uint*)(addr ? *(m_uint*)addr : i);
ANN m_int gwi_enum_end(const Gwi gwi) {
DL_Enum* d = &gwi->enum_data;
const Stmt stmt = new_stmt_enum(d->base, d->t ? insert_symbol(d->t) : NULL);
- if(traverse_stmt_enum(gwi->env, &stmt->d.stmt_enum) < 0) {
+ if(traverse_stmt_enum(gwi->gwion->env, &stmt->d.stmt_enum) < 0) {
free_id_list(d->base);
return GW_ERROR;
}
free_stmt(stmt);
return GW_OK;
}
+
+ANN void register_freearg(const Gwi gwi, const f_instr _exec, void(*_free)(const Instr, void*)) {
+ map_set(&gwi->gwion->freearg, (vtype)_exec, (vtype)_free);
+}
\ No newline at end of file
#include "object.h"
#include "array.h"
#include "memoize.h"
+#include "gwion.h"
+#include "import.h"
-ANN static void free_code_instr_gack(const Instr instr, void *gwion) {
- const Vector v = (Vector)instr->m_val2;
- for(m_uint i = vector_size(v) + 1; --i;)
- REM_REF(((Type)vector_at(v, i - 1)), gwion);
- free_vector(v);
-}
-
-ANN static void free_array_info(ArrayInfo* info, void *gwion) {
- REM_REF((Type)vector_back(&info->type), gwion);
- vector_release(&info->type);
- mp_free(ArrayInfo, info);
-}
-
-ANN static void free_code_instr(const Vector v, void *gwion) {
+ANN static void free_code_instr(const Vector v, const Gwion gwion) {
for(m_uint i = vector_size(v) + 1; --i;) {
const Instr instr = (Instr)vector_at(v, i - 1);
- if(instr->opcode == eSporkIni || instr->opcode == eForkIni)
- REM_REF((VM_Code)instr->m_val, gwion)
- else if(instr->execute == ArrayAlloc)
- free_array_info((ArrayInfo*)instr->m_val, gwion);
- else if(instr->opcode == (m_uint)Gack)
- free_code_instr_gack(instr, gwion);
- else if(instr->execute == BranchSwitch)
- free_map((Map)instr->m_val2);
- else if(instr->execute == DotTmpl) {
- struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
- free_type_list(dt->tl);
- mp_free(dottmpl, dt);
- }
- else if(instr->execute == SwitchIni) {
- free_vector((Vector)instr->m_val);
- free_map((Map)instr->m_val2);
- } else if(instr->execute == VarargIni) {
- if(instr->m_val2)
- free_vector((Vector)instr->m_val2);
- }
+ const f_freearg f = (f_freearg)(map_get(&gwion->freearg, instr->opcode) ?:
+ map_get(&gwion->freearg, (vtype)instr->execute));
+ if(f)
+ f(instr, gwion);
mp_free(Instr, instr);
}
free_vector(v);
#endif
if(!GET_FLAG(a, builtin))
free_code_instr(a->instr, gwion);
- free(a->name);
+ xfree(a->name);
mp_free(VM_Code, a);
}