fixed amb200, added native test suite
This commit is contained in:
parent
5d4669d52e
commit
de530e2ca3
|
@ -46,12 +46,16 @@
|
||||||
//With the exception for param_convert, which was written by
|
//With the exception for param_convert, which was written by
|
||||||
// Julien "dJeyL" Laurent
|
// Julien "dJeyL" Laurent
|
||||||
|
|
||||||
CStack<int> g_ErrorStk;
|
|
||||||
CVector<regnative *> g_RegNatives;
|
CVector<regnative *> g_RegNatives;
|
||||||
CStack<regnative *> g_NativeStack;
|
|
||||||
static char g_errorStr[512] = {0};
|
static char g_errorStr[512] = {0};
|
||||||
bool g_Initialized = false;
|
bool g_Initialized = false;
|
||||||
|
|
||||||
|
/* Stack stuff */
|
||||||
|
regnative *g_pCurNative = NULL;
|
||||||
|
AMX *g_pCaller = NULL;
|
||||||
|
cell g_Params[CALLFUNC_MAXPARAMS];
|
||||||
|
int g_CurError = AMX_ERR_NONE;
|
||||||
|
|
||||||
int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
if (idx < 0 || idx >= (int)g_RegNatives.size())
|
if (idx < 0 || idx >= (int)g_RegNatives.size())
|
||||||
|
@ -79,37 +83,55 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pNative->caller)
|
/* Save old values on ZE STACK */
|
||||||
|
AMX *pSaveCaller = g_pCaller;
|
||||||
|
cell saveParams[CALLFUNC_MAXPARAMS];
|
||||||
|
regnative *pSaveNative = g_pCurNative;
|
||||||
|
int saveError = g_CurError;
|
||||||
|
|
||||||
|
if (pSaveNative)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Bug caught! Please contact the AMX Mod X Dev Team.");
|
for (ucell i = 0; i <= g_Params[0] / sizeof(cell); i++)
|
||||||
return 0;
|
{
|
||||||
|
saveParams[i] = g_Params[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//parameter stack
|
/* Save current info */
|
||||||
//NOTE: it is possible that recursive register native calling
|
g_CurError = AMX_ERR_NONE;
|
||||||
// could potentially be somehow damaged here.
|
g_pCaller = amx;
|
||||||
//so, a :TODO: - make the stack unique, rather than a known ptr
|
g_pCurNative = pNative;
|
||||||
pNative->caller = amx;
|
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
cell ret = 0;
|
cell ret = 0;
|
||||||
g_ErrorStk.push(0);
|
|
||||||
g_NativeStack.push(pNative);
|
|
||||||
if (pNative->style == 0)
|
if (pNative->style == 0)
|
||||||
{
|
{
|
||||||
amx_Push(pNative->amx, numParams);
|
amx_Push(pNative->amx, numParams);
|
||||||
amx_Push(pNative->amx, pPlugin->getId());
|
amx_Push(pNative->amx, pPlugin->getId());
|
||||||
for (int i=numParams; i>=0; i--)
|
for (int i=numParams; i>=0; i--)
|
||||||
pNative->params[i] = params[i];
|
{
|
||||||
|
g_Params[i] = params[i];
|
||||||
|
}
|
||||||
} else if (pNative->style == 1) {
|
} else if (pNative->style == 1) {
|
||||||
//use dJeyL's system .. very clever!
|
/**
|
||||||
|
* use dJeyL's system .. very clever!
|
||||||
|
* NOTE: clever, but doesn't work at all since the JIT does bounds checking
|
||||||
|
* this should REALLY be deprecated
|
||||||
|
*/
|
||||||
for (int i=numParams; i>=1; i--)
|
for (int i=numParams; i>=1; i--)
|
||||||
|
{
|
||||||
amx_Push(pNative->amx, params[i]);
|
amx_Push(pNative->amx, params[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Debugger *pDebugger = (Debugger *)pNative->amx->userdata[UD_DEBUGGER];
|
Debugger *pDebugger = (Debugger *)pNative->amx->userdata[UD_DEBUGGER];
|
||||||
if (pDebugger)
|
if (pDebugger)
|
||||||
|
{
|
||||||
pDebugger->BeginExec();
|
pDebugger->BeginExec();
|
||||||
|
}
|
||||||
|
|
||||||
err=amx_Exec(pNative->amx, &ret, pNative->func);
|
err=amx_Exec(pNative->amx, &ret, pNative->func);
|
||||||
|
|
||||||
if (err != AMX_ERR_NONE)
|
if (err != AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
if (pDebugger && pDebugger->ErrorExists())
|
if (pDebugger && pDebugger->ErrorExists())
|
||||||
|
@ -122,15 +144,26 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
||||||
pNative->amx->error = AMX_ERR_NONE;
|
pNative->amx->error = AMX_ERR_NONE;
|
||||||
//furthermore, log an error in the parent plugin.
|
//furthermore, log an error in the parent plugin.
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Unhandled dynamic native error");
|
LogError(amx, AMX_ERR_NATIVE, "Unhandled dynamic native error");
|
||||||
} else if (g_ErrorStk.front()) {
|
} else if (g_CurError != AMX_ERR_NONE) {
|
||||||
LogError(amx, g_ErrorStk.front(), g_errorStr);
|
LogError(amx, g_CurError, g_errorStr);
|
||||||
}
|
}
|
||||||
if (pDebugger)
|
|
||||||
pDebugger->EndExec();
|
|
||||||
g_NativeStack.pop();
|
|
||||||
g_ErrorStk.pop();
|
|
||||||
|
|
||||||
pNative->caller = NULL;
|
if (pDebugger)
|
||||||
|
{
|
||||||
|
pDebugger->EndExec();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore everything */
|
||||||
|
g_pCurNative = pSaveNative;
|
||||||
|
g_CurError = saveError;
|
||||||
|
g_pCaller = pSaveCaller;
|
||||||
|
if (pSaveNative)
|
||||||
|
{
|
||||||
|
for (ucell i = 0; i <= saveParams[0] / sizeof(cell); i++)
|
||||||
|
{
|
||||||
|
g_Params[i] = saveParams[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -138,7 +171,9 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
||||||
AMX_NATIVE_INFO *BuildNativeTable()
|
AMX_NATIVE_INFO *BuildNativeTable()
|
||||||
{
|
{
|
||||||
if (g_RegNatives.size() < 1)
|
if (g_RegNatives.size() < 1)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.size() + 1];
|
AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.size() + 1];
|
||||||
|
|
||||||
|
@ -164,8 +199,7 @@ static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
|
||||||
char *err = format_amxstring(amx, params, 2, len);
|
char *err = format_amxstring(amx, params, 2, len);
|
||||||
|
|
||||||
_snprintf(g_errorStr, sizeof(g_errorStr), "%s", err);
|
_snprintf(g_errorStr, sizeof(g_errorStr), "%s", err);
|
||||||
g_ErrorStk.pop();
|
g_CurError = params[1];
|
||||||
g_ErrorStk.push(params[1]);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -173,13 +207,12 @@ static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
|
||||||
//get_string(param, dest[], len)
|
//get_string(param, dest[], len)
|
||||||
static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
if (!g_NativeStack.size())
|
if (!g_pCurNative || (g_pCaller != amx))
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
if (g_pCurNative->style)
|
||||||
if (pNative->style)
|
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -187,20 +220,19 @@ static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
|
||||||
int p = params[1];
|
int p = params[1];
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
char *str = get_amxstring(pNative->caller, pNative->params[p], 0, len);
|
char *str = get_amxstring(g_pCaller, g_Params[p], 0, len);
|
||||||
return set_amxstring(amx, params[2], str, params[3]);
|
return set_amxstring(amx, params[2], str, params[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//set_string(param, source[], maxlen)
|
//set_string(param, source[], maxlen)
|
||||||
static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
if (!g_NativeStack.size())
|
if (!g_pCurNative || (g_pCaller != amx))
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
if (g_pCurNative->style)
|
||||||
if (pNative->style)
|
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -210,46 +242,44 @@ static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
|
||||||
int len;
|
int len;
|
||||||
char *str = get_amxstring(amx, params[2], 0, len);
|
char *str = get_amxstring(amx, params[2], 0, len);
|
||||||
|
|
||||||
return set_amxstring(pNative->caller, pNative->params[p], str, params[3]);
|
return set_amxstring(g_pCaller, g_Params[p], str, params[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//get a byvalue parameter
|
//get a byvalue parameter
|
||||||
//get_param(num)
|
//get_param(num)
|
||||||
static cell AMX_NATIVE_CALL get_param(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL get_param(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
if (!g_NativeStack.size())
|
if (!g_pCurNative || (g_pCaller != amx))
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
if (g_pCurNative->style)
|
||||||
if (pNative->style)
|
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int p = params[1];
|
int p = params[1];
|
||||||
|
|
||||||
return pNative->params[p];
|
return g_Params[p];
|
||||||
}
|
}
|
||||||
|
|
||||||
//get_param_byref(num)
|
//get_param_byref(num)
|
||||||
static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
if (!g_NativeStack.size())
|
if (!g_pCurNative || (g_pCaller != amx))
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
if (g_pCurNative->style)
|
||||||
if (pNative->style)
|
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int p = params[1];
|
int p = params[1];
|
||||||
|
|
||||||
cell *addr = get_amxaddr(pNative->caller, pNative->params[p]);
|
cell *addr = get_amxaddr(g_pCaller, g_Params[p]);
|
||||||
|
|
||||||
return addr[0];
|
return addr[0];
|
||||||
}
|
}
|
||||||
|
@ -257,20 +287,19 @@ static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
|
||||||
//set_param_byref(num, val)
|
//set_param_byref(num, val)
|
||||||
static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
if (!g_NativeStack.size())
|
if (!g_pCurNative || (g_pCaller != amx))
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
if (g_pCurNative->style)
|
||||||
if (pNative->style)
|
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int p = params[1];
|
int p = params[1];
|
||||||
|
|
||||||
cell *addr = get_amxaddr(pNative->caller, pNative->params[p]);
|
cell *addr = get_amxaddr(g_pCaller, g_Params[p]);
|
||||||
|
|
||||||
addr[0] = params[2];
|
addr[0] = params[2];
|
||||||
|
|
||||||
|
@ -280,20 +309,19 @@ static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
|
||||||
//get_array(param, dest[], size)
|
//get_array(param, dest[], size)
|
||||||
static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
if (!g_NativeStack.size())
|
if (!g_pCurNative || (g_pCaller != amx))
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
if (g_pCurNative->style)
|
||||||
if (pNative->style)
|
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int p = params[1];
|
int p = params[1];
|
||||||
|
|
||||||
cell *source = get_amxaddr(pNative->caller, pNative->params[p]);
|
cell *source = get_amxaddr(g_pCaller, g_Params[p]);
|
||||||
cell *dest = get_amxaddr(amx, params[2]);
|
cell *dest = get_amxaddr(amx, params[2]);
|
||||||
|
|
||||||
int size = params[3];
|
int size = params[3];
|
||||||
|
@ -306,20 +334,19 @@ static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
||||||
//set_array(param, source[], size)
|
//set_array(param, source[], size)
|
||||||
static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
if (!g_NativeStack.size())
|
if (!g_pCurNative || (g_pCaller != amx))
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
if (g_pCurNative->style)
|
||||||
if (pNative->style)
|
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int p = params[1];
|
int p = params[1];
|
||||||
|
|
||||||
cell *dest = get_amxaddr(pNative->caller, pNative->params[p]);
|
cell *dest = get_amxaddr(g_pCaller, g_Params[p]);
|
||||||
cell *source = get_amxaddr(amx, params[2]);
|
cell *source = get_amxaddr(amx, params[2]);
|
||||||
|
|
||||||
int size = params[3];
|
int size = params[3];
|
||||||
|
@ -331,15 +358,13 @@ static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL vdformat(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL vdformat(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
if (!g_NativeStack.size())
|
if (!g_pCurNative || (g_pCaller != amx))
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
regnative *pNative = g_NativeStack.front();
|
if (g_pCurNative->style)
|
||||||
|
|
||||||
if (pNative->style)
|
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -348,10 +373,7 @@ static cell AMX_NATIVE_CALL vdformat(AMX *amx, cell *params)
|
||||||
int vargPos = static_cast<int>(params[4]);
|
int vargPos = static_cast<int>(params[4]);
|
||||||
int fargPos = static_cast<int>(params[3]);
|
int fargPos = static_cast<int>(params[3]);
|
||||||
|
|
||||||
/** get the parent parameter array */
|
cell max = g_Params[0] / sizeof(cell);
|
||||||
cell *local_params = pNative->params;
|
|
||||||
|
|
||||||
cell max = local_params[0] / sizeof(cell);
|
|
||||||
if (vargPos > (int)max + 1)
|
if (vargPos > (int)max + 1)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid vararg parameter passed: %d", vargPos);
|
LogError(amx, AMX_ERR_NATIVE, "Invalid vararg parameter passed: %d", vargPos);
|
||||||
|
@ -374,7 +396,7 @@ static cell AMX_NATIVE_CALL vdformat(AMX *amx, cell *params)
|
||||||
}
|
}
|
||||||
fmt = get_amxaddr(amx, params[5]);
|
fmt = get_amxaddr(amx, params[5]);
|
||||||
} else {
|
} else {
|
||||||
fmt = get_amxaddr(pNative->caller, pNative->params[fargPos]);
|
fmt = get_amxaddr(g_pCaller, g_Params[fargPos]);
|
||||||
}
|
}
|
||||||
cell *realdest = get_amxaddr(amx, params[1]);
|
cell *realdest = get_amxaddr(amx, params[1]);
|
||||||
size_t maxlen = static_cast<size_t>(params[2]);
|
size_t maxlen = static_cast<size_t>(params[2]);
|
||||||
|
@ -385,7 +407,7 @@ static cell AMX_NATIVE_CALL vdformat(AMX *amx, cell *params)
|
||||||
dest = cpbuf;
|
dest = cpbuf;
|
||||||
|
|
||||||
/* perform format */
|
/* perform format */
|
||||||
size_t total = atcprintf(dest, maxlen, fmt, pNative->caller, local_params, &vargPos);
|
size_t total = atcprintf(dest, maxlen, fmt, g_pCaller, g_Params, &vargPos);
|
||||||
|
|
||||||
/* copy back */
|
/* copy back */
|
||||||
memcpy(realdest, dest, (total+1) * sizeof(cell));
|
memcpy(realdest, dest, (total+1) * sizeof(cell));
|
||||||
|
@ -399,20 +421,19 @@ static cell AMX_NATIVE_CALL vdformat(AMX *amx, cell *params)
|
||||||
//I've no idea how he thought of this, but it's great. No idea how well it works.
|
//I've no idea how he thought of this, but it's great. No idea how well it works.
|
||||||
static cell AMX_NATIVE_CALL param_convert(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL param_convert(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
if (!g_NativeStack.size())
|
if (!g_pCurNative || (g_pCaller != amx))
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
if (g_pCurNative->style != 1)
|
||||||
if (pNative->style != 1)
|
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cell p = params[1];
|
cell p = params[1];
|
||||||
|
|
||||||
AMX *caller = pNative->caller;
|
AMX *caller = g_pCaller;
|
||||||
|
|
||||||
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
||||||
unsigned char *realdata = caller->base+(int)((AMX_HEADER *)caller->base)->dat;
|
unsigned char *realdata = caller->base+(int)((AMX_HEADER *)caller->base)->dat;
|
||||||
|
@ -454,7 +475,6 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
|
||||||
regnative *pNative = new regnative;
|
regnative *pNative = new regnative;
|
||||||
pNative->amx = amx;
|
pNative->amx = amx;
|
||||||
pNative->func = idx;
|
pNative->func = idx;
|
||||||
pNative->caller = NULL;
|
|
||||||
|
|
||||||
//we'll apply a safety buffer too
|
//we'll apply a safety buffer too
|
||||||
//make our function
|
//make our function
|
||||||
|
|
|
@ -50,9 +50,7 @@ struct regnative
|
||||||
String name;
|
String name;
|
||||||
char *pfn;
|
char *pfn;
|
||||||
int func;
|
int func;
|
||||||
AMX *caller;
|
|
||||||
int style;
|
int style;
|
||||||
cell params[CALLFUNC_MAXPARAMS];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" void amxx_DynaInit(void *ptr);
|
extern "C" void amxx_DynaInit(void *ptr);
|
||||||
|
|
31
plugins/testsuite/native_test.sma
Normal file
31
plugins/testsuite/native_test.sma
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include <amxmodx>
|
||||||
|
|
||||||
|
native Factorial(num)
|
||||||
|
|
||||||
|
public __Factorial(id, num)
|
||||||
|
{
|
||||||
|
new num = get_param(1)
|
||||||
|
if (num == 0)
|
||||||
|
{
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return num * Factorial(num - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
public plugin_natives()
|
||||||
|
{
|
||||||
|
register_native("Factorial", "__Factorial")
|
||||||
|
}
|
||||||
|
|
||||||
|
public plugin_init()
|
||||||
|
{
|
||||||
|
register_plugin("Native Test", "1.0", "BAILOPAN")
|
||||||
|
register_srvcmd("test_native1", "Command_TestNative1")
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command_TestNative1()
|
||||||
|
{
|
||||||
|
new num = Factorial(6)
|
||||||
|
server_print("Factorial of 6 is: %d", num)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user