aboutsummaryrefslogtreecommitdiff
path: root/src/lj_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_lib.c')
-rw-r--r--src/lj_lib.c75
1 files changed, 60 insertions, 15 deletions
diff --git a/src/lj_lib.c b/src/lj_lib.c
index 0c91a1c8..56fb6555 100644
--- a/src/lj_lib.c
+++ b/src/lj_lib.c
@@ -18,6 +18,9 @@
18#include "lj_dispatch.h" 18#include "lj_dispatch.h"
19#include "lj_vm.h" 19#include "lj_vm.h"
20#include "lj_strscan.h" 20#include "lj_strscan.h"
21#include "lj_strfmt.h"
22#include "lj_lex.h"
23#include "lj_bcdump.h"
21#include "lj_lib.h" 24#include "lj_lib.h"
22 25
23/* -- Library initialization ---------------------------------------------- */ 26/* -- Library initialization ---------------------------------------------- */
@@ -43,6 +46,28 @@ static GCtab *lib_create_table(lua_State *L, const char *libname, int hsize)
43 return tabV(L->top-1); 46 return tabV(L->top-1);
44} 47}
45 48
49static const uint8_t *lib_read_lfunc(lua_State *L, const uint8_t *p, GCtab *tab)
50{
51 int len = *p++;
52 GCstr *name = lj_str_new(L, (const char *)p, len);
53 LexState ls;
54 GCproto *pt;
55 GCfunc *fn;
56 memset(&ls, 0, sizeof(ls));
57 ls.L = L;
58 ls.p = (const char *)(p+len);
59 ls.pe = (const char *)~(uintptr_t)0;
60 ls.c = -1;
61 ls.level = (BCDUMP_F_STRIP|(LJ_BE*BCDUMP_F_BE));
62 ls.chunkname = name;
63 pt = lj_bcread_proto(&ls);
64 pt->firstline = ~(BCLine)0;
65 fn = lj_func_newL_empty(L, pt, tabref(L->env));
66 /* NOBARRIER: See below for common barrier. */
67 setfuncV(L, lj_tab_setstr(L, tab, name), fn);
68 return (const uint8_t *)ls.p;
69}
70
46void lj_lib_register(lua_State *L, const char *libname, 71void lj_lib_register(lua_State *L, const char *libname,
47 const uint8_t *p, const lua_CFunction *cf) 72 const uint8_t *p, const lua_CFunction *cf)
48{ 73{
@@ -87,6 +112,9 @@ void lj_lib_register(lua_State *L, const char *libname,
87 ofn = fn; 112 ofn = fn;
88 } else { 113 } else {
89 switch (tag | len) { 114 switch (tag | len) {
115 case LIBINIT_LUA:
116 p = lib_read_lfunc(L, p, tab);
117 break;
90 case LIBINIT_SET: 118 case LIBINIT_SET:
91 L->top -= 2; 119 L->top -= 2;
92 if (tvisstr(L->top+1) && strV(L->top+1)->len == 0) 120 if (tvisstr(L->top+1) && strV(L->top+1)->len == 0)
@@ -120,6 +148,37 @@ void lj_lib_register(lua_State *L, const char *libname,
120 } 148 }
121} 149}
122 150
151/* Push internal function on the stack. */
152GCfunc *lj_lib_pushcc(lua_State *L, lua_CFunction f, int id, int n)
153{
154 GCfunc *fn;
155 lua_pushcclosure(L, f, n);
156 fn = funcV(L->top-1);
157 fn->c.ffid = (uint8_t)id;
158 setmref(fn->c.pc, &G(L)->bc_cfunc_int);
159 return fn;
160}
161
162void lj_lib_prereg(lua_State *L, const char *name, lua_CFunction f, GCtab *env)
163{
164 luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD", 4);
165 lua_pushcfunction(L, f);
166 /* NOBARRIER: The function is new (marked white). */
167 setgcref(funcV(L->top-1)->c.env, obj2gco(env));
168 lua_setfield(L, -2, name);
169 L->top--;
170}
171
172int lj_lib_postreg(lua_State *L, lua_CFunction cf, int id, const char *name)
173{
174 GCfunc *fn = lj_lib_pushcf(L, cf, id);
175 GCtab *t = tabref(curr_func(L)->c.env); /* Reference to parent table. */
176 setfuncV(L, lj_tab_setstr(L, t, lj_str_newz(L, name)), fn);
177 lj_gc_anybarriert(L, t);
178 setfuncV(L, L->top++, fn);
179 return 1;
180}
181
123/* -- Type checks --------------------------------------------------------- */ 182/* -- Type checks --------------------------------------------------------- */
124 183
125TValue *lj_lib_checkany(lua_State *L, int narg) 184TValue *lj_lib_checkany(lua_State *L, int narg)
@@ -137,7 +196,7 @@ GCstr *lj_lib_checkstr(lua_State *L, int narg)
137 if (LJ_LIKELY(tvisstr(o))) { 196 if (LJ_LIKELY(tvisstr(o))) {
138 return strV(o); 197 return strV(o);
139 } else if (tvisnumber(o)) { 198 } else if (tvisnumber(o)) {
140 GCstr *s = lj_str_fromnumber(L, o); 199 GCstr *s = lj_strfmt_number(L, o);
141 setstrV(L, o, s); 200 setstrV(L, o, s);
142 return s; 201 return s;
143 } 202 }
@@ -196,20 +255,6 @@ int32_t lj_lib_optint(lua_State *L, int narg, int32_t def)
196 return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def; 255 return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def;
197} 256}
198 257
199int32_t lj_lib_checkbit(lua_State *L, int narg)
200{
201 TValue *o = L->base + narg-1;
202 if (!(o < L->top && lj_strscan_numberobj(o)))
203 lj_err_argt(L, narg, LUA_TNUMBER);
204 if (LJ_LIKELY(tvisint(o))) {
205 return intV(o);
206 } else {
207 int32_t i = lj_num2bit(numV(o));
208 if (LJ_DUALNUM) setintV(o, i);
209 return i;
210 }
211}
212
213GCfunc *lj_lib_checkfunc(lua_State *L, int narg) 258GCfunc *lj_lib_checkfunc(lua_State *L, int narg)
214{ 259{
215 TValue *o = L->base + narg-1; 260 TValue *o = L->base + narg-1;