aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-02-22 11:31:19 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-02-22 11:31:19 -0200
commit39e1f079bdf045d64ad6f1b5da1eb48cc79c6c38 (patch)
tree4292e586fe67b34ade50c66bfcb6b8ef59072a4c /lcode.c
parent075da266e53868ae78dc4eebf8675592d312a67d (diff)
downloadlua-39e1f079bdf045d64ad6f1b5da1eb48cc79c6c38.tar.gz
lua-39e1f079bdf045d64ad6f1b5da1eb48cc79c6c38.tar.bz2
lua-39e1f079bdf045d64ad6f1b5da1eb48cc79c6c38.zip
code generator (and optimizer) for Lua
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/lcode.c b/lcode.c
new file mode 100644
index 00000000..c6162f6f
--- /dev/null
+++ b/lcode.c
@@ -0,0 +1,96 @@
1/*
2** $Id: $
3** Code generator for Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#include "lcode.h"
9#include "llex.h"
10#include "lmem.h"
11#include "lobject.h"
12#include "lopcodes.h"
13#include "lparser.h"
14
15
16static Instruction *last_i (FuncState *fs) {
17 static Instruction dummy = SET_OPCODE(0, ENDCODE);
18 if (fs->last_pc < 0)
19 return &dummy;
20 else
21 return &fs->f->code[fs->last_pc];
22}
23
24
25int luaK_primitivecode (LexState *ls, Instruction i) {
26 FuncState *fs = ls->fs;
27 luaM_growvector(ls->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAXARG_S);
28 fs->f->code[fs->pc] = i;
29 return fs->pc++;
30}
31
32
33
34int luaK_code (LexState *ls, Instruction i) {
35 FuncState *fs = ls->fs;
36 Instruction *last = last_i(fs);
37 switch (GET_OPCODE(i)) {
38
39 case MINUSOP:
40 switch(GET_OPCODE(*last)) {
41 case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); break;
42 case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); break;
43 case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); break;
44 default: fs->last_pc = luaK_primitivecode(ls, i);
45 }
46 break;
47
48 case GETTABLE:
49 switch(GET_OPCODE(*last)) {
50 case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break;
51 default: fs->last_pc = luaK_primitivecode(ls, i);
52 }
53 break;
54
55 case RETCODE:
56 switch(GET_OPCODE(*last)) {
57 case CALL:
58 *last = SET_OPCODE(*last, TAILCALL);
59 *last = SETARG_B(*last, GETARG_U(i));
60 break;
61 default: fs->last_pc = luaK_primitivecode(ls, i);
62 }
63 break;
64
65 case ADDOP:
66 switch(GET_OPCODE(*last)) {
67 case PUSHINT: *last = SET_OPCODE(*last, ADDI); break;
68 default: fs->last_pc = luaK_primitivecode(ls, i);
69 }
70 break;
71
72 case SUBOP:
73 switch(GET_OPCODE(*last)) {
74 case PUSHINT:
75 *last = SET_OPCODE(*last, ADDI);
76 *last = SETARG_S(*last, -GETARG_S(*last));
77 break;
78 default: fs->last_pc = luaK_primitivecode(ls, i);
79 }
80 break;
81
82 default: fs->last_pc = luaK_primitivecode(ls, i);
83 }
84 return fs->last_pc;
85}
86
87
88void luaK_fixjump (LexState *ls, int pc, int dest) {
89 FuncState *fs = ls->fs;
90 Instruction *jmp = &fs->f->code[pc];
91 /* jump is relative to position following jump instruction */
92 *jmp = SETARG_S(*jmp, dest-(pc+1));
93 fs->last_pc = pc;
94}
95
96