diff options
Diffstat (limited to 'modules/gdscript/gdscript_vm.cpp')
-rw-r--r-- | modules/gdscript/gdscript_vm.cpp | 99 |
1 files changed, 79 insertions, 20 deletions
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 7942ee8d97..dacd7df498 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -33,7 +33,6 @@ #include "core/core_string_names.h" #include "core/os/os.h" #include "gdscript.h" -#include "gdscript_functions.h" Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const { int address = p_address & ADDR_MASK; @@ -220,7 +219,9 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const &&OPCODE_CALL, \ &&OPCODE_CALL_RETURN, \ &&OPCODE_CALL_ASYNC, \ - &&OPCODE_CALL_BUILT_IN, \ + &&OPCODE_CALL_UTILITY, \ + &&OPCODE_CALL_UTILITY_VALIDATED, \ + &&OPCODE_CALL_GDSCRIPT_UTILITY, \ &&OPCODE_CALL_BUILTIN_TYPE_VALIDATED, \ &&OPCODE_CALL_SELF_BASE, \ &&OPCODE_CALL_METHOD_BIND, \ @@ -738,7 +739,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a const Variant::ValidatedKeyedSetter setter = _keyed_setters_ptr[index_setter]; bool valid; - setter(dst, index, value, valid); + setter(dst, index, value, &valid); #ifdef DEBUG_ENABLED if (!valid) { @@ -770,7 +771,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a int64_t int_index = *VariantInternal::get_int(index); bool oob; - setter(dst, int_index, value, oob); + setter(dst, int_index, value, &oob); #ifdef DEBUG_ENABLED if (oob) { @@ -835,9 +836,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED // Allow better error message in cases where src and dst are the same stack position. Variant ret; - getter(src, key, &ret, valid); + getter(src, key, &ret, &valid); #else - getter(src, key, dst, valid); + getter(src, key, dst, &valid); #endif #ifdef DEBUG_ENABLED if (!valid) { @@ -870,7 +871,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a int64_t int_index = *VariantInternal::get_int(index); bool oob; - getter(src, int_index, dst, oob); + getter(src, int_index, dst, &oob); #ifdef DEBUG_ENABLED if (oob) { @@ -1292,7 +1293,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GET_INSTRUCTION_ARG(dst, argc); - constructor(*dst, (const Variant **)argptrs); + constructor(dst, (const Variant **)argptrs); ip += 3; } @@ -1749,7 +1750,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } DISPATCH_OPCODE; - OPCODE(OPCODE_CALL_BUILT_IN) { + OPCODE(OPCODE_CALL_UTILITY) { CHECK_SPACE(3 + instr_arg_count); ip += instr_arg_count; @@ -1757,22 +1758,80 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a int argc = _code_ptr[ip + 1]; GD_ERR_BREAK(argc < 0); - GDScriptFunctions::Function func = GDScriptFunctions::Function(_code_ptr[ip + 2]); + GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _global_names_count); + StringName function = _global_names_ptr[_code_ptr[ip + 2]]; + + Variant **argptrs = instruction_args; + + GET_INSTRUCTION_ARG(dst, argc); + + Callable::CallError err; + Variant::call_utility_function(function, dst, (const Variant **)argptrs, argc, err); + +#ifdef DEBUG_ENABLED + if (err.error != Callable::CallError::CALL_OK) { + String methodstr = function; + if (dst->get_type() == Variant::STRING) { + // Call provided error string. + err_text = "Error calling utility function '" + methodstr + "': " + String(*dst); + } else { + err_text = _get_call_error(err, "utility function '" + methodstr + "'", (const Variant **)argptrs); + } + OPCODE_BREAK; + } +#endif + ip += 3; + } + DISPATCH_OPCODE; + + OPCODE(OPCODE_CALL_UTILITY_VALIDATED) { + CHECK_SPACE(3 + instr_arg_count); + + ip += instr_arg_count; + + int argc = _code_ptr[ip + 1]; + GD_ERR_BREAK(argc < 0); + + GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _utilities_count); + Variant::ValidatedUtilityFunction function = _utilities_ptr[_code_ptr[ip + 2]]; + + Variant **argptrs = instruction_args; + + GET_INSTRUCTION_ARG(dst, argc); + + function(dst, (const Variant **)argptrs, argc); + + ip += 3; + } + DISPATCH_OPCODE; + + OPCODE(OPCODE_CALL_GDSCRIPT_UTILITY) { + CHECK_SPACE(3 + instr_arg_count); + + ip += instr_arg_count; + + int argc = _code_ptr[ip + 1]; + GD_ERR_BREAK(argc < 0); + + GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _gds_utilities_count); + GDScriptUtilityFunctions::FunctionPtr function = _gds_utilities_ptr[_code_ptr[ip + 2]]; + Variant **argptrs = instruction_args; GET_INSTRUCTION_ARG(dst, argc); Callable::CallError err; - GDScriptFunctions::call(func, (const Variant **)argptrs, argc, *dst, err); + function(dst, (const Variant **)argptrs, argc, err); #ifdef DEBUG_ENABLED if (err.error != Callable::CallError::CALL_OK) { - String methodstr = GDScriptFunctions::get_func_name(func); + // TODO: Add this information in debug. + String methodstr = "<unkown function>"; if (dst->get_type() == Variant::STRING) { - //call provided error string - err_text = "Error calling built-in function '" + methodstr + "': " + String(*dst); + // Call provided error string. + err_text = "Error calling GDScript utility function '" + methodstr + "': " + String(*dst); } else { - err_text = _get_call_error(err, "built-in function '" + methodstr + "'", (const Variant **)argptrs); + err_text = _get_call_error(err, "GDScript utility function '" + methodstr + "'", (const Variant **)argptrs); } OPCODE_BREAK; } @@ -2223,7 +2282,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a VariantInternal::initialize(counter, Variant::INT); *VariantInternal::get_int(counter) = 0; - if (!str->empty()) { + if (!str->is_empty()) { GET_INSTRUCTION_ARG(iterator, 2); VariantInternal::initialize(iterator, Variant::STRING); *VariantInternal::get_string(iterator) = str->substr(0, 1); @@ -2249,7 +2308,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a const Variant *next = dict->next(nullptr); *counter = *next; - if (!dict->empty()) { + if (!dict->is_empty()) { GET_INSTRUCTION_ARG(iterator, 2); *iterator = *next; @@ -2275,7 +2334,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a VariantInternal::initialize(counter, Variant::INT); *VariantInternal::get_int(counter) = 0; - if (!array->empty()) { + if (!array->is_empty()) { GET_INSTRUCTION_ARG(iterator, 2); *iterator = array->get(0); @@ -2298,7 +2357,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a Vector<m_elem_type> *array = VariantInternal::m_get_func(container); \ VariantInternal::initialize(counter, Variant::INT); \ *VariantInternal::get_int(counter) = 0; \ - if (!array->empty()) { \ + if (!array->is_empty()) { \ GET_INSTRUCTION_ARG(iterator, 2); \ VariantInternal::initialize(iterator, Variant::m_var_ret_type); \ m_ret_type *it = VariantInternal::m_ret_get_func(iterator); \ @@ -2722,7 +2781,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GET_INSTRUCTION_ARG(message, 1); message_str = *message; } - if (message_str.empty()) { + if (message_str.is_empty()) { err_text = "Assertion failed."; } else { err_text = "Assertion failed: " + message_str; |