ANN void shreduler_add(const Shreduler s, const VM_Shred shred);
ANEW ANN VM_Shred new_vm_shred(MemPool, const VM_Code code) __attribute__((hot));
+ANEW ANN VM_Shred new_shred_base(const VM_Shred, const VM_Code code) __attribute__((hot));
__attribute__((hot))
ANN static inline void vm_shred_exit(const VM_Shred shred) { shreduler_remove(shred->info->vm->shreduler, shred, 1); }
void free_vm_shred(const VM_Shred shred)__attribute__((hot, nonnull));
INSTR(EOC) {
vm_shred_exit(shred);
}
-#include "gwion.h"
+
INSTR(DTOR_EOC) {
- // TODO: we should be able to use shred->info->mp directly
- shred->info->mp = (MemPool)instr->m_val;
const M_Object o = *(M_Object*)MEM(0);
o->type_ref = o->type_ref->parent;
__release(o, shred);
ANN static void handle_dtor(const M_Object o, const VM_Shred shred) {
const VM_Shred sh = new_vm_shred(shred->info->mp, o->type_ref->nspc->dtor);
+ ADD_REF(o->type_ref->nspc->dtor);
sh->base = shred->base;
*(M_Object*)sh->mem = o;
vm_add_shred(shred->info->vm, sh);
#define FORK_RETVAL(o) (o->data + o_fork_retval)
#define FORK_ORIG(o) (*(VM**)((o)->data + o_fork_orig))
+VM_Shred new_shred_base(const VM_Shred shred, const VM_Code code) {
+ const VM_Shred sh = new_vm_shred(shred->info->mp, code);
+ ADD_REF(code)
+ sh->base = shred->base;
+ return sh;
+}
+
M_Object new_shred(const VM_Shred shred, m_bool is_spork) {
const M_Object obj = new_object(shred->info->mp, NULL, is_spork ? t_shred : t_fork);
ME(obj) = shred;
static MFUN(gw_shred_exit) {
const VM_Shred s = ME(o);
+ s->mem -= SZ_INT;
vm_shred_exit(s);
}
CHECK_BB(gwi_item_end(gwi, ae_flag_member, NULL))
gwi_item_ini(gwi, "int", "cancel");
- CHECK_BB((o_shred_cancel = gwi_item_end(gwi, ae_flag_const, NULL)))
+ CHECK_BB((o_shred_cancel = gwi_item_end(gwi, 0, NULL)))
gwi_func_ini(gwi, "void", "exit", gw_shred_exit);
CHECK_BB(gwi_func_end(gwi, 0))
#include "instr.h" // unwind
ANN void shreduler_set_loop(const Shreduler s, const m_bool loop) {
- s->loop = loop < 0 ? 0 : 1;
+ s->loop = loop > 0;
}
ANN VM_Shred shreduler_get(const Shreduler s) {
- Driver *bbq = s->bbq;
- struct ShredTick_ *tk = s->list;
+ Driver *const bbq = s->bbq;
+ struct ShredTick_ *const tk = s->list;
if(!tk) {
if(!vector_size(&s->shreds) && !s->loop)
bbq->is_running = 0;
return NULL;
}
- const m_float time = (m_float)bbq->pos + (m_float).5;
+ const m_float time = (m_float)bbq->pos + (m_float)GWION_EPSILON;
if(tk->wake_time <= time) {
if((s->list = tk->next))
s->list->prev = NULL;
while(code) {
const m_bit exec = (m_bit)((Instr)vector_back(code->instr))->opcode;
if(exec == eFuncReturn) {
- if(GET_FLAG(code, op))
- code = *(VM_Code*)(shred->mem - SZ_INT);
- else {
- if(GET_FLAG(code, ctor))
- code = *(VM_Code*)(shred->mem - SZ_INT*2);
- else
- code = *(VM_Code*)(shred->mem - SZ_INT*3);
+ 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;
if(shred->mem <= (((m_bit*)(shred) + sizeof(struct VM_Shred_) + SIZEOF_REG)))break;
} else break;
}
ANN void shreduler_add(const Shreduler s, const VM_Shred shred) {
-// create shred->tick here ?
+ shred->tick = mp_alloc(shred->info->mp, ShredTick);
+ shred->tick->self = shred;
shred->tick->shreduler = s;
shred->tick->xid = ++s->shred_ids;
vector_add(&s->shreds, (vtype)shred);
}
ANN static inline VM_Shred init_spork_shred(const VM_Shred shred, const Instr instr) {
- const VM_Code code = (VM_Code)instr->m_val;
- const VM_Shred sh = new_vm_shred(shred->info->mp, code);
- ADD_REF(code)
+ const VM_Shred sh = new_shred_base(shred, (VM_Code)instr->m_val);
+ vm_add_shred(shred->info->vm, sh);
sh->tick->parent = shred->tick;
if(!shred->tick->child.ptr)
vector_init(&shred->tick->child);
vector_add(&shred->tick->child, (vtype)sh);
- sh->base = shred->base;
- vm_add_shred(shred->info->vm, sh);
return sh;
}
ANN static inline VM_Shred init_fork_shred(const VM_Shred shred, const Instr instr) {
- const VM_Code code = (VM_Code)instr->m_val;
- const VM_Shred sh = new_vm_shred(shred->info->mp, code);
- ADD_REF(code)
- sh->base = shred->base;
+ const VM_Shred sh = new_shred_base(shred, (VM_Code)instr->m_val);
vm_fork(shred->info->vm, sh);
return sh;
}
*(m_uint*)(mem+instr->m_val) = *(m_uint*)(reg+instr->m_val2);
DISPATCH()
overflow:
- if(overflow_(mem, shred))
+ if(overflow_((shred->mem = mem), shred)) {
+shred->code = a.code;
Except(shred, "StackOverflow");
+ }
next:
PRAGMA_PUSH()
goto *dispatch[next];
_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;
+ shred->mem = mem;
exception(shred, "ArrayOutofBounds");
continue;
}
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->code = c;
shred->reg = (m_bit*)shred + sizeof(struct VM_Shred_);
shred->base = shred->mem = shred->reg + SIZEOF_REG;
- shred->tick = mp_alloc(p, ShredTick);
- shred->tick->self = shred;
shred->info = new_shredinfo(p, c->name);
vector_init(&shred->gc);
return shred;