/* converts lua value at 'pos' to typval 'tv' */ static void luaV_totypval (lua_State *L, int pos, typval_T *tv) { switch(lua_type(L, pos)) { case LUA_TBOOLEAN: tv->v_type = VAR_SPECIAL; tv->vval.v_number = (varnumber_T) lua_toboolean(L, pos); break; case LUA_TSTRING: tv->v_type = VAR_STRING; tv->vval.v_string = vim_strsave((char_u *) lua_tostring(L, pos)); break; case LUA_TNUMBER: #ifdef FEAT_FLOAT tv->v_type = VAR_FLOAT; tv->vval.v_float = (float_T) lua_tonumber(L, pos); #else tv->v_type = VAR_NUMBER; tv->vval.v_number = (varnumber_T) lua_tointeger(L, pos); #endif break; case LUA_TUSERDATA: { void *p = lua_touserdata(L, pos); if (lua_getmetatable(L, pos)) /* has metatable? */ { /* check list */ luaV_getfield(L, LUAVIM_LIST); if (lua_rawequal(L, -1, -2)) { tv->v_type = VAR_LIST; tv->vval.v_list = *((luaV_List *) p); ++tv->vval.v_list->lv_refcount; lua_pop(L, 2); /* MTs */ return; } /* check dict */ luaV_getfield(L, LUAVIM_DICT); if (lua_rawequal(L, -1, -3)) { tv->v_type = VAR_DICT; tv->vval.v_dict = *((luaV_Dict *) p); ++tv->vval.v_dict->dv_refcount; lua_pop(L, 3); /* MTs */ return; } lua_pop(L, 3); /* MTs */ } break; } default: tv->v_type = VAR_NUMBER; tv->vval.v_number = 0; } }
static luaV_Dict * luaV_newdict (lua_State *L, dict_T *dic) { luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict)); *d = dic; dic->dv_refcount++; /* reference in Lua */ luaV_setudata(L, dic); /* cache[dic] = udata */ luaV_getfield(L, LUAVIM_DICT); lua_setmetatable(L, -2); return d; }
static luaV_List * luaV_newlist (lua_State *L, list_T *lis) { luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List)); *l = lis; lis->lv_refcount++; /* reference in Lua */ luaV_setudata(L, lis); /* cache[lis] = udata */ luaV_getfield(L, LUAVIM_LIST); lua_setmetatable(L, -2); return l; }
static luaV_Window * luaV_newwindow(lua_State *L, win_T *win) { luaV_Window *w = (luaV_Window *) lua_newuserdata(L, sizeof(luaV_Window)); *w = win; lua_pushlightuserdata(L, (void *) win); lua_pushvalue(L, -2); lua_rawset(L, LUA_ENVIRONINDEX); /* env[win] = udata */ /* to avoid GC, store as key in env */ lua_pushvalue(L, -1); lua_pushboolean(L, 1); lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = true */ /* set metatable */ luaV_getfield(L, LUAVIM_WINDOW); lua_setmetatable(L, -2); return w; }
static luaV_Buffer * luaV_newbuffer(lua_State *L, buf_T *buf) { luaV_Buffer *b = (luaV_Buffer *) lua_newuserdata(L, sizeof(luaV_Buffer)); *b = buf; lua_pushlightuserdata(L, (void *) buf); lua_pushvalue(L, -2); lua_rawset(L, LUA_ENVIRONINDEX); /* env[buf] = udata */ /* to avoid GC, store as key in env */ lua_pushvalue(L, -1); lua_pushboolean(L, 1); lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = true */ /* set metatable */ luaV_getfield(L, LUAVIM_BUFFER); lua_setmetatable(L, -2); return b; }
static void * luaV_toudata(lua_State *L, int ud, const char *tname) { void *p = lua_touserdata(L, ud); if (p != NULL) /* value is userdata? */ { if (lua_getmetatable(L, ud)) /* does it have a metatable? */ { luaV_getfield(L, tname); /* get metatable */ if (lua_rawequal(L, -1, -2)) /* MTs match? */ { lua_pop(L, 2); /* MTs */ return p; } } } return NULL; }