aboutsummaryrefslogtreecommitdiff
path: root/src/lib_base.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib_base.c84
1 files changed, 32 insertions, 52 deletions
diff --git a/src/lib_base.c b/src/lib_base.c
index 1564725e..6107bde0 100644
--- a/src/lib_base.c
+++ b/src/lib_base.c
@@ -32,6 +32,7 @@
32#include "lj_dispatch.h" 32#include "lj_dispatch.h"
33#include "lj_char.h" 33#include "lj_char.h"
34#include "lj_strscan.h" 34#include "lj_strscan.h"
35#include "lj_strfmt.h"
35#include "lj_lib.h" 36#include "lj_lib.h"
36 37
37/* -- Base library: checks ------------------------------------------------ */ 38/* -- Base library: checks ------------------------------------------------ */
@@ -86,10 +87,11 @@ static int ffh_pairs(lua_State *L, MMS mm)
86 cTValue *mo = lj_meta_lookup(L, o, mm); 87 cTValue *mo = lj_meta_lookup(L, o, mm);
87 if ((LJ_52 || tviscdata(o)) && !tvisnil(mo)) { 88 if ((LJ_52 || tviscdata(o)) && !tvisnil(mo)) {
88 L->top = o+1; /* Only keep one argument. */ 89 L->top = o+1; /* Only keep one argument. */
89 copyTV(L, L->base-1, mo); /* Replace callable. */ 90 copyTV(L, L->base-1-LJ_FR2, mo); /* Replace callable. */
90 return FFH_TAILCALL; 91 return FFH_TAILCALL;
91 } else { 92 } else {
92 if (!tvistab(o)) lj_err_argt(L, 1, LUA_TTABLE); 93 if (!tvistab(o)) lj_err_argt(L, 1, LUA_TTABLE);
94 if (LJ_FR2) { copyTV(L, o-1, o); o--; }
93 setfuncV(L, o-1, funcV(lj_lib_upvalue(L, 1))); 95 setfuncV(L, o-1, funcV(lj_lib_upvalue(L, 1)));
94 if (mm == MM_pairs) setnilV(o+1); else setintV(o+1, 0); 96 if (mm == MM_pairs) setnilV(o+1); else setintV(o+1, 0);
95 return FFH_RES(3); 97 return FFH_RES(3);
@@ -100,7 +102,7 @@ static int ffh_pairs(lua_State *L, MMS mm)
100#endif 102#endif
101 103
102LJLIB_PUSH(lastcl) 104LJLIB_PUSH(lastcl)
103LJLIB_ASM(pairs) 105LJLIB_ASM(pairs) LJLIB_REC(xpairs 0)
104{ 106{
105 return ffh_pairs(L, MM_pairs); 107 return ffh_pairs(L, MM_pairs);
106} 108}
@@ -113,7 +115,7 @@ LJLIB_NOREGUV LJLIB_ASM(ipairs_aux) LJLIB_REC(.)
113} 115}
114 116
115LJLIB_PUSH(lastcl) 117LJLIB_PUSH(lastcl)
116LJLIB_ASM(ipairs) LJLIB_REC(.) 118LJLIB_ASM(ipairs) LJLIB_REC(xpairs 1)
117{ 119{
118 return ffh_pairs(L, MM_ipairs); 120 return ffh_pairs(L, MM_ipairs);
119} 121}
@@ -131,11 +133,11 @@ LJLIB_ASM(setmetatable) LJLIB_REC(.)
131 lj_err_caller(L, LJ_ERR_PROTMT); 133 lj_err_caller(L, LJ_ERR_PROTMT);
132 setgcref(t->metatable, obj2gco(mt)); 134 setgcref(t->metatable, obj2gco(mt));
133 if (mt) { lj_gc_objbarriert(L, t, mt); } 135 if (mt) { lj_gc_objbarriert(L, t, mt); }
134 settabV(L, L->base-1, t); 136 settabV(L, L->base-1-LJ_FR2, t);
135 return FFH_RES(1); 137 return FFH_RES(1);
136} 138}
137 139
138LJLIB_CF(getfenv) 140LJLIB_CF(getfenv) LJLIB_REC(.)
139{ 141{
140 GCfunc *fn; 142 GCfunc *fn;
141 cTValue *o = L->base; 143 cTValue *o = L->base;
@@ -144,6 +146,7 @@ LJLIB_CF(getfenv)
144 o = lj_debug_frame(L, level, &level); 146 o = lj_debug_frame(L, level, &level);
145 if (o == NULL) 147 if (o == NULL)
146 lj_err_arg(L, 1, LJ_ERR_INVLVL); 148 lj_err_arg(L, 1, LJ_ERR_INVLVL);
149 if (LJ_FR2) o--;
147 } 150 }
148 fn = &gcval(o)->fn; 151 fn = &gcval(o)->fn;
149 settabV(L, L->top++, isluafunc(fn) ? tabref(fn->l.env) : tabref(L->env)); 152 settabV(L, L->top++, isluafunc(fn) ? tabref(fn->l.env) : tabref(L->env));
@@ -165,6 +168,7 @@ LJLIB_CF(setfenv)
165 o = lj_debug_frame(L, level, &level); 168 o = lj_debug_frame(L, level, &level);
166 if (o == NULL) 169 if (o == NULL)
167 lj_err_arg(L, 1, LJ_ERR_INVLVL); 170 lj_err_arg(L, 1, LJ_ERR_INVLVL);
171 if (LJ_FR2) o--;
168 } 172 }
169 fn = &gcval(o)->fn; 173 fn = &gcval(o)->fn;
170 if (!isluafunc(fn)) 174 if (!isluafunc(fn))
@@ -257,7 +261,7 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
257 if (base == 10) { 261 if (base == 10) {
258 TValue *o = lj_lib_checkany(L, 1); 262 TValue *o = lj_lib_checkany(L, 1);
259 if (lj_strscan_numberobj(o)) { 263 if (lj_strscan_numberobj(o)) {
260 copyTV(L, L->base-1, o); 264 copyTV(L, L->base-1-LJ_FR2, o);
261 return FFH_RES(1); 265 return FFH_RES(1);
262 } 266 }
263#if LJ_HASFFI 267#if LJ_HASFFI
@@ -270,11 +274,11 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
270 ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) { 274 ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) {
271 int32_t i; 275 int32_t i;
272 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0); 276 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0);
273 setintV(L->base-1, i); 277 setintV(L->base-1-LJ_FR2, i);
274 return FFH_RES(1); 278 return FFH_RES(1);
275 } 279 }
276 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE), 280 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE),
277 (uint8_t *)&(L->base-1)->n, o, 0); 281 (uint8_t *)&(L->base-1-LJ_FR2)->n, o, 0);
278 return FFH_RES(1); 282 return FFH_RES(1);
279 } 283 }
280 } 284 }
@@ -290,45 +294,29 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
290 while (lj_char_isspace((unsigned char)(*ep))) ep++; 294 while (lj_char_isspace((unsigned char)(*ep))) ep++;
291 if (*ep == '\0') { 295 if (*ep == '\0') {
292 if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u)) 296 if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u))
293 setintV(L->base-1, (int32_t)ul); 297 setintV(L->base-1-LJ_FR2, (int32_t)ul);
294 else 298 else
295 setnumV(L->base-1, (lua_Number)ul); 299 setnumV(L->base-1-LJ_FR2, (lua_Number)ul);
296 return FFH_RES(1); 300 return FFH_RES(1);
297 } 301 }
298 } 302 }
299 } 303 }
300 setnilV(L->base-1); 304 setnilV(L->base-1-LJ_FR2);
301 return FFH_RES(1); 305 return FFH_RES(1);
302} 306}
303 307
304LJLIB_PUSH("nil")
305LJLIB_PUSH("false")
306LJLIB_PUSH("true")
307LJLIB_ASM(tostring) LJLIB_REC(.) 308LJLIB_ASM(tostring) LJLIB_REC(.)
308{ 309{
309 TValue *o = lj_lib_checkany(L, 1); 310 TValue *o = lj_lib_checkany(L, 1);
310 cTValue *mo; 311 cTValue *mo;
311 L->top = o+1; /* Only keep one argument. */ 312 L->top = o+1; /* Only keep one argument. */
312 if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) { 313 if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
313 copyTV(L, L->base-1, mo); /* Replace callable. */ 314 copyTV(L, L->base-1-LJ_FR2, mo); /* Replace callable. */
314 return FFH_TAILCALL; 315 return FFH_TAILCALL;
315 } else {
316 GCstr *s;
317 if (tvisnumber(o)) {
318 s = lj_str_fromnumber(L, o);
319 } else if (tvispri(o)) {
320 s = strV(lj_lib_upvalue(L, -(int32_t)itype(o)));
321 } else {
322 if (tvisfunc(o) && isffunc(funcV(o)))
323 lua_pushfstring(L, "function: builtin#%d", funcV(o)->c.ffid);
324 else
325 lua_pushfstring(L, "%s: %p", lj_typename(o), lua_topointer(L, 1));
326 /* Note: lua_pushfstring calls the GC which may invalidate o. */
327 s = strV(L->top-1);
328 }
329 setstrV(L, L->base-1, s);
330 return FFH_RES(1);
331 } 316 }
317 lj_gc_check(L);
318 setstrV(L, L->base-1-LJ_FR2, lj_strfmt_obj(L, L->base));
319 return FFH_RES(1);
332} 320}
333 321
334/* -- Base library: throw and catch errors -------------------------------- */ 322/* -- Base library: throw and catch errors -------------------------------- */
@@ -440,20 +428,20 @@ LJLIB_CF(dofile)
440 428
441LJLIB_CF(gcinfo) 429LJLIB_CF(gcinfo)
442{ 430{
443 setintV(L->top++, (G(L)->gc.total >> 10)); 431 setintV(L->top++, (int32_t)(G(L)->gc.total >> 10));
444 return 1; 432 return 1;
445} 433}
446 434
447LJLIB_CF(collectgarbage) 435LJLIB_CF(collectgarbage)
448{ 436{
449 int opt = lj_lib_checkopt(L, 1, LUA_GCCOLLECT, /* ORDER LUA_GC* */ 437 int opt = lj_lib_checkopt(L, 1, LUA_GCCOLLECT, /* ORDER LUA_GC* */
450 "\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul"); 438 "\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul\1\377\11isrunning");
451 int32_t data = lj_lib_optint(L, 2, 0); 439 int32_t data = lj_lib_optint(L, 2, 0);
452 if (opt == LUA_GCCOUNT) { 440 if (opt == LUA_GCCOUNT) {
453 setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0); 441 setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0);
454 } else { 442 } else {
455 int res = lua_gc(L, opt, data); 443 int res = lua_gc(L, opt, data);
456 if (opt == LUA_GCSTEP) 444 if (opt == LUA_GCSTEP || opt == LUA_GCISRUNNING)
457 setboolV(L->top, res); 445 setboolV(L->top, res);
458 else 446 else
459 setintV(L->top, res); 447 setintV(L->top, res);
@@ -506,21 +494,12 @@ LJLIB_CF(print)
506 } 494 }
507 shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring); 495 shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring);
508 for (i = 0; i < nargs; i++) { 496 for (i = 0; i < nargs; i++) {
497 cTValue *o = &L->base[i];
509 const char *str; 498 const char *str;
510 size_t size; 499 size_t size;
511 cTValue *o = &L->base[i]; 500 MSize len;
512 if (shortcut && tvisstr(o)) { 501 if (shortcut && (str = lj_strfmt_wstrnum(L, o, &len)) != NULL) {
513 str = strVdata(o); 502 size = len;
514 size = strV(o)->len;
515 } else if (shortcut && tvisint(o)) {
516 char buf[LJ_STR_INTBUF];
517 char *p = lj_str_bufint(buf, intV(o));
518 size = (size_t)(buf+LJ_STR_INTBUF-p);
519 str = p;
520 } else if (shortcut && tvisnum(o)) {
521 char buf[LJ_STR_NUMBUF];
522 size = lj_str_bufnum(buf, o);
523 str = buf;
524 } else { 503 } else {
525 copyTV(L, L->top+1, o); 504 copyTV(L, L->top+1, o);
526 copyTV(L, L->top, L->top-1); 505 copyTV(L, L->top, L->top-1);
@@ -558,7 +537,7 @@ LJLIB_CF(coroutine_status)
558 if (co == L) s = "running"; 537 if (co == L) s = "running";
559 else if (co->status == LUA_YIELD) s = "suspended"; 538 else if (co->status == LUA_YIELD) s = "suspended";
560 else if (co->status != 0) s = "dead"; 539 else if (co->status != 0) s = "dead";
561 else if (co->base > tvref(co->stack)+1) s = "normal"; 540 else if (co->base > tvref(co->stack)+1+LJ_FR2) s = "normal";
562 else if (co->top == co->base) s = "dead"; 541 else if (co->top == co->base) s = "dead";
563 else s = "suspended"; 542 else s = "suspended";
564 lua_pushstring(L, s); 543 lua_pushstring(L, s);
@@ -600,8 +579,8 @@ static int ffh_resume(lua_State *L, lua_State *co, int wrap)
600 (co->status == 0 && co->top == co->base)) { 579 (co->status == 0 && co->top == co->base)) {
601 ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD; 580 ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD;
602 if (wrap) lj_err_caller(L, em); 581 if (wrap) lj_err_caller(L, em);
603 setboolV(L->base-1, 0); 582 setboolV(L->base-1-LJ_FR2, 0);
604 setstrV(L, L->base, lj_err_str(L, em)); 583 setstrV(L, L->base-LJ_FR2, lj_err_str(L, em));
605 return FFH_RES(2); 584 return FFH_RES(2);
606 } 585 }
607 lj_state_growstack(co, (MSize)(L->top - L->base)); 586 lj_state_growstack(co, (MSize)(L->top - L->base));
@@ -642,9 +621,10 @@ static void setpc_wrap_aux(lua_State *L, GCfunc *fn);
642 621
643LJLIB_CF(coroutine_wrap) 622LJLIB_CF(coroutine_wrap)
644{ 623{
624 GCfunc *fn;
645 lj_cf_coroutine_create(L); 625 lj_cf_coroutine_create(L);
646 lj_lib_pushcc(L, lj_ffh_coroutine_wrap_aux, FF_coroutine_wrap_aux, 1); 626 fn = lj_lib_pushcc(L, lj_ffh_coroutine_wrap_aux, FF_coroutine_wrap_aux, 1);
647 setpc_wrap_aux(L, funcV(L->top-1)); 627 setpc_wrap_aux(L, fn);
648 return 1; 628 return 1;
649} 629}
650 630