1 /* $NetBSD: lapi.c,v 1.1.1.1 2010/10/31 11:16:54 mbalmer Exp $ */ 2 3 /* 4 ** Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp 5 ** Lua API 6 ** See Copyright Notice in lua.h 7 */ 8 9 10 #include <assert.h> 11 #include <math.h> 12 #include <stdarg.h> 13 #include <string.h> 14 15 #define lapi_c 16 #define LUA_CORE 17 18 #include "lua.h" 19 20 #include "lapi.h" 21 #include "ldebug.h" 22 #include "ldo.h" 23 #include "lfunc.h" 24 #include "lgc.h" 25 #include "lmem.h" 26 #include "lobject.h" 27 #include "lstate.h" 28 #include "lstring.h" 29 #include "ltable.h" 30 #include "ltm.h" 31 #include "lundump.h" 32 #include "lvm.h" 33 34 35 36 const char lua_ident[] = 37 "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n" 38 "$Authors: " LUA_AUTHORS " $\n" 39 "$URL: www.lua.org $\n"; 40 41 42 43 #define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) 44 45 #define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) 46 47 #define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} 48 49 50 51 static TValue *index2adr (lua_State *L, int idx) { 52 if (idx > 0) { 53 TValue *o = L->base + (idx - 1); 54 api_check(L, idx <= L->ci->top - L->base); 55 if (o >= L->top) return cast(TValue *, luaO_nilobject); 56 else return o; 57 } 58 else if (idx > LUA_REGISTRYINDEX) { 59 api_check(L, idx != 0 && -idx <= L->top - L->base); 60 return L->top + idx; 61 } 62 else switch (idx) { /* pseudo-indices */ 63 case LUA_REGISTRYINDEX: return registry(L); 64 case LUA_ENVIRONINDEX: { 65 Closure *func = curr_func(L); 66 sethvalue(L, &L->env, func->c.env); 67 return &L->env; 68 } 69 case LUA_GLOBALSINDEX: return gt(L); 70 default: { 71 Closure *func = curr_func(L); 72 idx = LUA_GLOBALSINDEX - idx; 73 return (idx <= func->c.nupvalues) 74 ? &func->c.upvalue[idx-1] 75 : cast(TValue *, luaO_nilobject); 76 } 77 } 78 } 79 80 81 static Table *getcurrenv (lua_State *L) { 82 if (L->ci == L->base_ci) /* no enclosing function? */ 83 return hvalue(gt(L)); /* use global table as environment */ 84 else { 85 Closure *func = curr_func(L); 86 return func->c.env; 87 } 88 } 89 90 91 void luaA_pushobject (lua_State *L, const TValue *o) { 92 setobj2s(L, L->top, o); 93 api_incr_top(L); 94 } 95 96 97 LUA_API int lua_checkstack (lua_State *L, int size) { 98 int res = 1; 99 lua_lock(L); 100 if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) 101 res = 0; /* stack overflow */ 102 else if (size > 0) { 103 luaD_checkstack(L, size); 104 if (L->ci->top < L->top + size) 105 L->ci->top = L->top + size; 106 } 107 lua_unlock(L); 108 return res; 109 } 110 111 112 LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { 113 int i; 114 if (from == to) return; 115 lua_lock(to); 116 api_checknelems(from, n); 117 api_check(from, G(from) == G(to)); 118 api_check(from, to->ci->top - to->top >= n); 119 from->top -= n; 120 for (i = 0; i < n; i++) { 121 setobj2s(to, to->top++, from->top + i); 122 } 123 lua_unlock(to); 124 } 125 126 127 LUA_API void lua_setlevel (lua_State *from, lua_State *to) { 128 to->nCcalls = from->nCcalls; 129 } 130 131 132 LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { 133 lua_CFunction old; 134 lua_lock(L); 135 old = G(L)->panic; 136 G(L)->panic = panicf; 137 lua_unlock(L); 138 return old; 139 } 140 141 142 LUA_API lua_State *lua_newthread (lua_State *L) { 143 lua_State *L1; 144 lua_lock(L); 145 luaC_checkGC(L); 146 L1 = luaE_newthread(L); 147 setthvalue(L, L->top, L1); 148 api_incr_top(L); 149 lua_unlock(L); 150 luai_userstatethread(L, L1); 151 return L1; 152 } 153 154 155 156 /* 157 ** basic stack manipulation 158 */ 159 160 161 LUA_API int lua_gettop (lua_State *L) { 162 return cast_int(L->top - L->base); 163 } 164 165 166 LUA_API void lua_settop (lua_State *L, int idx) { 167 lua_lock(L); 168 if (idx >= 0) { 169 api_check(L, idx <= L->stack_last - L->base); 170 while (L->top < L->base + idx) 171 setnilvalue(L->top++); 172 L->top = L->base + idx; 173 } 174 else { 175 api_check(L, -(idx+1) <= (L->top - L->base)); 176 L->top += idx+1; /* `subtract' index (index is negative) */ 177 } 178 lua_unlock(L); 179 } 180 181 182 LUA_API void lua_remove (lua_State *L, int idx) { 183 StkId p; 184 lua_lock(L); 185 p = index2adr(L, idx); 186 api_checkvalidindex(L, p); 187 while (++p < L->top) setobjs2s(L, p-1, p); 188 L->top--; 189 lua_unlock(L); 190 } 191 192 193 LUA_API void lua_insert (lua_State *L, int idx) { 194 StkId p; 195 StkId q; 196 lua_lock(L); 197 p = index2adr(L, idx); 198 api_checkvalidindex(L, p); 199 for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); 200 setobjs2s(L, p, L->top); 201 lua_unlock(L); 202 } 203 204 205 LUA_API void lua_replace (lua_State *L, int idx) { 206 StkId o; 207 lua_lock(L); 208 /* explicit test for incompatible code */ 209 if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) 210 luaG_runerror(L, "no calling environment"); 211 api_checknelems(L, 1); 212 o = index2adr(L, idx); 213 api_checkvalidindex(L, o); 214 if (idx == LUA_ENVIRONINDEX) { 215 Closure *func = curr_func(L); 216 api_check(L, ttistable(L->top - 1)); 217 func->c.env = hvalue(L->top - 1); 218 luaC_barrier(L, func, L->top - 1); 219 } 220 else { 221 setobj(L, o, L->top - 1); 222 if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ 223 luaC_barrier(L, curr_func(L), L->top - 1); 224 } 225 L->top--; 226 lua_unlock(L); 227 } 228 229 230 LUA_API void lua_pushvalue (lua_State *L, int idx) { 231 lua_lock(L); 232 setobj2s(L, L->top, index2adr(L, idx)); 233 api_incr_top(L); 234 lua_unlock(L); 235 } 236 237 238 239 /* 240 ** access functions (stack -> C) 241 */ 242 243 244 LUA_API int lua_type (lua_State *L, int idx) { 245 StkId o = index2adr(L, idx); 246 return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); 247 } 248 249 250 LUA_API const char *lua_typename (lua_State *L, int t) { 251 UNUSED(L); 252 return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; 253 } 254 255 256 LUA_API int lua_iscfunction (lua_State *L, int idx) { 257 StkId o = index2adr(L, idx); 258 return iscfunction(o); 259 } 260 261 262 LUA_API int lua_isnumber (lua_State *L, int idx) { 263 TValue n; 264 const TValue *o = index2adr(L, idx); 265 return tonumber(o, &n); 266 } 267 268 269 LUA_API int lua_isstring (lua_State *L, int idx) { 270 int t = lua_type(L, idx); 271 return (t == LUA_TSTRING || t == LUA_TNUMBER); 272 } 273 274 275 LUA_API int lua_isuserdata (lua_State *L, int idx) { 276 const TValue *o = index2adr(L, idx); 277 return (ttisuserdata(o) || ttislightuserdata(o)); 278 } 279 280 281 LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { 282 StkId o1 = index2adr(L, index1); 283 StkId o2 = index2adr(L, index2); 284 return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 285 : luaO_rawequalObj(o1, o2); 286 } 287 288 289 LUA_API int lua_equal (lua_State *L, int index1, int index2) { 290 StkId o1, o2; 291 int i; 292 lua_lock(L); /* may call tag method */ 293 o1 = index2adr(L, index1); 294 o2 = index2adr(L, index2); 295 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); 296 lua_unlock(L); 297 return i; 298 } 299 300 301 LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { 302 StkId o1, o2; 303 int i; 304 lua_lock(L); /* may call tag method */ 305 o1 = index2adr(L, index1); 306 o2 = index2adr(L, index2); 307 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 308 : luaV_lessthan(L, o1, o2); 309 lua_unlock(L); 310 return i; 311 } 312 313 314 315 LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { 316 TValue n; 317 const TValue *o = index2adr(L, idx); 318 if (tonumber(o, &n)) 319 return nvalue(o); 320 else 321 return 0; 322 } 323 324 325 LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { 326 TValue n; 327 const TValue *o = index2adr(L, idx); 328 if (tonumber(o, &n)) { 329 lua_Integer res; 330 lua_Number num = nvalue(o); 331 lua_number2integer(res, num); 332 return res; 333 } 334 else 335 return 0; 336 } 337 338 339 LUA_API int lua_toboolean (lua_State *L, int idx) { 340 const TValue *o = index2adr(L, idx); 341 return !l_isfalse(o); 342 } 343 344 345 LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { 346 StkId o = index2adr(L, idx); 347 if (!ttisstring(o)) { 348 lua_lock(L); /* `luaV_tostring' may create a new string */ 349 if (!luaV_tostring(L, o)) { /* conversion failed? */ 350 if (len != NULL) *len = 0; 351 lua_unlock(L); 352 return NULL; 353 } 354 luaC_checkGC(L); 355 o = index2adr(L, idx); /* previous call may reallocate the stack */ 356 lua_unlock(L); 357 } 358 if (len != NULL) *len = tsvalue(o)->len; 359 return svalue(o); 360 } 361 362 363 LUA_API size_t lua_objlen (lua_State *L, int idx) { 364 StkId o = index2adr(L, idx); 365 switch (ttype(o)) { 366 case LUA_TSTRING: return tsvalue(o)->len; 367 case LUA_TUSERDATA: return uvalue(o)->len; 368 case LUA_TTABLE: return luaH_getn(hvalue(o)); 369 case LUA_TNUMBER: { 370 size_t l; 371 lua_lock(L); /* `luaV_tostring' may create a new string */ 372 l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); 373 lua_unlock(L); 374 return l; 375 } 376 default: return 0; 377 } 378 } 379 380 381 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { 382 StkId o = index2adr(L, idx); 383 return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; 384 } 385 386 387 LUA_API void *lua_touserdata (lua_State *L, int idx) { 388 StkId o = index2adr(L, idx); 389 switch (ttype(o)) { 390 case LUA_TUSERDATA: return (rawuvalue(o) + 1); 391 case LUA_TLIGHTUSERDATA: return pvalue(o); 392 default: return NULL; 393 } 394 } 395 396 397 LUA_API lua_State *lua_tothread (lua_State *L, int idx) { 398 StkId o = index2adr(L, idx); 399 return (!ttisthread(o)) ? NULL : thvalue(o); 400 } 401 402 403 LUA_API const void *lua_topointer (lua_State *L, int idx) { 404 StkId o = index2adr(L, idx); 405 switch (ttype(o)) { 406 case LUA_TTABLE: return hvalue(o); 407 case LUA_TFUNCTION: return clvalue(o); 408 case LUA_TTHREAD: return thvalue(o); 409 case LUA_TUSERDATA: 410 case LUA_TLIGHTUSERDATA: 411 return lua_touserdata(L, idx); 412 default: return NULL; 413 } 414 } 415 416 417 418 /* 419 ** push functions (C -> stack) 420 */ 421 422 423 LUA_API void lua_pushnil (lua_State *L) { 424 lua_lock(L); 425 setnilvalue(L->top); 426 api_incr_top(L); 427 lua_unlock(L); 428 } 429 430 431 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { 432 lua_lock(L); 433 setnvalue(L->top, n); 434 api_incr_top(L); 435 lua_unlock(L); 436 } 437 438 439 LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { 440 lua_lock(L); 441 setnvalue(L->top, cast_num(n)); 442 api_incr_top(L); 443 lua_unlock(L); 444 } 445 446 447 LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { 448 lua_lock(L); 449 luaC_checkGC(L); 450 setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); 451 api_incr_top(L); 452 lua_unlock(L); 453 } 454 455 456 LUA_API void lua_pushstring (lua_State *L, const char *s) { 457 if (s == NULL) 458 lua_pushnil(L); 459 else 460 lua_pushlstring(L, s, strlen(s)); 461 } 462 463 464 LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, 465 va_list argp) { 466 const char *ret; 467 lua_lock(L); 468 luaC_checkGC(L); 469 ret = luaO_pushvfstring(L, fmt, argp); 470 lua_unlock(L); 471 return ret; 472 } 473 474 475 LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { 476 const char *ret; 477 va_list argp; 478 lua_lock(L); 479 luaC_checkGC(L); 480 va_start(argp, fmt); 481 ret = luaO_pushvfstring(L, fmt, argp); 482 va_end(argp); 483 lua_unlock(L); 484 return ret; 485 } 486 487 488 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { 489 Closure *cl; 490 lua_lock(L); 491 luaC_checkGC(L); 492 api_checknelems(L, n); 493 cl = luaF_newCclosure(L, n, getcurrenv(L)); 494 cl->c.f = fn; 495 L->top -= n; 496 while (n--) 497 setobj2n(L, &cl->c.upvalue[n], L->top+n); 498 setclvalue(L, L->top, cl); 499 lua_assert(iswhite(obj2gco(cl))); 500 api_incr_top(L); 501 lua_unlock(L); 502 } 503 504 505 LUA_API void lua_pushboolean (lua_State *L, int b) { 506 lua_lock(L); 507 setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ 508 api_incr_top(L); 509 lua_unlock(L); 510 } 511 512 513 LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { 514 lua_lock(L); 515 setpvalue(L->top, p); 516 api_incr_top(L); 517 lua_unlock(L); 518 } 519 520 521 LUA_API int lua_pushthread (lua_State *L) { 522 lua_lock(L); 523 setthvalue(L, L->top, L); 524 api_incr_top(L); 525 lua_unlock(L); 526 return (G(L)->mainthread == L); 527 } 528 529 530 531 /* 532 ** get functions (Lua -> stack) 533 */ 534 535 536 LUA_API void lua_gettable (lua_State *L, int idx) { 537 StkId t; 538 lua_lock(L); 539 t = index2adr(L, idx); 540 api_checkvalidindex(L, t); 541 luaV_gettable(L, t, L->top - 1, L->top - 1); 542 lua_unlock(L); 543 } 544 545 546 LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { 547 StkId t; 548 TValue key; 549 lua_lock(L); 550 t = index2adr(L, idx); 551 api_checkvalidindex(L, t); 552 setsvalue(L, &key, luaS_new(L, k)); 553 luaV_gettable(L, t, &key, L->top); 554 api_incr_top(L); 555 lua_unlock(L); 556 } 557 558 559 LUA_API void lua_rawget (lua_State *L, int idx) { 560 StkId t; 561 lua_lock(L); 562 t = index2adr(L, idx); 563 api_check(L, ttistable(t)); 564 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); 565 lua_unlock(L); 566 } 567 568 569 LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { 570 StkId o; 571 lua_lock(L); 572 o = index2adr(L, idx); 573 api_check(L, ttistable(o)); 574 setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); 575 api_incr_top(L); 576 lua_unlock(L); 577 } 578 579 580 LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { 581 lua_lock(L); 582 luaC_checkGC(L); 583 sethvalue(L, L->top, luaH_new(L, narray, nrec)); 584 api_incr_top(L); 585 lua_unlock(L); 586 } 587 588 589 LUA_API int lua_getmetatable (lua_State *L, int objindex) { 590 const TValue *obj; 591 Table *mt = NULL; 592 int res; 593 lua_lock(L); 594 obj = index2adr(L, objindex); 595 switch (ttype(obj)) { 596 case LUA_TTABLE: 597 mt = hvalue(obj)->metatable; 598 break; 599 case LUA_TUSERDATA: 600 mt = uvalue(obj)->metatable; 601 break; 602 default: 603 mt = G(L)->mt[ttype(obj)]; 604 break; 605 } 606 if (mt == NULL) 607 res = 0; 608 else { 609 sethvalue(L, L->top, mt); 610 api_incr_top(L); 611 res = 1; 612 } 613 lua_unlock(L); 614 return res; 615 } 616 617 618 LUA_API void lua_getfenv (lua_State *L, int idx) { 619 StkId o; 620 lua_lock(L); 621 o = index2adr(L, idx); 622 api_checkvalidindex(L, o); 623 switch (ttype(o)) { 624 case LUA_TFUNCTION: 625 sethvalue(L, L->top, clvalue(o)->c.env); 626 break; 627 case LUA_TUSERDATA: 628 sethvalue(L, L->top, uvalue(o)->env); 629 break; 630 case LUA_TTHREAD: 631 setobj2s(L, L->top, gt(thvalue(o))); 632 break; 633 default: 634 setnilvalue(L->top); 635 break; 636 } 637 api_incr_top(L); 638 lua_unlock(L); 639 } 640 641 642 /* 643 ** set functions (stack -> Lua) 644 */ 645 646 647 LUA_API void lua_settable (lua_State *L, int idx) { 648 StkId t; 649 lua_lock(L); 650 api_checknelems(L, 2); 651 t = index2adr(L, idx); 652 api_checkvalidindex(L, t); 653 luaV_settable(L, t, L->top - 2, L->top - 1); 654 L->top -= 2; /* pop index and value */ 655 lua_unlock(L); 656 } 657 658 659 LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { 660 StkId t; 661 TValue key; 662 lua_lock(L); 663 api_checknelems(L, 1); 664 t = index2adr(L, idx); 665 api_checkvalidindex(L, t); 666 setsvalue(L, &key, luaS_new(L, k)); 667 luaV_settable(L, t, &key, L->top - 1); 668 L->top--; /* pop value */ 669 lua_unlock(L); 670 } 671 672 673 LUA_API void lua_rawset (lua_State *L, int idx) { 674 StkId t; 675 lua_lock(L); 676 api_checknelems(L, 2); 677 t = index2adr(L, idx); 678 api_check(L, ttistable(t)); 679 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); 680 luaC_barriert(L, hvalue(t), L->top-1); 681 L->top -= 2; 682 lua_unlock(L); 683 } 684 685 686 LUA_API void lua_rawseti (lua_State *L, int idx, int n) { 687 StkId o; 688 lua_lock(L); 689 api_checknelems(L, 1); 690 o = index2adr(L, idx); 691 api_check(L, ttistable(o)); 692 setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); 693 luaC_barriert(L, hvalue(o), L->top-1); 694 L->top--; 695 lua_unlock(L); 696 } 697 698 699 LUA_API int lua_setmetatable (lua_State *L, int objindex) { 700 TValue *obj; 701 Table *mt; 702 lua_lock(L); 703 api_checknelems(L, 1); 704 obj = index2adr(L, objindex); 705 api_checkvalidindex(L, obj); 706 if (ttisnil(L->top - 1)) 707 mt = NULL; 708 else { 709 api_check(L, ttistable(L->top - 1)); 710 mt = hvalue(L->top - 1); 711 } 712 switch (ttype(obj)) { 713 case LUA_TTABLE: { 714 hvalue(obj)->metatable = mt; 715 if (mt) 716 luaC_objbarriert(L, hvalue(obj), mt); 717 break; 718 } 719 case LUA_TUSERDATA: { 720 uvalue(obj)->metatable = mt; 721 if (mt) 722 luaC_objbarrier(L, rawuvalue(obj), mt); 723 break; 724 } 725 default: { 726 G(L)->mt[ttype(obj)] = mt; 727 break; 728 } 729 } 730 L->top--; 731 lua_unlock(L); 732 return 1; 733 } 734 735 736 LUA_API int lua_setfenv (lua_State *L, int idx) { 737 StkId o; 738 int res = 1; 739 lua_lock(L); 740 api_checknelems(L, 1); 741 o = index2adr(L, idx); 742 api_checkvalidindex(L, o); 743 api_check(L, ttistable(L->top - 1)); 744 switch (ttype(o)) { 745 case LUA_TFUNCTION: 746 clvalue(o)->c.env = hvalue(L->top - 1); 747 break; 748 case LUA_TUSERDATA: 749 uvalue(o)->env = hvalue(L->top - 1); 750 break; 751 case LUA_TTHREAD: 752 sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); 753 break; 754 default: 755 res = 0; 756 break; 757 } 758 if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); 759 L->top--; 760 lua_unlock(L); 761 return res; 762 } 763 764 765 /* 766 ** `load' and `call' functions (run Lua code) 767 */ 768 769 770 #define adjustresults(L,nres) \ 771 { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } 772 773 774 #define checkresults(L,na,nr) \ 775 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) 776 777 778 LUA_API void lua_call (lua_State *L, int nargs, int nresults) { 779 StkId func; 780 lua_lock(L); 781 api_checknelems(L, nargs+1); 782 checkresults(L, nargs, nresults); 783 func = L->top - (nargs+1); 784 luaD_call(L, func, nresults); 785 adjustresults(L, nresults); 786 lua_unlock(L); 787 } 788 789 790 791 /* 792 ** Execute a protected call. 793 */ 794 struct CallS { /* data to `f_call' */ 795 StkId func; 796 int nresults; 797 }; 798 799 800 static void f_call (lua_State *L, void *ud) { 801 struct CallS *c = cast(struct CallS *, ud); 802 luaD_call(L, c->func, c->nresults); 803 } 804 805 806 807 LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { 808 struct CallS c; 809 int status; 810 ptrdiff_t func; 811 lua_lock(L); 812 api_checknelems(L, nargs+1); 813 checkresults(L, nargs, nresults); 814 if (errfunc == 0) 815 func = 0; 816 else { 817 StkId o = index2adr(L, errfunc); 818 api_checkvalidindex(L, o); 819 func = savestack(L, o); 820 } 821 c.func = L->top - (nargs+1); /* function to be called */ 822 c.nresults = nresults; 823 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); 824 adjustresults(L, nresults); 825 lua_unlock(L); 826 return status; 827 } 828 829 830 /* 831 ** Execute a protected C call. 832 */ 833 struct CCallS { /* data to `f_Ccall' */ 834 lua_CFunction func; 835 void *ud; 836 }; 837 838 839 static void f_Ccall (lua_State *L, void *ud) { 840 struct CCallS *c = cast(struct CCallS *, ud); 841 Closure *cl; 842 cl = luaF_newCclosure(L, 0, getcurrenv(L)); 843 cl->c.f = c->func; 844 setclvalue(L, L->top, cl); /* push function */ 845 api_incr_top(L); 846 setpvalue(L->top, c->ud); /* push only argument */ 847 api_incr_top(L); 848 luaD_call(L, L->top - 2, 0); 849 } 850 851 852 LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { 853 struct CCallS c; 854 int status; 855 lua_lock(L); 856 c.func = func; 857 c.ud = ud; 858 status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); 859 lua_unlock(L); 860 return status; 861 } 862 863 864 LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, 865 const char *chunkname) { 866 ZIO z; 867 int status; 868 lua_lock(L); 869 if (!chunkname) chunkname = "?"; 870 luaZ_init(L, &z, reader, data); 871 status = luaD_protectedparser(L, &z, chunkname); 872 lua_unlock(L); 873 return status; 874 } 875 876 877 LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { 878 int status; 879 TValue *o; 880 lua_lock(L); 881 api_checknelems(L, 1); 882 o = L->top - 1; 883 if (isLfunction(o)) 884 status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); 885 else 886 status = 1; 887 lua_unlock(L); 888 return status; 889 } 890 891 892 LUA_API int lua_status (lua_State *L) { 893 return L->status; 894 } 895 896 897 /* 898 ** Garbage-collection function 899 */ 900 901 LUA_API int lua_gc (lua_State *L, int what, int data) { 902 int res = 0; 903 global_State *g; 904 lua_lock(L); 905 g = G(L); 906 switch (what) { 907 case LUA_GCSTOP: { 908 g->GCthreshold = MAX_LUMEM; 909 break; 910 } 911 case LUA_GCRESTART: { 912 g->GCthreshold = g->totalbytes; 913 break; 914 } 915 case LUA_GCCOLLECT: { 916 luaC_fullgc(L); 917 break; 918 } 919 case LUA_GCCOUNT: { 920 /* GC values are expressed in Kbytes: #bytes/2^10 */ 921 res = cast_int(g->totalbytes >> 10); 922 break; 923 } 924 case LUA_GCCOUNTB: { 925 res = cast_int(g->totalbytes & 0x3ff); 926 break; 927 } 928 case LUA_GCSTEP: { 929 lu_mem a = (cast(lu_mem, data) << 10); 930 if (a <= g->totalbytes) 931 g->GCthreshold = g->totalbytes - a; 932 else 933 g->GCthreshold = 0; 934 while (g->GCthreshold <= g->totalbytes) { 935 luaC_step(L); 936 if (g->gcstate == GCSpause) { /* end of cycle? */ 937 res = 1; /* signal it */ 938 break; 939 } 940 } 941 break; 942 } 943 case LUA_GCSETPAUSE: { 944 res = g->gcpause; 945 g->gcpause = data; 946 break; 947 } 948 case LUA_GCSETSTEPMUL: { 949 res = g->gcstepmul; 950 g->gcstepmul = data; 951 break; 952 } 953 default: res = -1; /* invalid option */ 954 } 955 lua_unlock(L); 956 return res; 957 } 958 959 960 961 /* 962 ** miscellaneous functions 963 */ 964 965 966 LUA_API int lua_error (lua_State *L) { 967 lua_lock(L); 968 api_checknelems(L, 1); 969 luaG_errormsg(L); 970 lua_unlock(L); 971 return 0; /* to avoid warnings */ 972 } 973 974 975 LUA_API int lua_next (lua_State *L, int idx) { 976 StkId t; 977 int more; 978 lua_lock(L); 979 t = index2adr(L, idx); 980 api_check(L, ttistable(t)); 981 more = luaH_next(L, hvalue(t), L->top - 1); 982 if (more) { 983 api_incr_top(L); 984 } 985 else /* no more elements */ 986 L->top -= 1; /* remove key */ 987 lua_unlock(L); 988 return more; 989 } 990 991 992 LUA_API void lua_concat (lua_State *L, int n) { 993 lua_lock(L); 994 api_checknelems(L, n); 995 if (n >= 2) { 996 luaC_checkGC(L); 997 luaV_concat(L, n, cast_int(L->top - L->base) - 1); 998 L->top -= (n-1); 999 } 1000 else if (n == 0) { /* push empty string */ 1001 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); 1002 api_incr_top(L); 1003 } 1004 /* else n == 1; nothing to do */ 1005 lua_unlock(L); 1006 } 1007 1008 1009 LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { 1010 lua_Alloc f; 1011 lua_lock(L); 1012 if (ud) *ud = G(L)->ud; 1013 f = G(L)->frealloc; 1014 lua_unlock(L); 1015 return f; 1016 } 1017 1018 1019 LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { 1020 lua_lock(L); 1021 G(L)->ud = ud; 1022 G(L)->frealloc = f; 1023 lua_unlock(L); 1024 } 1025 1026 1027 LUA_API void *lua_newuserdata (lua_State *L, size_t size) { 1028 Udata *u; 1029 lua_lock(L); 1030 luaC_checkGC(L); 1031 u = luaS_newudata(L, size, getcurrenv(L)); 1032 setuvalue(L, L->top, u); 1033 api_incr_top(L); 1034 lua_unlock(L); 1035 return u + 1; 1036 } 1037 1038 1039 1040 1041 static const char *aux_upvalue (StkId fi, int n, TValue **val) { 1042 Closure *f; 1043 if (!ttisfunction(fi)) return NULL; 1044 f = clvalue(fi); 1045 if (f->c.isC) { 1046 if (!(1 <= n && n <= f->c.nupvalues)) return NULL; 1047 *val = &f->c.upvalue[n-1]; 1048 return ""; 1049 } 1050 else { 1051 Proto *p = f->l.p; 1052 if (!(1 <= n && n <= p->sizeupvalues)) return NULL; 1053 *val = f->l.upvals[n-1]->v; 1054 return getstr(p->upvalues[n-1]); 1055 } 1056 } 1057 1058 1059 LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { 1060 const char *name; 1061 TValue *val; 1062 lua_lock(L); 1063 name = aux_upvalue(index2adr(L, funcindex), n, &val); 1064 if (name) { 1065 setobj2s(L, L->top, val); 1066 api_incr_top(L); 1067 } 1068 lua_unlock(L); 1069 return name; 1070 } 1071 1072 1073 LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { 1074 const char *name; 1075 TValue *val; 1076 StkId fi; 1077 lua_lock(L); 1078 fi = index2adr(L, funcindex); 1079 api_checknelems(L, 1); 1080 name = aux_upvalue(fi, n, &val); 1081 if (name) { 1082 L->top--; 1083 setobj(L, val, L->top); 1084 luaC_barrier(L, clvalue(fi), L->top); 1085 } 1086 lua_unlock(L); 1087 return name; 1088 } 1089 1090