Przeglądaj źródła

code generator (and optimizer) for Lua

Roberto Ierusalimschy 25 lat temu
rodzic
commit
39e1f079bd
2 zmienionych plików z 115 dodań i 0 usunięć
  1. 96 0
      lcode.c
  2. 19 0
      lcode.h

+ 96 - 0
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;
+}
+
+

+ 19 - 0
lcode.h

@@ -0,0 +1,19 @@
+/*
+** $Id: $
+** Code generator for Lua
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lcode_h
+#define lcode_h
+
+#include "llex.h"
+#include "lobject.h"
+
+
+int luaK_primitivecode (LexState *ls, Instruction i);
+int luaK_code (LexState *ls, Instruction i);
+void luaK_fixjump (LexState *ls, int pc, int dest);
+
+
+#endif