summaryrefslogtreecommitdiff
path: root/modules/gdscript/gdscript_vm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/gdscript_vm.cpp')
-rw-r--r--modules/gdscript/gdscript_vm.cpp519
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()) {