zoukankan      html  css  js  c++  java
  • lua堆栈操作常用函数学习二

    1. /* 
    2. ** basic stack manipulation 
    3. */  
    4. LUA_API int  <strong> (lua_gettop) (lua_State *L);  </strong><pre class="cpp" name="code"></pre><pre class="cpp" name="code">//返回当前堆栈的大小  
    5. LUA_API int lua_gettop (lua_State *L) {  
    6.   return cast_int(L->top - L->base);  
    7. }  
    8.   
    9. int   lua_gettop(lua_State *L)  
    10. 取得栈的高度  
    11. for (int i = 0; i < 10; ++i)  
    12.       lua_pushnumber(L, i);  
    13. printf("%d", lua_gettop(L));  
    14. --> 10  
    15.   
    16.   
    17. LUA_API void  (lua_settop) (lua_State *L, int idx);  
    18. <pre class="cpp" name="code">//settop()是破坏性的 变小后数据就不恢复了  
    19. LUA_API void lua_settop (lua_State *L, int idx) {  
    20.   lua_lock(L);  
    21.   if (idx >= 0) {     //正数索引  是向外的有可能大于当前大小  但负数则不会过大越界  所以不会有填nil的机会  
    22.     api_check(L, idx <= L->stack_last - L->base);  
    23.     while (L->top < L->base + idx)//如果设置的大于当前堆栈大小 则填nil  
    24.       setnilvalue(L->top++);  
    25.     L->top = L->base + idx;  
    26.   }  
    27.   else {  
    28.     api_check(L, -(idx+1) <= (L->top - L->base));  
    29.     L->top += idx+1;  /* `subtract' index (index is negative) */  
    30.   }  
    31.   lua_unlock(L);  
    32. }  
    33. void  lua_settop(lua_State *L, int idx)  
    34. <strong>设置栈的高度,如果之前的栈顶比新设置的更高,那么高出来的元素会被丢弃,反之压入nil来补足大小。</strong>  
    35. 另外,Lua提供了一个宏,用来从栈中弹出n个元素:#define lua_pop(L, n) lua_settop(L, -(n)-1)  
    36. for (int i = 0; i < 10; ++i)  
    37.       lua_pushnumber(L, i);  
    38. lua_settop(L, 5)  
    39. printf("%d", lua_gettop(L));  
    40. --> 5  
    41.   
    42.   
    43. LUA_API void  (lua_pushvalue) (lua_State *L, int idx);<pre class="cpp" name="code"> </pre><pre class="cpp" name="code">LUA_API void lua_pushvalue (lua_State *L, int idx) {  
    44.   lua_lock(L);  
    45.   setobj2s(L, L->top, index2adr(L, idx));    <strong>//拷贝指定索引的值压入栈顶 栈顶位置更新</strong>  
    46.   api_incr_top(L);  
    47.   lua_unlock(L);  
    48. }  
    49.   
    50. void  lua_pushvalue(lua_State *L, int idx)  
    51. 将指定索引上值的副本压入栈  
    52. for (int i = 1; i <= 3; ++i)  
    53.       lua_pushnumber(i);  
    54. 栈中元素:(从下往上) 1 2 3  
    55. lua_pushvalue(L, 2)  
    56. 栈中元素:(从下往上) 1 2 3 2</pre><pre class="cpp" name="code"> </pre><br>  
    57. LUA_API void (lua_remove) (lua_State *L, int idx);<pre class="cpp" name="code"> </pre><pre class="cpp" name="code">LUA_API void lua_remove (lua_State *L, int idx) {  
    58.   StkId p;  
    59.   lua_lock(L);  
    60.   p = index2adr(L, idx);//取得指定索引  
    61.   api_checkvalidindex(L, p);  
    62.   while (++p < L->top)   
    63.       setobjs2s(L, p-1, p);//将索引后的数据一一迁移  
    64.   L->top--;                    
    65.   lua_unlock(L);  
    66. }  
    67.   
    68. void  lua_remove(lua_State *L, int idx)  
    69. 删除指定索引上的元素,并将该位置之上的所有元素上移以补空缺  
    70. for (int i = 1; i <= 3; ++i)  
    71.       lua_pushnumber(i);  
    72. 栈中元素:(从下往上) 1 2 3  
    73. lua_remove(L, 2)  
    74. 栈中元素:(从下往上) 1 3  
    75. </pre><br>  
    76. LUA_API void (lua_insert) (lua_State *L, int idx);<pre class="cpp" name="code"> </pre><pre class="cpp" name="code">LUA_API void lua_insert (lua_State *L, int idx) {  
    77.   StkId p;  
    78.   StkId q;  
    79.   lua_lock(L);  
    80.   p = index2adr(L, idx);//找到指定索引值处  
    81.   api_checkvalidindex(L, p);  
    82.   for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);//将后面的数据依次后移  
    83.   setobjs2s(L, p, L->top);  
    84.   lua_unlock(L);  
    85. }  
    86. void  lua_insert(lua_State *L, int idx)  
    87. 移指定位置上的所有元素以开辟一个空间槽的空间,然后将栈顶元素移到该位置  
    88. for (int i = 1; i <= 5; ++i)  
    89.       lua_pushnumber(i);  
    90. 栈中元素:(从下往上) 1 2 3 4 5  
    91. lua_insert(L, 3)  
    92. 栈中元素:(从下往上) 1 2 5 4 3  
    93.   
    94. </pre><br>  
    95. LUA_API void (lua_replace) (lua_State *L, int idx);  
    96. <pre></pre>  
    97. <pre class="cpp" name="code"> </pre><pre class="cpp" name="code"><pre class="cpp" name="code">LUA_API void lua_replace (lua_State *L, int idx) {  
    98.   StkId o;  
    99.   lua_lock(L);  
    100.   api_checknelems(L, 1);//检查是否有元素  
    101.   o = index2adr(L, idx);  
    102.   api_checkvalidindex(L, o);  
    103.   if (idx == LUA_ENVIRONINDEX) {  
    104.     Closure *func = curr_func(L);  
    105.     api_check(L, ttistable(L->top - 1));   
    106.     func->c.env = hvalue(L->top - 1);  
    107.     luaC_barrier(L, func, L->top - 1);  
    108.   }  
    109.   else {  
    110.     setobj(L, o, L->top - 1);//将栈顶元素 拷贝到指定所以处  
    111.     if (idx < LUA_GLOBALSINDEX)  /* function upvalue? */  
    112.       luaC_barrier(L, curr_func(L), L->top - 1);  
    113.   }  
    114.   L->top--;//栈顶减少  
    115.   lua_unlock(L);  
    116. }</pre>void  lua_replace(lua_State *L, int idx)<br>  
    117. <strong>弹出栈顶的值,并将该值设置到指定索引上,但它不会移动任何东西<br>  
    118. </strong>for (int i = 1; i <= 5; ++i)<br>  
    119.       lua_pushnumber(i);<br>  
    120. 栈中元素:(从下往上) 1 2 3 4 5<br>  
    121. lua_replace(L, 3)<br>  
    122. 栈中元素:(从下往上) 1 2 5 4<br>  
    123. <br>  
    124. <pre></pre>  
    125. <pre class="cpp" name="code"> </pre><pre class="cpp" name="code">LUA_API int (lua_checkstack) (lua_State *L, int sz);</pre><pre class="cpp" name="code"> </pre><pre class="cpp" name="code">LUA_API int lua_checkstack (lua_State *L, int size) {  
    126.   int res;  
    127.   lua_lock(L);  
    128.   if ((L->top - L->base + size) > LUAI_MAXCSTACK)  
    129.     res = 0;  /* stack overflow */  
    130.   else {  
    131.     luaD_checkstack(L, size);  
    132.     if (L->ci->top < L->top + size)  
    133.       L->ci->top = L->top + size;  
    134.     res = 1;  
    135.   }  
    136.   lua_unlock(L);  
    137.   return res;  
    138. }  
    139. </pre><pre class="cpp" name="code">int   lua_checkstack(lua_State *L, int sz)  
    140. 扩大栈的可用尺寸,栈的默认尺寸是20,此函数会确保堆栈上至少有 sz 个空位。如果不能把堆栈扩展到相应的尺寸,函数返回 false 。这个函数永远不会缩小堆栈;如果堆栈已经比需要的大了,那么就放在那里不会产生变化。  
    141. lua_checkstack(L, 100)  
    142.   
    143. </pre><pre class="cpp" name="code"> </pre><pre class="cpp" name="code">LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);<pre class="cpp" name="code">//将一个堆栈上的从栈顶起的n个元素  移到另一个堆栈上  
    144. LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {  
    145.   int i;  
    146.   if (from == to) return;  
    147.   lua_lock(to);  
    148.   api_checknelems(from, n);//确认 从from有n个元素  
    149.   api_check(from, G(from) == G(to));  
    150.   api_check(from, to->ci->top - to->top >= n);//确认to有n个元素  
    151.   from->top -= n;  
    152.   for (i = 0; i < n; i++) {  
    153.     setobj2s(to, to->top++, from->top + i);  
    154.   }  
    155.   lua_unlock(to);  
    156. }</pre><br>  
    157. <pre></pre>  
    158. <pre class="cpp" name="code"> </pre><pre class="cpp" name="code">/*** access functions (stack -> C)*/</pre><pre class="cpp" name="code">//类型判断函数</pre><pre class="cpp" name="code">LUA_API int (lua_isnumber) (lua_State *L, int idx);</pre><pre class="cpp" name="code"> </pre><pre class="cpp" name="code">LUA_API int (lua_isstring) (lua_State *L, int idx);</pre><pre class="cpp" name="code"> </pre><pre class="cpp" name="code">LUA_API int (lua_iscfunction) (lua_State *L, int idx);</pre><pre class="cpp" name="code"> </pre><pre class="cpp" name="code">LUA_API int (lua_isuserdata) (lua_State *L, int idx);</pre><pre class="cpp" name="code"> </pre><pre class="cpp" name="code">LUA_API int (lua_type) (lua_State *L, int idx);</pre><pre class="cpp" name="code">int   lua_type(lua_State *L, int idx)  
    159. 得到一个元素的类型,返回整型,返回值是如下列表之一:<p>int lua_isnil(lua_State *L, int idx);  
    160. int lua_isboolean(lua_State *L, int idx);  
    161. int lua_istable(lua_State *L, int idx);  
    162. int lua_isfunction(lua_State *L, int idx);  
    163. int lua_islightuserdata (lua_State *L, int idx);</p><p>#define LUA_TNONE  (-1)</p><p>#define LUA_TNIL  0  
    164. #define LUA_TBOOLEAN  1  
    165. #define LUA_TLIGHTUSERDATA 2  
    166. #define LUA_TNUMBER  3  
    167. #define LUA_TSTRING  4  
    168. #define LUA_TTABLE  5  
    169. #define LUA_TFUNCTION  6  
    170. #define LUA_TUSERDATA  7  
    171. #define LUA_TTHREAD  8</p><p>lua_pushnumber(L, 55);  
    172. lua_type(L, 1)-->LUA_TNUMBER  
    173. ---------------------------------------------------------------------------------------  
    174. const char* lua_typename(lua_State *L, int tp)  
    175. 将一个类型编码转换成类型名  
    176. lua_typename(L, 1)-->boolean  
    177. lua_typename(L, 3)-->number  
    178. ---------------------------------------------------------------------------------------</p><p>  
    179. int   lua_equal(lua_State *L, int idx1, int idx2)  
    180. 如果依照 Lua 中 == 操作符语义,索引 index1 和 index2 中的值相同的话,返回 1 。否则返回 0 。如果任何一个索引无效也会返回 0。   
    181. lua_pushstring(L, "this");  
    182. lua_pushboolean(L, 1);  
    183. lua_pushboolean(L, 1);  
    184. lua_equal(L, -2, -3)  
    185. -->0  
    186. lua_equal(L, -1, -2)  
    187. -->1  
    188. lua_equal(L, -1, -10)  
    189. -->0  
    190. </p></pre><pre class="cpp" name="code"> int   lua_rawequal(lua_State *L, int idx1, int idx2)  
    191. int   lua_lessthan(lua_State *L, int idx1, int idx2)<p> </p><p>---------------------------------------------------------------------------------------  
    192. lua_Number lua_tonumber(lua_State *L, int idx)  
    193. lua_Integer lua_tointeger(lua_State *L, int idx)  
    194. int   lua_toboolean(lua_State *L, int idx)  
    195. const char* lua_tolstring(lua_State *L, int idx, size_t *len)  
    196. 以上四个函数都有一个原型lua_to*(lua_State *L, int idx),用于从栈中取一个值。如果指定的元素不具有正确的类型,调用这些函数也不会有问题,  
    197. 在这种情况下,调用lua_toboolean,lua_tonumber,lua_tointeger会返回0,其它函数会返回NULL。通常不使用lua_is*函数,只需在调用它们之  
    198. 后测试返回结果是否为NULL就可以了。  
    199. lua_pushnumber(L, 100)  
    200. lua_tonumber(L, 1)-->100  
    201. lua_pushinteger(L, 200)  
    202. lua_tointeger(L, -1)-->200  
    203. lua_pushboolean(L, 0)  
    204. lua_toboolean(L, -1)-->false  
    205. lua_pushstring(L, "hello,lua")  
    206. lua_tolstring(L, -1, &len)-->hello,lua   
    207. 注:len是传出参数,表示字符串的长度,如果想忽略此参数,传入NULL  
    208. ---------------------------------------------------------------------------------------  
    209. size_t  lua_objlen(lua_State *L, int idx)  
    210. 返回值的长度,如果类型不正确,返回0  
    211. lua_pushstring(L, "hello,lua")  
    212. lua_objlen(L, 1)-->9  
    213. ---------------------------------------------------------------------------------------  
    214. lua_CFunction lua_tocfunction(lua_State *L, int idx)  
    215. void*  lua_touserdata(lua_State *L, int idx)  
    216. lua_State* lua_tothread(lua_State *L, int idx)  
    217. const void* lua_topointer(lua_State *L, int idx)</p><p> </p><p>//push functions (C -> stack)  
    218. void  lua_pushnil(lua_State *L)  
    219. void  lua_pushnumber(lua_State *L, lua_Number n)  
    220. void  lua_pushinteger(lua_State *L, lua_Integer n)  
    221. void  lua_pushlstring(lua_State *L, const char* s, size_t l)  
    222. void  lua_pushstring(lua_State *L, const char *s)  
    223. const char* lua_pushvfstring(lua_State *L, const char *fmt, va_list argp)  
    224. const char* lua_pushfstring(lua_State *L, const char *fmt, ...)  
    225. void  lua_pushcclosure(lua_State *L, lua_CFunction fn, int n)  
    226. void  lua_pushboolean(lua_State *L, void *b)  
    227. void  lua_pushlightuserdata(lua_State *L, void *p)  
    228. int   lua_pushthread(lua_State *L)</p><p>  
    229. void  lua_gettable(lua_State *L, int idx)  
    230. ---------------------------------------------------------------------------------------  
    231. void  lua_getfield(lua_State *L, int idx, const char *k)  
    232. 把 t[k] 值压入堆栈,这里的 t 是指有效索引 index 指向的值。在 Lua 中,这个函数可能触发对应 "index" 事件的元方法  
    233. ---------------------------------------------------------------------------------------  
    234. void  lua_rawget(lua_State *L, int idx)  
    235. void  lua_rawgeti(lua_State *L, int idx, int n)  
    236. ---------------------------------------------------------------------------------------  
    237. void  lua_createtable(lua_State *L, int narr, int nrec)  
    238. 创建一个新的空 table 压入堆栈。这个新 table 将被预分配 narr 个元素的数组空间以及 nrec 个元素的非数组空间。当你明确知道表中需要多少个元素时,预分配就非常有用。如果你不知道,可以使用函数 lua_newtable。   
    239. 举例暂缺  
    240. ---------------------------------------------------------------------------------------  
    241. void*  lua_newuserdata(lua_State *L, size_t sz)  
    242. int   lua_getmetatable(lua_State *L, int objindex)  
    243. ---------------------------------------------------------------------------------------  
    244. void  lua_getfenv(lua_State *L, int idx)</p><p>  
    245. 把索引处值的环境表压入堆栈  
    246. ---------------------------------------------------------------------------------------  
    247. void  lua_settable(lua_State *L, int idx);  
    248. void  lua_setfield(lua_State *L, int idx, const char *k)  
    249. void  lua_rawset(lua_State *L, int idx)  
    250. void  lua_rawseti(lua_State *L, int idx, int n)  
    251. int   lua_setmetatable(lua_State *L, int objindex)  
    252. int   lua_setfenv(lua_State *L, int idx)</p><p>  
    253. //'load' and 'call' functions (load and run lua code)  
    254. void  lua_call(lua_State *L, int nargs, int nresults);  
    255. int   lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)  
    256. ---------------------------------------------------------------------------------------  
    257. int   lua_cpcall(lua_State *L, lua_CFunction func, void *ud)  
    258. 以保护模式调用 C 函数 func 。 func 只有能从堆栈上拿到一个参数,就是包含有 ud 的 light userdata。当有错误时, lua_cpcall 返回和 lua_pcall 相同的错误代码,并在栈顶留下错误对象;否则它返回零,并不会修改堆栈。所有从 func 内返回的值都会被扔掉。  
    259. 举例暂缺  
    260. ---------------------------------------------------------------------------------------  
    261. int   lua_load(lua_State *L, lua_Reader reader, void *dt, const char *chunkname);  
    262. ---------------------------------------------------------------------------------------  
    263. int   lua_dump(lua_State *L, lua_Writer writer, void *data);  
    264. 把函数 dump 成二进制 chunk 。函数接收栈顶的 Lua 函数做参数,然后生成它的二进制 chunk 。若被 dump 出来的东西被再次加载,加载的结果就相当于原来的函数。当它在产生 chunk 的时候,lua_dump 通过调用函数 writer (参见 lua_Writer)来写入数据,后面的 data 参数会被传入 writer 。   
    265. 最后一次由写入器 (writer) 返回值将作为这个函数的返回值返回; 0 表示没有错误。   
    266. 这个函数不会把 Lua 返回弹出堆栈。   
    267. 举例暂缺  
    268. ---------------------------------------------------------------------------------------  
    269. int   lua_yield(lua_State *L, int nresults)  
    270. int   lua_resume(lua_State *L, int narg)  
    271. int   lua_status(lua_State *L)</p><p>---------------------------------------------------------------------------------------  
    272. int   lua_gc(lua_State *L, int what, int data)</p><p>控制垃圾收集器。 这个函数根据其参数 what 发起几种不同的任务:   
    273.  * LUA_GCSTOP: 停止垃圾收集器。   
    274.  * LUA_GCRESTART: 重启垃圾收集器。   
    275.  * LUA_GCCOLLECT: 发起一次完整的垃圾收集循环。   
    276.  * LUA_GCCOUNT: 返回 Lua 使用的内存总量(以 K 字节为单位)。   
    277.  * LUA_GCCOUNTB: 返回当前内存使用量除以 1024 的余数。   
    278.  * LUA_GCSTEP: 发起一步增量垃圾收集。步数由 data 控制(越大的值意味着越多步),而其具体含义(具体数字表示了多少)并未标准化。如果你想控制这个步数,必须实验性的测试 data 的值。如果这一步结束了一个垃圾收集周期,返回返回 1 。   
    279.  * LUA_GCSETPAUSE: 把 data/100 设置为 garbage-collector pause 的新值。函数返回以前的值。   
    280.  * LUA_GCSETSTEPMUL: 把 arg/100 设置成 step multiplier 。函数返回以前的值。  
    281. ---------------------------------------------------------------------------------------  
    282. int   lua_error(lua_State *L)  
    283. 产生一个 Lua 错误。错误信息(实际上可以是任何类型的 Lua 值)必须被置入栈顶。这个函数会做一次长跳转,因此它不会再返回。(参见 luaL_error)。  
    284. lua_pushstring(L, "one error");  
    285. lua_error(L);  
    286. printf("%s", "本行已经执行不到了");  
    287. ---------------------------------------------------------------------------------------  
    288. int   lua_next(lua_State *L, int idx)  
    289. ---------------------------------------------------------------------------------------  
    290. void  lua_concat(lua_State *L, int n)  
    291. 连接栈顶的 n 个值,然后将这些值出栈,并把结果放在栈顶。如果 n 为 1 ,结果就是一个字符串放在栈上(即,函数什么都不做);如果 n 为 0 ,结果是一个空串。 连接依照 Lua 中创建语义完成,如果尝试把两个不能连接的类型连接,程序会给出错误提示。  
    292.  lua_pushstring(L, "this");  
    293.  lua_pushboolean(L, 1);  
    294.  lua_pushnumber(L, 9989);  
    295.  lua_pushnumber(L, 1111);  
    296.  lua_pushboolean(L, 0);  
    297.  lua_pushstring(L, "满天都是小星星");  
    298.  lua_pushnumber(L, 1986);  
    299.  lua_pushstring(L, "onebyone");  
    300. -->'this' 'true' '9989' '1111' 'false' '满天都是小星星' '1986' 'onebyone'  
    301. lua_concat(L, 3);  
    302. -->'this' 'true' '9989' '1111' 'false' '满天都是小星星1986onebyone'  
    303. ---------------------------------------------------------------------------------------  
    304. lua_Alloc lua_getallocf(lua_State *L, void **ud)  
    305. 返回给定状态机的内存分配器函数。如果 ud 不是 NULL ,Lua 把调用 lua_newstate 时传入的那个指针放入 *ud 。   
    306. ---------------------------------------------------------------------------------------  
    307. void  lua_setallocf(lua_State *L, lua_Alloc f, void *ud)</p><p>  
    308. //Functions to be called by the debuger in specific events  
    309. int   lua_getstack(lua_State *L, int level, lua_Debug *ar)  
    310. int   lua_getinfo(lua_State *L, const char *what, lua_Debug *ar)  
    311. const char* lua_getlocal(lua_State *L, const lua_Debug *ar, int n)  
    312. const char* lua_setlocal(lua_State *L, const lua_Debug *ar, int n)  
    313. const char* lua_getupvalue(lua_State *L, int funcindex, int n)  
    314. const char* lua_setupvalue(lua_State *L, int funcindex, int n)  
    315. int   lua_sethook(lua_State *L, lua_Hook func, int mask, int count);  
    316. lua_Hook lua_gethook(lua_State *L)  
    317. int   lua_gethookmask(lua_State *L)  
    318. int   lua_gethookcount(lua_State *L)</p></pre>  
    319. <pre></pre>  
    320. <pre></pre>  
    321. <pre></pre>  
    322. <pre></pre>  
    323. <pre></pre>  
    324. <pre></pre>  
    325. <pre></pre>  
    326. <pre></pre>  
    327. <pre></pre>  
    328. <pre></pre>  
    329. <pre></pre>  
    330. <pre></pre>  
    331. </pre></pre></pre></pre>  

    来源: http://blog.csdn.net/xuzhonghai/article/details/8490547

  • 相关阅读:
    delphi 随意将函数执行权限提高到Ring0源代码
    delphi 使电脑睡眠代码
    delphi 监控文件系统
    在Delphi中使用系统对应文件类型的图标
    Panel
    delphi 读写记录类型文件Record
    C# winform 一次只能允许一个应用(使用mutex)
    winform捕获全局异常
    观察者模式实践-实现winform 窗体之间传值(事件实现)
    在wpf中利用异步lambda编程,模拟数据库连接,防止界面假死
  • 原文地址:https://www.cnblogs.com/tibetanmastiff/p/4457303.html
Copyright © 2011-2022 走看看