aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ldebug.js21
-rw-r--r--src/ldo.js45
-rw-r--r--src/loadlib.js3
-rw-r--r--src/lstate.js82
-rw-r--r--src/lstrlib.js2
-rw-r--r--src/lvm.js54
6 files changed, 104 insertions, 103 deletions
diff --git a/src/ldebug.js b/src/ldebug.js
index 5b537c2..13b9da7 100644
--- a/src/ldebug.js
+++ b/src/ldebug.js
@@ -17,8 +17,13 @@ const lvm = require('./lvm.js');
const CT = defs.constant_types;
const TS = defs.thread_status;
+const currentpc = function(ci) {
+ assert(ci.callstatus & lstate.CIST_LUA);
+ return ci.l_savedpc - 1;
+};
+
const currentline = function(ci) {
- return ci.func.value.p.lineinfo ? ci.func.value.p.lineinfo[ci.pcOff-1] : -1;
+ return ci.func.value.p.lineinfo ? ci.func.value.p.lineinfo[currentpc(ci)] : -1;
};
/*
@@ -43,7 +48,7 @@ const lua_sethook = function(L, func, mask, count) {
func = null;
}
if (L.ci.callstatus & lstate.CIST_LUA)
- L.oldpc = L.ci.pcOff;
+ L.oldpc = L.ci.l_savedpc;
L.hook = func;
L.basehookcount = count;
L.hookcount = L.basehookcount;
@@ -105,7 +110,7 @@ const findlocal = function(L, ci, n) {
return findvararg(ci, -n);
else {
base = ci.l_base;
- name = lfunc.luaF_getlocalname(ci.func.value.p, n, ci.pcOff);
+ name = lfunc.luaF_getlocalname(ci.func.value.p, n, currentpc(ci));
}
} else
base = ci.funcOff + 1;
@@ -439,7 +444,7 @@ const funcnamefromcode = function(L, ci) {
let tm = 0; /* (initial value avoids warnings) */
let p = ci.func.value.p; /* calling function */
- let pc = ci.pcOff - 1; /* calling instruction index */
+ let pc = currentpc(ci); /* calling instruction index */
let i = p.code[pc]; /* calling instruction */
if (ci.callstatus & lstate.CIST_HOOKED) {
@@ -529,7 +534,7 @@ const varinfo = function(L, o) {
kind = getupvalname(L, ci, o); /* check whether 'o' is an upvalue */
let stkid = isinstack(L, ci, o);
if (!kind && stkid) /* no? try a register */
- kind = getobjname(ci.func.value.p, ci.pcOff - 1, stkid - ci.l_base);
+ kind = getobjname(ci.func.value.p, currentpc(ci), stkid - ci.l_base);
}
return kind ? lobject.luaO_pushfstring(L, defs.to_luastring(" (%s '%s')", true), kind.funcname, kind.name) : defs.to_luastring("", true);
@@ -620,14 +625,14 @@ const luaG_traceexec = function(L) {
ldo.luaD_hook(L, defs.LUA_HOOKCOUNT, -1); /* call count hook */
if (mask & defs.LUA_MASKLINE) {
let p = ci.func.value.p;
- let npc = ci.pcOff; // pcRel(ci.u.l.savedpc, p);
+ let npc = ci.l_savedpc; // pcRel(ci.u.l.savedpc, p);
let newline = p.lineinfo ? p.lineinfo[npc] : -1;
if (npc === 0 || /* call linehook when enter a new function, */
- ci.pcOff <= L.oldpc || /* when jump back (loop), or when */
+ ci.l_savedpc <= L.oldpc || /* when jump back (loop), or when */
newline !== p.lineinfo ? p.lineinfo[L.oldpc] : -1) /* enter a new line */
ldo.luaD_hook(L, defs.LUA_HOOKLINE, newline); /* call line hook */
}
- L.oldpc = ci.pcOff;
+ L.oldpc = ci.l_savedpc;
if (L.status === TS.LUA_YIELD) { /* did hook yield? */
if (counthook)
L.hookcount = 1; /* undo decrement to zero */
diff --git a/src/ldo.js b/src/ldo.js
index 23c5969..5564e27 100644
--- a/src/ldo.js
+++ b/src/ldo.js
@@ -47,30 +47,16 @@ const seterrorobj = function(L, errcode, oldtop) {
*/
const luaD_precall = function(L, off, nresults) {
let func = L.stack[off];
- let ci;
switch(func.type) {
case CT.LUA_TCCL:
case CT.LUA_TLCF: {
let f = func.type === CT.LUA_TCCL ? func.value.f : func.value;
- // next_ci
- if (L.ci.next) {
- L.ci = L.ci.next;
- ci = L.ci;
- } else {
- ci = new lstate.CallInfo(off);
- L.ci.next = ci;
- ci.previous = L.ci;
- ci.next = null;
-
- L.ci = ci;
- L.ciOff++;
- }
-
+ let ci = lstate.luaE_extendCI(L);
+ ci.funcOff = off;
ci.nresults = nresults;
ci.func = func;
- ci.funcOff = off;
ci.top = L.top + defs.LUA_MINSTACK;
ci.callstatus = 0;
if (L.hookmask & defs.LUA_MASKCALL)
@@ -98,27 +84,14 @@ const luaD_precall = function(L, off, nresults) {
base = off + 1;
}
- // next_ci
- if (L.ci.next) {
- L.ci = L.ci.next;
- ci = L.ci;
- } else {
- ci = new lstate.CallInfo(off);
- L.ci.next = ci;
- ci.previous = L.ci;
- ci.next = null;
-
- L.ci = ci;
- L.ciOff++;
- }
+ let ci = lstate.luaE_extendCI(L);
+ ci.funcOff = off;
ci.nresults = nresults;
ci.func = func;
- ci.funcOff = off;
ci.l_base = base;
- ci.top = base + fsize;
- L.top = ci.top;
- ci.l_savedpc = p.code;
- ci.pcOff = 0;
+ L.top = ci.top = base + fsize;
+ ci.l_code = p.code;
+ ci.l_savedpc = 0;
ci.callstatus = lstate.CIST_LUA;
return false;
@@ -135,12 +108,12 @@ const luaD_poscall = function(L, ci, firstResult, nres) {
if (L.hookmask & (defs.LUA_MASKRET | defs.LUA_MASKLINE)) {
if (L.hookmask & defs.LUA_MASKRET)
luaD_hook(L, defs.LUA_HOOKRET, -1);
- L.oldpc = ci.previous.pcOff; /* 'oldpc' for caller function */
+ L.oldpc = ci.previous.l_savedpc; /* 'oldpc' for caller function */
}
let res = ci.funcOff;
L.ci = ci.previous;
- L.ciOff--;
+ L.ci.next = null;
return moveresults(L, firstResult, res, nres, wanted);
};
diff --git a/src/loadlib.js b/src/loadlib.js
index c70e7f9..c43f498 100644
--- a/src/loadlib.js
+++ b/src/loadlib.js
@@ -88,12 +88,11 @@ if (!WEB) {
try {
fd = fs.openSync(lua.to_jsstring(filename), 'r');
+ fs.closeSync(fd);
} catch (e) {
return false;
}
- fs.closeSync(fd);
-
return true;
};
}
diff --git a/src/lstate.js b/src/lstate.js
index 664ef27..7d7ff80 100644
--- a/src/lstate.js
+++ b/src/lstate.js
@@ -18,24 +18,24 @@ const BASIC_STACK_SIZE = 2 * defs.LUA_MINSTACK;
class CallInfo {
- constructor(funcOff, func, top, base, previous, next) {
- this.func = func;
- this.funcOff = funcOff;
- this.top = top;
- this.previous = previous;
- this.next = next;
- this.pcOff = 0;
+ constructor() {
+ this.func = null;
+ this.funcOff = NaN;
+ this.top = NaN;
+ this.previous = null;
+ this.next = null;
/* only for Lua functions */
- this.l_base = base; /* base for this function */
- this.l_savedpc = [];
+ this.l_base = NaN; /* base for this function */
+ this.l_code = null; /* reference to this.func.p.code */
+ this.l_savedpc = NaN; /* offset into l_code */
/* only for JS functions */
this.c_k = null; /* continuation in case of yields */
this.c_old_errfunc = null;
this.c_ctx = null; /* context info. in case of yields */
- this.nresults = 0;
- this.callstatus = 0;
+ this.nresults = NaN;
+ this.callstatus = NaN;
}
}
@@ -47,7 +47,6 @@ class lua_State {
this.base_ci = new CallInfo(); // Will be populated later
this.top = 0;
this.ci = null;
- this.ciOff = null;
this.stack = [];
this.openupval = null;
this.status = TS.LUA_OK;
@@ -74,6 +73,19 @@ class global_State {
}
+const luaE_extendCI = function(L) {
+ let ci = new CallInfo();
+ L.ci.next = ci;
+ ci.previous = L.ci;
+ ci.next = null;
+ L.ci = ci;
+ return ci;
+};
+
+const luaE_freeCI = function(L) {
+ let ci = L.ci;
+ ci.next = null;
+};
const stack_init = function(L1, L) {
L1.stack = new Array(BASIC_STACK_SIZE); // TODO: for now we don't care about the stack size
@@ -88,6 +100,12 @@ const stack_init = function(L1, L) {
L1.ci = ci;
};
+const freestack = function(L) {
+ L.ci = L.base_ci;
+ luaE_freeCI(L);
+ L.stack = null;
+};
+
/*
** Create registry table and its predefined values
*/
@@ -113,9 +131,8 @@ const f_luaopen = function(L) {
const preinit_thread = function(L, g) {
L.id = g.id_counter++;
L.l_G = g;
- L.stack = [];
+ L.stack = null;
L.ci = null;
- L.nci = 0;
L.errorJmp = null;
L.nCcalls = 0;
L.hook = null;
@@ -143,6 +160,11 @@ const lua_newthread = function(L) {
return L1;
};
+const luaE_freethread = function(L, L1) {
+ lfunc.luaF_close(L1, L1.stack);
+ freestack(L1);
+};
+
const lua_newstate = function() {
let L = new lua_State();
let g = new global_State(L);
@@ -158,6 +180,7 @@ const lua_newstate = function() {
const close_state = function(L) {
lfunc.luaF_close(L, L.stack); /* close all upvalues for this thread */
+ freestack(L);
};
const lua_close = function(L) {
@@ -165,17 +188,20 @@ const lua_close = function(L) {
close_state(L);
};
-module.exports.lua_State = lua_State;
-module.exports.CallInfo = CallInfo;
-module.exports.CIST_OAH = (1<<0); /* original value of 'allowhook' */
-module.exports.CIST_LUA = (1<<1); /* call is running a Lua function */
-module.exports.CIST_HOOKED = (1<<2); /* call is running a debug hook */
-module.exports.CIST_FRESH = (1<<3); /* call is running on a fresh invocation of luaV_execute */
-module.exports.CIST_YPCALL = (1<<4); /* call is a yieldable protected call */
-module.exports.CIST_TAIL = (1<<5); /* call was tail called */
-module.exports.CIST_HOOKYIELD = (1<<6); /* last hook called yielded */
-module.exports.CIST_LEQ = (1<<7); /* using __lt for __le */
-module.exports.CIST_FIN = (1<<8); /* call is running a finalizer */
-module.exports.lua_close = lua_close;
-module.exports.lua_newstate = lua_newstate;
-module.exports.lua_newthread = lua_newthread;
+module.exports.lua_State = lua_State;
+module.exports.CallInfo = CallInfo;
+module.exports.CIST_OAH = (1<<0); /* original value of 'allowhook' */
+module.exports.CIST_LUA = (1<<1); /* call is running a Lua function */
+module.exports.CIST_HOOKED = (1<<2); /* call is running a debug hook */
+module.exports.CIST_FRESH = (1<<3); /* call is running on a fresh invocation of luaV_execute */
+module.exports.CIST_YPCALL = (1<<4); /* call is a yieldable protected call */
+module.exports.CIST_TAIL = (1<<5); /* call was tail called */
+module.exports.CIST_HOOKYIELD = (1<<6); /* last hook called yielded */
+module.exports.CIST_LEQ = (1<<7); /* using __lt for __le */
+module.exports.CIST_FIN = (1<<8); /* call is running a finalizer */
+module.exports.lua_close = lua_close;
+module.exports.lua_newstate = lua_newstate;
+module.exports.lua_newthread = lua_newthread;
+module.exports.luaE_extendCI = luaE_extendCI;
+module.exports.luaE_freeCI = luaE_freeCI;
+module.exports.luaE_freethread = luaE_freethread;
diff --git a/src/lstrlib.js b/src/lstrlib.js
index 2eb9ff5..9a75b78 100644
--- a/src/lstrlib.js
+++ b/src/lstrlib.js
@@ -449,7 +449,7 @@ const getoption = function(h, fmt) {
case 'H'.charCodeAt(0): r.size = 2; r.opt = KOption.Kuint; return r;
case 'l'.charCodeAt(0): r.size = 8; r.opt = KOption.Kint; return r; // sizeof(long): 8
case 'L'.charCodeAt(0): r.size = 8; r.opt = KOption.Kuint; return r;
- case 'j'.charCodeAt(0): r.size = 4; r.opt = KOption.Kint; return r; // sizeof(lua_Integer): 8
+ case 'j'.charCodeAt(0): r.size = 4; r.opt = KOption.Kint; return r; // sizeof(lua_Integer): 4
case 'J'.charCodeAt(0): r.size = 8; r.opt = KOption.Kuint; return r;
case 'T'.charCodeAt(0): r.size = 8; r.opt = KOption.Kuint; return r; // sizeof(size_t): 8
case 'f'.charCodeAt(0): r.size = 4; r.opt = KOption.Kfloat; return r; // sizeof(float): 4
diff --git a/src/lvm.js b/src/lvm.js
index 542dd61..6a1602c 100644
--- a/src/lvm.js
+++ b/src/lvm.js
@@ -25,7 +25,7 @@ const luaV_finishOp = function(L) {
let ci = L.ci;
let OCi = lopcodes.OpCodesI;
let base = ci.l_base;
- let inst = ci.l_savedpc[ci.pcOff - 1]; /* interrupted instruction */
+ let inst = ci.l_code[ci.l_savedpc - 1]; /* interrupted instruction */
let op = inst.opcode;
switch (op) { /* finish its execution */
@@ -45,9 +45,9 @@ const luaV_finishOp = function(L) {
ci.callstatus ^= lstate.CIST_LEQ; /* clear mark */
res = res !== 1 ? 1 : 0; /* negate result */
}
- assert(ci.l_savedpc[ci.pcOff] === OCi.OP_JMP);
+ assert(ci.l_code[ci.l_savedpc] === OCi.OP_JMP);
if (res !== inst.A) /* condition failed? */
- ci.pcOff++; /* skip jump instruction */
+ ci.l_savedpc++; /* skip jump instruction */
break;
}
case OCi.OP_CONCAT: {
@@ -66,7 +66,7 @@ const luaV_finishOp = function(L) {
break;
}
case OCi.OP_TFORCALL: {
- assert(ci.l_savedpc[ci.pcOff] === OCi.OP_TFORLOOP);
+ assert(ci.l_code[ci.l_savedpc] === OCi.OP_TFORLOOP);
L.top = ci.top; /* correct top */
break;
}
@@ -110,7 +110,7 @@ const luaV_execute = function(L) {
let k = cl.p.k;
let base = ci.l_base;
- let i = ci.l_savedpc[ci.pcOff++];
+ let i = ci.l_code[ci.l_savedpc++];
if (L.hookmask & (defs.LUA_MASKLINE | defs.LUA_MASKCOUNT)) {
ldebug.luaG_traceexec(L);
@@ -130,8 +130,8 @@ const luaV_execute = function(L) {
break;
}
case OCi.OP_LOADKX: {
- assert(ci.l_savedpc[ci.pcOff].opcode === OCi.OP_EXTRAARG);
- let konst = k[ci.l_savedpc[ci.pcOff++].Ax];
+ assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_EXTRAARG);
+ let konst = k[ci.l_code[ci.l_savedpc++].Ax];
L.stack[ra] = new lobject.TValue(konst.type, konst.value);
break;
}
@@ -139,7 +139,7 @@ const luaV_execute = function(L) {
L.stack[ra] = new lobject.TValue(CT.LUA_TBOOLEAN, i.B !== 0);
if (i.C !== 0)
- ci.pcOff++; /* skip next instruction (if C) */
+ ci.l_savedpc++; /* skip next instruction (if C) */
break;
}
@@ -420,28 +420,28 @@ const luaV_execute = function(L) {
}
case OCi.OP_EQ: {
if (luaV_equalobj(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A)
- ci.pcOff++;
+ ci.l_savedpc++;
else
donextjump(L, ci);
break;
}
case OCi.OP_LT: {
if (luaV_lessthan(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A)
- ci.pcOff++;
+ ci.l_savedpc++;
else
donextjump(L, ci);
break;
}
case OCi.OP_LE: {
if (luaV_lessequal(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A)
- ci.pcOff++;
+ ci.l_savedpc++;
else
donextjump(L, ci);
break;
}
case OCi.OP_TEST: {
if (i.C ? L.stack[ra].l_isfalse() : !L.stack[ra].l_isfalse())
- ci.pcOff++;
+ ci.l_savedpc++;
else
donextjump(L, ci);
break;
@@ -449,7 +449,7 @@ const luaV_execute = function(L) {
case OCi.OP_TESTSET: {
let rb = L.stack[RB(L, base, i)];
if (i.C ? rb.l_isfalse() : !rb.l_isfalse())
- ci.pcOff++;
+ ci.l_savedpc++;
else {
L.stack[ra] = rb;
donextjump(L, ci);
@@ -489,14 +489,12 @@ const luaV_execute = function(L) {
L.stack[ofuncOff + aux] = L.stack[nfuncOff + aux];
oci.func = nci.func;
oci.l_base = ofuncOff + (nci.l_base - nfuncOff);
- L.top = ofuncOff + (L.top - nfuncOff);
- oci.top = L.top;
+ oci.top = L.top = ofuncOff + (L.top - nfuncOff);
+ oci.l_code = nci.l_code;
oci.l_savedpc = nci.l_savedpc;
- oci.pcOff = nci.pcOff;
oci.callstatus |= lstate.CIST_TAIL;
- L.ci = oci;
- ci = L.ci;
- L.ciOff--;
+ oci.next = null;
+ ci = L.ci = oci;
assert(L.top === oci.l_base + L.stack[ofuncOff].value.p.maxstacksize);
@@ -523,7 +521,7 @@ const luaV_execute = function(L) {
let limit = L.stack[ra + 1].value;
if (0 < step ? idx <= limit : limit <= idx) {
- ci.pcOff += i.sBx;
+ ci.l_savedpc += i.sBx;
L.stack[ra].value = idx;
L.stack[ra + 3] = new lobject.TValue(CT.LUA_TNUMINT, idx); // TODO: if tvalue already there, just update it
}
@@ -534,7 +532,7 @@ const luaV_execute = function(L) {
// TODO: luai_numlt, luai_numle
if (0 < step ? idx <= limit : limit <= idx) {
- ci.pcOff += i.sBx;
+ ci.l_savedpc += i.sBx;
L.stack[ra].value = idx;
L.stack[ra + 3] = new lobject.TValue(CT.LUA_TNUMFLT, idx); // TODO: if tvalue already there, just update it
}
@@ -575,7 +573,7 @@ const luaV_execute = function(L) {
init.value = ninit - nstep;
}
- ci.pcOff += i.sBx;
+ ci.l_savedpc += i.sBx;
break;
}
case OCi.OP_TFORCALL: {
@@ -587,7 +585,7 @@ const luaV_execute = function(L) {
ldo.luaD_call(L, cb, i.C);
/* go straight to OP_TFORLOOP */
L.top = ci.top;
- i = ci.l_savedpc[ci.pcOff++];
+ i = ci.l_code[ci.l_savedpc++];
ra = RA(L, base, i);
assert(i.opcode === OCi.OP_TFORLOOP);
/* fall through */
@@ -595,7 +593,7 @@ const luaV_execute = function(L) {
case OCi.OP_TFORLOOP: {
if (!L.stack[ra + 1].ttisnil()) { /* continue loop? */
L.stack[ra] = L.stack[ra + 1]; /* save control variable */
- ci.pcOff += i.sBx; /* jump back */
+ ci.l_savedpc += i.sBx; /* jump back */
}
break;
}
@@ -606,8 +604,8 @@ const luaV_execute = function(L) {
if (n === 0) n = L.top - ra - 1;
if (c === 0) {
- assert(ci.l_savedpc[ci.pcOff].opcode === OCi.OP_EXTRAARG);
- c = ci.l_savedpc[ci.pcOff++].Ax;
+ assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_EXTRAARG);
+ c = ci.l_code[ci.l_savedpc++].Ax;
}
let h = L.stack[ra].value;
@@ -668,11 +666,11 @@ const luaV_execute = function(L) {
const dojump = function(L, ci, i, e) {
let a = i.A;
if (a !== 0) lfunc.luaF_close(L, ci.l_base + a - 1);
- ci.pcOff += i.sBx + e;
+ ci.l_savedpc += i.sBx + e;
};
const donextjump = function(L, ci) {
- dojump(L, ci, ci.l_savedpc[ci.pcOff], 1);
+ dojump(L, ci, ci.l_code[ci.l_savedpc], 1);
};