aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/defs.js7
-rw-r--r--src/lapi.js15
-rw-r--r--src/lauxlib.js17
-rw-r--r--src/lbaselib.js2
-rw-r--r--src/ldblib.js4
-rw-r--r--src/ldump.js23
-rw-r--r--src/llex.js9
-rw-r--r--src/llimits.js4
-rw-r--r--src/lobject.js31
-rw-r--r--src/loslib.js10
-rw-r--r--src/lstring.js5
-rw-r--r--src/luaconf.js2
-rw-r--r--src/lundump.js4
-rw-r--r--src/lutf8lib.js2
-rw-r--r--src/lvm.js29
-rw-r--r--src/lzio.js42
16 files changed, 112 insertions, 94 deletions
diff --git a/src/defs.js b/src/defs.js
index 27498c6..381114b 100644
--- a/src/defs.js
+++ b/src/defs.js
@@ -131,10 +131,10 @@ class lua_Debug {
}
-const string_of = Array.of;
+const string_of = Uint8Array.of.bind(Uint8Array);
const is_luastring = function(s) {
- return Array.isArray(s);
+ return s instanceof Uint8Array;
};
/* test two lua strings for equality */
@@ -143,7 +143,7 @@ const luastring_cmp = function(a, b) {
};
const to_jsstring = function(value, from, to) {
- assert(is_luastring(value), "jsstring expects an array of bytes");
+ assert(is_luastring(value), "jsstring expects a Uint8Array");
if (to === void 0) {
to = value.length;
@@ -240,6 +240,7 @@ const to_luastring = function(str, cache) {
outU8Array[outIdx++] = 0x80 | (u & 63);
}
}
+ outU8Array = Uint8Array.from(outU8Array);
if (cache) to_luastring_cache[str] = outU8Array;
diff --git a/src/lapi.js b/src/lapi.js
index afa94ce..111735f 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -672,19 +672,8 @@ const lua_toljsstring = function(L, idx) {
const lua_tojsstring = lua_toljsstring;
const lua_todataview = function(L, idx) {
- let o = index2addr(L, idx);
-
- if (!o.ttisstring()) {
- if (!lvm.cvt2str(o)) { /* not convertible? */
- return null;
- }
- lobject.luaO_tostring(L, o);
- }
-
- let dv = new DataView(new ArrayBuffer(o.vslen()));
- o.svalue().forEach((e, i) => dv.setUint8(i, e, true));
-
- return dv;
+ let u8 = lua_tolstring(L, idx);
+ return new DataView(u8.buffer, u8.byteOffset, u8.byteLength);
};
const lua_rawlen = function(L, idx) {
diff --git a/src/lauxlib.js b/src/lauxlib.js
index b9b7078..5687242 100644
--- a/src/lauxlib.js
+++ b/src/lauxlib.js
@@ -62,7 +62,7 @@ const pushglobalfuncname = function(L, ar) {
if (findfield(L, top + 1, 2)) {
let name = lua.lua_tostring(L, -1);
if (name[0] === "_".charCodeAt(0) && name[1] === "G".charCodeAt(0) && name[2] === ".".charCodeAt(0)) { /* name start with '_G.'? */
- lua.lua_pushstring(L, name.slice(3)); /* push name without prefix */
+ lua.lua_pushstring(L, name.subarray(3)); /* push name without prefix */
lua.lua_remove(L, -2); /* remove original name */
}
lua.lua_copy(L, -1, top + 1); /* move name to proper place */
@@ -381,14 +381,14 @@ const luaL_prepbuffer = function(B) {
};
const luaL_addlstring = function(B, s, l) {
- B.b = B.b.concat(s.slice(0, l));
+ B.b = B.b.concat(Array.from(s.subarray(0, l)));
};
const luaL_addstring = luaL_addlstring;
const luaL_pushresult = function(B) {
let L = B.L;
- lua.lua_pushstring(L, B.b);
+ lua.lua_pushstring(L, Uint8Array.from(B.b));
};
const luaL_addchar = function(B, c) {
@@ -558,7 +558,7 @@ const luaL_gsub = function(L, s, p, r) {
s = s.slice(wild + p.length); /* continue after 'p' */
}
b.push(...s); /* push last suffix */
- lua.lua_pushstring(L, b);
+ lua.lua_pushstring(L, Uint8Array.from(b));
return lua.lua_tostring(L, -1);
};
@@ -713,7 +713,7 @@ class LoadF {
constructor() {
this.n = NaN; /* number of pre-read characters */
this.f = null; /* file being read */
- this.buff = typeof process === "undefined" ? new Array(1024) : new Buffer(1024); /* area for reading file */
+ this.buff = new Uint8Array(1024); /* area for reading file */
this.pos = 0; /* current position in file */
this.err = void 0;
}
@@ -726,8 +726,8 @@ if (typeof process === "undefined") {
if (lf.f !== null && lf.n > 0) { /* are there pre-read characters to be read? */
let bytes = lf.n; /* return them (chars already in buffer) */
lf.n = 0; /* no more pre-read characters */
- lf.f = lf.f.slice(lf.pos); /* we won't use lf.buff anymore */
- return lf.buff.slice(0, bytes);
+ lf.f = lf.f.subarray(lf.pos); /* we won't use lf.buff anymore */
+ return lf.buff.subarray(0, bytes);
}
let f = lf.f;
@@ -789,7 +789,6 @@ if (typeof process === "undefined") {
bytes = lf.n; /* return them (chars already in buffer) */
lf.n = 0; /* no more pre-read characters */
} else { /* read a block from file */
- lf.buff.fill(0);
try {
bytes = fs.readSync(lf.f, lf.buff, 0, lf.buff.length, lf.pos); /* read block */
} catch(e) {
@@ -799,7 +798,7 @@ if (typeof process === "undefined") {
lf.pos += bytes;
}
if (bytes > 0)
- return lf.buff.slice(0, bytes); /* slice on a node.js Buffer is 'free' */
+ return lf.buff.subarray(0, bytes); /* slice on a node.js Buffer is 'free' */
else return null;
};
diff --git a/src/lbaselib.js b/src/lbaselib.js
index 30e77fb..103a9ca 100644
--- a/src/lbaselib.js
+++ b/src/lbaselib.js
@@ -8,7 +8,7 @@ let lua_writeline;
if (typeof process === "undefined") {
let buff = [];
lua_writestring = function(s) {
- buff = buff.concat(s);
+ buff = buff.concat(Array.from(s));
};
lua_writeline = function() {
console.log(new TextDecoder("utf-8").decode(Uint8Array.from(buff)));
diff --git a/src/ldblib.js b/src/ldblib.js
index 746d3bf..df7d2ff 100644
--- a/src/ldblib.js
+++ b/src/ldblib.js
@@ -306,7 +306,7 @@ const unmakemask = function(mask, smask) {
if (mask & lua.LUA_MASKCALL) smask[i++] = "c".charCodeAt(0);
if (mask & lua.LUA_MASKRET) smask[i++] = "r".charCodeAt(0);
if (mask & lua.LUA_MASKLINE) smask[i++] = "l".charCodeAt(0);
- return smask;
+ return smask.subarray(0, i);
};
const db_sethook = function(L) {
@@ -344,7 +344,7 @@ const db_sethook = function(L) {
const db_gethook = function(L) {
let thread = getthread(L);
let L1 = thread.thread;
- let buff = [];
+ let buff = new Uint8Array(5);
let mask = lua.lua_gethookmask(L1);
let hook = lua.lua_gethook(L1);
if (hook === null) /* no hook? */
diff --git a/src/ldump.js b/src/ldump.js
index 964d6ff..7e62da3 100644
--- a/src/ldump.js
+++ b/src/ldump.js
@@ -34,31 +34,26 @@ const DumpByte = function(y, D) {
};
const DumpInt = function(x, D) {
- let dv = new DataView(new ArrayBuffer(4));
+ let ab = new ArrayBuffer(4);
+ let dv = new DataView(ab);
dv.setInt32(0, x, true);
- let t = [];
- for (let i = 0; i < 4; i++)
- t.push(dv.getUint8(i, true));
-
+ let t = new Uint8Array(ab);
DumpBlock(t, 4, D);
};
const DumpInteger = function(x, D) {
- let dv = new DataView(new ArrayBuffer(4));
+ let ab = new ArrayBuffer(4);
+ let dv = new DataView(ab);
dv.setInt32(0, x, true);
- let t = [];
- for (let i = 0; i < 4; i++)
- t.push(dv.getUint8(i, true));
+ let t = new Uint8Array(ab);
DumpBlock(t, 4, D);
};
const DumpNumber = function(x, D) {
- let dv = new DataView(new ArrayBuffer(8));
+ let ab = new ArrayBuffer(8);
+ let dv = new DataView(ab);
dv.setFloat64(0, x, true);
- let t = [];
- for (let i = 0; i < 8; i++)
- t.push(dv.getUint8(i, true));
-
+ let t = new Uint8Array(ab);
DumpBlock(t, 8, D);
};
diff --git a/src/llex.js b/src/llex.js
index 779557a..438f288 100644
--- a/src/llex.js
+++ b/src/llex.js
@@ -112,6 +112,8 @@ const save = function(ls, c) {
if (b.n + 1 > b.buffer.length) {
if (b.buffer.length >= llimits.MAX_INT/2)
lexerror(ls, defs.to_luastring("lexical element too long", true), 0);
+ let newsize = b.buffer.length*2;
+ lzio.luaZ_resizebuffer(ls.L, b, newsize);
}
b.buffer[b.n++] = c < 0 ? 255 + c + 1 : c;
};
@@ -192,6 +194,7 @@ const luaX_setinput = function(L, ls, z, source, firstchar) {
ls.lastline = 1;
ls.source = source;
ls.envn = lstring.luaS_bless(L, LUA_ENV);
+ lzio.luaZ_resizebuffer(L, ls.buff, llimits.LUA_MINBUFFER); /* initialize buffer */
};
const check_next1 = function(ls, c) {
@@ -325,7 +328,7 @@ const read_long_string = function(ls, seminfo, sep) {
}
if (seminfo)
- seminfo.ts = luaX_newstring(ls, ls.buff.buffer.slice(2 + sep, ls.buff.n - (2 + sep)));
+ seminfo.ts = luaX_newstring(ls, ls.buff.buffer.subarray(2 + sep, ls.buff.n - (2 + sep)));
};
const esccheck = function(ls, c, msg) {
@@ -369,7 +372,7 @@ const readutf8desc = function(ls) {
};
const utf8esc = function(ls) {
- let buff = new Array(lobject.UTF8BUFFSZ);
+ let buff = new Uint8Array(lobject.UTF8BUFFSZ);
let n = lobject.luaO_utf8esc(buff, readutf8desc(ls));
for (; n > 0; n--) /* add 'buff' to string */
save(ls, buff[lobject.UTF8BUFFSZ - n]);
@@ -450,7 +453,7 @@ const read_string = function(ls, del, seminfo) {
}
save_and_next(ls); /* skip delimiter */
- seminfo.ts = luaX_newstring(ls, ls.buff.buffer.slice(1, ls.buff.n-1));
+ seminfo.ts = luaX_newstring(ls, ls.buff.buffer.subarray(1, ls.buff.n-1));
};
const token_to_index = Object.create(null); /* don't want to return true for e.g. 'hasOwnProperty' */
diff --git a/src/llimits.js b/src/llimits.js
index 21a09a0..4a76bbe 100644
--- a/src/llimits.js
+++ b/src/llimits.js
@@ -3,6 +3,10 @@
const LUAI_MAXCCALLS = 200;
module.exports.LUAI_MAXCCALLS = LUAI_MAXCCALLS;
+/* minimum size for string buffer */
+const LUA_MINBUFFER = 32;
+module.exports.LUA_MINBUFFER = LUA_MINBUFFER;
+
const luai_nummod = function(L, a, b) {
let m = a % b;
if ((m*b) < 0)
diff --git a/src/lobject.js b/src/lobject.js
index 707cdf8..c02bc91 100644
--- a/src/lobject.js
+++ b/src/lobject.js
@@ -294,7 +294,7 @@ class LocVar {
}
}
-const RETS = defs.to_luastring("...", true);
+const RETS = defs.to_luastring("...");
const PRE = defs.to_luastring("[string \"");
const POS = defs.to_luastring("\"]");
@@ -305,26 +305,37 @@ const luaO_chunkid = function(source, bufflen) {
if (l < bufflen) /* small enough? */
out = source.slice(1);
else { /* truncate it */
- out = source.slice(1, bufflen);
+ out = source.slice(1, bufflen+1);
}
} else if (source[0] === char['@']) { /* file name */
if (l <= bufflen) /* small enough? */
out = source.slice(1);
else { /* add '...' before rest of name */
+ out = new Uint8Array(bufflen);
+ out.set(RETS);
bufflen -= RETS.length;
- out = RETS.concat(source.slice(1 + l - bufflen));
+ out.set(source.subarray(l - bufflen), RETS.length);
}
} else { /* string; format as [string "source"] */
+ out = new Uint8Array(bufflen);
let nli = source.indexOf(char['\n']); /* find first new line (if any) */
- out = PRE; /* add prefix */
- bufflen -= PRE.length + RETS.length + POS.length + 1; /* save space for prefix+suffix+'\0' */
+ out.set(PRE); /* add prefix */
+ let out_i = PRE.length;
+ bufflen -= PRE.length + RETS.length + POS.length; /* save space for prefix+suffix */
if (l < bufflen && nli === -1) { /* small one-line source? */
- out = out.concat(source, POS); /* keep it */
+ out.set(source, out_i); /* keep it */
+ out_i += source.length;
} else {
if (nli !== -1) l = nli; /* stop at first newline */
if (l > bufflen) l = bufflen;
- out = out.concat(source.slice(0, l), RETS, POS);
+ out.set(source.subarray(0, l), out_i);
+ out_i += l;
+ out.set(RETS, out_i);
+ out_i += RETS.length;
}
+ out.set(POS, out_i);
+ out_i += POS.length;
+ out = out.subarray(0, out_i);
}
return out;
};
@@ -530,7 +541,7 @@ const luaO_pushvfstring = function(L, fmt, argp) {
for (;;) {
e = fmt.indexOf(char['%'], i);
if (e == -1) break;
- pushstr(L, fmt.slice(i, e));
+ pushstr(L, fmt.subarray(i, e));
switch(fmt[e+1]) {
case char['s']: {
let s = argp[a++];
@@ -539,7 +550,7 @@ const luaO_pushvfstring = function(L, fmt, argp) {
/* respect null terminator */
let i = s.indexOf(0);
if (i !== -1)
- s = s.slice(0, i);
+ s = s.subarray(0, i);
}
pushstr(L, s);
break;
@@ -608,7 +619,7 @@ const luaO_pushvfstring = function(L, fmt, argp) {
i = e + 2;
}
ldo.luaD_checkstack(L, 1);
- pushstr(L, fmt.slice(i));
+ pushstr(L, fmt.subarray(i));
if (n > 0) lvm.luaV_concat(L, n+1);
return L.stack[L.top-1].svalue();
};
diff --git a/src/loslib.js b/src/loslib.js
index 19dfd02..f27a7ed 100644
--- a/src/loslib.js
+++ b/src/loslib.js
@@ -73,7 +73,7 @@ const checkoption = function(L, conv, i, buff) {
if (option[o] === '|'.charCodeAt(0)) /* next block? */
oplen++; /* will check options with next length (+1) */
else if (array_cmp(conv, i, option, o, oplen)) { /* match? */
- buff.push(...conv.slice(i, i+oplen)); /* copy valid option to buffer */
+ buff.set(conv.slice(i, i+oplen)); /* copy valid option to buffer */
return i + oplen; /* return next item */
}
}
@@ -102,6 +102,8 @@ const os_date = function(L) {
lua.lua_createtable(L, 0, 9); /* 9 = number of fields */
setallfields(L, stm, utc);
} else {
+ let cc = new Uint8Array(4);
+ cc[0] = "%".charCodeAt(0);
let b = new lauxlib.luaL_Buffer();
lauxlib.luaL_buffinit(L, b);
while (i < s.length) {
@@ -109,8 +111,10 @@ const os_date = function(L) {
lauxlib.luaL_addchar(b, s[i++]);
} else {
i++; /* skip '%' */
- let cc = ["%".charCodeAt(0)];
- i = checkoption(L, s, i, cc); /* copy specifier to 'cc' */
+ i = checkoption(L, s, i, cc.subarray(1)); /* copy specifier to 'cc' */
+ let len = cc.indexOf(0);
+ if (len !== -1)
+ cc = cc.subarray(0, len);
let buff = strftime(lua.to_jsstring(cc), stm);
lauxlib.luaL_addstring(b, lua.to_luastring(buff));
}
diff --git a/src/lstring.js b/src/lstring.js
index c85e5b2..c8da56a 100644
--- a/src/lstring.js
+++ b/src/lstring.js
@@ -31,7 +31,7 @@ const luaS_eqlngstr = function(a, b) {
make sure this doesn't conflict with any of the anti-collision strategies in ltable */
const luaS_hash = function(str) {
assert(defs.is_luastring(str));
- return str.map(e => `${e}|`).join('');
+ return '|'+str.join('|');
};
const luaS_hashlongstr = function(ts) {
@@ -44,12 +44,13 @@ const luaS_hashlongstr = function(ts) {
/* variant that takes ownership of array */
const luaS_bless = function(L, str) {
+ assert(str instanceof Uint8Array);
return new TString(L, str);
};
/* makes a copy */
const luaS_new = function(L, str) {
- return luaS_bless(L, str.slice(0));
+ return luaS_bless(L, Uint8Array.from(str));
};
/* takes a js string */
diff --git a/src/luaconf.js b/src/luaconf.js
index 00663a6..5331720 100644
--- a/src/luaconf.js
+++ b/src/luaconf.js
@@ -19,7 +19,7 @@ const LUAI_MAXSTACK = 100000;
@@ of a function in debug information.
** CHANGE it if you want a different size.
*/
-const LUA_IDSIZE = 60;
+const LUA_IDSIZE = 60-1; /* fengari uses 1 less than lua as we don't embed the null byte */
const lua_integer2str = function(n) {
return sprintf(LUA_INTEGER_FMT, n);
diff --git a/src/lundump.js b/src/lundump.js
index ff87903..e49c376 100644
--- a/src/lundump.js
+++ b/src/lundump.js
@@ -25,7 +25,7 @@ class BytecodeParser {
assert(defs.is_luastring(name));
if (name[0] == defs.char["@"] || name[0] == defs.char["="])
- this.name = name.slice(1);
+ this.name = name.subarray(1);
else if (name[0] == defs.LUA_SIGNATURE.charCodeAt(0))
this.name = defs.to_luastring("binary string", true);
else
@@ -46,7 +46,7 @@ class BytecodeParser {
let u8 = new Uint8Array(size);
if(lzio.luaZ_read(this.Z, u8, 0, size) !== 0)
this.error("truncated");
- return Array.from(u8);
+ return u8;
}
readByte() {
diff --git a/src/lutf8lib.js b/src/lutf8lib.js
index 3baeeef..f581a9e 100644
--- a/src/lutf8lib.js
+++ b/src/lutf8lib.js
@@ -216,7 +216,7 @@ const funcs = {
};
/* pattern to match a single UTF-8 character */
-const UTF8PATT = [ 91, 0, 45, 127, 194, 45, 244, 93, 91, 128, 45, 191, 93, 42 ];
+const UTF8PATT = Uint8Array.of(91, 0, 45, 127, 194, 45, 244, 93, 91, 128, 45, 191, 93, 42);
const luaopen_utf8 = function(L) {
lauxlib.luaL_newlib(L, funcs);
diff --git a/src/lvm.js b/src/lvm.js
index 3cdccb9..9d97c17 100644
--- a/src/lvm.js
+++ b/src/lvm.js
@@ -937,6 +937,18 @@ const isemptystr = function(o) {
return o.ttisstring() && o.vslen() === 0;
};
+/* copy strings in stack from top - n up to top - 1 to buffer */
+const copy2buff = function(L, top, n, buff) {
+ let tl = 0; /* size already copied */
+ do {
+ let tv = L.stack[top-n];
+ let l = tv.vslen(); /* length of string being copied */
+ let s = tv.svalue();
+ buff.set(s, tl);
+ tl += l;
+ } while (--n > 0);
+};
+
/*
** Main operation for concatenation: concat 'total' values in the stack,
** from 'L->top - total' up to 'L->top - 1'.
@@ -955,16 +967,15 @@ const luaV_concat = function(L, total) {
lobject.setobjs2s(L, top - 2, top - 1);
} else {
/* at least two non-empty string values; get as many as possible */
- let toconcat = new Array(total);
- toconcat[total-1] = L.stack[top-1].svalue();
- for (n = 1; n < total; n++) {
- if (!tostring(L, top - n - 1)) {
- toconcat = toconcat.slice(total-n);
- break;
- }
- toconcat[total-n-1] = L.stack[top - n - 1].svalue();
+ let tl = L.stack[top-1].vslen();
+ /* collect total length and number of strings */
+ for (n = 1; n < total && tostring(L, top - n - 1); n++) {
+ let l = L.stack[top - n - 1].vslen();
+ tl += l;
}
- let ts = lstring.luaS_bless(L, Array.prototype.concat.apply([], toconcat));
+ let buff = new Uint8Array(tl);
+ copy2buff(L, top, n, buff);
+ let ts = lstring.luaS_bless(L, buff);
lobject.setsvalue2s(L, top - n, ts);
}
total -= n - 1; /* got 'n' strings to create 1 new */
diff --git a/src/lzio.js b/src/lzio.js
index 3d877aa..a00a24b 100644
--- a/src/lzio.js
+++ b/src/lzio.js
@@ -11,7 +11,7 @@ class MBuffer {
}
const luaZ_buffer = function(buff) {
- return buff.buffer;
+ return buff.buffer.subarray(0, buff.n);
};
const luaZ_buffremove = function(buff, i) {
@@ -20,7 +20,13 @@ const luaZ_buffremove = function(buff, i) {
const luaZ_resetbuffer = function(buff) {
buff.n = 0;
- buff.buffer = [];
+};
+
+const luaZ_resizebuffer = function(L, buff, size) {
+ let newbuff = new Uint8Array(size);
+ if (buff.buffer)
+ newbuff.set(buff.buffer);
+ buff.buffer = newbuff;
};
class ZIO {
@@ -42,22 +48,15 @@ class ZIO {
const EOZ = -1;
const luaZ_fill = function(z) {
- let size;
let buff = z.reader(z.L, z.data);
if (buff === null)
return EOZ;
- if (buff instanceof DataView) {
- z.buffer = new Uint8Array(buff.buffer, buff.byteOffset, buff.byteLength);
- z.off = 0;
- size = buff.byteLength - buff.byteOffset;
- } else {
- assert(typeof buff !== "string", "Should only load binary of array of bytes");
- z.buffer = buff;
- z.off = 0;
- size = buff.length;
- }
+ assert(buff instanceof Uint8Array, "Should only load binary of array of bytes");
+ let size = buff.length;
if (size === 0)
return EOZ;
+ z.buffer = buff;
+ z.off = 0;
z.n = size - 1;
return z.buffer[z.off++];
};
@@ -87,11 +86,12 @@ const luaZ_read = function(z, b, b_offset, n) {
return 0;
};
-module.exports.EOZ = EOZ;
-module.exports.luaZ_buffer = luaZ_buffer;
-module.exports.luaZ_buffremove = luaZ_buffremove;
-module.exports.luaZ_fill = luaZ_fill;
-module.exports.luaZ_read = luaZ_read;
-module.exports.luaZ_resetbuffer = luaZ_resetbuffer;
-module.exports.MBuffer = MBuffer;
-module.exports.ZIO = ZIO;
+module.exports.EOZ = EOZ;
+module.exports.luaZ_buffer = luaZ_buffer;
+module.exports.luaZ_buffremove = luaZ_buffremove;
+module.exports.luaZ_fill = luaZ_fill;
+module.exports.luaZ_read = luaZ_read;
+module.exports.luaZ_resetbuffer = luaZ_resetbuffer;
+module.exports.luaZ_resizebuffer = luaZ_resizebuffer;
+module.exports.MBuffer = MBuffer;
+module.exports.ZIO = ZIO;