From 3d2f115de5272d011c32da5b66cac9174efac336 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Mon, 22 Mar 2021 21:26:05 +0100 Subject: [PATCH] separate bytecode bits into its own file --- src/cs_bcode.cc | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ src/cs_bcode.hh | 74 +++++++++++++++++++++++++++++++ src/cs_vm.cc | 98 ----------------------------------------- src/cs_vm.hh | 53 +---------------------- src/meson.build | 1 + 5 files changed, 189 insertions(+), 150 deletions(-) create mode 100644 src/cs_bcode.cc create mode 100644 src/cs_bcode.hh diff --git a/src/cs_bcode.cc b/src/cs_bcode.cc new file mode 100644 index 0000000..e8f40b0 --- /dev/null +++ b/src/cs_bcode.cc @@ -0,0 +1,113 @@ +#include "cs_bcode.hh" + +#include "cs_util.hh" + +namespace cscript { + +/* public API impls */ + +LIBCUBESCRIPT_EXPORT cs_bcode_ref::cs_bcode_ref(cs_bcode *v): p_code(v) { + bcode_ref(reinterpret_cast(p_code)); +} +LIBCUBESCRIPT_EXPORT cs_bcode_ref::cs_bcode_ref(cs_bcode_ref const &v): + p_code(v.p_code) +{ + bcode_ref(reinterpret_cast(p_code)); +} + +LIBCUBESCRIPT_EXPORT cs_bcode_ref::~cs_bcode_ref() { + bcode_unref(reinterpret_cast(p_code)); +} + +LIBCUBESCRIPT_EXPORT cs_bcode_ref &cs_bcode_ref::operator=( + cs_bcode_ref const &v +) { + bcode_unref(reinterpret_cast(p_code)); + p_code = v.p_code; + bcode_ref(reinterpret_cast(p_code)); + return *this; +} + +LIBCUBESCRIPT_EXPORT cs_bcode_ref &cs_bcode_ref::operator=(cs_bcode_ref &&v) { + bcode_unref(reinterpret_cast(p_code)); + p_code = v.p_code; + v.p_code = nullptr; + return *this; +} + +/* private funcs */ + +struct bcode_hdr { + cs_shared_state *cs; /* needed to construct the allocator */ + std::size_t asize; /* alloc size of the bytecode block */ + std::uint32_t init; /* CS_CODE_START + refcount */ +}; + +/* returned address is the 'init' member of the header */ +std::uint32_t *bcode_alloc(cs_state &cs, std::size_t sz) { + auto a = cs_allocator{cs}; + std::size_t hdrs = sizeof(bcode_hdr) / sizeof(std::uint32_t); + auto p = a.allocate(sz + hdrs - 1); + bcode_hdr *hdr = reinterpret_cast(p); + hdr->cs = cs_get_sstate(cs); + hdr->asize = sz + hdrs - 1; + return p + hdrs - 1; +} + +/* bc's address must be the 'init' member of the header */ +static inline void bcode_free(std::uint32_t *bc) { + auto *rp = bc + 1 - (sizeof(bcode_hdr) / sizeof(std::uint32_t)); + bcode_hdr *hdr = reinterpret_cast(rp); + cs_allocator{hdr->cs}.deallocate(rp, hdr->asize); +} + +void bcode_incr(std::uint32_t *bc) { + *bc += 0x100; +} + +void bcode_decr(std::uint32_t *bc) { + *bc -= 0x100; + if (std::int32_t(*bc) < 0x100) { + bcode_free(bc); + } +} + +void bcode_ref(std::uint32_t *code) { + if (!code) { + return; + } + if ((*code & CS_CODE_OP_MASK) == CS_CODE_START) { + bcode_incr(code); + return; + } + switch (code[-1]&CS_CODE_OP_MASK) { + case CS_CODE_START: + bcode_incr(&code[-1]); + break; + case CS_CODE_OFFSET: + code -= std::ptrdiff_t(code[-1] >> 8); + bcode_incr(code); + break; + } +} + +void bcode_unref(std::uint32_t *code) { + if (!code) { + return; + } + if ((*code & CS_CODE_OP_MASK) == CS_CODE_START) { + bcode_decr(code); + return; + } + switch (code[-1]&CS_CODE_OP_MASK) { + case CS_CODE_START: + bcode_decr(&code[-1]); + break; + case CS_CODE_OFFSET: + code -= std::ptrdiff_t(code[-1] >> 8); + bcode_decr(code); + break; + } +} + +} /* namespace cscript */ diff --git a/src/cs_bcode.hh b/src/cs_bcode.hh new file mode 100644 index 0000000..8205cd2 --- /dev/null +++ b/src/cs_bcode.hh @@ -0,0 +1,74 @@ +#ifndef LIBCUBESCRIPT_BCODE_HH +#define LIBCUBESCRIPT_BCODE_HH + +#include + +#include +#include + +namespace cscript { + +struct cs_bcode; + +enum { + CS_VAL_NULL = 0, CS_VAL_INT, CS_VAL_FLOAT, CS_VAL_STRING, + CS_VAL_ANY, CS_VAL_CODE, CS_VAL_IDENT, CS_VAL_WORD, + CS_VAL_POP, CS_VAL_COND +}; + +/* instruction: uint32 [length 24][retflag 2][opcode 6] */ +enum { + CS_CODE_START = 0, + CS_CODE_OFFSET, + CS_CODE_NULL, CS_CODE_TRUE, CS_CODE_FALSE, CS_CODE_NOT, + CS_CODE_POP, + CS_CODE_ENTER, CS_CODE_ENTER_RESULT, + CS_CODE_EXIT, CS_CODE_RESULT_ARG, + CS_CODE_VAL, CS_CODE_VAL_INT, + CS_CODE_DUP, + CS_CODE_BOOL, + CS_CODE_BLOCK, CS_CODE_EMPTY, + CS_CODE_COMPILE, CS_CODE_COND, + CS_CODE_FORCE, + CS_CODE_RESULT, + CS_CODE_IDENT, CS_CODE_IDENT_U, CS_CODE_IDENT_ARG, + CS_CODE_COM, CS_CODE_COM_C, CS_CODE_COM_V, + CS_CODE_CONC, CS_CODE_CONC_W, CS_CODE_CONC_M, + CS_CODE_SVAR, CS_CODE_SVAR1, + CS_CODE_IVAR, CS_CODE_IVAR1, CS_CODE_IVAR2, CS_CODE_IVAR3, + CS_CODE_FVAR, CS_CODE_FVAR1, + CS_CODE_LOOKUP, CS_CODE_LOOKUP_U, CS_CODE_LOOKUP_ARG, + CS_CODE_LOOKUP_M, CS_CODE_LOOKUP_MU, CS_CODE_LOOKUP_MARG, + CS_CODE_ALIAS, CS_CODE_ALIAS_U, CS_CODE_ALIAS_ARG, + CS_CODE_CALL, CS_CODE_CALL_U, CS_CODE_CALL_ARG, + CS_CODE_PRINT, + CS_CODE_LOCAL, + CS_CODE_DO, CS_CODE_DO_ARGS, + CS_CODE_JUMP, CS_CODE_JUMP_B, CS_CODE_JUMP_RESULT, + CS_CODE_BREAK, + + CS_CODE_OP_MASK = 0x3F, + CS_CODE_RET = 6, + CS_CODE_RET_MASK = 0xC0, + + /* return type flags */ + CS_RET_NULL = CS_VAL_NULL << CS_CODE_RET, + CS_RET_STRING = CS_VAL_STRING << CS_CODE_RET, + CS_RET_INT = CS_VAL_INT << CS_CODE_RET, + CS_RET_FLOAT = CS_VAL_FLOAT << CS_CODE_RET, + + /* CS_CODE_JUMP_B, CS_CODE_JUMP_RESULT */ + CS_CODE_FLAG_TRUE = 1 << CS_CODE_RET, + CS_CODE_FLAG_FALSE = 0 << CS_CODE_RET +}; + +std::uint32_t *bcode_alloc(cs_state &cs, std::size_t sz); + +void bcode_incr(std::uint32_t *code); +void bcode_decr(std::uint32_t *code); +void bcode_ref(std::uint32_t *code); +void bcode_unref(std::uint32_t *code); + +} /* namespace cscript */ + +#endif diff --git a/src/cs_vm.cc b/src/cs_vm.cc index fa43a54..723b66d 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -135,104 +135,6 @@ cs_stack_state cs_error::save_stack(cs_state &cs) { return cs_stack_state(cs, ret, total > dalias->get_value()); } -struct bcode_hdr { - cs_shared_state *cs; /* needed to construct the allocator */ - std::size_t asize; /* alloc size of the bytecode block */ - std::uint32_t init; /* CS_CODE_START + refcount */ -}; - -/* returned address is the 'init' member of the header */ -static inline std::uint32_t *bcode_alloc(cs_state &cs, std::size_t sz) { - auto a = cs_allocator{cs}; - std::size_t hdrs = sizeof(bcode_hdr) / sizeof(std::uint32_t); - auto p = a.allocate(sz + hdrs - 1); - bcode_hdr *hdr = reinterpret_cast(p); - hdr->cs = cs_get_sstate(cs); - hdr->asize = sz + hdrs - 1; - return p + hdrs - 1; -} - -/* bc's address must be the 'init' member of the header */ -static inline void bcode_free(uint32_t *bc) { - auto *rp = bc + 1 - (sizeof(bcode_hdr) / sizeof(std::uint32_t)); - bcode_hdr *hdr = reinterpret_cast(rp); - cs_allocator{hdr->cs}.deallocate(rp, hdr->asize); -} - -static inline void bcode_incr(uint32_t *bc) { - *bc += 0x100; -} - -static inline void bcode_decr(uint32_t *bc) { - *bc -= 0x100; - if (std::int32_t(*bc) < 0x100) { - bcode_free(bc); - } -} - -void bcode_ref(uint32_t *code) { - if (!code) { - return; - } - if ((*code & CS_CODE_OP_MASK) == CS_CODE_START) { - bcode_incr(code); - return; - } - switch (code[-1]&CS_CODE_OP_MASK) { - case CS_CODE_START: - bcode_incr(&code[-1]); - break; - case CS_CODE_OFFSET: - code -= std::ptrdiff_t(code[-1] >> 8); - bcode_incr(code); - break; - } -} - -void bcode_unref(uint32_t *code) { - if (!code) { - return; - } - if ((*code & CS_CODE_OP_MASK) == CS_CODE_START) { - bcode_decr(code); - return; - } - switch (code[-1]&CS_CODE_OP_MASK) { - case CS_CODE_START: - bcode_decr(&code[-1]); - break; - case CS_CODE_OFFSET: - code -= std::ptrdiff_t(code[-1] >> 8); - bcode_decr(code); - break; - } -} - -cs_bcode_ref::cs_bcode_ref(cs_bcode *v): p_code(v) { - bcode_ref(reinterpret_cast(p_code)); -} -cs_bcode_ref::cs_bcode_ref(cs_bcode_ref const &v): p_code(v.p_code) { - bcode_ref(reinterpret_cast(p_code)); -} - -cs_bcode_ref::~cs_bcode_ref() { - bcode_unref(reinterpret_cast(p_code)); -} - -cs_bcode_ref &cs_bcode_ref::operator=(cs_bcode_ref const &v) { - bcode_unref(reinterpret_cast(p_code)); - p_code = v.p_code; - bcode_ref(reinterpret_cast(p_code)); - return *this; -} - -cs_bcode_ref &cs_bcode_ref::operator=(cs_bcode_ref &&v) { - bcode_unref(reinterpret_cast(p_code)); - p_code = v.p_code; - v.p_code = nullptr; - return *this; -} - void cs_alias_impl::clean_code() { uint32_t *bcode = reinterpret_cast(p_acode); if (bcode) { diff --git a/src/cs_vm.hh b/src/cs_vm.hh index f012be6..05fec23 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -9,6 +9,7 @@ #include #include "cs_util.hh" +#include "cs_bcode.hh" namespace cscript { @@ -201,12 +202,6 @@ struct cs_valarray { std::aligned_storage_t stor[N]; }; -enum { - CS_VAL_NULL = 0, CS_VAL_INT, CS_VAL_FLOAT, CS_VAL_STRING, - CS_VAL_ANY, CS_VAL_CODE, CS_VAL_IDENT, CS_VAL_WORD, - CS_VAL_POP, CS_VAL_COND -}; - static const int cs_valtypet[] = { CS_VAL_NULL, CS_VAL_INT, CS_VAL_FLOAT, CS_VAL_STRING, CS_VAL_CODE, CS_VAL_IDENT @@ -216,52 +211,6 @@ static inline int cs_vtype_to_int(cs_value_type v) { return cs_valtypet[int(v)]; } -/* instruction: uint32 [length 24][retflag 2][opcode 6] */ -enum { - CS_CODE_START = 0, - CS_CODE_OFFSET, - CS_CODE_NULL, CS_CODE_TRUE, CS_CODE_FALSE, CS_CODE_NOT, - CS_CODE_POP, - CS_CODE_ENTER, CS_CODE_ENTER_RESULT, - CS_CODE_EXIT, CS_CODE_RESULT_ARG, - CS_CODE_VAL, CS_CODE_VAL_INT, - CS_CODE_DUP, - CS_CODE_BOOL, - CS_CODE_BLOCK, CS_CODE_EMPTY, - CS_CODE_COMPILE, CS_CODE_COND, - CS_CODE_FORCE, - CS_CODE_RESULT, - CS_CODE_IDENT, CS_CODE_IDENT_U, CS_CODE_IDENT_ARG, - CS_CODE_COM, CS_CODE_COM_C, CS_CODE_COM_V, - CS_CODE_CONC, CS_CODE_CONC_W, CS_CODE_CONC_M, - CS_CODE_SVAR, CS_CODE_SVAR1, - CS_CODE_IVAR, CS_CODE_IVAR1, CS_CODE_IVAR2, CS_CODE_IVAR3, - CS_CODE_FVAR, CS_CODE_FVAR1, - CS_CODE_LOOKUP, CS_CODE_LOOKUP_U, CS_CODE_LOOKUP_ARG, - CS_CODE_LOOKUP_M, CS_CODE_LOOKUP_MU, CS_CODE_LOOKUP_MARG, - CS_CODE_ALIAS, CS_CODE_ALIAS_U, CS_CODE_ALIAS_ARG, - CS_CODE_CALL, CS_CODE_CALL_U, CS_CODE_CALL_ARG, - CS_CODE_PRINT, - CS_CODE_LOCAL, - CS_CODE_DO, CS_CODE_DO_ARGS, - CS_CODE_JUMP, CS_CODE_JUMP_B, CS_CODE_JUMP_RESULT, - CS_CODE_BREAK, - - CS_CODE_OP_MASK = 0x3F, - CS_CODE_RET = 6, - CS_CODE_RET_MASK = 0xC0, - - /* return type flags */ - CS_RET_NULL = CS_VAL_NULL << CS_CODE_RET, - CS_RET_STRING = CS_VAL_STRING << CS_CODE_RET, - CS_RET_INT = CS_VAL_INT << CS_CODE_RET, - CS_RET_FLOAT = CS_VAL_FLOAT << CS_CODE_RET, - - /* CS_CODE_JUMP_B, CS_CODE_JUMP_RESULT */ - CS_CODE_FLAG_TRUE = 1 << CS_CODE_RET, - CS_CODE_FLAG_FALSE = 0 << CS_CODE_RET -}; - struct CsBreakException { }; diff --git a/src/meson.build b/src/meson.build index cb48f07..8dbde8a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -4,6 +4,7 @@ libcubescript_header_src = [ ] libcubescript_src = [ + 'cs_bcode.cc', 'cs_gen.cc', 'cs_util.cc', 'cs_val.cc',