~kvik/lu9-p9

ref: c85dc2c7a75a78c497c55ce5ad276f8f9fa04e17 lu9-p9/base/common.c -rw-r--r-- 1.9 KiB
c85dc2c7kvik misc: use usize instead of lua_Unsigned 1 year, 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
enum {
	Iosize = 8192,
	Smallbuf = 512,
};

#define min(a, b) ((a) < (b) ? (a) : (b))

static int
error(lua_State *L, char *fmt, ...)
{
	va_list varg;
	int n;
	char *buf;
	luaL_Buffer b;
	
	lua_pushnil(L);
	buf = luaL_buffinitsize(L, &b, Smallbuf);
	va_start(varg, fmt);
	n = vsnprint(buf, Smallbuf, fmt, varg);
	va_end(varg);
	luaL_pushresultsize(&b, n);
	return 2;
}

/* Memory allocator associated with Lua state */
static void*
Lallocf(lua_State *L, void *ptr, usize sz)
{
	void *ud;
	
	ptr = (lua_getallocf(L, &ud))(ud, ptr, LUA_TUSERDATA, sz);
	if(ptr == nil && sz != 0){
		lua_pushliteral(L, "out of memory");
		lua_error(L);
	}
	setmalloctag(ptr, getcallerpc(&L));
	return ptr;
}
#define Lrealloc(L, ptr, sz) Lallocf(L, ptr, sz)
#define Lmalloc(L, sz) Lallocf(L, nil, sz)
#define Lfree(L, ptr) Lallocf(L, ptr, 0)

/* 
 * Various functions in this library require a
 * variably sized buffer for their operation.
 * Rather than allocating one for each call
 * we preallocate a shared buffer of reasonable
 * size and grow it as needed.
 * The buffer gets associated with a Lua state
 * at library load time.
 * getbuffer(L, sz) returns a pointer to the
 * memory area of at least sz bytes.
 * 
 * To avoid stepping on each other's toes the
 * buffer use must be constrained to a single
 * call.
 */

typedef struct Buf Buf;

struct Buf {
	usize sz;
	char b[1];
};

static Buf*
resizebuffer(lua_State *L, Buf *buf, usize sz)
{
	if(buf == nil){
		buf = Lmalloc(L, sizeof(Buf) + sz);
		buf->sz = sz;
	}else if(buf->sz < sz){
		Lfree(L, buf);
		return resizebuffer(L, nil, sz);
	}
	return buf;
}

static char*
getbuffer(lua_State *L, usize sz)
{
	Buf *buf;
	
	lua_getfield(L, LUA_REGISTRYINDEX, "p9-buffer");
	buf = lua_touserdata(L, -1);
	lua_pop(L, 1);
	return resizebuffer(L, buf, sz)->b;
}

static void
dumpstack(lua_State *L)
{
	int i, top;
	
	top = lua_gettop(L);
	for(i = 1; i <= top; i++){
		fprint(2, "%d: %s\n", i, luaL_tolstring(L, i, nil));
		lua_pop(L, 1);
	}
}