📄 ltests.c
字号:
/*** $Id: ltests.c,v 1.1 2005/04/12 17:17:27 tlopatic Exp $** Internal Module for Debugging of the Lua Implementation** See Copyright Notice in lua.h*/#include <ctype.h>#include <limits.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#define ltests_c#include "lua.h"#include "lapi.h"#include "lauxlib.h"#include "lcode.h"#include "ldebug.h"#include "ldo.h"#include "lfunc.h"#include "lmem.h"#include "lopcodes.h"#include "lstate.h"#include "lstring.h"#include "ltable.h"#include "lualib.h"/*** The whole module only makes sense with LUA_DEBUG on*/#ifdef LUA_DEBUG#define lua_pushintegral(L,i) lua_pushnumber(L, cast(lua_Number, (i)))static lua_State *lua_state = NULL;int islocked = 0;#define func_at(L,k) (L->ci->base+(k) - 1)static void setnameval (lua_State *L, const char *name, int val) { lua_pushstring(L, name); lua_pushintegral(L, val); lua_settable(L, -3);}/*** {======================================================================** Controlled version for realloc.** =======================================================================*/#define MARK 0x55 /* 01010101 (a nice pattern) */#ifndef EXTERNMEMCHECK/* full memory check */#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */#define MARKSIZE 16 /* size of marks after each block */#define blockhead(b) (cast(char *, b) - HEADER)#define setsize(newblock, size) (*cast(size_t *, newblock) = size)#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b))))#define fillmem(mem,size) memset(mem, -MARK, size)#else/* external memory check: don't do it twice */#define HEADER 0#define MARKSIZE 0#define blockhead(b) (b)#define setsize(newblock, size) /* empty */#define checkblocksize(b,size) (1)#define fillmem(mem,size) /* empty */#endifunsigned long memdebug_numblocks = 0;unsigned long memdebug_total = 0;unsigned long memdebug_maxmem = 0;unsigned long memdebug_memlimit = ULONG_MAX;static void *checkblock (void *block, size_t size) { void *b = blockhead(block); int i; for (i=0;i<MARKSIZE;i++) lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */ return b;}static void freeblock (void *block, size_t size) { if (block) { lua_assert(checkblocksize(block, size)); block = checkblock(block, size); fillmem(block, size+HEADER+MARKSIZE); /* erase block */ free(block); /* free original block */ memdebug_numblocks--; memdebug_total -= size; }}void *debug_realloc (void *block, size_t oldsize, size_t size) { lua_assert(oldsize == 0 || checkblocksize(block, oldsize)); /* ISO does not specify what realloc(NULL, 0) does */ lua_assert(block != NULL || size > 0); if (size == 0) { freeblock(block, oldsize); return NULL; } else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit) return NULL; /* to test memory allocation errors */ else { void *newblock; int i; size_t realsize = HEADER+size+MARKSIZE; size_t commonsize = (oldsize < size) ? oldsize : size; if (realsize < size) return NULL; /* overflow! */ newblock = malloc(realsize); /* alloc a new block */ if (newblock == NULL) return NULL; if (block) { memcpy(cast(char *, newblock)+HEADER, block, commonsize); freeblock(block, oldsize); /* erase (and check) old copy */ } /* initialize new part of the block with something `weird' */ fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize); memdebug_total += size; if (memdebug_total > memdebug_maxmem) memdebug_maxmem = memdebug_total; memdebug_numblocks++; setsize(newblock, size); for (i=0;i<MARKSIZE;i++) *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i); return cast(char *, newblock)+HEADER; }}/* }====================================================================== *//*** {======================================================** Disassembler** =======================================================*/static char *buildop (Proto *p, int pc, char *buff) { Instruction i = p->code[pc]; OpCode o = GET_OPCODE(i); const char *name = luaP_opnames[o]; int line = getline(p, pc); sprintf(buff, "(%4d) %4d - ", line, pc); switch (getOpMode(o)) { case iABC: sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name, GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case iABx: sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i)); break; case iAsBx: sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i)); break; } return buff;}#if 0void luaI_printcode (Proto *pt, int size) { int pc; for (pc=0; pc<size; pc++) { char buff[100]; printf("%s\n", buildop(pt, pc, buff)); } printf("-------\n");}#endifstatic int listcode (lua_State *L) { int pc; Proto *p; luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, "Lua function expected"); p = clvalue(func_at(L, 1))->l.p; lua_newtable(L); setnameval(L, "maxstack", p->maxstacksize); setnameval(L, "numparams", p->numparams); for (pc=0; pc<p->sizecode; pc++) { char buff[100]; lua_pushintegral(L, pc+1); lua_pushstring(L, buildop(p, pc, buff)); lua_settable(L, -3); } return 1;}static int listk (lua_State *L) { Proto *p; int i; luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, "Lua function expected"); p = clvalue(func_at(L, 1))->l.p; lua_newtable(L); for (i=0; i<p->sizek; i++) { lua_pushintegral(L, i+1); luaA_pushobject(L, p->k+i); lua_settable(L, -3); } return 1;}static int listlocals (lua_State *L) { Proto *p; int pc = luaL_checkint(L, 2) - 1; int i = 0; const char *name; luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, "Lua function expected"); p = clvalue(func_at(L, 1))->l.p; while ((name = luaF_getlocalname(p, ++i, pc)) != NULL) lua_pushstring(L, name); return i-1;}/* }====================================================== */static int get_limits (lua_State *L) { lua_newtable(L); setnameval(L, "BITS_INT", BITS_INT); setnameval(L, "LFPF", LFIELDS_PER_FLUSH); setnameval(L, "MAXVARS", MAXVARS); setnameval(L, "MAXPARAMS", MAXPARAMS); setnameval(L, "MAXSTACK", MAXSTACK); setnameval(L, "MAXUPVALUES", MAXUPVALUES); return 1;}static int mem_query (lua_State *L) { if (lua_isnone(L, 1)) { lua_pushintegral(L, memdebug_total); lua_pushintegral(L, memdebug_numblocks); lua_pushintegral(L, memdebug_maxmem); return 3; } else { memdebug_memlimit = luaL_checkint(L, 1); return 0; }}static int hash_query (lua_State *L) { if (lua_isnone(L, 2)) { luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected"); lua_pushintegral(L, tsvalue(func_at(L, 1))->tsv.hash); } else { TObject *o = func_at(L, 1); Table *t; luaL_checktype(L, 2, LUA_TTABLE); t = hvalue(func_at(L, 2)); lua_pushintegral(L, luaH_mainposition(t, o) - t->node); } return 1;}static int stacklevel (lua_State *L) { unsigned long a = 0; lua_pushintegral(L, (int)(L->top - L->stack)); lua_pushintegral(L, (int)(L->stack_last - L->stack)); lua_pushintegral(L, (int)(L->ci - L->base_ci)); lua_pushintegral(L, (int)(L->end_ci - L->base_ci)); lua_pushintegral(L, (unsigned long)&a); return 5;}static int table_query (lua_State *L) { const Table *t; int i = luaL_optint(L, 2, -1); luaL_checktype(L, 1, LUA_TTABLE); t = hvalue(func_at(L, 1)); if (i == -1) { lua_pushintegral(L, t->sizearray); lua_pushintegral(L, sizenode(t)); lua_pushintegral(L, t->firstfree - t->node); } else if (i < t->sizearray) { lua_pushintegral(L, i); luaA_pushobject(L, &t->array[i]); lua_pushnil(L); } else if ((i -= t->sizearray) < sizenode(t)) { if (!ttisnil(gval(gnode(t, i))) || ttisnil(gkey(gnode(t, i))) || ttisnumber(gkey(gnode(t, i)))) { luaA_pushobject(L, gkey(gnode(t, i))); } else lua_pushstring(L, "<undef>"); luaA_pushobject(L, gval(gnode(t, i))); if (t->node[i].next) lua_pushintegral(L, t->node[i].next - t->node); else lua_pushnil(L); } return 3;}static int string_query (lua_State *L) { stringtable *tb = &G(L)->strt; int s = luaL_optint(L, 2, 0) - 1; if (s==-1) { lua_pushintegral(L ,tb->nuse); lua_pushintegral(L ,tb->size); return 2; } else if (s < tb->size) { GCObject *ts; int n = 0; for (ts = tb->hash[s]; ts; ts = ts->gch.next) { setsvalue2s(L->top, gcotots(ts)); incr_top(L); n++; } return n; } return 0;}static int tref (lua_State *L) { int level = lua_gettop(L); int lock = luaL_optint(L, 2, 1); luaL_checkany(L, 1); lua_pushvalue(L, 1); lua_pushintegral(L, lua_ref(L, lock)); assert(lua_gettop(L) == level+1); /* +1 for result */ return 1;}static int getref (lua_State *L) { int level = lua_gettop(L); lua_getref(L, luaL_checkint(L, 1)); assert(lua_gettop(L) == level+1); return 1;}static int unref (lua_State *L) { int level = lua_gettop(L); lua_unref(L, luaL_checkint(L, 1)); assert(lua_gettop(L) == level); return 0;}static int metatable (lua_State *L) { luaL_checkany(L, 1); if (lua_isnone(L, 2)) { if (lua_getmetatable(L, 1) == 0) lua_pushnil(L); } else { lua_settop(L, 2); luaL_checktype(L, 2, LUA_TTABLE); lua_setmetatable(L, 1); } return 1;}static int upvalue (lua_State *L) { int n = luaL_checkint(L, 2); luaL_checktype(L, 1, LUA_TFUNCTION); if (lua_isnone(L, 3)) { const char *name = lua_getupvalue(L, 1, n); if (name == NULL) return 0; lua_pushstring(L, name); return 2; } else { const char *name = lua_setupvalue(L, 1, n); lua_pushstring(L, name); return 1; }}static int newuserdata (lua_State *L) { size_t size = luaL_checkint(L, 1); char *p = cast(char *, lua_newuserdata(L, size)); while (size--) *p++ = '\0'; return 1;}static int pushuserdata (lua_State *L) { lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1))); return 1;}static int udataval (lua_State *L) { lua_pushintegral(L, cast(int, lua_touserdata(L, 1))); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -