diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-12-08 11:54:21 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-12-08 11:54:21 -0300 |
commit | 748d6d4e7a1ac247071f6354f2700d1d0ee46b24 (patch) | |
tree | c7ad182b83e6fc021ea16d81c2ce4422f94016f3 /ltests.c | |
parent | e2ea3b31c94bb3e1da27c233661cb2a16699c685 (diff) | |
download | lua-748d6d4e7a1ac247071f6354f2700d1d0ee46b24.tar.gz lua-748d6d4e7a1ac247071f6354f2700d1d0ee46b24.tar.bz2 lua-748d6d4e7a1ac247071f6354f2700d1d0ee46b24.zip |
Review of asserts in 'ltests.c'
The module 'ltests.c' must work correctly with asserts off, too.
Diffstat (limited to 'ltests.c')
-rw-r--r-- | ltests.c | 126 |
1 files changed, 70 insertions, 56 deletions
@@ -272,11 +272,15 @@ void *debug_realloc (void *ud, void *b, size_t oldsize, size_t size) { | |||
272 | 272 | ||
273 | 273 | ||
274 | /* | 274 | /* |
275 | ** {====================================================== | 275 | ** {===================================================================== |
276 | ** Functions to check memory consistency | 276 | ** Functions to check memory consistency. |
277 | ** ======================================================= | 277 | ** Most of these checks are done through asserts, so this code does |
278 | ** not make sense with asserts off. For this reason, it uses 'assert' | ||
279 | ** directly, instead of 'lua_assert'. | ||
280 | ** ====================================================================== | ||
278 | */ | 281 | */ |
279 | 282 | ||
283 | #include <assert.h> | ||
280 | 284 | ||
281 | /* | 285 | /* |
282 | ** Check GC invariants. For incremental mode, a black object cannot | 286 | ** Check GC invariants. For incremental mode, a black object cannot |
@@ -330,13 +334,23 @@ static int testobjref (global_State *g, GCObject *f, GCObject *t) { | |||
330 | return r1; | 334 | return r1; |
331 | } | 335 | } |
332 | 336 | ||
333 | #define checkobjref(g,f,t) \ | 337 | |
334 | { if (t) lua_longassert(testobjref(g,f,obj2gco(t))); } | 338 | static void checkobjref (global_State *g, GCObject *f, GCObject *t) { |
339 | assert(testobjref(g, f, t)); | ||
340 | } | ||
341 | |||
342 | |||
343 | /* | ||
344 | ** Version where 't' can be NULL. In that case, it should not apply the | ||
345 | ** macro 'obj2gco' over the object. ('t' may have several types, so this | ||
346 | ** definition must be a macro.) Most checks need this version, because | ||
347 | ** the check may run while an object is still being created. | ||
348 | */ | ||
349 | #define checkobjrefN(g,f,t) { if (t) checkobjref(g,f,obj2gco(t)); } | ||
335 | 350 | ||
336 | 351 | ||
337 | static void checkvalref (global_State *g, GCObject *f, const TValue *t) { | 352 | static void checkvalref (global_State *g, GCObject *f, const TValue *t) { |
338 | lua_assert(!iscollectable(t) || | 353 | assert(!iscollectable(t) || (righttt(t) && testobjref(g, f, gcvalue(t)))); |
339 | (righttt(t) && testobjref(g, f, gcvalue(t)))); | ||
340 | } | 354 | } |
341 | 355 | ||
342 | 356 | ||
@@ -345,14 +359,14 @@ static void checktable (global_State *g, Table *h) { | |||
345 | unsigned int asize = luaH_realasize(h); | 359 | unsigned int asize = luaH_realasize(h); |
346 | Node *n, *limit = gnode(h, sizenode(h)); | 360 | Node *n, *limit = gnode(h, sizenode(h)); |
347 | GCObject *hgc = obj2gco(h); | 361 | GCObject *hgc = obj2gco(h); |
348 | checkobjref(g, hgc, h->metatable); | 362 | checkobjrefN(g, hgc, h->metatable); |
349 | for (i = 0; i < asize; i++) | 363 | for (i = 0; i < asize; i++) |
350 | checkvalref(g, hgc, &h->array[i]); | 364 | checkvalref(g, hgc, &h->array[i]); |
351 | for (n = gnode(h, 0); n < limit; n++) { | 365 | for (n = gnode(h, 0); n < limit; n++) { |
352 | if (!isempty(gval(n))) { | 366 | if (!isempty(gval(n))) { |
353 | TValue k; | 367 | TValue k; |
354 | getnodekey(g->mainthread, &k, n); | 368 | getnodekey(g->mainthread, &k, n); |
355 | lua_assert(!keyisnil(n)); | 369 | assert(!keyisnil(n)); |
356 | checkvalref(g, hgc, &k); | 370 | checkvalref(g, hgc, &k); |
357 | checkvalref(g, hgc, gval(n)); | 371 | checkvalref(g, hgc, gval(n)); |
358 | } | 372 | } |
@@ -363,30 +377,26 @@ static void checktable (global_State *g, Table *h) { | |||
363 | static void checkudata (global_State *g, Udata *u) { | 377 | static void checkudata (global_State *g, Udata *u) { |
364 | int i; | 378 | int i; |
365 | GCObject *hgc = obj2gco(u); | 379 | GCObject *hgc = obj2gco(u); |
366 | checkobjref(g, hgc, u->metatable); | 380 | checkobjrefN(g, hgc, u->metatable); |
367 | for (i = 0; i < u->nuvalue; i++) | 381 | for (i = 0; i < u->nuvalue; i++) |
368 | checkvalref(g, hgc, &u->uv[i].uv); | 382 | checkvalref(g, hgc, &u->uv[i].uv); |
369 | } | 383 | } |
370 | 384 | ||
371 | 385 | ||
372 | /* | ||
373 | ** All marks are conditional because a GC may happen while the | ||
374 | ** prototype is still being created | ||
375 | */ | ||
376 | static void checkproto (global_State *g, Proto *f) { | 386 | static void checkproto (global_State *g, Proto *f) { |
377 | int i; | 387 | int i; |
378 | GCObject *fgc = obj2gco(f); | 388 | GCObject *fgc = obj2gco(f); |
379 | checkobjref(g, fgc, f->source); | 389 | checkobjrefN(g, fgc, f->source); |
380 | for (i=0; i<f->sizek; i++) { | 390 | for (i=0; i<f->sizek; i++) { |
381 | if (ttisstring(f->k + i)) | 391 | if (iscollectable(f->k + i)) |
382 | checkobjref(g, fgc, tsvalue(f->k + i)); | 392 | checkobjref(g, fgc, gcvalue(f->k + i)); |
383 | } | 393 | } |
384 | for (i=0; i<f->sizeupvalues; i++) | 394 | for (i=0; i<f->sizeupvalues; i++) |
385 | checkobjref(g, fgc, f->upvalues[i].name); | 395 | checkobjrefN(g, fgc, f->upvalues[i].name); |
386 | for (i=0; i<f->sizep; i++) | 396 | for (i=0; i<f->sizep; i++) |
387 | checkobjref(g, fgc, f->p[i]); | 397 | checkobjrefN(g, fgc, f->p[i]); |
388 | for (i=0; i<f->sizelocvars; i++) | 398 | for (i=0; i<f->sizelocvars; i++) |
389 | checkobjref(g, fgc, f->locvars[i].varname); | 399 | checkobjrefN(g, fgc, f->locvars[i].varname); |
390 | } | 400 | } |
391 | 401 | ||
392 | 402 | ||
@@ -401,11 +411,11 @@ static void checkCclosure (global_State *g, CClosure *cl) { | |||
401 | static void checkLclosure (global_State *g, LClosure *cl) { | 411 | static void checkLclosure (global_State *g, LClosure *cl) { |
402 | GCObject *clgc = obj2gco(cl); | 412 | GCObject *clgc = obj2gco(cl); |
403 | int i; | 413 | int i; |
404 | checkobjref(g, clgc, cl->p); | 414 | checkobjrefN(g, clgc, cl->p); |
405 | for (i=0; i<cl->nupvalues; i++) { | 415 | for (i=0; i<cl->nupvalues; i++) { |
406 | UpVal *uv = cl->upvals[i]; | 416 | UpVal *uv = cl->upvals[i]; |
407 | if (uv) { | 417 | if (uv) { |
408 | checkobjref(g, clgc, uv); | 418 | checkobjrefN(g, clgc, uv); |
409 | if (!upisopen(uv)) | 419 | if (!upisopen(uv)) |
410 | checkvalref(g, obj2gco(uv), uv->v); | 420 | checkvalref(g, obj2gco(uv), uv->v); |
411 | } | 421 | } |
@@ -428,17 +438,17 @@ static void checkstack (global_State *g, lua_State *L1) { | |||
428 | StkId o; | 438 | StkId o; |
429 | CallInfo *ci; | 439 | CallInfo *ci; |
430 | UpVal *uv; | 440 | UpVal *uv; |
431 | lua_assert(!isdead(g, L1)); | 441 | assert(!isdead(g, L1)); |
432 | if (L1->stack == NULL) { /* incomplete thread? */ | 442 | if (L1->stack == NULL) { /* incomplete thread? */ |
433 | lua_assert(L1->openupval == NULL && L1->ci == NULL); | 443 | assert(L1->openupval == NULL && L1->ci == NULL); |
434 | return; | 444 | return; |
435 | } | 445 | } |
436 | for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next) | 446 | for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next) |
437 | lua_assert(upisopen(uv)); /* must be open */ | 447 | assert(upisopen(uv)); /* must be open */ |
438 | lua_assert(L1->top <= L1->stack_last); | 448 | assert(L1->top <= L1->stack_last); |
439 | for (ci = L1->ci; ci != NULL; ci = ci->previous) { | 449 | for (ci = L1->ci; ci != NULL; ci = ci->previous) { |
440 | lua_assert(ci->top <= L1->stack_last); | 450 | assert(ci->top <= L1->stack_last); |
441 | lua_assert(lua_checkpc(ci)); | 451 | assert(lua_checkpc(ci)); |
442 | } | 452 | } |
443 | for (o = L1->stack; o < L1->stack_last; o++) | 453 | for (o = L1->stack; o < L1->stack_last; o++) |
444 | checkliveness(L1, s2v(o)); /* entire stack must have valid values */ | 454 | checkliveness(L1, s2v(o)); /* entire stack must have valid values */ |
@@ -477,10 +487,10 @@ static void checkrefs (global_State *g, GCObject *o) { | |||
477 | } | 487 | } |
478 | case LUA_VSHRSTR: | 488 | case LUA_VSHRSTR: |
479 | case LUA_VLNGSTR: { | 489 | case LUA_VLNGSTR: { |
480 | lua_assert(!isgray(o)); /* strings are never gray */ | 490 | assert(!isgray(o)); /* strings are never gray */ |
481 | break; | 491 | break; |
482 | } | 492 | } |
483 | default: lua_assert(0); | 493 | default: assert(0); |
484 | } | 494 | } |
485 | } | 495 | } |
486 | 496 | ||
@@ -499,14 +509,14 @@ static void checkrefs (global_State *g, GCObject *o) { | |||
499 | static void checkobject (global_State *g, GCObject *o, int maybedead, | 509 | static void checkobject (global_State *g, GCObject *o, int maybedead, |
500 | int listage) { | 510 | int listage) { |
501 | if (isdead(g, o)) | 511 | if (isdead(g, o)) |
502 | lua_assert(maybedead); | 512 | assert(maybedead); |
503 | else { | 513 | else { |
504 | lua_assert(g->gcstate != GCSpause || iswhite(o)); | 514 | assert(g->gcstate != GCSpause || iswhite(o)); |
505 | if (g->gckind == KGC_GEN) { /* generational mode? */ | 515 | if (g->gckind == KGC_GEN) { /* generational mode? */ |
506 | lua_assert(getage(o) >= listage); | 516 | assert(getage(o) >= listage); |
507 | lua_assert(!iswhite(o) || !isold(o)); | 517 | assert(!iswhite(o) || !isold(o)); |
508 | if (isold(o)) { | 518 | if (isold(o)) { |
509 | lua_assert(isblack(o) || | 519 | assert(isblack(o) || |
510 | getage(o) == G_TOUCHED1 || | 520 | getage(o) == G_TOUCHED1 || |
511 | getage(o) == G_OLD0 || | 521 | getage(o) == G_OLD0 || |
512 | o->tt == LUA_VTHREAD || | 522 | o->tt == LUA_VTHREAD || |
@@ -522,8 +532,8 @@ static lu_mem checkgraylist (global_State *g, GCObject *o) { | |||
522 | int total = 0; /* count number of elements in the list */ | 532 | int total = 0; /* count number of elements in the list */ |
523 | ((void)g); /* better to keep it available if we need to print an object */ | 533 | ((void)g); /* better to keep it available if we need to print an object */ |
524 | while (o) { | 534 | while (o) { |
525 | lua_assert(!!isgray(o) ^ (getage(o) == G_TOUCHED2)); | 535 | assert(!!isgray(o) ^ (getage(o) == G_TOUCHED2)); |
526 | lua_assert(!testbit(o->marked, TESTBIT)); | 536 | assert(!testbit(o->marked, TESTBIT)); |
527 | if (keepinvariant(g)) | 537 | if (keepinvariant(g)) |
528 | l_setbit(o->marked, TESTBIT); /* mark that object is in a gray list */ | 538 | l_setbit(o->marked, TESTBIT); /* mark that object is in a gray list */ |
529 | total++; | 539 | total++; |
@@ -534,10 +544,10 @@ static lu_mem checkgraylist (global_State *g, GCObject *o) { | |||
534 | case LUA_VTHREAD: o = gco2th(o)->gclist; break; | 544 | case LUA_VTHREAD: o = gco2th(o)->gclist; break; |
535 | case LUA_VPROTO: o = gco2p(o)->gclist; break; | 545 | case LUA_VPROTO: o = gco2p(o)->gclist; break; |
536 | case LUA_VUSERDATA: | 546 | case LUA_VUSERDATA: |
537 | lua_assert(gco2u(o)->nuvalue > 0); | 547 | assert(gco2u(o)->nuvalue > 0); |
538 | o = gco2u(o)->gclist; | 548 | o = gco2u(o)->gclist; |
539 | break; | 549 | break; |
540 | default: lua_assert(0); /* other objects cannot be in a gray list */ | 550 | default: assert(0); /* other objects cannot be in a gray list */ |
541 | } | 551 | } |
542 | } | 552 | } |
543 | return total; | 553 | return total; |
@@ -569,13 +579,13 @@ static void incifingray (global_State *g, GCObject *o, lu_mem *count) { | |||
569 | return; /* gray lists not being kept in these phases */ | 579 | return; /* gray lists not being kept in these phases */ |
570 | if (o->tt == LUA_VUPVAL) { | 580 | if (o->tt == LUA_VUPVAL) { |
571 | /* only open upvalues can be gray */ | 581 | /* only open upvalues can be gray */ |
572 | lua_assert(!isgray(o) || upisopen(gco2upv(o))); | 582 | assert(!isgray(o) || upisopen(gco2upv(o))); |
573 | return; /* upvalues are never in gray lists */ | 583 | return; /* upvalues are never in gray lists */ |
574 | } | 584 | } |
575 | /* these are the ones that must be in gray lists */ | 585 | /* these are the ones that must be in gray lists */ |
576 | if (isgray(o) || getage(o) == G_TOUCHED2) { | 586 | if (isgray(o) || getage(o) == G_TOUCHED2) { |
577 | (*count)++; | 587 | (*count)++; |
578 | lua_assert(testbit(o->marked, TESTBIT)); | 588 | assert(testbit(o->marked, TESTBIT)); |
579 | resetbit(o->marked, TESTBIT); /* prepare for next cycle */ | 589 | resetbit(o->marked, TESTBIT); /* prepare for next cycle */ |
580 | } | 590 | } |
581 | } | 591 | } |
@@ -588,22 +598,22 @@ static lu_mem checklist (global_State *g, int maybedead, int tof, | |||
588 | for (o = newl; o != survival; o = o->next) { | 598 | for (o = newl; o != survival; o = o->next) { |
589 | checkobject(g, o, maybedead, G_NEW); | 599 | checkobject(g, o, maybedead, G_NEW); |
590 | incifingray(g, o, &total); | 600 | incifingray(g, o, &total); |
591 | lua_assert(!tof == !tofinalize(o)); | 601 | assert(!tof == !tofinalize(o)); |
592 | } | 602 | } |
593 | for (o = survival; o != old; o = o->next) { | 603 | for (o = survival; o != old; o = o->next) { |
594 | checkobject(g, o, 0, G_SURVIVAL); | 604 | checkobject(g, o, 0, G_SURVIVAL); |
595 | incifingray(g, o, &total); | 605 | incifingray(g, o, &total); |
596 | lua_assert(!tof == !tofinalize(o)); | 606 | assert(!tof == !tofinalize(o)); |
597 | } | 607 | } |
598 | for (o = old; o != reallyold; o = o->next) { | 608 | for (o = old; o != reallyold; o = o->next) { |
599 | checkobject(g, o, 0, G_OLD1); | 609 | checkobject(g, o, 0, G_OLD1); |
600 | incifingray(g, o, &total); | 610 | incifingray(g, o, &total); |
601 | lua_assert(!tof == !tofinalize(o)); | 611 | assert(!tof == !tofinalize(o)); |
602 | } | 612 | } |
603 | for (o = reallyold; o != NULL; o = o->next) { | 613 | for (o = reallyold; o != NULL; o = o->next) { |
604 | checkobject(g, o, 0, G_OLD); | 614 | checkobject(g, o, 0, G_OLD); |
605 | incifingray(g, o, &total); | 615 | incifingray(g, o, &total); |
606 | lua_assert(!tof == !tofinalize(o)); | 616 | assert(!tof == !tofinalize(o)); |
607 | } | 617 | } |
608 | return total; | 618 | return total; |
609 | } | 619 | } |
@@ -616,16 +626,16 @@ int lua_checkmemory (lua_State *L) { | |||
616 | lu_mem totalin; /* total of objects that are in gray lists */ | 626 | lu_mem totalin; /* total of objects that are in gray lists */ |
617 | lu_mem totalshould; /* total of objects that should be in gray lists */ | 627 | lu_mem totalshould; /* total of objects that should be in gray lists */ |
618 | if (keepinvariant(g)) { | 628 | if (keepinvariant(g)) { |
619 | lua_assert(!iswhite(g->mainthread)); | 629 | assert(!iswhite(g->mainthread)); |
620 | lua_assert(!iswhite(gcvalue(&g->l_registry))); | 630 | assert(!iswhite(gcvalue(&g->l_registry))); |
621 | } | 631 | } |
622 | lua_assert(!isdead(g, gcvalue(&g->l_registry))); | 632 | assert(!isdead(g, gcvalue(&g->l_registry))); |
623 | lua_assert(g->sweepgc == NULL || issweepphase(g)); | 633 | assert(g->sweepgc == NULL || issweepphase(g)); |
624 | totalin = checkgrays(g); | 634 | totalin = checkgrays(g); |
625 | 635 | ||
626 | /* check 'fixedgc' list */ | 636 | /* check 'fixedgc' list */ |
627 | for (o = g->fixedgc; o != NULL; o = o->next) { | 637 | for (o = g->fixedgc; o != NULL; o = o->next) { |
628 | lua_assert(o->tt == LUA_VSHRSTR && isgray(o) && getage(o) == G_OLD); | 638 | assert(o->tt == LUA_VSHRSTR && isgray(o) && getage(o) == G_OLD); |
629 | } | 639 | } |
630 | 640 | ||
631 | /* check 'allgc' list */ | 641 | /* check 'allgc' list */ |
@@ -641,11 +651,11 @@ int lua_checkmemory (lua_State *L) { | |||
641 | for (o = g->tobefnz; o != NULL; o = o->next) { | 651 | for (o = g->tobefnz; o != NULL; o = o->next) { |
642 | checkobject(g, o, 0, G_NEW); | 652 | checkobject(g, o, 0, G_NEW); |
643 | incifingray(g, o, &totalshould); | 653 | incifingray(g, o, &totalshould); |
644 | lua_assert(tofinalize(o)); | 654 | assert(tofinalize(o)); |
645 | lua_assert(o->tt == LUA_VUSERDATA || o->tt == LUA_VTABLE); | 655 | assert(o->tt == LUA_VUSERDATA || o->tt == LUA_VTABLE); |
646 | } | 656 | } |
647 | if (keepinvariant(g)) | 657 | if (keepinvariant(g)) |
648 | lua_assert(totalin == totalshould); | 658 | assert(totalin == totalshould); |
649 | return 0; | 659 | return 0; |
650 | } | 660 | } |
651 | 661 | ||
@@ -1042,6 +1052,7 @@ static int tref (lua_State *L) { | |||
1042 | luaL_checkany(L, 1); | 1052 | luaL_checkany(L, 1); |
1043 | lua_pushvalue(L, 1); | 1053 | lua_pushvalue(L, 1); |
1044 | lua_pushinteger(L, luaL_ref(L, LUA_REGISTRYINDEX)); | 1054 | lua_pushinteger(L, luaL_ref(L, LUA_REGISTRYINDEX)); |
1055 | (void)level; /* to avoid warnings */ | ||
1045 | lua_assert(lua_gettop(L) == level+1); /* +1 for result */ | 1056 | lua_assert(lua_gettop(L) == level+1); /* +1 for result */ |
1046 | return 1; | 1057 | return 1; |
1047 | } | 1058 | } |
@@ -1049,6 +1060,7 @@ static int tref (lua_State *L) { | |||
1049 | static int getref (lua_State *L) { | 1060 | static int getref (lua_State *L) { |
1050 | int level = lua_gettop(L); | 1061 | int level = lua_gettop(L); |
1051 | lua_rawgeti(L, LUA_REGISTRYINDEX, luaL_checkinteger(L, 1)); | 1062 | lua_rawgeti(L, LUA_REGISTRYINDEX, luaL_checkinteger(L, 1)); |
1063 | (void)level; /* to avoid warnings */ | ||
1052 | lua_assert(lua_gettop(L) == level+1); | 1064 | lua_assert(lua_gettop(L) == level+1); |
1053 | return 1; | 1065 | return 1; |
1054 | } | 1066 | } |
@@ -1056,6 +1068,7 @@ static int getref (lua_State *L) { | |||
1056 | static int unref (lua_State *L) { | 1068 | static int unref (lua_State *L) { |
1057 | int level = lua_gettop(L); | 1069 | int level = lua_gettop(L); |
1058 | luaL_unref(L, LUA_REGISTRYINDEX, cast_int(luaL_checkinteger(L, 1))); | 1070 | luaL_unref(L, LUA_REGISTRYINDEX, cast_int(luaL_checkinteger(L, 1))); |
1071 | (void)level; /* to avoid warnings */ | ||
1059 | lua_assert(lua_gettop(L) == level); | 1072 | lua_assert(lua_gettop(L) == level); |
1060 | return 0; | 1073 | return 0; |
1061 | } | 1074 | } |
@@ -1724,6 +1737,7 @@ static struct X { int x; } x; | |||
1724 | else if EQ("tostring") { | 1737 | else if EQ("tostring") { |
1725 | const char *s = lua_tostring(L1, getindex); | 1738 | const char *s = lua_tostring(L1, getindex); |
1726 | const char *s1 = lua_pushstring(L1, s); | 1739 | const char *s1 = lua_pushstring(L1, s); |
1740 | (void)s1; /* to avoid warnings */ | ||
1727 | lua_longassert((s == NULL && s1 == NULL) || strcmp(s, s1) == 0); | 1741 | lua_longassert((s == NULL && s1 == NULL) || strcmp(s, s1) == 0); |
1728 | } | 1742 | } |
1729 | else if EQ("type") { | 1743 | else if EQ("type") { |
@@ -1937,15 +1951,15 @@ static void checkfinalmem (void) { | |||
1937 | 1951 | ||
1938 | int luaB_opentests (lua_State *L) { | 1952 | int luaB_opentests (lua_State *L) { |
1939 | void *ud; | 1953 | void *ud; |
1954 | lua_Alloc f = lua_getallocf(L, &ud); | ||
1940 | lua_atpanic(L, &tpanic); | 1955 | lua_atpanic(L, &tpanic); |
1941 | lua_setwarnf(L, &warnf, L); | 1956 | lua_setwarnf(L, &warnf, L); |
1942 | lua_pushboolean(L, 0); | 1957 | lua_pushboolean(L, 0); |
1943 | lua_setglobal(L, "_WARN"); /* _WARN = false */ | 1958 | lua_setglobal(L, "_WARN"); /* _WARN = false */ |
1944 | regcodes(L); | 1959 | regcodes(L); |
1945 | atexit(checkfinalmem); | 1960 | atexit(checkfinalmem); |
1946 | lua_assert(lua_getallocf(L, &ud) == debug_realloc); | 1961 | lua_assert(f == debug_realloc && ud == cast_voidp(&l_memcontrol)); |
1947 | lua_assert(ud == cast_voidp(&l_memcontrol)); | 1962 | lua_setallocf(L, f, ud); /* exercise this function */ |
1948 | lua_setallocf(L, lua_getallocf(L, NULL), ud); | ||
1949 | luaL_newlib(L, tests_funcs); | 1963 | luaL_newlib(L, tests_funcs); |
1950 | return 1; | 1964 | return 1; |
1951 | } | 1965 | } |