eRegAddRef,
eObjectAssign,
eObjectRelease,
+ eGWOP_EXCEPTBASE,
eGWOP_EXCEPT,
eAllocMember4,
eDotMember,
#define RegAddRef (f_instr)eRegAddRef
#define ObjectAssign (f_instr)eObjectAssign
#define ObjectRelease (f_instr)eObjectRelease
+#define GWOP_EXCEPTBASE (f_instr)eGWOP_EXCEPTBASE
#define GWOP_EXCEPT (f_instr)eGWOP_EXCEPT
#define AllocMember4 (f_instr)eAllocMember4
#define DotMember (f_instr)eDotMember
m_str name;
Vector args;
MemPool mp;
- VM_Code orig;
};
struct ShredTick_ {
RegAddRef
ObjectAssign
ObjectRelease
+GWOP_EXCEPTBASE
GWOP_EXCEPT
AllocMember4
DotMember
const m_uint is_var = exp_self(array)->emit_var;
const m_uint depth = get_depth(array->base->type) - exp_self(array)->type->array_depth;
CHECK_BB(emit_exp(emit, array->base, 0))
- emit_add_instr(emit, GcAdd);
CHECK_BB(emit_exp(emit, array->array->exp, 0))
const Instr pop = emit_add_instr(emit, RegPop);
pop->m_val = depth * SZ_INT;
- emit_add_instr(emit, GWOP_EXCEPT);
+ emit_add_instr(emit, GWOP_EXCEPTBASE);
for(m_uint i = 0; i < depth - 1; ++i) {
const Instr access = emit_add_instr(emit, ArrayAccess);
access->m_val = i;
ANN static m_bool emit_class_def(const Emitter, const Class_Def);
-ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) {
+ANN static m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) {
const Type t = typedef_base(decl->type);
- return !GET_FLAG(t, emit) ? emit_class_def(emit, t->e->def) : GW_OK;
+ if(!GET_FLAG(t, emit)) {
+ CHECK_BB(template_push_types(emit->env, t->e->def->tmpl->list.list, t->e->def->tmpl->base))
+ CHECK_BB(emit_class_def(emit, t->e->def))
+ emit_pop_type(emit);
+ }
+ return GW_OK;
}
ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
instr->m_val = (instr->m_val2 = i) + member;
++prelude->m_val2;
}
- }
- exec = Overflow;
+ exec = Overflow;
+ } else
+ exec = Next;
if(memoize)
memoize->m_val = prelude->m_val2 + 1;
return emit_add_instr(emit, exec);
(m_bit*)xcalloc(1, stmt->value->type->nspc->info->class_data_size);
stmt->value->type->nspc->info->offset = stmt->s;
Type_Decl *type_decl = new_type_decl(emit->gwion->mp,
- new_id_list(emit->gwion->mp, stmt->xid, loc_cpy(emit->gwion->mp, stmt_self(stmt)->pos)),
+ new_id_list(emit->gwion->mp, stmt->xid, loc_cpy(emit->gwion->mp, loc_cpy(emit->gwion->mp, stmt_self(stmt)->pos))),
// emit->env->class_def ? ae_flag_member : 0);
stmt->flag);
//if(emit->env->class_def && !GET_FLAG(stmt, static))
SET_FLAG(stmt->l->self->d.exp_decl.list->self->value, enum);
}
if(stmt->xid){
- const Instr instr = emit_add_instr(emit, RegPop);
- instr->m_val = !GET_FLAG(stmt, static) ? SZ_INT : SZ_INT*2;
+ const Instr instr = emit_add_instr(emit, RegPop);
+ instr->m_val = !GET_FLAG(stmt, static) ? SZ_INT : SZ_INT*2;
}
emit_union_offset(stmt->l, stmt->o);
if(stmt->xid || stmt->type_xid || global)
ERR_O(td_pos(decl->td), "can't infer type.");
if(GET_FLAG(decl->type , template)) {
const Type t = typedef_base(decl->type);
- if(!GET_FLAG(t, check))
- CHECK_BO(traverse_template(env, t->e->def))
+ CHECK_BO(traverse_template(env, t->e->def))
}
const m_bool global = GET_FLAG(decl->td, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
const Exp args = exp->args;
const Type_List types = exp->tmpl->types;
Func m_func = exp->m_func, former = env->func;
-if(types->td->types)exit(12);
const m_str tmpl_name = tl2str(env, types);
const m_uint sz = vector_size((Vector)env->curr->info->type);
const m_uint scope = env_push(env, v->owner_class, v->owner);
const Type t = class_def->base.type->e->parent->array_depth ?
array_base(class_def->base.type->e->parent) : class_def->base.type->e->parent;
if(!GET_FLAG(t, checked)) {
-// if(class_def->tmpl)
-// CHECK_BB(template_push_types(env, class_def->tmpl->list.list, class_def->tmpl->base))
+ if(class_def->tmpl)
+ CHECK_BB(template_push_types(env, class_def->tmpl->list.list, class_def->tmpl->base))
CHECK_BB(traverse_template(env, t->e->def))
-// if(class_def->tmpl)
-// nspc_pop_type(env->gwion->mp, env->curr);
+ if(class_def->tmpl)
+ nspc_pop_type(env->gwion->mp, env->curr);
}
}
if(!GET_FLAG(class_def->base.type->e->parent, checked))
ANN m_bool check_class_def(const Env env, const Class_Def class_def) {
if(tmpl_class_base(class_def->tmpl))
return GW_OK;
- if(class_def->base.type->e->parent == t_undefined) {
+ if(class_def->base.type->e->parent == t_undefined) {
class_def->base.type->e->parent = check_td(env, class_def->base.ext);
return traverse_class_def(env, class_def);
}
const ae_flag flag = base->e->def ? base->e->def->flag : 0;
const Class_Def cdef = new_class_def(env->gwion->mp, flag, stmt->xid, stmt->ext, NULL,
loc_cpy(env->gwion->mp, td_pos(stmt->ext)));
-//const Type parent = known_type(env, stmt->ext);
-//if(!parent->array_depth && !GET_FLAG(parent, builtin) && !GET_FLAG(parent, scan0)) {
-//puts(parent->name);
-//exit(9);
-//}
-//printf("%p\n", stmt->ext->types);exit(6);
-//if(stmt->ext->types)
-// cdef->tmpl = new_tmpl_class(, $2, -1);
CHECK_BB(scan0_class_def(env, cdef))
stmt->type = cdef->base.type;
}
ANN static Type union_type(const Env env, const Nspc nspc, const Symbol s, const m_bool add) {
const m_str name = s_name(s);
const Type t = type_copy(env->gwion->mp, t_union);
-//t->e->parent = t_union;
t->xid = ++env->scope->type_xid;
t->name = name;
t->nspc = new_nspc(env->gwion->mp, name);
(void)mk_class(env, cdef->base.type);
if(GET_FLAG(cdef, global))
env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
- SET_FLAG(cdef->base.type, scan0);
return GW_OK;
}
#include "vm.h"
#include "parse.h"
#include "traverse.h"
-#include "template.h"
ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
decl->base = t->e->def;
return decl->type = t;
}
-//#include "loc.h"
+
ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
Var_Decl_List list = decl->list;
ANN static m_bool scan2_class_parent(const Env env, const Class_Def cdef) {
const Type t = cdef->base.type->e->parent->array_depth ?
array_base(cdef->base.type->e->parent) : cdef->base.type->e->parent;
- if(!GET_FLAG(t, scan2) && GET_FLAG(cdef->base.ext, typedef)) {
+ if(!GET_FLAG(t, scan2) && GET_FLAG(cdef->base.ext, typedef))
CHECK_BB(scan2_class_def(env, t->e->def))
- }
if(cdef->base.ext->array)
CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
return GW_OK;
struct td_info {
Type_List tl;
- GwText text;
+ m_str str;
+ size_t len;
+ size_t cap;
};
+ANN static inline m_bool td_add(struct td_info* info, const char c) {
+ return *(info->str + info->len++ - 1) = c;
+}
+
+ANN static inline void td_check(struct td_info* info, const size_t len) {
+ if(info->len + len >= info->cap) {
+ while(info->len + len >= info->cap)
+ info->cap <<= 1;
+ info->str = (m_str)xrealloc(info->str, info->cap);
+ }
+}
+
ANEW ANN static m_str td2str(const Env env, const Type_Decl* td);
ANN static void td_info_run(const Env env, struct td_info* info) {
Type_List tl = info->tl;
do {
m_str name = td2str(env, tl->td);
- text_add(&info->text, name);
+ const size_t nlen = strlen(name);
+ td_check(info, nlen + !!tl->next);
+ strcpy(info->str + info->len -1, name);
+ info->len += nlen;
xfree(name);
- if(tl->next)
- text_add(&info->text, ",");
- } while((tl = tl->next));
+ } while((tl = tl->next) && td_add(info, ','));
}
ANEW ANN static m_str td2str(const Env env, const Type_Decl* td) {
m_uint depth = td->array ? td->array->depth : 0;
- const size_t len = id_list_len(td->xid) + depth * 2;
- const size_t cap = round2szint(len);
- struct td_info info = { td->types, { (m_str)xmalloc(cap), cap, len }};
- type_path(info.text.str, td->xid);
- while(depth--) { text_add(&info.text, "[]"); }
+ const size_t l = id_list_len(td->xid) + depth * 2;
+ struct td_info info = { td->types, (m_str)xmalloc(l), l, l };
+ type_path(info.str, td->xid);
+ while(depth--) { td_add(&info, '['); td_add(&info, ']'); }
Type_List tl = td->types;
if(tl) {
- text_add(&info.text, "<");
+ td_check(&info, 2);
+ td_add(&info, '<');
td_info_run(env, &info);
- text_add(&info.text, ">");
+ td_add(&info, '>');
}
- return info.text.str;
+ info.str[info.len - 1] = '\0';
+ return info.str;
}
ANEW ANN m_str tl2str(const Env env, Type_List tl) {
- struct td_info info = { .tl=tl };
+ struct td_info info = { tl, (m_str)xmalloc(32), 1, 32 };
td_info_run(env, &info);
- return info.text.str;
+ return info.str;
}
ANN static inline void* type_unknown(const Env env, const ID_List id) {
#include "object.h"
#include "driver.h"
#include "shreduler_private.h"
+#include "env.h" // unwind
+#include "gwion.h" // unwind
+#include "instr.h" // unwind
ANN void shreduler_set_loop(const Shreduler s, const m_bool loop) {
s->loop = loop > 0;
}
}
+ANN static void unwind(const VM_Shred shred) {
+ VM_Code code = shred->code;
+ while(code) {
+ if(shred->mem <= (((m_bit*)(shred) + sizeof(struct VM_Shred_) + SIZEOF_REG)))
+ break;
+ const m_bit exec = (m_bit)((Instr)vector_back(code->instr))->opcode;
+ if(exec == eFuncReturn) {
+ code = *(VM_Code*)(shred->mem - SZ_INT*3);
+ if(!GET_FLAG(code, op))
+ REM_REF(code, shred->info->vm->gwion)
+ shred->mem -= *(m_uint*)(shred->mem - SZ_INT*4) + SZ_INT*4;
+ } else break;
+ }
+ shred->code = code;
+}
+
ANN static inline void shreduler_child(const Vector v) {
for(m_uint i = vector_size(v) + 1; --i;) {
const VM_Shred child = (VM_Shred)vector_at(v, i - 1);
}
ANN static void shreduler_erase(const Shreduler s, struct ShredTick_ *tk) {
+ unwind(tk->self);
if(tk->parent)
shreduler_parent(tk->self, &tk->parent->child);
if(tk->child.ptr)
&&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat,
&&arrayappend, &&autoloop, &&autoloopptr, &&autoloopcount, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&arrayvalid,
&&newobj, &&addref, &&assign, &&remref,
- &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
+ &&exceptbase, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
&&staticint, &&staticfloat, &&staticother,
&&dotfunc, &&dotstaticfunc, &&staticcode, &&pushstr,
&&gcini, &&gcadd, &&gcend,
VM_Code code;
VM_Shred child;
} a;
+ register M_Object array_base = NULL;
MUTEX_LOCK(s->mutex);
do {
register Instr instr; DISPATCH();
*(m_uint*)(mem+instr->m_val) = *(m_uint*)(reg+instr->m_val2);
DISPATCH()
overflow:
- if(overflow_(mem + SZ_INT*8, shred)) {
- exception(shred, "StackOverflow");
- continue;
+ if(overflow_((shred->mem = mem), shred)) {
+PRAGMA_PUSH()
+// shred->code = a.code;
+ shred->mem = mem;
+PRAGMA_POP()
+ Except(shred, "StackOverflow");
}
next:
PRAGMA_PUSH()
{
const m_int idx = *(m_int*)(reg + SZ_INT * instr->m_val);
if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) {
+// should we go to except ? so we can remove release array_base
+ _release(array_base, shred);
gw_err("\t... at index [%" INT_F "]\n", idx);
gw_err("\t... at dimension [%" INT_F "]\n", instr->m_val);
shred->code = code;
*(m_bit**)(reg + (m_int)instr->m_val2) = m_vector_addr(ARRAY(a.obj), *(m_int*)(reg + SZ_INT * instr->m_val));
DISPATCH()
arrayvalid:
- vector_pop(&shred->gc);
+ array_base = NULL;
goto regpush;
newobj:
*(M_Object*)reg = new_object(vm->gwion->mp, shred, (Type)instr->m_val2);
remref:
release(*(M_Object*)(mem + instr->m_val), shred);
DISPATCH()
+exceptbase:
+ array_base = *(M_Object*)(reg-SZ_INT);
except:
if(!(a.obj = *(M_Object*)(reg-SZ_INT))) {
+ if(array_base) _release(array_base, shred);
+// shred->code = code;
+ shred->mem = mem;
exception(shred, "NullPtrException");
continue;
}
shred->reg = (m_bit*)shred + sizeof(struct VM_Shred_);
shred->base = shred->mem = shred->reg + SIZEOF_REG;
shred->info = new_shredinfo(p, c->name);
- shred->info->orig = c;
vector_init(&shred->gc);
return shred;
}
for(m_uint i = vector_size(&shred->gc) + 1; --i;)
release((M_Object)vector_at(&shred->gc, i - 1), shred);
vector_release(&shred->gc);
- REM_REF(shred->info->orig, shred->info->vm->gwion);
+ REM_REF(shred->code, shred->info->vm->gwion);
MemPool mp = shred->info->mp;
mp_free(mp, ShredTick, shred->tick);
free_shredinfo(mp, shred->info);