diff options
-rw-r--r-- | src/ldo.js | 6 | ||||
-rw-r--r-- | src/lobject.js | 13 | ||||
-rw-r--r-- | src/lparser.js | 26 | ||||
-rw-r--r-- | tests/lexparse.js | 7 | ||||
-rw-r--r-- | tests/lvm.js | 2 |
5 files changed, 36 insertions, 18 deletions
@@ -549,11 +549,11 @@ const luaD_protectedparser = function(L, z, name, mode) { p.z = z; p.name = name; p.mode = mode; - p.dyd.actvar.arr = null; + p.dyd.actvar.arr = []; p.dyd.actvar.size = 0; - p.dyd.gt.arr = null; + p.dyd.gt.arr = []; p.dyd.gt.size = 0; - p.dyd.label.arr = null; + p.dyd.label.arr = []; p.dyd.label.size = 0; let status = luaD_pcall(L, f_parser, p, L.top, L.errfunc); diff --git a/src/lobject.js b/src/lobject.js index f748416..bd234a1 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -204,6 +204,18 @@ class CClosure extends TValue { } +/* +** Description of a local variable for function prototypes +** (used for debug information) +*/ +class LocVar { + constructor() { + this.varname = null; + this.startpc = NaN; /* first point where variable is active */ + this.endpc = NaN; /* first point where variable is dead */ + } +} + const RETS = "..."; const PRE = "[string \""; const POS = "\"]"; @@ -400,6 +412,7 @@ const numarith = function(L, op, v1, v2) { module.exports.CClosure = CClosure; module.exports.LClosure = LClosure; +module.exports.LocVar = LocVar; module.exports.TValue = TValue; module.exports.Table = Table; module.exports.UTF8BUFFSZ = UTF8BUFFSZ; diff --git a/src/lparser.js b/src/lparser.js index aa48f10..1e454e0 100644 --- a/src/lparser.js +++ b/src/lparser.js @@ -225,6 +225,7 @@ const checkname = function(ls, e) { const registerlocalvar = function(ls, varname) { let fs = ls.fs; let f = fs.f; + f.locvars[fs.nlocvars] = new lobject.LocVar(); f.locvars[fs.nlocvars].varname = varname; return fs.nlocvars++; }; @@ -234,7 +235,9 @@ const new_localvar = function(ls, name) { let dyd = ls.dyd; let reg = registerlocalvar(ls, name); checklimit(fs, dyd.actvar.n + 1 - fs.firstlocal, MAXVARS, "local variables"); - dyd.actvar.arr[dyd.actvar.n++].idx = reg; + dyd.actvar.arr[dyd.actvar.n] = new Vardesc(); + dyd.actvar.arr[dyd.actvar.n].idx = reg; + dyd.actvar.n++; }; const new_localvarliteral = function(ls, name) { @@ -263,7 +266,7 @@ const removevars = function(fs, tolevel) { const searchupvalue = function(fs, name) { let up = fs.f.upvalues; for (let i = 0; i < fs.nups; i++) { - if (up[i].name === name) + if (up[i].name.value === name.value) return i; } return -1; /* not found */ @@ -281,7 +284,7 @@ const newupvalue = function(fs, name, v) { const searchvar = function(fs, n) { for (let i = fs.nactvar - 1; i >= 0; i--) { - if (n === getlocvar(fs, i).varname) + if (n.value === getlocvar(fs, i).varname.value) return i; } @@ -373,10 +376,10 @@ const closegoto = function(ls, g, label) { let fs = ls.fs; let gl = ls.dyd.gt; let gt = gl.arr[g]; - assert(gt.name === label.name); + assert(gt.name.value === label.name.value); if (gt.nactvar < label.nactvar) { let vname = getlocvar(fs, gt.nactvar).varname; - semerror(ls, `<goto ${gt.name}> at line ${gt.line} jumps into the scope of local '${vname}'`); + semerror(ls, `<goto ${gt.name.value}> at line ${gt.line} jumps into the scope of local '${vname.value}'`); } lcode.luaK_patchlist(fs, gt.pc, label.pc); /* remove goto from pending list */ @@ -395,7 +398,7 @@ const findlabel = function(ls, g) { /* check labels in current block for a match */ for (let i = bl.firstlabel; i < dyd.label.n; i++) { let lb = dyd.label.arr[i]; - if (lb.name === gt.name) { /* correct label? */ + if (lb.name.value === gt.name.value) { /* correct label? */ if (gt.nactvar > lb.nactvar && (bl.upval || dyd.label.n > bl.firstlabel)) lcode.luaK_patchclose(ls.fs, gt.pc, lb.nactvar); closegoto(ls, g, lb); /* close it */ @@ -407,6 +410,7 @@ const findlabel = function(ls, g) { const newlabelentry = function(ls, l, name, line, pc) { let n = l.n; + l.arr[n] = new Labeldesc(); l.arr[n].name = name; l.arr[n].line = line; l.arr[n].nactvar = ls.fs.nactvar; @@ -423,7 +427,7 @@ const findgotos = function(ls, lb) { let gl = ls.dyd.gt; let i = ls.fs.bl.firstgoto; while (i < gl.n) { - if (gl.arr[i].name === lb.name) + if (gl.arr[i].name.value === lb.name.value) closegoto(ls, i, lb); else i++; @@ -478,9 +482,9 @@ const breaklabel = function(ls) { ** message when label name is a reserved word (which can only be 'break') */ const undefgoto = function(ls, gt) { - const msg = llex.isreserved(gt.name) - ? `<${gt.name}> at line ${gt.line} not inside a loop` - : `no visible label '${gt.name}' for <goto> at line ${gt.line}`; + const msg = llex.isreserved(gt.name.value) + ? `<${gt.name.value}> at line ${gt.line} not inside a loop` + : `no visible label '${gt.name.value}' for <goto> at line ${gt.line}`; semerror(ls, msg); }; @@ -1139,7 +1143,7 @@ const gotostat = function(ls, pc) { /* check for repeated labels on the same block */ const checkrepeated = function(fs, ll, label) { for (let i = fs.bl.firstlabel; i < ll.n; i++) { - if (label === ll.arr[i].name) { + if (label.value === ll.arr[i].name.value) { semerror(fs.ls, `label '${label}' already defined on line ${ll.arr[i].line}`); } } diff --git a/tests/lexparse.js b/tests/lexparse.js index 8320588..0d9c51d 100644 --- a/tests/lexparse.js +++ b/tests/lexparse.js @@ -11,9 +11,10 @@ const lauxlib = require("../src/lauxlib.js"); const linit = require('../src/linit.js'); -test('Hello World', function (t) { +test('LOADK, RETURN', function (t) { let luaCode = ` - return "hello world" + local a = "hello world" + return a `, L; t.plan(2); @@ -24,7 +25,7 @@ test('Hello World', function (t) { linit.luaL_openlibs(L); - lapi.lua_load(L, null, luaCode, "test-load", "text"); + lapi.lua_load(L, null, luaCode, "test", "text"); lapi.lua_call(L, 0, -1); diff --git a/tests/lvm.js b/tests/lvm.js index 5d4eae1..5b5deac 100644 --- a/tests/lvm.js +++ b/tests/lvm.js @@ -6,7 +6,7 @@ const beautify = require('js-beautify').js_beautify; const lua_State = require("../src/lstate.js").lua_State; const VM = require("../src/lvm.js"); const lapi = require("../src/lapi.js"); -const Table = require("../src/lobject.js").Table;; +const Table = require("../src/lobject.js").Table; const getState = require("./tests.js").getState; |