aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--src/lauxlib.js133
-rw-r--r--src/loadlib.js61
3 files changed, 91 insertions, 105 deletions
diff --git a/README.md b/README.md
index 4ce66c7..78ed892 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ To address that issue, Lua strings are represented by an array of bytes in Fenga
### `require` and `package.loadlib`
-In the browser `require` and `package.loadlib` try to find a file by making XHR requests.
+In the browser `require` and `package.loadlib` try to find a file by making synchronous XHR requests.
### _Missing_ features
diff --git a/src/lauxlib.js b/src/lauxlib.js
index eb174be..6489dc7 100644
--- a/src/lauxlib.js
+++ b/src/lauxlib.js
@@ -698,62 +698,48 @@ const skipcomment = function(lf) {
let luaL_loadfilex;
-if (!WEB) {
- const fs = require('fs');
-
- class LoadF {
- constructor() {
- this.n = NaN; /* number of pre-read characters */
- this.f = null; /* file being read */
- this.buff = new Buffer(1024); /* area for reading file */
- this.pos = 0; /* current position in file */
- this.err = void 0;
- }
+class LoadF {
+ constructor() {
+ this.n = NaN; /* number of pre-read characters */
+ this.f = null; /* file being read */
+ this.buff = new Buffer(1024); /* area for reading file */
+ this.pos = 0; /* current position in file */
+ this.err = void 0;
}
+}
+if (WEB) {
const getF = function(L, ud) {
let lf = ud;
- let bytes = 0;
- if (lf.n > 0) { /* are there pre-read characters to be read? */
- 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) {
- lf.err = e;
- bytes = 0;
- }
- lf.pos += bytes;
- }
- if (bytes > 0)
- return lf.buff.slice(0, bytes); /* slice on a node.js Buffer is 'free' */
- else return null;
+ let f = lf.f;
+ lf.f = null;
+ return f;
};
getc = function(lf) {
- let b = new Buffer(1);
- let bytes = fs.readSync(lf.f, b, 0, 1, lf.pos);
- lf.pos += bytes;
- return bytes > 0 ? b.readUInt8() : null;
+ return lf.pos < lf.f.length ? lf.f[lf.pos++] : null;
};
luaL_loadfilex = function(L, filename, mode) {
let lf = new LoadF();
let fnameindex = lua.lua_gettop(L) + 1; /* index of filename on the stack */
if (filename === null) {
- lua.lua_pushliteral(L, "=stdin");
- lf.f = process.stdin.fd;
+ throw new Error("Can't read stdin in the browser");
} else {
let jsfilename = lua.to_jsstring(filename);
lua.lua_pushfstring(L, "@%s", filename);
- try {
- lf.f = fs.openSync(jsfilename, "r");
- if (!fs.fstatSync(lf.f).isFile())
- throw new Error(`${jsfilename} is not a readable file`);
- } catch (e) {
- return errfile(L, "open", fnameindex, e);
+
+ let xhr = new XMLHttpRequest();
+ xhr.open("GET", jsfilename, false);
+ // TODO: find a way to load bytes instead of js string
+ xhr.send();
+
+ if (xhr.status >= 200 && xhr.status <= 299) {
+ /* TODO: Synchronous xhr alway return a js string */
+ lf.f = lua.to_luastring(xhr.response);
+ } else {
+ lf.err = xhr.status;
+ return errfile(L, "open", fnameindex, { message: `${xhr.status}: ${xhr.statusText}` });
}
}
let com = skipcomment(lf);
@@ -767,7 +753,6 @@ if (!WEB) {
lf.buff[lf.n++] = com.c; /* 'c' is the first character of the stream */
let status = lua.lua_load(L, getF, lf, lua.lua_tostring(L, -1), mode);
let readstatus = lf.err;
- if (filename) try { fs.closeSync(lf.f); } catch(e) {} /* close file (even in case of errors) */
if (readstatus) {
lua.lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
return errfile(L, "read", fnameindex, readstatus);
@@ -776,47 +761,51 @@ if (!WEB) {
return status;
};
} else {
- class LoadF {
- constructor() {
- this.n = NaN; /* number of pre-read characters */
- this.f = null; /* file being read */
- this.buff = new Buffer(1024); /* area for reading file */
- this.pos = 0; /* current position in file */
- this.err = void 0;
- }
- }
+ const fs = require('fs');
const getF = function(L, ud) {
let lf = ud;
- let f = lf.f;
- lf.f = null;
- return f;
+ let bytes = 0;
+ if (lf.n > 0) { /* are there pre-read characters to be read? */
+ 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) {
+ lf.err = e;
+ bytes = 0;
+ }
+ lf.pos += bytes;
+ }
+ if (bytes > 0)
+ return lf.buff.slice(0, bytes); /* slice on a node.js Buffer is 'free' */
+ else return null;
};
getc = function(lf) {
- return lf.pos < lf.f.length ? lf.f[lf.pos++] : null;
+ let b = new Buffer(1);
+ let bytes = fs.readSync(lf.f, b, 0, 1, lf.pos);
+ lf.pos += bytes;
+ return bytes > 0 ? b.readUInt8() : null;
};
luaL_loadfilex = function(L, filename, mode) {
let lf = new LoadF();
let fnameindex = lua.lua_gettop(L) + 1; /* index of filename on the stack */
if (filename === null) {
- throw new Error("Can't read stdin in the browser");
+ lua.lua_pushliteral(L, "=stdin");
+ lf.f = process.stdin.fd;
} else {
let jsfilename = lua.to_jsstring(filename);
- lua.lua_pushliteral(L, `@${jsfilename}`);
-
- let xhr = new XMLHttpRequest();
- xhr.open("GET", jsfilename, false);
- // TODO: find a way to load bytes instead of js string
- xhr.send();
-
- if (xhr.status >= 200 && xhr.status <= 299) {
- /* TODO: Synchronous xhr alway return a js string */
- lf.f = lua.to_luastring(xhr.response);
- } else {
- lf.err = xhr.status;
- return errfile(L, "open", fnameindex, { message: `${xhr.status}: ${xhr.statusText}` });
+ lua.lua_pushfstring(L, "@%s", filename);
+ try {
+ lf.f = fs.openSync(jsfilename, "r");
+ if (!fs.fstatSync(lf.f).isFile())
+ throw new Error(`${jsfilename} is not a readable file`);
+ } catch (e) {
+ return errfile(L, "open", fnameindex, e);
}
}
let com = skipcomment(lf);
@@ -830,6 +819,7 @@ if (!WEB) {
lf.buff[lf.n++] = com.c; /* 'c' is the first character of the stream */
let status = lua.lua_load(L, getF, lf, lua.lua_tostring(L, -1), mode);
let readstatus = lf.err;
+ if (filename) try { fs.closeSync(lf.f); } catch(e) {} /* close file (even in case of errors) */
if (readstatus) {
lua.lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
return errfile(L, "read", fnameindex, readstatus);
@@ -847,10 +837,6 @@ const luaL_dofile = function(L, filename) {
return (luaL_loadfile(L, filename) || lua.lua_pcall(L, 0, lua.LUA_MULTRET, 0));
};
-module.exports.luaL_dofile = luaL_dofile;
-module.exports.luaL_loadfilex = luaL_loadfilex;
-module.exports.luaL_loadfile = luaL_loadfile;
-
const lua_writestringerror = function(s) {
if (process.stderr) process.stderr.write(s);
else console.error(s);
@@ -895,6 +881,7 @@ module.exports.luaL_checkstring = luaL_checkstring;
module.exports.luaL_checktype = luaL_checktype;
module.exports.luaL_checkudata = luaL_checkudata;
module.exports.luaL_checkversion = luaL_checkversion;
+module.exports.luaL_dofile = luaL_dofile;
module.exports.luaL_dostring = luaL_dostring;
module.exports.luaL_error = luaL_error;
module.exports.luaL_execresult = luaL_execresult;
@@ -906,6 +893,8 @@ module.exports.luaL_gsub = luaL_gsub;
module.exports.luaL_len = luaL_len;
module.exports.luaL_loadbuffer = luaL_loadbuffer;
module.exports.luaL_loadbufferx = luaL_loadbufferx;
+module.exports.luaL_loadfile = luaL_loadfile;
+module.exports.luaL_loadfilex = luaL_loadfilex;
module.exports.luaL_loadstring = luaL_loadstring;
module.exports.luaL_newlib = luaL_newlib;
module.exports.luaL_newlibtable = luaL_newlibtable;
diff --git a/src/loadlib.js b/src/loadlib.js
index 9400bb0..ecb5cd2 100644
--- a/src/loadlib.js
+++ b/src/loadlib.js
@@ -34,20 +34,36 @@ const AUXMARK = [1];
** Returns the library; in case of error, returns NULL plus an
** error string in the stack.
*/
-let lsys_load = function(L, path) {
- try {
- path = lua.to_jsstring(path);
+let lsys_load;
+if (WEB) {
+ lsys_load = function(L, path) {
+ let xhr = new XMLHttpRequest();
+ xhr.open("GET", lua.to_jsstring(path), false);
+ xhr.send();
- // Relative path ?
- if (path.startsWith('.'))
- path = `${process.env.PWD}/${path}`;
+ if (xhr.status >= 200 && xhr.status <= 299) {
+ return eval(xhr.response);
+ } else {
+ lua.lua_pushstring(L, lua.to_luastring(`${xhr.status}: ${xhr.statusText}`));
+ return null;
+ }
+ };
+} else {
+ lsys_load = function(L, path) {
+ try {
+ path = lua.to_jsstring(path);
- return require(path);
- } catch (e) {
- lua.lua_pushstring(L, lua.to_luastring(e.message));
- return null;
- }
-};
+ // Relative path ?
+ if (path.startsWith('.'))
+ path = `${process.env.PWD}/${path}`;
+
+ return require(path);
+ } catch (e) {
+ lua.lua_pushstring(L, lua.to_luastring(e.message));
+ return null;
+ }
+ };
+}
/*
** Try to find a function named 'sym' in library 'lib'.
@@ -65,22 +81,6 @@ const lsys_sym = function(L, lib, sym) {
}
};
-if (WEB) {
- lsys_load = function(L, path) {
- let xhr = new XMLHttpRequest();
- xhr.open("GET", lua.to_jsstring(path), false);
- xhr.send();
- /* TODO: subresource integrity check? */
-
- if (xhr.status === 200) {
- return eval(xhr.response);
- } else {
- lua.lua_pushstring(L, lua.to_luastring(`${xhr.status}: ${xhr.statusText}`));
- return null;
- }
- };
-}
-
/*
** return registry.LUA_NOENV as a boolean
*/
@@ -91,9 +91,7 @@ const noenv = function(L) {
return b;
};
-let readable = function() {
- return false;
-};
+let readable;
// Only with Node
if (!WEB) {
@@ -118,7 +116,6 @@ if (!WEB) {
/* Following GET request done by searcher_Web will be cached */
xhr.open("GET", lua.to_jsstring(filename), false);
xhr.send();
- /* TODO: subresource integrity check? */
return xhr.status >= 200 && xhr.status <= 299;
};