[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Stack state before running a script
- From: Benoit Giannangeli <giann008@...>
- Date: Tue, 7 Feb 2017 10:25:52 +0100
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