From 39e1f079bdf045d64ad6f1b5da1eb48cc79c6c38 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 22 Feb 2000 11:31:19 -0200 Subject: code generator (and optimizer) for Lua --- lcode.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 lcode.c (limited to 'lcode.c') diff --git a/lcode.c b/lcode.c new file mode 100644 index 00000000..c6162f6f --- /dev/null +++ b/lcode.c @@ -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; +} + + -- cgit v1.2.3-55-g6feb