diff options
Diffstat (limited to 'modules/gdscript/gdscript_vm.cpp')
-rw-r--r-- | modules/gdscript/gdscript_vm.cpp | 519 |
1 files changed, 281 insertions, 238 deletions
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index fdcc0625d7..4ea4438b5e 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* gdscript_vm.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. */ -/*************************************************************************/ +/**************************************************************************/ +/* gdscript_vm.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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" @@ -35,39 +35,6 @@ #include "gdscript.h" #include "gdscript_lambda_callable.h" -Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, Variant *p_stack, String &r_error) const { - int address = p_address & ADDR_MASK; - - //sequential table (jump table generated by compiler) - switch ((p_address & ADDR_TYPE_MASK) >> ADDR_BITS) { - case ADDR_TYPE_STACK: { -#ifdef DEBUG_ENABLED - ERR_FAIL_INDEX_V(address, _stack_size, nullptr); -#endif - return &p_stack[address]; - } break; - case ADDR_TYPE_CONSTANT: { -#ifdef DEBUG_ENABLED - ERR_FAIL_INDEX_V(address, _constant_count, nullptr); -#endif - return &_constants_ptr[address]; - } break; - case ADDR_TYPE_MEMBER: { -#ifdef DEBUG_ENABLED - if (unlikely(!p_instance)) { - r_error = "Cannot access member without instance."; - return nullptr; - } -#endif - //member indexing is O(1) - return &p_instance->members.write[address]; - } break; - } - - ERR_FAIL_V_MSG(nullptr, "Bad code! (unknown addressing mode)."); - return nullptr; -} - #ifdef DEBUG_ENABLED static String _get_script_name(const Ref<Script> p_script) { Ref<GDScript> gdscript = p_script; @@ -413,14 +380,19 @@ void (*type_init_function_table[])(Variant *) = { #define OPCODE(m_op) \ m_op: -#define OPCODE_WHILE(m_test) \ - OPSWHILE: +#define OPCODE_WHILE(m_test) #define OPCODES_END \ OPSEXIT: #define OPCODES_OUT \ OPSOUT: -#define DISPATCH_OPCODE goto OPSWHILE #define OPCODE_SWITCH(m_test) goto *switch_table_ops[m_test]; +#ifdef DEBUG_ENABLED +#define DISPATCH_OPCODE \ + last_opcode = _code_ptr[ip]; \ + goto *switch_table_ops[last_opcode] +#else +#define DISPATCH_OPCODE goto *switch_table_ops[_code_ptr[ip]] +#endif #define OPCODE_BREAK goto OPSEXIT #define OPCODE_OUT goto OPSOUT #else @@ -607,21 +579,52 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #define CHECK_SPACE(m_space) \ GD_ERR_BREAK((ip + m_space) > _code_size) -#define GET_VARIANT_PTR(m_v, m_code_ofs) \ - Variant *m_v; \ - m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, stack, err_text); \ - if (unlikely(!m_v)) \ - OPCODE_BREAK; +#define GET_VARIANT_PTR(m_v, m_code_ofs) \ + Variant *m_v; \ + { \ + int address = _code_ptr[ip + 1 + (m_code_ofs)]; \ + int address_type = (address & ADDR_TYPE_MASK) >> ADDR_BITS; \ + if (unlikely(address_type < 0 || address_type >= ADDR_TYPE_MAX)) { \ + err_text = "Bad address type."; \ + OPCODE_BREAK; \ + } \ + int address_index = address & ADDR_MASK; \ + if (unlikely(address_index < 0 || address_index >= variant_address_limits[address_type])) { \ + if (address_type == ADDR_TYPE_MEMBER && !p_instance) { \ + err_text = "Cannot access member without instance."; \ + } else { \ + err_text = "Bad address index."; \ + } \ + OPCODE_BREAK; \ + } \ + m_v = &variant_addresses[address_type][address_index]; \ + if (unlikely(!m_v)) \ + OPCODE_BREAK; \ + } #else #define GD_ERR_BREAK(m_cond) #define CHECK_SPACE(m_space) -#define GET_VARIANT_PTR(m_v, m_code_ofs) \ - Variant *m_v; \ - m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, stack, err_text); + +#define GET_VARIANT_PTR(m_v, m_code_ofs) \ + Variant *m_v; \ + { \ + int address = _code_ptr[ip + 1 + (m_code_ofs)]; \ + m_v = &variant_addresses[(address & ADDR_TYPE_MASK) >> ADDR_BITS][address & ADDR_MASK]; \ + if (unlikely(!m_v)) \ + OPCODE_BREAK; \ + } #endif +#define LOAD_INSTRUCTION_ARGS \ + int instr_arg_count = _code_ptr[ip + 1]; \ + for (int i = 0; i < instr_arg_count; i++) { \ + GET_VARIANT_PTR(v, i + 1); \ + instruction_args[i] = v; \ + } \ + ip += 1; // Offset to skip instruction argcount. + #define GET_INSTRUCTION_ARG(m_v, m_idx) \ Variant *m_v = instruction_args[m_idx] @@ -639,21 +642,20 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool exit_ok = false; bool awaited = false; #endif +#ifdef DEBUG_ENABLED + int variant_address_limits[ADDR_TYPE_MAX] = { _stack_size, _constant_count, p_instance ? p_instance->members.size() : 0 }; +#endif + + Variant *variant_addresses[ADDR_TYPE_MAX] = { stack, _constants_ptr, p_instance ? p_instance->members.ptrw() : nullptr }; #ifdef DEBUG_ENABLED OPCODE_WHILE(ip < _code_size) { - int last_opcode = _code_ptr[ip] & INSTR_MASK; + int last_opcode = _code_ptr[ip]; #else OPCODE_WHILE(true) { #endif - // Load arguments for the instruction before each instruction. - int instr_arg_count = ((_code_ptr[ip]) & INSTR_ARGS_MASK) >> INSTR_BITS; - for (int i = 0; i < instr_arg_count; i++) { - GET_VARIANT_PTR(v, i + 1); - instruction_args[i] = v; - } - OPCODE_SWITCH(_code_ptr[ip] & INSTR_MASK) { + OPCODE_SWITCH(_code_ptr[ip]) { OPCODE(OPCODE_OPERATOR) { CHECK_SPACE(5); @@ -661,9 +663,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a Variant::Operator op = (Variant::Operator)_code_ptr[ip + 4]; GD_ERR_BREAK(op >= Variant::OP_MAX); - GET_INSTRUCTION_ARG(a, 0); - GET_INSTRUCTION_ARG(b, 1); - GET_INSTRUCTION_ARG(dst, 2); + GET_VARIANT_PTR(a, 0); + GET_VARIANT_PTR(b, 1); + GET_VARIANT_PTR(dst, 2); #ifdef DEBUG_ENABLED @@ -696,9 +698,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(operator_idx < 0 || operator_idx >= _operator_funcs_count); Variant::ValidatedOperatorEvaluator operator_func = _operator_funcs_ptr[operator_idx]; - GET_INSTRUCTION_ARG(a, 0); - GET_INSTRUCTION_ARG(b, 1); - GET_INSTRUCTION_ARG(dst, 2); + GET_VARIANT_PTR(a, 0); + GET_VARIANT_PTR(b, 1); + GET_VARIANT_PTR(dst, 2); operator_func(a, b, dst); @@ -709,9 +711,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_EXTENDS_TEST) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(a, 0); - GET_INSTRUCTION_ARG(b, 1); - GET_INSTRUCTION_ARG(dst, 2); + GET_VARIANT_PTR(a, 0); + GET_VARIANT_PTR(b, 1); + GET_VARIANT_PTR(dst, 2); #ifdef DEBUG_ENABLED if (b->get_type() != Variant::OBJECT || b->operator Object *() == nullptr) { @@ -784,8 +786,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_IS_BUILTIN) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(value, 0); - GET_INSTRUCTION_ARG(dst, 1); + GET_VARIANT_PTR(value, 0); + GET_VARIANT_PTR(dst, 1); Variant::Type var_type = (Variant::Type)_code_ptr[ip + 3]; GD_ERR_BREAK(var_type < 0 || var_type >= Variant::VARIANT_MAX); @@ -798,9 +800,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_SET_KEYED) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(dst, 0); - GET_INSTRUCTION_ARG(index, 1); - GET_INSTRUCTION_ARG(value, 2); + GET_VARIANT_PTR(dst, 0); + GET_VARIANT_PTR(index, 1); + GET_VARIANT_PTR(value, 2); bool valid; dst->set(*index, *value, &valid); @@ -824,9 +826,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_SET_KEYED_VALIDATED) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(dst, 0); - GET_INSTRUCTION_ARG(index, 1); - GET_INSTRUCTION_ARG(value, 2); + GET_VARIANT_PTR(dst, 0); + GET_VARIANT_PTR(index, 1); + GET_VARIANT_PTR(value, 2); int index_setter = _code_ptr[ip + 4]; GD_ERR_BREAK(index_setter < 0 || index_setter >= _keyed_setters_count); @@ -854,9 +856,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_SET_INDEXED_VALIDATED) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(dst, 0); - GET_INSTRUCTION_ARG(index, 1); - GET_INSTRUCTION_ARG(value, 2); + GET_VARIANT_PTR(dst, 0); + GET_VARIANT_PTR(index, 1); + GET_VARIANT_PTR(value, 2); int index_setter = _code_ptr[ip + 4]; GD_ERR_BREAK(index_setter < 0 || index_setter >= _indexed_setters_count); @@ -886,9 +888,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_GET_KEYED) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(src, 0); - GET_INSTRUCTION_ARG(index, 1); - GET_INSTRUCTION_ARG(dst, 2); + GET_VARIANT_PTR(src, 0); + GET_VARIANT_PTR(index, 1); + GET_VARIANT_PTR(dst, 2); bool valid; #ifdef DEBUG_ENABLED @@ -918,9 +920,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_GET_KEYED_VALIDATED) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(src, 0); - GET_INSTRUCTION_ARG(key, 1); - GET_INSTRUCTION_ARG(dst, 2); + GET_VARIANT_PTR(src, 0); + GET_VARIANT_PTR(key, 1); + GET_VARIANT_PTR(dst, 2); int index_getter = _code_ptr[ip + 4]; GD_ERR_BREAK(index_getter < 0 || index_getter >= _keyed_getters_count); @@ -954,9 +956,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_GET_INDEXED_VALIDATED) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(src, 0); - GET_INSTRUCTION_ARG(index, 1); - GET_INSTRUCTION_ARG(dst, 2); + GET_VARIANT_PTR(src, 0); + GET_VARIANT_PTR(index, 1); + GET_VARIANT_PTR(dst, 2); int index_getter = _code_ptr[ip + 4]; GD_ERR_BREAK(index_getter < 0 || index_getter >= _indexed_getters_count); @@ -986,8 +988,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_SET_NAMED) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(dst, 0); - GET_INSTRUCTION_ARG(value, 1); + GET_VARIANT_PTR(dst, 0); + GET_VARIANT_PTR(value, 1); int indexname = _code_ptr[ip + 3]; @@ -1011,8 +1013,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_SET_NAMED_VALIDATED) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(dst, 0); - GET_INSTRUCTION_ARG(value, 1); + GET_VARIANT_PTR(dst, 0); + GET_VARIANT_PTR(value, 1); int index_setter = _code_ptr[ip + 3]; GD_ERR_BREAK(index_setter < 0 || index_setter >= _setters_count); @@ -1026,8 +1028,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_GET_NAMED) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(src, 0); - GET_INSTRUCTION_ARG(dst, 1); + GET_VARIANT_PTR(src, 0); + GET_VARIANT_PTR(dst, 1); int indexname = _code_ptr[ip + 3]; @@ -1056,8 +1058,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_GET_NAMED_VALIDATED) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(src, 0); - GET_INSTRUCTION_ARG(dst, 1); + GET_VARIANT_PTR(src, 0); + GET_VARIANT_PTR(dst, 1); int index_getter = _code_ptr[ip + 3]; GD_ERR_BREAK(index_getter < 0 || index_getter >= _getters_count); @@ -1070,7 +1072,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_SET_MEMBER) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(src, 0); + GET_VARIANT_PTR(src, 0); int indexname = _code_ptr[ip + 2]; GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count); const StringName *index = &_global_names_ptr[indexname]; @@ -1094,7 +1096,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_GET_MEMBER) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(dst, 0); + GET_VARIANT_PTR(dst, 0); int indexname = _code_ptr[ip + 2]; GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count); const StringName *index = &_global_names_ptr[indexname]; @@ -1113,8 +1115,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ASSIGN) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(dst, 0); - GET_INSTRUCTION_ARG(src, 1); + GET_VARIANT_PTR(dst, 0); + GET_VARIANT_PTR(src, 1); *dst = *src; @@ -1124,7 +1126,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ASSIGN_TRUE) { CHECK_SPACE(2); - GET_INSTRUCTION_ARG(dst, 0); + GET_VARIANT_PTR(dst, 0); *dst = true; @@ -1134,7 +1136,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ASSIGN_FALSE) { CHECK_SPACE(2); - GET_INSTRUCTION_ARG(dst, 0); + GET_VARIANT_PTR(dst, 0); *dst = false; @@ -1144,8 +1146,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ASSIGN_TYPED_BUILTIN) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(dst, 0); - GET_INSTRUCTION_ARG(src, 1); + GET_VARIANT_PTR(dst, 0); + GET_VARIANT_PTR(src, 1); Variant::Type var_type = (Variant::Type)_code_ptr[ip + 3]; GD_ERR_BREAK(var_type < 0 || var_type >= Variant::VARIANT_MAX); @@ -1173,8 +1175,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ASSIGN_TYPED_ARRAY) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(dst, 0); - GET_INSTRUCTION_ARG(src, 1); + GET_VARIANT_PTR(dst, 0); + GET_VARIANT_PTR(src, 1); Array *dst_arr = VariantInternal::get_array(dst); @@ -1198,11 +1200,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ASSIGN_TYPED_NATIVE) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(dst, 0); - GET_INSTRUCTION_ARG(src, 1); + GET_VARIANT_PTR(dst, 0); + GET_VARIANT_PTR(src, 1); #ifdef DEBUG_ENABLED - GET_INSTRUCTION_ARG(type, 2); + GET_VARIANT_PTR(type, 2); GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(type->operator Object *()); GD_ERR_BREAK(!nc); if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) { @@ -1226,11 +1228,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ASSIGN_TYPED_SCRIPT) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(dst, 0); - GET_INSTRUCTION_ARG(src, 1); + GET_VARIANT_PTR(dst, 0); + GET_VARIANT_PTR(src, 1); #ifdef DEBUG_ENABLED - GET_INSTRUCTION_ARG(type, 2); + GET_VARIANT_PTR(type, 2); Script *base_type = Object::cast_to<Script>(type->operator Object *()); GD_ERR_BREAK(!base_type); @@ -1275,8 +1277,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_CAST_TO_BUILTIN) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(src, 0); - GET_INSTRUCTION_ARG(dst, 1); + GET_VARIANT_PTR(src, 0); + GET_VARIANT_PTR(dst, 1); Variant::Type to_type = (Variant::Type)_code_ptr[ip + 3]; GD_ERR_BREAK(to_type < 0 || to_type >= Variant::VARIANT_MAX); @@ -1304,9 +1306,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_CAST_TO_NATIVE) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(src, 0); - GET_INSTRUCTION_ARG(dst, 1); - GET_INSTRUCTION_ARG(to_type, 2); + GET_VARIANT_PTR(src, 0); + GET_VARIANT_PTR(dst, 1); + GET_VARIANT_PTR(to_type, 2); GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(to_type->operator Object *()); GD_ERR_BREAK(!nc); @@ -1335,9 +1337,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_CAST_TO_SCRIPT) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(src, 0); - GET_INSTRUCTION_ARG(dst, 1); - GET_INSTRUCTION_ARG(to_type, 2); + GET_VARIANT_PTR(src, 0); + GET_VARIANT_PTR(dst, 1); + GET_VARIANT_PTR(to_type, 2); Script *base_type = Object::cast_to<Script>(to_type->operator Object *()); @@ -1383,6 +1385,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CONSTRUCT) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(2 + instr_arg_count); ip += instr_arg_count; @@ -1390,6 +1393,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a int argc = _code_ptr[ip + 1]; Variant::Type t = Variant::Type(_code_ptr[ip + 2]); + Variant **argptrs = instruction_args; GET_INSTRUCTION_ARG(dst, argc); @@ -1409,8 +1413,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CONSTRUCT_VALIDATED) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(2 + instr_arg_count); - ip += instr_arg_count; int argc = _code_ptr[ip + 1]; @@ -1430,6 +1434,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CONSTRUCT_ARRAY) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(1 + instr_arg_count); ip += instr_arg_count; @@ -1451,6 +1456,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CONSTRUCT_TYPED_ARRAY) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(3 + instr_arg_count); ip += instr_arg_count; @@ -1480,6 +1486,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CONSTRUCT_DICTIONARY) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(2 + instr_arg_count); ip += instr_arg_count; @@ -1504,11 +1511,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_CALL_ASYNC) OPCODE(OPCODE_CALL_RETURN) OPCODE(OPCODE_CALL) { - CHECK_SPACE(3 + instr_arg_count); - bool call_ret = (_code_ptr[ip] & INSTR_MASK) != OPCODE_CALL; + bool call_ret = (_code_ptr[ip]) != OPCODE_CALL; #ifdef DEBUG_ENABLED - bool call_async = (_code_ptr[ip] & INSTR_MASK) == OPCODE_CALL_ASYNC; + bool call_async = (_code_ptr[ip]) == OPCODE_CALL_ASYNC; #endif + LOAD_INSTRUCTION_ARGS + CHECK_SPACE(3 + instr_arg_count); ip += instr_arg_count; @@ -1533,8 +1541,28 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a Callable::CallError err; if (call_ret) { GET_INSTRUCTION_ARG(ret, argc + 1); +#ifdef DEBUG_ENABLED + Variant::Type base_type = base->get_type(); + Object *base_obj = base->get_validated_object(); + StringName base_class = base_obj ? base_obj->get_class_name() : StringName(); +#endif base->callp(*methodname, (const Variant **)argptrs, argc, *ret, err); #ifdef DEBUG_ENABLED + if (ret->get_type() == Variant::NIL) { + if (base_type == Variant::OBJECT) { + if (base_obj) { + MethodBind *method = ClassDB::get_method(base_class, *methodname); + if (*methodname == CoreStringNames::get_singleton()->_free || (method && !method->has_return())) { + err_text = R"(Trying to get a return value of a method that returns "void")"; + OPCODE_BREAK; + } + } + } else if (Variant::has_builtin_method(base_type, *methodname) && !Variant::has_builtin_method_return_value(base_type, *methodname)) { + err_text = R"(Trying to get a return value of a method that returns "void")"; + OPCODE_BREAK; + } + } + if (!call_async && ret->get_type() == Variant::OBJECT) { // Check if getting a function state without await. bool was_freed = false; @@ -1603,8 +1631,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_CALL_METHOD_BIND) OPCODE(OPCODE_CALL_METHOD_BIND_RET) { + bool call_ret = (_code_ptr[ip]) == OPCODE_CALL_METHOD_BIND_RET; + LOAD_INSTRUCTION_ARGS CHECK_SPACE(3 + instr_arg_count); - bool call_ret = (_code_ptr[ip] & INSTR_MASK) == OPCODE_CALL_METHOD_BIND_RET; ip += instr_arg_count; @@ -1682,6 +1711,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CALL_BUILTIN_STATIC) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(4 + instr_arg_count); ip += instr_arg_count; @@ -1727,6 +1757,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CALL_NATIVE_STATIC) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(3 + instr_arg_count); ip += instr_arg_count; @@ -1770,6 +1801,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED #define OPCODE_CALL_PTR(m_type) \ OPCODE(OPCODE_CALL_PTRCALL_##m_type) { \ + LOAD_INSTRUCTION_ARGS \ CHECK_SPACE(3 + instr_arg_count); \ ip += instr_arg_count; \ int argc = _code_ptr[ip + 1]; \ @@ -1808,6 +1840,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #else #define OPCODE_CALL_PTR(m_type) \ OPCODE(OPCODE_CALL_PTRCALL_##m_type) { \ + LOAD_INSTRUCTION_ARGS \ CHECK_SPACE(3 + instr_arg_count); \ ip += instr_arg_count; \ int argc = _code_ptr[ip + 1]; \ @@ -1865,6 +1898,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_CALL_PTR(PACKED_VECTOR3_ARRAY); OPCODE_CALL_PTR(PACKED_COLOR_ARRAY); OPCODE(OPCODE_CALL_PTRCALL_OBJECT) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(3 + instr_arg_count); ip += instr_arg_count; @@ -1919,6 +1953,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } DISPATCH_OPCODE; OPCODE(OPCODE_CALL_PTRCALL_NO_RETURN) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(3 + instr_arg_count); ip += instr_arg_count; @@ -1971,6 +2006,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CALL_BUILTIN_TYPE_VALIDATED) { + LOAD_INSTRUCTION_ARGS + CHECK_SPACE(3 + instr_arg_count); ip += instr_arg_count; @@ -2005,6 +2042,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CALL_UTILITY) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(3 + instr_arg_count); ip += instr_arg_count; @@ -2039,6 +2077,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CALL_UTILITY_VALIDATED) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(3 + instr_arg_count); ip += instr_arg_count; @@ -2060,6 +2099,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CALL_GDSCRIPT_UTILITY) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(3 + instr_arg_count); ip += instr_arg_count; @@ -2095,6 +2135,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CALL_SELF_BASE) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(3 + instr_arg_count); ip += instr_arg_count; @@ -2164,7 +2205,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a CHECK_SPACE(2); // Do the one-shot connect. - GET_INSTRUCTION_ARG(argobj, 0); + GET_VARIANT_PTR(argobj, 0); Signal sig; bool is_signal = true; @@ -2191,7 +2232,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a if (result.get_type() != Variant::SIGNAL) { // Not async, return immediately using the target from OPCODE_AWAIT_RESUME. - GET_VARIANT_PTR(target, 3); + GET_VARIANT_PTR(target, 2); *target = result; ip += 4; // Skip OPCODE_AWAIT_RESUME and its data. is_signal = false; @@ -2257,13 +2298,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_BREAK; } #endif - GET_INSTRUCTION_ARG(result, 0); + GET_VARIANT_PTR(result, 0); *result = p_state->result; ip += 2; } DISPATCH_OPCODE; OPCODE(OPCODE_CREATE_LAMBDA) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(2 + instr_arg_count); ip += instr_arg_count; @@ -2292,6 +2334,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CREATE_SELF_LAMBDA) { + LOAD_INSTRUCTION_ARGS CHECK_SPACE(2 + instr_arg_count); GD_ERR_BREAK(p_instance == nullptr); @@ -2338,7 +2381,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_JUMP_IF) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(test, 0); + GET_VARIANT_PTR(test, 0); bool result = test->booleanize(); @@ -2355,7 +2398,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_JUMP_IF_NOT) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(test, 0); + GET_VARIANT_PTR(test, 0); bool result = test->booleanize(); @@ -2378,7 +2421,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_JUMP_IF_SHARED) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(val, 0); + GET_VARIANT_PTR(val, 0); if (val->is_shared()) { int to = _code_ptr[ip + 2]; @@ -2392,7 +2435,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_RETURN) { CHECK_SPACE(2); - GET_INSTRUCTION_ARG(r, 0); + GET_VARIANT_PTR(r, 0); retvalue = *r; #ifdef DEBUG_ENABLED exit_ok = true; @@ -2402,7 +2445,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_RETURN_TYPED_BUILTIN) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(r, 0); + GET_VARIANT_PTR(r, 0); Variant::Type ret_type = (Variant::Type)_code_ptr[ip + 2]; GD_ERR_BREAK(ret_type < 0 || ret_type >= Variant::VARIANT_MAX); @@ -2433,9 +2476,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_RETURN_TYPED_ARRAY) { CHECK_SPACE(5); - GET_INSTRUCTION_ARG(r, 0); + GET_VARIANT_PTR(r, 0); - GET_INSTRUCTION_ARG(script_type, 1); + GET_VARIANT_PTR(script_type, 1); Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 3]; int native_type_idx = _code_ptr[ip + 4]; GD_ERR_BREAK(native_type_idx < 0 || native_type_idx >= _global_names_count); @@ -2474,9 +2517,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_RETURN_TYPED_NATIVE) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(r, 0); + GET_VARIANT_PTR(r, 0); - GET_INSTRUCTION_ARG(type, 1); + GET_VARIANT_PTR(type, 1); GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(type->operator Object *()); GD_ERR_BREAK(!nc); @@ -2514,9 +2557,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_RETURN_TYPED_SCRIPT) { CHECK_SPACE(3); - GET_INSTRUCTION_ARG(r, 0); + GET_VARIANT_PTR(r, 0); - GET_INSTRUCTION_ARG(type, 1); + GET_VARIANT_PTR(type, 1); Script *base_type = Object::cast_to<Script>(type->operator Object *()); GD_ERR_BREAK(!base_type); @@ -2580,8 +2623,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_BEGIN) { CHECK_SPACE(8); // Space for this and a regular iterate. - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); bool valid; if (!container->iter_init(*counter, valid)) { @@ -2595,7 +2638,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *iterator = container->iter_get(*counter, valid); #ifdef DEBUG_ENABLED @@ -2612,8 +2655,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_BEGIN_INT) { CHECK_SPACE(8); // Check space for iterate instruction too. - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); int64_t size = *VariantInternal::get_int(container); @@ -2621,7 +2664,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a *VariantInternal::get_int(counter) = 0; if (size > 0) { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); VariantInternal::initialize(iterator, Variant::INT); *VariantInternal::get_int(iterator) = 0; @@ -2639,8 +2682,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_BEGIN_FLOAT) { CHECK_SPACE(8); // Check space for iterate instruction too. - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); double size = *VariantInternal::get_float(container); @@ -2648,7 +2691,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a *VariantInternal::get_float(counter) = 0.0; if (size > 0) { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); VariantInternal::initialize(iterator, Variant::FLOAT); *VariantInternal::get_float(iterator) = 0; @@ -2666,8 +2709,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_BEGIN_VECTOR2) { CHECK_SPACE(8); // Check space for iterate instruction too. - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); Vector2 *bounds = VariantInternal::get_vector2(container); @@ -2675,7 +2718,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a *VariantInternal::get_float(counter) = bounds->x; if (bounds->x < bounds->y) { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); VariantInternal::initialize(iterator, Variant::FLOAT); *VariantInternal::get_float(iterator) = bounds->x; @@ -2693,8 +2736,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_BEGIN_VECTOR2I) { CHECK_SPACE(8); // Check space for iterate instruction too. - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); Vector2i *bounds = VariantInternal::get_vector2i(container); @@ -2702,7 +2745,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a *VariantInternal::get_int(counter) = bounds->x; if (bounds->x < bounds->y) { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); VariantInternal::initialize(iterator, Variant::INT); *VariantInternal::get_int(iterator) = bounds->x; @@ -2720,8 +2763,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_BEGIN_VECTOR3) { CHECK_SPACE(8); // Check space for iterate instruction too. - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); Vector3 *bounds = VariantInternal::get_vector3(container); double from = bounds->x; @@ -2734,7 +2777,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool do_continue = from == to ? false : (from < to ? step > 0 : step < 0); if (do_continue) { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); VariantInternal::initialize(iterator, Variant::FLOAT); *VariantInternal::get_float(iterator) = from; @@ -2752,8 +2795,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_BEGIN_VECTOR3I) { CHECK_SPACE(8); // Check space for iterate instruction too. - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); Vector3i *bounds = VariantInternal::get_vector3i(container); int64_t from = bounds->x; @@ -2766,7 +2809,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool do_continue = from == to ? false : (from < to ? step > 0 : step < 0); if (do_continue) { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); VariantInternal::initialize(iterator, Variant::INT); *VariantInternal::get_int(iterator) = from; @@ -2784,8 +2827,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_BEGIN_STRING) { CHECK_SPACE(8); // Check space for iterate instruction too. - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); String *str = VariantInternal::get_string(container); @@ -2793,7 +2836,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a *VariantInternal::get_int(counter) = 0; if (!str->is_empty()) { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); VariantInternal::initialize(iterator, Variant::STRING); *VariantInternal::get_string(iterator) = str->substr(0, 1); @@ -2811,14 +2854,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_BEGIN_DICTIONARY) { CHECK_SPACE(8); // Check space for iterate instruction too. - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); Dictionary *dict = VariantInternal::get_dictionary(container); const Variant *next = dict->next(nullptr); if (!dict->is_empty()) { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *counter = *next; *iterator = *next; @@ -2836,8 +2879,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_BEGIN_ARRAY) { CHECK_SPACE(8); // Check space for iterate instruction too. - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); Array *array = VariantInternal::get_array(container); @@ -2845,7 +2888,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a *VariantInternal::get_int(counter) = 0; if (!array->is_empty()) { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *iterator = array->get(0); // Skip regular iterate. @@ -2862,13 +2905,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #define OPCODE_ITERATE_BEGIN_PACKED_ARRAY(m_var_type, m_elem_type, m_get_func, m_var_ret_type, m_ret_type, m_ret_get_func) \ OPCODE(OPCODE_ITERATE_BEGIN_PACKED_##m_var_type##_ARRAY) { \ CHECK_SPACE(8); \ - GET_INSTRUCTION_ARG(counter, 0); \ - GET_INSTRUCTION_ARG(container, 1); \ + GET_VARIANT_PTR(counter, 0); \ + GET_VARIANT_PTR(container, 1); \ Vector<m_elem_type> *array = VariantInternal::m_get_func(container); \ VariantInternal::initialize(counter, Variant::INT); \ *VariantInternal::get_int(counter) = 0; \ if (!array->is_empty()) { \ - GET_INSTRUCTION_ARG(iterator, 2); \ + GET_VARIANT_PTR(iterator, 2); \ VariantInternal::initialize(iterator, Variant::m_var_ret_type); \ m_ret_type *it = VariantInternal::m_ret_get_func(iterator); \ *it = array->get(0); \ @@ -2894,8 +2937,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_BEGIN_OBJECT) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); #ifdef DEBUG_ENABLED bool freed = false; @@ -2933,7 +2976,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *iterator = obj->callp(CoreStringNames::get_singleton()->_iter_get, (const Variant **)args, 1, ce); #ifdef DEBUG_ENABLED if (ce.error != Callable::CallError::CALL_OK) { @@ -2950,8 +2993,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); bool valid; if (!container->iter_next(*counter, valid)) { @@ -2965,7 +3008,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *iterator = container->iter_get(*counter, valid); #ifdef DEBUG_ENABLED @@ -2982,8 +3025,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_INT) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); int64_t size = *VariantInternal::get_int(container); int64_t *count = VariantInternal::get_int(counter); @@ -2995,7 +3038,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *VariantInternal::get_int(iterator) = *count; ip += 5; // Loop again. @@ -3006,8 +3049,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_FLOAT) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); double size = *VariantInternal::get_float(container); double *count = VariantInternal::get_float(counter); @@ -3019,7 +3062,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *VariantInternal::get_float(iterator) = *count; ip += 5; // Loop again. @@ -3030,8 +3073,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_VECTOR2) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); const Vector2 *bounds = VariantInternal::get_vector2((const Variant *)container); double *count = VariantInternal::get_float(counter); @@ -3043,7 +3086,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *VariantInternal::get_float(iterator) = *count; ip += 5; // Loop again. @@ -3054,8 +3097,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_VECTOR2I) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); const Vector2i *bounds = VariantInternal::get_vector2i((const Variant *)container); int64_t *count = VariantInternal::get_int(counter); @@ -3067,7 +3110,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *VariantInternal::get_int(iterator) = *count; ip += 5; // Loop again. @@ -3078,8 +3121,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_VECTOR3) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); const Vector3 *bounds = VariantInternal::get_vector3((const Variant *)container); double *count = VariantInternal::get_float(counter); @@ -3091,7 +3134,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *VariantInternal::get_float(iterator) = *count; ip += 5; // Loop again. @@ -3102,8 +3145,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_VECTOR3I) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); const Vector3i *bounds = VariantInternal::get_vector3i((const Variant *)container); int64_t *count = VariantInternal::get_int(counter); @@ -3115,7 +3158,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *VariantInternal::get_int(iterator) = *count; ip += 5; // Loop again. @@ -3126,8 +3169,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_STRING) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); const String *str = VariantInternal::get_string((const Variant *)container); int64_t *idx = VariantInternal::get_int(counter); @@ -3138,7 +3181,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *VariantInternal::get_string(iterator) = str->substr(*idx, 1); ip += 5; // Loop again. @@ -3149,8 +3192,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_DICTIONARY) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); const Dictionary *dict = VariantInternal::get_dictionary((const Variant *)container); const Variant *next = dict->next(counter); @@ -3160,7 +3203,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *counter = *next; *iterator = *next; @@ -3172,8 +3215,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_ARRAY) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); const Array *array = VariantInternal::get_array((const Variant *)container); int64_t *idx = VariantInternal::get_int(counter); @@ -3184,7 +3227,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *iterator = array->get(*idx); ip += 5; // Loop again. @@ -3195,8 +3238,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #define OPCODE_ITERATE_PACKED_ARRAY(m_var_type, m_elem_type, m_get_func, m_ret_get_func) \ OPCODE(OPCODE_ITERATE_PACKED_##m_var_type##_ARRAY) { \ CHECK_SPACE(4); \ - GET_INSTRUCTION_ARG(counter, 0); \ - GET_INSTRUCTION_ARG(container, 1); \ + GET_VARIANT_PTR(counter, 0); \ + GET_VARIANT_PTR(container, 1); \ const Vector<m_elem_type> *array = VariantInternal::m_get_func((const Variant *)container); \ int64_t *idx = VariantInternal::get_int(counter); \ (*idx)++; \ @@ -3205,7 +3248,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto<0 || jumpto> _code_size); \ ip = jumpto; \ } else { \ - GET_INSTRUCTION_ARG(iterator, 2); \ + GET_VARIANT_PTR(iterator, 2); \ *VariantInternal::m_ret_get_func(iterator) = array->get(*idx); \ ip += 5; \ } \ @@ -3225,8 +3268,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_ITERATE_OBJECT) { CHECK_SPACE(4); - GET_INSTRUCTION_ARG(counter, 0); - GET_INSTRUCTION_ARG(container, 1); + GET_VARIANT_PTR(counter, 0); + GET_VARIANT_PTR(container, 1); #ifdef DEBUG_ENABLED bool freed = false; @@ -3264,7 +3307,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; } else { - GET_INSTRUCTION_ARG(iterator, 2); + GET_VARIANT_PTR(iterator, 2); *iterator = obj->callp(CoreStringNames::get_singleton()->_iter_get, (const Variant **)args, 1, ce); #ifdef DEBUG_ENABLED if (ce.error != Callable::CallError::CALL_OK) { @@ -3283,7 +3326,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a int global_idx = _code_ptr[ip + 2]; GD_ERR_BREAK(global_idx < 0 || global_idx >= GDScriptLanguage::get_singleton()->get_global_array_size()); - GET_INSTRUCTION_ARG(dst, 0); + GET_VARIANT_PTR(dst, 0); *dst = GDScriptLanguage::get_singleton()->get_global_array()[global_idx]; ip += 3; @@ -3297,7 +3340,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a const StringName *globalname = &_global_names_ptr[globalname_idx]; GD_ERR_BREAK(!GDScriptLanguage::get_singleton()->get_named_globals_map().has(*globalname)); - GET_INSTRUCTION_ARG(dst, 0); + GET_VARIANT_PTR(dst, 0); *dst = GDScriptLanguage::get_singleton()->get_named_globals_map()[*globalname]; ip += 3; @@ -3307,7 +3350,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #define OPCODE_TYPE_ADJUST(m_v_type, m_c_type) \ OPCODE(OPCODE_TYPE_ADJUST_##m_v_type) { \ CHECK_SPACE(2); \ - GET_INSTRUCTION_ARG(arg, 0); \ + GET_VARIANT_PTR(arg, 0); \ VariantTypeAdjust<m_c_type>::adjust(arg); \ ip += 2; \ } \ @@ -3355,13 +3398,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a CHECK_SPACE(3); #ifdef DEBUG_ENABLED - GET_INSTRUCTION_ARG(test, 0); + GET_VARIANT_PTR(test, 0); bool result = test->booleanize(); if (!result) { String message_str; if (_code_ptr[ip + 2] != 0) { - GET_INSTRUCTION_ARG(message, 1); + GET_VARIANT_PTR(message, 1); message_str = *message; } if (message_str.is_empty()) { |