summaryrefslogtreecommitdiff
path: root/core/variant
diff options
context:
space:
mode:
authorRémi Verschelde <remi@verschelde.fr>2022-06-28 01:08:24 +0200
committerGitHub <noreply@github.com>2022-06-28 01:08:24 +0200
commitb863c40356b4b95192d1a1e2718db7d7aced4235 (patch)
treef07da843fb5c9a1c034abf526030c7b21f2777f2 /core/variant
parent8fd0b4d1f84867c6727e2e233ad08b1fed801eb7 (diff)
parent9ddebc0c22866d6b7a7ff3fa64b67cc86c8664da (diff)
Merge pull request #62468 from V-Sekai/core-const-expressions
Add a const call mode to Object, Variant and Script.
Diffstat (limited to 'core/variant')
-rw-r--r--core/variant/callable.h1
-rw-r--r--core/variant/variant.cpp2
-rw-r--r--core/variant/variant.h1
-rw-r--r--core/variant/variant_call.cpp36
4 files changed, 40 insertions, 0 deletions
diff --git a/core/variant/callable.h b/core/variant/callable.h
index 6a760958d6..bbcf5427ba 100644
--- a/core/variant/callable.h
+++ b/core/variant/callable.h
@@ -61,6 +61,7 @@ public:
CALL_ERROR_TOO_MANY_ARGUMENTS, // expected is number of arguments
CALL_ERROR_TOO_FEW_ARGUMENTS, // expected is number of arguments
CALL_ERROR_INSTANCE_IS_NULL,
+ CALL_ERROR_METHOD_NOT_CONST,
};
Error error = Error::CALL_OK;
int argument = 0;
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index cc22b9c451..ae92d7b5c4 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -3406,6 +3406,8 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method,
err_text = "Method not found.";
} else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
err_text = "Instance is null";
+ } else if (ce.error == Callable::CallError::CALL_ERROR_METHOD_NOT_CONST) {
+ err_text = "Method not const in const instance";
} else if (ce.error == Callable::CallError::CALL_OK) {
return "Call OK";
}
diff --git a/core/variant/variant.h b/core/variant/variant.h
index cb3a622417..872b374b13 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -556,6 +556,7 @@ public:
return ret;
}
+ void call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
static void call_static(Variant::Type p_type, const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
static String get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce);
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 5b9f77ad16..a4bb7630d6 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1031,6 +1031,37 @@ void Variant::callp(const StringName &p_method, const Variant **p_args, int p_ar
#endif
r_ret = _get_obj().obj->callp(p_method, p_args, p_argcount, r_error);
+ } else {
+ r_error.error = Callable::CallError::CALL_OK;
+
+ const VariantBuiltInMethodInfo *imf = builtin_method_info[type].lookup_ptr(p_method);
+
+ if (!imf) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
+ return;
+ }
+
+ imf->call(this, p_args, p_argcount, r_ret, imf->default_arguments, r_error);
+ }
+}
+
+void Variant::call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
+ if (type == Variant::OBJECT) {
+ //call object
+ Object *obj = _get_obj().obj;
+ if (!obj) {
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ return;
+ }
+#ifdef DEBUG_ENABLED
+ if (EngineDebugger::is_active() && !_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ return;
+ }
+
+#endif
+ r_ret = _get_obj().obj->call_const(p_method, p_args, p_argcount, r_error);
+
//else if (type==Variant::METHOD) {
} else {
r_error.error = Callable::CallError::CALL_OK;
@@ -1042,6 +1073,11 @@ void Variant::callp(const StringName &p_method, const Variant **p_args, int p_ar
return;
}
+ if (!imf->is_const) {
+ r_error.error = Callable::CallError::CALL_ERROR_METHOD_NOT_CONST;
+ return;
+ }
+
imf->call(this, p_args, p_argcount, r_ret, imf->default_arguments, r_error);
}
}