From: Jérémie Astor Date: Thu, 5 Dec 2019 17:01:08 +0000 (+0100) Subject: :art: init_fork_shred can fail X-Git-Tag: nightly~2070^2~7 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=6cee2bd4a489bc0366c058c817a0670c96aa55c4;p=gwion.git :art: init_fork_shred can fail --- diff --git a/src/vm/vm.c b/src/vm/vm.c index f251ca8a..9c8c4acc 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -87,18 +87,14 @@ ANN m_bool vm_running(VM *vm) { } ANN static void vm_fork(VM* src, const VM_Shred shred) { - vm_lock(src); - if(vm_running(src)) { - VM* vm = (shred->info->vm = gwion_cpy(src)); - vm->parent = src; - const M_Object o = shred->info->me = new_shred(shred, 0); - ++shred->info->me->ref; - if(!src->gwion->data->child.ptr) - vector_init(&src->gwion->data->child); - vector_add(&src->gwion->data->child, (vtype)o); - shreduler_add(vm->shreduler, shred); - } - vm_unlock(src); + VM* vm = (shred->info->vm = gwion_cpy(src)); + vm->parent = src; + const M_Object o = shred->info->me = new_shred(shred, 0); + ++shred->info->me->ref; + if(!src->gwion->data->child.ptr) + vector_init(&src->gwion->data->child); + vector_add(&src->gwion->data->child, (vtype)o); + shreduler_add(vm->shreduler, shred); } __attribute__((hot)) @@ -143,12 +139,20 @@ ANN static inline VM_Shred init_spork_shred(const VM_Shred shred, const VM_Code return sh; } -ANN static inline VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code) { +ANN static inline VM_Shred fork_shred(const VM_Shred shred, const VM_Code code) { const VM_Shred sh = new_shred_base(shred, code); vm_fork(shred->info->vm, sh); return sh; } +ANN static inline VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code) { + VM *vm = shred->info->vm; + vm_lock(vm); + const VM_Shred sh = vm_running(vm) ? fork_shred(shred, code) : NULL; + vm_unlock(vm); + return sh; +} + #define TEST0(t, pos) if(!*(t*)(reg-pos)){ shred->pc = PC; exception(shred, "ZeroDivideException"); break; } #define ADVANCE() byte += BYTECODE_SZ; @@ -655,7 +659,8 @@ funcmemberend: } PC_DISPATCH(shred->pc) sporkini: - a.child = (VAL2 ? init_spork_shred : init_fork_shred)(shred, (VM_Code)VAL); + if(!(a.child = (VAL2 ? init_spork_shred : init_fork_shred)(shred, (VM_Code)VAL))) + goto eoc; DISPATCH() sporkfunc: // LOOP_OPTIM