drop the whole cs_alias_internal nonsense
parent
f8eb07ee2b
commit
436098cc38
|
@ -417,9 +417,7 @@ bool cs_stacked_value::push() {
|
|||
if (!p_a) {
|
||||
return false;
|
||||
}
|
||||
cs_alias_internal::push_arg(
|
||||
static_cast<cs_alias_impl *>(p_a), *this, p_stack
|
||||
);
|
||||
static_cast<cs_alias_impl *>(p_a)->push_arg(*this, p_stack);
|
||||
p_pushed = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -428,7 +426,7 @@ bool cs_stacked_value::pop() {
|
|||
if (!p_pushed || !p_a) {
|
||||
return false;
|
||||
}
|
||||
cs_alias_internal::pop_arg(static_cast<cs_alias_impl *>(p_a));
|
||||
static_cast<cs_alias_impl *>(p_a)->pop_arg();
|
||||
p_pushed = false;
|
||||
return true;
|
||||
}
|
||||
|
|
43
src/cs_vm.cc
43
src/cs_vm.cc
|
@ -26,13 +26,13 @@ struct cs_cmd_internal {
|
|||
static inline void cs_push_alias(cs_state &cs, cs_ident *id, cs_ident_stack &st) {
|
||||
if (id->is_alias() && (id->get_index() >= MaxArguments)) {
|
||||
cs_value nv{cs};
|
||||
cs_alias_internal::push_arg(static_cast<cs_alias_impl *>(id), nv, st);
|
||||
static_cast<cs_alias_impl *>(id)->push_arg(nv, st);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cs_pop_alias(cs_ident *id) {
|
||||
if (id->is_alias() && (id->get_index() >= MaxArguments)) {
|
||||
cs_alias_internal::pop_arg(static_cast<cs_alias_impl *>(id));
|
||||
static_cast<cs_alias_impl *>(id)->pop_arg();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,8 +469,7 @@ static inline void cs_call_alias(
|
|||
cs_ivar *anargs = static_cast<cs_ivar *>(cs.p_state->identmap[NumargsIdx]);
|
||||
cs_valarray<cs_ident_stack, MaxArguments> argstack{cs};
|
||||
for(int i = 0; i < callargs; i++) {
|
||||
cs_alias_internal::push_arg(
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i]),
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i])->push_arg(
|
||||
args[offset + i], argstack[i], false
|
||||
);
|
||||
}
|
||||
|
@ -483,7 +482,7 @@ static inline void cs_call_alias(
|
|||
};
|
||||
cs.p_callstack = &aliaslink;
|
||||
uint32_t *codep = reinterpret_cast<uint32_t *>(
|
||||
cs_alias_internal::compile_code(static_cast<cs_alias_impl *>(a), cs)
|
||||
static_cast<cs_alias_impl *>(a)->compile_code(cs)
|
||||
);
|
||||
bcode_incr(codep);
|
||||
cs_do_and_cleanup([&]() {
|
||||
|
@ -493,16 +492,14 @@ static inline void cs_call_alias(
|
|||
cs.p_callstack = aliaslink.next;
|
||||
cs.identflags = oldflags;
|
||||
for (int i = 0; i < callargs; i++) {
|
||||
cs_alias_internal::pop_arg(
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i])
|
||||
);
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i])->pop_arg();
|
||||
}
|
||||
int argmask = aliaslink.usedargs & int(~0U << callargs);
|
||||
for (; argmask; ++callargs) {
|
||||
if (argmask & (1 << callargs)) {
|
||||
cs_alias_internal::pop_arg(static_cast<cs_alias_impl *>(
|
||||
cs.p_state->identmap[callargs])
|
||||
);
|
||||
static_cast<cs_alias_impl *>(
|
||||
cs.p_state->identmap[callargs]
|
||||
)->pop_arg();
|
||||
argmask &= ~(1 << callargs);
|
||||
}
|
||||
}
|
||||
|
@ -952,9 +949,8 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
);
|
||||
if (!cs_is_arg_used(cs, a)) {
|
||||
cs_value nv{cs};
|
||||
cs_alias_internal::push_arg(
|
||||
static_cast<cs_alias_impl *>(a), nv,
|
||||
cs.p_callstack->argstack[a->get_index()], false
|
||||
static_cast<cs_alias_impl *>(a)->push_arg(
|
||||
nv, cs.p_callstack->argstack[a->get_index()], false
|
||||
);
|
||||
cs.p_callstack->usedargs |= 1 << a->get_index();
|
||||
}
|
||||
|
@ -969,9 +965,8 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
}
|
||||
if ((id->get_index() < MaxArguments) && !cs_is_arg_used(cs, id)) {
|
||||
cs_value nv{cs};
|
||||
cs_alias_internal::push_arg(
|
||||
static_cast<cs_alias_impl *>(id), nv,
|
||||
cs.p_callstack->argstack[id->get_index()], false
|
||||
static_cast<cs_alias_impl *>(id)->push_arg(
|
||||
nv, cs.p_callstack->argstack[id->get_index()], false
|
||||
);
|
||||
cs.p_callstack->usedargs |= 1 << id->get_index();
|
||||
}
|
||||
|
@ -1401,16 +1396,14 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
}
|
||||
|
||||
case CS_CODE_ALIAS:
|
||||
cs_alias_internal::set_alias(
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[op >> 8]),
|
||||
cs, args[--numargs]
|
||||
);
|
||||
static_cast<cs_alias_impl *>(
|
||||
cs.p_state->identmap[op >> 8]
|
||||
)->set_alias(cs, args[--numargs]);
|
||||
continue;
|
||||
case CS_CODE_ALIAS_ARG:
|
||||
cs_alias_internal::set_arg(
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[op >> 8]),
|
||||
cs, args[--numargs]
|
||||
);
|
||||
static_cast<cs_alias_impl *>(
|
||||
cs.p_state->identmap[op >> 8]
|
||||
)->set_arg(cs, args[--numargs]);
|
||||
continue;
|
||||
case CS_CODE_ALIAS_U:
|
||||
numargs -= 2;
|
||||
|
|
179
src/cs_vm.hh
179
src/cs_vm.hh
|
@ -78,6 +78,20 @@ struct cs_svar_impl: cs_var_impl, cs_svar {
|
|||
cs_strref p_storage, p_overrideval;
|
||||
};
|
||||
|
||||
struct cs_ident_link {
|
||||
cs_ident *id;
|
||||
cs_ident_link *next;
|
||||
int usedargs;
|
||||
cs_ident_stack *argstack;
|
||||
};
|
||||
|
||||
static inline bool cs_is_arg_used(cs_state &cs, cs_ident *id) {
|
||||
if (!cs.p_callstack) {
|
||||
return true;
|
||||
}
|
||||
return cs.p_callstack->usedargs & (1 << id->get_index());
|
||||
}
|
||||
|
||||
struct cs_alias_impl: cs_ident_impl, cs_alias {
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, cs_strref a, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, std::string_view a, int flags);
|
||||
|
@ -86,6 +100,69 @@ struct cs_alias_impl: cs_ident_impl, cs_alias {
|
|||
cs_alias_impl(cs_state &cs, cs_strref n, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, cs_value v, int flags);
|
||||
|
||||
void push_arg(cs_value &v, cs_ident_stack &st, bool um = true) {
|
||||
if (p_astack == &st) {
|
||||
/* prevent cycles and unnecessary code elsewhere */
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
return;
|
||||
}
|
||||
st.val_s = std::move(p_val);
|
||||
st.next = p_astack;
|
||||
p_astack = &st;
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
if (um) {
|
||||
p_flags &= ~CS_IDF_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void pop_arg() {
|
||||
if (!p_astack) {
|
||||
return;
|
||||
}
|
||||
cs_ident_stack *st = p_astack;
|
||||
p_val = std::move(p_astack->val_s);
|
||||
clean_code();
|
||||
p_astack = st->next;
|
||||
}
|
||||
|
||||
void undo_arg(cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = p_astack;
|
||||
st.val_s = std::move(p_val);
|
||||
st.next = prev;
|
||||
p_astack = prev->next;
|
||||
p_val = std::move(prev->val_s);
|
||||
clean_code();
|
||||
}
|
||||
|
||||
void redo_arg(cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = st.next;
|
||||
prev->val_s = std::move(p_val);
|
||||
p_astack = prev;
|
||||
p_val = std::move(st.val_s);
|
||||
clean_code();
|
||||
}
|
||||
|
||||
void set_arg(cs_state &cs, cs_value &v) {
|
||||
if (cs_is_arg_used(cs, this)) {
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
} else {
|
||||
push_arg(v, cs.p_callstack->argstack[get_index()], false);
|
||||
cs.p_callstack->usedargs |= 1 << get_index();
|
||||
}
|
||||
}
|
||||
|
||||
void set_alias(cs_state &cs, cs_value &v) {
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
p_flags = (p_flags & cs.identflags) | cs.identflags;
|
||||
}
|
||||
|
||||
void clean_code();
|
||||
cs_bcode *compile_code(cs_state &cs);
|
||||
|
||||
cs_bcode *p_acode;
|
||||
cs_ident_stack *p_astack;
|
||||
cs_value p_val;
|
||||
|
@ -99,13 +176,6 @@ struct cs_command_impl: cs_ident_impl, cs_command {
|
|||
int p_numargs;
|
||||
};
|
||||
|
||||
struct cs_ident_link {
|
||||
cs_ident *id;
|
||||
cs_ident_link *next;
|
||||
int usedargs;
|
||||
cs_ident_stack *argstack;
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct cs_valarray {
|
||||
cs_valarray(cs_state &cs) {
|
||||
|
@ -358,98 +428,27 @@ static inline void bcode_decr(uint32_t *bc) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool cs_is_arg_used(cs_state &cs, cs_ident *id) {
|
||||
if (!cs.p_callstack) {
|
||||
return true;
|
||||
}
|
||||
return cs.p_callstack->usedargs & (1 << id->get_index());
|
||||
}
|
||||
|
||||
struct cs_alias_internal {
|
||||
static void push_arg(
|
||||
cs_alias_impl *a, cs_value &v, cs_ident_stack &st, bool um = true
|
||||
) {
|
||||
if (a->p_astack == &st) {
|
||||
/* prevent cycles and unnecessary code elsewhere */
|
||||
a->p_val = std::move(v);
|
||||
clean_code(a);
|
||||
return;
|
||||
}
|
||||
st.val_s = std::move(a->p_val);
|
||||
st.next = a->p_astack;
|
||||
a->p_astack = &st;
|
||||
a->p_val = std::move(v);
|
||||
clean_code(a);
|
||||
if (um) {
|
||||
a->p_flags &= ~CS_IDF_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void pop_arg(cs_alias_impl *a) {
|
||||
if (!a->p_astack) {
|
||||
return;
|
||||
}
|
||||
cs_ident_stack *st = a->p_astack;
|
||||
a->p_val = std::move(a->p_astack->val_s);
|
||||
clean_code(a);
|
||||
a->p_astack = st->next;
|
||||
}
|
||||
|
||||
static void undo_arg(cs_alias_impl *a, cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = a->p_astack;
|
||||
st.val_s = std::move(a->p_val);
|
||||
st.next = prev;
|
||||
a->p_astack = prev->next;
|
||||
a->p_val = std::move(prev->val_s);
|
||||
clean_code(a);
|
||||
}
|
||||
|
||||
static void redo_arg(cs_alias_impl *a, cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = st.next;
|
||||
prev->val_s = std::move(a->p_val);
|
||||
a->p_astack = prev;
|
||||
a->p_val = std::move(st.val_s);
|
||||
clean_code(a);
|
||||
}
|
||||
|
||||
static void set_arg(cs_alias_impl *a, cs_state &cs, cs_value &v) {
|
||||
if (cs_is_arg_used(cs, a)) {
|
||||
a->p_val = std::move(v);
|
||||
clean_code(a);
|
||||
} else {
|
||||
push_arg(a, v, cs.p_callstack->argstack[a->get_index()], false);
|
||||
cs.p_callstack->usedargs |= 1 << a->get_index();
|
||||
}
|
||||
}
|
||||
|
||||
static void set_alias(cs_alias_impl *a, cs_state &cs, cs_value &v) {
|
||||
a->p_val = std::move(v);
|
||||
clean_code(a);
|
||||
a->p_flags = (a->p_flags & cs.identflags) | cs.identflags;
|
||||
}
|
||||
|
||||
static void clean_code(cs_alias_impl *a) {
|
||||
uint32_t *bcode = reinterpret_cast<uint32_t *>(a->p_acode);
|
||||
inline void cs_alias_impl::clean_code() {
|
||||
uint32_t *bcode = reinterpret_cast<uint32_t *>(p_acode);
|
||||
if (bcode) {
|
||||
bcode_decr(bcode);
|
||||
a->p_acode = nullptr;
|
||||
p_acode = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static cs_bcode *compile_code(cs_alias_impl *a, cs_state &cs) {
|
||||
if (!a->p_acode) {
|
||||
inline cs_bcode *cs_alias_impl::compile_code(cs_state &cs) {
|
||||
if (!p_acode) {
|
||||
cs_gen_state gs(cs);
|
||||
gs.code.reserve(64);
|
||||
gs.gen_main(a->get_value().get_str());
|
||||
gs.gen_main(get_value().get_str());
|
||||
/* i wish i could steal the memory somehow */
|
||||
uint32_t *code = new uint32_t[gs.code.size()];
|
||||
memcpy(code, gs.code.data(), gs.code.size() * sizeof(uint32_t));
|
||||
bcode_incr(code);
|
||||
a->p_acode = reinterpret_cast<cs_bcode *>(code);
|
||||
p_acode = reinterpret_cast<cs_bcode *>(code);
|
||||
}
|
||||
return a->p_acode;
|
||||
return p_acode;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
static void cs_do_args(cs_state &cs, F body) {
|
||||
|
@ -461,8 +460,8 @@ static void cs_do_args(cs_state &cs, F body) {
|
|||
int argmask1 = cs.p_callstack->usedargs;
|
||||
for (int i = 0; argmask1; argmask1 >>= 1, ++i) {
|
||||
if (argmask1 & 1) {
|
||||
cs_alias_internal::undo_arg(
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i]), argstack[i]
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i])->undo_arg(
|
||||
argstack[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -481,8 +480,8 @@ static void cs_do_args(cs_state &cs, F body) {
|
|||
int argmask2 = cs.p_callstack->usedargs;
|
||||
for (int i = 0; argmask2; argmask2 >>= 1, ++i) {
|
||||
if (argmask2 & 1) {
|
||||
cs_alias_internal::redo_arg(
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i]), argstack[i]
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i])->redo_arg(
|
||||
argstack[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -417,7 +417,7 @@ LIBCUBESCRIPT_EXPORT void cs_state::destroy() {
|
|||
cs_alias *a = i->get_alias();
|
||||
if (a) {
|
||||
a->get_value().force_none();
|
||||
cs_alias_internal::clean_code(static_cast<cs_alias_impl *>(a));
|
||||
static_cast<cs_alias_impl *>(a)->clean_code();
|
||||
}
|
||||
p_state->destroy(i);
|
||||
}
|
||||
|
@ -469,7 +469,7 @@ LIBCUBESCRIPT_EXPORT void cs_state::clear_override(cs_ident &id) {
|
|||
switch (id.get_type()) {
|
||||
case cs_ident_type::ALIAS: {
|
||||
cs_alias_impl &a = static_cast<cs_alias_impl &>(id);
|
||||
cs_alias_internal::clean_code(&a);
|
||||
a.clean_code();
|
||||
a.get_value().set_str("");
|
||||
break;
|
||||
}
|
||||
|
@ -636,9 +636,9 @@ LIBCUBESCRIPT_EXPORT void cs_state::set_alias(std::string_view name, cs_value v)
|
|||
case cs_ident_type::ALIAS: {
|
||||
cs_alias_impl *a = static_cast<cs_alias_impl *>(id);
|
||||
if (a->get_index() < MaxArguments) {
|
||||
cs_alias_internal::set_arg(a, *this, v);
|
||||
a->set_arg(*this, v);
|
||||
} else {
|
||||
cs_alias_internal::set_alias(a, *this, v);
|
||||
a->set_alias(*this, v);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1116,12 +1116,8 @@ void cs_init_lib_base(cs_state &gcs) {
|
|||
rc = false;
|
||||
}
|
||||
ret.set_int(rc);
|
||||
cs_alias_internal::set_alias(
|
||||
static_cast<cs_alias_impl *>(cret), cs, result
|
||||
);
|
||||
cs_alias_internal::set_alias(
|
||||
static_cast<cs_alias_impl *>(css), cs, tback
|
||||
);
|
||||
static_cast<cs_alias_impl *>(cret)->set_alias(cs, result);
|
||||
static_cast<cs_alias_impl *>(css)->set_alias(cs, tback);
|
||||
});
|
||||
|
||||
gcs.new_command("?", "ttt", [](auto &, auto args, auto &res) {
|
||||
|
|
Loading…
Reference in New Issue