From 77e4d85002fc630e0da4752d6f0e2de0060d3623 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 10 Sep 2006 02:30:10 +0000 Subject: [PATCH] fixed up a callfunc issue and added copyback parameter --- amxmodx/amxmodx.cpp | 46 ++++++++++++++++++++++------- plugins/include/amxmodx.inc | 9 ++++-- plugins/testsuite/callfunc_test.sma | 6 +++- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index 5054dd0d..a545858e 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -3055,6 +3055,7 @@ struct CallFunc_ParamInfo cell byrefAddr; // byref address in caller plugin cell size; // byref size cell *alloc; // allocated block + bool copyback; // copy back? }; #if !defined CALLFUNC_MAXPARAMS @@ -3262,17 +3263,20 @@ static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params) if (gparamInfo[i].flags & CALLFUNC_FLAG_BYREF) { // copy back so that references work - AMX *amxCaller = curPlugin->getAMX(); AMX *amxCalled = plugin->getAMX(); - AMX_HEADER *hdrCaller = (AMX_HEADER *)amxCaller->base; - AMX_HEADER *hdrCalled = (AMX_HEADER *)amxCalled->base; - - memcpy( /** DEST ADDR **/ - (amxCaller->data ? amxCaller->data : (amxCaller->base + hdrCaller->dat)) + gparamInfo[i].byrefAddr, - /** SOURCE ADDR **/ - (amxCalled->data ? amxCalled->data : (amxCalled->base + hdrCalled->dat)) + gparams[i], - /** SIZE **/ - gparamInfo[i].size * sizeof(cell)); + + if (gparamInfo[i].copyback) + { + AMX *amxCaller = curPlugin->getAMX(); + AMX_HEADER *hdrCaller = (AMX_HEADER *)amxCaller->base; + AMX_HEADER *hdrCalled = (AMX_HEADER *)amxCalled->base; + memcpy( /** DEST ADDR **/ + (amxCaller->data ? amxCaller->data : (amxCaller->base + hdrCaller->dat)) + gparamInfo[i].byrefAddr, + /** SOURCE ADDR **/ + (amxCalled->data ? amxCalled->data : (amxCalled->base + hdrCalled->dat)) + gparams[i], + /** SIZE **/ + gparamInfo[i].size * sizeof(cell)); + } // free memory used for params passed by reference amx_Release(amxCalled, gparams[i]); @@ -3334,6 +3338,7 @@ static cell AMX_NATIVE_CALL callfunc_push_byref(AMX *amx, cell *params) g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1]; g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = 1; g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = NULL; + g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = true; g_CallFunc_Params[g_CallFunc_CurParam++] = i; /* referenced parameter */ return 0; } @@ -3351,12 +3356,13 @@ static cell AMX_NATIVE_CALL callfunc_push_byref(AMX *amx, cell *params) g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1]; g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = 1; g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = phys_addr; + g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = true; g_CallFunc_Params[g_CallFunc_CurParam++] = 0; return 0; } -// native callfunc_push_array(array[], size) +// native callfunc_push_array(array[], size, [copyback]) static cell AMX_NATIVE_CALL callfunc_push_array(AMX *amx, cell *params) { if (!g_CallFunc_Plugin) @@ -3382,6 +3388,7 @@ static cell AMX_NATIVE_CALL callfunc_push_array(AMX *amx, cell *params) g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1]; g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = 1; g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = NULL; + g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = g_CallFunc_ParamInfo[i].copyback; g_CallFunc_Params[g_CallFunc_CurParam++] = i; /* referenced parameter */ return 0; } @@ -3402,6 +3409,14 @@ static cell AMX_NATIVE_CALL callfunc_push_array(AMX *amx, cell *params) g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1]; g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = array_size; g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = phys_addr; + + if (params[0] / sizeof(cell) >= 3) + { + g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = params[3] ? true : false; + } else { + g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = true; + } + g_CallFunc_Params[g_CallFunc_CurParam++] = 0; return 0; @@ -3433,6 +3448,7 @@ static cell AMX_NATIVE_CALL callfunc_push_str(AMX *amx, cell *params) g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1]; g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = 1; g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = NULL; + g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = g_CallFunc_ParamInfo[i].copyback; g_CallFunc_Params[g_CallFunc_CurParam++] = i; // we are done return 0; @@ -3457,6 +3473,14 @@ static cell AMX_NATIVE_CALL callfunc_push_str(AMX *amx, cell *params) g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1]; g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = len + 1; g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = phys_addr; + + if (params[0] / sizeof(cell) >= 3) + { + g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = params[3] ? true : false; + } else { + g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = true; + } + g_CallFunc_Params[g_CallFunc_CurParam++] = 0; return 0; diff --git a/plugins/include/amxmodx.inc b/plugins/include/amxmodx.inc index 3e16c367..f5cf252e 100755 --- a/plugins/include/amxmodx.inc +++ b/plugins/include/amxmodx.inc @@ -649,11 +649,16 @@ native get_func_id(const funcName[], pluginId = -1); * can be modified by the called function. */ native callfunc_push_int(value); -native callfunc_push_str(VALUE[]); native callfunc_push_float(Float: value); native callfunc_push_intrf(&value); native callfunc_push_floatrf(& Float: value); -native callfunc_push_array(VALUE[], array_size); + +/* If copyback is 1 (default), any changes are copied back. + * Note that this will defy the 'const' specifier for push_str(), + * which is only kept for special backwards compatibility. + */ +native callfunc_push_str(const VALUE[], bool:copyback=true); +native callfunc_push_array(VALUE[], array_size, bool:copyback=true); /* Make the actual call. * Return value of the function called. */ diff --git a/plugins/testsuite/callfunc_test.sma b/plugins/testsuite/callfunc_test.sma index ef7d53eb..f19ecd3e 100644 --- a/plugins/testsuite/callfunc_test.sma +++ b/plugins/testsuite/callfunc_test.sma @@ -7,7 +7,7 @@ public plugin_init() register_srvcmd("test_callfunc", "Command_Callfunc") } -public OnCallfuncReceived(num, str[], &val, array[], array2[], size) +public OnCallfuncReceived(num, str[], &val, array[], array2[], size, hello2[1]) { server_print("num = %d (expected: %d)", num, 5) server_print("str[] = ^"%s^" (expected: %s)", str, "Gaben") @@ -25,12 +25,14 @@ public OnCallfuncReceived(num, str[], &val, array[], array2[], size) } array[0] = 5 array2[1] = 6 + hello2[0] = 25 } public Command_Callfunc() { new a = 62 new hello[] = {0,1,2,3,4,5} + new hello2[] = {9} new pm = 6 new err @@ -46,11 +48,13 @@ public Command_Callfunc() callfunc_push_array(hello, pm) callfunc_push_array(hello, pm) callfunc_push_int(pm) + callfunc_push_array(hello2, 1, false) callfunc_end() server_print("a = %d (expected: %d)", a, 15) server_print("hello[0] = %d (expected: %d)", hello[0], 5) server_print("hello[1] = %d (expected: %d)", hello[1], 6) + server_print("hello2[0] = %d (expected: %d)", hello2[0], 9) return PLUGIN_HANDLED }