diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index cfb4ec6..4da6ee0 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -116,6 +116,9 @@ struct CsIdentStack { }; struct CsState; +struct CsSharedState; +struct CsErrorException; +struct GenState; enum class CsIdentType { Ivar = 0, Fvar, Svar, Command, Alias, Special @@ -130,6 +133,7 @@ struct CsCommand; struct OSTD_EXPORT CsIdent { friend struct CsState; + friend struct CsSharedState; CsIdent() = delete; CsIdent(CsIdent const &) = delete; @@ -196,6 +200,7 @@ using CsVarCb = ostd::Function; struct OSTD_EXPORT CsVar: CsIdent { friend struct CsState; + friend struct CsSharedState; protected: CsVar(CsIdentType tp, ostd::ConstCharRange name, CsVarCb func, int flags = 0); @@ -214,6 +219,7 @@ private: struct OSTD_EXPORT CsIvar: CsVar { friend struct CsState; + friend struct CsSharedState; CsInt get_val_min() const; CsInt get_val_max() const; @@ -233,6 +239,7 @@ private: struct OSTD_EXPORT CsFvar: CsVar { friend struct CsState; + friend struct CsSharedState; CsFloat get_val_min() const; CsFloat get_val_max() const; @@ -253,6 +260,7 @@ private: struct OSTD_EXPORT CsSvar: CsVar { friend struct CsState; + friend struct CsSharedState; ostd::ConstCharRange get_value() const; void set_value(CsString val); @@ -267,6 +275,7 @@ private: struct OSTD_EXPORT CsAlias: CsIdent { friend struct CsState; + friend struct CsSharedState; friend struct CsAliasInternal; CsValue const &get_value() const { @@ -295,6 +304,7 @@ using CsCommandCb = ostd::Function; struct CsCommand: CsIdent { friend struct CsState; + friend struct CsSharedState; friend struct CsCommandInternal; ostd::ConstCharRange get_args() const; @@ -323,42 +333,6 @@ enum { using CsHookCb = ostd::Function; using CsAllocCb = void *(*)(void *, void *, ostd::Size, ostd::Size); -template -struct CsAllocator { - template - friend struct CsAllocator; - - using Value = T; - static constexpr bool PropagateOnContainerCopyAssignment = true; - static constexpr bool PropagateOnContainerMoveAssignment = true; - static constexpr bool PropagateOnContainerSwap = true; - - CsAllocator() = delete; - CsAllocator(CsAllocator const &a) noexcept: p_state(a.p_state) {} - CsAllocator(CsState &cs) noexcept: p_state(cs) {} - - template - CsAllocator(CsAllocator const &a) noexcept: p_state(a.p_state) {} - - T *allocate(ostd::Size n); - void deallocate(T *p, ostd::Size n) noexcept; - - bool operator==(CsAllocator const &o) const noexcept { - return &p_state != &o.p_state; - } - - bool operator!=(CsAllocator const &o) const noexcept { - return &p_state != &o.p_state; - } - -private: - CsState &p_state; -}; - -struct CsErrorException; -struct CsSharedState; -struct GenState; - enum class CsLoopState { Normal = 0, Break, Continue }; @@ -394,36 +368,6 @@ struct OSTD_EXPORT CsState { )); } - void *alloc(void *ptr, ostd::Size olds, ostd::Size news); - - template - T *create(A &&...args) { - T *ret = static_cast(alloc(nullptr, 0, sizeof(T))); - new (ret) T(ostd::forward(args)...); - return ret; - } - - template - T *create_array(ostd::Size len) { - T *ret = static_cast(alloc(nullptr, 0, len * sizeof(T))); - for (ostd::Size i = 0; i < len; ++i) { - new (&ret[i]) T(); - } - return ret; - } - - template - void destroy(T *v) noexcept { - v->~T(); - alloc(v, sizeof(T), 0); - } - - template - void destroy_array(T *v, ostd::Size len) noexcept { - v->~T(); - alloc(v, len * sizeof(T), 0); - } - void init_libs(int libs = CsLibAll); void clear_override(CsIdent &id); @@ -568,6 +512,44 @@ struct OSTD_EXPORT CsState { private: CsIdent *add_ident(CsIdent *id); + void *alloc(void *ptr, ostd::Size olds, ostd::Size news); + + template + struct CsAllocator { + template + friend struct CsAllocator; + + using Value = T; + static constexpr bool PropagateOnContainerCopyAssignment = true; + static constexpr bool PropagateOnContainerMoveAssignment = true; + static constexpr bool PropagateOnContainerSwap = true; + + CsAllocator() = delete; + CsAllocator(CsAllocator const &a) noexcept: p_state(a.p_state) {} + CsAllocator(CsState &cs) noexcept: p_state(cs) {} + + template + CsAllocator(CsAllocator const &a) noexcept: p_state(a.p_state) {} + + T *allocate(ostd::Size n) { + return static_cast(p_state.alloc(nullptr, 0, n * sizeof(T))); + } + void deallocate(T *p, ostd::Size n) noexcept { + p_state.alloc(p, n * sizeof(T), 0); + } + + bool operator==(CsAllocator const &o) const noexcept { + return &p_state != &o.p_state; + } + + bool operator!=(CsAllocator const &o) const noexcept { + return &p_state != &o.p_state; + } + + private: + CsState &p_state; + }; + GenState *p_pstate = nullptr; int p_inloop = 0; @@ -679,16 +661,6 @@ private: bool p_pushed; }; -template -T *CsAllocator::allocate(ostd::Size n) { - return static_cast(p_state.alloc(nullptr, 0, n * sizeof(T))); -} - -template -void CsAllocator::deallocate(T *p, ostd::Size n) noexcept { - p_state.alloc(p, n * sizeof(T), 0); -} - namespace util { template inline ostd::Size escape_string(R &&writer, ostd::ConstCharRange str) { diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 003ecd9..fa8b77c 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -50,7 +50,7 @@ CsStackState::~CsStackState() { for (CsStackStateNode const *nd = p_node; nd; nd = nd->next) { ++len; } - p_state.destroy_array(p_node, len); + p_state.p_state->destroy_array(p_node, len); } CsStackState &CsStackState::operator=(CsStackState &&st) { @@ -81,7 +81,7 @@ CsStackState CsErrorException::save_stack(CsState &cs) { if (!total) { return CsStackState(cs, nullptr, false); } - CsStackStateNode *st = cs.create_array( + CsStackStateNode *st = cs.p_state->create_array( ostd::min(total, dalias->get_value()) ); CsStackStateNode *ret = st, *nd = st; diff --git a/src/cs_vm.hh b/src/cs_vm.hh index 111b49a..12184a8 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -99,6 +99,38 @@ struct CsSharedState { CsVector identmap; CsAllocCb allocf; void *aptr; + + void *alloc(void *ptr, ostd::Size os, ostd::Size ns) { + return allocf(aptr, ptr, os, ns); + } + + template + T *create(A &&...args) { + T *ret = static_cast(alloc(nullptr, 0, sizeof(T))); + new (ret) T(ostd::forward(args)...); + return ret; + } + + template + T *create_array(ostd::Size len) { + T *ret = static_cast(alloc(nullptr, 0, len * sizeof(T))); + for (ostd::Size i = 0; i < len; ++i) { + new (&ret[i]) T(); + } + return ret; + } + + template + void destroy(T *v) noexcept { + v->~T(); + alloc(v, sizeof(T), 0); + } + + template + void destroy_array(T *v, ostd::Size len) noexcept { + v->~T(); + alloc(v, len * sizeof(T), 0); + } }; struct CsBreakException { diff --git a/src/cubescript.cc b/src/cubescript.cc index 04104bd..4f50b6e 100644 --- a/src/cubescript.cc +++ b/src/cubescript.cc @@ -405,9 +405,9 @@ CsState::~CsState() { a->get_value().force_null(); CsAliasInternal::clean_code(a); } - destroy(i); + p_state->destroy(i); } - destroy(p_state); + p_state->destroy(p_state); } CsHookCb CsState::set_call_hook(CsHookCb func) { @@ -425,7 +425,7 @@ CsHookCb &CsState::get_call_hook() { } void *CsState::alloc(void *ptr, ostd::Size os, ostd::Size ns) { - return p_state->allocf(p_state->aptr, ptr, os, ns); + return p_state->alloc(ptr, os, ns); } void CsState::clear_override(CsIdent &id) { @@ -486,7 +486,7 @@ CsIdent *CsState::new_ident(ostd::ConstCharRange name, int flags) { *this, "number %s is not a valid identifier name", name ); } - id = add_ident(create(name, flags)); + id = add_ident(p_state->create(name, flags)); } return id; } @@ -544,7 +544,7 @@ CsIvar *CsState::new_ivar( ostd::ConstCharRange n, CsInt m, CsInt x, CsInt v, CsVarCb f, int flags ) { return add_ident( - create(n, m, x, v, ostd::move(f), flags) + p_state->create(n, m, x, v, ostd::move(f), flags) )->get_ivar(); } @@ -552,7 +552,7 @@ CsFvar *CsState::new_fvar( ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat v, CsVarCb f, int flags ) { return add_ident( - create(n, m, x, v, ostd::move(f), flags) + p_state->create(n, m, x, v, ostd::move(f), flags) )->get_fvar(); } @@ -560,7 +560,7 @@ CsSvar *CsState::new_svar( ostd::ConstCharRange n, CsString v, CsVarCb f, int flags ) { return add_ident( - create(n, ostd::move(v), ostd::move(f), flags) + p_state->create(n, ostd::move(v), ostd::move(f), flags) )->get_svar(); } @@ -613,7 +613,7 @@ void CsState::set_alias(ostd::ConstCharRange name, CsValue v) { } else if (cs_check_num(name)) { throw CsErrorException(*this, "cannot alias number %s", name); } else { - add_ident(create(name, ostd::move(v), identflags)); + add_ident(p_state->create(name, ostd::move(v), identflags)); } } @@ -974,7 +974,7 @@ CsCommand *CsState::new_command( } } return static_cast( - add_ident(create(name, args, nargs, ostd::move(func))) + add_ident(p_state->create(name, args, nargs, ostd::move(func))) ); }