From b62742903651b2e621fb34407b5f8ca38558a84a Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Thu, 27 Apr 2023 11:59:40 +0800 Subject: [PATCH 01/14] Generate type definitions with tsc --- package.json | 7 +++++-- tsconfig.json | 10 ++++++++++ yarn.lock | 5 +++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 tsconfig.json diff --git a/package.json b/package.json index 2ea7e30..3feaade 100644 --- a/package.json +++ b/package.json @@ -3,13 +3,15 @@ "version": "0.1.4", "description": "A Lua VM written in JS ES6 targeting the browser", "main": "src/fengari.js", + "types": "dist/fengari.d.ts", "directories": { "lib": "src", "test": "test" }, "scripts": { + "emit": "tsc", "lint": "eslint src/ test/", - "prepublishOnly": "git diff-index --quiet --cached HEAD -- && npm run lint && npm run test", + "prepublishOnly": "git diff-index --quiet --cached HEAD -- && npm run lint && npm run emit && npm run test", "test": "jest" }, "repository": { @@ -31,7 +33,8 @@ "homepage": "https://github.com/fengari-lua/fengari#readme", "devDependencies": { "eslint": "^5.15.1", - "jest": "^24.5.0" + "jest": "^24.5.0", + "typescript": "^5.0.4" }, "dependencies": { "readline-sync": "^1.4.9", diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6465c60 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,10 @@ +{ + "include": ["src/**/*"], + "compilerOptions": { + "allowJs": true, + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "dist", + "declarationMap": true + } +} diff --git a/yarn.lock b/yarn.lock index b4a1d75..0f5de9c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3488,6 +3488,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +typescript@^5.0.4: + version "5.0.4" + resolved "https://registry.npmmirror.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + uglify-js@^3.1.4: version "3.4.9" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" From 40bfd91d2733b84e127e5d7667fd70d4bf098514 Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Thu, 27 Apr 2023 12:01:03 +0800 Subject: [PATCH 02/14] src/defs.js: add jsdoc with typing info --- src/defs.js | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/src/defs.js b/src/defs.js index daa5f70..5b9470c 100644 --- a/src/defs.js +++ b/src/defs.js @@ -4,6 +4,11 @@ * Fengari specific string conversion functions */ +/** + * Converts a JavaScript string into a Uint8Array (used a Lua string). + * + * @type {function(string):Uint8Array} + */ let luastring_from; if (typeof Uint8Array.from === "function") { luastring_from = Uint8Array.from.bind(Uint8Array); @@ -17,6 +22,11 @@ if (typeof Uint8Array.from === "function") { }; } +/** + * Returns the index of the first occurrence of the character in the Lua string. + * + * @type {function(Uint8Array, number, number?):number} + */ let luastring_indexOf; if (typeof (new Uint8Array().indexOf) === "function") { luastring_indexOf = function(s, v, i) { @@ -31,6 +41,11 @@ if (typeof (new Uint8Array().indexOf) === "function") { }; } +/** + * Constructs a Lua string from characters. + * + * @type {function(...number):Uint8Array} + */ let luastring_of; if (typeof Uint8Array.of === "function") { luastring_of = Uint8Array.of.bind(Uint8Array); @@ -40,11 +55,22 @@ if (typeof Uint8Array.of === "function") { }; } +/** + * Returns `true` if the object can be used as a Lua string. + * + * @param {any} s the object + */ const is_luastring = function(s) { return s instanceof Uint8Array; }; -/* test two lua strings for equality */ +/** + * Tests two Lua strings for equality. + * + * @param {Uint8Array} a str 1 + * @param {Uint8Array} b str 2 + * @returns {boolean} + */ const luastring_eq = function(a, b) { if (a !== b) { let len = a.length; @@ -57,6 +83,16 @@ const luastring_eq = function(a, b) { }; const unicode_error_message = "cannot convert invalid utf8 to javascript string"; + +/** + * Converts a Lua string (in UTF-8) to a normal JavaScript string. + * + * @param {Uint8Array} value the Lua string + * @param {number?} from the staring index + * @param {number?} to the ending index + * @param {boolean?} replacement_char whether to replace invalid utf8 chars + * @returns {string} + */ const to_jsstring = function(value, from, to, replacement_char) { if (!is_luastring(value)) throw new TypeError("to_jsstring expects a Uint8Array"); @@ -159,7 +195,12 @@ const uri_allowed = (";,/?:@&=+$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV return uri_allowed; }, {}); -/* utility function to convert a lua string to a js string with uri escaping */ +/** + * Utility function to convert a Lua string to a JavaScript string with URI escaping. + * + * @param {Uint8Array} a the string + * @returns {string} + */ const to_uristring = function(a) { if (!is_luastring(a)) throw new TypeError("to_uristring expects a Uint8Array"); let s = ""; @@ -176,6 +217,11 @@ const to_uristring = function(a) { const to_luastring_cache = {}; +/** + * @param {string} str + * @param {object?} cache + * @returns {Uint8Array} + */ const to_luastring = function(str, cache) { if (typeof str !== "string") throw new TypeError("to_luastring expects a javascript string"); @@ -224,6 +270,15 @@ const to_luastring = function(str, cache) { return outU8Array; }; +/** + * Returns a Lua string. + * + * If `str` is already a Lua string, it returns it as is. + * Otherwise, it tries to convert it. + * + * @param {string|Uint8Array} str + * @returns + */ const from_userstring = function(str) { if (!is_luastring(str)) { if (typeof str === "string") { @@ -269,7 +324,6 @@ module.exports.LUA_RELEASE = LUA_RELEASE; module.exports.LUA_COPYRIGHT = LUA_COPYRIGHT; module.exports.LUA_AUTHORS = LUA_AUTHORS; - const thread_status = { LUA_OK: 0, LUA_YIELD: 1, @@ -291,7 +345,15 @@ const constant_types = { LUA_TFUNCTION: 6, LUA_TUSERDATA: 7, LUA_TTHREAD: 8, - LUA_NUMTAGS: 9 + LUA_NUMTAGS: 9, + + LUA_TSHRSTR: 0, + LUA_TLNGSTR: 0, + LUA_TNUMFLT: 0, + LUA_TNUMINT: 0, + LUA_TLCL: 0, + LUA_TLCF: 0, + LUA_TCCL: 0, }; constant_types.LUA_TSHRSTR = constant_types.LUA_TSTRING | (0 << 4); /* short strings */ @@ -332,6 +394,12 @@ const LUA_MINSTACK = 20; const { LUAI_MAXSTACK } = require('./luaconf.js'); const LUA_REGISTRYINDEX = -LUAI_MAXSTACK - 1000; +/** + * Returns a pseudo-index for the i-th upvalue. + * + * @param {number} i + * @returns {number} + */ const lua_upvalueindex = function(i) { return LUA_REGISTRYINDEX - i; }; From b400812c2308c49da226727afb0afda9d63b4b07 Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Thu, 27 Apr 2023 12:11:50 +0800 Subject: [PATCH 03/14] src/luaconf.js: add typing info --- src/luaconf.js | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/luaconf.js b/src/luaconf.js index 5fb91cd..66757da 100644 --- a/src/luaconf.js +++ b/src/luaconf.js @@ -126,6 +126,7 @@ if (typeof process === "undefined") { ** This macro is not on by default even in compatibility mode, ** because this is not really an incompatibility. */ +/** @type {boolean} */ const LUA_COMPAT_FLOATSTRING = conf.LUA_COMPAT_FLOATSTRING || false; const LUA_MAXINTEGER = 2147483647; @@ -137,6 +138,7 @@ const LUA_MININTEGER = -2147483648; ** its only purpose is to stop Lua from consuming unlimited stack ** space (and to reserve some numbers for pseudo-indices). */ +/** @type {number} */ const LUAI_MAXSTACK = conf.LUAI_MAXSTACK || 1000000; /* @@ -144,16 +146,29 @@ const LUAI_MAXSTACK = conf.LUAI_MAXSTACK || 1000000; @@ of a function in debug information. ** CHANGE it if you want a different size. */ +/** @type {number} */ const LUA_IDSIZE = conf.LUA_IDSIZE || (60-1); /* fengari uses 1 less than lua as we don't embed the null byte */ +/** + * @param {number} n + * @returns {string} + */ const lua_integer2str = function(n) { return String(n); /* should match behaviour of LUA_INTEGER_FMT */ }; +/** + * @param {number} n + * @returns {string} + */ const lua_number2str = function(n) { return String(Number(n.toPrecision(14))); /* should match behaviour of LUA_NUMBER_FMT */ }; +/** + * @param {number} n + * @returns {number|false} + */ const lua_numbertointeger = function(n) { return n >= LUA_MININTEGER && n < -LUA_MININTEGER ? n : false; }; @@ -175,9 +190,15 @@ const lua_getlocaledecpoint = function() { /* @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. */ +/** @type {number} */ const LUAL_BUFFERSIZE = conf.LUAL_BUFFERSIZE || 8192; -// See: http://croquetweak.blogspot.fr/2014/08/deconstructing-floats-frexp-and-ldexp.html +/** + * See: http://croquetweak.blogspot.fr/2014/08/deconstructing-floats-frexp-and-ldexp.html + * + * @param {number} value + * @returns {[number, number]} + */ const frexp = function(value) { if (value === 0) return [value, 0]; var data = new DataView(new ArrayBuffer(8)); @@ -192,6 +213,13 @@ const frexp = function(value) { return [mantissa, exponent]; }; +/** + * See: http://croquetweak.blogspot.fr/2014/08/deconstructing-floats-frexp-and-ldexp.html + * + * @param {number} mantissa + * @param {number} exponent + * @returns {number} + */ const ldexp = function(mantissa, exponent) { var steps = Math.min(3, Math.ceil(Math.abs(exponent) / 1023)); var result = mantissa; From d7bc2fecb411f87fc969e54ed03a218c6d32839d Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Thu, 27 Apr 2023 14:12:14 +0800 Subject: [PATCH 04/14] src/lapi.js: add type info --- src/defs.js | 2 +- src/lapi.js | 455 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lstring.js | 18 ++ 3 files changed, 474 insertions(+), 1 deletion(-) diff --git a/src/defs.js b/src/defs.js index 5b9470c..7b41a1c 100644 --- a/src/defs.js +++ b/src/defs.js @@ -277,7 +277,7 @@ const to_luastring = function(str, cache) { * Otherwise, it tries to convert it. * * @param {string|Uint8Array} str - * @returns + * @returns {Uint8Array} */ const from_userstring = function(str) { if (!is_luastring(str)) { diff --git a/src/lapi.js b/src/lapi.js index 7443fb7..ed88612 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -1,5 +1,9 @@ "use strict"; +/** + * @typedef {import('./lstate').lua_State} lua_State + */ + const { LUA_MULTRET, LUA_OPBNOT, @@ -73,17 +77,31 @@ const isvalid = function(o) { return o !== lobject.luaO_nilobject; }; +/** + * @param {lua_State} L + * @returns {number} + */ const lua_version = function(L) { if (L === null) return LUA_VERSION_NUM; else return L.l_G.version; }; +/** + * @param {lua_State} L + * @param {function?} panicf + * @returns {function?} + */ const lua_atpanic = function(L, panicf) { let old = L.l_G.panic; L.l_G.panic = panicf; return old; }; +/** + * @param {lua_State} L + * @param {function?} errorf + * @returns {function?} + */ const lua_atnativeerror = function(L, errorf) { let old = L.l_G.atnativeerror; L.l_G.atnativeerror = errorf; @@ -130,6 +148,11 @@ const index2addr_ = function(L, idx) { } }; +/** + * @param {lua_State} L + * @param {number} n + * @returns {boolean} + */ const lua_checkstack = function(L, n) { let res; let ci = L.ci; @@ -152,6 +175,11 @@ const lua_checkstack = function(L, n) { return res; }; +/** + * @param {lua_State} from + * @param {lua_State} to + * @param {number} n + */ const lua_xmove = function(from, to, n) { if (from === to) return; api_checknelems(from, n); @@ -173,21 +201,38 @@ const lua_xmove = function(from, to, n) { /* ** convert an acceptable stack index into an absolute index */ +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_absindex = function(L, idx) { return (idx > 0 || idx <= LUA_REGISTRYINDEX) ? idx : (L.top - L.ci.funcOff) + idx; }; +/** + * @param {lua_State} L + * @returns {number} + */ const lua_gettop = function(L) { return L.top - (L.ci.funcOff + 1); }; +/** + * @param {lua_State} L + * @param {number} idx + */ const lua_pushvalue = function(L, idx) { lobject.pushobj2s(L, index2addr(L, idx)); api_check(L, L.top <= L.ci.top, "stack overflow"); }; +/** + * @param {lua_State} L + * @param {number} idx + */ const lua_settop = function(L, idx) { let func = L.ci.funcOff; let newtop; @@ -201,6 +246,10 @@ const lua_settop = function(L, idx) { ldo.adjust_top(L, newtop); }; +/** + * @param {lua_State} L + * @param {number} n + */ const lua_pop = function(L, n) { lua_settop(L, -n - 1); }; @@ -218,6 +267,11 @@ const reverse = function(L, from, to) { ** Let x = AB, where A is a prefix of length 'n'. Then, ** rotate x n === BA. But BA === (A^r . B^r)^r. */ +/** + * @param {lua_State} L + * @param {number} idx + * @param {number} n + */ const lua_rotate = function(L, idx, n) { let t = L.top - 1; let pIdx = index2addr_(L, idx); @@ -230,20 +284,37 @@ const lua_rotate = function(L, idx, n) { reverse(L, pIdx, L.top - 1); }; +/** + * @param {lua_State} L + * @param {number} fromidx + * @param {number} toidx + */ const lua_copy = function(L, fromidx, toidx) { let from = index2addr(L, fromidx); index2addr(L, toidx).setfrom(from); }; +/** + * @param {lua_State} L + * @param {number} idx + */ const lua_remove = function(L, idx) { lua_rotate(L, idx, -1); lua_pop(L, 1); }; +/** + * @param {lua_State} L + * @param {number} idx + */ const lua_insert = function(L, idx) { lua_rotate(L, idx, 1); }; +/** + * @param {lua_State} L + * @param {number} idx + */ const lua_replace = function(L, idx) { lua_copy(L, -1, idx); lua_pop(L, 1); @@ -253,23 +324,40 @@ const lua_replace = function(L, idx) { ** push functions (JS -> stack) */ +/** + * @param {lua_State} L + */ const lua_pushnil = function(L) { L.stack[L.top] = new TValue(LUA_TNIL, null); api_incr_top(L); }; +/** + * @param {lua_State} L + * @param {number} n + */ const lua_pushnumber = function(L, n) { fengari_argcheck(typeof n === "number"); L.stack[L.top] = new TValue(LUA_TNUMFLT, n); api_incr_top(L); }; +/** + * @param {lua_State} L + * @param {number} n + */ const lua_pushinteger = function(L, n) { fengari_argcheckinteger(n); L.stack[L.top] = new TValue(LUA_TNUMINT, n); api_incr_top(L); }; +/** + * @param {lua_State} L + * @param {string|Uint8Array} s + * @param {number} len + * @returns {any} + */ const lua_pushlstring = function(L, s, len) { fengari_argcheckinteger(len); let ts; @@ -286,6 +374,11 @@ const lua_pushlstring = function(L, s, len) { return ts.value; }; +/** + * @param {lua_State} L + * @param {string|Uint8Array} s + * @returns {any} + */ const lua_pushstring = function (L, s) { if (s === undefined || s === null) { L.stack[L.top] = new TValue(LUA_TNIL, null); @@ -299,17 +392,34 @@ const lua_pushstring = function (L, s) { return s; }; +/** + * @param {lua_State} L + * @param {string|Uint8Array} fmt + * @param {any[]} argp + * @returns {any} + */ const lua_pushvfstring = function (L, fmt, argp) { fmt = from_userstring(fmt); return lobject.luaO_pushvfstring(L, fmt, argp); }; +/** + * @param {lua_State} L + * @param {string|Uint8Array} fmt + * @param {any} argp + * @returns {any} + */ const lua_pushfstring = function (L, fmt, ...argp) { fmt = from_userstring(fmt); return lobject.luaO_pushvfstring(L, fmt, argp); }; /* Similar to lua_pushstring, but takes a JS string */ +/** + * @param {lua_State} L + * @param {string} s + * @returns {any} + */ const lua_pushliteral = function (L, s) { if (s === undefined || s === null) { L.stack[L.top] = new TValue(LUA_TNIL, null); @@ -325,6 +435,11 @@ const lua_pushliteral = function (L, s) { return s; }; +/** + * @param {lua_State} L + * @param {function} fn + * @param {number} n + */ const lua_pushcclosure = function(L, fn, n) { fengari_argcheck(typeof fn === "function"); fengari_argcheckinteger(n); @@ -347,28 +462,47 @@ const lua_pushcclosure = function(L, fn, n) { const lua_pushjsclosure = lua_pushcclosure; +/** + * @param {lua_State} L + * @param {function} fn + */ const lua_pushcfunction = function(L, fn) { lua_pushcclosure(L, fn, 0); }; const lua_pushjsfunction = lua_pushcfunction; +/** + * @param {lua_State} L + * @param {number} b + */ const lua_pushboolean = function(L, b) { L.stack[L.top] = new TValue(LUA_TBOOLEAN, !!b); api_incr_top(L); }; +/** + * @param {lua_State} L + * @param {any} p + */ const lua_pushlightuserdata = function(L, p) { L.stack[L.top] = new TValue(LUA_TLIGHTUSERDATA, p); api_incr_top(L); }; +/** + * @param {lua_State} L + * @returns {boolean} + */ const lua_pushthread = function(L) { L.stack[L.top] = new TValue(LUA_TTHREAD, L); api_incr_top(L); return L.l_G.mainthread === L; }; +/** + * @param {lua_State} L + */ const lua_pushglobaltable = function(L) { lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); }; @@ -391,10 +525,18 @@ const auxsetstr = function(L, t, k) { delete L.stack[--L.top]; }; +/** + * @param {lua_State} L + * @param {Uint8Array} name + */ const lua_setglobal = function(L, name) { auxsetstr(L, ltable.luaH_getint(L.l_G.l_registry.value, LUA_RIDX_GLOBALS), name); }; +/** + * @param {lua_State} L + * @param {number} objindex + */ const lua_setmetatable = function(L, objindex) { api_checknelems(L, 1); let mt; @@ -422,6 +564,10 @@ const lua_setmetatable = function(L, objindex) { return true; }; +/** + * @param {lua_State} L + * @param {number} idx + */ const lua_settable = function(L, idx) { api_checknelems(L, 2); let t = index2addr(L, idx); @@ -430,10 +576,20 @@ const lua_settable = function(L, idx) { delete L.stack[--L.top]; }; +/** + * @param {lua_State} L + * @param {number} idx + * @param {Uint8Array} k + */ const lua_setfield = function(L, idx, k) { auxsetstr(L, index2addr(L, idx), k); }; +/** + * @param {lua_State} L + * @param {number} idx + * @param {number} n + */ const lua_seti = function(L, idx, n) { fengari_argcheckinteger(n); api_checknelems(L, 1); @@ -446,6 +602,10 @@ const lua_seti = function(L, idx, n) { delete L.stack[--L.top]; }; +/** + * @param {lua_State} L + * @param {number} idx + */ const lua_rawset = function(L, idx) { api_checknelems(L, 2); let o = index2addr(L, idx); @@ -458,6 +618,11 @@ const lua_rawset = function(L, idx) { delete L.stack[--L.top]; }; +/** + * @param {lua_State} L + * @param {number} idx + * @param {number} n + */ const lua_rawseti = function(L, idx, n) { fengari_argcheckinteger(n); api_checknelems(L, 1); @@ -467,6 +632,11 @@ const lua_rawseti = function(L, idx, n) { delete L.stack[--L.top]; }; +/** + * @param {lua_State} L + * @param {number} idx + * @param {any} p + */ const lua_rawsetp = function(L, idx, p) { api_checknelems(L, 1); let o = index2addr(L, idx); @@ -489,6 +659,12 @@ const auxgetstr = function(L, t, k) { return L.stack[L.top - 1].ttnov(); }; +/** + * @param {lua_State} L + * @param {number} idx + * @param {number} n + * @returns {number} + */ const lua_rawgeti = function(L, idx, n) { let t = index2addr(L, idx); fengari_argcheckinteger(n); @@ -498,6 +674,12 @@ const lua_rawgeti = function(L, idx, n) { return L.stack[L.top - 1].ttnov(); }; +/** + * @param {lua_State} L + * @param {number} idx + * @param {any} p + * @returns {number} + */ const lua_rawgetp = function(L, idx, p) { let t = index2addr(L, idx); api_check(L, t.ttistable(), "table expected"); @@ -507,6 +689,11 @@ const lua_rawgetp = function(L, idx, p) { return L.stack[L.top - 1].ttnov(); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_rawget = function(L, idx) { let t = index2addr(L, idx); api_check(L, t.ttistable(t), "table expected"); @@ -515,6 +702,11 @@ const lua_rawget = function(L, idx) { }; // narray and nrec are mostly useless for this implementation +/** + * @param {lua_State} L + * @param {number} narray + * @param {number} nrec + */ const lua_createtable = function(L, narray, nrec) { let t = new lobject.TValue(LUA_TTABLE, ltable.luaH_new(L)); L.stack[L.top] = t; @@ -525,6 +717,11 @@ const luaS_newudata = function(L, size) { return new lobject.Udata(L, size); }; +/** + * @param {lua_State} L + * @param {number} size + * @returns {any} + */ const lua_newuserdata = function(L, size) { let u = luaS_newudata(L, size); L.stack[L.top] = new lobject.TValue(LUA_TUSERDATA, u); @@ -557,6 +754,12 @@ const aux_upvalue = function(L, fi, n) { } }; +/** + * @param {lua_State} L + * @param {number} funcindex + * @param {number} n + * @returns {any} + */ const lua_getupvalue = function(L, funcindex, n) { let up = aux_upvalue(L, index2addr(L, funcindex), n); if (up) { @@ -569,6 +772,12 @@ const lua_getupvalue = function(L, funcindex, n) { return null; }; +/** + * @param {lua_State} L + * @param {number} funcindex + * @param {number} n + * @returns {any} + */ const lua_setupvalue = function(L, funcindex, n) { let fi = index2addr(L, funcindex); api_checknelems(L, 1); @@ -583,15 +792,28 @@ const lua_setupvalue = function(L, funcindex, n) { return null; }; +/** + * @param {lua_State} L + */ const lua_newtable = function(L) { lua_createtable(L, 0, 0); }; +/** + * @param {lua_State} L + * @param {Uint8Array} n + * @param {function} f + */ const lua_register = function(L, n, f) { lua_pushcfunction(L, f); lua_setglobal(L, n); }; +/** + * @param {lua_State} L + * @param {number} objindex + * @returns {number} + */ const lua_getmetatable = function(L, objindex) { let obj = index2addr(L, objindex); let mt; @@ -615,6 +837,11 @@ const lua_getmetatable = function(L, objindex) { return res; }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_getuservalue = function(L, idx) { let o = index2addr(L, idx); api_check(L, o.ttisfulluserdata(), "full userdata expected"); @@ -624,16 +851,33 @@ const lua_getuservalue = function(L, idx) { return L.stack[L.top - 1].ttnov(); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_gettable = function(L, idx) { let t = index2addr(L, idx); lvm.luaV_gettable(L, t, L.stack[L.top - 1], L.top - 1); return L.stack[L.top - 1].ttnov(); }; +/** + * @param {lua_State} L + * @param {number} idx + * @param {Uint8Array} k + * @returns {number} + */ const lua_getfield = function(L, idx, k) { return auxgetstr(L, index2addr(L, idx), k); }; +/** + * @param {lua_State} L + * @param {number} idx + * @param {number} n + * @returns {number} + */ const lua_geti = function(L, idx, n) { let t = index2addr(L, idx); fengari_argcheckinteger(n); @@ -643,6 +887,11 @@ const lua_geti = function(L, idx, n) { return L.stack[L.top - 1].ttnov(); }; +/** + * @param {lua_State} L + * @param {Uint8Array} name + * @returns {number} + */ const lua_getglobal = function(L, name) { return auxgetstr(L, ltable.luaH_getint(L.l_G.l_registry.value, LUA_RIDX_GLOBALS), name); }; @@ -651,11 +900,21 @@ const lua_getglobal = function(L, name) { ** access functions (stack -> JS) */ +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_toboolean = function(L, idx) { let o = index2addr(L, idx); return !o.l_isfalse(); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {Uint8Array} + */ const lua_tolstring = function(L, idx) { let o = index2addr(L, idx); @@ -670,6 +929,11 @@ const lua_tolstring = function(L, idx) { const lua_tostring = lua_tolstring; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {string} + */ const lua_tojsstring = function(L, idx) { let o = index2addr(L, idx); @@ -682,11 +946,21 @@ const lua_tojsstring = function(L, idx) { return o.jsstring(); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {DataView} + */ const lua_todataview = function(L, idx) { let u8 = lua_tolstring(L, idx); return new DataView(u8.buffer, u8.byteOffset, u8.byteLength); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_rawlen = function(L, idx) { let o = index2addr(L, idx); switch (o.ttype()) { @@ -702,30 +976,60 @@ const lua_rawlen = function(L, idx) { } }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {function?} + */ const lua_tocfunction = function(L, idx) { let o = index2addr(L, idx); if (o.ttislcf() || o.ttisCclosure()) return o.value; else return null; /* not a C function */ }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_tointeger = function(L, idx) { let n = lua_tointegerx(L, idx); return n === false ? 0 : n; }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_tointegerx = function(L, idx) { return lvm.tointeger(index2addr(L, idx)); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_tonumber = function(L, idx) { let n = lua_tonumberx(L, idx); return n === false ? 0 : n; }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_tonumberx = function(L, idx) { return lvm.tonumber(index2addr(L, idx)); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {any} + */ const lua_touserdata = function(L, idx) { let o = index2addr(L, idx); switch (o.ttnov()) { @@ -737,11 +1041,21 @@ const lua_touserdata = function(L, idx) { } }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {lua_State} + */ const lua_tothread = function(L, idx) { let o = index2addr(L, idx); return o.ttisthread() ? o.value : null; }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {any} + */ const lua_topointer = function(L, idx) { let o = index2addr(L, idx); switch (o.ttype()) { @@ -790,6 +1104,13 @@ const lua_toproxy = function(L, idx) { }; +/** + * @param {lua_State} L + * @param {number} index1 + * @param {number} index2 + * @param {number} op + * @returns {number} + */ const lua_compare = function(L, index1, index2, op) { let o1 = index2addr(L, index1); let o2 = index2addr(L, index2); @@ -808,6 +1129,11 @@ const lua_compare = function(L, index1, index2, op) { return i; }; +/** + * @param {lua_State} L + * @param {Uint8Array} s + * @returns {number} + */ const lua_stringtonumber = function(L, s) { let tv = new TValue(); let sz = lobject.luaO_str2num(s, tv); @@ -822,77 +1148,162 @@ const f_call = function(L, ud) { ldo.luaD_callnoyield(L, ud.funcOff, ud.nresults); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_type = function(L, idx) { let o = index2addr(L, idx); return isvalid(o) ? o.ttnov() : LUA_TNONE; }; +/** + * @param {lua_State} L + * @param {number} t + * @returns {Uint8Array} + */ const lua_typename = function(L, t) { api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag"); return ltm.ttypename(t); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_iscfunction = function(L, idx) { let o = index2addr(L, idx); return o.ttislcf(o) || o.ttisCclosure(); }; +/** + * @param {lua_State} L + * @param {number} n + * @returns {number} + */ const lua_isnil = function(L, n) { return lua_type(L, n) === LUA_TNIL; }; +/** + * @param {lua_State} L + * @param {number} n + * @returns {number} + */ const lua_isboolean = function(L, n) { return lua_type(L, n) === LUA_TBOOLEAN; }; +/** + * @param {lua_State} L + * @param {number} n + * @returns {number} + */ const lua_isnone = function(L, n) { return lua_type(L, n) === LUA_TNONE; }; +/** + * @param {lua_State} L + * @param {number} n + * @returns {number} + */ const lua_isnoneornil = function(L, n) { return lua_type(L, n) <= 0; }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_istable = function(L, idx) { return index2addr(L, idx).ttistable(); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_isinteger = function(L, idx) { return index2addr(L, idx).ttisinteger(); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_isnumber = function(L, idx) { return lvm.tonumber(index2addr(L, idx)) !== false; }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_isstring = function(L, idx) { let o = index2addr(L, idx); return o.ttisstring() || lvm.cvt2str(o); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_isuserdata = function(L, idx) { let o = index2addr(L, idx); return o.ttisfulluserdata(o) || o.ttislightuserdata(); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_isthread = function(L, idx) { return lua_type(L, idx) === LUA_TTHREAD; }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_isfunction = function(L, idx) { return lua_type(L, idx) === LUA_TFUNCTION; }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_islightuserdata = function(L, idx) { return lua_type(L, idx) === LUA_TLIGHTUSERDATA; }; +/** + * @param {lua_State} L + * @param {number} index1 + * @param {number} index2 + * @returns {number} + */ const lua_rawequal = function(L, index1, index2) { let o1 = index2addr(L, index1); let o2 = index2addr(L, index2); return isvalid(o1) && isvalid(o2) ? lvm.luaV_equalobj(null, o1, o2) : 0; }; +/** + * @param {lua_State} L + * @param {number} op + */ const lua_arith = function(L, op) { if (op !== LUA_OPUNM && op !== LUA_OPBNOT) api_checknelems(L, 2); /* all other operations expect two operands */ @@ -937,10 +1348,18 @@ const lua_dump = function(L, writer, data, strip) { return 1; }; +/** + * @param {lua_State} L + * @returns {number} + */ const lua_status = function(L) { return L.status; }; +/** + * @param {lua_State} L + * @param {number} idx + */ const lua_setuservalue = function(L, idx) { api_checknelems(L, 1); let o = index2addr(L, idx); @@ -972,6 +1391,11 @@ const lua_callk = function(L, nargs, nresults, ctx, k) { L.ci.top = L.top; }; +/** + * @param {lua_State} L + * @param {number} n + * @param {number} r + */ const lua_call = function(L, n, r) { lua_callk(L, n, r, 0, null); }; @@ -1017,6 +1441,13 @@ const lua_pcallk = function(L, nargs, nresults, errfunc, ctx, k) { return status; }; +/** + * @param {lua_State} L + * @param {number} n + * @param {number} r + * @param {any} f + * @returns {number} + */ const lua_pcall = function(L, n, r, f) { return lua_pcallk(L, n, r, f, 0, null); }; @@ -1025,11 +1456,20 @@ const lua_pcall = function(L, n, r, f) { ** miscellaneous functions */ +/** + * @param {lua_State} L + * @returns {number} + */ const lua_error = function(L) { api_checknelems(L, 1); ldebug.luaG_errormsg(L); }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const lua_next = function(L, idx) { let t = index2addr(L, idx); api_check(L, t.ttistable(), "table expected"); @@ -1045,6 +1485,10 @@ const lua_next = function(L, idx) { } }; +/** + * @param {lua_State} L + * @param {number} n + */ const lua_concat = function(L, n) { api_checknelems(L, n); if (n >= 2) @@ -1055,6 +1499,10 @@ const lua_concat = function(L, n) { } }; +/** + * @param {lua_State} L + * @param {number} idx + */ const lua_len = function(L, idx) { let t = index2addr(L, idx); let tv = new TValue(); @@ -1094,6 +1542,13 @@ const lua_upvalueid = function(L, fidx, n) { } }; +/** + * @param {lua_State} L + * @param {number} fidx1 + * @param {number} n1 + * @param {number} fidx2 + * @param {number} n2 + */ const lua_upvaluejoin = function(L, fidx1, n1, fidx2, n2) { let ref1 = getupvalref(L, fidx1, n1); let ref2 = getupvalref(L, fidx2, n2); diff --git a/src/lstring.js b/src/lstring.js index 4769866..eeb883f 100644 --- a/src/lstring.js +++ b/src/lstring.js @@ -8,8 +8,16 @@ const { } = require('./defs.js'); const { lua_assert } = require("./llimits.js"); +/** + * @typedef {import('./lstate').lua_State} lua_State + */ + class TString { + /** + * @param {lua_State} L + * @param {Uint8Array} str + */ constructor(L, str) { this.hash = null; this.realstring = str; @@ -57,11 +65,21 @@ const luaS_bless = function(L, str) { }; /* makes a copy */ +/** + * @param {lua_State} L + * @param {Uint8Array} str + * @returns {TString} + */ const luaS_new = function(L, str) { return luaS_bless(L, luastring_from(str)); }; /* takes a js string */ +/** + * @param {lua_State} L + * @param {string} str + * @returns {TString} + */ const luaS_newliteral = function(L, str) { return luaS_bless(L, to_luastring(str)); }; From 71d42ecb639c437ca96395f87cf88f236cf1d071 Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Thu, 27 Apr 2023 14:17:13 +0800 Subject: [PATCH 05/14] src/lualib.js: add type info --- src/lualib.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/lualib.js b/src/lualib.js index fa30268..ca5abb6 100644 --- a/src/lualib.js +++ b/src/lualib.js @@ -5,37 +5,48 @@ const { LUA_VERSION_MINOR } = require("./lua.js"); +/** + * @typedef {import('./lstate').lua_State} lua_State + */ + const LUA_VERSUFFIX = "_" + LUA_VERSION_MAJOR + "_" + LUA_VERSION_MINOR; module.exports.LUA_VERSUFFIX = LUA_VERSUFFIX; module.exports.lua_assert = function(c) {}; +/** @type {(L: lua_State) => number} */ module.exports.luaopen_base = require("./lbaselib.js").luaopen_base; const LUA_COLIBNAME = "coroutine"; module.exports.LUA_COLIBNAME = LUA_COLIBNAME; +/** @type {(L: lua_State) => number} */ module.exports.luaopen_coroutine = require("./lcorolib.js").luaopen_coroutine; const LUA_TABLIBNAME = "table"; module.exports.LUA_TABLIBNAME = LUA_TABLIBNAME; +/** @type {(L: lua_State) => number} */ module.exports.luaopen_table = require("./ltablib.js").luaopen_table; if (typeof process !== "undefined") { const LUA_IOLIBNAME = "io"; module.exports.LUA_IOLIBNAME = LUA_IOLIBNAME; + /** @type {(L: lua_State) => number} */ module.exports.luaopen_io = require("./liolib.js").luaopen_io; } const LUA_OSLIBNAME = "os"; module.exports.LUA_OSLIBNAME = LUA_OSLIBNAME; +/** @type {(L: lua_State) => number} */ module.exports.luaopen_os = require("./loslib.js").luaopen_os; const LUA_STRLIBNAME = "string"; module.exports.LUA_STRLIBNAME = LUA_STRLIBNAME; +/** @type {(L: lua_State) => number} */ module.exports.luaopen_string = require("./lstrlib.js").luaopen_string; const LUA_UTF8LIBNAME = "utf8"; module.exports.LUA_UTF8LIBNAME = LUA_UTF8LIBNAME; +/** @type {(L: lua_State) => number} */ module.exports.luaopen_utf8 = require("./lutf8lib.js").luaopen_utf8; const LUA_BITLIBNAME = "bit32"; @@ -44,19 +55,24 @@ module.exports.LUA_BITLIBNAME = LUA_BITLIBNAME; const LUA_MATHLIBNAME = "math"; module.exports.LUA_MATHLIBNAME = LUA_MATHLIBNAME; +/** @type {(L: lua_State) => number} */ module.exports.luaopen_math = require("./lmathlib.js").luaopen_math; const LUA_DBLIBNAME = "debug"; module.exports.LUA_DBLIBNAME = LUA_DBLIBNAME; +/** @type {(L: lua_State) => number} */ module.exports.luaopen_debug = require("./ldblib.js").luaopen_debug; const LUA_LOADLIBNAME = "package"; module.exports.LUA_LOADLIBNAME = LUA_LOADLIBNAME; +/** @type {(L: lua_State) => number} */ module.exports.luaopen_package = require("./loadlib.js").luaopen_package; const LUA_FENGARILIBNAME = "fengari"; module.exports.LUA_FENGARILIBNAME = LUA_FENGARILIBNAME; +/** @type {(L: lua_State) => number} */ module.exports.luaopen_fengari = require("./fengarilib.js").luaopen_fengari; const linit = require('./linit.js'); +/** @type {(L: lua_State) => void} */ module.exports.luaL_openlibs = linit.luaL_openlibs; From 16a4a59bd8b1c9b786f6c70aa9e7aa93b233f43f Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Thu, 27 Apr 2023 14:26:51 +0800 Subject: [PATCH 06/14] src/lauxlib.js: add type info --- src/lauxlib.js | 190 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) diff --git a/src/lauxlib.js b/src/lauxlib.js index 9d414b2..b62bf27 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -1,5 +1,9 @@ "use strict"; +/** + * @typedef {import('./lstate').lua_State} lua_State + */ + const { LUAL_BUFFERSIZE } = require('./luaconf.js'); @@ -198,6 +202,12 @@ const lastlevel = function(L) { return le - 1; }; +/** + * @param {lua_State} L + * @param {lua_State} L1 + * @param {Uint8Array} msg + * @param {number} level + */ const luaL_traceback = function(L, L1, msg, level) { let ar = new lua_Debug(); let top = lua_gettop(L); @@ -231,6 +241,12 @@ const panic = function(L) { throw new Error(msg); }; +/** + * @param {lua_State} L + * @param {number} arg + * @param {Uint8Array} extramsg + * @returns {number} + */ const luaL_argerror = function(L, arg, extramsg) { let ar = new lua_Debug(); @@ -264,6 +280,10 @@ const typeerror = function(L, arg, tname) { return luaL_argerror(L, arg, msg); }; +/** + * @param {lua_State} L + * @param {number} level + */ const luaL_where = function(L, level) { let ar = new lua_Debug(); if (lua_getstack(L, level, ar)) { @@ -284,6 +304,12 @@ const luaL_error = function(L, fmt, ...argp) { }; /* Unlike normal lua, we pass in an error object */ +/** + * @param {lua_State} L + * @param {number} stat + * @param {Uint8Array} fname + * @returns {number} + */ const luaL_fileresult = function(L, stat, fname, e) { if (stat) { lua_pushboolean(L, 1); @@ -308,6 +334,11 @@ const luaL_fileresult = function(L, stat, fname, e) { }; /* Unlike normal lua, we pass in an error object */ +/** + * @param {lua_State} L + * @param {number} e + * @returns {number} + */ const luaL_execresult = function(L, e) { let what, stat; if (e === null) { @@ -331,10 +362,20 @@ const luaL_execresult = function(L, e) { return 3; }; +/** + * @param {lua_State} L + * @param {Uint8Array} n + * @returns {number} + */ const luaL_getmetatable = function(L, n) { return lua_getfield(L, LUA_REGISTRYINDEX, n); }; +/** + * @param {lua_State} L + * @param {Uint8Array} tname + * @returns {number} + */ const luaL_newmetatable = function(L, tname) { if (luaL_getmetatable(L, tname) !== LUA_TNIL) /* name already in use? */ return 0; /* leave previous value on top, but return 0 */ @@ -348,6 +389,10 @@ const luaL_newmetatable = function(L, tname) { }; +/** + * @param {lua_State} L + * @param {Uint8Array} tname + */ const luaL_setmetatable = function(L, tname) { luaL_getmetatable(L, tname); lua_setmetatable(L, -2); @@ -385,6 +430,10 @@ const tag_error = function(L, arg, tag) { typeerror(L, arg, lua_typename(L, tag)); }; +/** + * @param {number} + * @returns {lua_State} + */ const luaL_newstate = function() { let L = lua_newstate(); if (L) lua_atpanic(L, panic); @@ -392,24 +441,49 @@ const luaL_newstate = function() { }; +/** + * @param {lua_State} L + * @param {number} i + * @returns {Uint8Array} + */ const luaL_typename = function(L, i) { return lua_typename(L, lua_type(L, i)); }; +/** + * @param {lua_State} L + * @param {number} cond + * @param {number} arg + * @param {Uint8Array} extramsg + */ const luaL_argcheck = function(L, cond, arg, extramsg) { if (!cond) luaL_argerror(L, arg, extramsg); }; +/** + * @param {lua_State} L + * @param {number} arg + */ const luaL_checkany = function(L, arg) { if (lua_type(L, arg) === LUA_TNONE) luaL_argerror(L, arg, to_luastring("value expected", true)); }; +/** + * @param {lua_State} L + * @param {number} arg + * @param {number} t + */ const luaL_checktype = function(L, arg, t) { if (lua_type(L, arg) !== t) tag_error(L, arg, t); }; +/** + * @param {lua_State} L + * @param {number} arg + * @returns {Uint8Array} + */ const luaL_checklstring = function(L, arg) { let s = lua_tolstring(L, arg); if (s === null || s === undefined) tag_error(L, arg, LUA_TSTRING); @@ -418,6 +492,12 @@ const luaL_checklstring = function(L, arg) { const luaL_checkstring = luaL_checklstring; +/** + * @param {lua_State} L + * @param {number} arg + * @param {Uint8Array} def + * @returns {Uint8Array} + */ const luaL_optlstring = function(L, arg, def) { if (lua_type(L, arg) <= 0) { return def === null ? null : from_userstring(def); @@ -433,6 +513,11 @@ const interror = function(L, arg) { tag_error(L, arg, LUA_TNUMBER); }; +/** + * @param {lua_State} L + * @param {number} arg + * @returns {number} + */ const luaL_checknumber = function(L, arg) { let d = lua_tonumberx(L, arg); if (d === false) @@ -440,10 +525,21 @@ const luaL_checknumber = function(L, arg) { return d; }; +/** + * @param {lua_State} L + * @param {number} arg + * @param {number} def + * @returns {number} + */ const luaL_optnumber = function(L, arg, def) { return luaL_opt(L, luaL_checknumber, arg, def); }; +/** + * @param {lua_State} L + * @param {number} arg + * @returns {number} + */ const luaL_checkinteger = function(L, arg) { let d = lua_tointegerx(L, arg); if (d === false) @@ -451,6 +547,12 @@ const luaL_checkinteger = function(L, arg) { return d; }; +/** + * @param {lua_State} L + * @param {number} arg + * @param {number} def + * @returns {number} + */ const luaL_optinteger = function(L, arg, def) { return luaL_opt(L, luaL_checkinteger, arg, def); }; @@ -532,22 +634,53 @@ const getS = function(L, ud) { return s; }; +/** + * @param {lua_State} L + * @param {Uint8Array} buff + * @param {number} size + * @param {Uint8Array} name + * @param {Uint8Array} mode + * @returns {number} + */ const luaL_loadbufferx = function(L, buff, size, name, mode) { return lua_load(L, getS, {string: buff}, name, mode); }; +/** + * @param {lua_State} L + * @param {Uint8Array} s + * @param {number} sz + * @param {Uint8Array} n + * @returns {number} + */ const luaL_loadbuffer = function(L, s, sz, n) { return luaL_loadbufferx(L, s, sz, n, null); }; +/** + * @param {lua_State} L + * @param {Uint8Array} s + * @returns {number} + */ const luaL_loadstring = function(L, s) { return luaL_loadbuffer(L, s, s.length, s); }; +/** + * @param {lua_State} L + * @param {Uint8Array} s + * @returns {number} + */ const luaL_dostring = function(L, s) { return (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)); }; +/** + * @param {lua_State} L + * @param {number} obj + * @param {Uint8Array} event + * @returns {number} + */ const luaL_getmetafield = function(L, obj, event) { if (!lua_getmetatable(L, obj)) /* no metatable? */ return LUA_TNIL; @@ -562,6 +695,12 @@ const luaL_getmetafield = function(L, obj, event) { } }; +/** + * @param {lua_State} L + * @param {number} obj + * @param {Uint8Array} event + * @returns {number} + */ const luaL_callmeta = function(L, obj, event) { obj = lua_absindex(L, obj); if (luaL_getmetafield(L, obj, event) === LUA_TNIL) @@ -573,6 +712,11 @@ const luaL_callmeta = function(L, obj, event) { return true; }; +/** + * @param {lua_State} L + * @param {number} idx + * @returns {number} + */ const luaL_len = function(L, idx) { lua_len(L, idx); let l = lua_tointegerx(L, -1); @@ -584,6 +728,11 @@ const luaL_len = function(L, idx) { const p_I = to_luastring("%I"); const p_f = to_luastring("%f"); +/** + * @param {lua_State} L + * @param {number} idx + * @returns {Uint8Array} + */ const luaL_tolstring = function(L, idx) { if (luaL_callmeta(L, idx, __tostring)) { if (!lua_isstring(L, -1)) @@ -659,6 +808,13 @@ const find_subarray = function(arr, subarr, from_index) { return -1; }; +/** + * @param {lua_State} L + * @param {Uint8Array} s + * @param {Uint8Array} p + * @param {Uint8Array} r + * @returns {Uint8Array} + */ const luaL_gsub = function(L, s, p, r) { let wild; let b = new luaL_Buffer(); @@ -677,6 +833,12 @@ const luaL_gsub = function(L, s, p, r) { ** ensure that stack[idx][fname] has a table and push that table ** into the stack */ +/** + * @param {lua_State} L + * @param {number} idx + * @param {Uint8Array} fname + * @returns {number} + */ const luaL_getsubtable = function(L, idx, fname) { if (lua_getfield(L, idx, fname) === LUA_TTABLE) return true; /* table already there */ @@ -713,6 +875,11 @@ const luaL_setfuncs = function(L, l, nup) { ** this extra space, Lua will generate the same 'stack overflow' error, ** but without 'msg'.) */ +/** + * @param {lua_State} L + * @param {number} space + * @param {Uint8Array} msg + */ const luaL_checkstack = function(L, space, msg) { if (!lua_checkstack(L, space)) { if (msg) @@ -735,6 +902,11 @@ const luaL_newlib = function(L, l) { const LUA_NOREF = -2; const LUA_REFNIL = -1; +/** + * @param {lua_State} L + * @param {number} t + * @returns {number} + */ const luaL_ref = function(L, t) { let ref; if (lua_isnil(L, -1)) { @@ -756,6 +928,11 @@ const luaL_ref = function(L, t) { }; +/** + * @param {lua_State} L + * @param {number} t + * @param {number} ref + */ const luaL_unref = function(L, t, ref) { if (ref >= 0) { t = lua_absindex(L, t); @@ -978,10 +1155,20 @@ if (typeof process === "undefined") { }; } +/** + * @param {lua_State} L + * @param {Uint8Array} filename + * @returns {number} + */ const luaL_loadfile = function(L, filename) { return luaL_loadfilex(L, filename, null); }; +/** + * @param {lua_State} L + * @param {Uint8Array} filename + * @returns {number} + */ const luaL_dofile = function(L, filename) { return (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0)); }; @@ -1015,6 +1202,9 @@ const luaL_checkversion_ = function(L, ver, sz) { }; /* There is no point in providing this function... */ +/** + * @param {lua_State} L + */ const luaL_checkversion = function(L) { luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES); }; From 64aaa89b1b49bc372dbe5f7a0da72831055efb4d Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Thu, 27 Apr 2023 16:02:32 +0800 Subject: [PATCH 07/14] Fix incorrect signatures with tsc checkJs --- package.json | 1 + src/defs.js | 15 ++++++++------- src/lapi.js | 44 ++++++++++++++++++++++---------------------- src/lauxlib.js | 34 ++++++++++++++++++++-------------- src/ldebug.js | 3 +++ src/ldo.js | 3 +++ src/llimits.js | 8 ++++++-- 7 files changed, 63 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index 3feaade..92e2f74 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "scripts": { "emit": "tsc", + "type-test": "tsc --allowJs --checkJs", "lint": "eslint src/ test/", "prepublishOnly": "git diff-index --quiet --cached HEAD -- && npm run lint && npm run emit && npm run test", "test": "jest" diff --git a/src/defs.js b/src/defs.js index 7b41a1c..e9ae44c 100644 --- a/src/defs.js +++ b/src/defs.js @@ -7,7 +7,7 @@ /** * Converts a JavaScript string into a Uint8Array (used a Lua string). * - * @type {function(string):Uint8Array} + * @type {function(ArrayLike<number>):Uint8Array} */ let luastring_from; if (typeof Uint8Array.from === "function") { @@ -25,7 +25,7 @@ if (typeof Uint8Array.from === "function") { /** * Returns the index of the first occurrence of the character in the Lua string. * - * @type {function(Uint8Array, number, number?):number} + * @type {function(Uint8Array|any[], number, number=):number} */ let luastring_indexOf; if (typeof (new Uint8Array().indexOf) === "function") { @@ -34,7 +34,7 @@ if (typeof (new Uint8Array().indexOf) === "function") { }; } else { /* Browsers that don't support Uint8Array.indexOf seem to allow using Array.indexOf on Uint8Array objects e.g. IE11 */ - let array_indexOf = [].indexOf; + let array_indexOf = [0].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); @@ -88,9 +88,9 @@ const unicode_error_message = "cannot convert invalid utf8 to javascript string" * Converts a Lua string (in UTF-8) to a normal JavaScript string. * * @param {Uint8Array} value the Lua string - * @param {number?} from the staring index - * @param {number?} to the ending index - * @param {boolean?} replacement_char whether to replace invalid utf8 chars + * @param {number} [from] the staring index + * @param {number} [to] the ending index + * @param {boolean} [replacement_char] whether to replace invalid utf8 chars * @returns {string} */ const to_jsstring = function(value, from, to, replacement_char) { @@ -219,7 +219,7 @@ const to_luastring_cache = {}; /** * @param {string} str - * @param {object?} cache + * @param {boolean} [cache] * @returns {Uint8Array} */ const to_luastring = function(str, cache) { @@ -231,6 +231,7 @@ const to_luastring = function(str, cache) { } let len = str.length; + /** @type {Array<number> | Uint8Array} */ let outU8Array = Array(len); /* array is at *least* going to be length of string */ let outIdx = 0; for (let i = 0; i < len; ++i) { diff --git a/src/lapi.js b/src/lapi.js index ed88612..835984e 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -78,7 +78,7 @@ const isvalid = function(o) { }; /** - * @param {lua_State} L + * @param {lua_State?} L * @returns {number} */ const lua_version = function(L) { @@ -417,7 +417,7 @@ const lua_pushfstring = function (L, fmt, ...argp) { /* Similar to lua_pushstring, but takes a JS string */ /** * @param {lua_State} L - * @param {string} s + * @param {string?} [s] * @returns {any} */ const lua_pushliteral = function (L, s) { @@ -474,7 +474,7 @@ const lua_pushjsfunction = lua_pushcfunction; /** * @param {lua_State} L - * @param {number} b + * @param {any} b */ const lua_pushboolean = function(L, b) { L.stack[L.top] = new TValue(LUA_TBOOLEAN, !!b); @@ -704,8 +704,8 @@ const lua_rawget = function(L, idx) { // narray and nrec are mostly useless for this implementation /** * @param {lua_State} L - * @param {number} narray - * @param {number} nrec + * @param {number} [narray] + * @param {number} [nrec] */ const lua_createtable = function(L, narray, nrec) { let t = new lobject.TValue(LUA_TTABLE, ltable.luaH_new(L)); @@ -719,7 +719,7 @@ const luaS_newudata = function(L, size) { /** * @param {lua_State} L - * @param {number} size + * @param {number} [size] * @returns {any} */ const lua_newuserdata = function(L, size) { @@ -812,7 +812,7 @@ const lua_register = function(L, n, f) { /** * @param {lua_State} L * @param {number} objindex - * @returns {number} + * @returns {boolean} */ const lua_getmetatable = function(L, objindex) { let obj = index2addr(L, objindex); @@ -903,7 +903,7 @@ const lua_getglobal = function(L, name) { /** * @param {lua_State} L * @param {number} idx - * @returns {number} + * @returns {boolean} */ const lua_toboolean = function(L, idx) { let o = index2addr(L, idx); @@ -913,7 +913,7 @@ const lua_toboolean = function(L, idx) { /** * @param {lua_State} L * @param {number} idx - * @returns {Uint8Array} + * @returns {Uint8Array?} */ const lua_tolstring = function(L, idx) { let o = index2addr(L, idx); @@ -932,7 +932,7 @@ const lua_tostring = lua_tolstring; /** * @param {lua_State} L * @param {number} idx - * @returns {string} + * @returns {string?} */ const lua_tojsstring = function(L, idx) { let o = index2addr(L, idx); @@ -1000,7 +1000,7 @@ const lua_tointeger = function(L, idx) { /** * @param {lua_State} L * @param {number} idx - * @returns {number} + * @returns {number|false} */ const lua_tointegerx = function(L, idx) { return lvm.tointeger(index2addr(L, idx)); @@ -1019,7 +1019,7 @@ const lua_tonumber = function(L, idx) { /** * @param {lua_State} L * @param {number} idx - * @returns {number} + * @returns {number|false} */ const lua_tonumberx = function(L, idx) { return lvm.tonumber(index2addr(L, idx)); @@ -1181,7 +1181,7 @@ const lua_iscfunction = function(L, idx) { /** * @param {lua_State} L * @param {number} n - * @returns {number} + * @returns {boolean} */ const lua_isnil = function(L, n) { return lua_type(L, n) === LUA_TNIL; @@ -1190,7 +1190,7 @@ const lua_isnil = function(L, n) { /** * @param {lua_State} L * @param {number} n - * @returns {number} + * @returns {boolean} */ const lua_isboolean = function(L, n) { return lua_type(L, n) === LUA_TBOOLEAN; @@ -1199,7 +1199,7 @@ const lua_isboolean = function(L, n) { /** * @param {lua_State} L * @param {number} n - * @returns {number} + * @returns {boolean} */ const lua_isnone = function(L, n) { return lua_type(L, n) === LUA_TNONE; @@ -1208,7 +1208,7 @@ const lua_isnone = function(L, n) { /** * @param {lua_State} L * @param {number} n - * @returns {number} + * @returns {boolean} */ const lua_isnoneornil = function(L, n) { return lua_type(L, n) <= 0; @@ -1217,7 +1217,7 @@ const lua_isnoneornil = function(L, n) { /** * @param {lua_State} L * @param {number} idx - * @returns {number} + * @returns {boolean} */ const lua_istable = function(L, idx) { return index2addr(L, idx).ttistable(); @@ -1235,7 +1235,7 @@ const lua_isinteger = function(L, idx) { /** * @param {lua_State} L * @param {number} idx - * @returns {number} + * @returns {boolean} */ const lua_isnumber = function(L, idx) { return lvm.tonumber(index2addr(L, idx)) !== false; @@ -1264,7 +1264,7 @@ const lua_isuserdata = function(L, idx) { /** * @param {lua_State} L * @param {number} idx - * @returns {number} + * @returns {boolean} */ const lua_isthread = function(L, idx) { return lua_type(L, idx) === LUA_TTHREAD; @@ -1273,7 +1273,7 @@ const lua_isthread = function(L, idx) { /** * @param {lua_State} L * @param {number} idx - * @returns {number} + * @returns {boolean} */ const lua_isfunction = function(L, idx) { return lua_type(L, idx) === LUA_TFUNCTION; @@ -1282,7 +1282,7 @@ const lua_isfunction = function(L, idx) { /** * @param {lua_State} L * @param {number} idx - * @returns {number} + * @returns {boolean} */ const lua_islightuserdata = function(L, idx) { return lua_type(L, idx) === LUA_TLIGHTUSERDATA; @@ -1458,7 +1458,7 @@ const lua_pcall = function(L, n, r, f) { /** * @param {lua_State} L - * @returns {number} + * @returns {never} */ const lua_error = function(L) { api_checknelems(L, 1); diff --git a/src/lauxlib.js b/src/lauxlib.js index b62bf27..9d7e677 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -244,8 +244,8 @@ const panic = function(L) { /** * @param {lua_State} L * @param {number} arg - * @param {Uint8Array} extramsg - * @returns {number} + * @param {any} extramsg + * @returns {never} */ const luaL_argerror = function(L, arg, extramsg) { let ar = new lua_Debug(); @@ -267,6 +267,9 @@ const luaL_argerror = function(L, arg, extramsg) { return luaL_error(L, to_luastring("bad argument #%d to '%s' (%s)"), arg, ar.name, extramsg); }; +/** + * @returns {never} + */ const typeerror = function(L, arg, tname) { let typearg; if (luaL_getmetafield(L, arg, __name) === LUA_TSTRING) @@ -306,8 +309,9 @@ const luaL_error = function(L, fmt, ...argp) { /* Unlike normal lua, we pass in an error object */ /** * @param {lua_State} L - * @param {number} stat - * @param {Uint8Array} fname + * @param {any} [stat] + * @param {string|Uint8Array|false} [fname] + * @param {any} [e] * @returns {number} */ const luaL_fileresult = function(L, stat, fname, e) { @@ -336,7 +340,7 @@ const luaL_fileresult = function(L, stat, fname, e) { /* Unlike normal lua, we pass in an error object */ /** * @param {lua_State} L - * @param {number} e + * @param {any} e * @returns {number} */ const luaL_execresult = function(L, e) { @@ -426,12 +430,14 @@ const luaL_checkoption = function(L, arg, def, lst) { return luaL_argerror(L, arg, lua_pushfstring(L, to_luastring("invalid option '%s'"), name)); }; +/** + * @returns {never} + */ const tag_error = function(L, arg, tag) { typeerror(L, arg, lua_typename(L, tag)); }; /** - * @param {number} * @returns {lua_State} */ const luaL_newstate = function() { @@ -452,9 +458,9 @@ const luaL_typename = function(L, i) { /** * @param {lua_State} L - * @param {number} cond + * @param {any} cond * @param {number} arg - * @param {Uint8Array} extramsg + * @param {any} extramsg */ const luaL_argcheck = function(L, cond, arg, extramsg) { if (!cond) luaL_argerror(L, arg, extramsg); @@ -495,7 +501,7 @@ const luaL_checkstring = luaL_checklstring; /** * @param {lua_State} L * @param {number} arg - * @param {Uint8Array} def + * @param {string|Uint8Array} [def] * @returns {Uint8Array} */ const luaL_optlstring = function(L, arg, def) { @@ -543,7 +549,7 @@ const luaL_optnumber = function(L, arg, def) { const luaL_checkinteger = function(L, arg) { let d = lua_tointegerx(L, arg); if (d === false) - interror(L, arg); + return interror(L, arg); return d; }; @@ -699,7 +705,7 @@ const luaL_getmetafield = function(L, obj, event) { * @param {lua_State} L * @param {number} obj * @param {Uint8Array} event - * @returns {number} + * @returns {boolean} */ const luaL_callmeta = function(L, obj, event) { obj = lua_absindex(L, obj); @@ -721,7 +727,7 @@ const luaL_len = function(L, idx) { lua_len(L, idx); let l = lua_tointegerx(L, -1); if (l === false) - luaL_error(L, to_luastring("object length is not an integer", true)); + return luaL_error(L, to_luastring("object length is not an integer", true)); lua_pop(L, 1); /* remove object */ return l; }; @@ -837,7 +843,7 @@ const luaL_gsub = function(L, s, p, r) { * @param {lua_State} L * @param {number} idx * @param {Uint8Array} fname - * @returns {number} + * @returns {boolean} */ const luaL_getsubtable = function(L, idx, fname) { if (lua_getfield(L, idx, fname) === LUA_TTABLE) @@ -878,7 +884,7 @@ const luaL_setfuncs = function(L, l, nup) { /** * @param {lua_State} L * @param {number} space - * @param {Uint8Array} msg + * @param {any} msg */ const luaL_checkstack = function(L, space, msg) { if (!lua_checkstack(L, space)) { diff --git a/src/ldebug.js b/src/ldebug.js index a471c75..a22cad0 100644 --- a/src/ldebug.js +++ b/src/ldebug.js @@ -608,6 +608,9 @@ const luaG_runerror = function(L, fmt, ...argp) { luaG_errormsg(L); }; +/** + * @returns {never} + */ const luaG_errormsg = function(L) { if (L.errfunc !== 0) { /* is there an error handling function? */ let errfunc = L.errfunc; diff --git a/src/ldo.js b/src/ldo.js index 5f849ca..b4b1336 100644 --- a/src/ldo.js +++ b/src/ldo.js @@ -368,6 +368,9 @@ const luaD_call = function(L, off, nResults) { L.nCcalls--; }; +/** + * @returns {never} + */ const luaD_throw = function(L, errcode) { if (L.errorJmp) { /* thread has an error handler? */ L.errorJmp.status = errcode; /* set status */ diff --git a/src/llimits.js b/src/llimits.js index 4f2b3f3..a573585 100644 --- a/src/llimits.js +++ b/src/llimits.js @@ -1,7 +1,11 @@ "use strict"; -const lua_assert = function(c) { - if (!c) throw Error("assertion failed"); +/** + * @param {any} c + * @param {string} [msg] + */ +const lua_assert = function(c, msg) { + if (!c) throw Error(msg || "assertion failed"); }; module.exports.lua_assert = lua_assert; From 477f93fc9e16d24d305d181a56138d06029fdedb Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Thu, 27 Apr 2023 16:33:33 +0800 Subject: [PATCH 08/14] Workaround possible tsc caveat when re-exporting Possibly due to [TypeScript#51819], the exported declarations are quite incomplete when re-exporting using `module.exports.key = value` syntax. [TypeScript#51819]: https://github.com/microsoft/TypeScript/issues/51819 --- src/fengari.js | 43 +++--- src/lua.js | 370 +++++++++++++++++++++++++------------------------ 2 files changed, 208 insertions(+), 205 deletions(-) diff --git a/src/fengari.js b/src/fengari.js index 147756f..267ed00 100644 --- a/src/fengari.js +++ b/src/fengari.js @@ -10,28 +10,27 @@ Copyright © 1994–2017 Lua.org, PUC-Rio. const core = require("./fengaricore.js"); -module.exports.FENGARI_AUTHORS = core.FENGARI_AUTHORS; -module.exports.FENGARI_COPYRIGHT = core.FENGARI_COPYRIGHT; -module.exports.FENGARI_RELEASE = core.FENGARI_RELEASE; -module.exports.FENGARI_VERSION = core.FENGARI_VERSION; -module.exports.FENGARI_VERSION_MAJOR = core.FENGARI_VERSION_MAJOR; -module.exports.FENGARI_VERSION_MINOR = core.FENGARI_VERSION_MINOR; -module.exports.FENGARI_VERSION_NUM = core.FENGARI_VERSION_NUM; -module.exports.FENGARI_VERSION_RELEASE = core.FENGARI_VERSION_RELEASE; +const exported = { + FENGARI_AUTHORS: core.FENGARI_AUTHORS, + FENGARI_COPYRIGHT: core.FENGARI_COPYRIGHT, + FENGARI_RELEASE: core.FENGARI_RELEASE, + FENGARI_VERSION: core.FENGARI_VERSION, + FENGARI_VERSION_MAJOR: core.FENGARI_VERSION_MAJOR, + FENGARI_VERSION_MINOR: core.FENGARI_VERSION_MINOR, + FENGARI_VERSION_NUM: core.FENGARI_VERSION_NUM, + FENGARI_VERSION_RELEASE: core.FENGARI_VERSION_RELEASE, -module.exports.luastring_eq = core.luastring_eq; -module.exports.luastring_indexOf = core.luastring_indexOf; -module.exports.luastring_of = core.luastring_of; -module.exports.to_jsstring = core.to_jsstring; -module.exports.to_luastring = core.to_luastring; -module.exports.to_uristring = core.to_uristring; + luastring_eq: core.luastring_eq, + luastring_indexOf: core.luastring_indexOf, + luastring_of: core.luastring_of, + to_jsstring: core.to_jsstring, + to_luastring: core.to_luastring, + to_uristring: core.to_uristring, -const luaconf = require('./luaconf.js'); -const lua = require('./lua.js'); -const lauxlib = require('./lauxlib.js'); -const lualib = require('./lualib.js'); + luaconf: require('./luaconf.js'), + lua: require('./lua.js'), + lauxlib: require('./lauxlib.js'), + lualib: require('./lualib.js'), +}; -module.exports.luaconf = luaconf; -module.exports.lua = lua; -module.exports.lauxlib = lauxlib; -module.exports.lualib = lualib; +module.exports = exported; diff --git a/src/lua.js b/src/lua.js index 154cfa8..635d6d9 100644 --- a/src/lua.js +++ b/src/lua.js @@ -6,186 +6,190 @@ const ldebug = require("./ldebug.js"); const ldo = require("./ldo.js"); const lstate = require("./lstate.js"); -module.exports.LUA_AUTHORS = defs.LUA_AUTHORS; -module.exports.LUA_COPYRIGHT = defs.LUA_COPYRIGHT; -module.exports.LUA_ERRERR = defs.thread_status.LUA_ERRERR; -module.exports.LUA_ERRGCMM = defs.thread_status.LUA_ERRGCMM; -module.exports.LUA_ERRMEM = defs.thread_status.LUA_ERRMEM; -module.exports.LUA_ERRRUN = defs.thread_status.LUA_ERRRUN; -module.exports.LUA_ERRSYNTAX = defs.thread_status.LUA_ERRSYNTAX; -module.exports.LUA_HOOKCALL = defs.LUA_HOOKCALL; -module.exports.LUA_HOOKCOUNT = defs.LUA_HOOKCOUNT; -module.exports.LUA_HOOKLINE = defs.LUA_HOOKLINE; -module.exports.LUA_HOOKRET = defs.LUA_HOOKRET; -module.exports.LUA_HOOKTAILCALL = defs.LUA_HOOKTAILCALL; -module.exports.LUA_MASKCALL = defs.LUA_MASKCALL; -module.exports.LUA_MASKCOUNT = defs.LUA_MASKCOUNT; -module.exports.LUA_MASKLINE = defs.LUA_MASKLINE; -module.exports.LUA_MASKRET = defs.LUA_MASKRET; -module.exports.LUA_MINSTACK = defs.LUA_MINSTACK; -module.exports.LUA_MULTRET = defs.LUA_MULTRET; -module.exports.LUA_NUMTAGS = defs.constant_types.LUA_NUMTAGS; -module.exports.LUA_OK = defs.thread_status.LUA_OK; -module.exports.LUA_OPADD = defs.LUA_OPADD; -module.exports.LUA_OPBAND = defs.LUA_OPBAND; -module.exports.LUA_OPBNOT = defs.LUA_OPBNOT; -module.exports.LUA_OPBOR = defs.LUA_OPBOR; -module.exports.LUA_OPBXOR = defs.LUA_OPBXOR; -module.exports.LUA_OPDIV = defs.LUA_OPDIV; -module.exports.LUA_OPEQ = defs.LUA_OPEQ; -module.exports.LUA_OPIDIV = defs.LUA_OPIDIV; -module.exports.LUA_OPLE = defs.LUA_OPLE; -module.exports.LUA_OPLT = defs.LUA_OPLT; -module.exports.LUA_OPMOD = defs.LUA_OPMOD; -module.exports.LUA_OPMUL = defs.LUA_OPMUL; -module.exports.LUA_OPPOW = defs.LUA_OPPOW; -module.exports.LUA_OPSHL = defs.LUA_OPSHL; -module.exports.LUA_OPSHR = defs.LUA_OPSHR; -module.exports.LUA_OPSUB = defs.LUA_OPSUB; -module.exports.LUA_OPUNM = defs.LUA_OPUNM; -module.exports.LUA_REGISTRYINDEX = defs.LUA_REGISTRYINDEX; -module.exports.LUA_RELEASE = defs.LUA_RELEASE; -module.exports.LUA_RIDX_GLOBALS = defs.LUA_RIDX_GLOBALS; -module.exports.LUA_RIDX_LAST = defs.LUA_RIDX_LAST; -module.exports.LUA_RIDX_MAINTHREAD = defs.LUA_RIDX_MAINTHREAD; -module.exports.LUA_SIGNATURE = defs.LUA_SIGNATURE; -module.exports.LUA_TNONE = defs.constant_types.LUA_TNONE; -module.exports.LUA_TNIL = defs.constant_types.LUA_TNIL; -module.exports.LUA_TBOOLEAN = defs.constant_types.LUA_TBOOLEAN; -module.exports.LUA_TLIGHTUSERDATA = defs.constant_types.LUA_TLIGHTUSERDATA; -module.exports.LUA_TNUMBER = defs.constant_types.LUA_TNUMBER; -module.exports.LUA_TSTRING = defs.constant_types.LUA_TSTRING; -module.exports.LUA_TTABLE = defs.constant_types.LUA_TTABLE; -module.exports.LUA_TFUNCTION = defs.constant_types.LUA_TFUNCTION; -module.exports.LUA_TUSERDATA = defs.constant_types.LUA_TUSERDATA; -module.exports.LUA_TTHREAD = defs.constant_types.LUA_TTHREAD; -module.exports.LUA_VERSION = defs.LUA_VERSION; -module.exports.LUA_VERSION_MAJOR = defs.LUA_VERSION_MAJOR; -module.exports.LUA_VERSION_MINOR = defs.LUA_VERSION_MINOR; -module.exports.LUA_VERSION_NUM = defs.LUA_VERSION_NUM; -module.exports.LUA_VERSION_RELEASE = defs.LUA_VERSION_RELEASE; -module.exports.LUA_YIELD = defs.thread_status.LUA_YIELD; -module.exports.lua_Debug = defs.lua_Debug; -module.exports.lua_upvalueindex = defs.lua_upvalueindex; -module.exports.lua_absindex = lapi.lua_absindex; -module.exports.lua_arith = lapi.lua_arith; -module.exports.lua_atpanic = lapi.lua_atpanic; -module.exports.lua_atnativeerror = lapi.lua_atnativeerror; -module.exports.lua_call = lapi.lua_call; -module.exports.lua_callk = lapi.lua_callk; -module.exports.lua_checkstack = lapi.lua_checkstack; -module.exports.lua_close = lstate.lua_close; -module.exports.lua_compare = lapi.lua_compare; -module.exports.lua_concat = lapi.lua_concat; -module.exports.lua_copy = lapi.lua_copy; -module.exports.lua_createtable = lapi.lua_createtable; -module.exports.lua_dump = lapi.lua_dump; -module.exports.lua_error = lapi.lua_error; -module.exports.lua_gc = lapi.lua_gc; -module.exports.lua_getallocf = lapi.lua_getallocf; -module.exports.lua_getextraspace = lapi.lua_getextraspace; -module.exports.lua_getfield = lapi.lua_getfield; -module.exports.lua_getglobal = lapi.lua_getglobal; -module.exports.lua_gethook = ldebug.lua_gethook; -module.exports.lua_gethookcount = ldebug.lua_gethookcount; -module.exports.lua_gethookmask = ldebug.lua_gethookmask; -module.exports.lua_geti = lapi.lua_geti; -module.exports.lua_getinfo = ldebug.lua_getinfo; -module.exports.lua_getlocal = ldebug.lua_getlocal; -module.exports.lua_getmetatable = lapi.lua_getmetatable; -module.exports.lua_getstack = ldebug.lua_getstack; -module.exports.lua_gettable = lapi.lua_gettable; -module.exports.lua_gettop = lapi.lua_gettop; -module.exports.lua_getupvalue = lapi.lua_getupvalue; -module.exports.lua_getuservalue = lapi.lua_getuservalue; -module.exports.lua_insert = lapi.lua_insert; -module.exports.lua_isboolean = lapi.lua_isboolean; -module.exports.lua_iscfunction = lapi.lua_iscfunction; -module.exports.lua_isfunction = lapi.lua_isfunction; -module.exports.lua_isinteger = lapi.lua_isinteger; -module.exports.lua_islightuserdata = lapi.lua_islightuserdata; -module.exports.lua_isnil = lapi.lua_isnil; -module.exports.lua_isnone = lapi.lua_isnone; -module.exports.lua_isnoneornil = lapi.lua_isnoneornil; -module.exports.lua_isnumber = lapi.lua_isnumber; -module.exports.lua_isproxy = lapi.lua_isproxy; -module.exports.lua_isstring = lapi.lua_isstring; -module.exports.lua_istable = lapi.lua_istable; -module.exports.lua_isthread = lapi.lua_isthread; -module.exports.lua_isuserdata = lapi.lua_isuserdata; -module.exports.lua_isyieldable = ldo.lua_isyieldable; -module.exports.lua_len = lapi.lua_len; -module.exports.lua_load = lapi.lua_load; -module.exports.lua_newstate = lstate.lua_newstate; -module.exports.lua_newtable = lapi.lua_newtable; -module.exports.lua_newthread = lstate.lua_newthread; -module.exports.lua_newuserdata = lapi.lua_newuserdata; -module.exports.lua_next = lapi.lua_next; -module.exports.lua_pcall = lapi.lua_pcall; -module.exports.lua_pcallk = lapi.lua_pcallk; -module.exports.lua_pop = lapi.lua_pop; -module.exports.lua_pushboolean = lapi.lua_pushboolean; -module.exports.lua_pushcclosure = lapi.lua_pushcclosure; -module.exports.lua_pushcfunction = lapi.lua_pushcfunction; -module.exports.lua_pushfstring = lapi.lua_pushfstring; -module.exports.lua_pushglobaltable = lapi.lua_pushglobaltable; -module.exports.lua_pushinteger = lapi.lua_pushinteger; -module.exports.lua_pushjsclosure = lapi.lua_pushjsclosure; -module.exports.lua_pushjsfunction = lapi.lua_pushjsfunction; -module.exports.lua_pushlightuserdata = lapi.lua_pushlightuserdata; -module.exports.lua_pushliteral = lapi.lua_pushliteral; -module.exports.lua_pushlstring = lapi.lua_pushlstring; -module.exports.lua_pushnil = lapi.lua_pushnil; -module.exports.lua_pushnumber = lapi.lua_pushnumber; -module.exports.lua_pushstring = lapi.lua_pushstring; -module.exports.lua_pushthread = lapi.lua_pushthread; -module.exports.lua_pushvalue = lapi.lua_pushvalue; -module.exports.lua_pushvfstring = lapi.lua_pushvfstring; -module.exports.lua_rawequal = lapi.lua_rawequal; -module.exports.lua_rawget = lapi.lua_rawget; -module.exports.lua_rawgeti = lapi.lua_rawgeti; -module.exports.lua_rawgetp = lapi.lua_rawgetp; -module.exports.lua_rawlen = lapi.lua_rawlen; -module.exports.lua_rawset = lapi.lua_rawset; -module.exports.lua_rawseti = lapi.lua_rawseti; -module.exports.lua_rawsetp = lapi.lua_rawsetp; -module.exports.lua_register = lapi.lua_register; -module.exports.lua_remove = lapi.lua_remove; -module.exports.lua_replace = lapi.lua_replace; -module.exports.lua_resume = ldo.lua_resume; -module.exports.lua_rotate = lapi.lua_rotate; -module.exports.lua_setallocf = lapi.lua_setallocf; -module.exports.lua_setfield = lapi.lua_setfield; -module.exports.lua_setglobal = lapi.lua_setglobal; -module.exports.lua_sethook = ldebug.lua_sethook; -module.exports.lua_seti = lapi.lua_seti; -module.exports.lua_setlocal = ldebug.lua_setlocal; -module.exports.lua_setmetatable = lapi.lua_setmetatable; -module.exports.lua_settable = lapi.lua_settable; -module.exports.lua_settop = lapi.lua_settop; -module.exports.lua_setupvalue = lapi.lua_setupvalue; -module.exports.lua_setuservalue = lapi.lua_setuservalue; -module.exports.lua_status = lapi.lua_status; -module.exports.lua_stringtonumber = lapi.lua_stringtonumber; -module.exports.lua_toboolean = lapi.lua_toboolean; -module.exports.lua_todataview = lapi.lua_todataview; -module.exports.lua_tointeger = lapi.lua_tointeger; -module.exports.lua_tointegerx = lapi.lua_tointegerx; -module.exports.lua_tojsstring = lapi.lua_tojsstring; -module.exports.lua_tolstring = lapi.lua_tolstring; -module.exports.lua_tonumber = lapi.lua_tonumber; -module.exports.lua_tonumberx = lapi.lua_tonumberx; -module.exports.lua_topointer = lapi.lua_topointer; -module.exports.lua_toproxy = lapi.lua_toproxy; -module.exports.lua_tostring = lapi.lua_tostring; -module.exports.lua_tothread = lapi.lua_tothread; -module.exports.lua_touserdata = lapi.lua_touserdata; -module.exports.lua_type = lapi.lua_type; -module.exports.lua_typename = lapi.lua_typename; -module.exports.lua_upvalueid = lapi.lua_upvalueid; -module.exports.lua_upvaluejoin = lapi.lua_upvaluejoin; -module.exports.lua_version = lapi.lua_version; -module.exports.lua_xmove = lapi.lua_xmove; -module.exports.lua_yield = ldo.lua_yield; -module.exports.lua_yieldk = ldo.lua_yieldk; -module.exports.lua_tocfunction = lapi.lua_tocfunction; +const exported = { + LUA_AUTHORS: defs.LUA_AUTHORS, + LUA_COPYRIGHT: defs.LUA_COPYRIGHT, + LUA_ERRERR: defs.thread_status.LUA_ERRERR, + LUA_ERRGCMM: defs.thread_status.LUA_ERRGCMM, + LUA_ERRMEM: defs.thread_status.LUA_ERRMEM, + LUA_ERRRUN: defs.thread_status.LUA_ERRRUN, + LUA_ERRSYNTAX: defs.thread_status.LUA_ERRSYNTAX, + LUA_HOOKCALL: defs.LUA_HOOKCALL, + LUA_HOOKCOUNT: defs.LUA_HOOKCOUNT, + LUA_HOOKLINE: defs.LUA_HOOKLINE, + LUA_HOOKRET: defs.LUA_HOOKRET, + LUA_HOOKTAILCALL: defs.LUA_HOOKTAILCALL, + LUA_MASKCALL: defs.LUA_MASKCALL, + LUA_MASKCOUNT: defs.LUA_MASKCOUNT, + LUA_MASKLINE: defs.LUA_MASKLINE, + LUA_MASKRET: defs.LUA_MASKRET, + LUA_MINSTACK: defs.LUA_MINSTACK, + LUA_MULTRET: defs.LUA_MULTRET, + LUA_NUMTAGS: defs.constant_types.LUA_NUMTAGS, + LUA_OK: defs.thread_status.LUA_OK, + LUA_OPADD: defs.LUA_OPADD, + LUA_OPBAND: defs.LUA_OPBAND, + LUA_OPBNOT: defs.LUA_OPBNOT, + LUA_OPBOR: defs.LUA_OPBOR, + LUA_OPBXOR: defs.LUA_OPBXOR, + LUA_OPDIV: defs.LUA_OPDIV, + LUA_OPEQ: defs.LUA_OPEQ, + LUA_OPIDIV: defs.LUA_OPIDIV, + LUA_OPLE: defs.LUA_OPLE, + LUA_OPLT: defs.LUA_OPLT, + LUA_OPMOD: defs.LUA_OPMOD, + LUA_OPMUL: defs.LUA_OPMUL, + LUA_OPPOW: defs.LUA_OPPOW, + LUA_OPSHL: defs.LUA_OPSHL, + LUA_OPSHR: defs.LUA_OPSHR, + LUA_OPSUB: defs.LUA_OPSUB, + LUA_OPUNM: defs.LUA_OPUNM, + LUA_REGISTRYINDEX: defs.LUA_REGISTRYINDEX, + LUA_RELEASE: defs.LUA_RELEASE, + LUA_RIDX_GLOBALS: defs.LUA_RIDX_GLOBALS, + LUA_RIDX_LAST: defs.LUA_RIDX_LAST, + LUA_RIDX_MAINTHREAD: defs.LUA_RIDX_MAINTHREAD, + LUA_SIGNATURE: defs.LUA_SIGNATURE, + LUA_TNONE: defs.constant_types.LUA_TNONE, + LUA_TNIL: defs.constant_types.LUA_TNIL, + LUA_TBOOLEAN: defs.constant_types.LUA_TBOOLEAN, + LUA_TLIGHTUSERDATA: defs.constant_types.LUA_TLIGHTUSERDATA, + LUA_TNUMBER: defs.constant_types.LUA_TNUMBER, + LUA_TSTRING: defs.constant_types.LUA_TSTRING, + LUA_TTABLE: defs.constant_types.LUA_TTABLE, + LUA_TFUNCTION: defs.constant_types.LUA_TFUNCTION, + LUA_TUSERDATA: defs.constant_types.LUA_TUSERDATA, + LUA_TTHREAD: defs.constant_types.LUA_TTHREAD, + LUA_VERSION: defs.LUA_VERSION, + LUA_VERSION_MAJOR: defs.LUA_VERSION_MAJOR, + LUA_VERSION_MINOR: defs.LUA_VERSION_MINOR, + LUA_VERSION_NUM: defs.LUA_VERSION_NUM, + LUA_VERSION_RELEASE: defs.LUA_VERSION_RELEASE, + LUA_YIELD: defs.thread_status.LUA_YIELD, + lua_Debug: defs.lua_Debug, + lua_upvalueindex: defs.lua_upvalueindex, + lua_absindex: lapi.lua_absindex, + lua_arith: lapi.lua_arith, + lua_atpanic: lapi.lua_atpanic, + lua_atnativeerror: lapi.lua_atnativeerror, + lua_call: lapi.lua_call, + lua_callk: lapi.lua_callk, + lua_checkstack: lapi.lua_checkstack, + lua_close: lstate.lua_close, + lua_compare: lapi.lua_compare, + lua_concat: lapi.lua_concat, + lua_copy: lapi.lua_copy, + lua_createtable: lapi.lua_createtable, + lua_dump: lapi.lua_dump, + lua_error: lapi.lua_error, + lua_gc: lapi.lua_gc, + lua_getallocf: lapi.lua_getallocf, + lua_getextraspace: lapi.lua_getextraspace, + lua_getfield: lapi.lua_getfield, + lua_getglobal: lapi.lua_getglobal, + lua_gethook: ldebug.lua_gethook, + lua_gethookcount: ldebug.lua_gethookcount, + lua_gethookmask: ldebug.lua_gethookmask, + lua_geti: lapi.lua_geti, + lua_getinfo: ldebug.lua_getinfo, + lua_getlocal: ldebug.lua_getlocal, + lua_getmetatable: lapi.lua_getmetatable, + lua_getstack: ldebug.lua_getstack, + lua_gettable: lapi.lua_gettable, + lua_gettop: lapi.lua_gettop, + lua_getupvalue: lapi.lua_getupvalue, + lua_getuservalue: lapi.lua_getuservalue, + lua_insert: lapi.lua_insert, + lua_isboolean: lapi.lua_isboolean, + lua_iscfunction: lapi.lua_iscfunction, + lua_isfunction: lapi.lua_isfunction, + lua_isinteger: lapi.lua_isinteger, + lua_islightuserdata: lapi.lua_islightuserdata, + lua_isnil: lapi.lua_isnil, + lua_isnone: lapi.lua_isnone, + lua_isnoneornil: lapi.lua_isnoneornil, + lua_isnumber: lapi.lua_isnumber, + lua_isproxy: lapi.lua_isproxy, + lua_isstring: lapi.lua_isstring, + lua_istable: lapi.lua_istable, + lua_isthread: lapi.lua_isthread, + lua_isuserdata: lapi.lua_isuserdata, + lua_isyieldable: ldo.lua_isyieldable, + lua_len: lapi.lua_len, + lua_load: lapi.lua_load, + lua_newstate: lstate.lua_newstate, + lua_newtable: lapi.lua_newtable, + lua_newthread: lstate.lua_newthread, + lua_newuserdata: lapi.lua_newuserdata, + lua_next: lapi.lua_next, + lua_pcall: lapi.lua_pcall, + lua_pcallk: lapi.lua_pcallk, + lua_pop: lapi.lua_pop, + lua_pushboolean: lapi.lua_pushboolean, + lua_pushcclosure: lapi.lua_pushcclosure, + lua_pushcfunction: lapi.lua_pushcfunction, + lua_pushfstring: lapi.lua_pushfstring, + lua_pushglobaltable: lapi.lua_pushglobaltable, + lua_pushinteger: lapi.lua_pushinteger, + lua_pushjsclosure: lapi.lua_pushjsclosure, + lua_pushjsfunction: lapi.lua_pushjsfunction, + lua_pushlightuserdata: lapi.lua_pushlightuserdata, + lua_pushliteral: lapi.lua_pushliteral, + lua_pushlstring: lapi.lua_pushlstring, + lua_pushnil: lapi.lua_pushnil, + lua_pushnumber: lapi.lua_pushnumber, + lua_pushstring: lapi.lua_pushstring, + lua_pushthread: lapi.lua_pushthread, + lua_pushvalue: lapi.lua_pushvalue, + lua_pushvfstring: lapi.lua_pushvfstring, + lua_rawequal: lapi.lua_rawequal, + lua_rawget: lapi.lua_rawget, + lua_rawgeti: lapi.lua_rawgeti, + lua_rawgetp: lapi.lua_rawgetp, + lua_rawlen: lapi.lua_rawlen, + lua_rawset: lapi.lua_rawset, + lua_rawseti: lapi.lua_rawseti, + lua_rawsetp: lapi.lua_rawsetp, + lua_register: lapi.lua_register, + lua_remove: lapi.lua_remove, + lua_replace: lapi.lua_replace, + lua_resume: ldo.lua_resume, + lua_rotate: lapi.lua_rotate, + lua_setallocf: lapi.lua_setallocf, + lua_setfield: lapi.lua_setfield, + lua_setglobal: lapi.lua_setglobal, + lua_sethook: ldebug.lua_sethook, + lua_seti: lapi.lua_seti, + lua_setlocal: ldebug.lua_setlocal, + lua_setmetatable: lapi.lua_setmetatable, + lua_settable: lapi.lua_settable, + lua_settop: lapi.lua_settop, + lua_setupvalue: lapi.lua_setupvalue, + lua_setuservalue: lapi.lua_setuservalue, + lua_status: lapi.lua_status, + lua_stringtonumber: lapi.lua_stringtonumber, + lua_toboolean: lapi.lua_toboolean, + lua_todataview: lapi.lua_todataview, + lua_tointeger: lapi.lua_tointeger, + lua_tointegerx: lapi.lua_tointegerx, + lua_tojsstring: lapi.lua_tojsstring, + lua_tolstring: lapi.lua_tolstring, + lua_tonumber: lapi.lua_tonumber, + lua_tonumberx: lapi.lua_tonumberx, + lua_topointer: lapi.lua_topointer, + lua_toproxy: lapi.lua_toproxy, + lua_tostring: lapi.lua_tostring, + lua_tothread: lapi.lua_tothread, + lua_touserdata: lapi.lua_touserdata, + lua_type: lapi.lua_type, + lua_typename: lapi.lua_typename, + lua_upvalueid: lapi.lua_upvalueid, + lua_upvaluejoin: lapi.lua_upvaluejoin, + lua_version: lapi.lua_version, + lua_xmove: lapi.lua_xmove, + lua_yield: ldo.lua_yield, + lua_yieldk: ldo.lua_yieldk, + lua_tocfunction: lapi.lua_tocfunction, +}; + +module.exports = exported; From 2c73341969fa0e638ce577173c6578246bb28f99 Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Thu, 27 Apr 2023 18:29:21 +0800 Subject: [PATCH 09/14] Bug fixes and typing tests with checkJs Attempts to make tsc happy. Possible bugs: - lapi.js: there is no ts.value but ts.realstring - liolib.js: "19.x.x" > 6 is always false - loadlib.js: not lua_pushstring but lua_pushfstring - loslib.js: Uint8Arrays instead of strings passed to nodejs functions - lstrlib.js: wrong args to luaL_argcheck - ltm.js: extraneous new --- package.json | 6 +++--- src/defs.js | 1 + src/lapi.js | 11 +++++----- src/lauxlib.js | 4 ++-- src/ldump.js | 2 +- src/liolib.js | 2 +- src/loadlib.js | 3 ++- src/lobject.js | 2 +- src/loslib.js | 29 ++++++++++++++------------ src/lstrlib.js | 9 +++++---- src/ltable.js | 6 +++--- src/ltm.js | 48 ++++++++++++++++++++++---------------------- src/lvm.js | 1 + test/lapi.test.js | 3 ++- test/lauxlib.test.js | 17 +++++++++++++++- tsconfig.json | 3 ++- yarn.lock | 5 +++++ 17 files changed, 91 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index 92e2f74..ea5fd96 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,9 @@ }, "scripts": { "emit": "tsc", - "type-test": "tsc --allowJs --checkJs", "lint": "eslint src/ test/", - "prepublishOnly": "git diff-index --quiet --cached HEAD -- && npm run lint && npm run emit && npm run test", - "test": "jest" + "prepublishOnly": "git diff-index --quiet --cached HEAD -- && npm run lint && npm run test", + "test": "npm run emit && jest" }, "repository": { "type": "git", @@ -33,6 +32,7 @@ }, "homepage": "https://github.com/fengari-lua/fengari#readme", "devDependencies": { + "@types/node": "^18.16.1", "eslint": "^5.15.1", "jest": "^24.5.0", "typescript": "^5.0.4" diff --git a/src/defs.js b/src/defs.js index e9ae44c..454558b 100644 --- a/src/defs.js +++ b/src/defs.js @@ -288,6 +288,7 @@ const from_userstring = function(str) { throw new TypeError("expects an array of bytes or javascript string"); } } + // @ts-ignore return str; }; diff --git a/src/lapi.js b/src/lapi.js index 835984e..4e3b46a 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -356,7 +356,7 @@ const lua_pushinteger = function(L, n) { * @param {lua_State} L * @param {string|Uint8Array} s * @param {number} len - * @returns {any} + * @returns {Uint8Array} */ const lua_pushlstring = function(L, s, len) { fengari_argcheckinteger(len); @@ -371,7 +371,7 @@ const lua_pushlstring = function(L, s, len) { } lobject.pushsvalue2s(L, ts); api_check(L, L.top <= L.ci.top, "stack overflow"); - return ts.value; + return ts.realstring; }; /** @@ -418,9 +418,10 @@ const lua_pushfstring = function (L, fmt, ...argp) { /** * @param {lua_State} L * @param {string?} [s] - * @returns {any} + * @returns {Uint8Array?} */ const lua_pushliteral = function (L, s) { + let arr = null; if (s === undefined || s === null) { L.stack[L.top] = new TValue(LUA_TNIL, null); L.top++; @@ -428,11 +429,11 @@ const lua_pushliteral = function (L, s) { fengari_argcheck(typeof s === "string"); let ts = luaS_newliteral(L, s); lobject.pushsvalue2s(L, ts); - s = ts.getstr(); /* internal copy */ + arr = ts.getstr(); /* internal copy */ } api_check(L, L.top <= L.ci.top, "stack overflow"); - return s; + return arr; }; /** diff --git a/src/lauxlib.js b/src/lauxlib.js index 9d7e677..35ba417 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -1010,7 +1010,7 @@ if (typeof process === "undefined") { this.f = null; /* file being read */ this.buff = new Uint8Array(1024); /* area for reading file */ this.pos = 0; /* current position in file */ - this.err = void 0; + this.err = null; } } @@ -1089,7 +1089,7 @@ if (typeof process === "undefined") { this.f = null; /* file being read */ this.buff = Buffer.alloc(1024); /* area for reading file */ this.pos = 0; /* current position in file */ - this.err = void 0; + this.err = null; } } diff --git a/src/ldump.js b/src/ldump.js index 596a319..6a30f0b 100644 --- a/src/ldump.js +++ b/src/ldump.js @@ -24,7 +24,7 @@ const LUAC_FORMAT = 0; /* this is the official format */ class DumpState { constructor() { this.L = null; - this.write = null; + this.writer = null; this.data = null; this.strip = NaN; this.status = NaN; diff --git a/src/liolib.js b/src/liolib.js index 92dda58..9372dca 100644 --- a/src/liolib.js +++ b/src/liolib.js @@ -131,7 +131,7 @@ const io_output = function(L) { }; /* node <= 6 doesn't support passing a Uint8Array to fs.writeSync */ -const prepare_string_for_write = process.versions.node > 6 ? +const prepare_string_for_write = parseInt(process.versions.node.split('.')[0]) > 6 ? (s) => s : // identity function (s) => Buffer.from(s.buffer, s.byteOffset, s.byteLength); diff --git a/src/loadlib.js b/src/loadlib.js index afcfd3c..56848f7 100644 --- a/src/loadlib.js +++ b/src/loadlib.js @@ -79,6 +79,7 @@ const global_env = (function() { } else if (typeof window !== "undefined") { /* browser window */ return window; + // @ts-ignore } else if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) { /* web worker */ return self; @@ -437,7 +438,7 @@ const searcher_Croot = function(L) { if (stat != ERRFUNC) return checkload(L, 0, filename); /* real error */ else { /* open function not found */ - lua_pushstring(L, to_luastring("\n\tno module '%s' in file '%s'"), name, filename); + lua_pushfstring(L, to_luastring("\n\tno module '%s' in file '%s'"), name, filename); return 1; } } diff --git a/src/lobject.js b/src/lobject.js index c83439c..4db914e 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -552,7 +552,7 @@ const l_str2int = function(s) { } else { /* decimal */ for (; i < s.length && lisdigit(s[i]); i++) { let d = s[i] - 48 /* ('0').charCodeAt(0) */; - if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */ + if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + (neg ? 1 : 0))) /* overflow? */ return null; /* do not accept it (as integer) */ a = (a * 10 + d)|0; empty = false; diff --git a/src/loslib.js b/src/loslib.js index 2e7b90e..9e67e36 100644 --- a/src/loslib.js +++ b/src/loslib.js @@ -85,7 +85,8 @@ const setallfields = function(L, time, utc) { setfield(L, "month", (utc ? time.getUTCMonth() : time.getMonth()) + 1); setfield(L, "year", utc ? time.getUTCFullYear() : time.getFullYear()); setfield(L, "wday", (utc ? time.getUTCDay() : time.getDay()) + 1); - setfield(L, "yday", Math.floor((time - (new Date(time.getFullYear(), 0, 0 /* shortcut to correct day by one */))) / 86400000)); + setfield(L, "yday", Math.floor( + (time.valueOf() - (new Date(time.getFullYear(), 0, 0 /* shortcut to correct day by one */)).valueOf()) / 86400000)); // setboolfield(L, "isdst", time.get); }; @@ -142,7 +143,7 @@ const week_number = function(date, start_of_week) { else weekday--; } - let yday = (date - new Date(date.getFullYear(), 0, 1)) / 86400000; + let yday = (date.valueOf() - new Date(date.getFullYear(), 0, 1).valueOf()) / 86400000; return Math.floor((yday + 7 - weekday) / 7); }; @@ -283,7 +284,7 @@ const strftime = function(L, b, s, date) { // '000' case 106 /* j */: { - let yday = Math.floor((date - new Date(date.getFullYear(), 0, 1)) / 86400000); + let yday = Math.floor((date.valueOf() - new Date(date.getFullYear(), 0, 1).valueOf()) / 86400000); if (yday < 100) { if (yday < 10) luaL_addchar(b, 48 /* 0 */); @@ -425,17 +426,17 @@ const os_time = function(L) { luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 1); /* make sure table is at the top */ t = new Date( - getfield(L, "year", -1, 0), - getfield(L, "month", -1, 1), - getfield(L, "day", -1, 0), - getfield(L, "hour", 12, 0), - getfield(L, "min", 0, 0), - getfield(L, "sec", 0, 0) + Number(getfield(L, "year", -1, 0)), + Number(getfield(L, "month", -1, 1)), + Number(getfield(L, "day", -1, 0)), + Number(getfield(L, "hour", 12, 0)), + Number(getfield(L, "min", 0, 0)), + Number(getfield(L, "sec", 0, 0)) ); setallfields(L, t); } - lua_pushinteger(L, Math.floor(t / 1000)); + lua_pushinteger(L, Math.floor(t.valueOf() / 1000)); return 1; }; @@ -501,6 +502,7 @@ if (typeof process === "undefined") { }; syslib.getenv = function(L) { + /** @type {string|Uint8Array} */ let key = luaL_checkstring(L, 1); key = to_jsstring(key); /* https://github.com/nodejs/node/issues/16961 */ if (Object.prototype.hasOwnProperty.call(process.env, key)) { @@ -521,7 +523,7 @@ if (typeof process === "undefined") { }; syslib.remove = function(L) { - let filename = luaL_checkstring(L, 1); + let filename = to_jsstring(luaL_checkstring(L, 1)); try { fs.unlinkSync(filename); } catch (e) { @@ -539,8 +541,8 @@ if (typeof process === "undefined") { }; syslib.rename = function(L) { - let fromname = luaL_checkstring(L, 1); - let toname = luaL_checkstring(L, 2); + let fromname = to_jsstring(luaL_checkstring(L, 1)); + let toname = to_jsstring(luaL_checkstring(L, 2)); try { fs.renameSync(fromname, toname); } catch (e) { @@ -558,6 +560,7 @@ if (typeof process === "undefined") { }; syslib.execute = function(L) { + /** @type {string|Uint8Array} */ let cmd = luaL_optstring(L, 1, null); if (cmd !== null) { cmd = to_jsstring(cmd); diff --git a/src/lstrlib.js b/src/lstrlib.js index 21609d4..fe59a20 100644 --- a/src/lstrlib.js +++ b/src/lstrlib.js @@ -131,7 +131,7 @@ const str_char = function(L) { let p = luaL_buffinitsize(L, b, n); for (let i = 1; i <= n; i++) { let c = luaL_checkinteger(L, i); - luaL_argcheck(L, c >= 0 && c <= 255, "value out of range"); // Strings are 8-bit clean + luaL_argcheck(L, c >= 0 && c <= 255, i, "value out of range"); // Strings are 8-bit clean p[i-1] = c; } luaL_pushresultsize(b, n); @@ -540,8 +540,7 @@ const getdetails = function(h, totalsize, fmt) { else { let o = getoption(h, fmt); align = o.size; - o = o.opt; - if (o === Kchar || align === 0) + if (o.opt === Kchar || align === 0) luaL_argerror(h.L, 1, to_luastring("invalid next option for option 'X'")); } } @@ -809,7 +808,7 @@ const unpacknum = function(L, b, islittle, size) { let dv = new DataView(new ArrayBuffer(size)); for (let i = 0; i < size; i++) - dv.setUint8(i, b[i], islittle); + dv.setUint8(i, b[i]); if (size == 4) return dv.getFloat32(0, islittle); else return dv.getFloat64(0, islittle); @@ -1390,8 +1389,10 @@ const add_value = function(ms, b, s, e, tr) { }; const str_gsub = function(L) { + /** @type {any|Uint8Array} */ let src = luaL_checkstring(L, 1); /* subject */ let srcl = src.length; + /** @type {number|Uint8Array} */ let p = luaL_checkstring(L, 2); /* pattern */ let lp = p.length; let lastmatch = null; /* end of last match */ diff --git a/src/ltable.js b/src/ltable.js index fdc34bf..4e62d0b 100644 --- a/src/ltable.js +++ b/src/ltable.js @@ -106,9 +106,9 @@ class Table { this.id = L.l_G.id_counter++; this.strong = new Map(); this.dead_strong = new Map(); - this.dead_weak = void 0; /* initialised when needed */ - this.f = void 0; /* first entry */ - this.l = void 0; /* last entry */ + this.dead_weak = null; /* initialised when needed */ + this.f = null; /* first entry */ + this.l = null; /* last entry */ this.metatable = null; this.flags = ~0; } diff --git a/src/ltm.js b/src/ltm.js index a1aa8e3..3949ff5 100644 --- a/src/ltm.js +++ b/src/ltm.js @@ -71,30 +71,30 @@ const TMS = { }; const luaT_init = function(L) { - L.l_G.tmname[TMS.TM_INDEX] = new luaS_new(L, to_luastring("__index", true)); - L.l_G.tmname[TMS.TM_NEWINDEX] = new luaS_new(L, to_luastring("__newindex", true)); - L.l_G.tmname[TMS.TM_GC] = new luaS_new(L, to_luastring("__gc", true)); - L.l_G.tmname[TMS.TM_MODE] = new luaS_new(L, to_luastring("__mode", true)); - L.l_G.tmname[TMS.TM_LEN] = new luaS_new(L, to_luastring("__len", true)); - L.l_G.tmname[TMS.TM_EQ] = new luaS_new(L, to_luastring("__eq", true)); - L.l_G.tmname[TMS.TM_ADD] = new luaS_new(L, to_luastring("__add", true)); - L.l_G.tmname[TMS.TM_SUB] = new luaS_new(L, to_luastring("__sub", true)); - L.l_G.tmname[TMS.TM_MUL] = new luaS_new(L, to_luastring("__mul", true)); - L.l_G.tmname[TMS.TM_MOD] = new luaS_new(L, to_luastring("__mod", true)); - L.l_G.tmname[TMS.TM_POW] = new luaS_new(L, to_luastring("__pow", true)); - L.l_G.tmname[TMS.TM_DIV] = new luaS_new(L, to_luastring("__div", true)); - L.l_G.tmname[TMS.TM_IDIV] = new luaS_new(L, to_luastring("__idiv", true)); - L.l_G.tmname[TMS.TM_BAND] = new luaS_new(L, to_luastring("__band", true)); - L.l_G.tmname[TMS.TM_BOR] = new luaS_new(L, to_luastring("__bor", true)); - L.l_G.tmname[TMS.TM_BXOR] = new luaS_new(L, to_luastring("__bxor", true)); - L.l_G.tmname[TMS.TM_SHL] = new luaS_new(L, to_luastring("__shl", true)); - L.l_G.tmname[TMS.TM_SHR] = new luaS_new(L, to_luastring("__shr", true)); - L.l_G.tmname[TMS.TM_UNM] = new luaS_new(L, to_luastring("__unm", true)); - L.l_G.tmname[TMS.TM_BNOT] = new luaS_new(L, to_luastring("__bnot", true)); - L.l_G.tmname[TMS.TM_LT] = new luaS_new(L, to_luastring("__lt", true)); - L.l_G.tmname[TMS.TM_LE] = new luaS_new(L, to_luastring("__le", true)); - L.l_G.tmname[TMS.TM_CONCAT] = new luaS_new(L, to_luastring("__concat", true)); - L.l_G.tmname[TMS.TM_CALL] = new luaS_new(L, to_luastring("__call", true)); + L.l_G.tmname[TMS.TM_INDEX] = luaS_new(L, to_luastring("__index", true)); + L.l_G.tmname[TMS.TM_NEWINDEX] = luaS_new(L, to_luastring("__newindex", true)); + L.l_G.tmname[TMS.TM_GC] = luaS_new(L, to_luastring("__gc", true)); + L.l_G.tmname[TMS.TM_MODE] = luaS_new(L, to_luastring("__mode", true)); + L.l_G.tmname[TMS.TM_LEN] = luaS_new(L, to_luastring("__len", true)); + L.l_G.tmname[TMS.TM_EQ] = luaS_new(L, to_luastring("__eq", true)); + L.l_G.tmname[TMS.TM_ADD] = luaS_new(L, to_luastring("__add", true)); + L.l_G.tmname[TMS.TM_SUB] = luaS_new(L, to_luastring("__sub", true)); + L.l_G.tmname[TMS.TM_MUL] = luaS_new(L, to_luastring("__mul", true)); + L.l_G.tmname[TMS.TM_MOD] = luaS_new(L, to_luastring("__mod", true)); + L.l_G.tmname[TMS.TM_POW] = luaS_new(L, to_luastring("__pow", true)); + L.l_G.tmname[TMS.TM_DIV] = luaS_new(L, to_luastring("__div", true)); + L.l_G.tmname[TMS.TM_IDIV] = luaS_new(L, to_luastring("__idiv", true)); + L.l_G.tmname[TMS.TM_BAND] = luaS_new(L, to_luastring("__band", true)); + L.l_G.tmname[TMS.TM_BOR] = luaS_new(L, to_luastring("__bor", true)); + L.l_G.tmname[TMS.TM_BXOR] = luaS_new(L, to_luastring("__bxor", true)); + L.l_G.tmname[TMS.TM_SHL] = luaS_new(L, to_luastring("__shl", true)); + L.l_G.tmname[TMS.TM_SHR] = luaS_new(L, to_luastring("__shr", true)); + L.l_G.tmname[TMS.TM_UNM] = luaS_new(L, to_luastring("__unm", true)); + L.l_G.tmname[TMS.TM_BNOT] = luaS_new(L, to_luastring("__bnot", true)); + L.l_G.tmname[TMS.TM_LT] = luaS_new(L, to_luastring("__lt", true)); + L.l_G.tmname[TMS.TM_LE] = luaS_new(L, to_luastring("__le", true)); + L.l_G.tmname[TMS.TM_CONCAT] = luaS_new(L, to_luastring("__concat", true)); + L.l_G.tmname[TMS.TM_CALL] = luaS_new(L, to_luastring("__call", true)); }; /* diff --git a/src/lvm.js b/src/lvm.js index 423d2a7..78f5048 100644 --- a/src/lvm.js +++ b/src/lvm.js @@ -595,6 +595,7 @@ const luaV_execute = function(L) { let init = L.stack[ra]; let plimit = L.stack[ra + 1]; let pstep = L.stack[ra + 2]; + /** @type {any} */ let forlim; if (init.ttisinteger() && pstep.ttisinteger() && (forlim = forlimit(plimit, pstep.value))) { diff --git a/test/lapi.test.js b/test/lapi.test.js index 399155a..70570d1 100644 --- a/test/lapi.test.js +++ b/test/lapi.test.js @@ -57,7 +57,8 @@ test('lua_pushliteral', () => { if (!L) throw Error("failed to create lua state"); { - lua.lua_pushliteral(L, "hello"); + expect(lua.lua_pushliteral(L, "hello")) + .toBeInstanceOf(Uint8Array); } expect(lauxlib.luaL_typename(L, -1)) diff --git a/test/lauxlib.test.js b/test/lauxlib.test.js index 62198ac..df9d816 100644 --- a/test/lauxlib.test.js +++ b/test/lauxlib.test.js @@ -2,7 +2,7 @@ const lua = require('../src/lua.js'); const lauxlib = require("../src/lauxlib.js"); -const {to_luastring} = require("../src/fengaricore.js"); +const {to_jsstring, to_luastring} = require("../src/fengaricore.js"); test('luaL_ref, lua_rawgeti, luaL_unref, LUA_REGISTRYINDEX', () => { @@ -20,3 +20,18 @@ test('luaL_ref, lua_rawgeti, luaL_unref, LUA_REGISTRYINDEX', () => { expect(lua.lua_tojsstring(L, -1)) .toBe("hello references!"); }); + + +test('luaL_checkstring', () => { + let L = lauxlib.luaL_newstate(); + if (!L) throw Error("failed to create lua state"); + + { + lua.lua_pushstring(L, to_luastring("hello!")); + } + + expect(lauxlib.luaL_checkstring(L, -1)) + .toBeInstanceOf(Uint8Array); + expect(to_jsstring(lauxlib.luaL_checkstring(L, -1))) + .toBe("hello!"); +}); diff --git a/tsconfig.json b/tsconfig.json index 6465c60..afac56e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ "declaration": true, "emitDeclarationOnly": true, "outDir": "dist", - "declarationMap": true + "declarationMap": true, + "checkJs": true } } diff --git a/yarn.lock b/yarn.lock index 0f5de9c..cc8ff9b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -319,6 +319,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.3.tgz#7c6b0f8eaf16ae530795de2ad1b85d34bf2f5c58" integrity sha512-wp6IOGu1lxsfnrD+5mX6qwSwWuqsdkKKxTN4aQc4wByHAKZJf9/D4KXPQ1POUjEbnCP5LMggB0OEFNY9OTsMqg== +"@types/node@^18.16.1": + version "18.16.1" + resolved "https://registry.npmmirror.com/@types/node/-/node-18.16.1.tgz#5db121e9c5352925bb1f1b892c4ae620e3526799" + integrity sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA== + "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" From 7523f530f7c39961f90b96800c7c74ad90578905 Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Fri, 28 Apr 2023 01:34:04 +0800 Subject: [PATCH 10/14] Reverse several unnecessary changes - Define new variables when reusing older ones confuse tsc - Pass buffers to nodejs functions to avoid decoding errors - Refine type info and rid @ts-ignore --- src/defs.js | 84 ++++++++++++++++++++++++++++---------------------- src/lapi.js | 2 +- src/loadlib.js | 1 - src/lobject.js | 3 +- src/loslib.js | 31 +++++++++++-------- src/lvm.js | 3 +- tsconfig.json | 4 ++- 7 files changed, 73 insertions(+), 55 deletions(-) diff --git a/src/defs.js b/src/defs.js index 454558b..583b601 100644 --- a/src/defs.js +++ b/src/defs.js @@ -5,7 +5,7 @@ */ /** - * Converts a JavaScript string into a Uint8Array (used a Lua string). + * Converts a char array into a Uint8Array. * * @type {function(ArrayLike<number>):Uint8Array} */ @@ -34,7 +34,7 @@ if (typeof (new Uint8Array().indexOf) === "function") { }; } else { /* Browsers that don't support Uint8Array.indexOf seem to allow using Array.indexOf on Uint8Array objects e.g. IE11 */ - let array_indexOf = [0].indexOf; + let array_indexOf = Array.prototype.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); @@ -231,8 +231,7 @@ const to_luastring = function(str, cache) { } let len = str.length; - /** @type {Array<number> | Uint8Array} */ - let outU8Array = Array(len); /* array is at *least* going to be length of string */ + const 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); @@ -264,11 +263,11 @@ const to_luastring = function(str, cache) { } } } - outU8Array = luastring_from(outU8Array); + const converted = luastring_from(outU8Array); - if (cache) to_luastring_cache[str] = outU8Array; + if (cache) to_luastring_cache[str] = converted; - return outU8Array; + return converted; }; /** @@ -281,14 +280,13 @@ const to_luastring = function(str, cache) { * @returns {Uint8Array} */ const from_userstring = function(str) { - if (!is_luastring(str)) { + if (!(str instanceof Uint8Array)) { if (typeof str === "string") { str = to_luastring(str); } else { throw new TypeError("expects an array of bytes or javascript string"); } } - // @ts-ignore return str; }; @@ -336,37 +334,49 @@ const thread_status = { LUA_ERRERR: 6 }; -const constant_types = { - LUA_TNONE: -1, - LUA_TNIL: 0, - LUA_TBOOLEAN: 1, - LUA_TLIGHTUSERDATA: 2, - LUA_TNUMBER: 3, - LUA_TSTRING: 4, - LUA_TTABLE: 5, - LUA_TFUNCTION: 6, - LUA_TUSERDATA: 7, - LUA_TTHREAD: 8, - LUA_NUMTAGS: 9, - - LUA_TSHRSTR: 0, - LUA_TLNGSTR: 0, - LUA_TNUMFLT: 0, - LUA_TNUMINT: 0, - LUA_TLCL: 0, - LUA_TLCF: 0, - LUA_TCCL: 0, -}; +const LUA_TNONE = -1; +const LUA_TNIL = 0; +const LUA_TBOOLEAN = 1; +const LUA_TLIGHTUSERDATA = 2; +const LUA_TNUMBER = 3; +const LUA_TSTRING = 4; +const LUA_TTABLE = 5; +const LUA_TFUNCTION = 6; +const LUA_TUSERDATA = 7; +const LUA_TTHREAD = 8; +const LUA_NUMTAGS = 9; + +const LUA_TSHRSTR = LUA_TSTRING | (0 << 4); /* short strings */ +const LUA_TLNGSTR = LUA_TSTRING | (1 << 4); /* long strings */ -constant_types.LUA_TSHRSTR = constant_types.LUA_TSTRING | (0 << 4); /* short strings */ -constant_types.LUA_TLNGSTR = constant_types.LUA_TSTRING | (1 << 4); /* long strings */ +const LUA_TNUMFLT = LUA_TNUMBER | (0 << 4); /* float numbers */ +const LUA_TNUMINT = LUA_TNUMBER | (1 << 4); /* integer numbers */ -constant_types.LUA_TNUMFLT = constant_types.LUA_TNUMBER | (0 << 4); /* float numbers */ -constant_types.LUA_TNUMINT = constant_types.LUA_TNUMBER | (1 << 4); /* integer numbers */ +const LUA_TLCL = LUA_TFUNCTION | (0 << 4); /* Lua closure */ +const LUA_TLCF = LUA_TFUNCTION | (1 << 4); /* light C function */ +const LUA_TCCL = LUA_TFUNCTION | (2 << 4); /* C closure */ -constant_types.LUA_TLCL = constant_types.LUA_TFUNCTION | (0 << 4); /* Lua closure */ -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 constant_types = { + LUA_TNONE: LUA_TNONE, + LUA_TNIL: LUA_TNIL, + LUA_TBOOLEAN: LUA_TBOOLEAN, + LUA_TLIGHTUSERDATA: LUA_TLIGHTUSERDATA, + LUA_TNUMBER: LUA_TNUMBER, + LUA_TSTRING: LUA_TSTRING, + LUA_TTABLE: LUA_TTABLE, + LUA_TFUNCTION: LUA_TFUNCTION, + LUA_TUSERDATA: LUA_TUSERDATA, + LUA_TTHREAD: LUA_TTHREAD, + LUA_NUMTAGS: LUA_NUMTAGS, + + LUA_TSHRSTR: LUA_TSHRSTR, + LUA_TLNGSTR: LUA_TLNGSTR, + LUA_TNUMFLT: LUA_TNUMFLT, + LUA_TNUMINT: LUA_TNUMINT, + LUA_TLCL: LUA_TLCL, + LUA_TLCF: LUA_TLCF, + LUA_TCCL: LUA_TCCL, +}; /* ** Comparison and arithmetic functions diff --git a/src/lapi.js b/src/lapi.js index 4e3b46a..e50080f 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -406,7 +406,7 @@ const lua_pushvfstring = function (L, fmt, argp) { /** * @param {lua_State} L * @param {string|Uint8Array} fmt - * @param {any} argp + * @param {any[]} argp * @returns {any} */ const lua_pushfstring = function (L, fmt, ...argp) { diff --git a/src/loadlib.js b/src/loadlib.js index 56848f7..92bf677 100644 --- a/src/loadlib.js +++ b/src/loadlib.js @@ -79,7 +79,6 @@ const global_env = (function() { } else if (typeof window !== "undefined") { /* browser window */ return window; - // @ts-ignore } else if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) { /* web worker */ return self; diff --git a/src/lobject.js b/src/lobject.js index 4db914e..c6be413 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -538,6 +538,7 @@ const l_str2int = function(s) { let i = 0; let a = 0; let empty = true; + /** @type {boolean|any} */ let neg; while (lisspace(s[i])) i++; /* skip initial spaces */ @@ -552,7 +553,7 @@ const l_str2int = function(s) { } else { /* decimal */ for (; i < s.length && lisdigit(s[i]); i++) { let d = s[i] - 48 /* ('0').charCodeAt(0) */; - if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + (neg ? 1 : 0))) /* overflow? */ + if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */ return null; /* do not accept it (as integer) */ a = (a * 10 + d)|0; empty = false; diff --git a/src/loslib.js b/src/loslib.js index 9e67e36..9dbaf1d 100644 --- a/src/loslib.js +++ b/src/loslib.js @@ -92,6 +92,13 @@ const setallfields = function(L, time, utc) { const L_MAXDATEFIELD = (Number.MAX_SAFE_INTEGER / 2); +/** + * @param {import('./lstate').lua_State} L + * @param {string} key + * @param {number} d + * @param {number} delta + * @returns + */ const getfield = function(L, key, d, delta) { let t = lua_getfield(L, -1, to_luastring(key, true)); /* get field and its type */ let res = lua_tointegerx(L, -1); @@ -426,12 +433,12 @@ const os_time = function(L) { luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 1); /* make sure table is at the top */ t = new Date( - Number(getfield(L, "year", -1, 0)), - Number(getfield(L, "month", -1, 1)), - Number(getfield(L, "day", -1, 0)), - Number(getfield(L, "hour", 12, 0)), - Number(getfield(L, "min", 0, 0)), - Number(getfield(L, "sec", 0, 0)) + getfield(L, "year", -1, 0), + getfield(L, "month", -1, 1), + getfield(L, "day", -1, 0), + getfield(L, "hour", 12, 0), + getfield(L, "min", 0, 0), + getfield(L, "sec", 0, 0) ); setallfields(L, t); } @@ -523,13 +530,13 @@ if (typeof process === "undefined") { }; syslib.remove = function(L) { - let filename = to_jsstring(luaL_checkstring(L, 1)); + let filename = luaL_checkstring(L, 1); try { - fs.unlinkSync(filename); + fs.unlinkSync(Buffer.from(filename)); } catch (e) { if (e.code === 'EISDIR') { try { - fs.rmdirSync(filename); + fs.rmdirSync(Buffer.from(filename)); } catch (e) { return luaL_fileresult(L, false, filename, e); } @@ -541,10 +548,10 @@ if (typeof process === "undefined") { }; syslib.rename = function(L) { - let fromname = to_jsstring(luaL_checkstring(L, 1)); - let toname = to_jsstring(luaL_checkstring(L, 2)); + let fromname = luaL_checkstring(L, 1); + let toname = luaL_checkstring(L, 2); try { - fs.renameSync(fromname, toname); + fs.renameSync(Buffer.from(fromname), Buffer.from(toname)); } catch (e) { return luaL_fileresult(L, false, false, e); } diff --git a/src/lvm.js b/src/lvm.js index 78f5048..c02335e 100644 --- a/src/lvm.js +++ b/src/lvm.js @@ -595,7 +595,6 @@ const luaV_execute = function(L) { let init = L.stack[ra]; let plimit = L.stack[ra + 1]; let pstep = L.stack[ra + 2]; - /** @type {any} */ let forlim; if (init.ttisinteger() && pstep.ttisinteger() && (forlim = forlimit(plimit, pstep.value))) { @@ -800,7 +799,7 @@ const forlimit = function(obj, step) { if (ilimit === false) { let n = tonumber(obj); if (n === false) - return false; + return null; if (0 < n) { ilimit = LUA_MAXINTEGER; diff --git a/tsconfig.json b/tsconfig.json index afac56e..f7d9569 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,8 @@ "emitDeclarationOnly": true, "outDir": "dist", "declarationMap": true, - "checkJs": true + "checkJs": true, + "lib": ["DOM", "WebWorker", "ES2015"], + "skipLibCheck": true } } From 81472fba051dcce2b2be7ce4c4d2e70c64164502 Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Fri, 28 Apr 2023 10:46:45 +0800 Subject: [PATCH 11/14] Test type info with test files --- package.json | 3 +- test/ldblib.test.js | 3 + test/lstrlib.test.js | 4 +- test/test-suite/ltests.js | 10 +- tsconfig.test.json | 8 ++ yarn.lock | 288 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 307 insertions(+), 9 deletions(-) create mode 100644 tsconfig.test.json diff --git a/package.json b/package.json index ea5fd96..f2658bc 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "emit": "tsc", "lint": "eslint src/ test/", "prepublishOnly": "git diff-index --quiet --cached HEAD -- && npm run lint && npm run test", - "test": "npm run emit && jest" + "test": "tsc -p ./tsconfig.test.json && jest" }, "repository": { "type": "git", @@ -32,6 +32,7 @@ }, "homepage": "https://github.com/fengari-lua/fengari#readme", "devDependencies": { + "@types/jest": "^29.5.1", "@types/node": "^18.16.1", "eslint": "^5.15.1", "jest": "^24.5.0", diff --git a/test/ldblib.test.js b/test/ldblib.test.js index ba68853..d33abef 100644 --- a/test/ldblib.test.js +++ b/test/ldblib.test.js @@ -194,6 +194,7 @@ test('debug.traceback (with a global)', () => { let L = lauxlib.luaL_newstate(); if (!L) throw Error("failed to create lua state"); + /** @type {string|Uint8Array} */ let luaCode = ` local trace @@ -238,6 +239,7 @@ test('debug.traceback (with a upvalue)', () => { let L = lauxlib.luaL_newstate(); if (!L) throw Error("failed to create lua state"); + /** @type {string|Uint8Array} */ let luaCode = ` local trace local rec @@ -282,6 +284,7 @@ test('debug.getinfo', () => { let L = lauxlib.luaL_newstate(); if (!L) throw Error("failed to create lua state"); + /** @type {string|Uint8Array} */ let luaCode = ` local alocal = function(p1, p2) end global = function() return alocal end diff --git a/test/lstrlib.test.js b/test/lstrlib.test.js index 3ae2ec3..e41495f 100644 --- a/test/lstrlib.test.js +++ b/test/lstrlib.test.js @@ -159,9 +159,7 @@ test('string.format', () => { lua.lua_call(L, 0, -1); } - expect(lua.lua_tojsstring(L, -1)).toBe('"a string with \\"quotes\\" and \\\n new line"', - "Correct element(s) on the stack" - ); + expect(lua.lua_tojsstring(L, -1)).toBe('"a string with \\"quotes\\" and \\\n new line"'); }); diff --git a/test/test-suite/ltests.js b/test/test-suite/ltests.js index 6fc086c..02f1453 100644 --- a/test/test-suite/ltests.js +++ b/test/test-suite/ltests.js @@ -171,6 +171,7 @@ const runJS = function(L, L1, pc) { break; } case "func2num": { + /** @type {any} */ let func = lua.lua_tocfunction(L1, getindex(L, L1, pc)); if (func === null) func = 0; else if (func.id) func = func.id; @@ -187,7 +188,7 @@ const runJS = function(L, L1, pc) { break; } case "getmetatable": { - if (lua.lua_getmetatable(L1, getindex(L, L1, pc)) === 0) + if (lua.lua_getmetatable(L1, getindex(L, L1, pc)) === false) lua.lua_pushnil(L1); break; } @@ -307,7 +308,7 @@ const runJS = function(L, L1, pc) { case "print": { let n = getnum(L, L1, pc); if (n !== 0) { - console.log(`${lauxlib.luaL_tojsstring(L1, n, null)}\n`); + console.log(`${lua.lua_tojsstring(L1, n)}\n`); lua.lua_pop(L1, 1); } else printstack(L1); @@ -607,11 +608,10 @@ const closestate = function(L) { const doremote = function(L) { let L1 = getstate(L); - let lcode; - let code = lauxlib.luaL_checklstring(L, 2, lcode); + let code = lauxlib.luaL_checklstring(L, 2); let status; lua.lua_settop(L1, 0); - status = lauxlib.luaL_loadbuffer(L1, code, lcode, code); + status = lauxlib.luaL_loadbuffer(L1, code, code.length, code); if (status === lua.LUA_OK) status = lua.lua_pcall(L1, 0, lua.LUA_MULTRET, 0); if (status !== lua.LUA_OK) { diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..2560a3d --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,8 @@ +{ + "include": ["src/**/*", "test/**/*"], + "compilerOptions": { + "noEmit": true, + "emitDeclarationOnly": false, + }, + "extends": "./tsconfig.json", +} diff --git a/yarn.lock b/yarn.lock index cc8ff9b..a5dec95 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,6 +9,13 @@ dependencies: "@babel/highlight" "^7.0.0" +"@babel/code-frame@^7.12.13": + version "7.21.4" + resolved "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" + integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== + dependencies: + "@babel/highlight" "^7.18.6" + "@babel/core@^7.1.0": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.4.tgz#921a5a13746c21e32445bf0798680e9d11a6530b" @@ -68,6 +75,11 @@ dependencies: "@babel/types" "^7.0.0" +"@babel/helper-validator-identifier@^7.18.6": + version "7.19.1" + resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + "@babel/helpers@^7.2.0": version "7.3.1" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.3.1.tgz#949eec9ea4b45d3210feb7dc1c22db664c9e44b9" @@ -86,6 +98,15 @@ esutils "^2.0.2" js-tokens "^4.0.0" +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.2.2", "@babel/parser@^7.3.4": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.4.tgz#a43357e4bbf4b92a437fb9e465c192848287f27c" @@ -193,6 +214,13 @@ "@types/node" "*" jest-mock "^24.5.0" +"@jest/expect-utils@^29.5.0": + version "29.5.0" + resolved "https://registry.npmmirror.com/@jest/expect-utils/-/expect-utils-29.5.0.tgz#f74fad6b6e20f924582dc8ecbf2cb800fe43a036" + integrity sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg== + dependencies: + jest-get-type "^29.4.3" + "@jest/fake-timers@^24.5.0": version "24.5.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.5.0.tgz#4a29678b91fd0876144a58f8d46e6c62de0266f0" @@ -229,6 +257,13 @@ source-map "^0.6.0" string-length "^2.0.0" +"@jest/schemas@^29.4.3": + version "29.4.3" + resolved "https://registry.npmmirror.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" + integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== + dependencies: + "@sinclair/typebox" "^0.25.16" + "@jest/source-map@^24.3.0": version "24.3.0" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28" @@ -276,6 +311,23 @@ "@types/istanbul-lib-coverage" "^1.1.0" "@types/yargs" "^12.0.9" +"@jest/types@^29.5.0": + version "29.5.0" + resolved "https://registry.npmmirror.com/@jest/types/-/types-29.5.0.tgz#f59ef9b031ced83047c67032700d8c807d6e1593" + integrity sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog== + dependencies: + "@jest/schemas" "^29.4.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@sinclair/typebox@^0.25.16": + version "0.25.24" + resolved "https://registry.npmmirror.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" + integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== + "@types/babel__core@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.0.tgz#710f2487dda4dcfd010ca6abb2b4dc7394365c51" @@ -309,11 +361,38 @@ dependencies: "@babel/types" "^7.3.0" +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.4" + resolved "https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + "@types/istanbul-lib-coverage@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz#2cc2ca41051498382b43157c8227fea60363f94a" integrity sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ== +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.npmmirror.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.npmmirror.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^29.5.1": + version "29.5.1" + resolved "https://registry.npmmirror.com/@types/jest/-/jest-29.5.1.tgz#83c818aa9a87da27d6da85d3378e5a34d2f31a47" + integrity sha512-tEuVcHrpaixS36w7hpsfLBLpjtMRJUE09/MHXn923LOVojDwyC14cWcfc0rDs0VEfUyYmt/+iX1kxxp+gZMcaQ== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + "@types/node@*": version "11.11.3" resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.3.tgz#7c6b0f8eaf16ae530795de2ad1b85d34bf2f5c58" @@ -329,11 +408,28 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.npmmirror.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + "@types/yargs@^12.0.2", "@types/yargs@^12.0.9": version "12.0.9" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.9.tgz#693e76a52f61a2f1e7fb48c0eef167b95ea4ffd0" integrity sha512-sCZy4SxP9rN2w30Hlmg5dtdRwgYQfYRiLo9usw8X9cxlf+H4FqM1xX7+sNH7NNKVdbXMJWqva7iyy+fxh/V7fA== +"@types/yargs@^17.0.8": + version "17.0.24" + resolved "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== + dependencies: + "@types/yargs-parser" "*" + abab@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" @@ -404,6 +500,18 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -596,6 +704,13 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + browser-process-hrtime@^0.1.2: version "0.1.3" resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" @@ -666,6 +781,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -676,6 +799,11 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +ci-info@^3.2.0: + version "3.8.0" + resolved "https://registry.npmmirror.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -732,11 +860,23 @@ color-convert@^1.9.0: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" @@ -900,6 +1040,11 @@ diff-sequences@^24.3.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975" integrity sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw== +diff-sequences@^29.4.3: + version "29.4.3" + resolved "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" + integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== + doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -967,6 +1112,11 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escodegen@^1.9.1: version "1.11.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.1.tgz#c485ff8d6b4cdb89e27f4a856e91f118401ca510" @@ -1130,6 +1280,17 @@ expect@^24.5.0: jest-message-util "^24.5.0" jest-regex-util "^24.3.0" +expect@^29.0.0: + version "29.5.0" + resolved "https://registry.npmmirror.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" + integrity sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg== + dependencies: + "@jest/expect-utils" "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -1237,6 +1398,13 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -1345,6 +1513,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== +graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -1379,6 +1552,11 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" @@ -1629,6 +1807,11 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -1833,6 +2016,16 @@ jest-diff@^24.5.0: jest-get-type "^24.3.0" pretty-format "^24.5.0" +jest-diff@^29.5.0: + version "29.5.0" + resolved "https://registry.npmmirror.com/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63" + integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" + jest-docblock@^24.3.0: version "24.3.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.3.0.tgz#b9c32dac70f72e4464520d2ba4aec02ab14db5dd" @@ -1879,6 +2072,11 @@ jest-get-type@^24.3.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.3.0.tgz#582cfd1a4f91b5cdad1d43d2932f816d543c65da" integrity sha512-HYF6pry72YUlVcvUx3sEpMRwXEWGEPlJ0bSPVnB3b3n++j4phUEoSPcS6GC0pPJ9rpyPSe4cb5muFo6D39cXow== +jest-get-type@^29.4.3: + version "29.4.3" + resolved "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" + integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== + jest-haste-map@^24.5.0: version "24.5.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.5.0.tgz#3f17d0c548b99c0c96ed2893f9c0ccecb2eb9066" @@ -1933,6 +2131,16 @@ jest-matcher-utils@^24.5.0: jest-get-type "^24.3.0" pretty-format "^24.5.0" +jest-matcher-utils@^29.5.0: + version "29.5.0" + resolved "https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz#d957af7f8c0692c5453666705621ad4abc2c59c5" + integrity sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw== + dependencies: + chalk "^4.0.0" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" + jest-message-util@^24.5.0: version "24.5.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.5.0.tgz#181420a65a7ef2e8b5c2f8e14882c453c6d41d07" @@ -1947,6 +2155,21 @@ jest-message-util@^24.5.0: slash "^2.0.0" stack-utils "^1.0.1" +jest-message-util@^29.5.0: + version "29.5.0" + resolved "https://registry.npmmirror.com/jest-message-util/-/jest-message-util-29.5.0.tgz#1f776cac3aca332ab8dd2e3b41625435085c900e" + integrity sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.5.0" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.5.0" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^24.5.0: version "24.5.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.5.0.tgz#976912c99a93f2a1c67497a9414aa4d9da4c7b76" @@ -2080,6 +2303,18 @@ jest-util@^24.5.0: slash "^2.0.0" source-map "^0.6.0" +jest-util@^29.5.0: + version "29.5.0" + resolved "https://registry.npmmirror.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" + integrity sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ== + dependencies: + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-validate@^24.5.0: version "24.5.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.5.0.tgz#62fd93d81214c070bb2d7a55f329a79d8057c7de" @@ -2377,6 +2612,14 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + mime-db@~1.38.0: version "1.38.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad" @@ -2730,6 +2973,11 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" @@ -2774,6 +3022,15 @@ pretty-format@^24.5.0: ansi-styles "^3.2.0" react-is "^16.8.4" +pretty-format@^29.0.0, pretty-format@^29.5.0: + version "29.5.0" + resolved "https://registry.npmmirror.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" + integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw== + dependencies: + "@jest/schemas" "^29.4.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" @@ -2825,6 +3082,11 @@ react-is@^16.8.4: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.4.tgz#90f336a68c3a29a096a3d648ab80e87ec61482a2" integrity sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA== +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + read-pkg-up@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" @@ -3119,6 +3381,11 @@ slash@^2.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + slice-ansi@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" @@ -3255,6 +3522,13 @@ stack-utils@^1.0.1: resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -3359,6 +3633,13 @@ supports-color@^6.0.0, supports-color@^6.1.0: dependencies: has-flag "^3.0.0" +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + symbol-tree@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" @@ -3431,6 +3712,13 @@ to-regex-range@^2.1.0: is-number "^3.0.0" repeat-string "^1.6.1" +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" From 8eec9d522fb383e9b568de1e939f4e254d72e119 Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Fri, 28 Apr 2023 11:17:50 +0800 Subject: [PATCH 12/14] Add a os.rename/remove test --- test/loslib.test.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/loslib.test.js b/test/loslib.test.js index af7de92..cafdb7f 100644 --- a/test/loslib.test.js +++ b/test/loslib.test.js @@ -160,3 +160,31 @@ test('os.getenv', () => { expect(lua.lua_isstring(L, -1)).toBe(true); }); + +describe('filesystem tests', () => { + (process ? it : it.skip)('os.rename, os.remove', () => { + expect(typeof lualib.luaopen_io).toBe("function"); + let L = lauxlib.luaL_newstate(); + if (!L) throw Error("failed to create lua state"); + + { + const fs = require("fs"); + const tmp = require("tmp"); + const file = tmp.fileSync(); + lua.lua_pushstring(L, file.name); + lua.lua_setglobal(L, "filename"); + lualib.luaL_openlibs(L); + + expect(lauxlib.luaL_loadstring(L, to_luastring(`assert(os.rename(filename, filename .. '.renamed'))`))) + .toBe(lua.LUA_OK); + lua.lua_call(L, 0, -1); + expect(fs.existsSync(file.name)).toBe(false); + expect(fs.existsSync(`${file.name}.renamed`)).toBe(true); + + expect(lauxlib.luaL_loadstring(L, to_luastring(`assert(os.remove(filename .. '.renamed'))`))) + .toBe(lua.LUA_OK); + lua.lua_call(L, 0, -1); + expect(fs.existsSync(`${file.name}.renamed`)).toBe(false); + } + }); +}); From 4e3dc6a0260d750706ee1cb9ae698ec53a892c77 Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Fri, 28 Apr 2023 11:33:10 +0800 Subject: [PATCH 13/14] Use LuaString as a type alias for Uint8Array --- package.json | 2 +- src/defs.js | 26 ++++++++++++++----------- src/lapi.js | 29 ++++++++++++++------------- src/lauxlib.js | 53 +++++++++++++++++++++++++------------------------- src/loadlib.js | 3 +-- src/loslib.js | 8 ++++++-- src/lstring.js | 3 ++- src/lstrlib.js | 8 ++++++-- 8 files changed, 73 insertions(+), 59 deletions(-) diff --git a/package.json b/package.json index f2658bc..aaa2a21 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "scripts": { "emit": "tsc", "lint": "eslint src/ test/", - "prepublishOnly": "git diff-index --quiet --cached HEAD -- && npm run lint && npm run test", + "prepublishOnly": "git diff-index --quiet --cached HEAD -- && npm run lint && npm run emit && npm run test", "test": "tsc -p ./tsconfig.test.json && jest" }, "repository": { diff --git a/src/defs.js b/src/defs.js index 583b601..af391ba 100644 --- a/src/defs.js +++ b/src/defs.js @@ -5,9 +5,13 @@ */ /** - * Converts a char array into a Uint8Array. + * @typedef {Uint8Array} LuaString + */ + +/** + * Converts a char array into a Lua string. * - * @type {function(ArrayLike<number>):Uint8Array} + * @type {function(ArrayLike<number>):LuaString} */ let luastring_from; if (typeof Uint8Array.from === "function") { @@ -25,7 +29,7 @@ if (typeof Uint8Array.from === "function") { /** * Returns the index of the first occurrence of the character in the Lua string. * - * @type {function(Uint8Array|any[], number, number=):number} + * @type {function(LuaString|number[], number, number=):number} */ let luastring_indexOf; if (typeof (new Uint8Array().indexOf) === "function") { @@ -44,7 +48,7 @@ if (typeof (new Uint8Array().indexOf) === "function") { /** * Constructs a Lua string from characters. * - * @type {function(...number):Uint8Array} + * @type {function(...number):LuaString} */ let luastring_of; if (typeof Uint8Array.of === "function") { @@ -67,8 +71,8 @@ const is_luastring = function(s) { /** * Tests two Lua strings for equality. * - * @param {Uint8Array} a str 1 - * @param {Uint8Array} b str 2 + * @param {LuaString} a str 1 + * @param {LuaString} b str 2 * @returns {boolean} */ const luastring_eq = function(a, b) { @@ -87,7 +91,7 @@ const unicode_error_message = "cannot convert invalid utf8 to javascript string" /** * Converts a Lua string (in UTF-8) to a normal JavaScript string. * - * @param {Uint8Array} value the Lua string + * @param {LuaString} value the Lua string * @param {number} [from] the staring index * @param {number} [to] the ending index * @param {boolean} [replacement_char] whether to replace invalid utf8 chars @@ -198,7 +202,7 @@ const uri_allowed = (";,/?:@&=+$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV /** * Utility function to convert a Lua string to a JavaScript string with URI escaping. * - * @param {Uint8Array} a the string + * @param {LuaString} a the string * @returns {string} */ const to_uristring = function(a) { @@ -220,7 +224,7 @@ const to_luastring_cache = {}; /** * @param {string} str * @param {boolean} [cache] - * @returns {Uint8Array} + * @returns {LuaString} */ const to_luastring = function(str, cache) { if (typeof str !== "string") throw new TypeError("to_luastring expects a javascript string"); @@ -276,8 +280,8 @@ const to_luastring = function(str, cache) { * If `str` is already a Lua string, it returns it as is. * Otherwise, it tries to convert it. * - * @param {string|Uint8Array} str - * @returns {Uint8Array} + * @param {string|LuaString} str + * @returns {LuaString} */ const from_userstring = function(str) { if (!(str instanceof Uint8Array)) { diff --git a/src/lapi.js b/src/lapi.js index e50080f..ef6cf21 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -2,6 +2,7 @@ /** * @typedef {import('./lstate').lua_State} lua_State + * @typedef {import('./defs').LuaString} LuaString */ const { @@ -354,9 +355,9 @@ const lua_pushinteger = function(L, n) { /** * @param {lua_State} L - * @param {string|Uint8Array} s + * @param {string|LuaString} s * @param {number} len - * @returns {Uint8Array} + * @returns {LuaString} */ const lua_pushlstring = function(L, s, len) { fengari_argcheckinteger(len); @@ -376,7 +377,7 @@ const lua_pushlstring = function(L, s, len) { /** * @param {lua_State} L - * @param {string|Uint8Array} s + * @param {string|LuaString} s * @returns {any} */ const lua_pushstring = function (L, s) { @@ -394,7 +395,7 @@ const lua_pushstring = function (L, s) { /** * @param {lua_State} L - * @param {string|Uint8Array} fmt + * @param {string|LuaString} fmt * @param {any[]} argp * @returns {any} */ @@ -405,7 +406,7 @@ const lua_pushvfstring = function (L, fmt, argp) { /** * @param {lua_State} L - * @param {string|Uint8Array} fmt + * @param {string|LuaString} fmt * @param {any[]} argp * @returns {any} */ @@ -418,7 +419,7 @@ const lua_pushfstring = function (L, fmt, ...argp) { /** * @param {lua_State} L * @param {string?} [s] - * @returns {Uint8Array?} + * @returns {LuaString?} */ const lua_pushliteral = function (L, s) { let arr = null; @@ -528,7 +529,7 @@ const auxsetstr = function(L, t, k) { /** * @param {lua_State} L - * @param {Uint8Array} name + * @param {string|LuaString} name */ const lua_setglobal = function(L, name) { auxsetstr(L, ltable.luaH_getint(L.l_G.l_registry.value, LUA_RIDX_GLOBALS), name); @@ -580,7 +581,7 @@ const lua_settable = function(L, idx) { /** * @param {lua_State} L * @param {number} idx - * @param {Uint8Array} k + * @param {LuaString} k */ const lua_setfield = function(L, idx, k) { auxsetstr(L, index2addr(L, idx), k); @@ -802,7 +803,7 @@ const lua_newtable = function(L) { /** * @param {lua_State} L - * @param {Uint8Array} n + * @param {LuaString} n * @param {function} f */ const lua_register = function(L, n, f) { @@ -866,7 +867,7 @@ const lua_gettable = function(L, idx) { /** * @param {lua_State} L * @param {number} idx - * @param {Uint8Array} k + * @param {string|LuaString} k * @returns {number} */ const lua_getfield = function(L, idx, k) { @@ -890,7 +891,7 @@ const lua_geti = function(L, idx, n) { /** * @param {lua_State} L - * @param {Uint8Array} name + * @param {LuaString} name * @returns {number} */ const lua_getglobal = function(L, name) { @@ -914,7 +915,7 @@ const lua_toboolean = function(L, idx) { /** * @param {lua_State} L * @param {number} idx - * @returns {Uint8Array?} + * @returns {LuaString?} */ const lua_tolstring = function(L, idx) { let o = index2addr(L, idx); @@ -1132,7 +1133,7 @@ const lua_compare = function(L, index1, index2, op) { /** * @param {lua_State} L - * @param {Uint8Array} s + * @param {LuaString} s * @returns {number} */ const lua_stringtonumber = function(L, s) { @@ -1162,7 +1163,7 @@ const lua_type = function(L, idx) { /** * @param {lua_State} L * @param {number} t - * @returns {Uint8Array} + * @returns {LuaString} */ const lua_typename = function(L, t) { api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag"); diff --git a/src/lauxlib.js b/src/lauxlib.js index 35ba417..eb81551 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -2,6 +2,7 @@ /** * @typedef {import('./lstate').lua_State} lua_State + * @typedef {import('./defs').LuaString} LuaString */ const { @@ -205,7 +206,7 @@ const lastlevel = function(L) { /** * @param {lua_State} L * @param {lua_State} L1 - * @param {Uint8Array} msg + * @param {LuaString} msg * @param {number} level */ const luaL_traceback = function(L, L1, msg, level) { @@ -310,7 +311,7 @@ const luaL_error = function(L, fmt, ...argp) { /** * @param {lua_State} L * @param {any} [stat] - * @param {string|Uint8Array|false} [fname] + * @param {string|LuaString|false} [fname] * @param {any} [e] * @returns {number} */ @@ -368,7 +369,7 @@ const luaL_execresult = function(L, e) { /** * @param {lua_State} L - * @param {Uint8Array} n + * @param {LuaString} n * @returns {number} */ const luaL_getmetatable = function(L, n) { @@ -377,7 +378,7 @@ const luaL_getmetatable = function(L, n) { /** * @param {lua_State} L - * @param {Uint8Array} tname + * @param {LuaString} tname * @returns {number} */ const luaL_newmetatable = function(L, tname) { @@ -395,7 +396,7 @@ const luaL_newmetatable = function(L, tname) { /** * @param {lua_State} L - * @param {Uint8Array} tname + * @param {LuaString} tname */ const luaL_setmetatable = function(L, tname) { luaL_getmetatable(L, tname); @@ -450,7 +451,7 @@ const luaL_newstate = function() { /** * @param {lua_State} L * @param {number} i - * @returns {Uint8Array} + * @returns {LuaString} */ const luaL_typename = function(L, i) { return lua_typename(L, lua_type(L, i)); @@ -488,7 +489,7 @@ const luaL_checktype = function(L, arg, t) { /** * @param {lua_State} L * @param {number} arg - * @returns {Uint8Array} + * @returns {LuaString} */ const luaL_checklstring = function(L, arg) { let s = lua_tolstring(L, arg); @@ -501,8 +502,8 @@ const luaL_checkstring = luaL_checklstring; /** * @param {lua_State} L * @param {number} arg - * @param {string|Uint8Array} [def] - * @returns {Uint8Array} + * @param {string|LuaString} [def] + * @returns {LuaString} */ const luaL_optlstring = function(L, arg, def) { if (lua_type(L, arg) <= 0) { @@ -642,10 +643,10 @@ const getS = function(L, ud) { /** * @param {lua_State} L - * @param {Uint8Array} buff + * @param {LuaString} buff * @param {number} size - * @param {Uint8Array} name - * @param {Uint8Array} mode + * @param {LuaString} name + * @param {LuaString} mode * @returns {number} */ const luaL_loadbufferx = function(L, buff, size, name, mode) { @@ -654,9 +655,9 @@ const luaL_loadbufferx = function(L, buff, size, name, mode) { /** * @param {lua_State} L - * @param {Uint8Array} s + * @param {LuaString} s * @param {number} sz - * @param {Uint8Array} n + * @param {LuaString} n * @returns {number} */ const luaL_loadbuffer = function(L, s, sz, n) { @@ -665,7 +666,7 @@ const luaL_loadbuffer = function(L, s, sz, n) { /** * @param {lua_State} L - * @param {Uint8Array} s + * @param {LuaString} s * @returns {number} */ const luaL_loadstring = function(L, s) { @@ -674,7 +675,7 @@ const luaL_loadstring = function(L, s) { /** * @param {lua_State} L - * @param {Uint8Array} s + * @param {LuaString} s * @returns {number} */ const luaL_dostring = function(L, s) { @@ -684,7 +685,7 @@ const luaL_dostring = function(L, s) { /** * @param {lua_State} L * @param {number} obj - * @param {Uint8Array} event + * @param {LuaString} event * @returns {number} */ const luaL_getmetafield = function(L, obj, event) { @@ -704,7 +705,7 @@ const luaL_getmetafield = function(L, obj, event) { /** * @param {lua_State} L * @param {number} obj - * @param {Uint8Array} event + * @param {LuaString} event * @returns {boolean} */ const luaL_callmeta = function(L, obj, event) { @@ -737,7 +738,7 @@ const p_f = to_luastring("%f"); /** * @param {lua_State} L * @param {number} idx - * @returns {Uint8Array} + * @returns {LuaString} */ const luaL_tolstring = function(L, idx) { if (luaL_callmeta(L, idx, __tostring)) { @@ -816,10 +817,10 @@ const find_subarray = function(arr, subarr, from_index) { /** * @param {lua_State} L - * @param {Uint8Array} s - * @param {Uint8Array} p - * @param {Uint8Array} r - * @returns {Uint8Array} + * @param {LuaString} s + * @param {LuaString} p + * @param {LuaString} r + * @returns {LuaString} */ const luaL_gsub = function(L, s, p, r) { let wild; @@ -842,7 +843,7 @@ const luaL_gsub = function(L, s, p, r) { /** * @param {lua_State} L * @param {number} idx - * @param {Uint8Array} fname + * @param {LuaString} fname * @returns {boolean} */ const luaL_getsubtable = function(L, idx, fname) { @@ -1163,7 +1164,7 @@ if (typeof process === "undefined") { /** * @param {lua_State} L - * @param {Uint8Array} filename + * @param {LuaString} filename * @returns {number} */ const luaL_loadfile = function(L, filename) { @@ -1172,7 +1173,7 @@ const luaL_loadfile = function(L, filename) { /** * @param {lua_State} L - * @param {Uint8Array} filename + * @param {LuaString} filename * @returns {number} */ const luaL_dofile = function(L, filename) { diff --git a/src/loadlib.js b/src/loadlib.js index 92bf677..58ea283 100644 --- a/src/loadlib.js +++ b/src/loadlib.js @@ -70,7 +70,6 @@ const { to_luastring, to_uristring } = require("./fengaricore.js"); -const fengari = require('./fengari.js'); const global_env = (function() { if (typeof process !== "undefined") { @@ -143,7 +142,7 @@ if (typeof process === "undefined") { lua_pushstring(L, to_luastring(`${e.name}: ${e.message}`)); return null; } - let res = func(fengari); + let res = func(require('./fengari.js')); if (typeof res === "function" || (typeof res === "object" && res !== null)) { return res; } else if (res === void 0) { /* assume library added symbols to global environment */ diff --git a/src/loslib.js b/src/loslib.js index 9dbaf1d..da05bcd 100644 --- a/src/loslib.js +++ b/src/loslib.js @@ -1,5 +1,9 @@ "use strict"; +/** + * @typedef {import('./defs').LuaString} LuaString + */ + const { LUA_TNIL, LUA_TTABLE, @@ -509,7 +513,7 @@ if (typeof process === "undefined") { }; syslib.getenv = function(L) { - /** @type {string|Uint8Array} */ + /** @type {string|LuaString} */ let key = luaL_checkstring(L, 1); key = to_jsstring(key); /* https://github.com/nodejs/node/issues/16961 */ if (Object.prototype.hasOwnProperty.call(process.env, key)) { @@ -567,7 +571,7 @@ if (typeof process === "undefined") { }; syslib.execute = function(L) { - /** @type {string|Uint8Array} */ + /** @type {string|LuaString} */ let cmd = luaL_optstring(L, 1, null); if (cmd !== null) { cmd = to_jsstring(cmd); diff --git a/src/lstring.js b/src/lstring.js index eeb883f..750f660 100644 --- a/src/lstring.js +++ b/src/lstring.js @@ -10,6 +10,7 @@ const { lua_assert } = require("./llimits.js"); /** * @typedef {import('./lstate').lua_State} lua_State + * @typedef {import('./defs').LuaString} LuaString */ class TString { @@ -67,7 +68,7 @@ const luaS_bless = function(L, str) { /* makes a copy */ /** * @param {lua_State} L - * @param {Uint8Array} str + * @param {LuaString} str * @returns {TString} */ const luaS_new = function(L, str) { diff --git a/src/lstrlib.js b/src/lstrlib.js index fe59a20..5e056bd 100644 --- a/src/lstrlib.js +++ b/src/lstrlib.js @@ -2,6 +2,10 @@ const { sprintf } = require('sprintf-js'); +/** + * @typedef {import('./defs').LuaString} LuaString + */ + const { LUA_INTEGER_FMT, LUA_INTEGER_FRMLEN, @@ -1389,10 +1393,10 @@ const add_value = function(ms, b, s, e, tr) { }; const str_gsub = function(L) { - /** @type {any|Uint8Array} */ + /** @type {any|LuaString} */ let src = luaL_checkstring(L, 1); /* subject */ let srcl = src.length; - /** @type {number|Uint8Array} */ + /** @type {number|LuaString} */ let p = luaL_checkstring(L, 2); /* pattern */ let lp = p.length; let lastmatch = null; /* end of last match */ From a6476ff677efc478c83b2d2cc9ab835bae18583f Mon Sep 17 00:00:00 2001 From: gudzpoz <gudzpoz@live.com> Date: Fri, 28 Apr 2023 12:00:30 +0800 Subject: [PATCH 14/14] Ask tsc to merge all d.ts files into one --- src/fengari.js | 4 +--- src/fengaricore.js | 36 +++++++++++++++++++----------------- src/lua.js | 4 +--- src/lualib.js | 3 +-- tsconfig.json | 2 +- 5 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/fengari.js b/src/fengari.js index 267ed00..32a8a63 100644 --- a/src/fengari.js +++ b/src/fengari.js @@ -10,7 +10,7 @@ Copyright © 1994–2017 Lua.org, PUC-Rio. const core = require("./fengaricore.js"); -const exported = { +module.exports = { FENGARI_AUTHORS: core.FENGARI_AUTHORS, FENGARI_COPYRIGHT: core.FENGARI_COPYRIGHT, FENGARI_RELEASE: core.FENGARI_RELEASE, @@ -32,5 +32,3 @@ const exported = { lauxlib: require('./lauxlib.js'), lualib: require('./lualib.js'), }; - -module.exports = exported; diff --git a/src/fengaricore.js b/src/fengaricore.js index b253e9a..854ece0 100644 --- a/src/fengaricore.js +++ b/src/fengaricore.js @@ -17,20 +17,22 @@ const FENGARI_RELEASE = FENGARI_VERSION + "." + FENGARI_VERSION_RELEASE; const FENGARI_AUTHORS = "B. Giannangeli, Daurnimator"; const FENGARI_COPYRIGHT = FENGARI_RELEASE + " Copyright (C) 2017-2019 " + FENGARI_AUTHORS + "\nBased on: " + defs.LUA_COPYRIGHT; -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.is_luastring = defs.is_luastring; -module.exports.luastring_eq = defs.luastring_eq; -module.exports.luastring_from = defs.luastring_from; -module.exports.luastring_indexOf = defs.luastring_indexOf; -module.exports.luastring_of = defs.luastring_of; -module.exports.to_jsstring = defs.to_jsstring; -module.exports.to_luastring = defs.to_luastring; -module.exports.to_uristring = defs.to_uristring; -module.exports.from_userstring = defs.from_userstring; +module.exports = { + FENGARI_AUTHORS: FENGARI_AUTHORS, + FENGARI_COPYRIGHT: FENGARI_COPYRIGHT, + FENGARI_RELEASE: FENGARI_RELEASE, + FENGARI_VERSION: FENGARI_VERSION, + FENGARI_VERSION_MAJOR: FENGARI_VERSION_MAJOR, + FENGARI_VERSION_MINOR: FENGARI_VERSION_MINOR, + FENGARI_VERSION_NUM: FENGARI_VERSION_NUM, + FENGARI_VERSION_RELEASE: FENGARI_VERSION_RELEASE, + is_luastring: defs.is_luastring, + luastring_eq: defs.luastring_eq, + luastring_from: defs.luastring_from, + luastring_indexOf: defs.luastring_indexOf, + luastring_of: defs.luastring_of, + to_jsstring: defs.to_jsstring, + to_luastring: defs.to_luastring, + to_uristring: defs.to_uristring, + from_userstring: defs.from_userstring +}; diff --git a/src/lua.js b/src/lua.js index 635d6d9..aff83d3 100644 --- a/src/lua.js +++ b/src/lua.js @@ -6,7 +6,7 @@ const ldebug = require("./ldebug.js"); const ldo = require("./ldo.js"); const lstate = require("./lstate.js"); -const exported = { +module.exports = { LUA_AUTHORS: defs.LUA_AUTHORS, LUA_COPYRIGHT: defs.LUA_COPYRIGHT, LUA_ERRERR: defs.thread_status.LUA_ERRERR, @@ -191,5 +191,3 @@ const exported = { lua_yieldk: ldo.lua_yieldk, lua_tocfunction: lapi.lua_tocfunction, }; - -module.exports = exported; diff --git a/src/lualib.js b/src/lualib.js index ca5abb6..47170aa 100644 --- a/src/lualib.js +++ b/src/lualib.js @@ -73,6 +73,5 @@ module.exports.LUA_FENGARILIBNAME = LUA_FENGARILIBNAME; /** @type {(L: lua_State) => number} */ module.exports.luaopen_fengari = require("./fengarilib.js").luaopen_fengari; -const linit = require('./linit.js'); /** @type {(L: lua_State) => void} */ -module.exports.luaL_openlibs = linit.luaL_openlibs; +module.exports.luaL_openlibs = require('./linit.js').luaL_openlibs; diff --git a/tsconfig.json b/tsconfig.json index f7d9569..3eb2ead 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "allowJs": true, "declaration": true, "emitDeclarationOnly": true, - "outDir": "dist", + "outFile": "dist/fengari.js", "declarationMap": true, "checkJs": true, "lib": ["DOM", "WebWorker", "ES2015"],