From 6482d1ddc52f26d0a8e2e2a398276db73fbaa2bf Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Thu, 23 Feb 2017 15:02:16 +0100 Subject: coroutine.running, upvalue need to be attached to their thread --- README.md | 3 ++- src/lfunc.js | 9 +++++---- src/lobject.js | 4 ++-- src/lundump.js | 2 +- src/lvm.js | 2 +- tests/lcorolib.js | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 6 files changed, 55 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 2eec1ff..50c4d7e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ - [x] nil - [x] boolean - [x] table + - [ ] weak table - [x] function - [ ] string (8-bit clean) - [ ] number (32-bit ?) @@ -226,9 +227,9 @@ - [x] coroutine.create - [x] coroutine.isyieldable - [x] coroutine.resume + - [x] coroutine.running - [x] coroutine.status - [x] coroutine.yield - - [ ] coroutine.running - [ ] coroutine.wrap - [ ] Debug (errors) - [ ] DOM API binding diff --git a/src/lfunc.js b/src/lfunc.js index 7057f2d..3b3c8ce 100644 --- a/src/lfunc.js +++ b/src/lfunc.js @@ -24,7 +24,8 @@ class Proto { class UpVal { - constructor() { + constructor(L) { + this.L = L; // Keep track of the thread it comes from this.v = null; /* if null, upval is closed, value is in u.value */ this.u = { open: { /* (when open) */ @@ -41,7 +42,7 @@ class UpVal { setval(L, ra) { if (this.v !== null) { - L.stack[this.v] = L.stack[ra]; + this.L.stack[this.v] = L.stack[ra]; this.v = ra; } else this.u.value = L.stack[ra]; } @@ -64,7 +65,7 @@ const findupval = function(L, level) { pp = p.u.open.next; } - let uv = new UpVal(); + let uv = new UpVal(L); uv.refcount = 0; uv.u.open.next = pp; uv.u.open.touched = true; @@ -92,7 +93,7 @@ const luaF_close = function(L, level) { const luaF_initupvals = function(L, cl) { for (let i = 0; i < cl.nupvalues; i++) { - let uv = new UpVal(); + let uv = new UpVal(L); uv.refcount = 1; uv.u.value = null; uv.v = uv.u.value; diff --git a/src/lobject.js b/src/lobject.js index 4e4b701..086af00 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -163,13 +163,13 @@ class Table extends TValue { class LClosure extends TValue { - constructor(n) { + constructor(L, n) { super(CT.LUA_TLCL, null); this.p = null; this.nupvalues = n; - let _ENV = new UpVal(); + let _ENV = new UpVal(L); _ENV.refcount = 0; _ENV.v = null; _ENV.u.open.next = null; diff --git a/src/lundump.js b/src/lundump.js index ab1dd6f..b79e6ea 100644 --- a/src/lundump.js +++ b/src/lundump.js @@ -293,7 +293,7 @@ class BytecodeParser { luaU_undump(L) { this.checkHeader(); - let cl = new LClosure(this.readByte()); + let cl = new LClosure(L, this.readByte()); L.stack[L.top] = cl; L.top++; diff --git a/src/lvm.js b/src/lvm.js index 5615acd..95e8cc4 100644 --- a/src/lvm.js +++ b/src/lvm.js @@ -659,7 +659,7 @@ const luaV_execute = function(L) { let p = cl.p.p[i.Bx]; let nup = p.upvalues.length; let uv = p.upvalues; - let ncl = new LClosure(nup); + let ncl = new LClosure(L, nup); ncl.p = p; L.stack[ra] = ncl; diff --git a/tests/lcorolib.js b/tests/lcorolib.js index 5f6d43d..dfecd71 100644 --- a/tests/lcorolib.js +++ b/tests/lcorolib.js @@ -14,6 +14,7 @@ const lapi = require("../src/lapi.js"); const lauxlib = require("../src/lauxlib.js"); const lua = require('../src/lua.js'); const linit = require('../src/linit.js'); +const lstate = require('../src/lstate.js'); const CT = lua.constant_types; @@ -130,15 +131,54 @@ test('coroutine.isyieldable', function (t) { }, "JS Lua program ran without error"); - t.strictEqual( + t.ok( lapi.lua_toboolean(L, -2), - true, "Correct element(s) on the stack" ); - t.strictEqual( + t.notOk( + lapi.lua_toboolean(L, -1), + "Correct element(s) on the stack" + ); +}); + + +test('coroutine.running', function (t) { + let luaCode = ` + local running, ismain + + local co = coroutine.create(function () + running, ismain = coroutine.running() + end) + + coroutine.resume(co) + + return running, ismain + `, L; + + t.plan(3); + + t.doesNotThrow(function () { + + let bc = toByteCode(luaCode).dataView; + + L = lauxlib.luaL_newstate(); + + linit.luaL_openlibs(L); + + lapi.lua_load(L, bc, "test-coroutine.running"); + + lapi.lua_call(L, 0, -1); + + }, "JS Lua program ran without error"); + + t.ok( + lapi.lua_tothread(L, -2) instanceof lstate.lua_State, + "Correct element(s) on the stack" + ); + + t.notOk( lapi.lua_toboolean(L, -1), - false, "Correct element(s) on the stack" ); }); \ No newline at end of file -- cgit v1.2.3-70-g09d2