summaryrefslogtreecommitdiff
path: root/src/defs.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/defs.js')
-rw-r--r--src/defs.js382
1 files changed, 215 insertions, 167 deletions
diff --git a/src/defs.js b/src/defs.js
index a2c5c75..70d0c73 100644
--- a/src/defs.js
+++ b/src/defs.js
@@ -1,16 +1,200 @@
"use strict";
-const assert = require('assert');
-const luaconf = require('./luaconf.js');
+const { LUAI_MAXSTACK } = require('./luaconf.js');
-// To avoid charCodeAt everywhere
-const char = [];
-for (let i = 0; i < 127; i++)
- char[String.fromCharCode(i)] = i;
-module.exports.char = char;
+/*
+ * Fengari specific string conversion functions
+ */
+
+let luastring_from;
+if (typeof Uint8Array.from === "function") {
+ luastring_from = Uint8Array.from.bind(Uint8Array);
+} else {
+ luastring_from = function(a) {
+ let i = 0;
+ let len = a.length;
+ let r = new Uint8Array(len);
+ while (len > i) r[i] = a[i++];
+ return r;
+ };
+}
+
+let luastring_indexOf;
+if (typeof (new Uint8Array().indexOf) === "function") {
+ luastring_indexOf = function(s, v, i) {
+ return s.indexOf(v, i);
+ };
+} else {
+ /* Browsers that don't support Uint8Array.indexOf seem to allow using Array.indexOf on Uint8Array objects e.g. IE11 */
+ let array_indexOf = [].indexOf;
+ if (array_indexOf.call(new Uint8Array(1), 0) !== 0) throw Error("missing .indexOf");
+ luastring_indexOf = function(s, v, i) {
+ return array_indexOf.call(s, v, i);
+ };
+}
+
+let luastring_of;
+if (typeof Uint8Array.of === "function") {
+ luastring_of = Uint8Array.of.bind(Uint8Array);
+} else {
+ luastring_of = function() {
+ return luastring_from(arguments);
+ };
+}
+
+const is_luastring = function(s) {
+ return s instanceof Uint8Array;
+};
+
+/* test two lua strings for equality */
+const luastring_eq = function(a, b) {
+ if (a !== b) {
+ let len = a.length;
+ if (len !== b.length) return false;
+ /* XXX: Should this be a constant time algorithm? */
+ for (let i=0; i<len; i++)
+ if (a[i] !== b[i]) return false;
+ }
+ return true;
+};
+
+const to_jsstring = function(value, from, to) {
+ if (!is_luastring(value)) throw new TypeError("to_jsstring expects a Uint8Array");
+
+ if (to === void 0) {
+ to = value.length;
+ } else {
+ to = Math.min(value.length, to);
+ }
+
+ let str = "";
+ for (let i = (from!==void 0?from:0); i < to;) {
+ let u0 = value[i++];
+ if (u0 < 0x80) {
+ /* single byte sequence */
+ str += String.fromCharCode(u0);
+ } else if (u0 < 0xC2 || u0 > 0xF4) {
+ throw RangeError("cannot convert invalid utf8 to javascript string");
+ } else if (u0 <= 0xDF) {
+ /* two byte sequence */
+ if (i >= to) throw RangeError("cannot convert invalid utf8 to javascript string");
+ let u1 = value[i++];
+ if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
+ str += String.fromCharCode(((u0 & 0x1F) << 6) + (u1 & 0x3F));
+ } else if (u0 <= 0xEF) {
+ /* three byte sequence */
+ if (i+1 >= to) throw RangeError("cannot convert invalid utf8 to javascript string");
+ let u1 = value[i++];
+ if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
+ let u2 = value[i++];
+ if ((u2&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
+ let u = ((u0 & 0x0F) << 12) + ((u1 & 0x3F) << 6) + (u2 & 0x3F);
+ if (u <= 0xFFFF) { /* BMP codepoint */
+ str += String.fromCharCode(u);
+ } else { /* Astral codepoint */
+ u -= 0x10000;
+ let s1 = (u >> 10) + 0xD800;
+ let s2 = (u % 0x400) + 0xDC00;
+ str += String.fromCharCode(s1, s2);
+ }
+ } else {
+ /* four byte sequence */
+ if (i+2 >= to) throw RangeError("cannot convert invalid utf8 to javascript string");
+ let u1 = value[i++];
+ if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
+ let u2 = value[i++];
+ if ((u2&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
+ let u3 = value[i++];
+ if ((u3&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
+ /* Has to be astral codepoint */
+ let u = ((u0 & 0x07) << 18) + ((u1 & 0x3F) << 12) + ((u2 & 0x3F) << 6) + (u3 & 0x3F);
+ u -= 0x10000;
+ let s1 = (u >> 10) + 0xD800;
+ let s2 = (u % 0x400) + 0xDC00;
+ str += String.fromCharCode(s1, s2);
+ }
+ }
+ return str;
+};
+
+/* bytes allowed unescaped in a uri */
+const uri_allowed = (";,/?:@&=+$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,-_.!~*'()#").split('').reduce(function(uri_allowed, c) {
+ uri_allowed[c.charCodeAt(0)] = true;
+ return uri_allowed;
+}, {});
+
+/* utility function to convert a lua string to a js string with uri escaping */
+const to_uristring = function(a) {
+ if (!is_luastring(a)) throw new TypeError("to_uristring expects a Uint8Array");
+ let s = "";
+ for (let i=0; i<a.length; i++) {
+ let v = a[i];
+ if (uri_allowed[v]) {
+ s += String.fromCharCode(v);
+ } else {
+ s += "%" + (v<0x10?"0":"") + v.toString(16);
+ }
+ }
+ return s;
+};
+
+const to_luastring_cache = {};
+
+const to_luastring = function(str, cache) {
+ if (typeof str !== "string") throw new TypeError("to_luastring expects a javascript string");
+
+ if (cache) {
+ let cached = to_luastring_cache[str];
+ if (is_luastring(cached)) return cached;
+ }
+
+ let len = str.length;
+ let outU8Array = Array(len); /* array is at *least* going to be length of string */
+ let outIdx = 0;
+ for (let i = 0; i < len; ++i) {
+ let u = str.charCodeAt(i);
+ if (u <= 0x7F) {
+ outU8Array[outIdx++] = u;
+ } else if (u <= 0x7FF) {
+ outU8Array[outIdx++] = 0xC0 | (u >> 6);
+ outU8Array[outIdx++] = 0x80 | (u & 63);
+ } else {
+ /* This part is to work around possible lack of String.codePointAt */
+ if (u >= 0xD800 && u <= 0xDBFF && (i+1) < len) {
+ /* is first half of surrogate pair */
+ let v = str.charCodeAt(i+1);
+ if (v >= 0xDC00 && v <= 0xDFFF) {
+ /* is valid low surrogate */
+ i++;
+ u = (u - 0xD800) * 0x400 + v + 0x2400;
+ }
+ }
+ if (u <= 0xFFFF) {
+ outU8Array[outIdx++] = 0xE0 | (u >> 12);
+ outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
+ outU8Array[outIdx++] = 0x80 | (u & 63);
+ } else {
+ outU8Array[outIdx++] = 0xF0 | (u >> 18);
+ outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);
+ outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
+ outU8Array[outIdx++] = 0x80 | (u & 63);
+ }
+ }
+ }
+ outU8Array = luastring_from(outU8Array);
+
+ if (cache) to_luastring_cache[str] = outU8Array;
+
+ return outU8Array;
+};
+
+const from_userstring = function(str) {
+ if (!is_luastring(str)) throw new TypeError("expects an array of bytes");
+ return str;
+};
/* mark for precompiled code ('<esc>Lua') */
-const LUA_SIGNATURE = "\x1bLua";
+const LUA_SIGNATURE = to_luastring("\x1bLua");
const LUA_VERSION_MAJOR = "5";
const LUA_VERSION_MINOR = "3";
@@ -22,16 +206,6 @@ const LUA_RELEASE = LUA_VERSION + "." + LUA_VERSION_RELEASE;
const LUA_COPYRIGHT = LUA_RELEASE + " Copyright (C) 1994-2017 Lua.org, PUC-Rio";
const LUA_AUTHORS = "R. Ierusalimschy, L. H. de Figueiredo, W. Celes";
-const FENGARI_VERSION_MAJOR = "0";
-const FENGARI_VERSION_MINOR = "0";
-const FENGARI_VERSION_NUM = 1;
-const FENGARI_VERSION_RELEASE = "1";
-
-const FENGARI_VERSION = "Fengari " + FENGARI_VERSION_MAJOR + "." + FENGARI_VERSION_MINOR;
-const FENGARI_RELEASE = FENGARI_VERSION + "." + FENGARI_VERSION_RELEASE;
-const FENGARI_AUTHORS = "B. Giannangeli, Daurnimator";
-const FENGARI_COPYRIGHT = FENGARI_RELEASE + " Copyright (C) 2017 " + FENGARI_AUTHORS + "\nBased on: " + LUA_COPYRIGHT;
-
const LUA_VERSUFFIX = "_" + LUA_VERSION_MAJOR + "_" + LUA_VERSION_MINOR;
const LUA_INIT_VAR = "LUA_INIT";
@@ -71,8 +245,6 @@ constant_types.LUA_TLCL = constant_types.LUA_TFUNCTION | (0 << 4); /* Lua closu
constant_types.LUA_TLCF = constant_types.LUA_TFUNCTION | (1 << 4); /* light C function */
constant_types.LUA_TCCL = constant_types.LUA_TFUNCTION | (2 << 4); /* C closure */
-const CT = constant_types;
-
/*
** Comparison and arithmetic functions
*/
@@ -98,7 +270,7 @@ const LUA_OPLE = 2;
const LUA_MINSTACK = 20;
-const LUA_REGISTRYINDEX = -luaconf.LUAI_MAXSTACK - 1000;
+const LUA_REGISTRYINDEX = -LUAI_MAXSTACK - 1000;
const lua_upvalueindex = function(i) {
return LUA_REGISTRYINDEX - i;
@@ -110,7 +282,6 @@ const LUA_RIDX_GLOBALS = 2;
const LUA_RIDX_LAST = LUA_RIDX_GLOBALS;
class lua_Debug {
-
constructor() {
this.event = NaN;
this.name = null; /* (n) */
@@ -128,130 +299,8 @@ class lua_Debug {
/* private part */
this.i_ci = null; /* active function */
}
-
-}
-
-const string_of = Uint8Array.of.bind(Uint8Array);
-
-const is_luastring = function(s) {
- return s instanceof Uint8Array;
-};
-
-/* test two lua strings for equality */
-const luastring_cmp = function(a, b) {
- return a === b || (a.length === b.length && a.join() === b.join());
-};
-
-const to_jsstring = function(value, from, to) {
- assert(is_luastring(value), "jsstring expects a Uint8Array");
-
- if (to === void 0) {
- to = value.length;
- } else {
- to = Math.min(value.length, to);
- }
-
- let str = "";
- for (let i = (from!==void 0?from:0); i < to;) {
- let u;
- let u0 = value[i++];
- if (u0 < 0x80) {
- /* single byte sequence */
- u = u0;
- } else if (u0 < 0xC2 || u0 > 0xF4) {
- throw RangeError("cannot convert invalid utf8 to javascript string");
- } else if (u0 <= 0xDF) {
- /* two byte sequence */
- if (i >= to) throw RangeError("cannot convert invalid utf8 to javascript string");
- let u1 = value[i++];
- if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
- u = ((u0 & 0x1F) << 6) + (u1 & 0x3F);
- } else if (u0 <= 0xEF) {
- /* three byte sequence */
- if (i+1 >= to) throw RangeError("cannot convert invalid utf8 to javascript string");
- let u1 = value[i++];
- if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
- let u2 = value[i++];
- if ((u2&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
- u = ((u0 & 0x0F) << 12) + ((u1 & 0x3F) << 6) + (u2 & 0x3F);
- } else {
- /* four byte sequence */
- if (i+2 >= to) throw RangeError("cannot convert invalid utf8 to javascript string");
- let u1 = value[i++];
- if ((u1&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
- let u2 = value[i++];
- if ((u2&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
- let u3 = value[i++];
- if ((u3&0xC0) !== 0x80) throw RangeError("cannot convert invalid utf8 to javascript string");
- u = ((u0 & 0x07) << 18) + ((u1 & 0x3F) << 12) + ((u2 & 0x3F) << 6) + (u3 & 0x3F);
- }
- str += String.fromCodePoint(u);
- }
- return str;
-};
-
-const uri_allowed = {}; /* bytes allowed unescaped in a uri */
-for (let c of ";,/?:@&=+$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,-_.!~*'()#") {
- uri_allowed[c.charCodeAt(0)] = true;
}
-/* utility function to convert a lua string to a js string with uri escaping */
-const to_uristring = function(a) {
- let s = "";
- for (let i=0; i<a.length; i++) {
- let v = a[i];
- if (uri_allowed[v]) {
- s += String.fromCharCode(v);
- } else {
- s += "%" + (v<0x10?"0":"") + v.toString(16);
- }
- }
- return s;
-};
-
-const to_luastring_cache = {};
-
-const to_luastring = function(str, cache) {
- assert(typeof str === "string", "to_luastring expects a javascript string");
-
- if (cache) {
- let cached = to_luastring_cache[str];
- if (is_luastring(cached)) return cached;
- }
-
- let outU8Array = Array(str.length); /* array is at *least* going to be length of string */
- let outIdx = 0;
- for (let i = 0; i < str.length; ++i) {
- let u = str.codePointAt(i);
- if (u <= 0x7F) {
- outU8Array[outIdx++] = u;
- } else if (u <= 0x7FF) {
- outU8Array[outIdx++] = 0xC0 | (u >> 6);
- outU8Array[outIdx++] = 0x80 | (u & 63);
- } else if (u <= 0xFFFF) {
- outU8Array[outIdx++] = 0xE0 | (u >> 12);
- outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
- outU8Array[outIdx++] = 0x80 | (u & 63);
- } else {
- i++; /* It was a surrogate pair and hence used up two javascript chars */
- outU8Array[outIdx++] = 0xF0 | (u >> 18);
- outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);
- outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
- outU8Array[outIdx++] = 0x80 | (u & 63);
- }
- }
- outU8Array = Uint8Array.from(outU8Array);
-
- if (cache) to_luastring_cache[str] = outU8Array;
-
- return outU8Array;
-};
-
-const from_userstring = function(str) {
- assert(is_luastring(str), "expects an array of bytes");
- return str;
-};
-
/*
** Event codes
*/
@@ -309,14 +358,16 @@ if (typeof process === "undefined") {
const LUA_CDIR = "./lua/" + LUA_VDIR + "/";
module.exports.LUA_CDIR = LUA_CDIR;
- const LUA_PATH_DEFAULT =
+ const LUA_PATH_DEFAULT = to_luastring(
LUA_LDIR + "?.lua;" + LUA_LDIR + "?/init.lua;" +
LUA_CDIR + "?.lua;" + LUA_CDIR + "?/init.lua;" +
- "./?.lua;./?/init.lua";
+ "./?.lua;./?/init.lua"
+ );
module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT;
- const LUA_CPATH_DEFAULT =
- LUA_CDIR + "?.js;" + LUA_CDIR + "loadall.js;./?.js";
+ const LUA_CPATH_DEFAULT = to_luastring(
+ LUA_CDIR + "?.js;" + LUA_CDIR + "loadall.js;./?.js"
+ );
module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT;
} else if (require('os').platform() === 'win32') {
const LUA_DIRSEP = "\\";
@@ -335,17 +386,19 @@ if (typeof process === "undefined") {
const LUA_SHRDIR = "!\\..\\share\\lua\\" + LUA_VDIR + "\\";
module.exports.LUA_SHRDIR = LUA_SHRDIR;
- const LUA_PATH_DEFAULT =
+ const LUA_PATH_DEFAULT = to_luastring(
LUA_LDIR + "?.lua;" + LUA_LDIR + "?\\init.lua;" +
LUA_CDIR + "?.lua;" + LUA_CDIR + "?\\init.lua;" +
LUA_SHRDIR + "?.lua;" + LUA_SHRDIR + "?\\init.lua;" +
- ".\\?.lua;.\\?\\init.lua";
+ ".\\?.lua;.\\?\\init.lua"
+ );
module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT;
- const LUA_CPATH_DEFAULT =
+ const LUA_CPATH_DEFAULT = to_luastring(
LUA_CDIR + "?.dll;" +
LUA_CDIR + "..\\lib\\lua\\" + LUA_VDIR + "\\?.dll;" +
- LUA_CDIR + "loadall.dll;.\\?.dll";
+ LUA_CDIR + "loadall.dll;.\\?.dll"
+ );
module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT;
} else {
const LUA_DIRSEP = "/";
@@ -360,26 +413,19 @@ if (typeof process === "undefined") {
const LUA_CDIR = LUA_ROOT + "lib/lua/" + LUA_VDIR + "/";
module.exports.LUA_CDIR = LUA_CDIR;
- const LUA_PATH_DEFAULT =
+ const LUA_PATH_DEFAULT = to_luastring(
LUA_LDIR + "?.lua;" + LUA_LDIR + "?/init.lua;" +
LUA_CDIR + "?.lua;" + LUA_CDIR + "?/init.lua;" +
- "./?.lua;./?/init.lua";
+ "./?.lua;./?/init.lua"
+ );
module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT;
- const LUA_CPATH_DEFAULT =
- LUA_CDIR + "?.so;" + LUA_CDIR + "loadall.so;./?.so";
+ const LUA_CPATH_DEFAULT = to_luastring(
+ LUA_CDIR + "?.so;" + LUA_CDIR + "loadall.so;./?.so"
+ );
module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT;
}
-module.exports.CT = CT;
-module.exports.FENGARI_AUTHORS = FENGARI_AUTHORS;
-module.exports.FENGARI_COPYRIGHT = FENGARI_COPYRIGHT;
-module.exports.FENGARI_RELEASE = FENGARI_RELEASE;
-module.exports.FENGARI_VERSION = FENGARI_VERSION;
-module.exports.FENGARI_VERSION_MAJOR = FENGARI_VERSION_MAJOR;
-module.exports.FENGARI_VERSION_MINOR = FENGARI_VERSION_MINOR;
-module.exports.FENGARI_VERSION_NUM = FENGARI_VERSION_NUM;
-module.exports.FENGARI_VERSION_RELEASE = FENGARI_VERSION_RELEASE;
module.exports.LUA_AUTHORS = LUA_AUTHORS;
module.exports.LUA_COPYRIGHT = LUA_COPYRIGHT;
module.exports.LUA_HOOKCALL = LUA_HOOKCALL;
@@ -429,8 +475,10 @@ module.exports.lua_Debug = lua_Debug;
module.exports.lua_upvalueindex = lua_upvalueindex;
module.exports.thread_status = thread_status;
module.exports.is_luastring = is_luastring;
-module.exports.luastring_cmp = luastring_cmp;
-module.exports.string_of = string_of;
+module.exports.luastring_eq = luastring_eq;
+module.exports.luastring_from = luastring_from;
+module.exports.luastring_indexOf = luastring_indexOf;
+module.exports.luastring_of = luastring_of;
module.exports.to_jsstring = to_jsstring;
module.exports.to_luastring = to_luastring;
module.exports.to_uristring = to_uristring;