A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 1100 lines 23 kB view raw
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 34const 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 49static 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 79static 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 89void luaA_pushobject (lua_State *L, const TValue *o) { 90 setobj2s(L, L->top, o); 91 api_incr_top(L); 92} 93 94 95LUA_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 110LUA_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 125LUA_API void lua_setlevel (lua_State *from, lua_State *to) { 126 to->nCcalls = from->nCcalls; 127} 128 129 130LUA_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 140LUA_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 159LUA_API int lua_gettop (lua_State *L) { 160 return cast_int(L->top - L->base); 161} 162 163 164LUA_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 180LUA_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 191LUA_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 203LUA_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 228LUA_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 242LUA_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 248LUA_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 254LUA_API int lua_iscfunction (lua_State *L, int idx) { 255 StkId o = index2adr(L, idx); 256 return iscfunction(o); 257} 258 259 260LUA_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 267LUA_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 273LUA_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 279LUA_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 287LUA_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 299LUA_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 313LUA_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 323LUA_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 337LUA_API int lua_toboolean (lua_State *L, int idx) { 338 const TValue *o = index2adr(L, idx); 339 return !l_isfalse(o); 340} 341 342 343LUA_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 361LUA_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 379LUA_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 385LUA_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 395LUA_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 401LUA_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 421LUA_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 429LUA_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 437LUA_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 445LUA_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 454LUA_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 462LUA_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 473LUA_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 486LUA_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 503LUA_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 511LUA_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 519LUA_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 534LUA_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 544LUA_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 fixedstack(L); 551 setsvalue(L, &key, luaS_new(L, k)); 552 unfixedstack(L); 553 luaV_gettable(L, t, &key, L->top); 554 api_incr_top(L); 555 lua_unlock(L); 556} 557 558 559LUA_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 569LUA_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 580LUA_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 589LUA_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 618LUA_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 647LUA_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 659LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { 660 StkId t; 661 lua_lock(L); 662 api_checknelems(L, 1); 663 t = index2adr(L, idx); 664 api_checkvalidindex(L, t); 665 setsvalue2s(L, L->top, luaS_new(L, k)); 666 api_incr_top(L); 667 luaV_settable(L, t, L->top - 1, L->top - 2); 668 L->top -= 2; /* pop key and value */ 669 lua_unlock(L); 670} 671 672 673LUA_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 fixedstack(L); 680 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); 681 unfixedstack(L); 682 luaC_barriert(L, hvalue(t), L->top-1); 683 L->top -= 2; 684 lua_unlock(L); 685} 686 687 688LUA_API void lua_rawseti (lua_State *L, int idx, int n) { 689 StkId o; 690 lua_lock(L); 691 api_checknelems(L, 1); 692 o = index2adr(L, idx); 693 api_check(L, ttistable(o)); 694 fixedstack(L); 695 setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); 696 unfixedstack(L); 697 luaC_barriert(L, hvalue(o), L->top-1); 698 L->top--; 699 lua_unlock(L); 700} 701 702 703LUA_API int lua_setmetatable (lua_State *L, int objindex) { 704 TValue *obj; 705 Table *mt; 706 lua_lock(L); 707 api_checknelems(L, 1); 708 obj = index2adr(L, objindex); 709 api_checkvalidindex(L, obj); 710 if (ttisnil(L->top - 1)) 711 mt = NULL; 712 else { 713 api_check(L, ttistable(L->top - 1)); 714 mt = hvalue(L->top - 1); 715 } 716 switch (ttype(obj)) { 717 case LUA_TTABLE: { 718 hvalue(obj)->metatable = mt; 719 if (mt) 720 luaC_objbarriert(L, hvalue(obj), mt); 721 break; 722 } 723 case LUA_TUSERDATA: { 724 uvalue(obj)->metatable = mt; 725 if (mt) 726 luaC_objbarrier(L, rawuvalue(obj), mt); 727 break; 728 } 729 default: { 730 G(L)->mt[ttype(obj)] = mt; 731 break; 732 } 733 } 734 L->top--; 735 lua_unlock(L); 736 return 1; 737} 738 739 740LUA_API int lua_setfenv (lua_State *L, int idx) { 741 StkId o; 742 int res = 1; 743 lua_lock(L); 744 api_checknelems(L, 1); 745 o = index2adr(L, idx); 746 api_checkvalidindex(L, o); 747 api_check(L, ttistable(L->top - 1)); 748 switch (ttype(o)) { 749 case LUA_TFUNCTION: 750 clvalue(o)->c.env = hvalue(L->top - 1); 751 break; 752 case LUA_TUSERDATA: 753 uvalue(o)->env = hvalue(L->top - 1); 754 break; 755 case LUA_TTHREAD: 756 sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); 757 break; 758 default: 759 res = 0; 760 break; 761 } 762 if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); 763 L->top--; 764 lua_unlock(L); 765 return res; 766} 767 768 769/* 770** `load' and `call' functions (run Lua code) 771*/ 772 773 774#define adjustresults(L,nres) \ 775 { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } 776 777 778#define checkresults(L,na,nr) \ 779 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) 780 781 782LUA_API void lua_call (lua_State *L, int nargs, int nresults) { 783 StkId func; 784 lua_lock(L); 785 api_checknelems(L, nargs+1); 786 checkresults(L, nargs, nresults); 787 func = L->top - (nargs+1); 788 luaD_call(L, func, nresults); 789 adjustresults(L, nresults); 790 lua_unlock(L); 791} 792 793 794 795/* 796** Execute a protected call. 797*/ 798struct CallS { /* data to `f_call' */ 799 StkId func; 800 int nresults; 801}; 802 803 804static void f_call (lua_State *L, void *ud) { 805 struct CallS *c = cast(struct CallS *, ud); 806 luaD_call(L, c->func, c->nresults); 807} 808 809 810 811LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { 812 struct CallS c; 813 int status; 814 ptrdiff_t func; 815 lua_lock(L); 816 api_checknelems(L, nargs+1); 817 checkresults(L, nargs, nresults); 818 if (errfunc == 0) 819 func = 0; 820 else { 821 StkId o = index2adr(L, errfunc); 822 api_checkvalidindex(L, o); 823 func = savestack(L, o); 824 } 825 c.func = L->top - (nargs+1); /* function to be called */ 826 c.nresults = nresults; 827 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); 828 adjustresults(L, nresults); 829 lua_unlock(L); 830 return status; 831} 832 833 834/* 835** Execute a protected C call. 836*/ 837struct CCallS { /* data to `f_Ccall' */ 838 lua_CFunction func; 839 void *ud; 840}; 841 842 843static void f_Ccall (lua_State *L, void *ud) { 844 struct CCallS *c = cast(struct CCallS *, ud); 845 Closure *cl; 846 cl = luaF_newCclosure(L, 0, getcurrenv(L)); 847 cl->c.f = c->func; 848 setclvalue(L, L->top, cl); /* push function */ 849 api_incr_top(L); 850 setpvalue(L->top, c->ud); /* push only argument */ 851 api_incr_top(L); 852 luaD_call(L, L->top - 2, 0); 853} 854 855 856LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { 857 struct CCallS c; 858 int status; 859 lua_lock(L); 860 c.func = func; 861 c.ud = ud; 862 status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); 863 lua_unlock(L); 864 return status; 865} 866 867 868LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, 869 const char *chunkname) { 870 ZIO z; 871 int status; 872 lua_lock(L); 873 if (!chunkname) chunkname = "?"; 874 luaZ_init(L, &z, reader, data); 875 status = luaD_protectedparser(L, &z, chunkname); 876 lua_unlock(L); 877 return status; 878} 879 880 881LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { 882 int status; 883 TValue *o; 884 lua_lock(L); 885 api_checknelems(L, 1); 886 o = L->top - 1; 887 if (isLfunction(o)) 888 status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); 889 else 890 status = 1; 891 lua_unlock(L); 892 return status; 893} 894 895 896LUA_API int lua_status (lua_State *L) { 897 return L->status; 898} 899 900 901/* 902** Garbage-collection function 903*/ 904 905LUA_API int lua_gc (lua_State *L, int what, int data) { 906 int res = 0; 907 global_State *g; 908 lua_lock(L); 909 g = G(L); 910 switch (what) { 911 case LUA_GCSTOP: { 912 set_block_gc(L); 913 break; 914 } 915 case LUA_GCRESTART: { 916 unset_block_gc(L); 917 break; 918 } 919 case LUA_GCCOLLECT: { 920 luaC_fullgc(L); 921 break; 922 } 923 case LUA_GCCOUNT: { 924 /* GC values are expressed in Kbytes: #bytes/2^10 */ 925 res = cast_int(g->totalbytes >> 10); 926 break; 927 } 928 case LUA_GCCOUNTB: { 929 res = cast_int(g->totalbytes & 0x3ff); 930 break; 931 } 932 case LUA_GCSTEP: { 933 if(is_block_gc(L)) { 934 res = 1; /* gc is block so we need to pretend that the collection cycle finished. */ 935 break; 936 } 937 lu_mem a = (cast(lu_mem, data) << 10); 938 if (a <= g->totalbytes) 939 g->GCthreshold = g->totalbytes - a; 940 else 941 g->GCthreshold = 0; 942 while (g->GCthreshold <= g->totalbytes) { 943 luaC_step(L); 944 if (g->gcstate == GCSpause) { /* end of cycle? */ 945 res = 1; /* signal it */ 946 break; 947 } 948 } 949 break; 950 } 951 case LUA_GCSETPAUSE: { 952 res = g->gcpause; 953 g->gcpause = data; 954 break; 955 } 956 case LUA_GCSETSTEPMUL: { 957 res = g->gcstepmul; 958 g->gcstepmul = data; 959 break; 960 } 961 default: res = -1; /* invalid option */ 962 } 963 lua_unlock(L); 964 return res; 965} 966 967 968 969/* 970** miscellaneous functions 971*/ 972 973 974LUA_API int lua_error (lua_State *L) { 975 lua_lock(L); 976 api_checknelems(L, 1); 977 luaG_errormsg(L); 978 lua_unlock(L); 979 return 0; /* to avoid warnings */ 980} 981 982 983LUA_API int lua_next (lua_State *L, int idx) { 984 StkId t; 985 int more; 986 lua_lock(L); 987 t = index2adr(L, idx); 988 api_check(L, ttistable(t)); 989 more = luaH_next(L, hvalue(t), L->top - 1); 990 if (more) { 991 api_incr_top(L); 992 } 993 else /* no more elements */ 994 L->top -= 1; /* remove key */ 995 lua_unlock(L); 996 return more; 997} 998 999 1000LUA_API void lua_concat (lua_State *L, int n) { 1001 lua_lock(L); 1002 api_checknelems(L, n); 1003 if (n >= 2) { 1004 luaC_checkGC(L); 1005 luaV_concat(L, n, cast_int(L->top - L->base) - 1); 1006 L->top -= (n-1); 1007 } 1008 else if (n == 0) { /* push empty string */ 1009 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); 1010 api_incr_top(L); 1011 } 1012 /* else n == 1; nothing to do */ 1013 lua_unlock(L); 1014} 1015 1016 1017LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { 1018 lua_Alloc f; 1019 lua_lock(L); 1020 if (ud) *ud = G(L)->ud; 1021 f = G(L)->frealloc; 1022 lua_unlock(L); 1023 return f; 1024} 1025 1026 1027LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { 1028 lua_lock(L); 1029 G(L)->ud = ud; 1030 G(L)->frealloc = f; 1031 lua_unlock(L); 1032} 1033 1034 1035LUA_API void *lua_newuserdata (lua_State *L, size_t size) { 1036 Udata *u; 1037 lua_lock(L); 1038 luaC_checkGC(L); 1039 u = luaS_newudata(L, size, getcurrenv(L)); 1040 setuvalue(L, L->top, u); 1041 api_incr_top(L); 1042 lua_unlock(L); 1043 return u + 1; 1044} 1045 1046 1047 1048 1049static const char *aux_upvalue (StkId fi, int n, TValue **val) { 1050 Closure *f; 1051 if (!ttisfunction(fi)) return NULL; 1052 f = clvalue(fi); 1053 if (f->c.isC) { 1054 if (!(1 <= n && n <= f->c.nupvalues)) return NULL; 1055 *val = &f->c.upvalue[n-1]; 1056 return ""; 1057 } 1058 else { 1059 Proto *p = f->l.p; 1060 if (!(1 <= n && n <= p->nups)) // not a valid upvalue 1061 return NULL; 1062 *val = f->l.upvals[n-1]->v; 1063 if (!(1 <= n && n <= p->sizeupvalues)) // don't have a name for this upvalue 1064 return ""; 1065 return getstr(p->upvalues[n-1]); 1066 } 1067} 1068 1069 1070LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { 1071 const char *name; 1072 TValue *val; 1073 lua_lock(L); 1074 name = aux_upvalue(index2adr(L, funcindex), n, &val); 1075 if (name) { 1076 setobj2s(L, L->top, val); 1077 api_incr_top(L); 1078 } 1079 lua_unlock(L); 1080 return name; 1081} 1082 1083 1084LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { 1085 const char *name; 1086 TValue *val; 1087 StkId fi; 1088 lua_lock(L); 1089 fi = index2adr(L, funcindex); 1090 api_checknelems(L, 1); 1091 name = aux_upvalue(fi, n, &val); 1092 if (name) { 1093 L->top--; 1094 setobj(L, val, L->top); 1095 luaC_barrier(L, clvalue(fi), L->top); 1096 } 1097 lua_unlock(L); 1098 return name; 1099} 1100