⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 manual.html

📁 Lua 语言解释器源码
💻 HTML
📖 第 1 页 / 共 5 页
字号:
(that is, those objects that are no longer accessible from Lua).All objects in Lua are subject to automatic management:tables, userdata, functions, threads, and strings.<p>Lua uses two numbers to control its garbage-collection cycles.One number counts how many bytes of dynamic memory Lua is using;the other is a threshold.When the number of bytes crosses the threshold,Lua runs the garbage collector,which reclaims the memory of all dead objects.The byte counter is adjusted,and then the threshold is reset to twice the new value of the byte counter.<p>Through the C&nbsp;API, you can query those numbersand change the threshold (see <a href="#GC-API">3.7</a>).Setting the threshold to zero actually forces an immediategarbage-collection cycle,while setting it to a huge number effectively stops the garbage collector.Using Lua code you have a more limited control over garbage-collection cycles,through the <code>gcinfo</code> and <code>collectgarbage</code> functions(see <a href="#predefined">5.1</a>).<p><a name="2.9.1"><h3>2.9.1 - Garbage-Collection Metamethods</h3></a><p>Using the C&nbsp;API,you can set garbage-collector metamethods for userdata (see <a href="#metatable">2.8</a>).These metamethods are also called <em>finalizers</em>.Finalizers allow you to coordinate Lua's garbage collectionwith external resource management(such as closing files, network or database connections,or freeing your own memory).<p>Free userdata with a field <code>__gc</code> in their metatables are notcollected immediately by the garbage collector.Instead, Lua puts them in a list.After the collection,Lua does the equivalent of the following functionfor each userdata in that list:<PRE> function gc_event (udata)   local h = metatable(udata).__gc   if h then     h(udata)   end end</PRE><p>At the end of each garbage-collection cycle,the finalizers for userdata are called in <em>reverse</em>order of their creation,among those collected in that cycle.That is, the first finalizer to be called is the one associatedwith the userdata created last in the program.<p><a name="weak-table"><a name="2.9.2"><h3>2.9.2 - Weak Tables</h3></a></a><p>A <em>weak table</em> is a table whose elements are<em>weak references</em>.A weak reference is ignored by the garbage collector.In other words,if the only references to an object are weak references,then the garbage collector will collect that object.<p>A weak table can have weak keys, weak values, or both.A table with weak keys allows the collection of its keys,but prevents the collection of its values.A table with both weak keys and weak values allows the collection ofboth keys and values.In any case, if either the key or the value is collected,the whole pair is removed from the table.The weakness of a table is controlled by the value of the<code>__mode</code> field of its metatable.If the <code>__mode</code> field is a string containing the character&nbsp;`<code>k</code>&acute;,the keys in the table are weak.If <code>__mode</code> contains `<code>v</code>&acute;,the values in the table are weak.<p>After you use a table as a metatable,you should not change the value of its field <code>__mode</code>.Otherwise, the weak behavior of the tables controlled by thismetatable is undefined.<p><a name="coroutine"><a name="2.10"><h2>2.10 - Coroutines</h2></a></a><p>Lua supports coroutines,also called <em>semi-coroutines</em>or <em>collaborative multithreading</em>.A coroutine in Lua represents an independent thread of execution.Unlike threads in multithread systems, however,a coroutine only suspends its execution by explicitly callinga yield function.<p>You create a coroutine with a call to <code>coroutine.create</code>.Its sole argument is a functionthat is the main function of the coroutine.The <code>create</code> function only creates a new coroutine andreturns a handle to it (an object of type <em>thread</em>);it does not start the coroutine execution.<p>When you first call <code>coroutine.resume</code>,passing as its first argument the thread returned by <code>coroutine.create</code>,the coroutine starts its execution,at the first line of its main function.Extra arguments passed to <code>coroutine.resume</code> are given asparameters for the coroutine main function.After the coroutine starts running,it runs until it terminates or <em>yields</em>.<p>A coroutine can terminate its execution in two ways:Normally, when its main function returns(explicitly or implicitly, after the last instruction);and abnormally, if there is an unprotected error.In the first case, <code>coroutine.resume</code> returns <B>true</B>,plus any values returned by the coroutine main function.In case of errors, <code>coroutine.resume</code> returns <B>false</B>plus an error message.<p>A coroutine yields by calling <code>coroutine.yield</code>.When a coroutine yields,the corresponding <code>coroutine.resume</code> returns immediately,even if the yield happens inside nested function calls(that is, not in the main function,but in a function directly or indirectly called by the main function).In the case of a yield, <code>coroutine.resume</code> also returns <B>true</B>,plus any values passed to <code>coroutine.yield</code>.The next time you resume the same coroutine,it continues its execution from the point where it yielded,with the call to <code>coroutine.yield</code> returning any extraarguments passed to <code>coroutine.resume</code>.<p>The <code>coroutine.wrap</code> function creates a coroutinelike <code>coroutine.create</code>,but instead of returning the coroutine itself,it returns a function that, when called, resumes the coroutine.Any arguments passed to that functiongo as extra arguments to resume.The function returns all the values returned by resume,except the first one (the boolean error code).Unlike <code>coroutine.resume</code>,this function does not catch errors;any error is propagated to the caller.<p>As an example,consider the next code:<PRE>function foo1 (a)  print("foo", a)  return coroutine.yield(2*a)endco = coroutine.create(function (a,b)      print("co-body", a, b)      local r = foo1(a+1)      print("co-body", r)      local r, s = coroutine.yield(a+b, a-b)      print("co-body", r, s)      return b, "end"end)       a, b = coroutine.resume(co, 1, 10)print("main", a, b)a, b, c = coroutine.resume(co, "r")print("main", a, b, c)a, b, c = coroutine.resume(co, "x", "y")print("main", a, b, c)a, b = coroutine.resume(co, "x", "y")print("main", a, b)</PRE>When you run it, it produces the following output:<PRE>co-body 1       10foo     2main    true    4co-body rmain    true    11      -9co-body x       ymain    true    10      endmain    false   cannot resume dead coroutine</PRE><p><a name="API"><a name="3"><h1>3 - The Application Program Interface</h1></a></a><p>This section describes the C API for Lua, that is,the set of C&nbsp;functions available to the host program to communicatewith Lua.All API functions and related types and constantsare declared in the header file <code>lua.h</code>.<p>Even when we use the term "function",any facility in the API may be provided as a <em>macro</em> instead.All such macros use each of its arguments exactly once(except for the first argument, which is always a Lua state),and so do not generate hidden side-effects.<p><a name="mangstate"><a name="3.1"><h2>3.1 - States</h2></a></a><p>The Lua library is fully reentrant:it has no global variables.The whole state of the Lua interpreter(global variables, stack, etc.)is stored in a dynamically allocated structure of type <code>lua_State</code>.A pointer to this state must be passed as the first argument toevery function in the library, except to <code>lua_open</code>,which creates a Lua state from scratch.<p>Before calling any API function,you must create a state by calling <code>lua_open</code>:<PRE>       lua_State *lua_open (void);</PRE><p>To release a state created with <code>lua_open</code>, call <code>lua_close</code>:<PRE>       void lua_close (lua_State *L);</PRE>This function destroys all objects in the given Lua state(calling the corresponding garbage-collection metamethods, if any)and frees all dynamic memory used by that state.On several platforms, you may not need to call this function,because all resources are naturally released when the host program ends.On the other hand,long-running programs,such as a daemon or a web server,might need to release states as soon as they are not needed,to avoid growing too large.<p><a name="3.2"><h2>3.2 - The Stack and Indices</h2></a><p>Lua uses a <em>virtual stack</em> to pass values to and from C.Each element in this stack represents a Lua value(<B>nil</B>, number, string, etc.).<p>Whenever Lua calls C, the called function gets a new stack,which is independent of previous stacks and of stacks ofC functions that are still active.That stack initially contains any arguments to the C function,and it is where the C function pushes its results to be returned to the caller (see <a href="#LuacallC">3.16</a>)to be returned to the caller.<p>For convenience,most query operations in the API do not follow a strict stack discipline.Instead, they can refer to any element in the stack by using an <em>index</em>:A positive index represents an <em>absolute</em> stack position(starting at&nbsp;1);a negative index represents an <em>offset</em> from the top of the stack.More specifically, if the stack has <em>n</em> elements,then index&nbsp;1 represents the first element(that is, the element that was pushed onto the stack first)andindex&nbsp;<em>n</em> represents the last element;index&nbsp;<em>-1</em> also represents the last element(that is, the element at the top)and index <em>-n</em> represents the first element.We say that an index is <em>valid</em>if it lies between&nbsp;1 and the stack top(that is, if <code>1 &#060;= abs(index) &#060;= top</code>). <p>At any time, you can get the index of the top element by calling<code>lua_gettop</code>:<PRE>       int lua_gettop (lua_State *L);</PRE>Because indices start at&nbsp;1,the result of <code>lua_gettop</code> is equal to the number of elements in the stack(and so 0&nbsp;means an empty stack).<p>When you interact with Lua API,<em>you are responsible for controlling stack overflow</em>.The function<PRE>       int lua_checkstack (lua_State *L, int extra);</PRE>grows the stack size to <code>top + extra</code> elements;it returns false if it cannot grow the stack to that size.This function never shrinks the stack;if the stack is already larger than the new size,it is left unchanged.<p>Whenever Lua calls C, it ensures that at least <code>LUA_MINSTACK</code> stack positions are available.<code>LUA_MINSTACK</code> is defined in <code>lua.h</code> as 20,so that usually you do not have to worry about stack spaceunless your code has loops pushing elements onto the stack.<p>Most query functions accept as indices any value inside theavailable stack space, that is, indices up to the maximum stack sizeyou have set through <code>lua_checkstack</code>.Such indices are called <em>acceptable indices</em>.More formally, we define an <em>acceptable index</em>as follows:<PRE>     (index &#060; 0 &#038;&#038; abs(index) &#060;= top) || (index > 0 &#038;&#038; index &#060;= stackspace)</PRE>Note that 0 is never an acceptable index.<p>Unless otherwise noted,any function that accepts valid indices can also be called with<em>pseudo-indices</em>,which represent some Lua values that are accessible to the C&nbsp;codebut are not in the stack.Pseudo-indices are used to access the global environment,the registry, and the upvalues of a C&nbsp;function (see <a href="#c-closure">3.17</a>).<p><a name="3.3"><h2>3.3 - Stack Manipulation</h2></a>The API offers the following functions for basic stack manipulation:<PRE>       void lua_settop    (lua_State *L, int index);       void lua_pushvalue (lua_State *L, int index);       void lua_remove    (lua_State *L, int index);       void lua_insert    (lua_State *L, int index);       void lua_replace   (lua_State *L, int index);</PRE><p><code>lua_settop</code> accepts any acceptable index,or 0,and sets the stack top to that index.If the new top is larger than the old one,then the new elements are filled with <B>nil</B>.If <code>index</code> is 0, then all stack elements are removed.A useful macro defined in the <code>lua.h</code> is<PRE>       #define lua_pop(L,n)   lua_settop(L, -(n)-1)</PRE>which pops <code>n</code> elements from the stack.<p><code>lua_pushvalue</code> pushes onto the stack a copy of the elementat the given index.<code>lua_remove</code> removes the element at the given position,shifting down the elements above that position to fill the gap.<code>lua_insert</code> moves the top element into the given position,shifting up the elements above that position to open space.<code>lua_replace</code> moves the top element into the given position,without shifting any element (therefore replacing the value atthe given position).All these functions accept only valid indices.(You cannot call <code>lua_remove</code> or <code>lua_insert</code> withpseudo-indices, as they do not represent a stack position.)<p>As an example, if the stack starts as <code>10 20 30 40 50*</code>(from bottom to top; the `<code>*</code>&acute; marks the top),then<PRE>       lua_pushvalue(L, 3)    --> 10 20 30 40 50 30*       lua_pushvalue(L, -1)   --> 10 20 30 40 50 30 30*       lua_remove(L, -3)      --> 10 20 30 40 30 30*       lua_remove(L,  6)      --> 10 20 30 40 30*       lua_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -