2812
+ − 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);
3697
+ − 214
api_check(L, ttistable(L->top - 1));
2812
+ − 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)))
3697
+ − 774
2812
+ − 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