mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
integrating the existing state of TON Storage / TON Payments / CPS Fift development branches
This commit is contained in:
parent
040df63c98
commit
4e2624459b
153 changed files with 10760 additions and 1695 deletions
|
@ -68,33 +68,69 @@ void CharClassifier::set_char_class(int c, int cl) {
|
|||
}
|
||||
|
||||
IntCtx::Savepoint::Savepoint(IntCtx& _ctx, std::string new_filename, std::string new_current_dir,
|
||||
std::istream* new_input_stream)
|
||||
std::unique_ptr<std::istream> new_input_stream)
|
||||
: ctx(_ctx)
|
||||
, old_line_no(_ctx.line_no)
|
||||
, old_need_line(_ctx.need_line)
|
||||
, old_filename(_ctx.filename)
|
||||
, old_current_dir(_ctx.currentd_dir)
|
||||
, old_input_stream(_ctx.input_stream)
|
||||
, old_input_stream_holder(std::move(_ctx.input_stream_holder))
|
||||
, old_curline(_ctx.str)
|
||||
, old_curpos(_ctx.input_ptr - _ctx.str.c_str()) {
|
||||
, old_curpos(_ctx.input_ptr - _ctx.str.c_str())
|
||||
, old_word(_ctx.word) {
|
||||
ctx.line_no = 0;
|
||||
ctx.filename = new_filename;
|
||||
ctx.currentd_dir = new_current_dir;
|
||||
ctx.input_stream = new_input_stream;
|
||||
ctx.input_stream = new_input_stream.get();
|
||||
ctx.input_stream_holder = std::move(new_input_stream);
|
||||
ctx.str = "";
|
||||
ctx.input_ptr = 0;
|
||||
++(ctx.include_depth);
|
||||
}
|
||||
|
||||
IntCtx::Savepoint::~Savepoint() {
|
||||
bool IntCtx::Savepoint::restore(IntCtx& _ctx) {
|
||||
if (restored || &ctx != &_ctx) {
|
||||
return false;
|
||||
}
|
||||
ctx.line_no = old_line_no;
|
||||
ctx.need_line = old_need_line;
|
||||
ctx.filename = old_filename;
|
||||
ctx.currentd_dir = old_current_dir;
|
||||
ctx.input_stream = old_input_stream;
|
||||
ctx.input_stream_holder = std::move(old_input_stream_holder);
|
||||
ctx.str = old_curline;
|
||||
ctx.input_ptr = ctx.str.c_str() + old_curpos;
|
||||
ctx.word = old_word;
|
||||
--(ctx.include_depth);
|
||||
return restored = true;
|
||||
}
|
||||
|
||||
bool IntCtx::enter_ctx(std::string new_filename, std::string new_current_dir,
|
||||
std::unique_ptr<std::istream> new_input_stream) {
|
||||
if (!new_input_stream) {
|
||||
return false;
|
||||
}
|
||||
ctx_save_stack.emplace_back(*this, std::move(new_filename), std::move(new_current_dir), std::move(new_input_stream));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IntCtx::leave_ctx() {
|
||||
if (ctx_save_stack.empty()) {
|
||||
return false;
|
||||
}
|
||||
bool ok = ctx_save_stack.back().restore(*this);
|
||||
ctx_save_stack.pop_back();
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool IntCtx::top_ctx() {
|
||||
while (!ctx_save_stack.empty()) {
|
||||
if (!leave_ctx()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IntCtx::load_next_line() {
|
||||
|
@ -194,4 +230,99 @@ void IntCtx::check_int_exec() const {
|
|||
throw IntError{"internal interpret mode only"};
|
||||
}
|
||||
}
|
||||
|
||||
bool IntCtx::print_error_backtrace(std::ostream& os) const {
|
||||
if (exc_cont.is_null() && exc_next.is_null()) {
|
||||
os << "(no backtrace)\n";
|
||||
return false;
|
||||
}
|
||||
if (exc_cont.not_null()) {
|
||||
os << "top: ";
|
||||
exc_cont->dump(os, *this);
|
||||
}
|
||||
return print_backtrace(os, exc_next);
|
||||
}
|
||||
|
||||
bool IntCtx::print_backtrace(std::ostream& os, Ref<FiftCont> cont) const {
|
||||
for (int i = 1; cont.not_null() && i <= 16; i++) {
|
||||
os << "level " << i << ": ";
|
||||
cont->dump(os, *this);
|
||||
cont = cont->up();
|
||||
}
|
||||
if (cont.not_null()) {
|
||||
os << "... more levels ...\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Ref<FiftCont> IntCtx::throw_exception(td::Status err, Ref<FiftCont> cur) {
|
||||
exc_cont = std::move(cur);
|
||||
exc_next = std::move(next);
|
||||
error = std::move(err);
|
||||
next.clear();
|
||||
auto cont = std::move(exc_handler);
|
||||
if (cont.is_null()) {
|
||||
return {}; // no Fift exception handler set
|
||||
} else if (cont.is_unique()) {
|
||||
return cont.unique_write().handle_modify(*this);
|
||||
} else {
|
||||
return cont->handle_tail(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void IntCtx::clear_error() {
|
||||
error = td::Status::OK();
|
||||
exit_code = 0;
|
||||
}
|
||||
|
||||
td::Result<int> IntCtx::get_result() {
|
||||
if (error.is_error()) {
|
||||
return error.move_as_error();
|
||||
} else {
|
||||
return exit_code;
|
||||
}
|
||||
}
|
||||
|
||||
td::Status IntCtx::add_error_loc(td::Status err) const {
|
||||
if (err.is_error()) {
|
||||
std::ostringstream os;
|
||||
if (include_depth && line_no) {
|
||||
os << filename << ":" << line_no << ":\t";
|
||||
}
|
||||
if (!word.empty()) {
|
||||
os << word << ":";
|
||||
}
|
||||
return err.move_as_error_prefix(os.str());
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
td::Result<int> IntCtx::run(Ref<FiftCont> cont) {
|
||||
clear_error();
|
||||
while (cont.not_null()) {
|
||||
try {
|
||||
if (cont.is_unique()) {
|
||||
cont = cont.unique_write().run_modify(*this);
|
||||
} else {
|
||||
cont = cont->run_tail(*this);
|
||||
}
|
||||
} catch (IntError& err) {
|
||||
cont = throw_exception(td::Status::Error(err.msg), std::move(cont));
|
||||
} catch (vm::VmError& err) {
|
||||
cont = throw_exception(err.as_status(), std::move(cont));
|
||||
} catch (vm::VmVirtError& err) {
|
||||
cont = throw_exception(err.as_status(), std::move(cont));
|
||||
} catch (vm::CellBuilder::CellWriteError&) {
|
||||
cont = throw_exception(td::Status::Error("Cell builder write error"), std::move(cont));
|
||||
} catch (vm::VmFatal&) {
|
||||
cont = throw_exception(td::Status::Error("fatal vm error"), std::move(cont));
|
||||
}
|
||||
if (cont.is_null()) {
|
||||
cont = std::move(next);
|
||||
}
|
||||
}
|
||||
return get_result();
|
||||
}
|
||||
|
||||
} // namespace fift
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue