From 25894b469e7b0c9f366d4db851e60d18e7675e8f Mon Sep 17 00:00:00 2001 From: q66 Date: Fri, 2 Sep 2016 21:42:10 +0100 Subject: [PATCH] make the arg/code APIs for CsAlias purely internal --- cs_gen.cc | 21 -------- cs_vm.cc | 97 ++++++++-------------------------- cs_vm.hh | 143 +++++++++++++++++++++++++++++++++++++++++--------- cubescript.cc | 52 ++++++++++++++++-- cubescript.hh | 60 +++------------------ 5 files changed, 195 insertions(+), 178 deletions(-) diff --git a/cs_gen.cc b/cs_gen.cc index bcea5519..2a79551f 100644 --- a/cs_gen.cc +++ b/cs_gen.cc @@ -1701,25 +1701,4 @@ void GenState::gen_main(ostd::ConstCharRange s, int ret_type) { code.push(CODE_EXIT | ((ret_type < VAL_ANY) ? (ret_type << CODE_RET) : 0)); } -void CsAlias::clean_code() { - ostd::Uint32 *bcode = reinterpret_cast(p_acode); - if (bcode) { - bcode_decr(bcode); - p_acode = nullptr; - } -} - -CsBytecode *CsAlias::compile_code(CsState &cs) { - if (!p_acode) { - GenState gs(cs); - gs.code.reserve(64); - gs.gen_main(p_val.get_str()); - ostd::Uint32 *code = new ostd::Uint32[gs.code.size()]; - memcpy(code, gs.code.data(), gs.code.size() * sizeof(ostd::Uint32)); - bcode_incr(code); - p_acode = reinterpret_cast(code); - } - return p_acode; -} - } /* namespace cscript */ \ No newline at end of file diff --git a/cs_vm.cc b/cs_vm.cc index 4a7e94e0..35b7fbfa 100644 --- a/cs_vm.cc +++ b/cs_vm.cc @@ -6,70 +6,6 @@ namespace cscript { -void CsAlias::push_arg(CsValue const &v, CsIdentStack &st, bool um) { - if (p_astack == &st) { - /* prevent cycles and unnecessary code elsewhere */ - p_val.cleanup(); - p_val = v; - clean_code(); - return; - } - st.val_s = p_val; - st.next = p_astack; - p_astack = &st; - p_val = v; - clean_code(); - if (um) { - p_flags &= ~IDF_UNKNOWN; - } -} - -void CsAlias::pop_arg() { - if (!p_astack) { - return; - } - CsIdentStack *st = p_astack; - p_val.cleanup(); - p_val = p_astack->val_s; - clean_code(); - p_astack = st->next; -} - -void CsAlias::undo_arg(CsIdentStack &st) { - CsIdentStack *prev = p_astack; - st.val_s = p_val; - st.next = prev; - p_astack = prev->next; - p_val = prev->val_s; - clean_code(); -} - -void CsAlias::redo_arg(CsIdentStack const &st) { - CsIdentStack *prev = st.next; - prev->val_s = p_val; - p_astack = prev; - p_val = st.val_s; - clean_code(); -} - -void CsAlias::set_arg(CsState &cs, CsValue &v) { - if (cs.p_stack->usedargs & (1 << get_index())) { - p_val.cleanup(); - p_val = v; - clean_code(); - } else { - push_arg(v, cs.p_stack->argstack[get_index()], false); - cs.p_stack->usedargs |= 1 << get_index(); - } -} - -void CsAlias::set_alias(CsState &cs, CsValue &v) { - p_val.cleanup(); - p_val = v; - clean_code(); - p_flags = (p_flags & cs.identflags) | cs.identflags; -} - static inline bool cs_has_cmd_cb(CsIdent *id) { if (!id->is_command() && !id->is_special()) { return false; @@ -80,13 +16,13 @@ static inline bool cs_has_cmd_cb(CsIdent *id) { static inline void cs_push_alias(CsIdent *id, CsIdentStack &st) { if (id->is_alias() && (id->get_index() >= MaxArguments)) { - static_cast(id)->push_arg(null_value, st); + CsAliasInternal::push_arg(static_cast(id), null_value, st); } } static inline void cs_pop_alias(CsIdent *id) { if (id->is_alias() && (id->get_index() >= MaxArguments)) { - static_cast(id)->pop_arg(); + CsAliasInternal::pop_arg(static_cast(id)); } } @@ -521,7 +457,8 @@ static inline void cs_call_alias( CsIvar *anargs = static_cast(cs.identmap[NumargsIdx]); CsIdentStack argstack[MaxArguments]; for(int i = 0; i < callargs; i++) { - static_cast(cs.identmap[i])->push_arg( + CsAliasInternal::push_arg( + static_cast(cs.identmap[i]), args[offset + i], argstack[i], false ); } @@ -533,19 +470,23 @@ static inline void cs_call_alias( a, cs.p_stack, (1<(a->compile_code(cs)); + ostd::Uint32 *codep = reinterpret_cast( + CsAliasInternal::compile_code(a, cs) + ); bcode_incr(codep); runcode(cs, codep+1, (result)); bcode_decr(codep); cs.p_stack = aliaslink.next; cs.identflags = oldflags; for (int i = 0; i < callargs; i++) { - static_cast(cs.identmap[i])->pop_arg(); + CsAliasInternal::pop_arg(static_cast(cs.identmap[i])); } int argmask = aliaslink.usedargs & (~0 << callargs); for (; argmask; ++callargs) { if (argmask & (1 << callargs)) { - static_cast(cs.identmap[callargs])->pop_arg(); + CsAliasInternal::pop_arg(static_cast( + cs.identmap[callargs]) + ); argmask &= ~(1 << callargs); } } @@ -1008,8 +949,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { case CODE_IDENTARG: { CsAlias *a = static_cast(cs.identmap[op >> 8]); if (!(cs.p_stack->usedargs & (1 << a->get_index()))) { - a->push_arg( - null_value, cs.p_stack->argstack[a->get_index()], false + CsAliasInternal::push_arg( + a, null_value, cs.p_stack->argstack[a->get_index()], + false ); cs.p_stack->usedargs |= 1 << a->get_index(); } @@ -1030,8 +972,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { id->get_index() < MaxArguments && !(cs.p_stack->usedargs & (1 << id->get_index())) ) { - static_cast(id)->push_arg( - null_value, cs.p_stack->argstack[id->get_index()], false + CsAliasInternal::push_arg( + static_cast(id), null_value, + cs.p_stack->argstack[id->get_index()], false ); cs.p_stack->usedargs |= 1 << id->get_index(); } @@ -1468,12 +1411,14 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { } case CODE_ALIAS: - static_cast(cs.identmap[op >> 8])->set_alias( + CsAliasInternal::set_alias( + static_cast(cs.identmap[op >> 8]), cs, args[--numargs] ); continue; case CODE_ALIASARG: - static_cast(cs.identmap[op >> 8])->set_arg( + CsAliasInternal::set_arg( + static_cast(cs.identmap[op >> 8]), cs, args[--numargs] ); continue; diff --git a/cs_vm.hh b/cs_vm.hh index 74a72947..84d71b22 100644 --- a/cs_vm.hh +++ b/cs_vm.hh @@ -83,31 +83,6 @@ struct NullValue: CsValue { NullValue() { set_null(); } } const null_value; -template -static void cs_do_args(CsState &cs, F body) { - CsIdentStack argstack[MaxArguments]; - int argmask1 = cs.p_stack->usedargs; - for (int i = 0; argmask1; argmask1 >>= 1, ++i) { - if (argmask1 & 1) { - static_cast(cs.identmap[i])->undo_arg(argstack[i]); - } - } - CsIdentLink *prevstack = cs.p_stack->next; - CsIdentLink aliaslink = { - cs.p_stack->id, cs.p_stack, prevstack->usedargs, prevstack->argstack - }; - cs.p_stack = &aliaslink; - body(); - prevstack->usedargs = aliaslink.usedargs; - cs.p_stack = aliaslink.next; - int argmask2 = cs.p_stack->usedargs; - for (int i = 0; argmask2; argmask2 >>= 1, ++i) { - if (argmask2 & 1) { - static_cast(cs.identmap[i])->redo_arg(argstack[i]); - } - } -} - ostd::ConstCharRange cs_debug_line( ostd::ConstCharRange p, ostd::ConstCharRange fmt, ostd::CharRange buf ); @@ -255,6 +230,124 @@ static inline void bcode_decr(ostd::Uint32 *bc) { } } +struct CsAliasInternal { + static void push_arg( + CsAlias *a, CsValue const &v, CsIdentStack &st, bool um = true + ) { + if (a->p_astack == &st) { + /* prevent cycles and unnecessary code elsewhere */ + a->p_val.cleanup(); + a->p_val = v; + clean_code(a); + return; + } + st.val_s = a->p_val; + st.next = a->p_astack; + a->p_astack = &st; + a->p_val = v; + clean_code(a); + if (um) { + a->p_flags &= ~IDF_UNKNOWN; + } + } + + static void pop_arg(CsAlias *a) { + if (!a->p_astack) { + return; + } + CsIdentStack *st = a->p_astack; + a->p_val.cleanup(); + a->p_val = a->p_astack->val_s; + clean_code(a); + a->p_astack = st->next; + } + + static void undo_arg(CsAlias *a, CsIdentStack &st) { + CsIdentStack *prev = a->p_astack; + st.val_s = a->p_val; + st.next = prev; + a->p_astack = prev->next; + a->p_val = prev->val_s; + clean_code(a); + } + + static void redo_arg(CsAlias *a, CsIdentStack const &st) { + CsIdentStack *prev = st.next; + prev->val_s = a->p_val; + a->p_astack = prev; + a->p_val = st.val_s; + clean_code(a); + } + + static void set_arg(CsAlias *a, CsState &cs, CsValue &v) { + if (cs.p_stack->usedargs & (1 << a->get_index())) { + a->p_val.cleanup(); + a->p_val = v; + clean_code(a); + } else { + push_arg(a, v, cs.p_stack->argstack[a->get_index()], false); + cs.p_stack->usedargs |= 1 << a->get_index(); + } + } + + static void set_alias(CsAlias *a, CsState &cs, CsValue &v) { + a->p_val.cleanup(); + a->p_val = v; + clean_code(a); + a->p_flags = (a->p_flags & cs.identflags) | cs.identflags; + } + + static void clean_code(CsAlias *a) { + ostd::Uint32 *bcode = reinterpret_cast(a->p_acode); + if (bcode) { + bcode_decr(bcode); + a->p_acode = nullptr; + } + } + + static CsBytecode *compile_code(CsAlias *a, CsState &cs) { + if (!a->p_acode) { + GenState gs(cs); + gs.code.reserve(64); + gs.gen_main(a->get_value().get_str()); + ostd::Uint32 *code = new ostd::Uint32[gs.code.size()]; + memcpy(code, gs.code.data(), gs.code.size() * sizeof(ostd::Uint32)); + bcode_incr(code); + a->p_acode = reinterpret_cast(code); + } + return a->p_acode; + } +}; + +template +static void cs_do_args(CsState &cs, F body) { + CsIdentStack argstack[MaxArguments]; + int argmask1 = cs.p_stack->usedargs; + for (int i = 0; argmask1; argmask1 >>= 1, ++i) { + if (argmask1 & 1) { + CsAliasInternal::undo_arg( + static_cast(cs.identmap[i]), argstack[i] + ); + } + } + CsIdentLink *prevstack = cs.p_stack->next; + CsIdentLink aliaslink = { + cs.p_stack->id, cs.p_stack, prevstack->usedargs, prevstack->argstack + }; + cs.p_stack = &aliaslink; + body(); + prevstack->usedargs = aliaslink.usedargs; + cs.p_stack = aliaslink.next; + int argmask2 = cs.p_stack->usedargs; + for (int i = 0; argmask2; argmask2 >>= 1, ++i) { + if (argmask2 & 1) { + CsAliasInternal::redo_arg( + static_cast(cs.identmap[i]), argstack[i] + ); + } + } +} + } /* namespace cscript */ #endif /* LIBCUBESCRIPT_CS_VM_HH */ diff --git a/cubescript.cc b/cubescript.cc index 3f714387..0c14aed6 100644 --- a/cubescript.cc +++ b/cubescript.cc @@ -343,7 +343,7 @@ CsState::~CsState() { CsAlias *a = i->get_alias(); if (a) { a->get_value().force_null(); - a->clean_code(); + CsAliasInternal::clean_code(a); } delete i; } @@ -381,7 +381,7 @@ void CsState::clear_override(CsIdent &id) { case CsIdentType::alias: { CsAlias &a = static_cast(id); a.get_value().cleanup(); - a.clean_code(); + CsAliasInternal::clean_code(&a); a.get_value().set_str(""); break; } @@ -505,9 +505,9 @@ void CsState::set_alias(ostd::ConstCharRange name, CsValue &v) { case CsIdentType::alias: { CsAlias *a = static_cast(id); if (a->get_index() < MaxArguments) { - a->set_arg(*this, v); + CsAliasInternal::set_arg(a, *this, v); } else { - a->set_alias(*this, v); + CsAliasInternal::set_alias(a, *this, v); } return; } @@ -949,6 +949,50 @@ int CsIdent::get_index() const { return p_index; } +CsStackedValue::CsStackedValue(CsIdent *id): + CsValue(), p_a(nullptr), p_stack(), p_pushed(false) +{ + set_alias(id); +} + +CsStackedValue::~CsStackedValue() { + pop(); +} + +bool CsStackedValue::set_alias(CsIdent *id) { + if (!id || !id->is_alias()) { + return false; + } + p_a = static_cast(id); + return true; +} + +CsAlias *CsStackedValue::get_alias() const { + return p_a; +} + +bool CsStackedValue::has_alias() const { + return p_a != nullptr; +} + +bool CsStackedValue::push() { + if (!p_a) { + return false; + } + CsAliasInternal::push_arg(p_a, *this, p_stack); + p_pushed = true; + return true; +} + +bool CsStackedValue::pop() { + if (!p_pushed || !p_a) { + return false; + } + CsAliasInternal::pop_arg(p_a); + p_pushed = false; + return true; +} + template static inline bool cs_override_var(CsState &cs, CsVar *v, int &vflags, SF sf) { if ((cs.identflags & IDF_OVERRIDDEN) || (vflags & IDF_OVERRIDE)) { diff --git a/cubescript.hh b/cubescript.hh index d26f0dcd..c30615dc 100644 --- a/cubescript.hh +++ b/cubescript.hh @@ -257,6 +257,7 @@ private: struct OSTD_EXPORT CsAlias: CsIdent { friend struct CsState; + friend struct CsAliasInternal; CsValue const &get_value() const { return p_val; @@ -268,17 +269,6 @@ struct OSTD_EXPORT CsAlias: CsIdent { void get_cstr(CsValue &v) const; void get_cval(CsValue &v) const; - - /* TODO: make all these internal */ - void push_arg(CsValue const &v, CsIdentStack &st, bool um = true); - void pop_arg(); - void undo_arg(CsIdentStack &st); - void redo_arg(CsIdentStack const &st); - void set_arg(CsState &cs, CsValue &v); - void set_alias(CsState &cs, CsValue &v); - void clean_code(); - CsBytecode *compile_code(CsState &cs); - private: CsAlias(ostd::ConstCharRange n, char *a, int flags); CsAlias(ostd::ConstCharRange n, CsInt a, int flags); @@ -476,49 +466,15 @@ private: }; struct OSTD_EXPORT CsStackedValue: CsValue { - CsStackedValue(CsIdent *id = nullptr): - CsValue(), p_a(nullptr), p_stack(), p_pushed(false) - { - set_alias(id); - } + CsStackedValue(CsIdent *id = nullptr); + ~CsStackedValue(); - ~CsStackedValue() { - pop(); - } + bool set_alias(CsIdent *id); + CsAlias *get_alias() const; + bool has_alias() const; - bool set_alias(CsIdent *id) { - if (!id || !id->is_alias()) { - return false; - } - p_a = static_cast(id); - return true; - } - - CsAlias *get_alias() const { - return p_a; - } - - bool has_alias() const { - return p_a != nullptr; - } - - bool push() { - if (!p_a) { - return false; - } - p_a->push_arg(*this, p_stack); - p_pushed = true; - return true; - } - - bool pop() { - if (!p_pushed || !p_a) { - return false; - } - p_a->pop_arg(); - p_pushed = false; - return true; - } + bool push(); + bool pop(); private: CsAlias *p_a;