Now the do_dump function in luac. C is analyzed for the relevant part of the compiler.
There are two main types of calls in this function, storing bytecode and printing bytecode.
Let's take a look at printing byte. to print the bytecode, You need to include the "-l" option in the command line option of the compiler.
static void do_dump(TFunc* tf) /* only for tf==main */{ if (dumping) DumpHeader(D); while (tf!=NULL) { TFunc* nf; if (listing) PrintFunction(tf); if (dumping) DumpFunction(tf,D); nf=tf->next; /* list only built after first main */ luaI_freefunc(tf); tf=nf; }}
The print bytecode calls the printfunction above. It can be seen that it is controlled by the listing condition, and the listing value is 1 only when the "-l" option is available in the command line.
In actual use, it is found that there is a small error. When the-P-l option is used simultaneously (only syntax analysis is performed without dumping bytecode), printfunction is called only once, that is, only the bytecode of the main function is printed, the bytecode of other custom functions will not be printed. When the-P option is removed (that is, the bytecode is also stored to the default output luac. Out file), it is normal.
For example, for the following Lua script:
function add(x, y) return x + yendprint (add(3, 4))
When you run it with-P-l, the output is as follows:
Main of "test. Lua" (25 bytes at 00602090)
0 pushfunction 00602120; "test. Lua": 1
5 storeglobal 13; add
8 pushglobal 7; print
11 pushglobal 13; add
14 pushbyte 3
16 pushbyte 4
18 callfunc 2 1
21 callfunc 1 0
24 retcode0
Strange: Where does function add go?
When you run it with-L, the output is as follows:
Main of "test. Lua" (25 bytes at 001120d8)
0 pushfunction 00112168; "test. Lua": 1
5 storeglobal 13; add
8 pushglobal 7; print
11 pushglobal 13; add
14 pushbyte 3
16 pushbyte 4
18 callfunc 2 1
21 callfunc 1 0
24 retcode0
Function "test. Lua": 1 (9 bytes at 00112168); used at main + 1
0 adjust 2
2 pushlocal0 0;
3 pushlocal1 1;
4 addop
5 retcode 2
7 retcode 2
See it. Here the bytecode of the add function is added.
Why? It should have been a program error.
After analysis, it is found that when the-P option is available, it is better to set TF-> next in do_dump code to null without the-P option. After debugging, we found that, after dumpfunction is executed, TF-> next is assigned a value, and the following sentence is found in threadcode in dumpfunction:
case PUSHFUNCTION: { CodeCode c; p++; get_code(c,p); c.tf->marked=at; c.tf->next=NULL; /* TODO: remove? */ lastF=lastF->next=c.tf; break; }
When the-P option is available, the above sentence is not executed, So TF-> next is not assigned a value, and the printed bytecode above cannot print the bytecode added by the function.
Normally, the main function and all functions defined in the Lua script are compiled to form a tfunc chain. The function bytecode is included in the tfunc code field.
Print. h defines the name array of A bytecode instruction, which is used when printing bytecode.
Check the printfunction code.
void PrintFunction(TFunc* tf){ if (IsMain(tf)) printf("\nmain of \"%s\" (%d bytes at %p)\n",tf->fileName,tf->size,tf); else printf("\nfunction \"%s\":%d (%d bytes at %p); used at main+%d\n", tf->fileName,tf->lineDefined,tf->size,tf,tf->marked); V=tf->locvars; PrintCode(tf->code,tf->code+tf->size);}
The description information printed by the main function is different from that printed by the user-defined function. The ismain macro is used to determine whether it is the main function.
# Define ismain (f) (F-> linedefined = 0)
The user-defined function must have a value greater than 0, and the main function is set to 0.
Then, call printcode to print the bytecode command.
static void PrintCode(Byte* code, Byte* end){ Byte* p; for (p=code; p!=end;) { OpCode op=(OpCode)*p; if (op>SETLINE) op=SETLINE+1; printf("%6d\t%s",p-code,OpCodeName[op]); switch (op) {/*cases and other codes*/}}}
The position and name of the print command, that is, printf.
If the command is invalid, OP> setline will print an empty string. Because the next string in the opcodename array "setline" is an empty string "".
Next, a switch case prints some other data-related information in other commands. Including the data part of the instruction and the string-related part used. Comparing the printed bytecode, you can easily see the intention of the Code, this part is equivalent to a simple parsing of bytecode (that is, a simple comparison with the real execution of bytecode in the virtual machine ). Therefore, we will not perform a row-based analysis on it.
----------------------------------------
So far:
> What are the dump-related methods called in the do_dump method?
----------------------------------------
Lua2.4 print the bytecode print. c