WFL: Fix stack overflow when attempting to call a non-existent function
This commit is contained in:
parent
1bb750f649
commit
3f3a176f57
4 changed files with 18 additions and 19 deletions
|
@ -35,6 +35,7 @@ Version 1.13.8+dev:
|
|||
* WFL Engine
|
||||
* Add owner key to terrain space callable, for villages
|
||||
* Location formulas in [tunnel] now have a teleport_unit variable
|
||||
* Fix a crash when attempting to call a non-existent function
|
||||
* WML Engine
|
||||
* If ai_algorithm is used in [modify_side][ai], it now replaces the whole AI
|
||||
with the contents of [modify_side][ai], instead of appending these parameters.
|
||||
|
|
|
@ -1596,7 +1596,7 @@ public:
|
|||
#define FUNCTION(name) add_function(#name, formula_function_ptr( \
|
||||
new builtin_formula_function<name##_function>(#name)))
|
||||
|
||||
ai_function_symbol_table::ai_function_symbol_table(ai::formula_ai& ai) : function_symbol_table(new action_function_symbol_table) {
|
||||
ai_function_symbol_table::ai_function_symbol_table(ai::formula_ai& ai) : function_symbol_table(std::make_shared<action_function_symbol_table>()) {
|
||||
FUNCTION(outcomes);
|
||||
//AI_FUNCTION(evaluate_for_position);
|
||||
FUNCTION(move);
|
||||
|
|
|
@ -1570,11 +1570,7 @@ function_expression_ptr user_formula_function::generate_function_expression(cons
|
|||
return function_expression_ptr(new formula_function_expression(name_, args, formula_, precondition_, args_));
|
||||
}
|
||||
|
||||
function_symbol_table::function_symbol_table(function_symbol_table* parent) : parent(parent) {}
|
||||
|
||||
function_symbol_table::~function_symbol_table() {
|
||||
if(parent) delete parent;
|
||||
}
|
||||
function_symbol_table::function_symbol_table(std::shared_ptr<function_symbol_table> parent) : parent(parent ? parent : get_builtins()) {}
|
||||
|
||||
void function_symbol_table::add_function(const std::string& name, formula_function_ptr fcn)
|
||||
{
|
||||
|
@ -1588,9 +1584,11 @@ expression_ptr function_symbol_table::create_function(const std::string& fn, con
|
|||
return i->second->generate_function_expression(args);
|
||||
}
|
||||
|
||||
expression_ptr res((parent ? parent : get_builtins())->create_function(fn, args));
|
||||
if(res) {
|
||||
return res;
|
||||
if(parent) {
|
||||
expression_ptr res(parent->create_function(fn, args));
|
||||
if(res) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
throw formula_error("Unknown function: " + fn, "", "", 0);
|
||||
|
@ -1601,8 +1599,6 @@ std::set<std::string> function_symbol_table::get_function_names() const
|
|||
std::set<std::string> res;
|
||||
if(parent) {
|
||||
res = parent->get_function_names();
|
||||
} else if(this != get_builtins()) {
|
||||
res = get_builtins()->get_function_names();
|
||||
}
|
||||
for(functions_map::const_iterator iter = custom_formulas_.begin(); iter != custom_formulas_.end(); ++iter ) {
|
||||
res.insert((*iter).first);
|
||||
|
@ -1613,10 +1609,11 @@ std::set<std::string> function_symbol_table::get_function_names() const
|
|||
#define FUNCTION(name) functions_table.add_function(#name, \
|
||||
formula_function_ptr(new builtin_formula_function<name##_function>(#name)))
|
||||
|
||||
function_symbol_table* function_symbol_table::get_builtins() {
|
||||
static function_symbol_table functions_table;
|
||||
std::shared_ptr<function_symbol_table> function_symbol_table::get_builtins() {
|
||||
static function_symbol_table functions_table(builtins_tag);
|
||||
|
||||
if(functions_table.empty()) {
|
||||
functions_table.parent = nullptr;
|
||||
using namespace builtins;
|
||||
FUNCTION(debug);
|
||||
FUNCTION(dir);
|
||||
|
@ -1680,7 +1677,7 @@ function_symbol_table* function_symbol_table::get_builtins() {
|
|||
FUNCTION(type);
|
||||
}
|
||||
|
||||
return &functions_table;
|
||||
return std::shared_ptr<function_symbol_table>(&functions_table, [](function_symbol_table*){});
|
||||
}
|
||||
|
||||
action_function_symbol_table::action_function_symbol_table() {
|
||||
|
|
|
@ -139,16 +139,17 @@ typedef std::shared_ptr<formula_function> formula_function_ptr;
|
|||
typedef std::map<std::string, formula_function_ptr> functions_map;
|
||||
|
||||
class function_symbol_table {
|
||||
function_symbol_table* parent = nullptr;
|
||||
std::shared_ptr<function_symbol_table> parent;
|
||||
functions_map custom_formulas_;
|
||||
enum builtins_tag_t {builtins_tag};
|
||||
function_symbol_table(builtins_tag_t) {}
|
||||
public:
|
||||
explicit function_symbol_table(function_symbol_table* parent = nullptr);
|
||||
~function_symbol_table();
|
||||
explicit function_symbol_table(std::shared_ptr<function_symbol_table> parent = nullptr);
|
||||
void add_function(const std::string& name, formula_function_ptr fcn);
|
||||
expression_ptr create_function(const std::string& fn, const std::vector<expression_ptr>& args) const;
|
||||
std::set<std::string> get_function_names() const;
|
||||
bool empty() {return custom_formulas_.empty();}
|
||||
static function_symbol_table* get_builtins();
|
||||
bool empty() {return custom_formulas_.empty() && (parent == nullptr || parent->empty());}
|
||||
static std::shared_ptr<function_symbol_table> get_builtins();
|
||||
};
|
||||
|
||||
class action_function_symbol_table : public function_symbol_table {
|
||||
|
|
Loading…
Add table
Reference in a new issue