getsize.c

1
/* lua-getsize
2
   Author: (C) 2009 Matthew Wild
3
   License: MIT/X11 license
4
   Description: Adds a debug.getsize() function which
5
                returns the size in bytes of a Lua object
6
*/
7
 
8
#include <stdio.h>
9
 
10
#include <lua.h>
11
#include <lstate.h>
12
#include <lobject.h>
13
#include <lfunc.h>
14
 
15
int debug_getsize(lua_State* L)
16
{
17
  TValue* o = L->base;
18
  switch (o->tt) {
19
    /* Container types */
20
    case LUA_TTABLE: {
21
      Table *h = hvalue(o);
22
      lua_pushinteger(L, sizeof(Table) + sizeof(TValue) * h->sizearray +
23
                             sizeof(Node) * sizenode(h));
24
      break;
25
    }
26
    case LUA_TFUNCTION: {
27
      Closure *cl = clvalue(o);
28
      lua_pushinteger(L, (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
29
                           sizeLclosure(cl->l.nupvalues));
30
      break;
31
    }
32
    case LUA_TTHREAD: {
33
      lua_State *th = thvalue(o);
34
      lua_pushinteger(L, sizeof(lua_State) + sizeof(TValue) * th->stacksize +
35
                                 sizeof(CallInfo) * th->size_ci);
36
      break;
37
    }
38
    case LUA_TPROTO: {
39
      Proto *p = pvalue(o);
40
      lua_pushinteger(L, sizeof(Proto) + sizeof(Instruction) * p->sizecode +
41
                             sizeof(Proto *) * p->sizep +
42
                             sizeof(TValue) * p->sizek + 
43
                             sizeof(int) * p->sizelineinfo +
44
                             sizeof(LocVar) * p->sizelocvars +
45
                             sizeof(TString *) * p->sizeupvalues);
46
     break;
47
    }
48
    /* Non-containers */
49
    case LUA_TUSERDATA: {
50
      lua_pushnumber(L, uvalue(o)->len);
51
      break;
52
    }
53
    case LUA_TLIGHTUSERDATA: {
54
      lua_pushnumber(L, sizeof(void*));
55
      break;
56
    }
57
    case LUA_TSTRING: {
58
      TString *s = rawtsvalue(o);
59
      lua_pushinteger(L, sizeof(TString) + s->tsv.len + 1);
60
      break;
61
    }
62
    case LUA_TNUMBER: {
63
      lua_pushinteger(L, sizeof(lua_Number));
64
      break;
65
    }
66
    case LUA_TBOOLEAN: {
67
      lua_pushinteger(L, sizeof(int));
68
      break;
69
    }
70
    default: return 0;
71
  }
72
  return 1;
73
}
74
 
75
int luaopen_getsize(lua_State* L)
76
{
77
	lua_getglobal(L, "debug");
78
	lua_pushcfunction(L, debug_getsize);
79
	lua_setfield(L, -2, "getsize");
80
	return 0;
81
}