|
@@ -0,0 +1,96 @@
|
|
|
+/*
|
|
|
+** $Id: $
|
|
|
+** Code generator for Lua
|
|
|
+** See Copyright Notice in lua.h
|
|
|
+*/
|
|
|
+
|
|
|
+
|
|
|
+#include "lcode.h"
|
|
|
+#include "llex.h"
|
|
|
+#include "lmem.h"
|
|
|
+#include "lobject.h"
|
|
|
+#include "lopcodes.h"
|
|
|
+#include "lparser.h"
|
|
|
+
|
|
|
+
|
|
|
+static Instruction *last_i (FuncState *fs) {
|
|
|
+ static Instruction dummy = SET_OPCODE(0, ENDCODE);
|
|
|
+ if (fs->last_pc < 0)
|
|
|
+ return &dummy;
|
|
|
+ else
|
|
|
+ return &fs->f->code[fs->last_pc];
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int luaK_primitivecode (LexState *ls, Instruction i) {
|
|
|
+ FuncState *fs = ls->fs;
|
|
|
+ luaM_growvector(ls->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAXARG_S);
|
|
|
+ fs->f->code[fs->pc] = i;
|
|
|
+ return fs->pc++;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int luaK_code (LexState *ls, Instruction i) {
|
|
|
+ FuncState *fs = ls->fs;
|
|
|
+ Instruction *last = last_i(fs);
|
|
|
+ switch (GET_OPCODE(i)) {
|
|
|
+
|
|
|
+ case MINUSOP:
|
|
|
+ switch(GET_OPCODE(*last)) {
|
|
|
+ case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); break;
|
|
|
+ case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); break;
|
|
|
+ case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); break;
|
|
|
+ default: fs->last_pc = luaK_primitivecode(ls, i);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case GETTABLE:
|
|
|
+ switch(GET_OPCODE(*last)) {
|
|
|
+ case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break;
|
|
|
+ default: fs->last_pc = luaK_primitivecode(ls, i);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case RETCODE:
|
|
|
+ switch(GET_OPCODE(*last)) {
|
|
|
+ case CALL:
|
|
|
+ *last = SET_OPCODE(*last, TAILCALL);
|
|
|
+ *last = SETARG_B(*last, GETARG_U(i));
|
|
|
+ break;
|
|
|
+ default: fs->last_pc = luaK_primitivecode(ls, i);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case ADDOP:
|
|
|
+ switch(GET_OPCODE(*last)) {
|
|
|
+ case PUSHINT: *last = SET_OPCODE(*last, ADDI); break;
|
|
|
+ default: fs->last_pc = luaK_primitivecode(ls, i);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SUBOP:
|
|
|
+ switch(GET_OPCODE(*last)) {
|
|
|
+ case PUSHINT:
|
|
|
+ *last = SET_OPCODE(*last, ADDI);
|
|
|
+ *last = SETARG_S(*last, -GETARG_S(*last));
|
|
|
+ break;
|
|
|
+ default: fs->last_pc = luaK_primitivecode(ls, i);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default: fs->last_pc = luaK_primitivecode(ls, i);
|
|
|
+ }
|
|
|
+ return fs->last_pc;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void luaK_fixjump (LexState *ls, int pc, int dest) {
|
|
|
+ FuncState *fs = ls->fs;
|
|
|
+ Instruction *jmp = &fs->f->code[pc];
|
|
|
+ /* jump is relative to position following jump instruction */
|
|
|
+ *jmp = SETARG_S(*jmp, dest-(pc+1));
|
|
|
+ fs->last_pc = pc;
|
|
|
+}
|
|
|
+
|
|
|
+
|