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