/************************************************************************* > File Name: lua_plugin_chunk.c > Author: > Created Time: 2024-08 > Encoding : UTF-8 ************************************************************************/ /************************************************************************* * 实现代码块相关操作 * version * [ v0.1 ] * 08-12 * 1. 实现函数 * int lua_chunk_execute; ************************************************************************/ #include "lua_plugin_manage_internal.h" /* * Function: lua_chunk_execute * Input: | lua_State * | state | 执行该代码块使用的状态机 * | int | ref_id | 代码块在状态机中的引用ID * | int | pcount | 执行过程中传入的参数个数 * | struct lua_cdata * | params | 执行过程中传入的参数 * | int | rcount | 执行结束后返回值的个数 * | struct lua_cdata * | returns | 执行结束后返回值 * Output: * Return: enum LUA_PLUGIN_RETURN * Description: 在lua状态机中执行一段代码块, 执行的代码块需要提前在状态机中完成注册 * 并已经生成相关的引用ID, 根据该ID进行调用 */ int lua_chunk_execute( lua_State *state, int ref_id, int pcount, struct lua_cdata *params, int rcount, struct lua_cdata *returns) { if (__glibc_unlikely(!state || ref_id == LUA_REFNIL)) return PARAM_ERR; if ((pcount && !params) || (pcount < 0)) return PARAM_ERR; if ((rcount && !returns) || (rcount < 0)) return PARAM_ERR; #ifdef LUAPLUGIN_BASIC_UNITTEST LOGDEBUG("now execute chunk, %p, %d", state, ref_id); #endif /* 需要调用的函数入栈, 由于后续在读取参数个数的时候对栈操作较多, 需要先将函数入栈 */ lua_rawgeti(state, LUA_REGISTRYINDEX, ref_id); if (lua_gettop(state) == 0 || lua_type(state, -1) != LUA_TFUNCTION) { lua_settop(state, 0); return CHUNK_TYPE_NOT_FUNCTION; } /* 参数入栈 */ int pushret = 0; for (int i = 0; i < pcount; ++i) { if ((pushret = lua_cdata_push_stack(state, ¶ms[i]))) { lua_settop(state, 0); return pushret; } } /* 执行该脚本并记录执行时间 */ // clock_t start_time, end_time; // start_time = clock(); /* 调用该脚本 or 代码片段 */ if (lua_pcall(state, pcount, LUA_MULTRET, 0)) { // end_time = clock(); LOGERROR("run script failed, mess is %s\n", lua_tostring(state, -1)); /* 仅函数运行过程中出错记入出错记录, 由于参数错误等原因导致的错误不记录 */ lua_settop(state, 0); return CHUNK_RUN_CODE_FAIL; } // end_time = clock(); /* 返回值出栈 */ if (rcount > 0) { /* 如果rmaxcount为0, 说明在期望中不准备接收返回值, 也不必处理 */ int count = lua_gettop(state); if (count > rcount) { lua_settop(state, 0); return CHUNK_RCOUNT_ERR; } int pop_ret = 0; for (int i = (count - 1); i >= 0; --i) { if ((pop_ret = lua_cdata_pop_stack(state, &(returns[i])))) { lua_settop(state, 0); return pop_ret; } } } lua_settop(state, 0); /* TODO: 记录耗时等数据 */ return SUCCESS; }