Merge branch 'fix-native-updating'

This commit is contained in:
David Anderson 2015-02-25 22:20:41 -08:00
commit 1f351c50d5
11 changed files with 85 additions and 70 deletions

View File

@ -84,11 +84,11 @@ void CNativeOwner::UnbindWeakRef(const WeakNative &ref)
IPluginContext *pContext; IPluginContext *pContext;
pContext = ref.pl->GetBaseContext(); pContext = ref.pl->GetBaseContext();
if ((pContext->GetNativeByIndex(ref.idx, &native)) == SP_ERROR_NONE) pContext->GetRuntime()->UpdateNativeBinding(
{ ref.idx,
native->status = SP_NATIVE_UNBOUND; nullptr,
native->pfn = NULL; 0,
} nullptr);
} }
void CNativeOwner::DropEverything() void CNativeOwner::DropEverything()

View File

@ -646,11 +646,7 @@ void CPlugin::DependencyDropped(CPlugin *pOwner)
if (m_pRuntime->FindNativeByName(entry->name(), &idx) != SP_ERROR_NONE) if (m_pRuntime->FindNativeByName(entry->name(), &idx) != SP_ERROR_NONE)
continue; continue;
sp_native_t *native; m_pRuntime->UpdateNativeBinding(idx, nullptr, 0, nullptr);
m_pRuntime->GetNativeByIndex(idx, &native);
native->pfn = NULL;
native->status = SP_NATIVE_UNBOUND;
unbound++; unbound++;
} }
@ -1357,16 +1353,14 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng
/* Find any unbound natives. Right now, these are not allowed. */ /* Find any unbound natives. Right now, these are not allowed. */
IPluginContext *pContext = pPlugin->GetBaseContext(); IPluginContext *pContext = pPlugin->GetBaseContext();
uint32_t num = pContext->GetNativesNum(); uint32_t num = pContext->GetNativesNum();
sp_native_t *native;
for (unsigned int i=0; i<num; i++) for (unsigned int i=0; i<num; i++)
{ {
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE) const sp_native_t *native = pContext->GetRuntime()->GetNative(i);
{ if (!native)
break; break;
} if (native->status == SP_NATIVE_UNBOUND &&
if (native->status == SP_NATIVE_UNBOUND native->name[0] != '@' &&
&& native->name[0] != '@' !(native->flags & SP_NTVFLAG_OPTIONAL))
&& !(native->flags & SP_NTVFLAG_OPTIONAL))
{ {
if (error) if (error)
{ {
@ -1478,16 +1472,14 @@ void CPluginManager::TryRefreshDependencies(CPlugin *pPlugin)
*/ */
IPluginContext *pContext = pPlugin->GetBaseContext(); IPluginContext *pContext = pPlugin->GetBaseContext();
uint32_t num = pContext->GetNativesNum(); uint32_t num = pContext->GetNativesNum();
sp_native_t *native;
for (unsigned int i=0; i<num; i++) for (unsigned int i=0; i<num; i++)
{ {
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE) const sp_native_t *native = pContext->GetRuntime()->GetNative(i);
{ if (!native)
break; break;
} if (native->status == SP_NATIVE_UNBOUND &&
if (native->status == SP_NATIVE_UNBOUND native->name[0] != '@' &&
&& native->name[0] != '@' !(native->flags & SP_NTVFLAG_OPTIONAL))
&& !(native->flags & SP_NTVFLAG_OPTIONAL))
{ {
pPlugin->SetErrorState(Plugin_Error, "Native not found: %s", native->name); pPlugin->SetErrorState(Plugin_Error, "Native not found: %s", native->name);
return; return;

View File

@ -271,7 +271,6 @@ PassRef<Native> ShareSystem::FindNative(const char *name)
void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly) void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
{ {
sp_native_t *native;
uint32_t i, native_count; uint32_t i, native_count;
IPluginContext *pContext; IPluginContext *pContext;
@ -284,7 +283,8 @@ void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
native_count = pContext->GetNativesNum(); native_count = pContext->GetNativesNum();
for (i = 0; i < native_count; i++) for (i = 0; i < native_count; i++)
{ {
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE) const sp_native_t *native = pContext->GetRuntime()->GetNative(i);
if (!native)
continue; continue;
// If we're already bound, no need to do anything else. // If we're already bound, no need to do anything else.
@ -314,8 +314,8 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, const Ref<Native> &entry)
if (pContext->FindNativeByName(entry->name(), &i) != SP_ERROR_NONE) if (pContext->FindNativeByName(entry->name(), &i) != SP_ERROR_NONE)
return; return;
sp_native_t *native; const sp_native_t *native = pContext->GetRuntime()->GetNative(i);
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE) if (!native)
return; return;
if (native->status == SP_NATIVE_BOUND) if (native->status == SP_NATIVE_BOUND)
@ -324,18 +324,15 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, const Ref<Native> &entry)
BindNativeToPlugin(pPlugin, native, i, entry); BindNativeToPlugin(pPlugin, native, i, entry);
} }
void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *native, uint32_t index, void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, const sp_native_t *native, uint32_t index,
const Ref<Native> &pEntry) const Ref<Native> &pEntry)
{ {
/* Mark as bound... we do the rest next. */ uint32_t flags = 0;
native->status = SP_NATIVE_BOUND;
native->pfn = pEntry->func();
if (pEntry->fake) if (pEntry->fake)
{ {
/* This native is not necessarily optional, but we don't guarantee /* This native is not necessarily optional, but we don't guarantee
* that its address is long-lived. */ * that its address is long-lived. */
native->flags |= SP_NTVFLAG_EPHEMERAL; flags |= SP_NTVFLAG_EPHEMERAL;
} }
/* We don't bother with dependency crap if the owner is Core. */ /* We don't bother with dependency crap if the owner is Core. */
@ -345,10 +342,9 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *native, uint
if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL) if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL)
{ {
/* Only add if there is a valid owner. */ /* Only add if there is a valid owner. */
if (pEntry->owner) if (!pEntry->owner)
pEntry->owner->AddWeakRef(WeakNative(pPlugin, index)); return;
else pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
native->status = SP_NATIVE_UNBOUND;
} }
/* Otherwise, we're a strong dependent and not a weak one */ /* Otherwise, we're a strong dependent and not a weak one */
else else
@ -367,6 +363,12 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *native, uint
} }
} }
} }
pPlugin->GetRuntime()->UpdateNativeBinding(
index,
pEntry->func(),
flags,
nullptr);
} }
PassRef<Native> ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv) PassRef<Native> ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv)
@ -468,9 +470,7 @@ FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name
if (pRuntime->FindNativeByName(name, &index) == SP_ERROR_NONE) if (pRuntime->FindNativeByName(name, &index) == SP_ERROR_NONE)
{ {
sp_native_t *native; if (const sp_native_t *native = pRuntime->GetNative(index)) {
if (pRuntime->GetNativeByIndex(index, &native) == SP_ERROR_NONE)
{
if (native->status == SP_NATIVE_BOUND) if (native->status == SP_NATIVE_BOUND)
return FeatureStatus_Available; return FeatureStatus_Available;
else else

View File

@ -126,7 +126,7 @@ public:
private: private:
ke::PassRef<Native> AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv); ke::PassRef<Native> AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv);
void ClearNativeFromCache(CNativeOwner *pOwner, const char *name); void ClearNativeFromCache(CNativeOwner *pOwner, const char *name);
void BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *ntv, uint32_t index, const ke::Ref<Native> &pEntry); void BindNativeToPlugin(CPlugin *pPlugin, const sp_native_t *ntv, uint32_t index, const ke::Ref<Native> &pEntry);
private: private:
typedef NameHashSet<ke::Ref<Native>, Native> NativeCache; typedef NameHashSet<ke::Ref<Native>, Native> NativeCache;

View File

@ -457,7 +457,6 @@ static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *param
{ {
char *name; char *name;
uint32_t idx; uint32_t idx;
sp_native_t *native;
pContext->LocalToString(params[1], &name); pContext->LocalToString(params[1], &name);
if (pContext->FindNativeByName(name, &idx) != SP_ERROR_NONE) if (pContext->FindNativeByName(name, &idx) != SP_ERROR_NONE)
@ -466,10 +465,7 @@ static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *param
return 0; return 0;
} }
pContext->GetNativeByIndex(idx, &native); pContext->GetRuntime()->UpdateNativeBinding(idx, nullptr, SP_NTVFLAG_OPTIONAL, nullptr);
native->flags |= SP_NTVFLAG_OPTIONAL;
return 1; return 1;
} }

View File

@ -22,8 +22,8 @@
#include "sp_vm_types.h" #include "sp_vm_types.h"
/** SourcePawn Engine API Versions */ /** SourcePawn Engine API Versions */
#define SOURCEPAWN_ENGINE2_API_VERSION 7 #define SOURCEPAWN_ENGINE2_API_VERSION 8
#define SOURCEPAWN_API_VERSION 0x0207 #define SOURCEPAWN_API_VERSION 0x0208
namespace SourceMod { namespace SourceMod {
struct IdentityToken_t; struct IdentityToken_t;
@ -305,10 +305,11 @@ namespace SourcePawn
virtual int FindNativeByName(const char *name, uint32_t *index) =0; virtual int FindNativeByName(const char *name, uint32_t *index) =0;
/** /**
* @brief Gets native info by index. * @brief Deprecated, does nothing.
* *
* @param index Index number of native. * @param index Unused.
* @param native Optionally filled with pointer to native structure. * @param native Unused.
* @return Returns SP_ERROR_PARAM.
*/ */
virtual int GetNativeByIndex(uint32_t index, sp_native_t **native) =0; virtual int GetNativeByIndex(uint32_t index, sp_native_t **native) =0;
@ -446,6 +447,23 @@ namespace SourcePawn
* @return 16-byte buffer with MD5 hash of the plugin's Data. * @return 16-byte buffer with MD5 hash of the plugin's Data.
*/ */
virtual unsigned char *GetDataHash() =0; virtual unsigned char *GetDataHash() =0;
/**
* @brief Update the native binding at the given index.
*
* @param pfn Native function pointer.
* @param flags Native flags.
* @param user User data pointer.
*/
virtual int UpdateNativeBinding(uint32_t index, SPVM_NATIVE_FUNC pfn, uint32_t flags, void *data) = 0;
/**
* @brief Returns the native at the given index.
*
* @param index Native index.
* @return Native pointer, or NULL on failure.
*/
virtual const sp_native_t *GetNative(uint32_t index) = 0;
}; };
/** /**
@ -537,10 +555,11 @@ namespace SourcePawn
virtual int FindNativeByName(const char *name, uint32_t *index) =0; virtual int FindNativeByName(const char *name, uint32_t *index) =0;
/** /**
* @brief Deprecated, use IPluginRuntime instead. * @brief Deprecated, does nothing.
* *
* @param index Index number of native. * @param index Unused.
* @param native Optionally filled with pointer to native structure. * @param native Unused.
* @return Returns SP_ERROR_PARAM.
*/ */
virtual int GetNativeByIndex(uint32_t index, sp_native_t **native) =0; virtual int GetNativeByIndex(uint32_t index, sp_native_t **native) =0;

View File

@ -111,8 +111,8 @@ CContextTrace::GetLastNative(uint32_t *index)
if (lastNative < 0) if (lastNative < 0)
return NULL; return NULL;
sp_native_t *native; const sp_native_t *native = m_pRuntime->GetNative(lastNative);
if (m_pRuntime->GetNativeByIndex(lastNative, &native) != SP_ERROR_NONE) if (!native)
return NULL; return NULL;
if (index) if (index)

View File

@ -173,12 +173,7 @@ static void BindNative(IPluginRuntime *rt, const char *name, SPVM_NATIVE_FUNC fn
if ((err = rt->FindNativeByName(name, &index)) != SP_ERROR_NONE) if ((err = rt->FindNativeByName(name, &index)) != SP_ERROR_NONE)
return; return;
sp_native_t *native; rt->UpdateNativeBinding(index, fn, 0, nullptr);
if (rt->GetNativeByIndex(index, &native) != SP_ERROR_NONE)
return;
native->pfn = fn;
native->status = SP_NATIVE_BOUND;
} }
static cell_t PrintFloat(IPluginContext *cx, const cell_t *params) static cell_t PrintFloat(IPluginContext *cx, const cell_t *params)

View File

@ -351,20 +351,32 @@ PluginRuntime::FindNativeByName(const char *name, uint32_t *index)
int int
PluginRuntime::GetNativeByIndex(uint32_t index, sp_native_t **native) PluginRuntime::GetNativeByIndex(uint32_t index, sp_native_t **native)
{
return SP_ERROR_PARAM;
}
int
PluginRuntime::UpdateNativeBinding(uint32_t index, SPVM_NATIVE_FUNC pfn, uint32_t flags, void *data)
{ {
if (index >= m_plugin.num_natives) if (index >= m_plugin.num_natives)
return SP_ERROR_INDEX; return SP_ERROR_INDEX;
if (native) sp_native_t *native = &m_plugin.natives[index];
*native = &(m_plugin.natives[index]);
native->pfn = pfn;
native->status = pfn
? SP_NATIVE_BOUND
: SP_NATIVE_UNBOUND;
native->flags = flags;
native->user = data;
return SP_ERROR_NONE; return SP_ERROR_NONE;
} }
sp_native_t * const sp_native_t *
PluginRuntime::GetNativeByIndex(uint32_t index) PluginRuntime::GetNative(uint32_t index)
{ {
assert(index < m_plugin.num_natives); if (index >= m_plugin.num_natives)
return nullptr;
return &m_plugin.natives[index]; return &m_plugin.natives[index];
} }

View File

@ -60,7 +60,6 @@ class PluginRuntime
virtual IPluginDebugInfo *GetDebugInfo(); virtual IPluginDebugInfo *GetDebugInfo();
virtual int FindNativeByName(const char *name, uint32_t *index); virtual int FindNativeByName(const char *name, uint32_t *index);
virtual int GetNativeByIndex(uint32_t index, sp_native_t **native); virtual int GetNativeByIndex(uint32_t index, sp_native_t **native);
virtual sp_native_t *GetNativeByIndex(uint32_t index);
virtual uint32_t GetNativesNum(); virtual uint32_t GetNativesNum();
virtual int FindPublicByName(const char *name, uint32_t *index); virtual int FindPublicByName(const char *name, uint32_t *index);
virtual int GetPublicByIndex(uint32_t index, sp_public_t **publicptr); virtual int GetPublicByIndex(uint32_t index, sp_public_t **publicptr);
@ -83,6 +82,8 @@ class PluginRuntime
void SetName(const char *name); void SetName(const char *name);
unsigned GetNativeReplacement(size_t index); unsigned GetNativeReplacement(size_t index);
ScriptedInvoker *GetPublicFunction(size_t index); ScriptedInvoker *GetPublicFunction(size_t index);
int UpdateNativeBinding(uint32_t index, SPVM_NATIVE_FUNC pfn, uint32_t flags, void *data) KE_OVERRIDE;
const sp_native_t *GetNative(uint32_t index) KE_OVERRIDE;
PluginContext *GetBaseContext(); PluginContext *GetBaseContext();
const sp_plugin_t *plugin() const { const sp_plugin_t *plugin() const {

View File

@ -1497,7 +1497,7 @@ Compiler::emitNativeCall(OPCODE op)
__ subl(stk, dat); __ subl(stk, dat);
__ movl(Operand(eax, PluginContext::offsetOfSp()), stk); __ movl(Operand(eax, PluginContext::offsetOfSp()), stk);
sp_native_t *native = rt_->GetNativeByIndex(native_index); const sp_native_t *native = rt_->GetNative(native_index);
if ((native->status != SP_NATIVE_BOUND) || if ((native->status != SP_NATIVE_BOUND) ||
(native->flags & (SP_NTVFLAG_OPTIONAL | SP_NTVFLAG_EPHEMERAL))) (native->flags & (SP_NTVFLAG_OPTIONAL | SP_NTVFLAG_EPHEMERAL)))
{ {