~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/lua/src/ldblib.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** $Id: ldblib.c,v 1.132 2012/01/19 20:14:44 roberto Exp $
 
3
** Interface from Lua to its debug API
 
4
** See Copyright Notice in lua.h
 
5
*/
 
6
 
 
7
 
 
8
#include <stdio.h>
 
9
#include <stdlib.h>
 
10
#include <string.h>
 
11
 
 
12
#define ldblib_c
 
13
#define LUA_LIB
 
14
 
 
15
#include "lua.h"
 
16
 
 
17
#include "lauxlib.h"
 
18
#include "lualib.h"
 
19
 
 
20
 
 
21
#define HOOKKEY         "_HKEY"
 
22
 
 
23
 
 
24
 
 
25
static int db_getregistry (lua_State *L) {
 
26
  lua_pushvalue(L, LUA_REGISTRYINDEX);
 
27
  return 1;
 
28
}
 
29
 
 
30
 
 
31
static int db_getmetatable (lua_State *L) {
 
32
  luaL_checkany(L, 1);
 
33
  if (!lua_getmetatable(L, 1)) {
 
34
    lua_pushnil(L);  /* no metatable */
 
35
  }
 
36
  return 1;
 
37
}
 
38
 
 
39
 
 
40
static int db_setmetatable (lua_State *L) {
 
41
  int t = lua_type(L, 2);
 
42
  luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
 
43
                    "nil or table expected");
 
44
  lua_settop(L, 2);
 
45
  lua_setmetatable(L, 1);
 
46
  return 1;  /* return 1st argument */
 
47
}
 
48
 
 
49
 
 
50
static int db_getuservalue (lua_State *L) {
 
51
  if (lua_type(L, 1) != LUA_TUSERDATA)
 
52
    lua_pushnil(L);
 
53
  else
 
54
    lua_getuservalue(L, 1);
 
55
  return 1;
 
56
}
 
57
 
 
58
 
 
59
static int db_setuservalue (lua_State *L) {
 
60
  if (lua_type(L, 1) == LUA_TLIGHTUSERDATA)
 
61
    luaL_argerror(L, 1, "full userdata expected, got light userdata");
 
62
  luaL_checktype(L, 1, LUA_TUSERDATA);
 
63
  if (!lua_isnoneornil(L, 2))
 
64
    luaL_checktype(L, 2, LUA_TTABLE);
 
65
  lua_settop(L, 2);
 
66
  lua_setuservalue(L, 1);
 
67
  return 1;
 
68
}
 
69
 
 
70
 
 
71
static void settabss (lua_State *L, const char *i, const char *v) {
 
72
  lua_pushstring(L, v);
 
73
  lua_setfield(L, -2, i);
 
74
}
 
75
 
 
76
 
 
77
static void settabsi (lua_State *L, const char *i, int v) {
 
78
  lua_pushinteger(L, v);
 
79
  lua_setfield(L, -2, i);
 
80
}
 
81
 
 
82
 
 
83
static void settabsb (lua_State *L, const char *i, int v) {
 
84
  lua_pushboolean(L, v);
 
85
  lua_setfield(L, -2, i);
 
86
}
 
87
 
 
88
 
 
89
static lua_State *getthread (lua_State *L, int *arg) {
 
90
  if (lua_isthread(L, 1)) {
 
91
    *arg = 1;
 
92
    return lua_tothread(L, 1);
 
93
  }
 
94
  else {
 
95
    *arg = 0;
 
96
    return L;
 
97
  }
 
98
}
 
99
 
 
100
 
 
101
static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
 
102
  if (L == L1) {
 
103
    lua_pushvalue(L, -2);
 
104
    lua_remove(L, -3);
 
105
  }
 
106
  else
 
107
    lua_xmove(L1, L, 1);
 
108
  lua_setfield(L, -2, fname);
 
109
}
 
110
 
 
111
 
 
112
static int db_getinfo (lua_State *L) {
 
113
  lua_Debug ar;
 
114
  int arg;
 
115
  lua_State *L1 = getthread(L, &arg);
 
116
  const char *options = luaL_optstring(L, arg+2, "flnStu");
 
117
  if (lua_isnumber(L, arg+1)) {
 
118
    if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
 
119
      lua_pushnil(L);  /* level out of range */
 
120
      return 1;
 
121
    }
 
122
  }
 
123
  else if (lua_isfunction(L, arg+1)) {
 
124
    lua_pushfstring(L, ">%s", options);
 
125
    options = lua_tostring(L, -1);
 
126
    lua_pushvalue(L, arg+1);
 
127
    lua_xmove(L, L1, 1);
 
128
  }
 
129
  else
 
130
    return luaL_argerror(L, arg+1, "function or level expected");
 
131
  if (!lua_getinfo(L1, options, &ar))
 
132
    return luaL_argerror(L, arg+2, "invalid option");
 
133
  lua_createtable(L, 0, 2);
 
134
  if (strchr(options, 'S')) {
 
135
    settabss(L, "source", ar.source);
 
136
    settabss(L, "short_src", ar.short_src);
 
137
    settabsi(L, "linedefined", ar.linedefined);
 
138
    settabsi(L, "lastlinedefined", ar.lastlinedefined);
 
139
    settabss(L, "what", ar.what);
 
140
  }
 
141
  if (strchr(options, 'l'))
 
142
    settabsi(L, "currentline", ar.currentline);
 
143
  if (strchr(options, 'u')) {
 
144
    settabsi(L, "nups", ar.nups);
 
145
    settabsi(L, "nparams", ar.nparams);
 
146
    settabsb(L, "isvararg", ar.isvararg);
 
147
  }
 
148
  if (strchr(options, 'n')) {
 
149
    settabss(L, "name", ar.name);
 
150
    settabss(L, "namewhat", ar.namewhat);
 
151
  }
 
152
  if (strchr(options, 't'))
 
153
    settabsb(L, "istailcall", ar.istailcall);
 
154
  if (strchr(options, 'L'))
 
155
    treatstackoption(L, L1, "activelines");
 
156
  if (strchr(options, 'f'))
 
157
    treatstackoption(L, L1, "func");
 
158
  return 1;  /* return table */
 
159
}
 
160
 
 
161
 
 
162
static int db_getlocal (lua_State *L) {
 
163
  int arg;
 
164
  lua_State *L1 = getthread(L, &arg);
 
165
  lua_Debug ar;
 
166
  const char *name;
 
167
  int nvar = luaL_checkint(L, arg+2);  /* local-variable index */
 
168
  if (lua_isfunction(L, arg + 1)) {  /* function argument? */
 
169
    lua_pushvalue(L, arg + 1);  /* push function */
 
170
    lua_pushstring(L, lua_getlocal(L, NULL, nvar));  /* push local name */
 
171
    return 1;
 
172
  }
 
173
  else {  /* stack-level argument */
 
174
    if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))  /* out of range? */
 
175
      return luaL_argerror(L, arg+1, "level out of range");
 
176
    name = lua_getlocal(L1, &ar, nvar);
 
177
    if (name) {
 
178
      lua_xmove(L1, L, 1);  /* push local value */
 
179
      lua_pushstring(L, name);  /* push name */
 
180
      lua_pushvalue(L, -2);  /* re-order */
 
181
      return 2;
 
182
    }
 
183
    else {
 
184
      lua_pushnil(L);  /* no name (nor value) */
 
185
      return 1;
 
186
    }
 
187
  }
 
188
}
 
189
 
 
190
 
 
191
static int db_setlocal (lua_State *L) {
 
192
  int arg;
 
193
  lua_State *L1 = getthread(L, &arg);
 
194
  lua_Debug ar;
 
195
  if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))  /* out of range? */
 
196
    return luaL_argerror(L, arg+1, "level out of range");
 
197
  luaL_checkany(L, arg+3);
 
198
  lua_settop(L, arg+3);
 
199
  lua_xmove(L, L1, 1);
 
200
  lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
 
201
  return 1;
 
202
}
 
203
 
 
204
 
 
205
static int auxupvalue (lua_State *L, int get) {
 
206
  const char *name;
 
207
  int n = luaL_checkint(L, 2);
 
208
  luaL_checktype(L, 1, LUA_TFUNCTION);
 
209
  name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
 
210
  if (name == NULL) return 0;
 
211
  lua_pushstring(L, name);
 
212
  lua_insert(L, -(get+1));
 
213
  return get + 1;
 
214
}
 
215
 
 
216
 
 
217
static int db_getupvalue (lua_State *L) {
 
218
  return auxupvalue(L, 1);
 
219
}
 
220
 
 
221
 
 
222
static int db_setupvalue (lua_State *L) {
 
223
  luaL_checkany(L, 3);
 
224
  return auxupvalue(L, 0);
 
225
}
 
226
 
 
227
 
 
228
static int checkupval (lua_State *L, int argf, int argnup) {
 
229
  lua_Debug ar;
 
230
  int nup = luaL_checkint(L, argnup);
 
231
  luaL_checktype(L, argf, LUA_TFUNCTION);
 
232
  lua_pushvalue(L, argf);
 
233
  lua_getinfo(L, ">u", &ar);
 
234
  luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index");
 
235
  return nup;
 
236
}
 
237
 
 
238
 
 
239
static int db_upvalueid (lua_State *L) {
 
240
  int n = checkupval(L, 1, 2);
 
241
  lua_pushlightuserdata(L, lua_upvalueid(L, 1, n));
 
242
  return 1;
 
243
}
 
244
 
 
245
 
 
246
static int db_upvaluejoin (lua_State *L) {
 
247
  int n1 = checkupval(L, 1, 2);
 
248
  int n2 = checkupval(L, 3, 4);
 
249
  luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
 
250
  luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
 
251
  lua_upvaluejoin(L, 1, n1, 3, n2);
 
252
  return 0;
 
253
}
 
254
 
 
255
 
 
256
#define gethooktable(L) luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)
 
257
 
 
258
 
 
259
static void hookf (lua_State *L, lua_Debug *ar) {
 
260
  static const char *const hooknames[] =
 
261
    {"call", "return", "line", "count", "tail call"};
 
262
  gethooktable(L);
 
263
  lua_pushthread(L);
 
264
  lua_rawget(L, -2);
 
265
  if (lua_isfunction(L, -1)) {
 
266
    lua_pushstring(L, hooknames[(int)ar->event]);
 
267
    if (ar->currentline >= 0)
 
268
      lua_pushinteger(L, ar->currentline);
 
269
    else lua_pushnil(L);
 
270
    lua_assert(lua_getinfo(L, "lS", ar));
 
271
    lua_call(L, 2, 0);
 
272
  }
 
273
}
 
274
 
 
275
 
 
276
static int makemask (const char *smask, int count) {
 
277
  int mask = 0;
 
278
  if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
 
279
  if (strchr(smask, 'r')) mask |= LUA_MASKRET;
 
280
  if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
 
281
  if (count > 0) mask |= LUA_MASKCOUNT;
 
282
  return mask;
 
283
}
 
284
 
 
285
 
 
286
static char *unmakemask (int mask, char *smask) {
 
287
  int i = 0;
 
288
  if (mask & LUA_MASKCALL) smask[i++] = 'c';
 
289
  if (mask & LUA_MASKRET) smask[i++] = 'r';
 
290
  if (mask & LUA_MASKLINE) smask[i++] = 'l';
 
291
  smask[i] = '\0';
 
292
  return smask;
 
293
}
 
294
 
 
295
 
 
296
static int db_sethook (lua_State *L) {
 
297
  int arg, mask, count;
 
298
  lua_Hook func;
 
299
  lua_State *L1 = getthread(L, &arg);
 
300
  if (lua_isnoneornil(L, arg+1)) {
 
301
    lua_settop(L, arg+1);
 
302
    func = NULL; mask = 0; count = 0;  /* turn off hooks */
 
303
  }
 
304
  else {
 
305
    const char *smask = luaL_checkstring(L, arg+2);
 
306
    luaL_checktype(L, arg+1, LUA_TFUNCTION);
 
307
    count = luaL_optint(L, arg+3, 0);
 
308
    func = hookf; mask = makemask(smask, count);
 
309
  }
 
310
  if (gethooktable(L) == 0) {  /* creating hook table? */
 
311
    lua_pushstring(L, "k");
 
312
    lua_setfield(L, -2, "__mode");  /** hooktable.__mode = "k" */
 
313
    lua_pushvalue(L, -1);
 
314
    lua_setmetatable(L, -2);  /* setmetatable(hooktable) = hooktable */
 
315
  }
 
316
  lua_pushthread(L1); lua_xmove(L1, L, 1);
 
317
  lua_pushvalue(L, arg+1);
 
318
  lua_rawset(L, -3);  /* set new hook */
 
319
  lua_sethook(L1, func, mask, count);  /* set hooks */
 
320
  return 0;
 
321
}
 
322
 
 
323
 
 
324
static int db_gethook (lua_State *L) {
 
325
  int arg;
 
326
  lua_State *L1 = getthread(L, &arg);
 
327
  char buff[5];
 
328
  int mask = lua_gethookmask(L1);
 
329
  lua_Hook hook = lua_gethook(L1);
 
330
  if (hook != NULL && hook != hookf)  /* external hook? */
 
331
    lua_pushliteral(L, "external hook");
 
332
  else {
 
333
    gethooktable(L);
 
334
    lua_pushthread(L1); lua_xmove(L1, L, 1);
 
335
    lua_rawget(L, -2);   /* get hook */
 
336
    lua_remove(L, -2);  /* remove hook table */
 
337
  }
 
338
  lua_pushstring(L, unmakemask(mask, buff));
 
339
  lua_pushinteger(L, lua_gethookcount(L1));
 
340
  return 3;
 
341
}
 
342
 
 
343
 
 
344
static int db_debug (lua_State *L) {
 
345
  for (;;) {
 
346
    char buffer[250];
 
347
    luai_writestringerror("%s", "lua_debug> ");
 
348
    if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
 
349
        strcmp(buffer, "cont\n") == 0)
 
350
      return 0;
 
351
    if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
 
352
        lua_pcall(L, 0, 0, 0))
 
353
      luai_writestringerror("%s\n", lua_tostring(L, -1));
 
354
    lua_settop(L, 0);  /* remove eventual returns */
 
355
  }
 
356
}
 
357
 
 
358
 
 
359
static int db_traceback (lua_State *L) {
 
360
  int arg;
 
361
  lua_State *L1 = getthread(L, &arg);
 
362
  const char *msg = lua_tostring(L, arg + 1);
 
363
  if (msg == NULL && !lua_isnoneornil(L, arg + 1))  /* non-string 'msg'? */
 
364
    lua_pushvalue(L, arg + 1);  /* return it untouched */
 
365
  else {
 
366
    int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0);
 
367
    luaL_traceback(L, L1, msg, level);
 
368
  }
 
369
  return 1;
 
370
}
 
371
 
 
372
 
 
373
static const luaL_Reg dblib[] = {
 
374
  {"debug", db_debug},
 
375
  {"getuservalue", db_getuservalue},
 
376
  {"gethook", db_gethook},
 
377
  {"getinfo", db_getinfo},
 
378
  {"getlocal", db_getlocal},
 
379
  {"getregistry", db_getregistry},
 
380
  {"getmetatable", db_getmetatable},
 
381
  {"getupvalue", db_getupvalue},
 
382
  {"upvaluejoin", db_upvaluejoin},
 
383
  {"upvalueid", db_upvalueid},
 
384
  {"setuservalue", db_setuservalue},
 
385
  {"sethook", db_sethook},
 
386
  {"setlocal", db_setlocal},
 
387
  {"setmetatable", db_setmetatable},
 
388
  {"setupvalue", db_setupvalue},
 
389
  {"traceback", db_traceback},
 
390
  {NULL, NULL}
 
391
};
 
392
 
 
393
 
 
394
LUAMOD_API int luaopen_debug (lua_State *L) {
 
395
  luaL_newlib(L, dblib);
 
396
  return 1;
 
397
}
 
398