unify arg and non-arg opcodes

master
Daniel Kolesa 2021-03-28 00:19:51 +01:00
parent d1e131dbf6
commit 99f227bfd9
4 changed files with 54 additions and 119 deletions

View File

@ -46,16 +46,16 @@ enum {
BC_INST_COMPILE, BC_INST_COND, BC_INST_COMPILE, BC_INST_COND,
BC_INST_FORCE, BC_INST_FORCE,
BC_INST_RESULT, BC_INST_RESULT,
BC_INST_IDENT, BC_INST_IDENT_U, BC_INST_IDENT_ARG, BC_INST_IDENT, BC_INST_IDENT_U,
BC_INST_COM, BC_INST_COM_C, BC_INST_COM_V, BC_INST_COM, BC_INST_COM_C, BC_INST_COM_V,
BC_INST_CONC, BC_INST_CONC_W, BC_INST_CONC_M, BC_INST_CONC, BC_INST_CONC_W, BC_INST_CONC_M,
BC_INST_SVAR, BC_INST_SVAR1, BC_INST_SVAR, BC_INST_SVAR1,
BC_INST_IVAR, BC_INST_IVAR1, BC_INST_IVAR2, BC_INST_IVAR3, BC_INST_IVAR, BC_INST_IVAR1, BC_INST_IVAR2, BC_INST_IVAR3,
BC_INST_FVAR, BC_INST_FVAR1, BC_INST_FVAR, BC_INST_FVAR1,
BC_INST_LOOKUP, BC_INST_LOOKUP_U, BC_INST_LOOKUP_ARG, BC_INST_LOOKUP, BC_INST_LOOKUP_U,
BC_INST_LOOKUP_M, BC_INST_LOOKUP_MU, BC_INST_LOOKUP_MARG, BC_INST_LOOKUP_M, BC_INST_LOOKUP_MU,
BC_INST_ALIAS, BC_INST_ALIAS_U, BC_INST_ALIAS_ARG, BC_INST_ALIAS, BC_INST_ALIAS_U,
BC_INST_CALL, BC_INST_CALL_U, BC_INST_CALL_ARG, BC_INST_CALL, BC_INST_CALL_U,
BC_INST_PRINT, BC_INST_PRINT,
BC_INST_LOCAL, BC_INST_LOCAL,
BC_INST_DO, BC_INST_DO_ARGS, BC_INST_DO, BC_INST_DO_ARGS,

View File

@ -294,28 +294,21 @@ lookupid:
return; return;
case VAL_COND: case VAL_COND:
gs.code.push_back( gs.code.push_back(
((id->get_flags() & IDENT_FLAG_ARG) BC_INST_LOOKUP_M | (id->get_index() << 8)
? BC_INST_LOOKUP_MARG
: BC_INST_LOOKUP_M
) | (id->get_index() << 8)
); );
break; break;
case VAL_CODE: case VAL_CODE:
case VAL_IDENT: case VAL_IDENT:
gs.code.push_back( gs.code.push_back(
((id->get_flags() & IDENT_FLAG_ARG) BC_INST_LOOKUP_M | BC_RET_STRING |
? BC_INST_LOOKUP_MARG (id->get_index() << 8)
: BC_INST_LOOKUP_M
) | BC_RET_STRING | (id->get_index() << 8)
); );
break; break;
default: default:
gs.code.push_back( gs.code.push_back(
((id->get_flags() & IDENT_FLAG_ARG) BC_INST_LOOKUP |
? BC_INST_LOOKUP_ARG ret_code(ltype, BC_RET_STRING) |
: BC_INST_LOOKUP (id->get_index() << 8)
) | ret_code(ltype, BC_RET_STRING) |
(id->get_index() << 8)
); );
break; break;
} }
@ -552,10 +545,7 @@ lookupid:
goto done; goto done;
case ident_type::ALIAS: case ident_type::ALIAS:
gs.code.push_back( gs.code.push_back(
((id->get_flags() & IDENT_FLAG_ARG) BC_INST_LOOKUP_M | (id->get_index() << 8)
? BC_INST_LOOKUP_MARG
: BC_INST_LOOKUP_M
) | (id->get_index() << 8)
); );
goto done; goto done;
default: default:
@ -1054,8 +1044,7 @@ static void compile_alias(codegen_state &gs, alias *id, bool &more, int prevargs
++numargs; ++numargs;
} }
gs.code.push_back( gs.code.push_back(
((id->get_flags() & IDENT_FLAG_ARG) ? BC_INST_CALL_ARG : BC_INST_CALL) BC_INST_CALL | (numargs << 8) | (id->get_index() << 13)
| (numargs << 8) | (id->get_index() << 13)
); );
} }
@ -1244,10 +1233,7 @@ static void compilestatements(codegen_state &gs, int rettype, int brak, int prev
gs.gen_str(); gs.gen_str();
} }
gs.code.push_back( gs.code.push_back(
((id->get_flags() & IDENT_FLAG_ARG) BC_INST_ALIAS | (id->get_index() << 8)
? BC_INST_ALIAS_ARG
: BC_INST_ALIAS
) | (id->get_index() << 8)
); );
goto endstatement; goto endstatement;
case ident_type::IVAR: case ident_type::IVAR:

View File

@ -109,12 +109,7 @@ struct codegen_state {
void gen_float(std::string_view word); void gen_float(std::string_view word);
void gen_ident(ident *id) { void gen_ident(ident *id) {
code.push_back( code.push_back(BC_INST_IDENT | (id->get_index() << 8));
((id->get_flags() & IDENT_FLAG_ARG)
? BC_INST_IDENT_ARG
: BC_INST_IDENT
) | (id->get_index() << 8)
);
} }
void gen_ident() { void gen_ident() {

View File

@ -261,7 +261,13 @@ run_depth_guard::~run_depth_guard() { --rundepth; }
static inline alias *get_lookup_id(thread_state &ts, std::uint32_t op) { static inline alias *get_lookup_id(thread_state &ts, std::uint32_t op) {
ident *id = ts.istate->identmap[op >> 8]; ident *id = ts.istate->identmap[op >> 8];
if (id->get_flags() & IDENT_FLAG_UNKNOWN) {
auto flags = id->get_flags();
if (flags & IDENT_FLAG_ARG) {
if (!ident_is_used_arg(id, ts)) {
return nullptr;
}
} else if (flags & IDENT_FLAG_UNKNOWN) {
throw error{ throw error{
*ts.pstate, "unknown alias lookup: %s", id->get_name().data() *ts.pstate, "unknown alias lookup: %s", id->get_name().data()
}; };
@ -269,14 +275,6 @@ static inline alias *get_lookup_id(thread_state &ts, std::uint32_t op) {
return static_cast<alias *>(id); return static_cast<alias *>(id);
} }
static inline alias *get_lookuparg_id(thread_state &ts, std::uint32_t op) {
ident *id = ts.istate->identmap[op >> 8];
if (!ident_is_used_arg(id, ts)) {
return nullptr;
}
return static_cast<alias *>(id);
}
static inline int get_lookupu_type( static inline int get_lookupu_type(
thread_state &ts, any_value &arg, ident *&id, std::uint32_t op thread_state &ts, any_value &arg, ident *&id, std::uint32_t op
) { ) {
@ -709,14 +707,14 @@ std::uint32_t *vm_exec(
continue; continue;
} }
case BC_INST_IDENT: case BC_INST_IDENT: {
args.emplace_back(cs).set_ident(ts.istate->identmap[op >> 8]);
continue;
case BC_INST_IDENT_ARG: {
alias *a = static_cast<alias *>( alias *a = static_cast<alias *>(
ts.istate->identmap[op >> 8] ts.istate->identmap[op >> 8]
); );
if (!ident_is_used_arg(a, ts)) { if (
(a->get_flags() & IDENT_FLAG_ARG) &&
!ident_is_used_arg(a, ts)
) {
any_value nv{cs}; any_value nv{cs};
static_cast<alias_impl *>(a)->push_arg( static_cast<alias_impl *>(a)->push_arg(
nv, ts.callstack->argstack[a->get_index()], nv, ts.callstack->argstack[a->get_index()],
@ -775,13 +773,7 @@ std::uint32_t *vm_exec(
} }
} }
case BC_INST_LOOKUP | BC_RET_STRING: { case BC_INST_LOOKUP | BC_RET_STRING: {
auto &v = args.emplace_back(cs); alias *a = get_lookup_id(ts, op);
v = get_lookup_id(ts, op)->get_value();
v.force_str();
continue;
}
case BC_INST_LOOKUP_ARG | BC_RET_STRING: {
alias *a = get_lookuparg_id(ts, op);
if (!a) { if (!a) {
args.emplace_back(cs).set_str(""); args.emplace_back(cs).set_str("");
} else { } else {
@ -820,13 +812,8 @@ std::uint32_t *vm_exec(
continue; continue;
} }
} }
case BC_INST_LOOKUP | BC_RET_INT: case BC_INST_LOOKUP | BC_RET_INT: {
args.emplace_back(cs).set_int( alias *a = get_lookup_id(ts, op);
get_lookup_id(ts, op)->get_value().get_int()
);
continue;
case BC_INST_LOOKUP_ARG | BC_RET_INT: {
alias *a = get_lookuparg_id(ts, op);
if (!a) { if (!a) {
args.emplace_back(cs).set_int(0); args.emplace_back(cs).set_int(0);
} else { } else {
@ -865,13 +852,8 @@ std::uint32_t *vm_exec(
continue; continue;
} }
} }
case BC_INST_LOOKUP | BC_RET_FLOAT: case BC_INST_LOOKUP | BC_RET_FLOAT: {
args.emplace_back(cs).set_float( alias *a = get_lookup_id(ts, op);
get_lookup_id(ts, op)->get_value().get_float()
);
continue;
case BC_INST_LOOKUP_ARG | BC_RET_FLOAT: {
alias *a = get_lookuparg_id(ts, op);
if (!a) { if (!a) {
args.emplace_back(cs).set_float(float_type(0)); args.emplace_back(cs).set_float(float_type(0));
} else { } else {
@ -904,13 +886,8 @@ std::uint32_t *vm_exec(
continue; continue;
} }
} }
case BC_INST_LOOKUP | BC_RET_NULL: case BC_INST_LOOKUP | BC_RET_NULL: {
get_lookup_id(ts, op)->get_value().get_val( alias *a = get_lookup_id(ts, op);
args.emplace_back(cs)
);
continue;
case BC_INST_LOOKUP_ARG | BC_RET_NULL: {
alias *a = get_lookuparg_id(ts, op);
if (!a) { if (!a) {
args.emplace_back(cs).set_none(); args.emplace_back(cs).set_none();
} else { } else {
@ -946,13 +923,7 @@ std::uint32_t *vm_exec(
} }
} }
case BC_INST_LOOKUP_M | BC_RET_STRING: { case BC_INST_LOOKUP_M | BC_RET_STRING: {
auto &v = args.emplace_back(cs); alias *a = get_lookup_id(ts, op);
v = get_lookup_id(ts, op)->get_value();
v.force_str();
continue;
}
case BC_INST_LOOKUP_MARG | BC_RET_STRING: {
alias *a = get_lookuparg_id(ts, op);
if (!a) { if (!a) {
args.emplace_back(cs).set_str(""); args.emplace_back(cs).set_str("");
} else { } else {
@ -985,11 +956,8 @@ std::uint32_t *vm_exec(
continue; continue;
} }
} }
case BC_INST_LOOKUP_M | BC_RET_NULL: case BC_INST_LOOKUP_M | BC_RET_NULL: {
get_lookup_id(ts, op)->get_cval(args.emplace_back(cs)); alias *a = get_lookup_id(ts, op);
continue;
case BC_INST_LOOKUP_MARG | BC_RET_NULL: {
alias *a = get_lookuparg_id(ts, op);
if (!a) { if (!a) {
args.emplace_back(cs).set_none(); args.emplace_back(cs).set_none();
} else { } else {
@ -1193,18 +1161,18 @@ std::uint32_t *vm_exec(
continue; continue;
} }
case BC_INST_ALIAS: case BC_INST_ALIAS: {
static_cast<alias_impl *>( auto *imp = static_cast<alias_impl *>(
ts.istate->identmap[op >> 8] ts.istate->identmap[op >> 8]
)->set_alias(ts, args.back()); );
args.pop_back(); if (imp->get_flags() & IDENT_FLAG_ARG) {
continue; imp->set_arg(ts, args.back());
case BC_INST_ALIAS_ARG: } else {
static_cast<alias_impl *>( imp->set_alias(ts, args.back());
ts.istate->identmap[op >> 8] }
)->set_arg(ts, args.back());
args.pop_back(); args.pop_back();
continue; continue;
}
case BC_INST_ALIAS_U: { case BC_INST_ALIAS_U: {
auto v = std::move(args.back()); auto v = std::move(args.back());
args.pop_back(); args.pop_back();
@ -1222,7 +1190,14 @@ std::uint32_t *vm_exec(
std::size_t callargs = (op >> 8) & 0x1F; std::size_t callargs = (op >> 8) & 0x1F;
std::size_t nnargs = args.size(); std::size_t nnargs = args.size();
std::size_t offset = nnargs - callargs; std::size_t offset = nnargs - callargs;
if (id->get_flags() & IDENT_FLAG_UNKNOWN) { auto flags = id->get_flags();
if (flags & IDENT_FLAG_ARG) {
if (!ident_is_used_arg(id, ts)) {
args.resize(offset, any_value{cs});
force_arg(result, op & BC_INST_RET_MASK);
continue;
}
} else if (flags & IDENT_FLAG_UNKNOWN) {
force_arg(result, op & BC_INST_RET_MASK); force_arg(result, op & BC_INST_RET_MASK);
throw error{ throw error{
cs, "unknown command: %s", id->get_name().data() cs, "unknown command: %s", id->get_name().data()
@ -1235,27 +1210,6 @@ std::uint32_t *vm_exec(
args.resize(nnargs, any_value{cs}); args.resize(nnargs, any_value{cs});
continue; continue;
} }
case BC_INST_CALL_ARG | BC_RET_NULL:
case BC_INST_CALL_ARG | BC_RET_STRING:
case BC_INST_CALL_ARG | BC_RET_FLOAT:
case BC_INST_CALL_ARG | BC_RET_INT: {
result.force_none();
ident *id = ts.istate->identmap[op >> 13];
std::size_t callargs = (op >> 8) & 0x1F;
std::size_t nnargs = args.size();
std::size_t offset = nnargs - callargs;
if (!ident_is_used_arg(id, ts)) {
args.resize(offset, any_value{cs});
force_arg(result, op & BC_INST_RET_MASK);
continue;
}
exec_alias(
ts, static_cast<alias *>(id), &args[0], result, callargs,
nnargs, offset, 0, op
);
args.resize(nnargs, any_value{cs});
continue;
}
case BC_INST_CALL_U | BC_RET_NULL: case BC_INST_CALL_U | BC_RET_NULL:
case BC_INST_CALL_U | BC_RET_STRING: case BC_INST_CALL_U | BC_RET_STRING: