summaryrefslogtreecommitdiff
path: root/src/lstate.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/lstate.js')
-rw-r--r--src/lstate.js115
1 files changed, 102 insertions, 13 deletions
diff --git a/src/lstate.js b/src/lstate.js
index 84aefc0..4d71be7 100644
--- a/src/lstate.js
+++ b/src/lstate.js
@@ -1,10 +1,19 @@
/*jshint esversion: 6 */
"use strict";
-const lua = require('./lua.js');
-const LUA_MULTRET = lua.LUA_MULTRET;
-const TS = lua.thread_status;
-const Table = require('./lobject.js').Table;
+const lua = require('./lua.js');
+const Table = require('./lobject.js').Table;
+const ldo = require('./ldo.js');
+const lapi = require('./lapi.js');
+const nil = ldo.nil;
+const luaD_rawrunprotected = ldo.luaD_rawrunprotected;
+const luaT_init = require('./ltm.js').luaT_init;
+const CT = lua.constant_types;
+const LUA_MULTRET = lua.LUA_MULTRET;
+const TS = lua.thread_status;
+const LUA_NUMTAGS = lua.LUA_NUMTAGS;
+
+const BASIC_STACK_SIZE = 2 * lua.LUA_MINSTACK;
class CallInfo {
@@ -35,20 +44,99 @@ class CallInfo {
class lua_State {
constructor(cl) {
- this.top = 1;
- this.ci = new CallInfo(0, cl, 1, 1, null, null);
- this.ci.u.l.savedpc = cl.p.code;
- this.ci.nresults = LUA_MULTRET;
- this.ciOff = 0;
- this.stack = [
- cl
- ];
+ if (cl) { // TODO: remove
+ this.top = 1;
+ this.ci = new CallInfo(0, cl, 1, 1, null, null);
+ this.ci.u.l.savedpc = cl.p.code;
+ this.ci.nresults = LUA_MULTRET;
+ this.ciOff = 0;
+ this.stack = [
+ cl
+ ];
+ } else {
+ this.base_ci = new CallInfo(); // Will be populated later
+ this.top = 0;
+ this.ci = null;
+ this.ciOff = null;
+ this.stack = [];
+ }
this.openupval = [];
this.status = TS.LUA_OK;
+ this.next = null;
+ this.tt = CT.LUA_TTHREAD;
+ this.twups = [this];
+ this.errorJmp = null;
+ // TODO: hooks
+ this.nny = 1;
+ this.errfunc = 0;
+ }
+
+}
+
+class global_State {
+
+ constructor(L) {
+ this.mainthread = L;
+ this.strt = null // TODO: string hash table
+ this.l_registry = nil;
+ this.panic = null;
+ this.version = null;
+ this.twups = [];
+ this.mt = new Array(LUA_NUMTAGS);
}
}
+
+const stack_init = function(L1, L) {
+ L1.stack = new Array(BASIC_STACK_SIZE); // TODO: for now we don't care about the stack size
+ L1.top = 0;
+ let ci = L1.base_ci;
+ ci.next = ci.previous = null;
+ ci.callstatus = 0;
+ ci.func = L1.stack[L1.top];
+ ci.funcOff = L1.top;
+ L1.stack[L1.top++] = nil;
+ ci.top = L1.top + lua.LUA_MINSTACK;
+ L1.ci = ci;
+};
+
+/*
+** Create registry table and its predefined values
+*/
+const init_registry = function(L, g) {
+ let registry = new Table();
+ g.l_registry = registry;
+ registry.value.array[lua.LUA_RIDX_MAINTHREAD] = L;
+ registry.value.array[lua.LUA_RIDX_GLOBALS] = new Table();
+};
+
+/*
+** open parts of the state that may cause memory-allocation errors.
+** ('g->version' != NULL flags that the state was completely build)
+*/
+const f_luaopen = function(L) {
+ let g = L.l_G;
+ stack_init(L, L);
+ init_registry(L, g);
+ // TODO: luaS_init(L);
+ luaT_init(L);
+ g.version = lapi.lua_version(null);
+};
+
+const lua_newstate = function() {
+ let L = new lua_State();
+ let g = new global_State(L);
+
+ L.l_G = g;
+
+ if (luaD_rawrunprotected(L, f_luaopen, null) !== TS.LUA_OK) {
+ L = null;
+ }
+
+ return L;
+};
+
module.exports.lua_State = lua_State;
module.exports.CallInfo = CallInfo;
module.exports.CIST_OAH = (1<<0); /* original value of 'allowhook' */
@@ -59,4 +147,5 @@ 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 */ \ No newline at end of file
+module.exports.CIST_FIN = (1<<8); /* call is running a finalizer */
+module.exports.lua_newstate = lua_newstate; \ No newline at end of file