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;
pContext = ref.pl->GetBaseContext();
if ((pContext->GetNativeByIndex(ref.idx, &native)) == SP_ERROR_NONE)
{
native->status = SP_NATIVE_UNBOUND;
native->pfn = NULL;
}
pContext->GetRuntime()->UpdateNativeBinding(
ref.idx,
nullptr,
0,
nullptr);
}
void CNativeOwner::DropEverything()

View File

@ -646,11 +646,7 @@ void CPlugin::DependencyDropped(CPlugin *pOwner)
if (m_pRuntime->FindNativeByName(entry->name(), &idx) != SP_ERROR_NONE)
continue;
sp_native_t *native;
m_pRuntime->GetNativeByIndex(idx, &native);
native->pfn = NULL;
native->status = SP_NATIVE_UNBOUND;
m_pRuntime->UpdateNativeBinding(idx, nullptr, 0, nullptr);
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. */
IPluginContext *pContext = pPlugin->GetBaseContext();
uint32_t num = pContext->GetNativesNum();
sp_native_t *native;
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;
}
if (native->status == SP_NATIVE_UNBOUND
&& native->name[0] != '@'
&& !(native->flags & SP_NTVFLAG_OPTIONAL))
if (native->status == SP_NATIVE_UNBOUND &&
native->name[0] != '@' &&
!(native->flags & SP_NTVFLAG_OPTIONAL))
{
if (error)
{
@ -1478,16 +1472,14 @@ void CPluginManager::TryRefreshDependencies(CPlugin *pPlugin)
*/
IPluginContext *pContext = pPlugin->GetBaseContext();
uint32_t num = pContext->GetNativesNum();
sp_native_t *native;
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;
}
if (native->status == SP_NATIVE_UNBOUND
&& native->name[0] != '@'
&& !(native->flags & SP_NTVFLAG_OPTIONAL))
if (native->status == SP_NATIVE_UNBOUND &&
native->name[0] != '@' &&
!(native->flags & SP_NTVFLAG_OPTIONAL))
{
pPlugin->SetErrorState(Plugin_Error, "Native not found: %s", native->name);
return;

View File

@ -271,7 +271,6 @@ PassRef<Native> ShareSystem::FindNative(const char *name)
void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
{
sp_native_t *native;
uint32_t i, native_count;
IPluginContext *pContext;
@ -284,7 +283,8 @@ void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
native_count = pContext->GetNativesNum();
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;
// 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)
return;
sp_native_t *native;
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
const sp_native_t *native = pContext->GetRuntime()->GetNative(i);
if (!native)
return;
if (native->status == SP_NATIVE_BOUND)
@ -324,18 +324,15 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, const Ref<Native> &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)
{
/* Mark as bound... we do the rest next. */
native->status = SP_NATIVE_BOUND;
native->pfn = pEntry->func();
uint32_t flags = 0;
if (pEntry->fake)
{
/* This native is not necessarily optional, but we don't guarantee
* 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. */
@ -345,10 +342,9 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *native, uint
if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL)
{
/* Only add if there is a valid owner. */
if (pEntry->owner)
pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
else
native->status = SP_NATIVE_UNBOUND;
if (!pEntry->owner)
return;
pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
}
/* Otherwise, we're a strong dependent and not a weak one */
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)
@ -468,9 +470,7 @@ FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name
if (pRuntime->FindNativeByName(name, &index) == SP_ERROR_NONE)
{
sp_native_t *native;
if (pRuntime->GetNativeByIndex(index, &native) == SP_ERROR_NONE)
{
if (const sp_native_t *native = pRuntime->GetNative(index)) {
if (native->status == SP_NATIVE_BOUND)
return FeatureStatus_Available;
else

View File

@ -126,7 +126,7 @@ public:
private:
ke::PassRef<Native> AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv);
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:
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;
uint32_t idx;
sp_native_t *native;
pContext->LocalToString(params[1], &name);
if (pContext->FindNativeByName(name, &idx) != SP_ERROR_NONE)
@ -466,10 +465,7 @@ static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *param
return 0;
}
pContext->GetNativeByIndex(idx, &native);
native->flags |= SP_NTVFLAG_OPTIONAL;
pContext->GetRuntime()->UpdateNativeBinding(idx, nullptr, SP_NTVFLAG_OPTIONAL, nullptr);
return 1;
}

View File

@ -22,8 +22,8 @@
#include "sp_vm_types.h"
/** SourcePawn Engine API Versions */
#define SOURCEPAWN_ENGINE2_API_VERSION 7
#define SOURCEPAWN_API_VERSION 0x0207
#define SOURCEPAWN_ENGINE2_API_VERSION 8
#define SOURCEPAWN_API_VERSION 0x0208
namespace SourceMod {
struct IdentityToken_t;
@ -305,10 +305,11 @@ namespace SourcePawn
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 native Optionally filled with pointer to native structure.
* @param index Unused.
* @param native Unused.
* @return Returns SP_ERROR_PARAM.
*/
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.
*/
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;
/**
* @brief Deprecated, use IPluginRuntime instead.
* @brief Deprecated, does nothing.
*
* @param index Index number of native.
* @param native Optionally filled with pointer to native structure.
* @param index Unused.
* @param native Unused.
* @return Returns SP_ERROR_PARAM.
*/
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)
return NULL;
sp_native_t *native;
if (m_pRuntime->GetNativeByIndex(lastNative, &native) != SP_ERROR_NONE)
const sp_native_t *native = m_pRuntime->GetNative(lastNative);
if (!native)
return NULL;
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)
return;
sp_native_t *native;
if (rt->GetNativeByIndex(index, &native) != SP_ERROR_NONE)
return;
native->pfn = fn;
native->status = SP_NATIVE_BOUND;
rt->UpdateNativeBinding(index, fn, 0, nullptr);
}
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
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)
return SP_ERROR_INDEX;
if (native)
*native = &(m_plugin.natives[index]);
sp_native_t *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;
}
sp_native_t *
PluginRuntime::GetNativeByIndex(uint32_t index)
const sp_native_t *
PluginRuntime::GetNative(uint32_t index)
{
assert(index < m_plugin.num_natives);
if (index >= m_plugin.num_natives)
return nullptr;
return &m_plugin.natives[index];
}

View File

@ -60,7 +60,6 @@ class PluginRuntime
virtual IPluginDebugInfo *GetDebugInfo();
virtual int FindNativeByName(const char *name, uint32_t *index);
virtual int GetNativeByIndex(uint32_t index, sp_native_t **native);
virtual sp_native_t *GetNativeByIndex(uint32_t index);
virtual uint32_t GetNativesNum();
virtual int FindPublicByName(const char *name, uint32_t *index);
virtual int GetPublicByIndex(uint32_t index, sp_public_t **publicptr);
@ -83,6 +82,8 @@ class PluginRuntime
void SetName(const char *name);
unsigned GetNativeReplacement(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();
const sp_plugin_t *plugin() const {

View File

@ -1497,7 +1497,7 @@ Compiler::emitNativeCall(OPCODE op)
__ subl(stk, dat);
__ 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) ||
(native->flags & (SP_NTVFLAG_OPTIONAL | SP_NTVFLAG_EPHEMERAL)))
{