-Subproject commit b26e47f2eb001944c922d5b406ef03ae3e229782
+Subproject commit 54f6475d7a9686929d553695180bb6bd0be262bf
struct Vector_ lib;
struct Vector_ config;
struct SoundInfo_ *si;
- m_bool loop;
- m_bool quit : 1;
+ bool loop;
+ bool quit;
enum COLOR color;
} Arg;
struct ArrayAccessInfo {
struct Array_Sub_ array;
const Type type;
- const m_bool is_var;
+ const bool is_var;
};
typedef struct M_Vector_ {
f_bbqset func;
f_bbqrun run;
struct DriverData_* driver;
- volatile uint is_running;
+ volatile bool is_running;
} Driver;
#define DRVINI(a) ANN m_bool a(struct VM_ *vm NUSED, Driver* di NUSED)
m_str name;
Ast tree;
Nspc nspc;
- m_bool error;
- m_bool global;
+ bool error;
+ bool global;
uint16_t ref;
};
const void *data;
const m_int scope;
const enum tflag flag;
- m_bool run;
+ bool run;
};
ANN m_bool envset_run(struct EnvSet*, const Type);
tflag_dtor = 1 << 14,
tflag_tmpl = 1 << 15,
tflag_typedef = 1 << 16,
+ tflag_distinct = 1 << 17,
} __attribute__((packed));
struct Type_ {
struct Vector_ shreds;
MUTEX_TYPE mutex;
size_t shred_ids;
- m_bool loop;
+ bool loop;
};
#endif
idck ck;
f_instr exec;
idem em;
- m_bool is_const;
+ bool is_const;
};
#define ID_CHECK(a) ANN Type a(const Env env NUSED, const Exp_Primary* prim NUSED)
};
size_t stack_depth;
Type ret_type; // could be `struct Vector_ tmpl_types;`
- void* memoize;
- Closure *closure;
+ union {
+ void* memoize;
+ Closure *closure;
+ };
m_str name;
uint16_t ref;
ae_flag flag;
bool builtin;
bool callback;
+ bool is_memoize;
};
typedef struct Shreduler_* Shreduler;
ANN ANEW VM_Code vmcode_callback(MemPool p, const VM_Code code);
ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot));
-ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool erase)__attribute__((hot));
+ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const bool erase)__attribute__((hot));
ANN void shredule(const Shreduler s, const VM_Shred shred, const m_float wake_time)__attribute__((hot));
-ANN void shreduler_set_loop(const Shreduler s, const m_bool loop);
+ANN void shreduler_set_loop(const Shreduler s, const bool loop);
ANN void shreduler_ini(const Shreduler s, const VM_Shred shred);
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); }
+ANN static inline void vm_shred_exit(const VM_Shred shred) { shreduler_remove(shred->info->vm->shreduler, shred, true); }
void free_vm_shred(const VM_Shred shred)__attribute__((hot, nonnull));
ANN void vm_run(const VM* vm) __attribute__((hot));
-ANEW VM* new_vm(MemPool, const m_bool);
+ANEW VM* new_vm(MemPool, const bool);
ANN void vm_lock(VM const*);
ANN void vm_unlock(VM const*);
-ANN m_bool vm_running(VM const*);
+ANN bool vm_running(VM const*);
ANN void free_vm(VM* vm);
ANN void vm_ini_shred(const VM* vm, const VM_Shred shred)__attribute__((hot));
ANN void vm_add_shred(const VM* vm, const VM_Shred shred)__attribute__((hot));
ANN void vm_remove(const VM* vm, const m_uint index)__attribute__((hot));
ANN m_str code_name_set(MemPool p, const m_str, const m_str);
-ANN m_str code_name(const m_str, const m_bool);
+ANN m_str code_name(const m_str, const bool);
ANN uint32_t gw_rand(uint32_t s[2]);
ANN void gw_seed(uint32_t s[2], const uint64_t);
#endif
config_parse(arg_int, option->value);
break;
case 'l':
- _arg->loop = (m_bool)ARG2INT(option->value) > 0 ? 1 : -1;
+ _arg->loop = ARG2INT(option->value) > 0 ? true : false;
break;
case 'g':
arg_set_pass(arg_int->gwion, option->value);
f->code = finalyze(emit, FuncReturn);
return emit->env->class_def->info->gack = f->code;
}
- return finalyze(emit, FuncReturn);
+ const VM_Code code = finalyze(emit, FuncReturn);
+ if(emit->info->memoize && fflag(emit->env->func, fflag_pure))
+ code->is_memoize = true;
+ return code;
}
ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
ANN VM* gwion_cpy(const VM* src) {
const Gwion gwion = mp_calloc(src->gwion->mp, Gwion);
- gwion->vm = new_vm(src->gwion->mp, 0);
+ gwion->vm = new_vm(src->gwion->mp, false);
gwion->vm->gwion = gwion;
gwion->vm->bbq->si = soundinfo_cpy(src->gwion->mp, src->bbq->si);
gwion->emit = src->gwion->emit;
}
ANN static void gwion_core(const Gwion gwion) {
- gwion->vm = new_vm(gwion->mp, 1);
+ gwion->vm = new_vm(gwion->mp, true);
gwion->emit = new_emitter(gwion->mp);
gwion->env = new_env(gwion->mp);
gwion->emit->env = gwion->env;
static INSTR(EventWait) {
POP_REG(shred, SZ_FLOAT);
const M_Object event = *(M_Object*)REG(-SZ_INT);
- shreduler_remove(shred->tick->shreduler, shred, 0);
+ shreduler_remove(shred->tick->shreduler, shred, false);
const Vector v = &EV_SHREDS(event);
vector_add(v, (vtype)shred);
*(m_int*)REG(-SZ_INT) = 1;
const Fptr_Def fptr_def = new_fptr_def(env->gwion->mp, fbase);
char name[13 + strlen(env->curr->name) +
num_digit(bin->rhs->pos.first.line) + num_digit(bin->rhs->pos.first.column)];
+ sprintf(name, "generated@%s@%u:%u", env->curr->name, bin->rhs->pos.first.line, bin->rhs->pos.first.column);
fptr_def->base->xid = insert_symbol(name);
const m_bool ret = traverse_fptr_def(env, fptr_def);
const Type t = fptr_def->type;
}
static INSTR(UURet) {
- shreduler_remove(shred->tick->shreduler, shred, 0);
+ shreduler_remove(shred->tick->shreduler, shred, false);
}
ANN static void code_prepare(const VM_Code code) {
const VM_Shred s = ME(o);
const Shreduler sh = s->tick->shreduler;
if(s != shred)
- shreduler_remove(sh, s, 0);
+ shreduler_remove(sh, s, false);
shredule(sh, s, GWION_EPSILON);
}
static MFUN(fork_join) {
if(*(m_int*)(o->data + o_fork_done))
return;
- shreduler_remove(shred->tick->shreduler, shred, 0);
+ shreduler_remove(shred->tick->shreduler, shred, false);
vector_add(&EV_SHREDS(*(M_Object*)(o->data + o_fork_ev)), (vtype)shred);
}
#endif
int main(int argc, char** argv) {
- Arg arg = { .arg={.argc=argc, .argv=argv}, .loop=-1 };
+ Arg arg = { .arg={.argc=argc, .argv=argv}, .loop=false };
signal(SIGINT, sig);
signal(SIGTERM, sig);
struct Gwion_ gwion = {};
gwerr_basic(_("Invalid variable"), _("not legit at this point."), NULL,
env->name, prim_pos(data), 0);
did_you_mean_nspc(v ? value_owner(env, v) : env->curr, s_name(sym));
- env->context->error++;
+ env->context->error = true;
return NULL;
}
prim_self(data)->value = v;
sprintf(from, "in `{/+}%s{0}` definition", tdef->type->name);
gwerr_secondary(from, env->name, tdef->pos);
if(env->context)
- env->context->error++;
+ env->context->error = true;
return GW_ERROR;
}
/*
static inline void context_global(const Env env) {
if(env->context)
- env->context->global = 1;
+ env->context->global = true;
}
static inline Type scan0_type(const Env env, const m_str name, const Type t) {
const Type t = scan0_type(env, s_name(tdef->xid), base);
t->size = base->size;
const Nspc nspc = (!env->class_def && GET_FLAG(tdef->ext, global)) ?
- env->global_nspc : env->curr;
+ env->global_nspc : env->curr;
if(GET_FLAG(tdef->ext, global))
context_global(env);
add_type(env, nspc, t);
tdef->type = t;
- if(base->nspc)
+ if(base->nspc) // create a new nspc if `distinct`?
nspc_addref((t->nspc = base->nspc));
t->flag = tdef->ext->flag;
if(tdef->ext->array && !tdef->ext->array->exp)
typedef_fptr(env, tdef, base);
if(!tdef->distinct && !tdef->when)
scan0_implicit_similar(env, tdef->type, base);
+ if(tdef->distinct)
+ set_tflag(tdef->type, tflag_distinct);
if(global)
env_pop(env, 0);
set_tflag(tdef->type, tflag_typedef);
CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
CHECK_OB(decl->type)
- const m_bool global = GET_FLAG(decl->td, global);
+ const bool global = GET_FLAG(decl->td, global);
if(global) {
if(env->context)
- env->context->global = 1;
+ env->context->global = true;
if(!is_global(decl->type->info->value->from->owner, env->global_nspc))
ERR_B(exp_self(decl)->pos, _("type '%s' is not global"), decl->type->name)
}
}
ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) {
- const uint global = GET_FLAG(fdef->base, global);
+ const bool global = GET_FLAG(fdef->base, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
if(fdef->base->td)
CHECK_BB(env_storage(env, fdef->base->flag, fdef->base->td->pos))
}
ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) {
- const m_bool global = GET_FLAG(decl->td, global);
+ const bool global = GET_FLAG(decl->td, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
const m_bool ret = scan2_decl(env, decl);
if(global)
ANN static m_bool scan2_args(const Func_Def f) {
Arg_List list = f->base->args;
- const uint global = GET_FLAG(f->base, global);
+ const bool global = GET_FLAG(f->base, global);
do {
const Value v = list->var_decl->value;
v->from->offset = f->stack_depth;
#include "driver.h"
#include "shreduler_private.h"
-ANN void shreduler_set_loop(const Shreduler s, const m_bool loop) {
- s->loop = loop > 0;
+ANN void shreduler_set_loop(const Shreduler s, const bool loop) {
+ s->loop = loop;
}
ANN VM_Shred shreduler_get(const Shreduler s) {
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);
- shreduler_remove(child->info->vm->shreduler, child, 1);
+ shreduler_remove(child->info->vm->shreduler, child, true);
}
}
vector_rem2(&s->shreds, (vtype)tk->self);
}
-ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool erase) {
+ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const bool erase) {
MUTEX_LOCK(s->mutex);
struct ShredTick_ *tk = out->tick;
if(tk == s->curr)
while((vm = vm->parent));
}
-ANN m_bool vm_running(VM const *vm) {
+ANN bool vm_running(VM const *vm) {
if(!vm->shreduler->bbq->is_running)
return 0;
if(!vm->parent)
vm_ugen_init(vm);
}
-VM* new_vm(MemPool p, const m_bool audio) {
+VM* new_vm(MemPool p, const bool audio) {
VM* vm = (VM*)mp_calloc(p, VM);
vector_init(&vm->ugen);
vm->bbq = new_driver(p);
}
ANN void free_vmcode(VM_Code a, Gwion gwion) {
- if(a->memoize)
- memoize_end(gwion->mp, a->memoize);
if(!a->builtin) {
_mp_free(gwion->mp, vector_size(a->instr) * BYTECODE_SZ, a->bytecode);
if(likely(!a->callback)) {
- if(a->closure)
- free_closure(a->closure, gwion);
+ if(a->closure) {
+ if(!a->is_memoize)
+ free_closure(a->closure, gwion);
+ else
+ memoize_end(gwion->mp, a->memoize);
+ }
free_code_instr(a->instr, gwion);
}
free_vector(gwion->mp, a->instr);