mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Add pragmas to funC for precise control of computation order (#589)
* FunC pragmas: allow-post-modification and compute-asm-ltr * Warn if #pragma is enabled only in included files * Add tests for new pragmas * Add special ops for "allow-post-modification" only when needed * Update FunC version to 0.4.1 * Allow empty inlines (#10) Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
parent
6b49d6a382
commit
653c88aa9d
8 changed files with 344 additions and 61 deletions
|
@ -39,7 +39,7 @@ extern std::string generated_from;
|
|||
|
||||
constexpr int optimize_depth = 20;
|
||||
|
||||
const std::string func_version{"0.4.0"};
|
||||
const std::string func_version{"0.4.1"};
|
||||
|
||||
enum Keyword {
|
||||
_Eof = -1,
|
||||
|
@ -306,7 +306,7 @@ struct TmpVar {
|
|||
sym_idx_t name;
|
||||
int coord;
|
||||
std::unique_ptr<SrcLocation> where;
|
||||
size_t modify_forbidden = 0;
|
||||
std::vector<std::function<void(const SrcLocation &)>> on_modification;
|
||||
TmpVar(var_idx_t _idx, int _cls, TypeExpr* _type = 0, SymDef* sym = 0, const SrcLocation* loc = 0);
|
||||
void show(std::ostream& os, int omit_idx = 0) const;
|
||||
void dump(std::ostream& os) const;
|
||||
|
@ -681,6 +681,7 @@ typedef std::vector<FormalArg> FormalArgList;
|
|||
struct AsmOpList;
|
||||
|
||||
struct CodeBlob {
|
||||
enum { _AllowPostModification = 1, _ComputeAsmLtr = 2 };
|
||||
int var_cnt, in_var_cnt, op_cnt;
|
||||
TypeExpr* ret_type;
|
||||
std::string name;
|
||||
|
@ -689,6 +690,7 @@ struct CodeBlob {
|
|||
std::unique_ptr<Op> ops;
|
||||
std::unique_ptr<Op>* cur_ops;
|
||||
std::stack<std::unique_ptr<Op>*> cur_ops_stack;
|
||||
int flags = 0;
|
||||
CodeBlob(TypeExpr* ret = nullptr) : var_cnt(0), in_var_cnt(0), op_cnt(0), ret_type(ret), cur_ops(&ops) {
|
||||
}
|
||||
template <typename... Args>
|
||||
|
@ -729,19 +731,9 @@ struct CodeBlob {
|
|||
void generate_code(AsmOpList& out_list, int mode = 0);
|
||||
void generate_code(std::ostream& os, int mode = 0, int indent = 0);
|
||||
|
||||
void mark_modify_forbidden(var_idx_t idx) {
|
||||
++vars.at(idx).modify_forbidden;
|
||||
}
|
||||
|
||||
void unmark_modify_forbidden(var_idx_t idx) {
|
||||
assert(vars.at(idx).modify_forbidden > 0);
|
||||
--vars.at(idx).modify_forbidden;
|
||||
}
|
||||
|
||||
void check_modify_forbidden(var_idx_t idx, const SrcLocation& here) const {
|
||||
if (vars.at(idx).modify_forbidden) {
|
||||
throw src::ParseError{here, PSTRING() << "Modifying local variable " << vars[idx].to_string()
|
||||
<< " after using it in the same expression"};
|
||||
void on_var_modification(var_idx_t idx, const SrcLocation& here) const {
|
||||
for (auto& f : vars.at(idx).on_modification) {
|
||||
f(here);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -855,7 +847,7 @@ extern std::vector<SymDef*> glob_func, glob_vars;
|
|||
|
||||
// defined in parse-func.cpp
|
||||
bool parse_source(std::istream* is, const src::FileDescr* fdescr);
|
||||
bool parse_source_file(const char* filename, src::Lexem lex = {});
|
||||
bool parse_source_file(const char* filename, src::Lexem lex = {}, bool is_main = false);
|
||||
bool parse_source_stdin();
|
||||
|
||||
extern std::stack<src::SrcLocation> inclusion_locations;
|
||||
|
@ -1700,6 +1692,41 @@ extern int verbosity, indent, opt_level;
|
|||
extern bool stack_layout_comments, op_rewrite_comments, program_envelope, asm_preamble, interactive;
|
||||
extern std::string generated_from, boc_output_filename;
|
||||
|
||||
class GlobalPragma {
|
||||
public:
|
||||
explicit GlobalPragma(std::string name) : name_(std::move(name)) {
|
||||
}
|
||||
const std::string& name() const {
|
||||
return name_;
|
||||
}
|
||||
bool enabled() const {
|
||||
return enabled_;
|
||||
}
|
||||
void enable(SrcLocation loc) {
|
||||
enabled_ = true;
|
||||
locs_.push_back(std::move(loc));
|
||||
}
|
||||
void check_enable_in_libs() {
|
||||
if (locs_.empty()) {
|
||||
return;
|
||||
}
|
||||
for (const SrcLocation& loc : locs_) {
|
||||
if (loc.fdescr->is_main) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
locs_[0].show_warning(PSTRING() << "#pragma " << name_
|
||||
<< " is enabled in included libraries, it may change the behavior of your code. "
|
||||
<< "Add this #pragma to the main source file to suppress this warning.");
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
bool enabled_ = false;
|
||||
std::vector<SrcLocation> locs_;
|
||||
};
|
||||
extern GlobalPragma pragma_allow_post_modification, pragma_compute_asm_ltr;
|
||||
|
||||
/*
|
||||
*
|
||||
* OUTPUT CODE GENERATOR
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue