summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordaurnimator <quae@daurnimator.com>2017-05-08 21:00:41 +1000
committerdaurnimator <quae@daurnimator.com>2017-05-09 14:25:51 +1000
commit9d1b2502045fe7d7bb86570779636c9bbc2ba19a (patch)
tree839179de719be4d0a1d94f5ed6c8c0807ef27698
parent048234f2ceaad1801473bf8a95219d08797b5e9d (diff)
downloadfengari-9d1b2502045fe7d7bb86570779636c9bbc2ba19a.tar.gz
fengari-9d1b2502045fe7d7bb86570779636c9bbc2ba19a.tar.bz2
fengari-9d1b2502045fe7d7bb86570779636c9bbc2ba19a.zip
Cache string hashes in TString
-rw-r--r--src/llex.js2
-rw-r--r--src/lstring.js26
-rw-r--r--src/ltable.js4
3 files changed, 21 insertions, 11 deletions
diff --git a/src/llex.js b/src/llex.js
index 220f45d..2e37eca 100644
--- a/src/llex.js
+++ b/src/llex.js
@@ -208,7 +208,7 @@ const luaX_newstring = function(ls, str) {
o.setbvalue(true);
} else { /* string already present */
/* HACK: Workaround lack of ltable 'keyfromval' */
- let tpair = ls.h.strong.get(lstring.luaS_hash(ts));
+ let tpair = ls.h.strong.get(lstring.luaS_hashlongstr(ts));
assert(tpair.value == o);
ts = tpair.key.tsvalue(); /* re-use value previously stored */
}
diff --git a/src/lstring.js b/src/lstring.js
index 3e94171..cc399b8 100644
--- a/src/lstring.js
+++ b/src/lstring.js
@@ -7,6 +7,7 @@ const defs = require('./defs.js');
class TString {
constructor(L, str) {
+ this.hash = null;
this.realstring = str;
}
@@ -28,8 +29,16 @@ const luaS_eqlngstr = function(a, b) {
/* converts strings (arrays) to a consistent map key */
const luaS_hash = function(str) {
- assert(str instanceof TString);
- return str.realstring.map(e => `${e}|`).join('');
+ assert(Array.isArray(str));
+ return str.map(e => `${e}|`).join('');
+};
+
+const luaS_hashlongstr = function(ts) {
+ assert(ts instanceof TString);
+ if(ts.hash === null) {
+ ts.hash = luaS_hash(ts.getstr());
+ }
+ return ts.hash;
};
/* variant that takes ownership of array */
@@ -48,9 +57,10 @@ const luaS_newliteral = function(L, str) {
return luaS_bless(L, defs.to_luastring(str));
};
-module.exports.luaS_eqlngstr = luaS_eqlngstr;
-module.exports.luaS_hash = luaS_hash;
-module.exports.luaS_bless = luaS_bless;
-module.exports.luaS_new = luaS_new;
-module.exports.luaS_newliteral = luaS_newliteral;
-module.exports.TString = TString;
+module.exports.luaS_eqlngstr = luaS_eqlngstr;
+module.exports.luaS_hash = luaS_hash;
+module.exports.luaS_hashlongstr = luaS_hashlongstr;
+module.exports.luaS_bless = luaS_bless;
+module.exports.luaS_new = luaS_new;
+module.exports.luaS_newliteral = luaS_newliteral;
+module.exports.TString = TString;
diff --git a/src/ltable.js b/src/ltable.js
index a2987d3..1b55256 100644
--- a/src/ltable.js
+++ b/src/ltable.js
@@ -24,7 +24,7 @@ const table_hash = function(key) {
return key.value;
case CT.LUA_TSHRSTR:
case CT.LUA_TLNGSTR:
- return lstring.luaS_hash(key.value);
+ return lstring.luaS_hashlongstr(key.tsvalue());
default:
throw new Error("unknown key type: " + key.type);
}
@@ -54,7 +54,7 @@ const luaH_getint = function(t, key) {
const luaH_getstr = function(t, key) {
assert(key instanceof lstring.TString);
- return getgeneric(t, lstring.luaS_hash(key));
+ return getgeneric(t, lstring.luaS_hashlongstr(key));
};
const luaH_get = function(t, key) {