lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


If JS doesn't have destructors, finalizers, RAII, or any other such built-in language feature for the clean up of objects, then I guess you can just add explicit "release" methods to your JS representation of a lua object?
Which would call `luaL_unref`, and tell lua that it is now okay to garbage collect that object. I mean presumably this is idiomatic in JS as you also will have to call "close" explicitly on file handles and such?

Don't have much knowledge of JS myself but I never encountered a problem like this before -- I guess it should be workable somehow? JS is a very mature technology, and iiuc you'd have the same issue making
bindings to any other garbage collected programming language.

On Tue, Feb 7, 2017 at 4:59 PM, Benoit Giannangeli <giann008@gmail.com> wrote:

This approach has already been attempted by daurnimator with lua.vm.js
(https://github.com/daurnimator/lua.vm.js). The issue is that any object
exposed from lua to js can never be released because there's no way to
know when js will no longer need the object. So it's not really a viable
solution. In other word, lua's gc gets in the way.

But I'm also simply doing this for my personal enlightenment. This is a
good way to learn the internals of the Lua VM and to gain a more
complete knowledge of the language itself.


On Tue, Feb 07, 2017 at 04:49:33PM -0500, chris beck wrote:
> >  I'm currently writing a Lua VM in JS.
>
> Out of curiosity, why are you doing this?
>
> You could also cross-compile the official lua sources to JS using
> emscripten -- this is not difficult and runs very well in my experience.
>
> Curious what use-cases aren't covered by that approach.
>
> Best Regards,
> Chris
>
> On Tue, Feb 7, 2017 at 4:25 AM, Benoit Giannangeli <giann008@gmail.com>
> wrote:
>
> > Hello,
> >
> > I'm currently writing a Lua VM in JS.
> > I'm trying to be as close as possible to Lua's source so that it will
> > make sense to those familiar with it and that it is easier for me to
> > write.
> >
> > I'm trying to figure out what is the state of the stack just before the
> > user script is executed.
> >
> > Until now I always found L->top to be at L->stack+5 at the start. So
> > when I was debugging to compare my VM to Lua's, I just corrected Lua's
> > top with -5.
> >
> > But know I'm seeing something else with the following script (its goal
> > is to test GETUPVAL and SETUPVAL):
> >
> > local a = 1
> >
> > local f = function ()
> >     a = a + 1
> >     return a
> > end
> >
> > f()
> >
> > return a
> >
> > The following code is generated:
> >
> > main <hello.lua:0,0> (6 instructions at 0x14fea20)
> > 0+ params, 3 slots, 1 upvalue, 2 locals, 1 constant, 1 function
> >      1       [1]     LOADK           0 -1    ; 1
> >      2       [6]     CLOSURE         1 0     ; 0x14fedf0
> >      3       [8]     MOVE            2 1
> >      4       [8]     CALL            2 1 1
> >      5       [10]    RETURN          0 2
> >      6       [10]    RETURN          0 1
> >
> > function <hello.lua:3,6> (6 instructions at 0x14fedf0)
> > 0 params, 2 slots, 1 upvalue, 0 locals, 1 constant, 0 functions
> >      1       [4]     GETUPVAL        0 0     ; a
> >      2       [4]     ADD             0 0 -1  ; - 1
> >      3       [4]     SETUPVAL        0 0     ; a
> >      4       [5]     GETUPVAL        0 0     ; a
> >      5       [5]     RETURN          0 2
> >      6       [6]     RETURN          0 1
> >
> >
> > I printed out L->top - L->stack - 5 before each vmdispatch:
> >
> > Before LOADK L->top is 4
> > Before CLOSURE L->top is 4
> > Before MOVE L->top is 4
> > Before CALL L->top is 4
> > Before GETUPVAL L->top is 6
> > Before ADD L->top is 6
> > Before SETUPVAL L->top is 6
> > Before GETUPVAL L->top is 6
> > Before RETURN L->top is 6
> > Before RETURN L->top is 4
> >
> > I figured I was wrong about those 5 elements on the stack, and that
> > it had to vary depending on the script which was executed.
> > But here's what's the top of the stack is in my VM:
> >
> > Before OP_LOADK L.top is 1
> > Before OP_CLOSURE L.top is 1
> > Before OP_MOVE L.top is 1
> > Before OP_CALL L.top is 1
> > Before OP_GETUPVAL L.top is 6
> > Before OP_ADD L.top is 6
> > Before OP_SETUPVAL L.top is 6
> > Before OP_GETUPVAL L.top is 6
> > Before OP_RETURN L.top is 6
> > Before OP_RETURN L.top is 1
> >
> > OP_CALL is setting my top to 6: R(A)+b (lvm.c:1134) and then poscall is
> > adding 2 to that which gives me 6.
> > So the bytecode seems to imply that the top has 3 more elements on the
> > stack after those 5 I always have.
> >
> > I tried looking at those 4 elements:
> >
> > (gdb) p ((TValue *)L->top).value_
> > $24 = {gc = 0x64a940, p = 0x64a940, b = 6596928, f = 0x64a940, i =
> > 6596928, n = 3.2593154928882029e-317}
> > (gdb) p ((TValue *)L->top-1).value_
> > $25 = {gc = 0x426e9b <b_rshift>, p = 0x426e9b <b_rshift>, b = 4353691, f
> > = 0x426e9b <b_rshift>, i = 4353691, n = 2.1510091557082225e-317}
> > (gdb) p ((TValue *)L->top-2).value_
> > $26 = {gc = 0x64bf20, p = 0x64bf20, b = 6602528, f = 0x64bf20, i =
> > 6602528, n = 3.2620822605049139e-317}
> > (gdb) p ((TValue *)L->top-3).value_
> > $27 = {gc = 0x0, p = 0x0, b = 0, f = 0x0, i = 0, n = 0}
> >
> > Those seem to be: 0, something, b_rshift (?!), something
> >
> > Why is b_rshift on the stack ? What are those elements.
> > What are the 5 elements that are always there ?
> >
> > Sorry for the long message.
> >
> > Regards,
> >
> > Benoit Giannangeli
> >
> >