ANN static m_bool emit_prim_perform(const Emitter emit, const Symbol *xid) {
const Instr instr = emit_add_instr(emit, PerformEffect);
- instr->m_val = (m_uint)s_name(*xid);
+ if(*xid) instr->m_val = (m_uint)s_name(*xid);
+ instr->m_val2 = emit->status.effect;
return GW_OK;
}
ANN static inline m_bool emit_handler_list(const restrict Emitter emit,
const Handler_List handlers,
const Vector v) {
+ emit_push_scope(emit);
+ const m_uint offset = emit_local(emit, emit->gwion->type[et_int]);
for(uint32_t i = 0; i < handlers->len; i++) {
Handler *handler = mp_vector_at(handlers, Handler, i);
+ // useless args. should be not in the VM
const Instr instr = emit_add_instr(emit, HandleEffect);
- instr->m_val2 = (m_uint)handler->xid;
+ instr->m_val = emit->status.effect = offset;
+ instr->m_val2 = (m_uint)handler->xid; // are we even using this?
CHECK_BB(scoped_stmt(emit, handler->stmt, 1));
emit_try_goto(emit, v);
instr->m_val = emit_code_size(emit);
}
+// emit->status.effect = 0;
+ emit_pop_scope(emit);
return GW_OK;
}
}
ANN static Type check_prim_perform(const Env env, const Symbol *data) {
- env_add_effect(env, *data, prim_pos(data));
+ if(*data) env_add_effect(env, *data, prim_pos(data));
+ else if(!env->scope->in_try)
+ ERR_O(prim_pos(data), "`rethrow` outside try/handle statement");
env_weight(env, 1);
return env->gwion->type[et_void];
}
ANN static inline m_bool check_handler_list(const restrict Env env,
const Handler_List handlers) {
+ const bool in_try = env->scope->in_try;
+ env->scope->in_try = true;
for(uint32_t i = 0; i < handlers->len; i++) {
Handler *handler = mp_vector_at(handlers, Handler, i);
CHECK_BB(check_handler(env, handler));
}
+ env->scope->in_try = in_try;
return GW_OK;
}
for(uint32_t i = 0; i < handlers->len; i++) {
Handler *handler = mp_vector_at(handlers, Handler, i);
if(xid == handler->xid) return true;
+ if(!handler->xid) return true;
}
return false;
}
RET_NSPC(check_stmt(env, stmt->stmt))
}
-ANN static inline m_bool _check_stmt_try(const restrict Env env, const Stmt_Try stmt) {
+ANN static inline m_bool check_stmt_try(const restrict Env env, const Stmt_Try stmt) {
CHECK_BB(check_handler_list(env, stmt->handler));
vector_add(&env->scope->effects, 0);
const m_bool ret = check_stmt_try_start(env, stmt);
return ret;
}
-ANN static inline m_bool check_stmt_try(const restrict Env env,
- const Stmt_Try stmt) {
- const bool in_try = env->scope->in_try;
- const m_bool ret = _check_stmt_try(env, stmt);
- env->scope->in_try = in_try;
- return ret;
-}
-
ANN static m_bool _check_stmt_match(const Env env, const Stmt_Match stmt) {
CHECK_OB(check_exp(env, stmt->cond));
MATCH_INI(env->scope)
(m_bit *)VPTR(&shred->info->frame, VLEN(&shred->info->frame) - 1);
shredule(shred->tick->shreduler, shred, 0);
shred->pc = pc; // VKEY(m, i);
+ const Instr instr = vector_at(&shred->code->instr, pc);
+ if(!instr->m_val)
+ *(m_uint*)(shred->mem + instr->m_val2) = s_name(effect);
+
vector_pop(&shred->info->frame);
vector_pop(&shred->info->frame);
return true;
// this should check the *xid* of the exception
DISPATCH();
performeffect:
-// VM_OUT
- handle(shred, (m_str)VAL);
+{
+ const m_str effect = (m_str)VAL ?: *(m_str*)(mem + VAL2);
+ handle(shred, effect);
+}
break;
noop:
DISPATCH();