diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index 3dd12b9b..cfb4ec6c 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -363,6 +363,14 @@ enum class CsLoopState { Normal = 0, Break, Continue }; +static inline void *cs_default_alloc(void *, void *p, ostd::Size, ostd::Size ns) { + if (!ns) { + delete[] static_cast(p); + return nullptr; + } + return new unsigned char[ns]; +} + struct OSTD_EXPORT CsState { friend struct CsErrorException; friend struct GenState; @@ -372,7 +380,7 @@ struct OSTD_EXPORT CsState { int identflags = 0; - CsState(CsAllocCb func = nullptr, void *data = nullptr); + CsState(CsAllocCb func = cs_default_alloc, void *data = nullptr); virtual ~CsState(); CsHookCb set_call_hook(CsHookCb func); @@ -563,9 +571,6 @@ private: GenState *p_pstate = nullptr; int p_inloop = 0; - CsAllocCb p_allocf; - void *p_aptr; - char p_errbuf[512]; CsHookCb p_callhook; diff --git a/src/cs_vm.hh b/src/cs_vm.hh index b53ca106..111b49ab 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -97,6 +97,8 @@ enum { struct CsSharedState { CsMap idents; CsVector identmap; + CsAllocCb allocf; + void *aptr; }; struct CsBreakException { diff --git a/src/cubescript.cc b/src/cubescript.cc index 6424bcec..04104bd8 100644 --- a/src/cubescript.cc +++ b/src/cubescript.cc @@ -287,10 +287,20 @@ int CsCommand::get_num_args() const { void cs_init_lib_base(CsState &cs); CsState::CsState(CsAllocCb func, void *data): - p_state(nullptr), - p_allocf(func), p_aptr(data), p_callhook() + p_state(nullptr), p_callhook() { - p_state = create(); + if (!func) { + func = cs_default_alloc; + } + /* allocator is not set up yet, use func directly */ + p_state = static_cast( + func(data, nullptr, 0, sizeof(CsSharedState)) + ); + new (p_state) CsSharedState(); + /* set up allocator, from now we can call into alloc() */ + p_state->allocf = func; + p_state->aptr = data; + for (int i = 0; i < MaxArguments; ++i) { char buf[32]; snprintf(buf, sizeof(buf), "arg%d", i + 1); @@ -415,14 +425,7 @@ CsHookCb &CsState::get_call_hook() { } void *CsState::alloc(void *ptr, ostd::Size os, ostd::Size ns) { - if (p_allocf) { - return p_allocf(p_aptr, ptr, os, ns); - } - if (!ns) { - delete[] static_cast(ptr); - return nullptr; - } - return new unsigned char[ns]; + return p_state->allocf(p_state->aptr, ptr, os, ns); } void CsState::clear_override(CsIdent &id) {