kran
kran

Reputation: 259

How Lua deal with the stack?

I'm trying Lua and want to know how lua_State working
code and result:

state.c

#include <stdio.h>
#include "lua/src/lua.h"
#include "lua/src/lauxlib.h"
static void stackDump(lua_State *L){
    int i;
    int top = lua_gettop(L);
    for(i = 1; i<= top; i++) {
        int t = lua_type(L, i);
        switch(t){
        case LUA_TSTRING:
            printf("'%s'", lua_tostring(L, i));
            break;
        case LUA_TBOOLEAN:
            printf(lua_toboolean(L, i) ?"true":"false");
            break;
        case LUA_TNUMBER:
            printf("%g", lua_tonumber(L, i));
            break;
        default:
            printf("%s", lua_typename(L, t));
            break;
        }
        printf(" ");
    }
    printf("\n");
}

static int divide(struct lua_State *L){

    double a = lua_tonumber(L, 1);
    double b = lua_tonumber(L, 2);
    printf("%p\n", L);

    stackDump(L);

    int quot = (int)a / (int)b;
    int rem = (int)a % (int)b;

    lua_pushnumber(L, quot);
    lua_pushnumber(L, rem);

    stackDump(L);
    printf("---end div---\n");

    return 2;
}

int main(void){
    struct lua_State *L = lua_open();
    lua_pushboolean(L, 1);
    lua_pushnumber(L, 10);
    lua_pushnil(L);
    lua_pushstring(L, "hello");

    printf("%p\n", L);

    stackDump(L);

    lua_register(L, "div", divide);
    luaL_dofile(L, "div.lua");

    stackDump(L);
    lua_close(L);
    return 0;
}

div.lua
local c = div(20, 10)

0x100c009e0
true 10 nil 'hello'
---start div---
0x100c009e0
20 10
20 10 2 0
---end div---
true 10 nil 'hello'

I see lua_State in divide is the same with the main one, but they have different data in stack, How this be done ?

I know the best way to understand this is to read source code of Lua , maybe you can tell me where to find the right place.

Upvotes: 2

Views: 899

Answers (3)

tprk77
tprk77

Reputation: 1161

Think of lua_State as containing the Lua stack, as well as indices delimiting the current visible part of the stack. When you invoke a Lua function, it may look like you have a new stack, but really only the indices have changed. That's the simplified version.

lua_State is defined in lstate.h. I've pulled out the relevant parts for you. stack is the beginning of the big Lua stack containing everything. base is the beginning of the stack for the current function. This is what your function sees as "the stack" when it is executing.

struct lua_State {
  /* ... */
  StkId top;  /* first free slot in the stack */
  StkId base;  /* base of current function */
  /* ... */
  StkId stack_last;  /* last free slot in the stack */
  StkId stack;  /* stack base */
  /* ... */
};

Programming in Lua, 2nd Edition discusses Lua states in chapter 30: Threads and States. You'll find some good information there. For example, lua_State not only represents a Lua state, but also a thread within that state. Furthermore, all threads have their own stack.

Upvotes: 3

lhf
lhf

Reputation: 72312

When Lua calls a registered C function, it gives it a new stack frame.

Upvotes: 0

Nicol Bolas
Nicol Bolas

Reputation: 473537

It gets different data the same way anything gets different data: code changes the data inside of the object.

struct Object
{
  int val;
};

void more_stuff(Object *the_data)
{
  //the_data->val has 5 in it now.
}

void do_stuff(Object *the_data)
{
  int old_val = the_data->val;
  the_data->val = 5;
  more_stuff(the_data);
  the_data->val = old_val;
}

int main()
{
  Object my_data;
  my_data.val = 1;

  //my_data.val has 1.
  do_stuff(&my_data);
  //my_data.val still has 1.
}

Upvotes: 2

Related Questions