diff options
Diffstat (limited to 'ltests.c')
-rw-r--r-- | ltests.c | 97 |
1 files changed, 75 insertions, 22 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 1.143 2002/11/14 15:41:38 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 1.144 2002/11/14 16:59:16 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -56,15 +56,25 @@ static void setnameval (lua_State *L, const char *name, int val) { | |||
56 | ** ======================================================================= | 56 | ** ======================================================================= |
57 | */ | 57 | */ |
58 | 58 | ||
59 | |||
60 | /* ensures maximum alignment for HEADER */ | ||
61 | #define HEADER (sizeof(L_Umaxalign)) | ||
62 | |||
63 | #define MARKSIZE 8 | ||
64 | #define MARK 0x55 /* 01010101 (a nice pattern) */ | 59 | #define MARK 0x55 /* 01010101 (a nice pattern) */ |
65 | 60 | ||
66 | 61 | #ifndef EXTERNMEMCHECK | |
67 | #define blocksize(b) (cast(size_t *, cast(char *, b) - HEADER)) | 62 | /* full memory check */ |
63 | #define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */ | ||
64 | #define MARKSIZE 16 /* size of marks after each block */ | ||
65 | #define blockhead(b) (cast(char *, b) - HEADER) | ||
66 | #define setsize(newblock, size) (*cast(size_t *, newblock) = size) | ||
67 | #define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b)))) | ||
68 | #define fillmem(mem,size) memset(mem, -MARK, size) | ||
69 | #else | ||
70 | /* external memory check: don't do it twice */ | ||
71 | #define HEADER 0 | ||
72 | #define MARKSIZE 0 | ||
73 | #define blockhead(b) (b) | ||
74 | #define setsize(newblock, size) /* empty */ | ||
75 | #define checkblocksize(b,size) (1) | ||
76 | #define fillmem(mem,size) /* empty */ | ||
77 | #endif | ||
68 | 78 | ||
69 | unsigned long memdebug_numblocks = 0; | 79 | unsigned long memdebug_numblocks = 0; |
70 | unsigned long memdebug_total = 0; | 80 | unsigned long memdebug_total = 0; |
@@ -72,9 +82,8 @@ unsigned long memdebug_maxmem = 0; | |||
72 | unsigned long memdebug_memlimit = ULONG_MAX; | 82 | unsigned long memdebug_memlimit = ULONG_MAX; |
73 | 83 | ||
74 | 84 | ||
75 | static void *checkblock (void *block) { | 85 | static void *checkblock (void *block, size_t size) { |
76 | size_t *b = blocksize(block); | 86 | void *b = blockhead(block); |
77 | size_t size = *b; | ||
78 | int i; | 87 | int i; |
79 | for (i=0;i<MARKSIZE;i++) | 88 | for (i=0;i<MARKSIZE;i++) |
80 | lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */ | 89 | lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */ |
@@ -82,11 +91,11 @@ static void *checkblock (void *block) { | |||
82 | } | 91 | } |
83 | 92 | ||
84 | 93 | ||
85 | static void freeblock (void *block) { | 94 | static void freeblock (void *block, size_t size) { |
86 | if (block) { | 95 | if (block) { |
87 | size_t size = *blocksize(block); | 96 | lua_assert(checkblocksize(block, size)); |
88 | block = checkblock(block); | 97 | block = checkblock(block, size); |
89 | memset(block, -1, size+HEADER+MARKSIZE); /* erase block */ | 98 | fillmem(block, size+HEADER+MARKSIZE); /* erase block */ |
90 | free(block); /* free original block */ | 99 | free(block); /* free original block */ |
91 | memdebug_numblocks--; | 100 | memdebug_numblocks--; |
92 | memdebug_total -= size; | 101 | memdebug_total -= size; |
@@ -95,11 +104,11 @@ static void freeblock (void *block) { | |||
95 | 104 | ||
96 | 105 | ||
97 | void *debug_realloc (void *block, size_t oldsize, size_t size) { | 106 | void *debug_realloc (void *block, size_t oldsize, size_t size) { |
98 | lua_assert(oldsize == 0 || oldsize == *blocksize(block)); | 107 | lua_assert(oldsize == 0 || checkblocksize(block, oldsize)); |
99 | /* ISO does not specify what realloc(NULL, 0) does */ | 108 | /* ISO does not specify what realloc(NULL, 0) does */ |
100 | lua_assert(block != NULL || size > 0); | 109 | lua_assert(block != NULL || size > 0); |
101 | if (size == 0) { | 110 | if (size == 0) { |
102 | freeblock(block); | 111 | freeblock(block, oldsize); |
103 | return NULL; | 112 | return NULL; |
104 | } | 113 | } |
105 | else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit) | 114 | else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit) |
@@ -108,21 +117,21 @@ void *debug_realloc (void *block, size_t oldsize, size_t size) { | |||
108 | void *newblock; | 117 | void *newblock; |
109 | int i; | 118 | int i; |
110 | size_t realsize = HEADER+size+MARKSIZE; | 119 | size_t realsize = HEADER+size+MARKSIZE; |
120 | size_t commonsize = (oldsize < size) ? oldsize : size; | ||
111 | if (realsize < size) return NULL; /* overflow! */ | 121 | if (realsize < size) return NULL; /* overflow! */ |
112 | newblock = malloc(realsize); /* alloc a new block */ | 122 | newblock = malloc(realsize); /* alloc a new block */ |
113 | if (newblock == NULL) return NULL; | 123 | if (newblock == NULL) return NULL; |
114 | if (oldsize > size) oldsize = size; | ||
115 | if (block) { | 124 | if (block) { |
116 | memcpy(cast(char *, newblock)+HEADER, block, oldsize); | 125 | memcpy(cast(char *, newblock)+HEADER, block, commonsize); |
117 | freeblock(block); /* erase (and check) old copy */ | 126 | freeblock(block, oldsize); /* erase (and check) old copy */ |
118 | } | 127 | } |
119 | /* initialize new part of the block with something `weird' */ | 128 | /* initialize new part of the block with something `weird' */ |
120 | memset(cast(char *, newblock)+HEADER+oldsize, -MARK, size-oldsize); | 129 | fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize); |
121 | memdebug_total += size; | 130 | memdebug_total += size; |
122 | if (memdebug_total > memdebug_maxmem) | 131 | if (memdebug_total > memdebug_maxmem) |
123 | memdebug_maxmem = memdebug_total; | 132 | memdebug_maxmem = memdebug_total; |
124 | memdebug_numblocks++; | 133 | memdebug_numblocks++; |
125 | *cast(size_t *, newblock) = size; | 134 | setsize(newblock, size); |
126 | for (i=0;i<MARKSIZE;i++) | 135 | for (i=0;i<MARKSIZE;i++) |
127 | *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i); | 136 | *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i); |
128 | return cast(char *, newblock)+HEADER; | 137 | return cast(char *, newblock)+HEADER; |
@@ -681,6 +690,48 @@ static int testC (lua_State *L) { | |||
681 | /* }====================================================== */ | 690 | /* }====================================================== */ |
682 | 691 | ||
683 | 692 | ||
693 | /* | ||
694 | ** {====================================================== | ||
695 | ** tests for yield inside hooks | ||
696 | ** ======================================================= | ||
697 | */ | ||
698 | |||
699 | static void yieldf (lua_State *L, lua_Debug *ar) { | ||
700 | lua_yield(L, 0); | ||
701 | } | ||
702 | |||
703 | static int setyhook (lua_State *L) { | ||
704 | if (lua_isnoneornil(L, 1)) | ||
705 | lua_sethook(L, NULL, 0); /* turn off hooks */ | ||
706 | else { | ||
707 | const char *smask = luaL_checkstring(L, 1); | ||
708 | unsigned long count = LUA_MASKCOUNT(luaL_optint(L, 2, 0)); | ||
709 | if (strchr(smask, 'l')) count |= LUA_MASKLINE; | ||
710 | lua_sethook(L, yieldf, count); | ||
711 | } | ||
712 | return 0; | ||
713 | } | ||
714 | |||
715 | |||
716 | static int coresume (lua_State *L) { | ||
717 | int status; | ||
718 | lua_State *co = lua_tothread(L, 1); | ||
719 | luaL_argcheck(L, co, 1, "coroutine expected"); | ||
720 | status = lua_resume(co, 0); | ||
721 | if (status != 0) { | ||
722 | lua_pushboolean(L, 0); | ||
723 | lua_insert(L, -2); | ||
724 | return 2; /* return false + error message */ | ||
725 | } | ||
726 | else { | ||
727 | lua_pushboolean(L, 1); | ||
728 | return 1; | ||
729 | } | ||
730 | } | ||
731 | |||
732 | /* }====================================================== */ | ||
733 | |||
734 | |||
684 | 735 | ||
685 | static const struct luaL_reg tests_funcs[] = { | 736 | static const struct luaL_reg tests_funcs[] = { |
686 | {"hash", hash_query}, | 737 | {"hash", hash_query}, |
@@ -709,6 +760,8 @@ static const struct luaL_reg tests_funcs[] = { | |||
709 | {"doremote", doremote}, | 760 | {"doremote", doremote}, |
710 | {"log2", log2_aux}, | 761 | {"log2", log2_aux}, |
711 | {"totalmem", mem_query}, | 762 | {"totalmem", mem_query}, |
763 | {"resume", coresume}, | ||
764 | {"setyhook", setyhook}, | ||
712 | {NULL, NULL} | 765 | {NULL, NULL} |
713 | }; | 766 | }; |
714 | 767 | ||