get rid of emptyblock

master
Daniel Kolesa 2021-03-22 22:01:49 +01:00
parent 83e92e6881
commit f9a49ffba7
5 changed files with 48 additions and 14 deletions

View File

@ -110,4 +110,28 @@ void bcode_unref(std::uint32_t *code) {
}
}
/* empty fallbacks */
static std::uint32_t emptyrets[CS_VAL_ANY] = {
CS_RET_NULL, CS_RET_INT, CS_RET_FLOAT, CS_RET_STRING
};
empty_block *bcode_init_empty(cs_shared_state *cs) {
auto a = cs_allocator<empty_block>{cs};
auto *p = a.allocate(CS_VAL_ANY);
for (std::size_t i = 0; i < CS_VAL_ANY; ++i) {
p[i].init.init = CS_CODE_START + 0x100;
p[i].code = CS_CODE_EXIT | emptyrets[i];
}
return p;
}
void bcode_free_empty(cs_shared_state *cs, empty_block *empty) {
cs_allocator<empty_block>{cs}.deallocate(empty, CS_VAL_ANY);
};
cs_bcode *bcode_get_empty(empty_block *empty, std::size_t val) {
return &empty[val].init + 1;
}
} /* namespace cscript */

View File

@ -79,6 +79,15 @@ void bcode_decr(std::uint32_t *code);
void bcode_ref(std::uint32_t *code);
void bcode_unref(std::uint32_t *code);
struct empty_block {
cs_bcode init;
std::uint32_t code;
};
empty_block *bcode_init_empty(cs_shared_state *cs);
void bcode_free_empty(cs_shared_state *cs, empty_block *empty);
cs_bcode *bcode_get_empty(empty_block *empty, std::size_t val);
} /* namespace cscript */
#endif

View File

@ -5,6 +5,8 @@
#include <unordered_map>
#include <vector>
#include "cs_bcode.hh"
namespace cscript {
cs_int cs_parse_int(
@ -140,6 +142,7 @@ struct cs_shared_state {
cs_vprint_cb varprintf;
cs_strman *strman;
empty_block *empty;
cs_shared_state() = delete;
@ -148,9 +151,15 @@ struct cs_shared_state {
idents{allocator_type{this}},
identmap{allocator_type{this}},
varprintf{},
strman{create<cs_strman>(this)}
strman{create<cs_strman>(this)},
empty{bcode_init_empty(this)}
{}
~cs_shared_state() {
bcode_free_empty(this, empty);
destroy(strman);
}
void *alloc(void *ptr, size_t os, size_t ns) {
void *p = allocf(aptr, ptr, os, ns);
if (!p && ns) {

View File

@ -185,13 +185,6 @@ static inline void forcecond(cs_state &cs, cs_value &v) {
}
}
static uint32_t emptyblock[CS_VAL_ANY][2] = {
{ CS_CODE_START + 0x100, CS_CODE_EXIT | CS_RET_NULL },
{ CS_CODE_START + 0x100, CS_CODE_EXIT | CS_RET_INT },
{ CS_CODE_START + 0x100, CS_CODE_EXIT | CS_RET_FLOAT },
{ CS_CODE_START + 0x100, CS_CODE_EXIT | CS_RET_STRING }
};
static inline void force_arg(cs_value &v, int type) {
switch (type) {
case CS_RET_STRING:
@ -303,7 +296,7 @@ static inline void callcommand(
break;
}
args[i].set_code(
reinterpret_cast<cs_bcode *>(emptyblock[CS_VAL_NULL] + 1)
bcode_get_empty(cs_get_sstate(cs)->empty, CS_VAL_NULL)
);
fakeargs++;
} else {
@ -750,22 +743,22 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
case CS_CODE_EMPTY | CS_RET_NULL:
args[numargs++].set_code(
reinterpret_cast<cs_bcode *>(emptyblock[CS_VAL_NULL] + 1)
bcode_get_empty(cs_get_sstate(cs)->empty, CS_VAL_NULL)
);
break;
case CS_CODE_EMPTY | CS_RET_STRING:
args[numargs++].set_code(
reinterpret_cast<cs_bcode *>(emptyblock[CS_VAL_STRING] + 1)
bcode_get_empty(cs_get_sstate(cs)->empty, CS_VAL_STRING)
);
break;
case CS_CODE_EMPTY | CS_RET_INT:
args[numargs++].set_code(
reinterpret_cast<cs_bcode *>(emptyblock[CS_VAL_INT] + 1)
bcode_get_empty(cs_get_sstate(cs)->empty, CS_VAL_INT)
);
break;
case CS_CODE_EMPTY | CS_RET_FLOAT:
args[numargs++].set_code(
reinterpret_cast<cs_bcode *>(emptyblock[CS_VAL_FLOAT] + 1)
bcode_get_empty(cs_get_sstate(cs)->empty, CS_VAL_FLOAT)
);
break;
case CS_CODE_BLOCK: {

View File

@ -421,7 +421,6 @@ LIBCUBESCRIPT_EXPORT void cs_state::destroy() {
}
p_state->destroy(i->p_impl);
}
p_state->destroy(p_state->strman);
p_state->destroy(static_cast<cs_charbuf *>(p_errbuf));
p_state->destroy(p_state);
}