mpdm_t mpsl_mkins(wchar_t * opcode, int args, mpdm_t a1, mpdm_t a2, mpdm_t a3, mpdm_t a4) /* creates an instruction */ { mpdm_t o; mpdm_t v; v = MPDM_A(args + 1); mpdm_ref(v); /* inserts the opcode */ o = mpdm_hget_s(mpsl_opcodes, opcode); mpdm_aset(v, o, 0); switch (args) { case 4: mpdm_aset(v, a4, 4); /* no break */ case 3: mpdm_aset(v, a3, 3); /* no break */ case 2: mpdm_aset(v, a2, 2); /* no break */ case 1: mpdm_aset(v, a1, 1); /* no break */ } mpdm_unrefnd(v); v = constant_fold(v); return v; }
O_TYPE mpsl_exec_i(O_ARGS) /* Executes one MPSL instruction in the MPSL virtual machine. Called from mpsl_exec_p() (which holds the flow control status variable) */ { mpdm_t ret = NULL; mpdm_ref(c); mpdm_ref(a); mpdm_ref(l); /* if aborted or NULL, do nothing */ if (!mpsl_abort && c != NULL) { /* gets the opcode and calls it */ ret = op_table[mpdm_ival(C0)].func(c, a, l, f); if (mpsl_trap_func != NULL) { mpdm_t f = mpsl_trap_func; mpdm_ref(ret); mpsl_trap_func = NULL; mpdm_exec_3(f, c, a, ret, l); mpsl_trap_func = f; mpdm_unrefnd(ret); } } mpdm_unref(l); mpdm_unref(a); mpdm_unref(c); return ret; }
/** argn = push(a, arg1 [, arg2, ... argn]); */ static mpdm_t F_push(F_ARGS) { int n; mpdm_t r = NULL; for (n = 1; n < mpdm_size(a); n++) { mpdm_unref(r); r = mpdm_push(A0, A(n)); mpdm_ref(r); } return mpdm_unrefnd(r); }
int mpdm_iterator_o(mpdm_t set, int *context, mpdm_t *v, mpdm_t *i) /* do not use it; use mpdm_iterator() */ { int ret = 0; mpdm_ref(set); if (mpdm_size(set)) { int bi, ei; /* get bucket and element index */ bi = (*context) % mpdm_size(set); ei = (*context) / mpdm_size(set); while (ret == 0 && bi < mpdm_size(set)) { mpdm_t b; /* if bucket is empty or there are no more elements in it, pick the next one */ if (!(b = mpdm_get_i(set, bi)) || ei >= mpdm_size(b)) { ei = 0; bi++; } else { /* get pair */ if (v) *v = mpdm_get_i(b, ei + 1); if (i) *i = mpdm_get_i(b, ei); ei += 2; /* update context */ *context = (ei * mpdm_size(set)) + bi; ret = 1; } } } mpdm_unrefnd(set); return ret; }
mpdm_t mpsl_build_opcodes(void) /* builds the table of opcodes */ { int n; mpdm_t r = MPDM_H(0); mpdm_ref(r); for (n = 0; op_table[n].name != NULL; n++) { mpdm_t v = MPDM_LS(op_table[n].name); mpdm_set_ival(v, n); /* keys and values are the same */ mpdm_hset(r, v, v); } mpdm_unrefnd(r); return r; }