get c_function* from lua_State*
发布日期:2021-06-30 22:10:26 浏览次数:2 分类:技术文章

本文共 3134 字,大约阅读时间需要 10 分钟。

前言

lua_State中有C程序注册到lua的接口函数指针

不同版本的lua可能不同吧,见到5.1.5和5.3.3不同.
将lua5.3.3的宏拆掉,看到了从lua_State*得到c_fuction*的过程

试验

对于一个L, 从头到尾是不变的.

当执行C接口函数时, 看到栈回溯上经过了luaV_execute, 在这里计算了L中f的值.
f的值在内存中,就是用户接口的地址.
luaV_execute只执行了1,2次, 其中有一个函数是C接口函数.
参照试验记录,在那一片内存的起始地址开始,往下找,很快能看到用户接口函数的信息.
明天再继续试验.

void luaV_execute(lua_State* L){    int iDebug = 0;    int bp = 0;    CallInfo* ci = L->ci;    LClosure* cl;    TValue* k;    StkId base = NULL;    StkId baseFirst = NULL;    ci->callstatus |= CIST_FRESH;  /* fresh invocation of 'luaV_execute" */newframe:  /* reentry point when frame changes (call/return) */    lua_assert(ci == L->ci);    cl = clLvalue(ci->func);  /* local reference to function's closure */    k = cl->p->k;  /* local reference to function's constant table */    base = ci->u.l.base;  /* local copy of function's base */    baseFirst = base;    /* main loop of interpreter */    for (;;) {        Instruction i;        Instruction iTmp;        StkId ra = NULL;        if (++iDebug == 9) {            bp = bp;        }        if (baseFirst != base) {            bp = bp;        }        // @todo modify by ls        // vmfetch(); // original        /* fetch an instruction and prepare its execution */        if (1)   {            i = *(ci->u.l.savedpc++);            if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) {                Protect(luaG_traceexec(L));            }            // #define getarg(i,pos,size)  (cast(int, ((i)>>pos) & MASK1(size,0)))            // #define SIZE_A 8            // #define POS_A       (POS_OP + SIZE_OP)            // #define SIZE_OP     6            // #define POS_OP      0            // ra = base + getarg(i, POS_A, SIZE_A);            // ra = base + getarg(i, 6, 8);            iTmp = (i >> 6);            ra = base + ((i >> 6) & 0xff); // 这里得到了ra怎么算得,下面的函数继续用ra算f            lua_assert(base == ci->u.l.base);            lua_assert(base <= L->top && L->top < L->stack + L->stacksize);        }
vmcase(OP_CALL) {                int b = GETARG_B(i);                int nresults = GETARG_C(i) - 1;                if (b != 0) {                    L->top = ra + b;    /* else previous instruction set top */                }                // 这里调用C接口函数, 将ra传进去,继续算f                if (luaD_precall(L, ra, nresults)) {  /* C function? */                     if (nresults >= 0) {                        L->top = ci->top;    /* adjust results */                    }                    Protect((void)0);  /* update 'base' */                } else { /* Lua function */                    ci = L->ci;                    goto newframe;  /* restart luaV_execute over new Lua function */                }                vmbreak;
int luaD_precall(lua_State* L, StkId func, int nresults){    int bp = 0;    lua_CFunction f = NULL;    CallInfo* ci;    switch (ttype(func)) {        case LUA_TCCL:  /* C closure */            f = clCvalue(func)->f;            goto Cfunc;        case LUA_TLCF:  /* light C function */            // @todo modify by ls            // f = fvalue(func); // original            ttislcf(func); // 这里判断了func是否为C函数, 不是抛异常            f = func->value_.f; // 这里得到C函数指针f            bp = bp;

转载地址:https://lostspeed.blog.csdn.net/article/details/52567732 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:CryptCreateHash + CALG_MD5
下一篇:hello lua

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月10日 07时55分00秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章