finished massive reorganization - IPluginFunction is now part of the VM, NOT the plugin system! This is how it should have been in the first place...
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40332
This commit is contained in:
parent
a25f2f7be6
commit
cd735aec71
@ -341,10 +341,6 @@
|
|||||||
RelativePath="..\..\public\ILibrarySys.h"
|
RelativePath="..\..\public\ILibrarySys.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\public\IPluginFunction.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\public\IPluginSys.h"
|
RelativePath="..\..\public\IPluginSys.h"
|
||||||
>
|
>
|
||||||
@ -372,10 +368,6 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
>
|
>
|
||||||
<File
|
|
||||||
RelativePath="..\systems\CFunction.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\systems\ExtensionSys.h"
|
RelativePath="..\systems\ExtensionSys.h"
|
||||||
>
|
>
|
||||||
@ -408,10 +400,6 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Source Files"
|
Name="Source Files"
|
||||||
>
|
>
|
||||||
<File
|
|
||||||
RelativePath="..\systems\CFunction.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\systems\ExtensionSys.cpp"
|
RelativePath="..\systems\ExtensionSys.cpp"
|
||||||
>
|
>
|
||||||
@ -456,6 +444,10 @@
|
|||||||
RelativePath="..\vm\sp_vm_engine.h"
|
RelativePath="..\vm\sp_vm_engine.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\vm\sp_vm_function.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Source Files"
|
Name="Source Files"
|
||||||
@ -468,28 +460,32 @@
|
|||||||
RelativePath="..\vm\sp_vm_engine.cpp"
|
RelativePath="..\vm\sp_vm_engine.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\vm\sp_vm_function.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="SDK"
|
Name="SDK"
|
||||||
>
|
>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\sourcepawn\include\sp_file_headers.h"
|
RelativePath="..\..\public\sourcepawn\sp_file_headers.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\sourcepawn\include\sp_typeutil.h"
|
RelativePath="..\..\public\sourcepawn\sp_typeutil.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\sourcepawn\include\sp_vm_api.h"
|
RelativePath="..\..\public\sourcepawn\sp_vm_api.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\sourcepawn\include\sp_vm_base.h"
|
RelativePath="..\..\public\sourcepawn\sp_vm_base.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\sourcepawn\include\sp_vm_types.h"
|
RelativePath="..\..\public\sourcepawn\sp_vm_types.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
@ -71,7 +71,7 @@ void CForwardManager::OnPluginLoaded(IPlugin *plugin)
|
|||||||
for (iter=m_managed.begin(); iter!=m_managed.end(); iter++)
|
for (iter=m_managed.begin(); iter!=m_managed.end(); iter++)
|
||||||
{
|
{
|
||||||
fwd = (*iter);
|
fwd = (*iter);
|
||||||
IPluginFunction *pFunc = plugin->GetFunctionByName(fwd->GetForwardName());
|
IPluginFunction *pFunc = plugin->GetBaseContext()->GetFunctionByName(fwd->GetForwardName());
|
||||||
if (pFunc)
|
if (pFunc)
|
||||||
{
|
{
|
||||||
fwd->AddFunction(pFunc);
|
fwd->AddFunction(pFunc);
|
||||||
@ -256,7 +256,8 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter)
|
|||||||
for (iter=m_functions.begin(); iter!=m_functions.end(); iter++)
|
for (iter=m_functions.begin(); iter!=m_functions.end(); iter++)
|
||||||
{
|
{
|
||||||
func = (*iter);
|
func = (*iter);
|
||||||
if (func->GetParentPlugin()->GetStatus() == Plugin_Paused)
|
/* Ugh... */
|
||||||
|
if (!func->GetParentContext()->IsRunnable())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -565,15 +566,10 @@ void CForward::Cancel()
|
|||||||
m_errstate = SP_ERROR_NONE;
|
m_errstate = SP_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CForward::AddFunction(sp_context_t *ctx, funcid_t index)
|
bool CForward::AddFunction(IPluginContext *pContext, funcid_t index)
|
||||||
{
|
{
|
||||||
IPlugin *pPlugin = g_PluginSys.FindPluginByContext(ctx);
|
IPluginFunction *pFunc = pContext->GetFunctionById(index);
|
||||||
if (!pPlugin)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPluginFunction *pFunc = pPlugin->GetFunctionById(index);
|
|
||||||
if (!pFunc)
|
if (!pFunc)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -614,10 +610,11 @@ unsigned int CForward::RemoveFunctionsOfPlugin(IPlugin *plugin)
|
|||||||
FuncIter iter;
|
FuncIter iter;
|
||||||
IPluginFunction *func;
|
IPluginFunction *func;
|
||||||
unsigned int removed = 0;
|
unsigned int removed = 0;
|
||||||
|
IPluginContext *pContext = plugin->GetBaseContext();
|
||||||
for (iter=m_functions.begin(); iter!=m_functions.end();)
|
for (iter=m_functions.begin(); iter!=m_functions.end();)
|
||||||
{
|
{
|
||||||
func = (*iter);
|
func = (*iter);
|
||||||
if (func->GetParentPlugin() == plugin)
|
if (func->GetParentContext() == pContext)
|
||||||
{
|
{
|
||||||
iter = m_functions.erase(iter);
|
iter = m_functions.erase(iter);
|
||||||
removed++;
|
removed++;
|
||||||
|
@ -50,7 +50,7 @@ public: //IChangeableForward
|
|||||||
virtual bool RemoveFunction(IPluginFunction *func);
|
virtual bool RemoveFunction(IPluginFunction *func);
|
||||||
virtual unsigned int RemoveFunctionsOfPlugin(IPlugin *plugin);
|
virtual unsigned int RemoveFunctionsOfPlugin(IPlugin *plugin);
|
||||||
virtual bool AddFunction(IPluginFunction *func);
|
virtual bool AddFunction(IPluginFunction *func);
|
||||||
virtual bool AddFunction(sp_context_t *ctx, funcid_t index);
|
virtual bool AddFunction(IPluginContext *ctx, funcid_t index);
|
||||||
public:
|
public:
|
||||||
static CForward *CreateForward(const char *name,
|
static CForward *CreateForward(const char *name,
|
||||||
ExecType et,
|
ExecType et,
|
||||||
|
@ -23,9 +23,6 @@ CPlugin::CPlugin(const char *file)
|
|||||||
m_status = Plugin_Uncompiled;
|
m_status = Plugin_Uncompiled;
|
||||||
m_serial = ++MySerial;
|
m_serial = ++MySerial;
|
||||||
m_plugin = NULL;
|
m_plugin = NULL;
|
||||||
m_funcsnum = 0;
|
|
||||||
m_priv_funcs = NULL;
|
|
||||||
m_pub_funcs = NULL;
|
|
||||||
m_errormsg[256] = '\0';
|
m_errormsg[256] = '\0';
|
||||||
snprintf(m_filename, sizeof(m_filename), "%s", file);
|
snprintf(m_filename, sizeof(m_filename), "%s", file);
|
||||||
m_handle = 0;
|
m_handle = 0;
|
||||||
@ -60,26 +57,6 @@ CPlugin::~CPlugin()
|
|||||||
m_ctx.co = NULL;
|
m_ctx.co = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pub_funcs)
|
|
||||||
{
|
|
||||||
for (uint32_t i=0; i<m_plugin->info.publics_num; i++)
|
|
||||||
{
|
|
||||||
g_PluginSys.ReleaseFunctionToPool(m_pub_funcs[i]);
|
|
||||||
}
|
|
||||||
delete [] m_pub_funcs;
|
|
||||||
m_pub_funcs = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_priv_funcs)
|
|
||||||
{
|
|
||||||
for (unsigned int i=0; i<m_funcsnum; i++)
|
|
||||||
{
|
|
||||||
g_PluginSys.ReleaseFunctionToPool(m_priv_funcs[i]);
|
|
||||||
}
|
|
||||||
delete [] m_priv_funcs;
|
|
||||||
m_priv_funcs = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_plugin)
|
if (m_plugin)
|
||||||
{
|
{
|
||||||
g_pSourcePawn->FreeFromMemory(m_plugin);
|
g_pSourcePawn->FreeFromMemory(m_plugin);
|
||||||
@ -190,30 +167,9 @@ bool CPlugin::FinishMyCompile(char *error, size_t maxlength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_ctx.base = new BaseContext(m_ctx.ctx);
|
m_ctx.base = new BaseContext(m_ctx.ctx);
|
||||||
|
m_ctx.base->SetRunnable(false);
|
||||||
m_ctx.ctx->user[SM_CONTEXTVAR_MYSELF] = (void *)this;
|
m_ctx.ctx->user[SM_CONTEXTVAR_MYSELF] = (void *)this;
|
||||||
|
|
||||||
m_funcsnum = m_ctx.vm->FunctionCount(m_ctx.ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Note: Since the m_plugin member will never change,
|
|
||||||
* it is safe to assume the function count will never change
|
|
||||||
*/
|
|
||||||
if (m_funcsnum && m_priv_funcs == NULL)
|
|
||||||
{
|
|
||||||
m_priv_funcs = new CFunction *[m_funcsnum];
|
|
||||||
memset(m_priv_funcs, 0, sizeof(CFunction *) * m_funcsnum);
|
|
||||||
} else {
|
|
||||||
m_priv_funcs = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_plugin->info.publics_num && m_pub_funcs == NULL)
|
|
||||||
{
|
|
||||||
m_pub_funcs = new CFunction *[m_plugin->info.publics_num];
|
|
||||||
memset(m_pub_funcs, 0, sizeof(CFunction *) * m_plugin->info.publics_num);
|
|
||||||
} else {
|
|
||||||
m_pub_funcs = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_status = Plugin_Created;
|
m_status = Plugin_Created;
|
||||||
m_ctx.co = NULL;
|
m_ctx.co = NULL;
|
||||||
|
|
||||||
@ -230,67 +186,11 @@ void CPlugin::SetErrorState(PluginStatus status, const char *error_fmt, ...)
|
|||||||
va_start(ap, error_fmt);
|
va_start(ap, error_fmt);
|
||||||
vsnprintf(m_errormsg, sizeof(m_errormsg), error_fmt, ap);
|
vsnprintf(m_errormsg, sizeof(m_errormsg), error_fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
|
||||||
|
|
||||||
IPluginFunction *CPlugin::GetFunctionById(funcid_t func_id)
|
if (m_ctx.base)
|
||||||
{
|
{
|
||||||
CFunction *pFunc = NULL;
|
m_ctx.base->SetRunnable(false);
|
||||||
funcid_t save = func_id;
|
|
||||||
|
|
||||||
if (func_id & 1)
|
|
||||||
{
|
|
||||||
func_id >>= 1;
|
|
||||||
if (func_id >= m_plugin->info.publics_num)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
pFunc = m_pub_funcs[func_id];
|
|
||||||
if (!pFunc)
|
|
||||||
{
|
|
||||||
pFunc = g_PluginSys.GetFunctionFromPool(save, this);
|
|
||||||
m_pub_funcs[func_id] = pFunc;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
func_id >>= 1;
|
|
||||||
unsigned int index;
|
|
||||||
if (!g_pVM->FunctionLookup(m_ctx.ctx, func_id, &index))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
pFunc = m_priv_funcs[func_id];
|
|
||||||
if (!pFunc)
|
|
||||||
{
|
|
||||||
pFunc = g_PluginSys.GetFunctionFromPool(save, this);
|
|
||||||
m_priv_funcs[func_id] = pFunc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pFunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPluginFunction *CPlugin::GetFunctionByName(const char *public_name)
|
|
||||||
{
|
|
||||||
uint32_t index;
|
|
||||||
IPluginContext *base = m_ctx.base;
|
|
||||||
|
|
||||||
if (base->FindPublicByName(public_name, &index) != SP_ERROR_NONE)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFunction *pFunc = m_pub_funcs[index];
|
|
||||||
if (!pFunc)
|
|
||||||
{
|
|
||||||
sp_public_t *pub = NULL;
|
|
||||||
base->GetPublicByIndex(index, &pub);
|
|
||||||
if (pub)
|
|
||||||
{
|
|
||||||
pFunc = g_PluginSys.GetFunctionFromPool(pub->funcid, this);
|
|
||||||
m_pub_funcs[index] = pFunc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pFunc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlugin::UpdateInfo()
|
void CPlugin::UpdateInfo()
|
||||||
@ -338,7 +238,7 @@ void CPlugin::Call_OnPluginInit()
|
|||||||
m_status = Plugin_Running;
|
m_status = Plugin_Running;
|
||||||
|
|
||||||
cell_t result;
|
cell_t result;
|
||||||
IPluginFunction *pFunction = GetFunctionByName("OnPluginInit");
|
IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginInit");
|
||||||
if (!pFunction)
|
if (!pFunction)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -356,7 +256,7 @@ void CPlugin::Call_OnPluginUnload()
|
|||||||
}
|
}
|
||||||
|
|
||||||
cell_t result;
|
cell_t result;
|
||||||
IPluginFunction *pFunction = GetFunctionByName("OnPluginUnload");
|
IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginUnload");
|
||||||
if (!pFunction)
|
if (!pFunction)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -373,10 +273,11 @@ bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_status = Plugin_Loaded;
|
m_status = Plugin_Loaded;
|
||||||
|
m_ctx.base->SetRunnable(true);
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
cell_t result;
|
cell_t result;
|
||||||
IPluginFunction *pFunction = GetFunctionByName("AskPluginLoad");
|
IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("AskPluginLoad");
|
||||||
|
|
||||||
if (!pFunction)
|
if (!pFunction)
|
||||||
{
|
{
|
||||||
@ -389,13 +290,11 @@ bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
|
|||||||
pFunction->PushCell(maxlength);
|
pFunction->PushCell(maxlength);
|
||||||
if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
|
if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
m_status = Plugin_Failed;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result || m_status != Plugin_Loaded)
|
if (!result || m_status != Plugin_Loaded)
|
||||||
{
|
{
|
||||||
m_status = Plugin_Failed;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,7 +362,7 @@ bool CPlugin::SetPauseState(bool paused)
|
|||||||
|
|
||||||
m_status = (paused) ? Plugin_Paused : Plugin_Running;
|
m_status = (paused) ? Plugin_Paused : Plugin_Running;
|
||||||
|
|
||||||
IPluginFunction *pFunction = GetFunctionByName("OnPluginPauseChange");
|
IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginPauseChange");
|
||||||
if (pFunction)
|
if (pFunction)
|
||||||
{
|
{
|
||||||
cell_t result;
|
cell_t result;
|
||||||
@ -756,7 +655,6 @@ bool CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool debug
|
|||||||
snprintf(error, err_max, "Unable to set JIT option (key \"%s\") (value \"%s\")", key, val);
|
snprintf(error, err_max, "Unable to set JIT option (key \"%s\") (value \"%s\")", key, val);
|
||||||
}
|
}
|
||||||
pPlugin->CancelMyCompile();
|
pPlugin->CancelMyCompile();
|
||||||
pPlugin->m_status = Plugin_Failed;
|
|
||||||
co = NULL;
|
co = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -932,7 +830,6 @@ bool CPluginManager::LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass
|
|||||||
{
|
{
|
||||||
snprintf(error, maxlength, "Required extension \"%s\" file(\"%s\") not running", name, file);
|
snprintf(error, maxlength, "Required extension \"%s\" file(\"%s\") not running", name, file);
|
||||||
}
|
}
|
||||||
pPlugin->m_status = Plugin_Failed;
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
g_Extensions.BindChildPlugin(pExt, pPlugin);
|
g_Extensions.BindChildPlugin(pExt, pPlugin);
|
||||||
@ -1091,29 +988,6 @@ void CPluginManager::ReleaseIterator(CPluginIterator *iter)
|
|||||||
m_iters.push(iter);
|
m_iters.push(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::ReleaseFunctionToPool(CFunction *func)
|
|
||||||
{
|
|
||||||
if (!func)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
func->Cancel();
|
|
||||||
m_funcpool.push(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
CFunction *CPluginManager::GetFunctionFromPool(funcid_t f, CPlugin *plugin)
|
|
||||||
{
|
|
||||||
if (m_funcpool.empty())
|
|
||||||
{
|
|
||||||
return new CFunction(f, plugin);
|
|
||||||
} else {
|
|
||||||
CFunction *func = m_funcpool.front();
|
|
||||||
m_funcpool.pop();
|
|
||||||
func->Set(f, plugin);
|
|
||||||
return func;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CPluginManager::TestAliasMatch(const char *alias, const char *localpath)
|
bool CPluginManager::TestAliasMatch(const char *alias, const char *localpath)
|
||||||
{
|
{
|
||||||
/* As an optimization, we do not call strlen, but compute the length in the first pass */
|
/* As an optimization, we do not call strlen, but compute the length in the first pass */
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include <sh_stack.h>
|
#include <sh_stack.h>
|
||||||
#include "sm_globals.h"
|
#include "sm_globals.h"
|
||||||
#include "vm/sp_vm_basecontext.h"
|
#include "vm/sp_vm_basecontext.h"
|
||||||
#include "CFunction.h"
|
|
||||||
#include "PluginInfoDatabase.h"
|
#include "PluginInfoDatabase.h"
|
||||||
#include "sm_trie.h"
|
#include "sm_trie.h"
|
||||||
#include "sourcemod.h"
|
#include "sourcemod.h"
|
||||||
@ -93,8 +92,6 @@ public:
|
|||||||
virtual bool SetPauseState(bool paused);
|
virtual bool SetPauseState(bool paused);
|
||||||
virtual unsigned int GetSerial() const;
|
virtual unsigned int GetSerial() const;
|
||||||
virtual const sp_plugin_t *GetPluginStructure() const;
|
virtual const sp_plugin_t *GetPluginStructure() const;
|
||||||
virtual IPluginFunction *GetFunctionByName(const char *public_name);
|
|
||||||
virtual IPluginFunction *GetFunctionById(funcid_t func_id);
|
|
||||||
virtual IdentityToken_t *GetIdentity() const;
|
virtual IdentityToken_t *GetIdentity() const;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -174,9 +171,6 @@ private:
|
|||||||
unsigned int m_serial;
|
unsigned int m_serial;
|
||||||
sm_plugininfo_t m_info;
|
sm_plugininfo_t m_info;
|
||||||
sp_plugin_t *m_plugin;
|
sp_plugin_t *m_plugin;
|
||||||
unsigned int m_funcsnum;
|
|
||||||
CFunction **m_priv_funcs;
|
|
||||||
CFunction **m_pub_funcs;
|
|
||||||
char m_errormsg[256];
|
char m_errormsg[256];
|
||||||
time_t m_LastAccess;
|
time_t m_LastAccess;
|
||||||
IdentityToken_t *m_ident;
|
IdentityToken_t *m_ident;
|
||||||
@ -312,8 +306,6 @@ protected:
|
|||||||
* Caching internal objects
|
* Caching internal objects
|
||||||
*/
|
*/
|
||||||
void ReleaseIterator(CPluginIterator *iter);
|
void ReleaseIterator(CPluginIterator *iter);
|
||||||
CFunction *GetFunctionFromPool(funcid_t f, CPlugin *plugin);
|
|
||||||
void ReleaseFunctionToPool(CFunction *func);
|
|
||||||
inline IdentityToken_t *GetIdentity()
|
inline IdentityToken_t *GetIdentity()
|
||||||
{
|
{
|
||||||
return m_MyIdent;
|
return m_MyIdent;
|
||||||
@ -323,7 +315,6 @@ private:
|
|||||||
List<CPlugin *> m_plugins;
|
List<CPlugin *> m_plugins;
|
||||||
List<sp_nativeinfo_t *> m_natives;
|
List<sp_nativeinfo_t *> m_natives;
|
||||||
CStack<CPluginManager::CPluginIterator *> m_iters;
|
CStack<CPluginManager::CPluginIterator *> m_iters;
|
||||||
CStack<CFunction *> m_funcpool;
|
|
||||||
CPluginInfoDatabase m_PluginInfo;
|
CPluginInfoDatabase m_PluginInfo;
|
||||||
Trie *m_LoadLookup;
|
Trie *m_LoadLookup;
|
||||||
bool m_AllPluginsLoaded;
|
bool m_AllPluginsLoaded;
|
||||||
|
@ -27,6 +27,60 @@ BaseContext::BaseContext(sp_context_t *_ctx)
|
|||||||
ctx->dbreak = GlobalDebugBreak;
|
ctx->dbreak = GlobalDebugBreak;
|
||||||
m_InExec = false;
|
m_InExec = false;
|
||||||
m_CustomMsg = false;
|
m_CustomMsg = false;
|
||||||
|
m_Runnable = true;
|
||||||
|
m_funcsnum = ctx->vmbase->FunctionCount(ctx);
|
||||||
|
m_priv_funcs = NULL;
|
||||||
|
m_pub_funcs = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: Since the m_plugin member will never change,
|
||||||
|
* it is safe to assume the function count will never change
|
||||||
|
*/
|
||||||
|
if (m_funcsnum && m_priv_funcs == NULL)
|
||||||
|
{
|
||||||
|
m_priv_funcs = new CFunction *[m_funcsnum];
|
||||||
|
memset(m_priv_funcs, 0, sizeof(CFunction *) * m_funcsnum);
|
||||||
|
} else {
|
||||||
|
m_priv_funcs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->plugin->info.publics_num && m_pub_funcs == NULL)
|
||||||
|
{
|
||||||
|
m_pub_funcs = new CFunction *[ctx->plugin->info.publics_num];
|
||||||
|
memset(m_pub_funcs, 0, sizeof(CFunction *) * ctx->plugin->info.publics_num);
|
||||||
|
} else {
|
||||||
|
m_pub_funcs = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseContext::FlushFunctionCache()
|
||||||
|
{
|
||||||
|
if (m_pub_funcs)
|
||||||
|
{
|
||||||
|
for (uint32_t i=0; i<ctx->plugin->info.publics_num; i++)
|
||||||
|
{
|
||||||
|
delete m_pub_funcs[i];
|
||||||
|
m_pub_funcs[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_priv_funcs)
|
||||||
|
{
|
||||||
|
for (unsigned int i=0; i<m_funcsnum; i++)
|
||||||
|
{
|
||||||
|
delete m_priv_funcs[i];
|
||||||
|
m_priv_funcs[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseContext::~BaseContext()
|
||||||
|
{
|
||||||
|
FlushFunctionCache();
|
||||||
|
delete [] m_pub_funcs;
|
||||||
|
m_pub_funcs = NULL;
|
||||||
|
delete [] m_priv_funcs;
|
||||||
|
m_priv_funcs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseContext::SetContext(sp_context_t *_ctx)
|
void BaseContext::SetContext(sp_context_t *_ctx)
|
||||||
@ -36,6 +90,9 @@ void BaseContext::SetContext(sp_context_t *_ctx)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctx = _ctx;
|
ctx = _ctx;
|
||||||
|
ctx->context = this;
|
||||||
|
ctx->dbreak = GlobalDebugBreak;
|
||||||
|
FlushFunctionCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
IVirtualMachine *BaseContext::GetVirtualMachine()
|
IVirtualMachine *BaseContext::GetVirtualMachine()
|
||||||
@ -73,6 +130,11 @@ IPluginDebugInfo *BaseContext::GetDebugInfo()
|
|||||||
|
|
||||||
int BaseContext::Execute(funcid_t funcid, cell_t *result)
|
int BaseContext::Execute(funcid_t funcid, cell_t *result)
|
||||||
{
|
{
|
||||||
|
if (!m_Runnable)
|
||||||
|
{
|
||||||
|
return SP_ERROR_NOT_RUNNABLE;
|
||||||
|
}
|
||||||
|
|
||||||
IVirtualMachine *vm = (IVirtualMachine *)ctx->vmbase;
|
IVirtualMachine *vm = (IVirtualMachine *)ctx->vmbase;
|
||||||
|
|
||||||
uint32_t pushcount = ctx->pushcount;
|
uint32_t pushcount = ctx->pushcount;
|
||||||
@ -794,6 +856,63 @@ int BaseContext::LookupLine(ucell_t addr, uint32_t *line)
|
|||||||
return SP_ERROR_NONE;
|
return SP_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IPluginFunction *BaseContext::GetFunctionById(funcid_t func_id)
|
||||||
|
{
|
||||||
|
CFunction *pFunc = NULL;
|
||||||
|
funcid_t save = func_id;
|
||||||
|
|
||||||
|
if (func_id & 1)
|
||||||
|
{
|
||||||
|
func_id >>= 1;
|
||||||
|
if (func_id >= ctx->plugin->info.publics_num)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pFunc = m_pub_funcs[func_id];
|
||||||
|
if (!pFunc)
|
||||||
|
{
|
||||||
|
m_pub_funcs[func_id] = new CFunction(save, this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
func_id >>= 1;
|
||||||
|
unsigned int index;
|
||||||
|
if (!g_pVM->FunctionLookup(ctx, func_id, &index))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pFunc = m_priv_funcs[func_id];
|
||||||
|
if (!pFunc)
|
||||||
|
{
|
||||||
|
m_priv_funcs[func_id] = new CFunction(save, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPluginFunction *BaseContext::GetFunctionByName(const char *public_name)
|
||||||
|
{
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
if (FindPublicByName(public_name, &index) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFunction *pFunc = m_pub_funcs[index];
|
||||||
|
if (!pFunc)
|
||||||
|
{
|
||||||
|
sp_public_t *pub = NULL;
|
||||||
|
GetPublicByIndex(index, &pub);
|
||||||
|
if (pub)
|
||||||
|
{
|
||||||
|
m_pub_funcs[index] = new CFunction(pub->funcid, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined SOURCEMOD_BUILD
|
#if defined SOURCEMOD_BUILD
|
||||||
SourceMod::IdentityToken_t *BaseContext::GetIdentity()
|
SourceMod::IdentityToken_t *BaseContext::GetIdentity()
|
||||||
{
|
{
|
||||||
@ -804,4 +923,14 @@ void BaseContext::SetIdentity(SourceMod::IdentityToken_t *token)
|
|||||||
{
|
{
|
||||||
m_pToken = token;
|
m_pToken = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BaseContext::IsRunnable()
|
||||||
|
{
|
||||||
|
return m_Runnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseContext::SetRunnable(bool runnable)
|
||||||
|
{
|
||||||
|
m_Runnable = runnable;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2,6 +2,11 @@
|
|||||||
#define _INCLUDE_SOURCEPAWN_BASECONTEXT_H_
|
#define _INCLUDE_SOURCEPAWN_BASECONTEXT_H_
|
||||||
|
|
||||||
#include "sp_vm_api.h"
|
#include "sp_vm_api.h"
|
||||||
|
#include "sp_vm_function.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* :TODO: Make functions allocate as a lump instead of individual allocations!
|
||||||
|
*/
|
||||||
|
|
||||||
namespace SourcePawn
|
namespace SourcePawn
|
||||||
{
|
{
|
||||||
@ -11,6 +16,7 @@ namespace SourcePawn
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BaseContext(sp_context_t *ctx);
|
BaseContext(sp_context_t *ctx);
|
||||||
|
~BaseContext();
|
||||||
public: //IPluginContext
|
public: //IPluginContext
|
||||||
IVirtualMachine *GetVirtualMachine();
|
IVirtualMachine *GetVirtualMachine();
|
||||||
sp_context_t *GetContext();
|
sp_context_t *GetContext();
|
||||||
@ -44,9 +50,13 @@ namespace SourcePawn
|
|||||||
virtual int Execute(funcid_t funcid, cell_t *result);
|
virtual int Execute(funcid_t funcid, cell_t *result);
|
||||||
virtual void ThrowNativeErrorEx(int error, const char *msg, ...);
|
virtual void ThrowNativeErrorEx(int error, const char *msg, ...);
|
||||||
virtual cell_t ThrowNativeError(const char *msg, ...);
|
virtual cell_t ThrowNativeError(const char *msg, ...);
|
||||||
|
virtual IPluginFunction *GetFunctionByName(const char *public_name);
|
||||||
|
virtual IPluginFunction *GetFunctionById(funcid_t func_id);
|
||||||
#if defined SOURCEMOD_BUILD
|
#if defined SOURCEMOD_BUILD
|
||||||
virtual SourceMod::IdentityToken_t *GetIdentity();
|
virtual SourceMod::IdentityToken_t *GetIdentity();
|
||||||
void SetIdentity(SourceMod::IdentityToken_t *token);
|
void SetIdentity(SourceMod::IdentityToken_t *token);
|
||||||
|
bool IsRunnable();
|
||||||
|
void SetRunnable(bool runnable);
|
||||||
#endif
|
#endif
|
||||||
public: //IPluginDebugInfo
|
public: //IPluginDebugInfo
|
||||||
virtual int LookupFile(ucell_t addr, const char **filename);
|
virtual int LookupFile(ucell_t addr, const char **filename);
|
||||||
@ -56,6 +66,7 @@ namespace SourcePawn
|
|||||||
void SetContext(sp_context_t *_ctx);
|
void SetContext(sp_context_t *_ctx);
|
||||||
private:
|
private:
|
||||||
void SetErrorMessage(const char *msg, va_list ap);
|
void SetErrorMessage(const char *msg, va_list ap);
|
||||||
|
void FlushFunctionCache();
|
||||||
private:
|
private:
|
||||||
sp_context_t *ctx;
|
sp_context_t *ctx;
|
||||||
#if defined SOURCEMOD_BUILD
|
#if defined SOURCEMOD_BUILD
|
||||||
@ -64,6 +75,10 @@ namespace SourcePawn
|
|||||||
char m_MsgCache[1024];
|
char m_MsgCache[1024];
|
||||||
bool m_CustomMsg;
|
bool m_CustomMsg;
|
||||||
bool m_InExec;
|
bool m_InExec;
|
||||||
|
bool m_Runnable;
|
||||||
|
unsigned int m_funcsnum;
|
||||||
|
CFunction **m_priv_funcs;
|
||||||
|
CFunction **m_pub_funcs;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,6 +53,9 @@ SourcePawnEngine::SourcePawnEngine()
|
|||||||
m_CallStack = NULL;
|
m_CallStack = NULL;
|
||||||
m_FreedCalls = NULL;
|
m_FreedCalls = NULL;
|
||||||
m_CurChain = 0;
|
m_CurChain = 0;
|
||||||
|
#if 0
|
||||||
|
m_pFreeFuncs = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SourcePawnEngine::~SourcePawnEngine()
|
SourcePawnEngine::~SourcePawnEngine()
|
||||||
@ -66,6 +69,16 @@ SourcePawnEngine::~SourcePawnEngine()
|
|||||||
delete m_FreedCalls;
|
delete m_FreedCalls;
|
||||||
m_FreedCalls = pTemp;
|
m_FreedCalls = pTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
CFunction *pNext;
|
||||||
|
while (m_pFreeFuncs)
|
||||||
|
{
|
||||||
|
pNext = m_pFreeFuncs->m_pNext;
|
||||||
|
delete m_pFreeFuncs;
|
||||||
|
m_pFreeFuncs = pNext;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void *SourcePawnEngine::ExecAlloc(size_t size)
|
void *SourcePawnEngine::ExecAlloc(size_t size)
|
||||||
@ -356,6 +369,32 @@ int SourcePawnEngine::FreeFromMemory(sp_plugin_t *plugin)
|
|||||||
return SP_ERROR_NONE;
|
return SP_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void SourcePawnEngine::ReleaseFunctionToPool(CFunction *func)
|
||||||
|
{
|
||||||
|
if (!func)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
func->Cancel();
|
||||||
|
func->m_pNext = m_pFreeFuncs;
|
||||||
|
m_pFreeFuncs = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFunction *SourcePawnEngine::GetFunctionFromPool(funcid_t f, IPluginContext *plugin)
|
||||||
|
{
|
||||||
|
if (!m_pFreeFuncs)
|
||||||
|
{
|
||||||
|
return new CFunction(f, plugin);
|
||||||
|
} else {
|
||||||
|
CFunction *pFunc = m_pFreeFuncs;
|
||||||
|
m_pFreeFuncs = m_pFreeFuncs->m_pNext;
|
||||||
|
pFunc->Set(f, plugin);
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
IDebugListener *SourcePawnEngine::SetDebugListener(IDebugListener *pListener)
|
IDebugListener *SourcePawnEngine::SetDebugListener(IDebugListener *pListener)
|
||||||
{
|
{
|
||||||
IDebugListener *old = m_pDebugHook;
|
IDebugListener *old = m_pDebugHook;
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
#define _INCLUDE_SOURCEPAWN_VM_ENGINE_H_
|
#define _INCLUDE_SOURCEPAWN_VM_ENGINE_H_
|
||||||
|
|
||||||
#include "sp_vm_api.h"
|
#include "sp_vm_api.h"
|
||||||
|
#include "sp_vm_function.h"
|
||||||
|
|
||||||
namespace SourcePawn
|
|
||||||
{
|
|
||||||
struct TracedCall
|
struct TracedCall
|
||||||
{
|
{
|
||||||
uint32_t cip;
|
uint32_t cip;
|
||||||
@ -70,6 +69,9 @@ namespace SourcePawn
|
|||||||
* @brief Runs tracer from a debug break.
|
* @brief Runs tracer from a debug break.
|
||||||
*/
|
*/
|
||||||
void RunTracer(sp_context_t *ctx, uint32_t frame, uint32_t codeip);
|
void RunTracer(sp_context_t *ctx, uint32_t frame, uint32_t codeip);
|
||||||
|
public: //Plugin function stuff
|
||||||
|
CFunction *GetFunctionFromPool(funcid_t f, IPluginContext *plugin);
|
||||||
|
void ReleaseFunctionToPool(CFunction *func);
|
||||||
private:
|
private:
|
||||||
TracedCall *MakeTracedCall(bool new_chain);
|
TracedCall *MakeTracedCall(bool new_chain);
|
||||||
void FreeTracedCall(TracedCall *pCall);
|
void FreeTracedCall(TracedCall *pCall);
|
||||||
@ -78,7 +80,7 @@ namespace SourcePawn
|
|||||||
TracedCall *m_FreedCalls;
|
TracedCall *m_FreedCalls;
|
||||||
TracedCall *m_CallStack;
|
TracedCall *m_CallStack;
|
||||||
unsigned int m_CurChain;
|
unsigned int m_CurChain;
|
||||||
};
|
//CFunction *m_pFreeFuncs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEPAWN_VM_ENGINE_H_
|
#endif //_INCLUDE_SOURCEPAWN_VM_ENGINE_H_
|
||||||
|
@ -5,33 +5,31 @@
|
|||||||
* FUNCTION CALLING *
|
* FUNCTION CALLING *
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
void CFunction::Set(funcid_t funcid, CPlugin *plugin)
|
void CFunction::Set(funcid_t funcid, IPluginContext *plugin)
|
||||||
{
|
{
|
||||||
m_funcid = funcid;
|
m_funcid = funcid;
|
||||||
m_pPlugin = plugin;
|
m_pContext = plugin;
|
||||||
m_curparam = 0;
|
m_curparam = 0;
|
||||||
m_errorstate = SP_ERROR_NONE;
|
m_errorstate = SP_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CFunction::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
|
int CFunction::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
|
||||||
{
|
{
|
||||||
IPluginContext *ctx = m_pPlugin->m_ctx.base;
|
|
||||||
|
|
||||||
while (num_params--)
|
while (num_params--)
|
||||||
{
|
{
|
||||||
ctx->PushCell(params[num_params]);
|
m_pContext->PushCell(params[num_params]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx->Execute(m_funcid, result);
|
return m_pContext->Execute(m_funcid, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPlugin *CFunction::GetParentPlugin()
|
IPluginContext *CFunction::GetParentContext()
|
||||||
{
|
{
|
||||||
return m_pPlugin;
|
return m_pContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFunction::CFunction(funcid_t funcid, CPlugin *plugin) :
|
CFunction::CFunction(funcid_t funcid, IPluginContext *plugin) :
|
||||||
m_funcid(funcid), m_pPlugin(plugin), m_curparam(0),
|
m_funcid(funcid), m_pContext(plugin), m_curparam(0),
|
||||||
m_errorstate(SP_ERROR_NONE)
|
m_errorstate(SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -79,11 +77,10 @@ int CFunction::PushArray(cell_t *inarray, unsigned int cells, cell_t **phys_addr
|
|||||||
return SetError(SP_ERROR_PARAMS_MAX);
|
return SetError(SP_ERROR_PARAMS_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPluginContext *ctx = m_pPlugin->m_ctx.base;
|
|
||||||
ParamInfo *info = &m_info[m_curparam];
|
ParamInfo *info = &m_info[m_curparam];
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if ((err=ctx->HeapAlloc(cells, &info->local_addr, &info->phys_addr)) != SP_ERROR_NONE)
|
if ((err=m_pContext->HeapAlloc(cells, &info->local_addr, &info->phys_addr)) != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
return SetError(err);
|
return SetError(err);
|
||||||
}
|
}
|
||||||
@ -127,12 +124,11 @@ int CFunction::_PushString(const char *string, int sz_flags, int cp_flags, size_
|
|||||||
return SetError(SP_ERROR_PARAMS_MAX);
|
return SetError(SP_ERROR_PARAMS_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPluginContext *base = m_pPlugin->m_ctx.base;
|
|
||||||
ParamInfo *info = &m_info[m_curparam];
|
ParamInfo *info = &m_info[m_curparam];
|
||||||
size_t cells = (len + sizeof(cell_t) - 1) / sizeof(cell_t);
|
size_t cells = (len + sizeof(cell_t) - 1) / sizeof(cell_t);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if ((err=base->HeapAlloc(cells, &info->local_addr, &info->phys_addr)) != SP_ERROR_NONE)
|
if ((err=m_pContext->HeapAlloc(cells, &info->local_addr, &info->phys_addr)) != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
return SetError(err);
|
return SetError(err);
|
||||||
}
|
}
|
||||||
@ -148,12 +144,12 @@ int CFunction::_PushString(const char *string, int sz_flags, int cp_flags, size_
|
|||||||
|
|
||||||
if (sz_flags & SM_PARAM_STRING_UTF8)
|
if (sz_flags & SM_PARAM_STRING_UTF8)
|
||||||
{
|
{
|
||||||
if ((err=base->StringToLocalUTF8(info->local_addr, len, string, NULL)) != SP_ERROR_NONE)
|
if ((err=m_pContext->StringToLocalUTF8(info->local_addr, len, string, NULL)) != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
return SetError(err);
|
return SetError(err);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((err=base->StringToLocal(info->local_addr, len, string)) != SP_ERROR_NONE)
|
if ((err=m_pContext->StringToLocal(info->local_addr, len, string)) != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
return SetError(err);
|
return SetError(err);
|
||||||
}
|
}
|
||||||
@ -174,13 +170,11 @@ void CFunction::Cancel()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPluginContext *base = m_pPlugin->m_ctx.base;
|
|
||||||
|
|
||||||
while (m_curparam--)
|
while (m_curparam--)
|
||||||
{
|
{
|
||||||
if (m_info[m_curparam].marked)
|
if (m_info[m_curparam].marked)
|
||||||
{
|
{
|
||||||
base->HeapRelease(m_info[m_curparam].local_addr);
|
m_pContext->HeapRelease(m_info[m_curparam].local_addr);
|
||||||
m_info[m_curparam].marked = false;
|
m_info[m_curparam].marked = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,8 +211,6 @@ int CFunction::Execute(cell_t *result)
|
|||||||
docopies = false;
|
docopies = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPluginContext *base = m_pPlugin->m_ctx.base;
|
|
||||||
|
|
||||||
while (numparams--)
|
while (numparams--)
|
||||||
{
|
{
|
||||||
if (!temp_info[numparams].marked)
|
if (!temp_info[numparams].marked)
|
||||||
@ -239,7 +231,7 @@ int CFunction::Execute(cell_t *result)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
base->HeapPop(temp_info[numparams].local_addr);
|
m_pContext->HeapPop(temp_info[numparams].local_addr);
|
||||||
temp_info[numparams].marked = false;
|
temp_info[numparams].marked = false;
|
||||||
}
|
}
|
||||||
|
|
55
core/vm/sp_vm_function.h
Normal file
55
core/vm/sp_vm_function.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef _INCLUDE_SOURCEMOD_BASEFUNCTION_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_BASEFUNCTION_H_
|
||||||
|
|
||||||
|
#include "sm_globals.h"
|
||||||
|
|
||||||
|
struct ParamInfo
|
||||||
|
{
|
||||||
|
int flags; /* Copy-back flags */
|
||||||
|
bool marked; /* Whether this is marked as being used */
|
||||||
|
cell_t local_addr; /* Local address to free */
|
||||||
|
cell_t *phys_addr; /* Physical address of our copy */
|
||||||
|
cell_t *orig_addr; /* Original address to copy back to */
|
||||||
|
ucell_t size; /* Size of array in bytes */
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPlugin;
|
||||||
|
|
||||||
|
class CFunction : public IPluginFunction
|
||||||
|
{
|
||||||
|
friend class SourcePawnEngine;
|
||||||
|
public:
|
||||||
|
CFunction(funcid_t funcid, IPluginContext *pContext);
|
||||||
|
public:
|
||||||
|
virtual int PushCell(cell_t cell);
|
||||||
|
virtual int PushCellByRef(cell_t *cell, int flags);
|
||||||
|
virtual int PushFloat(float number);
|
||||||
|
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 *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();
|
||||||
|
virtual int CallFunction(const cell_t *params, unsigned int num_params, cell_t *result);
|
||||||
|
virtual IPluginContext *GetParentContext();
|
||||||
|
public:
|
||||||
|
void Set(funcid_t funcid, IPluginContext *plugin);
|
||||||
|
private:
|
||||||
|
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
|
||||||
|
inline int SetError(int err)
|
||||||
|
{
|
||||||
|
m_errorstate = err;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
funcid_t m_funcid;
|
||||||
|
IPluginContext *m_pContext;
|
||||||
|
cell_t m_params[SP_MAX_EXEC_PARAMS];
|
||||||
|
ParamInfo m_info[SP_MAX_EXEC_PARAMS];
|
||||||
|
unsigned int m_curparam;
|
||||||
|
int m_errorstate;
|
||||||
|
CFunction *m_pNext;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SOURCEMOD_BASEFUNCTION_H_
|
@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
#include <IForwardSys.h>
|
#include <IForwardSys.h>
|
||||||
#include <IPluginSys.h>
|
#include <IPluginSys.h>
|
||||||
#include <IPluginFunction.h>
|
#include <sp_vm_api.h>
|
||||||
|
|
||||||
|
using namespace SourcePawn;
|
||||||
|
|
||||||
#define SMINTERFACE_FORWARDMANAGER_NAME "IForwardManager"
|
#define SMINTERFACE_FORWARDMANAGER_NAME "IForwardManager"
|
||||||
#define SMINTERFACE_FORWARDMANAGER_VERSION 1
|
#define SMINTERFACE_FORWARDMANAGER_VERSION 1
|
||||||
@ -190,7 +192,7 @@ namespace SourceMod
|
|||||||
* @param funcid Function id to add.
|
* @param funcid Function id to add.
|
||||||
* @return True on success, otherwise false.
|
* @return True on success, otherwise false.
|
||||||
*/
|
*/
|
||||||
virtual bool AddFunction(sp_context_t *ctx, funcid_t index) =0;
|
virtual bool AddFunction(IPluginContext *ctx, funcid_t index) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SP_PARAMTYPE_ANY 0
|
#define SP_PARAMTYPE_ANY 0
|
||||||
|
@ -1,153 +0,0 @@
|
|||||||
#ifndef _INCLUDE_SOURCEMOD_PLUGINFUNCTION_INTERFACE_H_
|
|
||||||
#define _INCLUDE_SOURCEMOD_PLUGINFUNCTION_INTERFACE_H_
|
|
||||||
|
|
||||||
#include <IPluginSys.h>
|
|
||||||
|
|
||||||
namespace SourceMod
|
|
||||||
{
|
|
||||||
#define SM_PARAM_COPYBACK (1<<0) /* Copy an array/reference back after call */
|
|
||||||
|
|
||||||
#define SM_PARAM_STRING_UTF8 (1<<0) /* String should be UTF-8 handled */
|
|
||||||
#define SM_PARAM_STRING_COPY (1<<1) /* String should be copied into the plugin */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Represents what a function needs to implement in order to be callable.
|
|
||||||
*/
|
|
||||||
class ICallable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Pushes a cell onto the current call.
|
|
||||||
*
|
|
||||||
* @param cell Parameter value to push.
|
|
||||||
* @return Error code, if any.
|
|
||||||
*/
|
|
||||||
virtual int PushCell(cell_t cell) =0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Pushes a cell by reference onto the current call.
|
|
||||||
* NOTE: On Execute, the pointer passed will be modified if copyback is enabled.
|
|
||||||
* NOTE: By reference parameters are cached and thus are not read until execution.
|
|
||||||
* This means you cannot push a pointer, change it, and push it again and expect
|
|
||||||
* two different values to come out.
|
|
||||||
*
|
|
||||||
* @param cell Address containing parameter value to push.
|
|
||||||
* @param flags Copy-back flags.
|
|
||||||
* @return Error code, if any.
|
|
||||||
*/
|
|
||||||
virtual int PushCellByRef(cell_t *cell, int flags) =0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Pushes a float onto the current call.
|
|
||||||
*
|
|
||||||
* @param float Parameter value to push.
|
|
||||||
* @return Error code, if any.
|
|
||||||
*/
|
|
||||||
virtual int PushFloat(float number) =0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Pushes a float onto the current call by reference.
|
|
||||||
* NOTE: On Execute, the pointer passed will be modified if copyback is enabled.
|
|
||||||
* NOTE: By reference parameters are cached and thus are not read until execution.
|
|
||||||
* This means you cannot push a pointer, change it, and push it again and expect
|
|
||||||
* two different values to come out.
|
|
||||||
*
|
|
||||||
* @param float Parameter value to push.
|
|
||||||
& @param flags Copy-back flags.
|
|
||||||
* @return Error code, if any.
|
|
||||||
*/
|
|
||||||
virtual int PushFloatByRef(float *number, int flags) =0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Pushes an array of cells onto the current call.
|
|
||||||
* NOTE: On Execute, the pointer passed will be modified if non-NULL and copy-back
|
|
||||||
* is enabled.
|
|
||||||
* NOTE: By reference parameters are cached and thus are not read until execution.
|
|
||||||
* This means you cannot push a pointer, change it, and push it again and expect
|
|
||||||
* two different values to come out.
|
|
||||||
*
|
|
||||||
* @param inarray Array to copy, NULL if no initial array should be copied.
|
|
||||||
* @param cells Number of cells to allocate and optionally read from the input array.
|
|
||||||
* @param phys_addr Optional return address for physical array, if one was made.
|
|
||||||
* @param flags Whether or not changes should be copied back to the input array.
|
|
||||||
* @return Error code, if any.
|
|
||||||
*/
|
|
||||||
virtual int PushArray(cell_t *inarray,
|
|
||||||
unsigned int cells,
|
|
||||||
cell_t **phys_addr,
|
|
||||||
int flags=0) =0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Pushes a string onto the current call.
|
|
||||||
*
|
|
||||||
* @param string String to push.
|
|
||||||
* @return Error code, if any.
|
|
||||||
*/
|
|
||||||
virtual int PushString(const char *string) =0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Pushes a string or string buffer.
|
|
||||||
* NOTE: On Execute, the pointer passed will be modified if copy-back is enabled.
|
|
||||||
*
|
|
||||||
* @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 *buffer, size_t length, int sz_flags, int cp_flags) =0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Cancels a function call that is being pushed but not yet executed.
|
|
||||||
* This can be used be reset for CallFunction() use.
|
|
||||||
*/
|
|
||||||
virtual void Cancel() =0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Encapsulates a function call in a plugin.
|
|
||||||
* NOTE: Function calls must be atomic to one execution context.
|
|
||||||
* NOTE: This object should not be deleted. It lives for the lifetime of the plugin.
|
|
||||||
*/
|
|
||||||
class IPluginFunction : public ICallable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Executes the forward, resets the pushed parameter list, and performs any copybacks.
|
|
||||||
*
|
|
||||||
* @param result Pointer to store return value in.
|
|
||||||
* @return Error code, if any.
|
|
||||||
*/
|
|
||||||
virtual int Execute(cell_t *result) =0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Executes the function with the given parameter array.
|
|
||||||
* Parameters are read in forward order (i.e. index 0 is parameter #1)
|
|
||||||
* NOTE: You will get an error if you attempt to use CallFunction() with
|
|
||||||
* previously pushed parameters.
|
|
||||||
*
|
|
||||||
* @param param Array of cell parameters.
|
|
||||||
* @param num_params Number of parameters to push.
|
|
||||||
* @param result Pointer to store result of function on return.
|
|
||||||
* @return SourcePawn error code (if any).
|
|
||||||
*/
|
|
||||||
virtual int CallFunction(const cell_t *params, unsigned int num_params, cell_t *result) =0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns which plugin this function belongs to.
|
|
||||||
*
|
|
||||||
* @return IPlugin pointer to parent plugin.
|
|
||||||
*/
|
|
||||||
virtual IPlugin *GetParentPlugin() =0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the physical address of a by-reference parameter.
|
|
||||||
*
|
|
||||||
* @param Parameter index to read (beginning at 0).
|
|
||||||
* @return Address, or NULL if invalid parameter specified.
|
|
||||||
*/
|
|
||||||
virtual cell_t *GetAddressOfPushedParam(unsigned int param) =0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_PLUGINFUNCTION_INTERFACE_H_
|
|
@ -57,8 +57,6 @@ namespace SourceMod
|
|||||||
PluginType_Global, /* Plugin will never be unloaded or updated */
|
PluginType_Global, /* Plugin will never be unloaded or updated */
|
||||||
};
|
};
|
||||||
|
|
||||||
class IPluginFunction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Encapsulates a run-time plugin as maintained by SourceMod.
|
* @brief Encapsulates a run-time plugin as maintained by SourceMod.
|
||||||
*/
|
*/
|
||||||
@ -129,22 +127,6 @@ namespace SourceMod
|
|||||||
*/
|
*/
|
||||||
virtual unsigned int GetSerial() const =0;
|
virtual unsigned int GetSerial() const =0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns a function by name.
|
|
||||||
*
|
|
||||||
* @param public_name Name of the function.
|
|
||||||
* @return A new IPluginFunction pointer, NULL if not found.
|
|
||||||
*/
|
|
||||||
virtual IPluginFunction *GetFunctionByName(const char *public_name) =0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns a function by its id.
|
|
||||||
*
|
|
||||||
* @param func_id Function ID.
|
|
||||||
* @return A new IPluginFunction pointer, NULL if not found.
|
|
||||||
*/
|
|
||||||
virtual IPluginFunction *GetFunctionById(funcid_t func_id) =0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a plugin's identity token.
|
* @brief Returns a plugin's identity token.
|
||||||
*/
|
*/
|
||||||
|
@ -17,6 +17,152 @@ namespace SourcePawn
|
|||||||
{
|
{
|
||||||
class IVirtualMachine;
|
class IVirtualMachine;
|
||||||
|
|
||||||
|
#define SM_PARAM_COPYBACK (1<<0) /* Copy an array/reference back after call */
|
||||||
|
|
||||||
|
#define SM_PARAM_STRING_UTF8 (1<<0) /* String should be UTF-8 handled */
|
||||||
|
#define SM_PARAM_STRING_COPY (1<<1) /* String should be copied into the plugin */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents what a function needs to implement in order to be callable.
|
||||||
|
*/
|
||||||
|
class ICallable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Pushes a cell onto the current call.
|
||||||
|
*
|
||||||
|
* @param cell Parameter value to push.
|
||||||
|
* @return Error code, if any.
|
||||||
|
*/
|
||||||
|
virtual int PushCell(cell_t cell) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pushes a cell by reference onto the current call.
|
||||||
|
* NOTE: On Execute, the pointer passed will be modified if copyback is enabled.
|
||||||
|
* NOTE: By reference parameters are cached and thus are not read until execution.
|
||||||
|
* This means you cannot push a pointer, change it, and push it again and expect
|
||||||
|
* two different values to come out.
|
||||||
|
*
|
||||||
|
* @param cell Address containing parameter value to push.
|
||||||
|
* @param flags Copy-back flags.
|
||||||
|
* @return Error code, if any.
|
||||||
|
*/
|
||||||
|
virtual int PushCellByRef(cell_t *cell, int flags) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pushes a float onto the current call.
|
||||||
|
*
|
||||||
|
* @param float Parameter value to push.
|
||||||
|
* @return Error code, if any.
|
||||||
|
*/
|
||||||
|
virtual int PushFloat(float number) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pushes a float onto the current call by reference.
|
||||||
|
* NOTE: On Execute, the pointer passed will be modified if copyback is enabled.
|
||||||
|
* NOTE: By reference parameters are cached and thus are not read until execution.
|
||||||
|
* This means you cannot push a pointer, change it, and push it again and expect
|
||||||
|
* two different values to come out.
|
||||||
|
*
|
||||||
|
* @param float Parameter value to push.
|
||||||
|
& @param flags Copy-back flags.
|
||||||
|
* @return Error code, if any.
|
||||||
|
*/
|
||||||
|
virtual int PushFloatByRef(float *number, int flags) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pushes an array of cells onto the current call.
|
||||||
|
* NOTE: On Execute, the pointer passed will be modified if non-NULL and copy-back
|
||||||
|
* is enabled.
|
||||||
|
* NOTE: By reference parameters are cached and thus are not read until execution.
|
||||||
|
* This means you cannot push a pointer, change it, and push it again and expect
|
||||||
|
* two different values to come out.
|
||||||
|
*
|
||||||
|
* @param inarray Array to copy, NULL if no initial array should be copied.
|
||||||
|
* @param cells Number of cells to allocate and optionally read from the input array.
|
||||||
|
* @param phys_addr Optional return address for physical array, if one was made.
|
||||||
|
* @param flags Whether or not changes should be copied back to the input array.
|
||||||
|
* @return Error code, if any.
|
||||||
|
*/
|
||||||
|
virtual int PushArray(cell_t *inarray,
|
||||||
|
unsigned int cells,
|
||||||
|
cell_t **phys_addr,
|
||||||
|
int flags=0) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pushes a string onto the current call.
|
||||||
|
*
|
||||||
|
* @param string String to push.
|
||||||
|
* @return Error code, if any.
|
||||||
|
*/
|
||||||
|
virtual int PushString(const char *string) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pushes a string or string buffer.
|
||||||
|
* NOTE: On Execute, the pointer passed will be modified if copy-back is enabled.
|
||||||
|
*
|
||||||
|
* @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 *buffer, size_t length, int sz_flags, int cp_flags) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Cancels a function call that is being pushed but not yet executed.
|
||||||
|
* This can be used be reset for CallFunction() use.
|
||||||
|
*/
|
||||||
|
virtual void Cancel() =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encapsulates a function call in a plugin.
|
||||||
|
* NOTE: Function calls must be atomic to one execution context.
|
||||||
|
* NOTE: This object should not be deleted. It lives for the lifetime of the plugin.
|
||||||
|
*/
|
||||||
|
class IPluginFunction : public ICallable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Executes the forward, resets the pushed parameter list, and performs any copybacks.
|
||||||
|
*
|
||||||
|
* @param result Pointer to store return value in.
|
||||||
|
* @return Error code, if any.
|
||||||
|
*/
|
||||||
|
virtual int Execute(cell_t *result) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Executes the function with the given parameter array.
|
||||||
|
* Parameters are read in forward order (i.e. index 0 is parameter #1)
|
||||||
|
* NOTE: You will get an error if you attempt to use CallFunction() with
|
||||||
|
* previously pushed parameters.
|
||||||
|
*
|
||||||
|
* @param param Array of cell parameters.
|
||||||
|
* @param num_params Number of parameters to push.
|
||||||
|
* @param result Pointer to store result of function on return.
|
||||||
|
* @return SourcePawn error code (if any).
|
||||||
|
*/
|
||||||
|
virtual int CallFunction(const cell_t *params, unsigned int num_params, cell_t *result) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns which plugin this function belongs to.
|
||||||
|
*
|
||||||
|
* @return IPluginContext pointer to parent plugin.
|
||||||
|
*/
|
||||||
|
virtual IPluginContext *GetParentContext() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the physical address of a by-reference parameter.
|
||||||
|
*
|
||||||
|
* @param Parameter index to read (beginning at 0).
|
||||||
|
* @return Address, or NULL if invalid parameter specified.
|
||||||
|
*/
|
||||||
|
virtual cell_t *GetAddressOfPushedParam(unsigned int param) =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Interface to managing a debug context at runtime.
|
* @brief Interface to managing a debug context at runtime.
|
||||||
*/
|
*/
|
||||||
@ -340,6 +486,22 @@ namespace SourcePawn
|
|||||||
*/
|
*/
|
||||||
virtual cell_t ThrowNativeError(const char *msg, ...) =0;
|
virtual cell_t ThrowNativeError(const char *msg, ...) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a function by name.
|
||||||
|
*
|
||||||
|
* @param public_name Name of the function.
|
||||||
|
* @return A new IPluginFunction pointer, NULL if not found.
|
||||||
|
*/
|
||||||
|
virtual IPluginFunction *GetFunctionByName(const char *public_name) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a function by its id.
|
||||||
|
*
|
||||||
|
* @param func_id Function ID.
|
||||||
|
* @return A new IPluginFunction pointer, NULL if not found.
|
||||||
|
*/
|
||||||
|
virtual IPluginFunction *GetFunctionById(funcid_t func_id) =0;
|
||||||
|
|
||||||
#if defined SOURCEMOD_BUILD
|
#if defined SOURCEMOD_BUILD
|
||||||
/**
|
/**
|
||||||
* @brief Returns the identity token for this context.
|
* @brief Returns the identity token for this context.
|
||||||
@ -348,6 +510,13 @@ namespace SourcePawn
|
|||||||
* @return Identity token.
|
* @return Identity token.
|
||||||
*/
|
*/
|
||||||
virtual SourceMod::IdentityToken_t *GetIdentity() =0;
|
virtual SourceMod::IdentityToken_t *GetIdentity() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns whether the identity is runnable.
|
||||||
|
*
|
||||||
|
* @return True if runnable, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool IsRunnable() =0;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ typedef uint32_t funcid_t;
|
|||||||
#define SP_ERROR_INVALID_NATIVE 21 /* Native was pending or invalid */
|
#define SP_ERROR_INVALID_NATIVE 21 /* Native was pending or invalid */
|
||||||
#define SP_ERROR_PARAMS_MAX 22 /* Maximum number of parameters reached */
|
#define SP_ERROR_PARAMS_MAX 22 /* Maximum number of parameters reached */
|
||||||
#define SP_ERROR_NATIVE 23 /* Error originates from a native */
|
#define SP_ERROR_NATIVE 23 /* Error originates from a native */
|
||||||
|
#define SP_ERROR_NOT_RUNNABLE 24 /* Function or plugin is not runnable */
|
||||||
|
|
||||||
/**********************************************
|
/**********************************************
|
||||||
*** The following structures are reference structures.
|
*** The following structures are reference structures.
|
||||||
|
Loading…
Reference in New Issue
Block a user