File: lua_ref_helper.c

package info (click to toggle)
lcm 1.3.1%2Brepack1-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 2,784 kB
  • sloc: ansic: 16,184; java: 6,843; cs: 2,266; cpp: 1,594; python: 989; makefile: 348; xml: 252; sh: 62
file content (51 lines) | stat: -rw-r--r-- 1,657 bytes parent folder | download | duplicates (5)
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
#include "lua_ref_helper.h"

#define FREELIST_REF 0

#if LUA_VERSION_NUM >= 502
#define lua_objlen(L, INDEX) lua_rawlen(L, INDEX)
#endif

/* convert a stack index to positive */
/* stolen from lauxlib.c, converted to a function */

static int abs_index(lua_State *L, int i) {
  return i > 0 || i <= LUA_REGISTRYINDEX ? i : lua_gettop(L) + i + 1;
}

LUALIB_API int luaX_ref(lua_State *L, int t, int l) {
  int ref;
  t = abs_index(L, t);
  l = abs_index(L, l);
  if (lua_isnil(L, -1)) {
    lua_pop(L, 1);     /* remove from stack */
    return LUA_REFNIL; /* 'nil' has a unique fixed reference */
  }
  lua_rawgeti(L, l, FREELIST_REF);   /* get first free element */
  ref = (int)lua_tointeger(L, -1);   /* ref = l[FREELIST_REF] */
  lua_pop(L, 1);                     /* remove it from stack */
  if (ref != 0) {                    /* any free element? */
    lua_rawgeti(L, l, ref);          /* remove it from list */
    lua_rawseti(L, l, FREELIST_REF); /* (l[FREELIST_REF] = l[ref]) */
  } else {                           /* no free elements */
    ref = (int)lua_objlen(L, l);
    ref++; /* create new reference */
  }
  lua_pushboolean(L, 1);
  lua_rawseti(L, l, ref); /* l[ref] = true */
  lua_rawseti(L, t, ref); /* t[ref] = value */
  return ref;
}

LUALIB_API void luaX_unref(lua_State *L, int t, int l, int ref) {
  if (ref >= 0) {
    t = abs_index(L, t);
    l = abs_index(L, l);
    lua_rawgeti(L, l, FREELIST_REF);
    lua_rawseti(L, l, ref); /* l[ref] = l[FREELIST_REF] */
    lua_pushinteger(L, ref);
    lua_rawseti(L, l, FREELIST_REF); /* l[FREELIST_REF] = ref */
    lua_pushnil(L);
    lua_rawseti(L, t, ref); /* t[ref] = nil */
  }
}