From 9d6afeba223c22163928557c69a102877223d3bd Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 15 Feb 2017 22:13:01 +0100 Subject: Everything need to make luaL_newstate work, lua_pushnil test --- src/lstate.js | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 13 deletions(-) (limited to 'src/lstate.js') 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 -- cgit v1.2.3-54-g00ecf