Merge branch 'fix-native-updating'
This commit is contained in:
commit
1f351c50d5
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
if (!pEntry->owner)
|
||||
return;
|
||||
pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
|
||||
else
|
||||
native->status = SP_NATIVE_UNBOUND;
|
||||
}
|
||||
/* 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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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)))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user