move idents/identmap into internal state

master
Daniel Kolesa 2016-09-12 20:04:59 +02:00
parent 931f7294de
commit ce62593840
7 changed files with 148 additions and 87 deletions

View File

@ -190,6 +190,9 @@ private:
int p_index = -1;
};
using CsIdentRange = ostd::PointerRange<CsIdent *>;
using CsConstIdentRange = ostd::PointerRange<CsIdent const *>;
using CsVarCb = ostd::Function<void(CsState &, CsIdent &)>;
struct OSTD_EXPORT CsVar: CsIdent {
@ -369,10 +372,10 @@ private:
CsState &p_state;
};
struct OSTD_EXPORT CsState {
CsMap<ostd::ConstCharRange, CsIdent *> idents;
CsVector<CsIdent *> identmap;
struct CsSharedState;
struct OSTD_EXPORT CsState {
CsSharedState *p_state;
CsIdentLink *p_callstack = nullptr;
int identflags = 0;
@ -381,6 +384,10 @@ struct OSTD_EXPORT CsState {
CsState();
virtual ~CsState();
bool is_alive() const {
return bool(p_state);
}
CsStream const &get_out() const;
CsStream &get_out();
void set_out(CsStream &s);
@ -492,25 +499,12 @@ struct OSTD_EXPORT CsState {
));
}
CsIdent *get_ident(ostd::ConstCharRange name) {
CsIdent **id = idents.at(name);
if (!id) {
return nullptr;
}
return *id;
}
CsIdent *get_ident(ostd::ConstCharRange name);
CsAlias *get_alias(ostd::ConstCharRange name);
bool have_ident(ostd::ConstCharRange name);
CsAlias *get_alias(ostd::ConstCharRange name) {
CsIdent *id = get_ident(name);
if (!id->is_alias()) {
return nullptr;
}
return static_cast<CsAlias *>(id);
}
bool have_ident(ostd::ConstCharRange name) {
return idents.at(name) != nullptr;
}
CsIdentRange get_idents();
CsConstIdentRange get_idents() const;
bool reset_var(ostd::ConstCharRange name);
void touch_var(ostd::ConstCharRange name);

View File

@ -66,7 +66,7 @@ bool CsStackState::gap() const {
}
CsStackState cs_save_stack(CsState &cs) {
CsIvar *dalias = static_cast<CsIvar *>(cs.identmap[DbgaliasIdx]);
CsIvar *dalias = static_cast<CsIvar *>(cs.p_state->identmap[DbgaliasIdx]);
if (!dalias->get_value()) {
return CsStackState(nullptr, !!cs.p_callstack);
}
@ -384,7 +384,7 @@ static inline void callcommand(
if (rep) {
break;
}
args[i].set_ident(cs.identmap[DummyIdx]);
args[i].set_ident(cs.p_state->identmap[DummyIdx]);
fakeargs++;
} else {
cs.force_ident(args[i]);
@ -432,11 +432,11 @@ static inline void cs_call_alias(
CsState &cs, CsAlias *a, CsValue *args, CsValue &result,
int callargs, int &nargs, int offset, int skip, ostd::Uint32 op
) {
CsIvar *anargs = static_cast<CsIvar *>(cs.identmap[NumargsIdx]);
CsIvar *anargs = static_cast<CsIvar *>(cs.p_state->identmap[NumargsIdx]);
CsIdentStack argstack[MaxArguments];
for(int i = 0; i < callargs; i++) {
CsAliasInternal::push_arg(
static_cast<CsAlias *>(cs.identmap[i]),
static_cast<CsAlias *>(cs.p_state->identmap[i]),
args[offset + i], argstack[i], false
);
}
@ -459,13 +459,15 @@ static inline void cs_call_alias(
cs.p_callstack = aliaslink.next;
cs.identflags = oldflags;
for (int i = 0; i < callargs; i++) {
CsAliasInternal::pop_arg(static_cast<CsAlias *>(cs.identmap[i]));
CsAliasInternal::pop_arg(
static_cast<CsAlias *>(cs.p_state->identmap[i])
);
}
int argmask = aliaslink.usedargs & (~0 << callargs);
for (; argmask; ++callargs) {
if (argmask & (1 << callargs)) {
CsAliasInternal::pop_arg(static_cast<CsAlias *>(
cs.identmap[callargs])
cs.p_state->identmap[callargs])
);
argmask &= ~(1 << callargs);
}
@ -480,7 +482,7 @@ static constexpr int MaxRunDepth = 255;
static thread_local int rundepth = 0;
static inline CsAlias *cs_get_lookup_id(CsState &cs, ostd::Uint32 op) {
CsIdent *id = cs.identmap[op >> 8];
CsIdent *id = cs.p_state->identmap[op >> 8];
if (id->get_flags() & CsIdfUnknown) {
cs_debug_code(cs, "unknown alias lookup: %s", id->get_name());
}
@ -488,7 +490,7 @@ static inline CsAlias *cs_get_lookup_id(CsState &cs, ostd::Uint32 op) {
}
static inline CsAlias *cs_get_lookuparg_id(CsState &cs, ostd::Uint32 op) {
CsIdent *id = cs.identmap[op >> 8];
CsIdent *id = cs.p_state->identmap[op >> 8];
if (!cs_is_arg_used(cs, id)) {
return nullptr;
}
@ -631,7 +633,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
args[numargs++] = ostd::move(result);
continue;
case CsCodePrint:
cs.print_var(static_cast<CsVar *>(cs.identmap[op >> 8]));
cs.print_var(static_cast<CsVar *>(cs.p_state->identmap[op >> 8]));
continue;
case CsCodeLocal: {
@ -892,10 +894,12 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
}
case CsCodeIdent:
args[numargs++].set_ident(cs.identmap[op >> 8]);
args[numargs++].set_ident(cs.p_state->identmap[op >> 8]);
continue;
case CsCodeIdentArg: {
CsAlias *a = static_cast<CsAlias *>(cs.identmap[op >> 8]);
CsAlias *a = static_cast<CsAlias *>(
cs.p_state->identmap[op >> 8]
);
if (!cs_is_arg_used(cs, a)) {
CsValue nv;
CsAliasInternal::push_arg(
@ -908,7 +912,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
}
case CsCodeIdentU: {
CsValue &arg = args[numargs - 1];
CsIdent *id = cs.identmap[DummyIdx];
CsIdent *id = cs.p_state->identmap[DummyIdx];
if (
arg.get_type() == CsValueType::String ||
arg.get_type() == CsValueType::Macro ||
@ -1176,58 +1180,58 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
case CsCodeSvar | CsRetString:
case CsCodeSvar | CsRetNull:
args[numargs++].set_str(
static_cast<CsSvar *>(cs.identmap[op >> 8])->get_value()
);
args[numargs++].set_str(static_cast<CsSvar *>(
cs.p_state->identmap[op >> 8]
)->get_value());
continue;
case CsCodeSvar | CsRetInt:
args[numargs++].set_int(cs_parse_int(
static_cast<CsSvar *>(cs.identmap[op >> 8])->get_value()
));
args[numargs++].set_int(cs_parse_int(static_cast<CsSvar *>(
cs.p_state->identmap[op >> 8]
)->get_value()));
continue;
case CsCodeSvar | CsRetFloat:
args[numargs++].set_float(cs_parse_float(
static_cast<CsSvar *>(cs.identmap[op >> 8])->get_value()
));
args[numargs++].set_float(cs_parse_float(static_cast<CsSvar *>(
cs.p_state->identmap[op >> 8]
)->get_value()));
continue;
case CsCodeSvarM:
args[numargs++].set_cstr(
static_cast<CsSvar *>(cs.identmap[op >> 8])->get_value()
);
args[numargs++].set_cstr(static_cast<CsSvar *>(
cs.p_state->identmap[op >> 8]
)->get_value());
continue;
case CsCodeSvar1:
cs.set_var_str_checked(
static_cast<CsSvar *>(cs.identmap[op >> 8]),
static_cast<CsSvar *>(cs.p_state->identmap[op >> 8]),
args[--numargs].get_strr()
);
continue;
case CsCodeIvar | CsRetInt:
case CsCodeIvar | CsRetNull:
args[numargs++].set_int(
static_cast<CsIvar *>(cs.identmap[op >> 8])->get_value()
);
args[numargs++].set_int(static_cast<CsIvar *>(
cs.p_state->identmap[op >> 8]
)->get_value());
continue;
case CsCodeIvar | CsRetString:
args[numargs++].set_str(ostd::move(intstr(
static_cast<CsIvar *>(cs.identmap[op >> 8])->get_value()
)));
args[numargs++].set_str(ostd::move(intstr(static_cast<CsIvar *>(
cs.p_state->identmap[op >> 8]
)->get_value())));
continue;
case CsCodeIvar | CsRetFloat:
args[numargs++].set_float(CsFloat(
static_cast<CsIvar *>(cs.identmap[op >> 8])->get_value()
));
args[numargs++].set_float(CsFloat(static_cast<CsIvar *>(
cs.p_state->identmap[op >> 8]
)->get_value()));
continue;
case CsCodeIvar1:
cs.set_var_int_checked(
static_cast<CsIvar *>(cs.identmap[op >> 8]),
static_cast<CsIvar *>(cs.p_state->identmap[op >> 8]),
args[--numargs].get_int()
);
continue;
case CsCodeIvar2:
numargs -= 2;
cs.set_var_int_checked(
static_cast<CsIvar *>(cs.identmap[op >> 8]),
static_cast<CsIvar *>(cs.p_state->identmap[op >> 8]),
(args[numargs].get_int() << 16)
| (args[numargs + 1].get_int() << 8)
);
@ -1235,7 +1239,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
case CsCodeIvar3:
numargs -= 3;
cs.set_var_int_checked(
static_cast<CsIvar *>(cs.identmap[op >> 8]),
static_cast<CsIvar *>(cs.p_state->identmap[op >> 8]),
(args[numargs].get_int() << 16)
| (args[numargs + 1].get_int() << 8)
| (args[numargs + 2].get_int()));
@ -1243,23 +1247,25 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
case CsCodeFvar | CsRetFloat:
case CsCodeFvar | CsRetNull:
args[numargs++].set_float(
static_cast<CsFvar *>(cs.identmap[op >> 8])->get_value()
);
args[numargs++].set_float(static_cast<CsFvar *>(
cs.p_state->identmap[op >> 8]
)->get_value());
continue;
case CsCodeFvar | CsRetString:
args[numargs++].set_str(ostd::move(floatstr(
static_cast<CsFvar *>(cs.identmap[op >> 8])->get_value()
static_cast<CsFvar *>(
cs.p_state->identmap[op >> 8]
)->get_value()
)));
continue;
case CsCodeFvar | CsRetInt:
args[numargs++].set_int(int(
static_cast<CsFvar *>(cs.identmap[op >> 8])->get_value()
));
args[numargs++].set_int(int(static_cast<CsFvar *>(
cs.p_state->identmap[op >> 8]
)->get_value()));
continue;
case CsCodeFvar1:
cs.set_var_float_checked(
static_cast<CsFvar *>(cs.identmap[op >> 8]),
static_cast<CsFvar *>(cs.p_state->identmap[op >> 8]),
args[--numargs].get_float()
);
continue;
@ -1268,7 +1274,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
case CsCodeCom | CsRetString:
case CsCodeCom | CsRetFloat:
case CsCodeCom | CsRetInt: {
CsCommand *id = static_cast<CsCommand *>(cs.identmap[op >> 8]);
CsCommand *id = static_cast<CsCommand *>(
cs.p_state->identmap[op >> 8]
);
int offset = numargs - id->get_num_args();
result.force_null();
CsCommandInternal::call(
@ -1284,7 +1292,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
case CsCodeComV | CsRetString:
case CsCodeComV | CsRetFloat:
case CsCodeComV | CsRetInt: {
CsCommand *id = static_cast<CsCommand *>(cs.identmap[op >> 13]);
CsCommand *id = static_cast<CsCommand *>(
cs.p_state->identmap[op >> 13]
);
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
result.force_null();
CsCommandInternal::call(
@ -1298,7 +1308,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
case CsCodeComC | CsRetString:
case CsCodeComC | CsRetFloat:
case CsCodeComC | CsRetInt: {
CsCommand *id = static_cast<CsCommand *>(cs.identmap[op >> 13]);
CsCommand *id = static_cast<CsCommand *>(
cs.p_state->identmap[op >> 13]
);
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
result.force_null();
{
@ -1353,13 +1365,13 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
case CsCodeAlias:
CsAliasInternal::set_alias(
static_cast<CsAlias *>(cs.identmap[op >> 8]),
static_cast<CsAlias *>(cs.p_state->identmap[op >> 8]),
cs, args[--numargs]
);
continue;
case CsCodeAliasArg:
CsAliasInternal::set_arg(
static_cast<CsAlias *>(cs.identmap[op >> 8]),
static_cast<CsAlias *>(cs.p_state->identmap[op >> 8]),
cs, args[--numargs]
);
continue;
@ -1375,7 +1387,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
case CsCodeCall | CsRetFloat:
case CsCodeCall | CsRetInt: {
result.force_null();
CsIdent *id = cs.identmap[op >> 13];
CsIdent *id = cs.p_state->identmap[op >> 13];
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
if (id->get_flags() & CsIdfUnknown) {
cs_debug_code(cs, "unknown command: %s", id->get_name());
@ -1394,7 +1406,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
case CsCodeCallArg | CsRetFloat:
case CsCodeCallArg | CsRetInt: {
result.force_null();
CsIdent *id = cs.identmap[op >> 13];
CsIdent *id = cs.p_state->identmap[op >> 13];
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
if (!cs_is_arg_used(cs, id)) {
numargs = offset;

View File

@ -89,6 +89,11 @@ enum {
CsRetFloat = CsValFloat << CsCodeRet,
};
struct CsSharedState {
CsMap<ostd::ConstCharRange, CsIdent *> idents;
CsVector<CsIdent *> identmap;
};
template<typename T>
constexpr ostd::Size CsTypeStorageSize =
(sizeof(T) - 1) / sizeof(ostd::Uint32) + 1;
@ -202,7 +207,7 @@ struct GenState {
}
void gen_ident() {
gen_ident(cs.identmap[DummyIdx]);
gen_ident(cs.p_state->identmap[DummyIdx]);
}
void gen_ident(ostd::ConstCharRange word) {
@ -343,7 +348,7 @@ static void cs_do_args(CsState &cs, F body) {
for (int i = 0; argmask1; argmask1 >>= 1, ++i) {
if (argmask1 & 1) {
CsAliasInternal::undo_arg(
static_cast<CsAlias *>(cs.identmap[i]), argstack[i]
static_cast<CsAlias *>(cs.p_state->identmap[i]), argstack[i]
);
}
}
@ -359,7 +364,7 @@ static void cs_do_args(CsState &cs, F body) {
for (int i = 0; argmask2; argmask2 >>= 1, ++i) {
if (argmask2 & 1) {
CsAliasInternal::redo_arg(
static_cast<CsAlias *>(cs.identmap[i]), argstack[i]
static_cast<CsAlias *>(cs.p_state->identmap[i]), argstack[i]
);
}
}

View File

@ -253,8 +253,19 @@ int CsCommand::get_num_args() const {
void cs_init_lib_base(CsState &cs);
CsState::CsState():
p_callhook(), p_panicfunc(), p_out(&ostd::out), p_err(&ostd::err)
p_state(nullptr), p_callhook(), p_panicfunc(),
p_out(&ostd::out), p_err(&ostd::err)
{
CsSharedState *ps = static_cast<CsSharedState *>(
alloc(nullptr, 0, sizeof(CsSharedState))
);
if (!ps) {
return;
}
/* TODO: protect with a Box */
new (ps) CsSharedState();
p_state = ps;
/* default panic func */
p_panicfunc = [](CsState &cs, ostd::ConstCharRange v, CsStackState) {
cs.get_err().writefln(
@ -342,7 +353,10 @@ CsState::CsState():
}
CsState::~CsState() {
for (auto &p: idents.iter()) {
if (!p_state) {
return;
}
for (auto &p: p_state->idents.iter()) {
CsIdent *i = p.second;
CsAlias *a = i->get_alias();
if (a) {
@ -351,6 +365,8 @@ CsState::~CsState() {
}
delete i;
}
p_state->~CsSharedState();
alloc(p_state, sizeof(CsSharedState), 0);
}
CsStream const &CsState::get_out() const {
@ -484,7 +500,7 @@ void CsState::clear_override(CsIdent &id) {
}
void CsState::clear_overrides() {
for (auto &p: idents.iter()) {
for (auto &p: p_state->idents.iter()) {
clear_override(*(p.second));
}
}
@ -493,9 +509,9 @@ CsIdent *CsState::add_ident(CsIdent *id) {
if (!id) {
return nullptr;
}
idents[id->get_name()] = id;
id->p_index = identmap.size();
return identmap.push(id);
p_state->idents[id->get_name()] = id;
id->p_index = p_state->identmap.size();
return p_state->identmap.push(id);
}
CsIdent *CsState::new_ident(ostd::ConstCharRange name, int flags) {
@ -505,7 +521,7 @@ CsIdent *CsState::new_ident(ostd::ConstCharRange name, int flags) {
cs_debug_code(
*this, "number %s is not a valid identifier name", name
);
return identmap[DummyIdx];
return p_state->identmap[DummyIdx];
}
id = add_ident(new CsAlias(name, flags));
}
@ -526,8 +542,39 @@ CsIdent *CsState::force_ident(CsValue &v) {
default:
break;
}
v.set_ident(identmap[DummyIdx]);
return identmap[DummyIdx];
v.set_ident(p_state->identmap[DummyIdx]);
return p_state->identmap[DummyIdx];
}
CsIdent *CsState::get_ident(ostd::ConstCharRange name) {
CsIdent **id = p_state->idents.at(name);
if (!id) {
return nullptr;
}
return *id;
}
CsAlias *CsState::get_alias(ostd::ConstCharRange name) {
CsIdent **id = p_state->idents.at(name);
if (!id || !(*id)->is_alias()) {
return nullptr;
}
return static_cast<CsAlias *>(*id);
}
bool CsState::have_ident(ostd::ConstCharRange name) {
return p_state->idents.at(name) != nullptr;
}
CsIdentRange CsState::get_idents() {
return CsIdentRange(p_state->identmap.data(), p_state->identmap.size());
}
CsConstIdentRange CsState::get_idents() const {
return CsConstIdentRange(
const_cast<CsIdent const **>(p_state->identmap.data()),
p_state->identmap.size()
);
}
CsIvar *CsState::new_ivar(

View File

@ -18,7 +18,7 @@ static CsState *ln_cs = nullptr;
#ifdef CS_REPL_HAS_COMPLETE
static void ln_complete(char const *buf, linenoiseCompletions *lc) {
ostd::ConstCharRange cmd = get_complete_cmd(buf);
for (auto id: ln_cs->identmap.iter()) {
for (auto id: ln_cs->get_idents()) {
if (!id->is_command()) {
continue;
}

View File

@ -20,7 +20,7 @@ static char *ln_complete_list(char const *buf, int state) {
if (!state) {
cmd = get_complete_cmd(buf);
itr = rd_cs->identmap.iter();
itr = rd_cs->get_idents();
}
for (; !itr.empty(); itr.pop_front()) {

View File

@ -273,6 +273,9 @@ static void do_tty(CsState &cs) {
int main(int argc, char **argv) {
CsState gcs;
if (!gcs.is_alive()) {
return 1;
}
gcs.init_libs();
gcs.new_command("exec", "sb", [](CsState &cs, auto args, auto &res) {