|
@@ -32,6 +32,7 @@
|
|
|
|
|
|
#include "core/core_string_names.h"
|
|
|
#include "core/object.h"
|
|
|
+#include "core/object_rc.h"
|
|
|
#include "core/script_language.h"
|
|
|
|
|
|
#define CASE_TYPE_ALL(PREFIX, OP) \
|
|
@@ -399,7 +400,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
|
|
CASE_TYPE(math, OP_EQUAL, NIL) {
|
|
|
if (p_b.type == NIL) _RETURN(true);
|
|
|
if (p_b.type == OBJECT)
|
|
|
- _RETURN(p_b._get_obj().obj == NULL);
|
|
|
+ _RETURN(_OBJ_PTR(p_b) == NULL);
|
|
|
|
|
|
_RETURN(false);
|
|
|
}
|
|
@@ -416,9 +417,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
|
|
|
|
|
CASE_TYPE(math, OP_EQUAL, OBJECT) {
|
|
|
if (p_b.type == OBJECT)
|
|
|
- _RETURN((p_a._get_obj().obj == p_b._get_obj().obj));
|
|
|
+ _RETURN(_OBJ_PTR(p_a) == _OBJ_PTR(p_b));
|
|
|
if (p_b.type == NIL)
|
|
|
- _RETURN(p_a._get_obj().obj == NULL);
|
|
|
+ _RETURN(_OBJ_PTR(p_a) == NULL);
|
|
|
|
|
|
_RETURN_FAIL;
|
|
|
}
|
|
@@ -486,7 +487,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
|
|
CASE_TYPE(math, OP_NOT_EQUAL, NIL) {
|
|
|
if (p_b.type == NIL) _RETURN(false);
|
|
|
if (p_b.type == OBJECT)
|
|
|
- _RETURN(p_b._get_obj().obj != NULL);
|
|
|
+ _RETURN(_OBJ_PTR(p_b) != NULL);
|
|
|
|
|
|
_RETURN(true);
|
|
|
}
|
|
@@ -504,9 +505,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
|
|
|
|
|
CASE_TYPE(math, OP_NOT_EQUAL, OBJECT) {
|
|
|
if (p_b.type == OBJECT)
|
|
|
- _RETURN((p_a._get_obj().obj != p_b._get_obj().obj));
|
|
|
+ _RETURN((_OBJ_PTR(p_a) != _OBJ_PTR(p_b)));
|
|
|
if (p_b.type == NIL)
|
|
|
- _RETURN(p_a._get_obj().obj != NULL);
|
|
|
+ _RETURN(_OBJ_PTR(p_a) != NULL);
|
|
|
|
|
|
_RETURN_FAIL;
|
|
|
}
|
|
@@ -589,7 +590,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
|
|
CASE_TYPE(math, OP_LESS, OBJECT) {
|
|
|
if (p_b.type != OBJECT)
|
|
|
_RETURN_FAIL;
|
|
|
- _RETURN((p_a._get_obj().obj < p_b._get_obj().obj));
|
|
|
+ _RETURN(_OBJ_PTR(p_a) < _OBJ_PTR(p_b));
|
|
|
}
|
|
|
|
|
|
CASE_TYPE(math, OP_LESS, ARRAY) {
|
|
@@ -643,7 +644,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
|
|
CASE_TYPE(math, OP_LESS_EQUAL, OBJECT) {
|
|
|
if (p_b.type != OBJECT)
|
|
|
_RETURN_FAIL;
|
|
|
- _RETURN((p_a._get_obj().obj <= p_b._get_obj().obj));
|
|
|
+ _RETURN(_OBJ_PTR(p_a) <= _OBJ_PTR(p_b));
|
|
|
}
|
|
|
|
|
|
DEFAULT_OP_NUM(math, OP_LESS_EQUAL, INT, <=, _int);
|
|
@@ -693,7 +694,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
|
|
CASE_TYPE(math, OP_GREATER, OBJECT) {
|
|
|
if (p_b.type != OBJECT)
|
|
|
_RETURN_FAIL;
|
|
|
- _RETURN((p_a._get_obj().obj > p_b._get_obj().obj));
|
|
|
+ _RETURN(_OBJ_PTR(p_a) > _OBJ_PTR(p_b));
|
|
|
}
|
|
|
|
|
|
CASE_TYPE(math, OP_GREATER, ARRAY) {
|
|
@@ -747,7 +748,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
|
|
CASE_TYPE(math, OP_GREATER_EQUAL, OBJECT) {
|
|
|
if (p_b.type != OBJECT)
|
|
|
_RETURN_FAIL;
|
|
|
- _RETURN((p_a._get_obj().obj >= p_b._get_obj().obj));
|
|
|
+ _RETURN(_OBJ_PTR(p_a) >= _OBJ_PTR(p_b));
|
|
|
}
|
|
|
|
|
|
DEFAULT_OP_NUM(math, OP_GREATER_EQUAL, INT, >=, _int);
|
|
@@ -1512,15 +1513,16 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
|
|
|
} break;
|
|
|
case OBJECT: {
|
|
|
|
|
|
+ Object *obj = _OBJ_PTR(*this);
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
- if (!_get_obj().obj) {
|
|
|
- break;
|
|
|
- } else if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) {
|
|
|
+ if (unlikely(!obj)) {
|
|
|
+ if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
|
|
|
+ WARN_PRINT("Attempted set on a deleted object.");
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
#endif
|
|
|
- _get_obj().obj->set(p_index, p_value, &valid);
|
|
|
+ obj->set(p_index, p_value, &valid);
|
|
|
|
|
|
} break;
|
|
|
default: {
|
|
@@ -1677,23 +1679,19 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
|
|
|
} break;
|
|
|
case OBJECT: {
|
|
|
|
|
|
+ Object *obj = _OBJ_PTR(*this);
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
- if (!_get_obj().obj) {
|
|
|
+ if (unlikely(!obj)) {
|
|
|
if (r_valid)
|
|
|
*r_valid = false;
|
|
|
- return "Instance base is null.";
|
|
|
- } else {
|
|
|
-
|
|
|
- if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) {
|
|
|
- if (r_valid)
|
|
|
- *r_valid = false;
|
|
|
- return "Attempted use of stray pointer object.";
|
|
|
+ if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
|
|
|
+ WARN_PRINT("Attempted get on a deleted object.");
|
|
|
}
|
|
|
+ return Variant();
|
|
|
}
|
|
|
-
|
|
|
#endif
|
|
|
|
|
|
- return _get_obj().obj->get(p_index, r_valid);
|
|
|
+ return obj->get(p_index, r_valid);
|
|
|
|
|
|
} break;
|
|
|
default: {
|
|
@@ -2167,29 +2165,24 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
|
|
|
} break;
|
|
|
case OBJECT: {
|
|
|
|
|
|
- Object *obj = _get_obj().obj;
|
|
|
- //only if debugging!
|
|
|
-
|
|
|
- if (obj) {
|
|
|
+ Object *obj = _OBJ_PTR(*this);
|
|
|
+ if (unlikely(!obj)) {
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
- if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
|
|
|
-
|
|
|
- if (!ObjectDB::instance_validate(obj)) {
|
|
|
- WARN_PRINT("Attempted use of stray pointer object.");
|
|
|
- valid = false;
|
|
|
- return;
|
|
|
- }
|
|
|
+ valid = false;
|
|
|
+ if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
|
|
|
+ WARN_PRINT("Attempted set on a deleted object.");
|
|
|
}
|
|
|
#endif
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- if (p_index.get_type() != Variant::STRING) {
|
|
|
- obj->setvar(p_index, p_value, r_valid);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- obj->set(p_index, p_value, r_valid);
|
|
|
+ if (p_index.get_type() != Variant::STRING) {
|
|
|
+ obj->setvar(p_index, p_value, r_valid);
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
+ obj->set(p_index, p_value, r_valid);
|
|
|
+ return;
|
|
|
} break;
|
|
|
case DICTIONARY: {
|
|
|
|
|
@@ -2542,23 +2535,20 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
|
|
|
case _RID: {
|
|
|
} break;
|
|
|
case OBJECT: {
|
|
|
- Object *obj = _get_obj().obj;
|
|
|
- if (obj) {
|
|
|
-
|
|
|
+ Object *obj = _OBJ_PTR(*this);
|
|
|
+ if (unlikely(!obj)) {
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
- if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
|
|
|
- //only if debugging!
|
|
|
- if (!ObjectDB::instance_validate(obj)) {
|
|
|
- valid = false;
|
|
|
- return "Attempted get on stray pointer.";
|
|
|
- }
|
|
|
+ valid = false;
|
|
|
+ if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
|
|
|
+ WARN_PRINT("Attempted get on a deleted object.");
|
|
|
}
|
|
|
#endif
|
|
|
+ return Variant();
|
|
|
+ }
|
|
|
|
|
|
- if (p_index.get_type() != Variant::STRING) {
|
|
|
- return obj->getvar(p_index, r_valid);
|
|
|
- }
|
|
|
-
|
|
|
+ if (p_index.get_type() != Variant::STRING) {
|
|
|
+ return obj->getvar(p_index, r_valid);
|
|
|
+ } else {
|
|
|
return obj->get(p_index, r_valid);
|
|
|
}
|
|
|
|
|
@@ -2606,34 +2596,26 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
|
|
|
|
|
|
} break;
|
|
|
case OBJECT: {
|
|
|
- Object *obj = _get_obj().obj;
|
|
|
- if (obj) {
|
|
|
-
|
|
|
- bool valid = false;
|
|
|
+ Object *obj = _OBJ_PTR(*this);
|
|
|
+ if (unlikely(!obj)) {
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
- if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
|
|
|
- //only if debugging!
|
|
|
- if (!ObjectDB::instance_validate(obj)) {
|
|
|
- if (r_valid) {
|
|
|
- *r_valid = false;
|
|
|
- }
|
|
|
- return true; // Attempted get on stray pointer.
|
|
|
- }
|
|
|
+ if (r_valid) {
|
|
|
+ *r_valid = false;
|
|
|
}
|
|
|
-#endif
|
|
|
-
|
|
|
- if (p_index.get_type() != Variant::STRING) {
|
|
|
- obj->getvar(p_index, &valid);
|
|
|
- } else {
|
|
|
- obj->get(p_index, &valid);
|
|
|
+ if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
|
|
|
+ WARN_PRINT("Attempted 'in' on a deleted object.");
|
|
|
}
|
|
|
+#endif
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- return valid;
|
|
|
+ bool result;
|
|
|
+ if (p_index.get_type() != Variant::STRING) {
|
|
|
+ obj->getvar(p_index, &result);
|
|
|
} else {
|
|
|
- if (r_valid)
|
|
|
- *r_valid = false;
|
|
|
+ obj->get(p_index, &result);
|
|
|
}
|
|
|
- return false;
|
|
|
+ return result;
|
|
|
} break;
|
|
|
case DICTIONARY: {
|
|
|
|
|
@@ -2880,21 +2862,17 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
|
|
|
} break;
|
|
|
case OBJECT: {
|
|
|
|
|
|
- Object *obj = _get_obj().obj;
|
|
|
- if (obj) {
|
|
|
+ Object *obj = _OBJ_PTR(*this);
|
|
|
+ if (unlikely(!obj)) {
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
- if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
|
|
|
- //only if debugging!
|
|
|
- if (!ObjectDB::instance_validate(obj)) {
|
|
|
- WARN_PRINT("Attempted get_property list on stray pointer.");
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
|
|
|
+ WARN_PRINT("Attempted get property list on a deleted object.");
|
|
|
}
|
|
|
#endif
|
|
|
-
|
|
|
- obj->get_property_list(p_list);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
+ obj->get_property_list(p_list);
|
|
|
} break;
|
|
|
case DICTIONARY: {
|
|
|
|
|
@@ -2961,14 +2939,13 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
|
|
|
} break;
|
|
|
case OBJECT: {
|
|
|
|
|
|
+ Object *obj = _OBJ_PTR(*this);
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
- if (!_get_obj().obj) {
|
|
|
- valid = false;
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) {
|
|
|
+ if (unlikely(!obj)) {
|
|
|
valid = false;
|
|
|
+ if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
|
|
|
+ WARN_PRINT("Attempted iteration start on a deleted object.");
|
|
|
+ }
|
|
|
return false;
|
|
|
}
|
|
|
#endif
|
|
@@ -2978,7 +2955,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
|
|
|
ref.push_back(r_iter);
|
|
|
Variant vref = ref;
|
|
|
const Variant *refp[] = { &vref };
|
|
|
- Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce);
|
|
|
+ Variant ret = obj->call(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce);
|
|
|
|
|
|
if (ref.size() != 1 || ce.error != Variant::CallError::CALL_OK) {
|
|
|
valid = false;
|
|
@@ -3129,14 +3106,13 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
|
|
|
} break;
|
|
|
case OBJECT: {
|
|
|
|
|
|
+ Object *obj = _OBJ_PTR(*this);
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
- if (!_get_obj().obj) {
|
|
|
- valid = false;
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) {
|
|
|
+ if (unlikely(!obj)) {
|
|
|
valid = false;
|
|
|
+ if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
|
|
|
+ WARN_PRINT("Attempted iteration check next on a deleted object.");
|
|
|
+ }
|
|
|
return false;
|
|
|
}
|
|
|
#endif
|
|
@@ -3146,7 +3122,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
|
|
|
ref.push_back(r_iter);
|
|
|
Variant vref = ref;
|
|
|
const Variant *refp[] = { &vref };
|
|
|
- Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce);
|
|
|
+ Variant ret = obj->call(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce);
|
|
|
|
|
|
if (ref.size() != 1 || ce.error != Variant::CallError::CALL_OK) {
|
|
|
valid = false;
|
|
@@ -3288,21 +3264,20 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
|
|
|
} break;
|
|
|
case OBJECT: {
|
|
|
|
|
|
+ Object *obj = _OBJ_PTR(*this);
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
- if (!_get_obj().obj) {
|
|
|
- r_valid = false;
|
|
|
- return Variant();
|
|
|
- }
|
|
|
-
|
|
|
- if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) {
|
|
|
+ if (unlikely(!obj)) {
|
|
|
r_valid = false;
|
|
|
+ if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
|
|
|
+ WARN_PRINT("Attempted iteration get next on a deleted object.");
|
|
|
+ }
|
|
|
return Variant();
|
|
|
}
|
|
|
#endif
|
|
|
Variant::CallError ce;
|
|
|
ce.error = Variant::CallError::CALL_OK;
|
|
|
const Variant *refp[] = { &r_iter };
|
|
|
- Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce);
|
|
|
+ Variant ret = obj->call(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce);
|
|
|
|
|
|
if (ce.error != Variant::CallError::CALL_OK) {
|
|
|
r_valid = false;
|