diff --git a/source/MdFunc.cpp b/source/MdFunc.cpp index f847cdaa7..a122ae38a 100644 --- a/source/MdFunc.cpp +++ b/source/MdFunc.cpp @@ -458,8 +458,7 @@ bool MdFunc::Call(ResultToken &aResultToken, ExprTokenType *aParam[], int aParam { // Although 0 or "" is a fairly conventional default, it might not be safe. // For error-detection and to avoid unexpected behaviour, "unset" the var. - var->Assign(); - var->MarkUninitialized(); + var->Uninitialize(); } } diff --git a/source/script_object.cpp b/source/script_object.cpp index 094876aa1..f5a725f57 100644 --- a/source/script_object.cpp +++ b/source/script_object.cpp @@ -2089,9 +2089,11 @@ ResultType Array::GetEnumItem(UINT &aIndex, Var *aVal, Var *aReserved, int aVarC switch (item.symbol) { default: - aVal->AssignString(item.string, item.string.Length()); if (item.symbol == SYM_MISSING) - aVal->MarkUninitialized(); + aVal->Uninitialize(); + else + aVal->AssignString(item.string, item.string.Length()); + break; case SYM_INTEGER: aVal->Assign(item.n_int64); break; case SYM_FLOAT: aVal->Assign(item.n_double); break; diff --git a/source/var.cpp b/source/var.cpp index 92a2c67b2..da0fe9e80 100644 --- a/source/var.cpp +++ b/source/var.cpp @@ -43,8 +43,7 @@ ResultType Var::Assign(Var &aVar) if (source_var.mAttrib & VAR_ATTRIB_UNINITIALIZED) { - target_var.Assign(); - target_var.MarkUninitialized(); + target_var.Uninitialize(); return OK; } @@ -84,10 +83,7 @@ ResultType Var::Assign(ExprTokenType &aToken) default: ASSERT(!"Unhandled symbol"); case SYM_MISSING: - if (!Assign()) - return FAIL; - MarkUninitialized(); - return OK; + return Uninitialize() ? OK : FAIL; } // Since above didn't return, it can only be SYM_STRING. return Assign(aToken.marker, aToken.marker_length); diff --git a/source/var.h b/source/var.h index 32949e857..0fb6eb498 100644 --- a/source/var.h +++ b/source/var.h @@ -926,9 +926,23 @@ class Var void MarkUninitialized() { - Var &var = *ResolveAlias(); + Var& var = *ResolveAlias(); var.mAttrib |= VAR_ATTRIB_UNINITIALIZED; } + ResultType Uninitialize() + { + Var& var = *ResolveAlias(); + auto obj = (var.mAttrib & VAR_ATTRIB_IS_OBJECT) ? mObject : nullptr; + if (obj) + obj -> AddRef(); + auto result = var.Assign(); + if (result) + var.MarkUninitialized(); + if (obj) + obj->Release(); + + return result; + } }; // class Var #pragma pack(pop) // Calling pack with no arguments restores the default value (which is 8, but "the alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.")