/*************************************************************************/ /* gdscript_function.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "gdscript_function.h" #include "gdscript.h" const int *GDScriptFunction::get_code() const { return _code_ptr; } int GDScriptFunction::get_code_size() const { return _code_size; } Variant GDScriptFunction::get_constant(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, constants.size(), ""); return constants[p_idx]; } StringName GDScriptFunction::get_global_name(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, global_names.size(), ""); return global_names[p_idx]; } int GDScriptFunction::get_default_argument_count() const { return _default_arg_count; } int GDScriptFunction::get_default_argument_addr(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, default_arguments.size(), -1); return default_arguments[p_idx]; } GDScriptDataType GDScriptFunction::get_return_type() const { return return_type; } GDScriptDataType GDScriptFunction::get_argument_type(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, argument_types.size(), GDScriptDataType()); return argument_types[p_idx]; } StringName GDScriptFunction::get_name() const { return name; } int GDScriptFunction::get_max_stack_size() const { return _stack_size; } struct _GDFKC { int order = 0; List pos; }; struct _GDFKCS { int order = 0; StringName id; int pos = 0; bool operator<(const _GDFKCS &p_r) const { return order < p_r.order; } }; void GDScriptFunction::debug_get_stack_member_state(int p_line, List> *r_stackvars) const { int oc = 0; HashMap sdmap; for (const StackDebug &sd : stack_debug) { if (sd.line >= p_line) { break; } if (sd.added) { if (!sdmap.has(sd.identifier)) { _GDFKC d; d.order = oc++; d.pos.push_back(sd.pos); sdmap[sd.identifier] = d; } else { sdmap[sd.identifier].pos.push_back(sd.pos); } } else { ERR_CONTINUE(!sdmap.has(sd.identifier)); sdmap[sd.identifier].pos.pop_back(); if (sdmap[sd.identifier].pos.is_empty()) { sdmap.erase(sd.identifier); } } } List<_GDFKCS> stackpositions; for (const KeyValue &E : sdmap) { _GDFKCS spp; spp.id = E.key; spp.order = E.value.order; spp.pos = E.value.pos.back()->get(); stackpositions.push_back(spp); } stackpositions.sort(); for (_GDFKCS &E : stackpositions) { Pair p; p.first = E.id; p.second = E.pos; r_stackvars->push_back(p); } } GDScriptFunction::GDScriptFunction() { name = ""; #ifdef DEBUG_ENABLED { MutexLock lock(GDScriptLanguage::get_singleton()->mutex); GDScriptLanguage::get_singleton()->function_list.add(&function_list); } #endif } GDScriptFunction::~GDScriptFunction() { get_script()->member_functions.erase(name); for (int i = 0; i < lambdas.size(); i++) { memdelete(lambdas[i]); } for (int i = 0; i < argument_types.size(); i++) { argument_types.write[i].script_type_ref = Ref