Remove native override API (bug 5852 part 1, r=ds).

--HG--
extra : rebase_source : 9df0399c88721b63667a9b0b5dca0eb20168117a
This commit is contained in:
David Anderson 2013-08-30 10:10:57 -07:00
parent 4dc5d0e12f
commit 0e677fb3a2
7 changed files with 58 additions and 177 deletions

View File

@ -1,5 +1,5 @@
/** /**
* vim: set ts=4 : * vim: set ts=4 sw=4 tw=99 noet :
* ============================================================================= * =============================================================================
* SourcePawn * SourcePawn
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
@ -69,30 +69,15 @@ INativeInvoker *NativeInterface::CreateInvoker()
bool NativeInvoker::Start(IPluginContext *pContext, const char *name) bool NativeInvoker::Start(IPluginContext *pContext, const char *name)
{ {
NativeEntry *entry; NativeEntry *entry = g_ShareSys.FindNative(name);
if (!entry)
entry = g_ShareSys.FindNative(name);
if (entry == NULL)
{
return false; return false;
}
native = NULL; if (!entry->owner || !entry->func)
if (entry->replacement.owner != NULL)
{
native = entry->replacement.func;
}
else if (entry->owner != NULL)
{
native = entry->func;
}
if (native == NULL)
{
return false; return false;
}
this->pContext = pContext; native_ = entry->func;
context_ = pContext;
m_curparam = 0; m_curparam = 0;
m_errorstate = SP_ERROR_NONE; m_errorstate = SP_ERROR_NONE;
@ -184,15 +169,13 @@ int NativeInvoker::_PushString(const char *string, int sz_flags, int cp_flags, s
void NativeInvoker::Cancel() void NativeInvoker::Cancel()
{ {
if (pContext == NULL) if (context_ == NULL)
{
return; return;
}
m_errorstate = SP_ERROR_NONE; m_errorstate = SP_ERROR_NONE;
m_curparam = 0; m_curparam = 0;
pContext = NULL; context_ = NULL;
native = NULL; native_ = NULL;
} }
int NativeInvoker::SetError(int err) int NativeInvoker::SetError(int err)
@ -205,10 +188,8 @@ int NativeInvoker::Invoke(cell_t *result)
{ {
int err = SP_ERROR_NONE; int err = SP_ERROR_NONE;
if (pContext == NULL) if (context_ == NULL)
{
return SP_ERROR_INVALID_NATIVE; return SP_ERROR_INVALID_NATIVE;
}
if (m_errorstate != SP_ERROR_NONE) if (m_errorstate != SP_ERROR_NONE)
{ {
@ -225,7 +206,7 @@ int NativeInvoker::Invoke(cell_t *result)
} }
//This is for re-entrancy! //This is for re-entrancy!
IPluginContext *ctx = pContext; IPluginContext *ctx = context_;
cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1]; cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
cell_t *temp_params = &_temp_params[1]; cell_t *temp_params = &_temp_params[1];
ParamInfo temp_info[SP_MAX_EXEC_PARAMS]; ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
@ -239,7 +220,7 @@ int NativeInvoker::Invoke(cell_t *result)
memcpy(temp_info, m_info, numparams * sizeof(ParamInfo)); memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
} }
m_curparam = 0; m_curparam = 0;
pContext = NULL; context_ = NULL;
/* Initialize 0th parameter */ /* Initialize 0th parameter */
_temp_params[0] = numparams; _temp_params[0] = numparams;
@ -324,7 +305,7 @@ int NativeInvoker::Invoke(cell_t *result)
/* Make the call if we can */ /* Make the call if we can */
if (err == SP_ERROR_NONE) if (err == SP_ERROR_NONE)
{ {
*result = native(ctx, _temp_params); *result = native_(ctx, _temp_params);
if (ctx->GetLastNativeError() != SP_ERROR_NONE) if (ctx->GetLastNativeError() != SP_ERROR_NONE)
{ {
docopies = false; docopies = false;

View File

@ -75,8 +75,8 @@ private:
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len); int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
int SetError(int err); int SetError(int err);
private: private:
IPluginContext *pContext; IPluginContext *context_;
SPVM_NATIVE_FUNC native; SPVM_NATIVE_FUNC native_;
cell_t m_params[SP_MAX_EXEC_PARAMS]; cell_t m_params[SP_MAX_EXEC_PARAMS];
ParamInfo m_info[SP_MAX_EXEC_PARAMS]; ParamInfo m_info[SP_MAX_EXEC_PARAMS];
unsigned int m_curparam; unsigned int m_curparam;

View File

@ -123,16 +123,6 @@ void CNativeOwner::DropEverything()
iter = m_WeakRefs.erase(iter); iter = m_WeakRefs.erase(iter);
} }
/* Unmark our replacement natives */
ntv_iter = m_ReplacedNatives.begin();
while (ntv_iter != m_ReplacedNatives.end())
{
pEntry = (*ntv_iter);
pEntry->replacement.func = NULL;
pEntry->replacement.owner = NULL;
ntv_iter = m_ReplacedNatives.erase(ntv_iter);
}
/* Strip all of our natives from the cache */ /* Strip all of our natives from the cache */
ntv_iter = m_Natives.begin(); ntv_iter = m_Natives.begin();
while (ntv_iter != m_Natives.end()) while (ntv_iter != m_Natives.end())
@ -167,8 +157,3 @@ void CNativeOwner::DropRefsTo(CPlugin *pPlugin)
m_Dependents.remove(pPlugin); m_Dependents.remove(pPlugin);
DropWeakRefsTo(pPlugin); DropWeakRefsTo(pPlugin);
} }
void CNativeOwner::AddReplacedNative(NativeEntry *pEntry)
{
m_ReplacedNatives.push_back(pEntry);
}

View File

@ -47,7 +47,6 @@ public:
void AddDependent(CPlugin *pPlugin); void AddDependent(CPlugin *pPlugin);
void AddWeakRef(const WeakNative & ref); void AddWeakRef(const WeakNative & ref);
void DropRefsTo(CPlugin *pPlugin); void DropRefsTo(CPlugin *pPlugin);
void AddReplacedNative(NativeEntry *pEntry);
private: private:
void DropWeakRefsTo(CPlugin *pPlugin); void DropWeakRefsTo(CPlugin *pPlugin);
void UnbindWeakRef(const WeakNative & ref); void UnbindWeakRef(const WeakNative & ref);
@ -56,7 +55,6 @@ protected:
unsigned int m_nMarkSerial; unsigned int m_nMarkSerial;
List<WeakNative> m_WeakRefs; List<WeakNative> m_WeakRefs;
List<NativeEntry *> m_Natives; List<NativeEntry *> m_Natives;
List<NativeEntry *> m_ReplacedNatives;
}; };
extern CNativeOwner g_CoreNatives; extern CNativeOwner g_CoreNatives;

View File

@ -35,6 +35,7 @@
#include "common_logic.h" #include "common_logic.h"
#include "PluginSys.h" #include "PluginSys.h"
#include "HandleSys.h" #include "HandleSys.h"
#include <assert.h>
ShareSystem g_ShareSys; ShareSystem g_ShareSys;
static unsigned int g_mark_serial = 0; static unsigned int g_mark_serial = 0;
@ -255,34 +256,7 @@ void ShareSystem::RegisterLibrary(IExtension *myself, const char *name)
void ShareSystem::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives) void ShareSystem::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives)
{ {
unsigned int i; assert(false);
NativeEntry *pEntry;
CNativeOwner *pOwner;
pOwner = g_Extensions.GetNativeOwner(myself);
for (i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
{
if ((pEntry = FindNative(natives[i].name)) == NULL)
{
continue;
}
if (pEntry->owner != &g_CoreNatives)
{
continue;
}
if (pEntry->replacement.owner != NULL)
{
continue;
}
/* Now it's safe to add the override */
pEntry->replacement.func = natives[i].func;
pEntry->replacement.owner = pOwner;
pOwner->AddReplacedNative(pEntry);
}
} }
NativeEntry *ShareSystem::FindNative(const char *name) NativeEntry *ShareSystem::FindNative(const char *name)
@ -295,7 +269,6 @@ NativeEntry *ShareSystem::FindNative(const char *name)
void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly) void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
{ {
NativeEntry *pEntry;
sp_native_t *native; sp_native_t *native;
uint32_t i, native_count; uint32_t i, native_count;
IPluginContext *pContext; IPluginContext *pContext;
@ -310,34 +283,19 @@ void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
for (i = 0; i < native_count; i++) for (i = 0; i < native_count; i++)
{ {
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE) if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
{
continue; continue;
}
/* If we're bound, check if there is a replacement available. // If we're already bound, no need to do anything else.
* If not, this native is totally finalized.
*/
if (native->status == SP_NATIVE_BOUND) if (native->status == SP_NATIVE_BOUND)
{
pEntry = (NativeEntry *)native->user;
assert(pEntry != NULL);
if (pEntry->replacement.owner == NULL
|| (pEntry->replacement.owner != NULL
&& pEntry->replacement.func == native->pfn))
{
continue;
}
}
/* Otherwise, the native must be in our cache. */
else if ((pEntry = FindNative(native->name)) == NULL)
{
continue; continue;
}
/* Otherwise, the native must be in our cache. */
NativeEntry *pEntry = FindNative(native->name);
if (!pEntry)
continue;
if (bCoreOnly && pEntry->owner != &g_CoreNatives) if (bCoreOnly && pEntry->owner != &g_CoreNatives)
{
continue; continue;
}
BindNativeToPlugin(pPlugin, native, i, pEntry); BindNativeToPlugin(pPlugin, native, i, pEntry);
} }
@ -377,49 +335,39 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin,
native->status = SP_NATIVE_BOUND; native->status = SP_NATIVE_BOUND;
native->user = pEntry; native->user = pEntry;
/* See if a replacement is available. */ /* Perform a bind. */
if (pEntry->replacement.owner != NULL) native->pfn = pEntry->func;
{
/* Perform a replacement bind. */
native->pfn = pEntry->replacement.func;
pEntry->replacement.owner->AddWeakRef(WeakNative(pPlugin, index, pEntry));
}
else
{
/* Perform a normal bind. */
native->pfn = pEntry->func;
/* We don't bother with dependency crap if the owner is Core. */ /* We don't bother with dependency crap if the owner is Core. */
if (pEntry->owner != &g_CoreNatives) if (pEntry->owner != &g_CoreNatives)
{
/* The native is optional, this is a special case */
if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL)
{ {
/* The native is optional, this is a special case */ /* Only add if there is a valid owner. */
if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL) if (pEntry->owner != NULL)
{ {
/* Only add if there is a valid owner. */ pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
if (pEntry->owner != NULL)
{
pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
}
else
{
native->status = SP_NATIVE_UNBOUND;
}
} }
/* Otherwise, we're a strong dependent and not a weak one */
else else
{ {
/* See if this has already been marked as a dependent. native->status = SP_NATIVE_UNBOUND;
* If it has, it means this relationship has already occurred, }
* and there is no reason to do it again. }
*/ /* Otherwise, we're a strong dependent and not a weak one */
if (pEntry->owner != pPlugin->ToNativeOwner() else
&& pEntry->owner->GetMarkSerial() != g_mark_serial) {
{ /* See if this has already been marked as a dependent.
/* This has not been marked as a dependency yet */ * If it has, it means this relationship has already occurred,
//pPlugin->AddDependency(pEntry->owner); * and there is no reason to do it again.
pEntry->owner->AddDependent(pPlugin); */
pEntry->owner->SetMarkSerial(g_mark_serial); if (pEntry->owner != pPlugin->ToNativeOwner()
} && pEntry->owner->GetMarkSerial() != g_mark_serial)
{
/* This has not been marked as a dependency yet */
//pPlugin->AddDependency(pEntry->owner);
pEntry->owner->AddDependent(pPlugin);
pEntry->owner->SetMarkSerial(g_mark_serial);
} }
} }
} }
@ -436,8 +384,6 @@ NativeEntry *ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_native
pEntry->owner = pOwner; pEntry->owner = pOwner;
pEntry->name = ntv->name; pEntry->name = ntv->name;
pEntry->func = ntv->func; pEntry->func = ntv->func;
pEntry->replacement.func = NULL;
pEntry->replacement.owner = NULL;
pEntry->fake = NULL; pEntry->fake = NULL;
m_NtvCache.insert(ntv->name, pEntry); m_NtvCache.insert(ntv->name, pEntry);
@ -481,8 +427,6 @@ void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
pEntry->func = NULL; pEntry->func = NULL;
pEntry->name = NULL; pEntry->name = NULL;
pEntry->owner = NULL; pEntry->owner = NULL;
pEntry->replacement.func = NULL;
pEntry->replacement.owner = NULL;
} }
NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func) NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
@ -518,8 +462,6 @@ NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name
pEntry->func = gate; pEntry->func = gate;
pEntry->name = pFake->name; pEntry->name = pFake->name;
pEntry->owner = g_PluginSys.GetPluginByCtx(pFake->ctx->GetContext()); pEntry->owner = g_PluginSys.GetPluginByCtx(pFake->ctx->GetContext());
pEntry->replacement.func = NULL;
pEntry->replacement.owner = NULL;
return pEntry; return pEntry;
} }
@ -582,18 +524,13 @@ FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name
} }
NativeEntry *entry = FindNative(name); NativeEntry *entry = FindNative(name);
if (entry == NULL) if (!entry)
return FeatureStatus_Unknown; return FeatureStatus_Unknown;
if ((entry->replacement.owner != NULL || entry->owner != NULL) && if (entry->owner && entry->func)
(entry->replacement.func != NULL || entry->func != NULL))
{
return FeatureStatus_Available; return FeatureStatus_Available;
}
else return FeatureStatus_Unavailable;
{
return FeatureStatus_Unavailable;
}
} }
FeatureStatus ShareSystem::TestCap(const char *name) FeatureStatus ShareSystem::TestCap(const char *name)

View File

@ -65,12 +65,6 @@ class CNativeOwner;
struct NativeEntry; struct NativeEntry;
class CPlugin; class CPlugin;
struct ReplaceNative
{
CNativeOwner *owner;
SPVM_NATIVE_FUNC func;
};
struct FakeNative struct FakeNative
{ {
char name[64]; char name[64];
@ -83,7 +77,6 @@ struct NativeEntry
CNativeOwner *owner; CNativeOwner *owner;
SPVM_NATIVE_FUNC func; SPVM_NATIVE_FUNC func;
const char *name; const char *name;
ReplaceNative replacement;
FakeNative *fake; FakeNative *fake;
static inline bool matches(const char *name, const NativeEntry *entry) static inline bool matches(const char *name, const NativeEntry *entry)

View File

@ -1,5 +1,5 @@
/** /**
* vim: set ts=4 : * vim: set ts=4 sw=4 tw=99 noet :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
@ -234,23 +234,10 @@ namespace SourceMod
virtual void RegisterLibrary(IExtension *myself, const char *name) =0; virtual void RegisterLibrary(IExtension *myself, const char *name) =0;
/** /**
* @brief Adds natives that will override Core natives when called. * @brief Deprecated. Does nothing.
* *
* A Core version of each native must exist. If one does not, then * @param myself Ignored.
* Core will simply ignore that entry. No more than one override * @param natives Ignored.
* can exist on a given native.
*
* Override natives represent a weak coupling. If the extension is
* unloaded, the native will be re-bound to the Core version. If
* the extension is loaded after plugins are loaded, the override
* will not take effect until those plugins are reloaded.
*
* @param myself Identity token of parent object.
* @param natives Array of natives to add. The last entry in
* the array must be filled with NULLs to
* terminate the array. The array must be static
* as Core will cache the pointer for the
* lifetime of the extension.
*/ */
virtual void OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives) =0; virtual void OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives) =0;