bytecode reference updates

gccjit-ravi534
Dibyendu Majumdar 7 years ago
parent fcb8ce93cd
commit 76e897ed20

@ -1376,8 +1376,8 @@ Syntax
Description
-----------
Creates an instance (or closure) of a function inside the parent function. The ``Bx`` parameter
identifies the entry in the parent function Prototype's table of closure prototypes (the field ``p``
Creates an instance (or closure) of a function prototype. The ``Bx`` parameter
identifies the entry in the parent function's table of closure prototypes (the field ``p``
in the struct ``Proto``). The indices start from 0, i.e., a parameter of Bx = 0 references the first
closure prototype in the table.
@ -1439,10 +1439,118 @@ named ``_ENV``::
The first ``0`` is the index of the upvalue in the main chunk. The ``1``
following the name is a boolean indicating that the upvalue is located on the
stack, and the last ``0`` is identifies the register location on the stack.
So the Lua Parser has setup the ``upvalue`` reference for ``_ENV``. We will come back
to the handling of ``_ENV``.
So the Lua Parser has setup the ``upvalue`` reference for ``_ENV``. However
note that there is no actual local in this case; the ``_ENV`` upvalue is
special and is setup by the Lua `lua_load() <http://www.lua.org/source/5.3/lapi.c.html#lua_load>`_
API function.
Now let's look at an example that creates a local up-value::
f=load('local u,v; function p() return v end')
We get following bytecodes::
main <(string):0,0> (4 instructions at 0000022149BBA3B0)
0+ params, 3 slots, 1 upvalue, 2 locals, 1 constant, 1 function
1 [1] LOADNIL 0 1
2 [1] CLOSURE 2 0 ; 0000022149BBB7B0
3 [1] SETTABUP 0 -1 2 ; _ENV "p"
4 [1] RETURN 0 1
constants (1) for 0000022149BBA3B0:
1 "p"
locals (2) for 0000022149BBA3B0:
0 u 2 5
1 v 2 5
upvalues (1) for 0000022149BBA3B0:
0 _ENV 1 0
function <(string):1,1> (3 instructions at 0000022149BBB7B0)
0 params, 2 slots, 1 upvalue, 0 locals, 0 constants, 0 functions
1 [1] GETUPVAL 0 0 ; v
2 [1] RETURN 0 2
3 [1] RETURN 0 1
constants (0) for 0000022149BBB7B0:
locals (0) for 0000022149BBB7B0:
upvalues (1) for 0000022149BBB7B0:
0 v 1 1
In the function 'p', which we see that the upvalue list contains::
upvalues (1) for 0000022149BBB7B0:
0 v 1 1
This says that the up-value is in the stack (first '1') and is located at register '1' of
the parent function. Access to this upvalue is indirectly obtained via the ``GETUPVAL``
instruction on line 1.
Now, lets look at what happens when the upvalue is not directly within the parent
function::
f=load('local u,v; function p() u=1; local function q() return v end end')
In this example, we have 1 upvalue reference in function 'p', which is 'u'. Function 'q' has
one upvalue reference 'v'. Let's see the resulting bytecodes::
main <(string):0,0> (4 instructions at 0000022149BBFE40)
0+ params, 3 slots, 1 upvalue, 2 locals, 1 constant, 1 function
1 [1] LOADNIL 0 1
2 [1] CLOSURE 2 0 ; 0000022149BBFC60
3 [1] SETTABUP 0 -1 2 ; _ENV "p"
4 [1] RETURN 0 1
constants (1) for 0000022149BBFE40:
1 "p"
locals (2) for 0000022149BBFE40:
0 u 2 5
1 v 2 5
upvalues (1) for 0000022149BBFE40:
0 _ENV 1 0
function <(string):1,1> (4 instructions at 0000022149BBFC60)
0 params, 2 slots, 2 upvalues, 1 local, 1 constant, 1 function
1 [1] LOADK 0 -1 ; 1
2 [1] SETUPVAL 0 0 ; u
3 [1] CLOSURE 0 0 ; 0000022149BC06B0
4 [1] RETURN 0 1
constants (1) for 0000022149BBFC60:
1 1
locals (1) for 0000022149BBFC60:
0 q 4 5
upvalues (2) for 0000022149BBFC60:
0 u 1 0
1 v 1 1
function <(string):1,1> (3 instructions at 0000022149BC06B0)
0 params, 2 slots, 1 upvalue, 0 locals, 0 constants, 0 functions
1 [1] GETUPVAL 0 0 ; v
2 [1] RETURN 0 2
3 [1] RETURN 0 1
constants (0) for 0000022149BC06B0:
locals (0) for 0000022149BC06B0:
upvalues (1) for 0000022149BC06B0:
0 v 0 1
We see that 'p' got the upvalues 'u' as expected, but it also got the
upvalue 'v', and both are marked as 'instack' of the parent function::
upvalues (2) for 0000022149BBFC60:
0 u 1 0
1 v 1 1
The reason for this is that any upvalue references in the inmost nested
function will also appear in the parent functions up the chain until the
function whose stack contains the variable being referenced. So although the
function 'p' does not directly reference 'v', but because its child function
'q' references 'v', 'p' gets the upvalue reference to 'v' as well.
Observe the upvalue list of 'q' now::
upvalues (1) for 0000022149BC06B0:
0 v 0 1
'q' has one upvalue reference as expected, but this time the upvalue is
not marked 'instack', so it means that the reference is to an upvalue in
parent function (in this case 'p') and the upvalue index is '1' (the
second upvalue in 'p').
OP_GETUPVAL and OP_SETUPVAL instructions
========================================

Loading…
Cancel
Save