瀏覽代碼

use a table to find (and reuse) constants when parsing

Roberto Ierusalimschy 24 年之前
父節點
當前提交
c3d72096c4
共有 6 個文件被更改,包括 32 次插入38 次删除
  1. 20 24
      lcode.c
  2. 1 7
      llimits.h
  3. 2 3
      lobject.h
  4. 5 1
      lparser.c
  5. 3 1
      lparser.h
  6. 1 2
      lstring.c

+ 20 - 24
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.77 2001/07/17 14:30:44 roberto Exp roberto $
+** $Id: lcode.c,v 1.78 2001/07/24 17:19:07 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -18,6 +18,7 @@
 #include "lobject.h"
 #include "lopcodes.h"
 #include "lparser.h"
+#include "ltable.h"
 
 
 #define hasjumps(e)	((e)->t != (e)->f)
@@ -222,38 +223,33 @@ static void freeexp (FuncState *fs, expdesc *e) {
 
 
 static int addk (FuncState *fs, TObject *k) {
-  Proto *f = fs->f;
-  luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
-                  MAXARG_Bc, l_s("constant table overflow"));
-  setobj(&f->k[fs->nk], k);
-  return fs->nk++;
+  const TObject *index = luaH_get(fs->h, k);
+  if (ttype(index) == LUA_TNUMBER) {
+    lua_assert(luaO_equalObj(&fs->f->k[(int)nvalue(index)], k));
+    return (int)nvalue(index);
+  }
+  else {  /* constant not found; create a new entry */
+    TObject o;
+    Proto *f = fs->f;
+    luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
+                    MAXARG_Bc, l_s("constant table overflow"));
+    setobj(&f->k[fs->nk], k);
+    setnvalue(&o, fs->nk);
+    setobj(luaH_set(fs->L, fs->h, k), &o);
+    return fs->nk++;
+  }
 }
 
 
 int luaK_stringk (FuncState *fs, TString *s) {
-  Proto *f = fs->f;
-  int c = s->tsv.constindex;
-  if (c >= fs->nk || ttype(&f->k[c]) != LUA_TSTRING || tsvalue(&f->k[c]) != s) {
-    TObject o;
-    setsvalue(&o, s);
-    c = addk(fs, &o);
-    s->tsv.constindex = (unsigned short)c;  /* hint for next time */
-  }
-  return c;
+  TObject o;
+  setsvalue(&o, s);
+  return addk(fs, &o);
 }
 
 
 static int number_constant (FuncState *fs, lua_Number r) {
-  /* check whether `r' has appeared within the last LOOKBACKNUMS entries */
   TObject o;
-  Proto *f = fs->f;
-  int c = fs->nk;
-  int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS;
-  while (--c >= lim) {
-    if (ttype(&f->k[c]) == LUA_TNUMBER && nvalue(&f->k[c]) == r)
-      return c;
-  }
-  /* not found; create a new entry */
   setnvalue(&o, r);
   return addk(fs, &o);
 }

+ 1 - 7
llimits.h

@@ -1,5 +1,5 @@
 /*
-** $Id: llimits.h,v 1.29 2001/06/05 18:17:01 roberto Exp roberto $
+** $Id: llimits.h,v 1.30 2001/06/05 20:01:09 roberto Exp roberto $
 ** Limits, basic types, and some other `installation-dependent' definitions
 ** See Copyright Notice in lua.h
 */
@@ -124,10 +124,4 @@ typedef unsigned long Instruction;
 
 
 
-/* maximum lookback to find a real constant (for code generation) */
-#ifndef LOOKBACKNUMS
-#define LOOKBACKNUMS    40      /* arbitrary constant */
-#endif
-
-
 #endif

+ 2 - 3
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 1.108 2001/06/28 14:48:44 roberto Exp roberto $
+** $Id: lobject.h,v 1.109 2001/06/28 14:56:25 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -90,8 +90,7 @@ typedef union TString {
   struct {
     lu_hash hash;
     size_t len;
-    unsigned short constindex;  /* hint to reuse constants */
-    short marked;
+    int marked;
     union TString *nexthash;  /* chain for hash table */
   } tsv;
 } TString;

+ 5 - 1
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.152 2001/07/10 20:02:22 roberto Exp roberto $
+** $Id: lparser.c,v 1.153 2001/08/10 20:53:03 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -318,6 +318,7 @@ static void open_func (LexState *ls, FuncState *fs) {
   fs->jlt = NO_JUMP;
   fs->freereg = 0;
   fs->nk = 0;
+  fs->h = luaH_new(ls->L, 0);
   fs->np = 0;
   fs->nlineinfo = 0;
   fs->nlocvars = 0;
@@ -339,6 +340,9 @@ static void close_func (LexState *ls) {
   luaK_codeABC(fs, OP_RETURN, 0, 0, 0);  /* final return */
   luaK_getlabel(fs);  /* close eventual list of pending jumps */
   removelocalvars(ls, fs->nactloc);
+  lua_assert(G(L)->roottable == fs->h);
+  G(L)->roottable = fs->h->next;
+  luaH_free(L, fs->h);
   luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
   f->sizecode = fs->pc;
   luaM_reallocvector(L, f->k, f->sizek, fs->nk, TObject);

+ 3 - 1
lparser.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.h,v 1.32 2001/06/28 14:56:25 roberto Exp roberto $
+** $Id: lparser.h,v 1.33 2001/08/10 20:53:03 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -8,6 +8,7 @@
 #define lparser_h
 
 #include "lobject.h"
+#include "ltable.h"
 #include "lzio.h"
 
 
@@ -53,6 +54,7 @@ typedef struct FuncState {
   int jlt;  /* list of jumps to `lasttarget' */
   int freereg;  /* first free register */
   int nk;  /* number of elements in `k' */
+  Hash *h;  /* table to find (and reuse) elements in `k' */
   int np;  /* number of elements in `p' */
   int nlineinfo;  /* number of elements in `lineinfo' */
   int nlocvars;  /* number of elements in `locvars' */

+ 1 - 2
lstring.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.c,v 1.64 2001/06/07 15:01:21 roberto Exp roberto $
+** $Id: lstring.c,v 1.65 2001/06/15 20:36:57 roberto Exp roberto $
 ** String table (keeps all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */
@@ -54,7 +54,6 @@ static TString *newlstr (lua_State *L, const l_char *str, size_t l, lu_hash h) {
   ts->tsv.len = l;
   ts->tsv.hash = h;
   ts->tsv.marked = 0;
-  ts->tsv.constindex = 0;
   memcpy(getstr(ts), str, l*sizeof(l_char));
   getstr(ts)[l] = l_c('\0');  /* ending 0 */
   tb = &G(L)->strt;