aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/LuaJIT-1.1.7/src/lbaselib.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/LuaJIT-1.1.7/src/lbaselib.c')
-rw-r--r--libraries/LuaJIT-1.1.7/src/lbaselib.c679
1 files changed, 679 insertions, 0 deletions
diff --git a/libraries/LuaJIT-1.1.7/src/lbaselib.c b/libraries/LuaJIT-1.1.7/src/lbaselib.c
new file mode 100644
index 0000000..2366a02
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lbaselib.c
@@ -0,0 +1,679 @@
1/*
2** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $
3** Basic library
4** See Copyright Notice in lua.h
5*/
6
7
8
9#include <ctype.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define lbaselib_c
15#define LUA_LIB
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21#ifndef COCO_DISABLE
22#include "lcoco.h"
23#endif
24
25
26
27
28/*
29** If your system does not support `stdout', you can just remove this function.
30** If you need, you can define your own `print' function, following this
31** model but changing `fputs' to put the strings at a proper place
32** (a console window or a log file, for instance).
33*/
34static int luaB_print (lua_State *L) {
35 int n = lua_gettop(L); /* number of arguments */
36 int i;
37 lua_getglobal(L, "tostring");
38 for (i=1; i<=n; i++) {
39 const char *s;
40 lua_pushvalue(L, -1); /* function to be called */
41 lua_pushvalue(L, i); /* value to print */
42 lua_call(L, 1, 1);
43 s = lua_tostring(L, -1); /* get result */
44 if (s == NULL)
45 return luaL_error(L, LUA_QL("tostring") " must return a string to "
46 LUA_QL("print"));
47 if (i>1) fputs("\t", stdout);
48 fputs(s, stdout);
49 lua_pop(L, 1); /* pop result */
50 }
51 fputs("\n", stdout);
52 return 0;
53}
54
55
56static int luaB_tonumber (lua_State *L) {
57 int base = luaL_optint(L, 2, 10);
58 if (base == 10) { /* standard conversion */
59 luaL_checkany(L, 1);
60 if (lua_isnumber(L, 1)) {
61 lua_pushnumber(L, lua_tonumber(L, 1));
62 return 1;
63 }
64 }
65 else {
66 const char *s1 = luaL_checkstring(L, 1);
67 char *s2;
68 unsigned long n;
69 luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
70 n = strtoul(s1, &s2, base);
71 if (s1 != s2) { /* at least one valid digit? */
72 while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
73 if (*s2 == '\0') { /* no invalid trailing characters? */
74 lua_pushnumber(L, (lua_Number)n);
75 return 1;
76 }
77 }
78 }
79 lua_pushnil(L); /* else not a number */
80 return 1;
81}
82
83
84static int luaB_error (lua_State *L) {
85 int level = luaL_optint(L, 2, 1);
86 lua_settop(L, 1);
87 if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
88 luaL_where(L, level);
89 lua_pushvalue(L, 1);
90 lua_concat(L, 2);
91 }
92 return lua_error(L);
93}
94
95
96static int luaB_getmetatable (lua_State *L) {
97 luaL_checkany(L, 1);
98 if (!lua_getmetatable(L, 1)) {
99 lua_pushnil(L);
100 return 1; /* no metatable */
101 }
102 luaL_getmetafield(L, 1, "__metatable");
103 return 1; /* returns either __metatable field (if present) or metatable */
104}
105
106
107static int luaB_setmetatable (lua_State *L) {
108 int t = lua_type(L, 2);
109 luaL_checktype(L, 1, LUA_TTABLE);
110 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
111 "nil or table expected");
112 if (luaL_getmetafield(L, 1, "__metatable"))
113 luaL_error(L, "cannot change a protected metatable");
114 lua_settop(L, 2);
115 lua_setmetatable(L, 1);
116 return 1;
117}
118
119
120static void getfunc (lua_State *L, int opt) {
121 if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
122 else {
123 lua_Debug ar;
124 int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
125 luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
126 if (lua_getstack(L, level, &ar) == 0)
127 luaL_argerror(L, 1, "invalid level");
128 lua_getinfo(L, "f", &ar);
129 if (lua_isnil(L, -1))
130 luaL_error(L, "no function environment for tail call at level %d",
131 level);
132 }
133}
134
135
136static int luaB_getfenv (lua_State *L) {
137 getfunc(L, 1);
138 if (lua_iscfunction(L, -1)) /* is a C function? */
139 lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
140 else
141 lua_getfenv(L, -1);
142 return 1;
143}
144
145
146static int luaB_setfenv (lua_State *L) {
147 luaL_checktype(L, 2, LUA_TTABLE);
148 getfunc(L, 0);
149 lua_pushvalue(L, 2);
150 if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
151 /* change environment of current thread */
152 lua_pushthread(L);
153 lua_insert(L, -2);
154 lua_setfenv(L, -2);
155 return 0;
156 }
157 else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
158 luaL_error(L,
159 LUA_QL("setfenv") " cannot change environment of given object");
160 return 1;
161}
162
163
164static int luaB_rawequal (lua_State *L) {
165 luaL_checkany(L, 1);
166 luaL_checkany(L, 2);
167 lua_pushboolean(L, lua_rawequal(L, 1, 2));
168 return 1;
169}
170
171
172static int luaB_rawget (lua_State *L) {
173 luaL_checktype(L, 1, LUA_TTABLE);
174 luaL_checkany(L, 2);
175 lua_settop(L, 2);
176 lua_rawget(L, 1);
177 return 1;
178}
179
180static int luaB_rawset (lua_State *L) {
181 luaL_checktype(L, 1, LUA_TTABLE);
182 luaL_checkany(L, 2);
183 luaL_checkany(L, 3);
184 lua_settop(L, 3);
185 lua_rawset(L, 1);
186 return 1;
187}
188
189
190static int luaB_gcinfo (lua_State *L) {
191 lua_pushinteger(L, lua_getgccount(L));
192 return 1;
193}
194
195
196static int luaB_collectgarbage (lua_State *L) {
197 static const char *const opts[] = {"stop", "restart", "collect",
198 "count", "step", "setpause", "setstepmul", NULL};
199 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
200 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
201 int o = luaL_checkoption(L, 1, "collect", opts);
202 int ex = luaL_optint(L, 2, 0);
203 int res = lua_gc(L, optsnum[o], ex);
204 switch (optsnum[o]) {
205 case LUA_GCCOUNT: {
206 int b = lua_gc(L, LUA_GCCOUNTB, 0);
207 lua_pushnumber(L, res + ((lua_Number)b/1024));
208 return 1;
209 }
210 case LUA_GCSTEP: {
211 lua_pushboolean(L, res);
212 return 1;
213 }
214 default: {
215 lua_pushnumber(L, res);
216 return 1;
217 }
218 }
219}
220
221
222static int luaB_type (lua_State *L) {
223 luaL_checkany(L, 1);
224 lua_pushstring(L, luaL_typename(L, 1));
225 return 1;
226}
227
228
229static int luaB_next (lua_State *L) {
230 luaL_checktype(L, 1, LUA_TTABLE);
231 lua_settop(L, 2); /* create a 2nd argument if there isn't one */
232 if (lua_next(L, 1))
233 return 2;
234 else {
235 lua_pushnil(L);
236 return 1;
237 }
238}
239
240
241static int luaB_pairs (lua_State *L) {
242 luaL_checktype(L, 1, LUA_TTABLE);
243 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
244 lua_pushvalue(L, 1); /* state, */
245 lua_pushnil(L); /* and initial value */
246 return 3;
247}
248
249
250static int ipairsaux (lua_State *L) {
251 int i = luaL_checkint(L, 2);
252 luaL_checktype(L, 1, LUA_TTABLE);
253 i++; /* next value */
254 lua_pushinteger(L, i);
255 lua_rawgeti(L, 1, i);
256 return (lua_isnil(L, -1)) ? 0 : 2;
257}
258
259
260static int luaB_ipairs (lua_State *L) {
261 luaL_checktype(L, 1, LUA_TTABLE);
262 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
263 lua_pushvalue(L, 1); /* state, */
264 lua_pushinteger(L, 0); /* and initial value */
265 return 3;
266}
267
268
269static int load_aux (lua_State *L, int status) {
270 if (status == 0) /* OK? */
271 return 1;
272 else {
273 lua_pushnil(L);
274 lua_insert(L, -2); /* put before error message */
275 return 2; /* return nil plus error message */
276 }
277}
278
279
280static int luaB_loadstring (lua_State *L) {
281 size_t l;
282 const char *s = luaL_checklstring(L, 1, &l);
283 const char *chunkname = luaL_optstring(L, 2, s);
284 return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
285}
286
287
288static int luaB_loadfile (lua_State *L) {
289 const char *fname = luaL_optstring(L, 1, NULL);
290 return load_aux(L, luaL_loadfile(L, fname));
291}
292
293
294/*
295** Reader for generic `load' function: `lua_load' uses the
296** stack for internal stuff, so the reader cannot change the
297** stack top. Instead, it keeps its resulting string in a
298** reserved slot inside the stack.
299*/
300static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
301 (void)ud; /* to avoid warnings */
302 luaL_checkstack(L, 2, "too many nested functions");
303 lua_pushvalue(L, 1); /* get function */
304 lua_call(L, 0, 1); /* call it */
305 if (lua_isnil(L, -1)) {
306 *size = 0;
307 return NULL;
308 }
309 else if (lua_isstring(L, -1)) {
310 lua_replace(L, 3); /* save string in a reserved stack slot */
311 return lua_tolstring(L, 3, size);
312 }
313 else luaL_error(L, "reader function must return a string");
314 return NULL; /* to avoid warnings */
315}
316
317
318static int luaB_load (lua_State *L) {
319 int status;
320 const char *cname = luaL_optstring(L, 2, "=(load)");
321 luaL_checktype(L, 1, LUA_TFUNCTION);
322 lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
323 status = lua_load(L, generic_reader, NULL, cname);
324 return load_aux(L, status);
325}
326
327
328static int luaB_dofile (lua_State *L) {
329 const char *fname = luaL_optstring(L, 1, NULL);
330 int n = lua_gettop(L);
331 if (luaL_loadfile(L, fname) != 0) lua_error(L);
332 lua_call(L, 0, LUA_MULTRET);
333 return lua_gettop(L) - n;
334}
335
336
337static int luaB_assert (lua_State *L) {
338 luaL_checkany(L, 1);
339 if (!lua_toboolean(L, 1))
340 return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
341 return lua_gettop(L);
342}
343
344
345static int luaB_unpack (lua_State *L) {
346 int i, e, n;
347 luaL_checktype(L, 1, LUA_TTABLE);
348 i = luaL_optint(L, 2, 1);
349 e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
350 if (i > e) return 0; /* empty range */
351 n = e - i + 1; /* number of elements */
352 if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
353 return luaL_error(L, "too many results to unpack");
354 lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
355 while (i++ < e) /* push arg[i + 1...e] */
356 lua_rawgeti(L, 1, i);
357 return n;
358}
359
360
361static int luaB_select (lua_State *L) {
362 int n = lua_gettop(L);
363 if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
364 lua_pushinteger(L, n-1);
365 return 1;
366 }
367 else {
368 int i = luaL_checkint(L, 1);
369 if (i < 0) i = n + i;
370 else if (i > n) i = n;
371 luaL_argcheck(L, 1 <= i, 1, "index out of range");
372 return n - i;
373 }
374}
375
376
377static int luaB_pcall (lua_State *L) {
378 int status;
379 luaL_checkany(L, 1);
380 status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
381 lua_pushboolean(L, (status == 0));
382 lua_insert(L, 1);
383 return lua_gettop(L); /* return status + all results */
384}
385
386
387static int luaB_xpcall (lua_State *L) {
388 int status;
389 luaL_checkany(L, 2);
390 lua_settop(L, 2);
391 lua_insert(L, 1); /* put error function under function to be called */
392 status = lua_pcall(L, 0, LUA_MULTRET, 1);
393 lua_pushboolean(L, (status == 0));
394 lua_replace(L, 1);
395 return lua_gettop(L); /* return status + all results */
396}
397
398
399static int luaB_tostring (lua_State *L) {
400 luaL_checkany(L, 1);
401 if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
402 return 1; /* use its value */
403 switch (lua_type(L, 1)) {
404 case LUA_TNUMBER:
405 lua_pushstring(L, lua_tostring(L, 1));
406 break;
407 case LUA_TSTRING:
408 lua_pushvalue(L, 1);
409 break;
410 case LUA_TBOOLEAN:
411 lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
412 break;
413 case LUA_TNIL:
414 lua_pushliteral(L, "nil");
415 break;
416 default:
417 lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
418 break;
419 }
420 return 1;
421}
422
423
424static int luaB_newproxy (lua_State *L) {
425 lua_settop(L, 1);
426 lua_newuserdata(L, 0); /* create proxy */
427 if (lua_toboolean(L, 1) == 0)
428 return 1; /* no metatable */
429 else if (lua_isboolean(L, 1)) {
430 lua_newtable(L); /* create a new metatable `m' ... */
431 lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
432 lua_pushboolean(L, 1);
433 lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
434 }
435 else {
436 int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
437 if (lua_getmetatable(L, 1)) {
438 lua_rawget(L, lua_upvalueindex(1));
439 validproxy = lua_toboolean(L, -1);
440 lua_pop(L, 1); /* remove value */
441 }
442 luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
443 lua_getmetatable(L, 1); /* metatable is valid; get it */
444 }
445 lua_setmetatable(L, 2);
446 return 1;
447}
448
449
450static const luaL_Reg base_funcs[] = {
451 {"assert", luaB_assert},
452 {"collectgarbage", luaB_collectgarbage},
453 {"dofile", luaB_dofile},
454 {"error", luaB_error},
455 {"gcinfo", luaB_gcinfo},
456 {"getfenv", luaB_getfenv},
457 {"getmetatable", luaB_getmetatable},
458 {"loadfile", luaB_loadfile},
459 {"load", luaB_load},
460 {"loadstring", luaB_loadstring},
461 {"next", luaB_next},
462 {"pcall", luaB_pcall},
463 {"print", luaB_print},
464 {"rawequal", luaB_rawequal},
465 {"rawget", luaB_rawget},
466 {"rawset", luaB_rawset},
467 {"select", luaB_select},
468 {"setfenv", luaB_setfenv},
469 {"setmetatable", luaB_setmetatable},
470 {"tonumber", luaB_tonumber},
471 {"tostring", luaB_tostring},
472 {"type", luaB_type},
473 {"unpack", luaB_unpack},
474 {"xpcall", luaB_xpcall},
475 {NULL, NULL}
476};
477
478
479/*
480** {======================================================
481** Coroutine library
482** =======================================================
483*/
484
485#define CO_RUN 0 /* running */
486#define CO_SUS 1 /* suspended */
487#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */
488#define CO_DEAD 3
489
490static const char *const statnames[] =
491 {"running", "suspended", "normal", "dead"};
492
493static int costatus (lua_State *L, lua_State *co) {
494 if (L == co) return CO_RUN;
495 switch (lua_status(co)) {
496 case LUA_YIELD:
497 return CO_SUS;
498 case 0: {
499 lua_Debug ar;
500 if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
501 return CO_NOR; /* it is running */
502 else if (lua_gettop(co) == 0)
503 return CO_DEAD;
504 else
505 return CO_SUS; /* initial state */
506 }
507 default: /* some error occured */
508 return CO_DEAD;
509 }
510}
511
512
513static int luaB_costatus (lua_State *L) {
514 lua_State *co = lua_tothread(L, 1);
515 luaL_argcheck(L, co, 1, "coroutine expected");
516 lua_pushstring(L, statnames[costatus(L, co)]);
517 return 1;
518}
519
520
521static int auxresume (lua_State *L, lua_State *co, int narg) {
522 int status = costatus(L, co);
523 if (!lua_checkstack(co, narg))
524 luaL_error(L, "too many arguments to resume");
525 if (status != CO_SUS) {
526 lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
527 return -1; /* error flag */
528 }
529 lua_xmove(L, co, narg);
530 status = lua_resume(co, narg);
531 if (status == 0 || status == LUA_YIELD) {
532 int nres = lua_gettop(co);
533 if (!lua_checkstack(L, nres + 1))
534 luaL_error(L, "too many results to resume");
535 lua_xmove(co, L, nres); /* move yielded values */
536 return nres;
537 }
538 else {
539 lua_xmove(co, L, 1); /* move error message */
540 return -1; /* error flag */
541 }
542}
543
544
545static int luaB_coresume (lua_State *L) {
546 lua_State *co = lua_tothread(L, 1);
547 int r;
548 luaL_argcheck(L, co, 1, "coroutine expected");
549 r = auxresume(L, co, lua_gettop(L) - 1);
550 if (r < 0) {
551 lua_pushboolean(L, 0);
552 lua_insert(L, -2);
553 return 2; /* return false + error message */
554 }
555 else {
556 lua_pushboolean(L, 1);
557 lua_insert(L, -(r + 1));
558 return r + 1; /* return true + `resume' returns */
559 }
560}
561
562
563static int luaB_auxwrap (lua_State *L) {
564 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
565 int r = auxresume(L, co, lua_gettop(L));
566 if (r < 0) {
567 if (lua_isstring(L, -1)) { /* error object is a string? */
568 luaL_where(L, 1); /* add extra info */
569 lua_insert(L, -2);
570 lua_concat(L, 2);
571 }
572 lua_error(L); /* propagate error */
573 }
574 return r;
575}
576
577
578#ifndef COCO_DISABLE
579static int luaB_cstacksize (lua_State *L)
580{
581 lua_pushinteger(L, luaCOCO_cstacksize(luaL_optint(L, 1, -1)));
582 return 1;
583}
584#endif
585
586
587static int luaB_cocreate (lua_State *L) {
588#ifdef COCO_DISABLE
589 lua_State *NL = lua_newthread(L);
590 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
591 "Lua function expected");
592#else
593 int cstacksize = luaL_optint(L, 2, 0);
594 lua_State *NL = lua_newcthread(L, cstacksize);
595 luaL_argcheck(L, lua_isfunction(L, 1) &&
596 (cstacksize >= 0 ? 1 : !lua_iscfunction(L, 1)),
597 1, "Lua function expected");
598#endif
599 lua_pushvalue(L, 1); /* move function to top */
600 lua_xmove(L, NL, 1); /* move function from L to NL */
601 return 1;
602}
603
604
605static int luaB_cowrap (lua_State *L) {
606 luaB_cocreate(L);
607 lua_pushcclosure(L, luaB_auxwrap, 1);
608 return 1;
609}
610
611
612static int luaB_yield (lua_State *L) {
613 return lua_yield(L, lua_gettop(L));
614}
615
616
617static int luaB_corunning (lua_State *L) {
618 if (lua_pushthread(L))
619 lua_pushnil(L); /* main thread is not a coroutine */
620 return 1;
621}
622
623
624static const luaL_Reg co_funcs[] = {
625 {"create", luaB_cocreate},
626 {"resume", luaB_coresume},
627 {"running", luaB_corunning},
628 {"status", luaB_costatus},
629 {"wrap", luaB_cowrap},
630 {"yield", luaB_yield},
631#ifndef COCO_DISABLE
632 {"cstacksize", luaB_cstacksize},
633#endif
634 {NULL, NULL}
635};
636
637/* }====================================================== */
638
639
640static void auxopen (lua_State *L, const char *name,
641 lua_CFunction f, lua_CFunction u) {
642 lua_pushcfunction(L, u);
643 lua_pushcclosure(L, f, 1);
644 lua_setfield(L, -2, name);
645}
646
647
648static void base_open (lua_State *L) {
649 /* set global _G */
650 lua_pushvalue(L, LUA_GLOBALSINDEX);
651 lua_setglobal(L, "_G");
652 /* open lib into global table */
653 luaL_register(L, "_G", base_funcs);
654 lua_pushliteral(L, LUA_VERSION);
655 lua_setglobal(L, "_VERSION"); /* set global _VERSION */
656 /* `ipairs' and `pairs' need auxliliary functions as upvalues */
657 auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
658 auxopen(L, "pairs", luaB_pairs, luaB_next);
659 /* `newproxy' needs a weaktable as upvalue */
660 lua_createtable(L, 0, 1); /* new table `w' */
661 lua_pushvalue(L, -1); /* `w' will be its own metatable */
662 lua_setmetatable(L, -2);
663 lua_pushliteral(L, "kv");
664 lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
665 lua_pushcclosure(L, luaB_newproxy, 1);
666 lua_setglobal(L, "newproxy"); /* set global `newproxy' */
667}
668
669
670LUALIB_API int luaopen_base (lua_State *L) {
671 base_open(L);
672 luaL_register(L, LUA_COLIBNAME, co_funcs);
673#ifndef COCO_DISABLE
674 lua_pushboolean(L, 1);
675 lua_setfield(L, -2, "coco");
676#endif
677 return 2;
678}
679