Add Call_PushNullVector and Call_PushNullString

Be able to push NULL_[VECTOR|STRING] to a forward or direct function call.
The callee can check the parameter using the IsNullVector/IsNullString natives.
This commit is contained in:
Peace-Maker
2017-05-04 22:56:31 -06:00
parent b67da15b5b
commit de42dfc783
5 changed files with 214 additions and 3 deletions
+90 -2
View File
@@ -273,7 +273,26 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter)
*/
if (type == Param_String)
{
err = func->PushStringEx((char *)param->byref.orig_addr, param->byref.cells, param->byref.sz_flags, param->byref.flags);
// If NULL_STRING was pushed, push the reference to the pubvar of the callee instead.
if (param->isnull)
{
IPluginRuntime *runtime = func->GetParentRuntime();
uint32_t null_string_idx;
err = runtime->FindPubvarByName("NULL_STRING", &null_string_idx);
if (!err)
{
cell_t null_string;
err = runtime->GetPubvarAddrs(null_string_idx, &null_string, nullptr);
if (!err)
err = func->PushCell(null_string);
}
}
else
{
err = func->PushStringEx((char *)param->byref.orig_addr, param->byref.cells, param->byref.sz_flags, param->byref.flags);
}
}
else if (type == Param_Float || type == Param_Cell)
{
@@ -281,7 +300,26 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter)
}
else
{
err = func->PushArray(param->byref.orig_addr, param->byref.cells, param->byref.flags);
// If NULL_VECTOR was pushed, push the reference to the pubvar of the callee instead.
if (param->isnull && type == Param_Array)
{
IPluginRuntime *runtime = func->GetParentRuntime();
uint32_t null_vector_idx;
err = runtime->FindPubvarByName("NULL_VECTOR", &null_vector_idx);
if (!err)
{
cell_t null_vector;
err = runtime->GetPubvarAddrs(null_vector_idx, &null_vector, nullptr);
if (!err)
err = func->PushCell(null_vector);
}
}
else
{
err = func->PushArray(param->byref.orig_addr, param->byref.cells, param->byref.flags);
}
assert(type == Param_Array || type == Param_FloatByRef || type == Param_CellByRef);
}
}
@@ -400,6 +438,7 @@ int CForward::PushCell(cell_t cell)
m_params[m_curparam].pushedas = Param_Cell;
}
m_params[m_curparam].isnull = false;
m_params[m_curparam++].val = cell;
return SP_ERROR_NONE;
@@ -423,6 +462,7 @@ int CForward::PushFloat(float number)
m_params[m_curparam].pushedas = Param_Float;
}
m_params[m_curparam].isnull = false;
m_params[m_curparam++].val = *(cell_t *)&number;
return SP_ERROR_NONE;
@@ -481,6 +521,7 @@ void CForward::_Int_PushArray(cell_t *inarray, unsigned int cells, int flags)
m_params[m_curparam].byref.cells = cells;
m_params[m_curparam].byref.flags = flags;
m_params[m_curparam].byref.orig_addr = inarray;
m_params[m_curparam].isnull = false;
}
int CForward::PushArray(cell_t *inarray, unsigned int cells, int flags)
@@ -520,6 +561,7 @@ void CForward::_Int_PushString(cell_t *inarray, unsigned int cells, int sz_flags
m_params[m_curparam].byref.flags = cp_flags;
m_params[m_curparam].byref.orig_addr = inarray;
m_params[m_curparam].byref.sz_flags = sz_flags;
m_params[m_curparam].isnull = false;
}
int CForward::PushString(const char *string)
@@ -570,6 +612,52 @@ int CForward::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_fla
return SP_ERROR_NONE;
}
int CForward::PushNullString()
{
if (m_curparam < m_numparams)
{
if (m_types[m_curparam] == Param_Any)
{
m_params[m_curparam].pushedas = Param_String;
} else if (m_types[m_curparam] != Param_String) {
return SetError(SP_ERROR_PARAM);
}
} else {
if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
m_params[m_curparam].pushedas = Param_String;
}
m_params[m_curparam++].isnull = true;
return SP_ERROR_NONE;
}
int CForward::PushNullVector()
{
if (m_curparam < m_numparams)
{
if (m_types[m_curparam] == Param_Any)
{
m_params[m_curparam].pushedas = Param_Array;
} else if (m_types[m_curparam] != Param_Array) {
return SetError(SP_ERROR_PARAM);
}
} else {
if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
m_params[m_curparam].pushedas = Param_Array;
}
m_params[m_curparam++].isnull = true;
return SP_ERROR_NONE;
}
void CForward::Cancel()
{
if (!m_curparam)