1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
diff -urwNpx '*.o' src-orig/lapi.c src/lapi.c
--- src-orig/lapi.c 2007-02-12 20:58:39.000000000 -0500
+++ src/lapi.c 2007-02-12 21:05:09.000000000 -0500
@@ -447,6 +447,16 @@ LUA_API void lua_pushlstring (lua_State
}
+LUA_API void lua_pushhstring (lua_State *L,
+ lua_Hash h, const char *s, size_t len) {
+ lua_lock(L);
+ luaC_checkGC(L);
+ setsvalue2s(L, L->top, luaS_newhstr(L, h, s, len));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
LUA_API void lua_pushstring (lua_State *L, const char *s) {
if (s == NULL)
lua_pushnil(L);
Binary files src-orig/liblua.a and src/liblua.a differ
diff -urwNpx '*.o' src-orig/lobject.h src/lobject.h
--- src-orig/lobject.h 2007-02-12 20:58:39.000000000 -0500
+++ src/lobject.h 2007-02-12 21:10:30.000000000 -0500
@@ -201,7 +201,7 @@ typedef union TString {
struct {
CommonHeader;
lu_byte reserved;
- unsigned int hash;
+ lua_Hash hash;
size_t len;
} tsv;
} TString;
diff -urwNpx '*.o' src-orig/lstring.c src/lstring.c
--- src-orig/lstring.c 2007-02-12 20:58:39.000000000 -0500
+++ src/lstring.c 2007-02-12 22:26:46.000000000 -0500
@@ -72,13 +72,41 @@ static TString *newlstr (lua_State *L, c
}
-TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
- GCObject *o;
- unsigned int h = cast(unsigned int, l); /* seed */
+static inline lua_Hash calchash(const char *str, size_t l) {
+ lua_Hash h = cast(unsigned int, l); /* seed */
size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
size_t l1;
- for (l1=l; l1>=step; l1-=step) /* compute hash */
+ for (l1=l; l1>=step; l1-=step) { /* compute hash */
h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
+ }
+ return h;
+}
+
+
+LUA_API lua_Hash lua_calchash(const char *str, size_t l) {
+ return calchash(str, l);
+}
+
+
+TString *luaS_newhstr (lua_State *L, lua_Hash h, const char *str, size_t l) {
+ GCObject *o;
+ for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
+ o != NULL;
+ o = o->gch.next) {
+ TString *ts = rawgco2ts(o);
+ if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
+ /* string may be dead */
+ if (isdead(G(L), o)) changewhite(o);
+ return ts;
+ }
+ }
+ return newlstr(L, str, l, h); /* not found */
+}
+
+
+TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
+ GCObject *o;
+ const lua_Hash h = calchash(str, l);
for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
o != NULL;
o = o->gch.next) {
diff -urwNpx '*.o' src-orig/lstring.h src/lstring.h
--- src-orig/lstring.h 2007-02-12 20:58:39.000000000 -0500
+++ src/lstring.h 2007-02-12 21:06:14.000000000 -0500
@@ -26,6 +26,8 @@
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
+LUAI_FUNC TString *luaS_newhstr (lua_State *L,
+ lua_Hash h, const char *str, size_t l);
#endif
Binary files src-orig/lua and src/lua differ
Binary files src-orig/luac and src/luac differ
diff -urwNpx '*.o' src-orig/lua.h src/lua.h
--- src-orig/lua.h 2007-02-12 20:58:39.000000000 -0500
+++ src/lua.h 2007-02-12 21:15:36.000000000 -0500
@@ -103,6 +103,10 @@ typedef LUA_NUMBER lua_Number;
typedef LUA_INTEGER lua_Integer;
+/* type for string hashes */
+typedef unsigned int lua_Hash;
+
+
/*
** state manipulation
@@ -165,6 +169,8 @@ LUA_API void (lua_pushstring) (lua_Stat
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
va_list argp);
LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
+LUA_API void (lua_pushhstring) (lua_State *L,
+ lua_Hash h, const char *s, size_t l);
LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
LUA_API void (lua_pushboolean) (lua_State *L, int b);
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
@@ -243,6 +249,8 @@ LUA_API void (lua_concat) (lua_State *L
LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
+/* for lua_pushhstring() */
+LUA_API lua_Hash (lua_calchash) (const char *s, size_t l);
/*
|