added experimental optional natives (part 1)

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401095
This commit is contained in:
Borja Ferrer 2007-07-12 02:57:43 +00:00
parent 5b8ffc08eb
commit 8a8e6ef594
6 changed files with 68 additions and 18 deletions

View File

@ -330,20 +330,44 @@ static cell_t AutoExecConfig(IPluginContext *pContext, const cell_t *params)
return 1; return 1;
} }
static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *params)
{
char *name;
uint32_t idx;
sp_context_t *ctx = pContext->GetContext();
CPlugin *pl = g_PluginSys.GetPluginByCtx(ctx);
if (!pl->IsInAskPluginLoad())
{
return pContext->ThrowNativeError("Calling MarkNativeAsOptional outside AskPluginLoad is not allowed");
}
pContext->LocalToString(params[1], &name);
if (pContext->FindNativeByName(name, &idx) != SP_ERROR_NONE)
{
return pContext->ThrowNativeError("Unable to find native \"%s\"", name);
}
ctx->natives[idx].flags |= SP_NTVFLAG_OPTIONAL;
return 1;
}
REGISTER_NATIVES(coreNatives) REGISTER_NATIVES(coreNatives)
{ {
{"AutoExecConfig", AutoExecConfig}, {"AutoExecConfig", AutoExecConfig},
{"GetPluginFilename", GetPluginFilename}, {"GetPluginFilename", GetPluginFilename},
{"GetPluginInfo", GetPluginInfo}, {"GetPluginInfo", GetPluginInfo},
{"GetPluginIterator", GetPluginIterator}, {"GetPluginIterator", GetPluginIterator},
{"GetPluginStatus", GetPluginStatus}, {"GetPluginStatus", GetPluginStatus},
{"GetSysTickCount", GetSysTickCount}, {"GetSysTickCount", GetSysTickCount},
{"GetTime", GetTime}, {"GetTime", GetTime},
{"IsPluginDebugging", IsPluginDebugging}, {"IsPluginDebugging", IsPluginDebugging},
{"MorePlugins", MorePlugins}, {"MorePlugins", MorePlugins},
{"ReadPlugin", ReadPlugin}, {"ReadPlugin", ReadPlugin},
{"ThrowError", ThrowError}, {"ThrowError", ThrowError},
{"SetFailState", SetFailState}, {"SetFailState", SetFailState},
{"FormatTime", FormatTime}, {"FormatTime", FormatTime},
{NULL, NULL}, {"MarkNativeAsOptional", MarkNativeAsOptional},
{NULL, NULL},
}; };

View File

@ -529,13 +529,19 @@ void CExtensionManager::BindAllNativesToPlugin(IPlugin *pPlugin)
n_iter++) n_iter++)
{ {
natives = (*n_iter); natives = (*n_iter);
uint32_t idx;
unsigned int i=0; unsigned int i=0;
while (natives[i].func != NULL && natives[i].name != NULL) while (natives[i].func != NULL && natives[i].name != NULL)
{ {
if (pContext->BindNative(&natives[i++]) == SP_ERROR_NONE) if (pContext->BindNative(&natives[i]) == SP_ERROR_NONE)
{ {
set = true; pContext->FindNativeByName(natives[i].name, &idx);
if (!(pContext->GetContext()->natives[idx].flags & SP_NTVFLAG_OPTIONAL))
{
set = true;
}
} }
i++;
} }
} }
if (set && (pExt->m_Plugins.find(pPlugin) == pExt->m_Plugins.end())) if (set && (pExt->m_Plugins.find(pPlugin) == pExt->m_Plugins.end()))

View File

@ -357,15 +357,19 @@ bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
return true; return true;
} }
m_IsInAskPluginLoad = true;
pFunction->PushCell(m_handle); pFunction->PushCell(m_handle);
pFunction->PushCell(g_PluginSys.IsLateLoadTime() ? 1 : 0); pFunction->PushCell(g_PluginSys.IsLateLoadTime() ? 1 : 0);
pFunction->PushStringEx(error, maxlength, 0, SM_PARAM_COPYBACK); pFunction->PushStringEx(error, maxlength, 0, SM_PARAM_COPYBACK);
pFunction->PushCell(maxlength); pFunction->PushCell(maxlength);
if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE) if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
{ {
m_IsInAskPluginLoad = false;
return false; return false;
} }
m_IsInAskPluginLoad = false;
if (!result || m_status != Plugin_Loaded) if (!result || m_status != Plugin_Loaded)
{ {
return false; return false;
@ -1098,7 +1102,8 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng
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))
{ {
if (error) if (error)
{ {
@ -1176,7 +1181,7 @@ void CPluginManager::TryRefreshNatives(CPlugin *pPlugin)
{ {
break; break;
} }
if (native->status == SP_NATIVE_UNBOUND) if (native->status == SP_NATIVE_UNBOUND && !(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;
@ -1213,6 +1218,12 @@ void CPluginManager::AddFakeNativesToPlugin(CPlugin *pPlugin)
native.func = pNative->func; native.func = pNative->func;
if (pContext->BindNative(&native) == SP_ERROR_NONE) if (pContext->BindNative(&native) == SP_ERROR_NONE)
{ {
uint32_t idx;
pContext->FindNativeByName(native.name, &idx);
if (!(pPlugin->GetContext()->natives[idx].flags & SP_NTVFLAG_OPTIONAL))
{
continue;
}
/* Add us as a dependency, but we're careful not to do this circularly! */ /* Add us as a dependency, but we're careful not to do this circularly! */
if (pNative->ctx != pContext) if (pNative->ctx != pContext)
{ {

View File

@ -234,6 +234,10 @@ public:
void AddConfig(bool autoCreate, const char *cfg, const char *folder); void AddConfig(bool autoCreate, const char *cfg, const char *folder);
unsigned int GetConfigCount(); unsigned int GetConfigCount();
AutoConfig *GetConfig(unsigned int i); AutoConfig *GetConfig(unsigned int i);
inline bool IsInAskPluginLoad()
{
return m_IsInAskPluginLoad;
}
protected: protected:
void UpdateInfo(); void UpdateInfo();
void SetTimeStamp(time_t t); void SetTimeStamp(time_t t);
@ -258,6 +262,7 @@ private:
Trie *m_pProps; Trie *m_pProps;
bool m_FakeNativesMissing; bool m_FakeNativesMissing;
CVector<AutoConfig *> m_configs; CVector<AutoConfig *> m_configs;
bool m_IsInAskPluginLoad;
}; };
class CPluginManager : class CPluginManager :

View File

@ -171,6 +171,8 @@ typedef struct sp_pubvar_s
#define SP_NATIVE_UNBOUND (0) /**< Native is undefined */ #define SP_NATIVE_UNBOUND (0) /**< Native is undefined */
#define SP_NATIVE_BOUND (1) /**< Native is bound */ #define SP_NATIVE_BOUND (1) /**< Native is bound */
#define SP_NTVFLAG_OPTIONAL (1<<0) /**< Native is optional */
/** /**
* @brief Native lookup table, by default names point back to the sp_plugin_infotab_t structure. * @brief Native lookup table, by default names point back to the sp_plugin_infotab_t structure.
*/ */
@ -179,6 +181,7 @@ typedef struct sp_native_s
SPVM_NATIVE_FUNC pfn; /**< Function pointer */ SPVM_NATIVE_FUNC pfn; /**< Function pointer */
const char * name; /**< Name of function */ const char * name; /**< Name of function */
uint32_t status; /**< Status flags */ uint32_t status; /**< Status flags */
uint32_t flags; /**< Native flags */
} sp_native_t; } sp_native_t;
/** /**

View File

@ -2445,6 +2445,7 @@ jit_rewind:
ctx->natives[iter].name = strbase + plugin->info.natives[iter].name; ctx->natives[iter].name = strbase + plugin->info.natives[iter].name;
ctx->natives[iter].pfn = &InvalidNative; ctx->natives[iter].pfn = &InvalidNative;
ctx->natives[iter].status = SP_NATIVE_UNBOUND; ctx->natives[iter].status = SP_NATIVE_UNBOUND;
ctx->natives[iter].flags = 0;
} }
} }