lua - What's the difference behind normal function call and pcall -
i using lua , know pcall protected calling , question if both ways of calling come down same c code. e.g.
function a(arg) ... end normal calling:
a(arg) protected call:
pcall(a, arg) actually using 'lua_lock/lua_unlock' protect lua_state corrupting. , form source (lua 5.1.4) can see 'lua_pcall' calling 'lua_lock/lua_unlock', not sure if normal way of function call based on 'lua_pcall' or using 'lua_lock/lua_unlock'? if not, mean have change function calling 'pcall(...)' benefit 'lua_lock/lua_unlock'?
could explain? thank you
pcall used handle errors in lua. i've made following example demonstrate how use it:
first make function me know produce error
function makeerror(n) return 'n'+n; end now our first example define following
function pcallexample1() if pcall(makeerror,n) print("no error!") else print("that method broken, fix it!") end end we invoke pcallexample1
pcallexample1() and output:
lua 5.1.3 copyright (c) 1994-2008 lua.org, puc-rio method broken, fix it! to demonstrate opposite:
function pcallexample2() if makeerror(5) print("no error!") else print("that method broken, fix it!") end end invoking have error remain unhanded , bubble display:
lua: /users/henryhollinworth/desktop/s.lua:2: attempt perform arithmetic on string value in terms of c, pcall defined as
static int luab_pcall (lua_state *l) { int status; lual_checkany(l, 1); lua_pushnil(l); lua_insert(l, 1); /* create space status result */ status = lua_pcallk(l, lua_gettop(l) - 2, lua_multret, 0, 0, pcallcont); return finishpcall(l, (status == lua_ok)); } where lua_pcallk is
lua_api int lua_pcallk (lua_state *l, int nargs, int nresults, int errfunc, int ctx, lua_cfunction k) { struct calls c; int status; ptrdiff_t func; lua_lock(l); api_check(l, k == null || !islua(l->ci), "cannot use continuations inside hooks"); api_checknelems(l, nargs+1); api_check(l, l->status == lua_ok, "cannot calls on non-normal thread"); checkresults(l, nargs, nresults); if (errfunc == 0) func = 0; else { stkid o = index2addr(l, errfunc); api_checkvalidindex(l, o); func = savestack(l, o); } c.func = l->top - (nargs+1); /* function called */ if (k == null || l->nny > 0) { /* no continuation or no yieldable? */ c.nresults = nresults; /* 'conventional' protected call */ status = luad_pcall(l, f_call, &c, savestack(l, c.func), func); } else { /* prepare continuation (call protected 'resume') */ callinfo *ci = l->ci; ci->u.c.k = k; /* save continuation */ ci->u.c.ctx = ctx; /* save context */ /* save information error recovery */ ci->u.c.extra = savestack(l, c.func); ci->u.c.old_allowhook = l->allowhook; ci->u.c.old_errfunc = l->errfunc; l->errfunc = func; /* mark function may error recovery */ ci->callstatus |= cist_ypcall; luad_call(l, c.func, nresults, 1); /* call */ ci->callstatus &= ~cist_ypcall; l->errfunc = ci->u.c.old_errfunc; status = lua_ok; /* if here, there no errors */ } adjustresults(l, nresults); lua_unlock(l); return status; } in contrast lua_callk
lua_api void lua_callk (lua_state *l, int nargs, int nresults, int ctx, lua_cfunction k) { stkid func; lua_lock(l); api_check(l, k == null || !islua(l->ci), "cannot use continuations inside hooks"); api_checknelems(l, nargs+1); api_check(l, l->status == lua_ok, "cannot calls on non-normal thread"); checkresults(l, nargs, nresults); func = l->top - (nargs+1); if (k != null && l->nny == 0) { /* need prepare continuation? */ l->ci->u.c.k = k; /* save continuation */ l->ci->u.c.ctx = ctx; /* save context */ luad_call(l, func, nresults, 1); /* call */ } else /* no continuation or no yieldable */ luad_call(l, func, nresults, 0); /* call */ adjustresults(l, nresults); lua_unlock(l); } note both make use of lua_lock() , lua_unlock(). both lock , unlock lua_state.
Comments
Post a Comment