summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--src/loadlib.js54
-rw-r--r--tests/lib-hello.js.mod8
-rw-r--r--tests/loadlib.js32
4 files changed, 85 insertions, 11 deletions
diff --git a/README.md b/README.md
index 8b31831..16701df 100644
--- a/README.md
+++ b/README.md
@@ -27,11 +27,11 @@
- [x] `package.config`
- [x] `package.cpath`
- [x] `package.loaded`
+ - [x] `package.loadlib`
- [x] `package.path`
- [x] `package.preload`
- [x] `package.searchers`
- [x] `require`
- - [ ] `package.loadlib`
- [ ] `package.searchpath`
- [ ] io
- [x] `file:__tostring()`
diff --git a/src/loadlib.js b/src/loadlib.js
index 5ed4703..f25e5dc 100644
--- a/src/loadlib.js
+++ b/src/loadlib.js
@@ -34,20 +34,38 @@ const AUXMARK = [1];
const LIB_FAIL = "absent";
const DLMSG = "dynamic libraries not enabled; check your Lua installation";
+/*
+** load JS library in file 'path'. If 'seeglb', load with all names in
+** the library global.
+** Returns the library; in case of error, returns NULL plus an
+** error string in the stack.
+*/
+const lsys_load = function(L, path) {
+ try {
+ path = lua.to_jsstring(path);
-const lsys_unloadlib = function(lib) {
-};
-
+ // Relative path ?
+ if (path.startsWith('.'))
+ path = `${process.env.PWD}/${path}`;
-const lsys_load = function(L, path, seeglb) {
- lua.lua_pushliteral(L, DLMSG);
- return null;
+ return require(path);
+ } catch (e) {
+ lua.lua_pushjsstring(L, e.message);
+ }
};
-
+/*
+** Try to find a function named 'sym' in library 'lib'.
+** Returns the function; in case of error, returns NULL plus an
+** error string in the stack.
+*/
const lsys_sym = function(L, lib, sym) {
- lua.lua_pushliteral(L, DLMSG);
- return null;
+ let f = lib[lua.to_jsstring(sym)];
+
+ if (f && typeof f === 'function')
+ return f;
+
+ lua.lua_pushliteral(L, `'${lua.to_jsstring(sym)}'`);
};
/*
@@ -109,6 +127,20 @@ const lookforfunc = function(L, path, sym) {
}
};
+const ll_loadlib = function(L) {
+ let path = lauxlib.luaL_checkstring(L, 1);
+ let init = lauxlib.luaL_checkstring(L, 2);
+ let stat = lookforfunc(L, path, init);
+ if (stat === 0) /* no errors? */
+ return 1; /* return the loaded function */
+ else { /* error; error message is on stack top */
+ lua.lua_pushnil(L);
+ lua.lua_insert(L, -2);
+ lua.lua_pushjsstring(L, (stat === ERRLIB) ? LIB_FAIL : "init");
+ return 3; /* return nil, error message, and where */
+ }
+};
+
/*
** Set a path
*/
@@ -315,7 +347,9 @@ const ll_require = function(L) {
return 1;
};
-const pk_funcs = {};
+const pk_funcs = {
+ "loadlib": ll_loadlib
+};
const ll_funcs = {
"require": ll_require
diff --git a/tests/lib-hello.js.mod b/tests/lib-hello.js.mod
new file mode 100644
index 0000000..d4c02e1
--- /dev/null
+++ b/tests/lib-hello.js.mod
@@ -0,0 +1,8 @@
+const lua = require('../src/lua.js');
+
+module.exports = {
+ "hello": function(L) {
+ lua.lua_pushliteral(L, "hello from js lib");
+ return 1;
+ }
+};
diff --git a/tests/loadlib.js b/tests/loadlib.js
index 933991c..b840bf5 100644
--- a/tests/loadlib.js
+++ b/tests/loadlib.js
@@ -66,3 +66,35 @@ test('require a file', function (t) {
);
});
+
+
+test('package.loadlib', function (t) {
+ let luaCode = `
+ return package.loadlib('./tests/lib-hello.js.mod', 'hello')()
+ `, L;
+
+ t.plan(3);
+
+ t.doesNotThrow(function () {
+
+ L = lauxlib.luaL_newstate();
+
+ lauxlib.luaL_openlibs(L);
+
+ lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode));
+
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
+ lua.lua_call(L, 0, -1);
+
+ }, "Lua program ran without error");
+
+ t.strictEqual(
+ lua.lua_tojsstring(L, -1),
+ "hello from js lib",
+ "Correct element(s) on the stack"
+ );
+
+});