- Thu Apr 30, 2015 3:39 am
#16072
As you may have noticed I am not a native speaker. So please correct me when I get non idiomatic.
prior to this, whenever I ran across anything referring to the stack in Lua, I assumed that it was similar in definition to the stack and heap that Arduino(AVR) uses, now I think it's more like a virtual stack, could still be wrong though.
You are right. When programming with arduino you have the processor stack which is used by the c language to
store values and pass parameters to functions etc.
Since it's the only stack its just "the stack".
I typicall call it the "c stack".
This is different from the stack you identified as "like a virtual stack" that lua uses to pass values and call functions.
In the end "virtual" is relative to the position you take so it depends.
Lets just call it "the lua stack".
The memory that is used for the lua stack is allocated from the heap with typical c "malloc"-like functions.
Normally the same that you use in your c program.
The lua stack is one of the central data structures of lua.
I suggest don't going into the implentation details of the stack first but stay on the conceptual level:
1. a stack has a stackpointer SP that point to the top of the stack
2. mostly you "push" values on the top of the stack and "pop" from the stack
3. If you address values on the stack you do it relative to the top. SP[0] is the top element SP[-1] the one below the top
and so on.
S:
push(100)
S: 100
^ SP
push(200)
S: 100 200
^SP
push(300)
S: 100 200 300
^SP
SP[0]: 300
SP[-1]: 200
SP[-2]: 100
pop()
S: 100 200
^SP
SP[0]: 200
SP[-1]: 100
Until your mind gets a "stack mode" just print current stack while following program flow on paper.
So a lua thread of execution needs a stack pointer.
Where is it?
This is where
lua_State* L
comes into play.
lua_State contains the context information needed for a lua thread and that includes the lua stack pointer.
Knowing this lets look at the code.
dnc40085 wrote:Alright, here goes...
Code: Select allstatic int wifi_station_listap( lua_State* L )
{
if(wifi_get_opmode() == SOFTAP_MODE) //if esp8266 operating mode is SOFTAP then...
Yep.Code: Select all {
return luaL_error( L, "Can't list ap in SOFTAP mode" ); // return error
}
gL = L; //copies pointer "L" to a global variable "gL" so it can be used in wifi_scan_done later
Yep.Code: Select all if (lua_type(L, 1) == LUA_TFUNCTION || lua_type(L, 1) == LUA_TLIGHTFUNCTION){ // if index 1 of "L" is a function then...
What may index 1 be? Where may it come from?Code: Select all
lua_pushvalue(L, 1); // copy argument (func) to the top of stack
Yep. Just say: push function on stackCode: Select all
if(wifi_scan_succeed != LUA_NOREF)// if variable(wifi_scan_succeed) is NOT equal to constant (LUA_NOREF(-2)) then...
luaL_unref(L, LUA_REGISTRYINDEX, wifi_scan_succeed); //release previous reference and corresponding value???
Yep. (Maybe time to get suspicious?)Code: Select all
wifi_scan_succeed = luaL_ref(L, LUA_REGISTRYINDEX); //create reference(lua pointer) to lua value and store the ID for the reference in the variable "wifi_scan_succeed"
What is this "value"? Where is it? Where does it come from?Code: Select all
wifi_station_scan(NULL,wifi_scan_done); //call station scan function from SDK
Correct. Notice what is passed and what it means.Code: Select all } else { // if index 1 of "L" is NOT a function then...
if(wifi_scan_succeed != LUA_NOREF) // if variable(wifi_scan_succeed) is NOT equal to constant (LUA_NOREF(-2)) then...
luaL_unref(L, LUA_REGISTRYINDEX, wifi_scan_succeed); //release previous reference and corresponding value???
Yep. (Maybe time to get even more suspicious?)Code: Select all wifi_scan_succeed = LUA_NOREF; //set variable "wifi_scan_succeed" to "LUA_NOREF(-2)" since the value corresponds to a non-existent reference
Exactly.
Code: Select allstatic void wifi_scan_done(void *arg, STATUS status)
{
uint8 ssid[33]; // Initialize variable "ssid"
Not really. It "defines" or declares the variable. The variable exists there after.
It is NOT initialialized which means "get a value". Its uninitialized. Typically contains garbage.
Note the size of the array.
Side note: memory for this local variable comes from the c stack. I will vanish Code: Select all char temp[128]; // Initialize variable "temp"
See above.Code: Select all if(wifi_scan_succeed == LUA_NOREF) //if variable "wifi_scan_succeed" contains no reference(lua pointer) then...
return; // since there is no reference ID, return
Yep. Does that have any meaning on lua application code level?Code: Select all if(arg == NULL) //if variable "arg" is NULL then...
return; //there is nothing to process so return
What is this arg? Where does it come from?Code: Select all
lua_rawgeti(gL, LUA_REGISTRYINDEX, wifi_scan_succeed); //push value corresponding to reference stored in "wifi_scan_succeed" onto the stack
Yep.
What type of object is it?
Just say: push <the-type-xxx> wifi_scan_succeed on the stack Code: Select all
if (status == OK) //if status equals OK(0) then...
{
struct bss_info *bss_link = (struct bss_info *)arg; //initialize a pointer to a struct containing the Access Point info("arg") that was passed to this function
Yep.Code: Select all bss_link = bss_link->next.stqe_next;//ignore first entry
I agree.Code: Select all lua_newtable( gL ); //create lua table, to store AP info
Yep.Code: Select all
while (bss_link != NULL) //while variable "bss_link" NOT EQUAL to NULL do...
{
c_memset(ssid, 0, 33); //set "0" to all chars in the variable "ssid"
Yep.Code: Select all if (c_strlen(bss_link->ssid) <= 32) //if length of the string contained within "bss_link->ssid" is LESS THAN or EQUAL to 32 characters then...
{
c_memcpy(ssid, bss_link->ssid, c_strlen(bss_link->ssid)); //copy contents of "bss_link->ssid " to "ssid"
}
else //not sure why this here, maybe to copy only 32 characters of the string if it's longer than 32 chars
Look at definition of target "ssid".Code: Select all {
c_memcpy(ssid, bss_link->ssid, 32); //copy contents of "bss_link->ssid " to "ssid"
Be more precise about the semantics.
Remember how c strings are defined (especially what defines the length of a c string).
Look at the definition of ssid.
Why does ssid contain a valid c string after this?
Code: Select all }
c_sprintf(temp,"%d,%d,"MACSTR",%d", bss_link->authmode, bss_link->rssi,
MAC2STR(bss_link->bssid),bss_link->channel); // copy "authmode, rssi, bssid, channel" values from variable "bss_link" to variable "temp"
"copy" is too unprecise for me.
Here may be dragons.
Based on the format string and parameters given to the function a new string is generated and written to the buffer
defined by temp.
I typically say "print xxx to buffer temp".
Side note: Can the buffer temp overflow? What would happen if it overflows?
Code: Select all
lua_pushstring(gL, temp); //set value of current key in lua table to contents of variable "temp"
Technically it just pushes a string on the stack.
What is "current key"?
Does it have a meaning?
Code: Select all lua_setfield( gL, -2, ssid ); //set "ssid" as the key name in lua table for (current?/last?) entry in the table. (don't get how the index(-2) works)
Maybe backwards thinking can help. Stay tuned.Code: Select all
// NODE_DBG(temp);
bss_link = bss_link->next.stqe_next; // select next ssid in bss_link???
Think of "next entry".Code: Select all }
}
else //if "STATUS" NOT EQUAL "OK(0)" then...
{
lua_pushnil(gL); //push nil value onto stack for pointer "gL"? not sure what exactly this does... maybe this makes sure that nothing is returned to user in case info is old or non-existent.
Think about what "gL" is used for. It's just the home for the SP.
Why push nil on the stack if we don't have anything? Why don't just leave the stack unchanged?
Code: Select all }
lua_call(gL, 1, 0); //calls user's callback function???
Consider the state of the lua stack, the definition (http://pgl.yoyo.org/luai/i/lua_call), explain the parameters to lua_call.
If you are confident what function it is:
What type of paremeter does it expect?
Can that help you understand the lua_setfield function?
http://pgl.yoyo.org/luai/i/lua_setfield
What do they mean with "t[k] = v" and how is that translated to the state of the lua stack and the parameters
of that function when it is called?
}
[/code]