(Part 1)
--------------------------------------
5. API
--------------------------------------
This section describes the Lua API, which is a group of C functions that the host program interacts with Lua. All API functions and associated types and constants are declared in the lua. h file.
The functions provided by all APIs can be replaced by macros, even if we use the ''function ''). This macro only uses its parameters once, so it will not produce hidden side effects.
-------------------
Status 5.1 (State)
-------------------
The Lua library is completely reentrant: it does not use any global variables. The complete state of the Lua interpreter (global variables, stacks, label methods, etc.) is saved in a dynamically allocated lua_State type. This state must be passed to every function in the library as the first parameter (except the lua_open mentioned below ).
Before calling any API function, you must create a new status by calling
Lua_State * lua_open (int stacksize );
The only parameter of this function is the stack size of the interpreter. (Each parameter of each function call requires a stack location, local variable, temporary value, and a location marked with a tag. Stack must have an additional 20 available locations. For a very small implementation, there is no recursive function, and the stack size of 100 may be enough .) If stacksize is 0, the default size of 1024 is used.
To release a status created by lua_open, call
Void lua_close (lua_State * L );
This function destroys all objects in the given Lua environment (call the corresponding garbage collection label method, if any) and releases the dynamic memory used in this state. Generally, you do not need to call this function, because when your program ends, all resources are naturally released. On the other hand, a program that runs for a long time, such as a daemon program or a web server program, may need to be released when the status is not needed to avoid excessive memory growth.
Except lua_open, all functions in Lua APIs need a state as their first parameter.
-------------------
5.2 Stack and index
-------------------
Lua transmits data between a stack and C. Each element in the stack represents a Lua value (nil, value, string, etc ).
For convenience, query operations in most APIs do not need to strictly abide by the stack usage rules. Instead, they can reference elements in any stack by using an index. A positive index represents an absolute stack position (starting from 1, unlike starting from 0 in C ). A negative index represents an offset starting from the top of the stack. More specifically, if the stack has n elements, index 1 indicates the first element (that is, the element of the first pressure stack), and index n indicates the last element; index-1 also represents the last element (that is, the element at the top of the stack), and index-n represents the first element. We say that an index is valid if it is located between 1 and the top of the stack (that is, if 1 <= abs (index) <= top ).
At any time, you can obtain the index of the top element of the stack by calling
Int lua_gettop (lua_State * L );
Because the index starts at 1, the result of lua_gettop is equal to the number of elements in the stack (so 0 indicates an empty stack ).
When you interact with Lua APIs, you have the responsibility to control stack overflow.
Function
Int lua_stackspace (lua_State * L );
Returns the number of available positions in the stack. Every time Lua calls C, it ensures that at least LUA_MINSTACK locations are available. LUA_MINSTACK is defined in lua. h with a minimum value of 16. Therefore, you need to worry about the stack space only when your code contains cyclic pressure stacks.
Most query functions accept any value in the available stack space as an index. Such an index is called an acceptable index. More formally, we can define an acceptable index as follows:
(Index <0 & abs (index) <= top) | (index> 0 & index <= top + stackspace)
Note that 0 is not an acceptable index.
-------------------
5.3 stack operations
-------------------
The API provides the following functions for basic stack operations:
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 );
Lua_settop accepts any acceptable index, or 0, and sets the stack top as the index. If the new stack is larger than the old one, the new elements are filled with nil. If the index is 0, all stack elements are removed. The macro definition in a useful API is
# Define lua_pop (L, n) lua_settop (L,-(n)-1)
It outputs n elements at the top of the stack.
Lua_pushvalue: copies of elements at the given index of the stack. Lua_remove removes the elements at a given position and moves all the elements above this position down to fill in the blank space. Lua_insert moves the elements at the top of the stack to a given position and moves the positions above the given position to open up space. These functions only accept valid indexes. As an example, if the stack starts with 10 20 30 40 50 (from the bottom of the stack to the top of the stack),
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
Lua_remove (L, 6) --> 10 20 30 40 30
Lua_insert (L, 1) --> 30 10 20 30 40
Lua_insert (L,-1) --> 30 10 20 30 40 (no effect)
Lua_settop (L,-3) --> 30 10 20
Lua_settop (L, 6) --> 30 10 20 nil
-------------------
5.4 Query stack
-------------------
To check the type of a stack element, you can use the following function:
Int lua_type (lua_State * L, int index );
Int lua_tag (lua_State * L, int index );
Int lua_isnil (lua_State * L, int index );
Int lua_isnumber (lua_State * L, int index );
Int lua_isstring (lua_State * L, int index );
Int lua_istable (lua_State * L, int index );
Int lua_isfunction (lua_State * L, int index );
Int lua_iscfunction (lua_State * L, int index );
Int lua_isuserdata (lua_State * L, int index );
These functions can be called using any acceptable index.
Lua_type returns one of the following constants based on the given object type: LUA_TNIL, LUA_TNUMBER, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA. If the index is invalid (that is, if the stack position is null), lua_type returns LUA_TNONE. This constant can be converted to a string
Const char * lua_typename (lua_State * L, int t );
T is the type returned by a lua_type. The strings returned by lua_typename are: "nil", "number", "string", "table", "function", "userdata", and "no value ".
The tag returned by lua_tag, or when the index is invalid.
Function lua_is * returns 1 if the given type of the object is compatible, otherwise 0. They always return 0 for invalid indexes. Lua_isnumber is a string that accepts numeric values and numeric values. lua_isstring accepts strings and numbers (see section 4.2). lua_isfunction accepts Lua and C functions. To distinguish between Lua and C functions, you should use lua_iscfunction. To distinguish between numeric values and numeric strings, you can use lua_type.
APIs also have functions to compare two values on the stack:
Int lua_equal (lua_State * L, int index1, int index2 );
Int lua_lessthan (lua_State * L, int index1, int index2 );
These functions are equivalent to the functions they correspond to in Lua. In particular, lua_lessthan is equivalent to the lt_event description in Section 4.8. Both functions return 0 if any index is invalid.
To convert a value on the stack to a specified C type, you can use the following conversion function:
Double lua_tonumber (lua_State * L, int index );
Const char * lua_tostring (lua_State * L, int index );
Size_t lua_strlen (lua_State * L, int index );
Lua_CFunction lua_tocfunction (lua_State * L, int index );
Void * lua_touserdata (lua_State * L, int index );
These functions can be called using any acceptable index. When an invalid index is called, they behave as if the given value has an incorrect type.
Lua_tonumber converts the value at the given index to a floating point number. This value must be a value or a string that can be converted to a value (see section 4.2); otherwise, 0 is returned.
Lua_tostring converts a Lua value to a string (const char *). The value must be a string or a value. Otherwise, the function returns NULL. This function returns a pointer to a string in the Lua environment. These strings always have a 0 ('\ 0') after the last character (like in C), but may contain other 0 inside it. If you do not know whether a string contains 0, you can use lua_strlen to obtain its actual length. Because Lua has garbage collection, the pointer returned by lua_tostring is not guaranteed to be valid after the respective values are removed from the stack.
Lua_tocfunction converts the value on the stack to a C function. This value must be a C function; otherwise, lua_tocfunction returns NULL. The type lua_CFunction is described in section 5.13.
Lua_touserdata converts a value to void *. This value must have the userdata type; otherwise, NULL is returned.
-------------------
5.5 pressure stack
-------------------
The API has the following functions used to push the C value to the stack:
Void lua_pushnumber (lua_State * L, double n );
Void lua_pushlstring (lua_State * L, const char * s, size_t len );
Void lua_pushstring (lua_State * L, const char * s );
Void lua_pushusertag (lua_State * L, void * u, int tag );
Void lua_pushnil (lua_State * L );
Void lua_pushcfunction (lua_State * L, lua_CFunction f );
The function accepts a C value, converts it to the corresponding Lua value, and compresses the result stack. In particular, lua_pushlstring and lua_pushstring generate an internal copy of the given string. Lua_pushstring can only be used to press the appropriate C string (that is, the string ends with 0 and the content is not 0); otherwise, you should use a more general lua_pushlstring, which accepts a specified size.
-------------------
5.6 garbage collection
-------------------
Lua uses two numeric values to control its garbage collection. One value calculates the number of bytes of dynamic memory used by Lua, and the other is a critical value. (The internal byte counter maintained by Lua is not completely accurate. It is only a lower limit. Generally, 10% is the correct value. [this half sentence does not know how to translate]) when the byte value reaches the critical value, Lua executes a garbage collection, which recycles the memory of all useless objects (that is, objects not accessible in Lua ). The byte counter is corrected, and the critical value is reset to twice the byte counter.
You can use the following function to use the current values of these two values:
Int lua_getgccount (lua_State * L );
Int lua_getgcthreshold (lua_State * L );
Return their values, in kilobytes. You can change the critical value
Void lua_setgcthreshold (lua_State * L, int newthreshold );
Again, the unit of the given newthreshold value is kilobytes. When you call this function, Lua sets a new critical value and checks it and the byte counter again. If the critical value is less than the byte counter, Lua will immediately perform garbage collection. After garbage collection, a new critical value will be set according to the previous rules.
If you want to change the adaptive behavior of garbage collection, you can use nil to use the garbage collection label method and set your own critical value (the label method will be called after Lua resets the critical value ).
-------------------
5.7 User-defined data and tags
-------------------
Because userdata is an object, the lua_pushusertag function may create a new userdata. If Lua has a given value (void *) and tag userdata, then userdata is pushed to the stack. Otherwise, a new userdata is created with a given value and tag. If this function is called using the label LUA_ANYTAG, Lua tries to find any userdata with a given value regardless of its label. If there is no userdata value, a new tag is created and the tag is 0.
Userdata can have different tags. Its semantics is only known to the host program. The tag is created by the following function:
Int lua_newtag (lua_State * L );
The function lua_settag is used to change the tag of the stack top object (it is not displayed ):
Void lua_settag (lua_State * L, int tag );
The object must be userdata or a table, and the given tag must be the value created by lua_newtag.
(To be continued)
Lua4.0 Reference Manual (v) 5.1-5.7