throw out of the VM on errors

master
Daniel Kolesa 2016-09-15 20:55:58 +02:00
parent 214ecf8ad2
commit 377e9d7702
2 changed files with 16 additions and 19 deletions

View File

@ -238,9 +238,7 @@ static inline void force_arg(CsValue &v, int type) {
} }
} }
static ostd::Uint32 *skipcode( static ostd::Uint32 *skipcode(ostd::Uint32 *code) {
ostd::Uint32 *code, CsValue *result = nullptr
) {
int depth = 0; int depth = 0;
for (;;) { for (;;) {
ostd::Uint32 op = *code++; ostd::Uint32 op = *code++;
@ -270,9 +268,6 @@ static ostd::Uint32 *skipcode(
case CsCodeExit | CsRetInt: case CsCodeExit | CsRetInt:
case CsCodeExit | CsRetFloat: case CsCodeExit | CsRetFloat:
if (depth <= 0) { if (depth <= 0) {
if (result) {
force_arg(*result, op & CsCodeRetMask);
}
return code; return code;
} }
--depth; --depth;
@ -503,7 +498,7 @@ static thread_local int rundepth = 0;
static inline CsAlias *cs_get_lookup_id(CsState &cs, ostd::Uint32 op) { static inline CsAlias *cs_get_lookup_id(CsState &cs, ostd::Uint32 op) {
CsIdent *id = cs.p_state->identmap[op >> 8]; CsIdent *id = cs.p_state->identmap[op >> 8];
if (id->get_flags() & CsIdfUnknown) { if (id->get_flags() & CsIdfUnknown) {
cs_debug_code(cs, "unknown alias lookup: %s", id->get_name()); throw CsErrorException(cs, "unknown alias lookup: %s", id->get_name());
} }
return static_cast<CsAlias *>(id); return static_cast<CsAlias *>(id);
} }
@ -554,15 +549,13 @@ static inline int cs_get_lookupu_type(
return CsIdUnknown; return CsIdUnknown;
} }
} }
cs_debug_code(cs, "unknown alias lookup: %s", arg.get_strr()); throw CsErrorException(cs, "unknown alias lookup: %s", arg.get_strr());
return CsIdUnknown;
} }
static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
result.set_null(); result.set_null();
if (rundepth >= MaxRunDepth) { if (rundepth >= MaxRunDepth) {
cs_debug_code(cs, "exceeded recursion limit"); throw CsErrorException(cs, "exceeded recursion limit");
return skipcode(code, &result);
} }
++rundepth; ++rundepth;
int numargs = 0; int numargs = 0;
@ -1423,10 +1416,10 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
CsIdent *id = cs.p_state->identmap[op >> 13]; CsIdent *id = cs.p_state->identmap[op >> 13];
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs; int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
if (id->get_flags() & CsIdfUnknown) { if (id->get_flags() & CsIdfUnknown) {
cs_debug_code(cs, "unknown command: %s", id->get_name());
numargs = offset;
force_arg(result, op & CsCodeRetMask); force_arg(result, op & CsCodeRetMask);
continue; throw CsErrorException(
cs, "unknown command: %s", id->get_name()
);
} }
cs_call_alias( cs_call_alias(
cs, static_cast<CsAlias *>(id), args, result, callargs, cs, static_cast<CsAlias *>(id), args, result, callargs,
@ -1476,11 +1469,11 @@ noid:
if (cs_check_num(idarg.get_strr())) { if (cs_check_num(idarg.get_strr())) {
goto litval; goto litval;
} }
cs_debug_code(cs, "unknown command: %s", idarg.get_strr());
result.force_null(); result.force_null();
numargs = offset - 1;
force_arg(result, op & CsCodeRetMask); force_arg(result, op & CsCodeRetMask);
continue; throw CsErrorException(
cs, "unknown command: %s", idarg.get_strr()
);
} }
result.force_null(); result.force_null();
switch (id->get_type_raw()) { switch (id->get_type_raw()) {
@ -1608,7 +1601,7 @@ void CsState::run(CsIdent *id, CsValueRange args, CsValue &ret) {
ret.set_null(); ret.set_null();
++rundepth; ++rundepth;
if (rundepth > MaxRunDepth) { if (rundepth > MaxRunDepth) {
cs_debug_code(*this, "exceeded recursion limit"); throw CsErrorException(*this, "exceeded recursion limit");
} else if (id) { } else if (id) {
switch (id->get_type()) { switch (id->get_type()) {
default: default:

View File

@ -207,13 +207,17 @@ static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
scs = nullptr; scs = nullptr;
ostd::ConstCharRange terr = e.what(); ostd::ConstCharRange terr = e.what();
auto col = ostd::find(terr, ':'); auto col = ostd::find(terr, ':');
bool is_lnum = false;
if (!col.empty()) { if (!col.empty()) {
is_lnum = ostd::find_if(
ostd::slice_until(terr, col), [](auto c) { return !isdigit(c); }
).empty();
terr = col + 2; terr = col + 2;
} }
if (!file && ((terr == "missing \"]\"") || (terr == "missing \")\""))) { if (!file && ((terr == "missing \"]\"") || (terr == "missing \")\""))) {
return true; return true;
} }
cs.get_out().writeln(col.empty() ? "stdin: " : "stdin:", e.what()); cs.get_out().writeln(!is_lnum ? "stdin: " : "stdin:", e.what());
if (e.get_stack().get()) { if (e.get_stack().get()) {
cscript::util::print_stack(cs.get_out().iter(), e.get_stack()); cscript::util::print_stack(cs.get_out().iter(), e.get_stack());
cs.get_out().write('\n'); cs.get_out().write('\n');