[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Lua return
- From: "Leandro Candido" <enclle@...>
- Date: Thu, 23 Oct 2003 00:31:52 -0200
----- Original Message -----
From: "Luiz Henrique de Figueiredo" <lhf@tecgraf.puc-rio.br>
To: <lua@bazar2.conectiva.com.br>
Sent: Wednesday, October 22, 2003 8:14 AM
Subject: Re: Lua return
...
> It's normal (and harmless). The code generator always generate a RETURN
> instruction at the end of functions. See close_func in lparser.c.
>
> It's not simple to avoid such duplication. It's not a simple matter of
just
> checking whether the last instruction is already a RETURN, because of the
> example below, where we need both RETURNs. In other words, it's not a
matter
> of peep-hole optimization. Since the extra RETURN is harmless and the cost
is
> a single instruction, the flow analysis required to remove it is not worth
it.
>
> --lhf
>
> function f()
> if a then
> return 2
> end
> end
>
> function </tmp/i:1> (6 instructions, 24 bytes at 0x805b6d8)
> 0 params, 2 stacks, 0 upvalues, 0 locals, 2 constants, 0 functions
> 1 [2] GETGLOBAL 0 0 ; a
> 2 [2] TEST 0 0 0
> 3 [2] JMP 0 2 ; to 6
> 4 [3] LOADK 0 1 ; 2
> 5 [3] RETURN 0 2 0
> 6 [5] RETURN 0 1 0
Ok,
I understand now why you use this, but can you or Roberto explain how is
the "calling" convention and what's the params to RETURN (010,020)?
Well, Why you guys don't make this?:
When encounter a return (in source code), do:
PUSH the values to the stack,
PUSH the number of values to return,
JUMP to the end of function, if necessary (if it's already at end),
where is the RETURN inst. The above will be something like:
1 GETGLOBAL 0 0 ; a
2 TEST 0 0 0
3 JMP 0 2; to 6
4 LOADK 0 1; 2
5 PUSHNUMOFVARSTORET 1
6 RETURN
Another example:
function multreturn( avar )
if avar == 1 then
return 1
elseif avar == 2 then
return 1,2
elseif avar == 3 then
return 1,2,3
end
end
--print(multreturn(3))
Output of luac -p -l:
...
function <variosrets.lua:1> (18 instructions, 72 bytes at 00882318)
1 param, 4 stacks, 0 upvalues, 1 local, 3 constants, 0 functions
1 [2] EQ 0 0 250 ; - 1
2 [2] JMP 0 3 ; to 6
3 [3] LOADK 1 0 ; 1
4 [3] RETURN 1 2 0 --> PUSHNUMOFVARSTORET 1
5 [3] JMP 0 12 ; to 18
6 [4] EQ 0 0 251 ; - 2
7 [4] JMP 0 4 ; to 12
8 [5] LOADK 1 0 ; 1
9 [5] LOADK 2 1 ; 2
10 [5] RETURN 1 3 0 --> PUSHNUMOFVARSTORET 2
11 [5] JMP 0 6 ; to 18
12 [6] EQ 0 0 252 ; - 3
13 [6] JMP 0 4 ; to 18
14 [7] LOADK 1 0 ; 1
15 [7] LOADK 2 1 ; 2
16 [7] LOADK 3 2 ; 3
17 [7] RETURN 1 4 0 --> PUSHNUMOFVARSTORET 3
18 [9] RETURN 0 1 0
constants (3) for 00882318:
0 1
1 2
2 3
locals (1) for 00882318:
0 avar 0 17
upvalues (0) for 00882318:
...
My version is after -->, it's like yours, the difference is that has only a
RETURN, and it will be always on end.
The God's Peace,
Leandro.