From f3ad0f5b675731d480c957a3900a3f8fdc5b16d1 Mon Sep 17 00:00:00 2001 From: Borja Ferrer Date: Wed, 6 Dec 2006 14:52:11 +0000 Subject: [PATCH] rewritten PushStringEx in Forward and Function systems fixed PushCellByRef and PushFloatByRef in the varargs case where it wouldn't set the pushed type fixed the BindNatives functions not setting the BOUND flag thus making the JIT not exec the natives done the rest of tests with forwards, only left to do string varargs --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40197 --- core/interfaces/IPluginFunction.h | 13 ++++++---- core/systems/CFunction.cpp | 31 +++++++++++++++++------- core/systems/CFunction.h | 4 ++-- core/systems/ForwardSys.cpp | 40 +++++++++++++++++++++---------- core/systems/ForwardSys.h | 4 +++- core/vm/sp_vm_basecontext.cpp | 2 ++ 6 files changed, 65 insertions(+), 29 deletions(-) diff --git a/core/interfaces/IPluginFunction.h b/core/interfaces/IPluginFunction.h index 320d54c2..e0716c79 100644 --- a/core/interfaces/IPluginFunction.h +++ b/core/interfaces/IPluginFunction.h @@ -7,6 +7,9 @@ namespace SourceMod { #define SM_FUNCFLAG_COPYBACK (1<<0) /* Copy an array/reference back after call */ + #define SP_STRING_UTF8 (1<<0) /* String should be UTF-8 handled */ + #define SP_STRING_COPY (1<<1) /* String should be copied into the plugin */ + /** * @brief Represents what a function needs to implement in order to be callable. */ @@ -83,14 +86,16 @@ namespace SourceMod virtual int PushString(const char *string) =0; /** - * @brief Pushes a string onto the current call. + * @brief Pushes a string or string buffer. * NOTE: On Execute, the pointer passed will be modified if copy-back is enabled. * - * @param string String to push. - * @param flags Copy-back flags. + * @param buffer Pointer to string buffer. + * @param length Length of buffer. + * @param sz_flags String flags. + * @param cp_flags Copy-back flags. * @return Error code, if any. */ - virtual int PushStringEx(char *string, int flags) =0; + virtual int PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags) =0; /** * @brief Cancels a function call that is being pushed but not yet executed. diff --git a/core/systems/CFunction.cpp b/core/systems/CFunction.cpp index 5acfa907..1ad5a5d1 100644 --- a/core/systems/CFunction.cpp +++ b/core/systems/CFunction.cpp @@ -112,15 +112,15 @@ int CFunction::PushArray(cell_t *inarray, unsigned int cells, cell_t **phys_addr int CFunction::PushString(const char *string) { - return _PushString(string, 0); + return _PushString(string, SP_STRING_COPY, 0, strlen(string)+1); } -int CFunction::PushStringEx(char *string, int flags) +int CFunction::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags) { - return _PushString(string, flags); + return _PushString(buffer, sz_flags, cp_flags, length); } -int CFunction::_PushString(const char *string, int flags) +int CFunction::_PushString(const char *string, int sz_flags, int cp_flags, size_t len) { if (m_curparam >= SP_MAX_EXEC_PARAMS) { @@ -129,8 +129,7 @@ int CFunction::_PushString(const char *string, int flags) IPluginContext *base = m_pPlugin->m_ctx_current.base; ParamInfo *info = &m_info[m_curparam]; - size_t len = strlen(string); - size_t cells = (len + sizeof(cell_t)) / sizeof(cell_t); + size_t cells = (len + sizeof(cell_t) - 1) / sizeof(cell_t); int err; if ((err=base->HeapAlloc(cells, &info->local_addr, &info->phys_addr)) != SP_ERROR_NONE) @@ -142,12 +141,26 @@ int CFunction::_PushString(const char *string, int flags) m_params[m_curparam] = info->local_addr; m_curparam++; /* Prevent a leak */ - if ((err=base->StringToLocalUTF8(info->local_addr, len+1, string, NULL)) != SP_ERROR_NONE) + if (!(sz_flags & SP_STRING_COPY)) { - return SetError(err); + goto skip_localtostr; } - info->flags = flags; + if (sz_flags & SP_STRING_UTF8) + { + if ((err=base->StringToLocalUTF8(info->local_addr, len, string, NULL)) != SP_ERROR_NONE) + { + return SetError(err); + } + } else { + if ((err=base->StringToLocal(info->local_addr, len, string)) != SP_ERROR_NONE) + { + return SetError(err); + } + } + +skip_localtostr: + info->flags = cp_flags; info->orig_addr = (cell_t *)string; info->size = cells; diff --git a/core/systems/CFunction.h b/core/systems/CFunction.h index 0deca0de..d68d837d 100644 --- a/core/systems/CFunction.h +++ b/core/systems/CFunction.h @@ -27,7 +27,7 @@ public: virtual int PushFloatByRef(float *number, int flags); virtual int PushArray(cell_t *inarray, unsigned int cells, cell_t **phys_addr, int copyback); virtual int PushString(const char *string); - virtual int PushStringEx(char *string, int flags); + virtual int PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags); virtual cell_t *GetAddressOfPushedParam(unsigned int param); virtual int Execute(cell_t *result); virtual void Cancel(); @@ -36,7 +36,7 @@ public: public: void Set(funcid_t funcid, CPlugin *plugin); private: - int _PushString(const char *string, int flags); + int _PushString(const char *string, int sz_flags, int cp_flags, size_t len); inline int SetError(int err) { m_errorstate = err; diff --git a/core/systems/ForwardSys.cpp b/core/systems/ForwardSys.cpp index 30fcc56f..7e3feb67 100644 --- a/core/systems/ForwardSys.cpp +++ b/core/systems/ForwardSys.cpp @@ -20,12 +20,12 @@ CForwardManager g_Forwards; * X Push strings (copyback tested = yes) * VARARG FUNCTIONS: * - Pushing no varargs - * - Push vararg cells (copyback should be verified to not happen = ??) - * - Push vararg cells byref (copyback tested = ??) - * - Push vararg floats (copyback should be verified to not happen = ??) - * - Push vararg floats byref (copyback tested = ??) - * - Push vararg arrays (copyback tested = ??) - * - Push vararg strings (copyback tested = ??) + * X Push vararg cells (copyback should be verified to not happen = didnt happen) + * X Push vararg cells byref (copyback tested = yes) + * X Push vararg floats (copyback should be verified to not happen = didnt happen) + * X Push vararg floats byref (copyback tested = yes) + * X Push vararg arrays (copyback tested = yes) + * X Push vararg strings (copyback tested = :TODO:) */ IForward *CForwardManager::CreateForward(const char *name, ExecType et, unsigned int num_params, ParamType *types, ...) @@ -227,9 +227,9 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter) /* If we're byref or we're vararg, we always push everything by ref. * Even if they're byval, we must push them byref. */ - if (type == Param_String) + if (type == Param_String) { - func->PushStringEx((char *)param->byref.orig_addr, param->byref.flags); + 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) { func->PushCellByRef(¶m->val, 0); } else { @@ -365,8 +365,10 @@ int CForward::PushCellByRef(cell_t *cell, int flags) { if (m_curparam < m_numparams) { - if (m_types[m_curparam] != Param_CellByRef && m_types[m_curparam] != Param_Any) + if (m_types[m_curparam] == Param_Any) { + m_params[m_curparam].pushedas = Param_CellByRef; + } else if (m_types[m_curparam] != Param_CellByRef) { return SetError(SP_ERROR_PARAM); } } else { @@ -374,6 +376,7 @@ int CForward::PushCellByRef(cell_t *cell, int flags) { return SetError(SP_ERROR_PARAMS_MAX); } + m_params[m_curparam].pushedas = Param_CellByRef; } _Int_PushArray(cell, 1, flags); @@ -386,8 +389,10 @@ int CForward::PushFloatByRef(float *num, int flags) { if (m_curparam < m_numparams) { - if (m_types[m_curparam] != Param_FloatByRef && m_types[m_curparam] != Param_Any) + if (m_types[m_curparam] == Param_Any) { + m_params[m_curparam].pushedas = Param_FloatByRef; + } else if (m_types[m_curparam] != Param_FloatByRef) { return SetError(SP_ERROR_PARAM); } } else { @@ -395,6 +400,7 @@ int CForward::PushFloatByRef(float *num, int flags) { return SetError(SP_ERROR_PARAMS_MAX); } + m_params[m_curparam].pushedas = Param_FloatByRef; } _Int_PushArray((cell_t *)num, 1, flags); @@ -446,6 +452,14 @@ int CForward::PushArray(cell_t *inarray, unsigned int cells, cell_t **phys_addr, return SP_ERROR_NONE; } +void CForward::_Int_PushString(cell_t *inarray, unsigned int cells, int sz_flags, int cp_flags) +{ + m_params[m_curparam].byref.cells = cells; /* Notice this contains the char count not cell count */ + 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; +} + int CForward::PushString(const char *string) { if (m_curparam < m_numparams) @@ -464,13 +478,13 @@ int CForward::PushString(const char *string) m_params[m_curparam].pushedas = Param_String; } - _Int_PushArray((cell_t *)string, 0, 0); + _Int_PushString((cell_t *)string, strlen(string)+1, SP_STRING_COPY, 0); m_curparam++; return SP_ERROR_NONE; } -int CForward::PushStringEx(char *string, int flags) +int CForward::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags) { if (m_curparam < m_numparams) { @@ -488,7 +502,7 @@ int CForward::PushStringEx(char *string, int flags) m_params[m_curparam].pushedas = Param_String; } - _Int_PushArray((cell_t *)string, 0, flags); + _Int_PushString((cell_t *)buffer, length, sz_flags, cp_flags); m_curparam++; return SP_ERROR_NONE; diff --git a/core/systems/ForwardSys.h b/core/systems/ForwardSys.h index b286284b..a3dfd5c9 100644 --- a/core/systems/ForwardSys.h +++ b/core/systems/ForwardSys.h @@ -19,6 +19,7 @@ struct ByrefInfo unsigned int cells; cell_t *orig_addr; int flags; + int sz_flags; }; struct FwdParamInfo @@ -37,7 +38,7 @@ public: //ICallable virtual int PushFloatByRef(float *number, int flags); virtual int PushArray(cell_t *inarray, unsigned int cells, cell_t **phys_addr, int flags); virtual int PushString(const char *string); - virtual int PushStringEx(char *string, int flags); + virtual int PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags); virtual void Cancel(); public: //IForward virtual const char *GetForwardName(); @@ -57,6 +58,7 @@ public: va_list ap); private: void _Int_PushArray(cell_t *inarray, unsigned int cells, int flags); + void _Int_PushString(cell_t *inarray, unsigned int cells, int sz_flags, int cp_flags); inline int SetError(int err) { m_errstate = err; diff --git a/core/vm/sp_vm_basecontext.cpp b/core/vm/sp_vm_basecontext.cpp index 09a23017..2a4531b4 100644 --- a/core/vm/sp_vm_basecontext.cpp +++ b/core/vm/sp_vm_basecontext.cpp @@ -374,6 +374,7 @@ int BaseContext::BindNative(sp_nativeinfo_t *native) } ctx->natives[index].pfn = native->func; + ctx->natives[index].status = SP_NATIVE_BOUND; return SP_ERROR_NONE; } @@ -389,6 +390,7 @@ int BaseContext::BindNativeToAny(SPVM_NATIVE_FUNC native) if (ctx->natives[i].status == SP_NATIVE_UNBOUND) { ctx->natives[i].pfn = native; + ctx->natives[i].status = SP_NATIVE_BOUND; } }