Find lua variables and global variables

First, start with the hello world

When performing print ( "Hello World!"), Which is obviously the need to perform a specific function prints a string to standard output, so here is related to the first problem is to find a function, and that is how the string the corresponding function linked. In the most common C language, this look is completed by the linker: it looks for the definition of this function from all the obj file and then convert this place into a CPU call instruction corresponding position. Correspondingly, for lua, this method also need to have real strings and function calls linked. Then the final question is: When lua encounters a variable, the variable is how to find it?

Second, look for implementation

1, find the code that implements

This code implementation is relatively straightforward: First, look at the function level of Local, if the find is considered to be VLOCAL type, or else find upvalue current function already exists, believed to be the last default in the global variable table. This "global" level is very high, the equivalent of the entire lua virtual machines share, which is a global variable.
The reason these variables to determine the type of instruction that they will affect the generation, and different instructions will indicate where to look for variables.
5.3.4-Lua \ the src \ lparser.c
/ *
the Find GIVEN variable name with 'n-'. IT IS AN the If an upvalue, the Add the this
an upvalue INTO All Intermediate Functions.
* /
static void singlevaraux (FuncState * FS, n-TString *, * var expdesc, int Base) {
IF (FS == NULL) / * NO More Levels * /?
init_exp (var, VVOID, 0); / * Global default IS * /
the else {
int = V searchvar (FS, n-) ; / * look up about locals AT Current Level * /
IF (v> = 0) {/ * found * /?
init_exp (var, Vlocal, v); / * local variable IS * /
IF (Base!)
markupval(fs, v); /* local will be used as an upval */
}
else { /* not found as local at current level; try upvalues */
int idx = searchupvalue(fs, n); /* try existing upvalues */
if (idx < 0) { /* not found? */
singlevaraux(fs->prev, n, var, 0); /* try upper levels */
if (var->k == VVOID) /* not found? */
return; /* it is a global */
/* else was LOCAL or UPVAL */
idx = newupvalue(fs, n, var); /* will be a new upvalue */
}
init_exp(var, VUPVAL, idx); /* new or old upvalue */
}
}
}

2, a process flow Local variables

In the following code as an example:
local A, B, C = l, 2,3
executed first is a function of the do while {} (testnext (ls , ',')) cycle, this is equivalent to the function register locvars variable, but it will also be a position where a determined position.
static void localstat (LexState * LS) {
/ * STAT -> the LOCAL NAME { ',' NAME} [ '=' explist] * /
int nvars = 0;
int nexps;
expdesc E;
do {
new_localvar (LS, str_checkname (LS ));
nvars ++;
} the while (testnext (LS, ','));
IF (testnext (LS, '='))
nexps = explist (LS, & E);
the else {
EK = VVOID;
nexps = 0;
}
adjust_assign (LS, nvars, nexps, & E);
adjustlocalvars (LS, nvars);
}

3, the processing for the global variable

For a variable g, and if not found, the local upvalue in that the lookup is considered to use from the global variable named env string, and is a key register allocation is to find the global variable is also necessary to use the function luaK_indexed register.
void singlevar static (LexState * LS, expdesc * var) {
TString * varname = str_checkname (LS);
FuncState * FS = LS-> FS;
singlevaraux (FS, varname, var,. 1);
IF (VAR-> == K VVOID) {/ * Global name * /?
expdesc Key;
singlevaraux (FS, LS-> envn, var,. 1); / * GET Environment variable * /
! lua_assert (VAR-> K = VVOID); / * the this One MUST * exist /
codeString (LS, & Key, varname); / * * Key IS variable name /
luaK_indexed (FS, var, & Key); / * the env [varname] * /
}
}

Third, look for the print function

1, the function call resolution

Since print is not found locally to the symbols, the code required to generate the lookup from the env, so long as the running string variables to the global variable table.

2, the registration system functions

print due to internal lua call the function parameter is a state machine (this advantage is that when you call a function pointer, this type of function pointers is clear), it is the custom luaB_print function.

LUAMOD_API int luaopen_base (lua_State *L) {
/* open lib into global table */
lua_pushglobaltable(L);
luaL_setfuncs(L, base_funcs, 0);
/* set global _G */
lua_pushvalue(L, -1);
lua_setfield(L, -2, "_G");
/* set global _VERSION */
lua_pushliteral(L, LUA_VERSION);
lua_setfield(L, -2, "_VERSION");
return 1;
}

3, the system registry settings

LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
const char *chunkname, const char *mode) {
ZIO z;
int status;
lua_lock(L);
if (!chunkname) chunkname = "?";
luaZ_init(L, &z, reader, data);
status = luaD_protectedparser(L, &z, chunkname, mode);
if (status == LUA_OK) { /* no errors? */
LClosure *f = clLvalue(L->top - 1); /* get newly created function */
if (f->nupvalues >= 1) { /* does it have an upvalue? */
/* get global table from registry */
Table *reg = hvalue(&G(L)->l_registry);
const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
setobj(L, f->upvals[0]->v, gt);
luaC_upvalbarrier(L, f->upvals[0]);
}
}
lua_unlock(L);
return status;
}

 

Guess you like

Origin www.cnblogs.com/tsecer/p/11493487.html