Mercurial Hosting > luan
annotate core/src/luan/impl/Closure.java @ 659:f1150518c467
remove tail recursion
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 05 Apr 2016 20:30:42 -0600 |
parents | cdc70de628b5 |
children | b438a47196bc |
rev | line source |
---|---|
166
4eaee12f6c65
move luan/interp to impl
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
132
diff
changeset
|
1 package luan.impl; |
21
c93d8c781853
add functions
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
2 |
111
2428ecfed375
change LuanFunction.call() from returning Object[] to returning Object, to reduce garbage collection
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
86
diff
changeset
|
3 import luan.Luan; |
48
64ecb7a3aad7
rename Lua to Luan
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
40
diff
changeset
|
4 import luan.LuanFunction; |
64ecb7a3aad7
rename Lua to Luan
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
40
diff
changeset
|
5 import luan.LuanState; |
64ecb7a3aad7
rename Lua to Luan
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
40
diff
changeset
|
6 import luan.LuanException; |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
49
diff
changeset
|
7 import luan.DeepCloner; |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
49
diff
changeset
|
8 import luan.DeepCloneable; |
21
c93d8c781853
add functions
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
9 |
c93d8c781853
add functions
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
10 |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
301
diff
changeset
|
11 final class Closure extends LuanFunction implements DeepCloneable { |
301
a6bf8ff720f8
add java security
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
208
diff
changeset
|
12 final FnDef fnDef; |
78
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
13 private UpValue[] upValues; |
21
c93d8c781853
add functions
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
14 |
208
5ba136769034
remove MetatableGetter and use a generic metatable instead
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
195
diff
changeset
|
15 Closure(LuanStateImpl luan,FnDef fnDef) throws LuanException { |
86
6db8f286fa6c
_ENV is per module, not global
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
78
diff
changeset
|
16 this.fnDef = fnDef; |
6db8f286fa6c
_ENV is per module, not global
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
78
diff
changeset
|
17 UpValue.Getter[] upValueGetters = fnDef.upValueGetters; |
195
24ede40ee0aa
make MetatableGetter DeepCloneable, scoped, and secure
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
171
diff
changeset
|
18 this.upValues = new UpValue[upValueGetters.length]; |
86
6db8f286fa6c
_ENV is per module, not global
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
78
diff
changeset
|
19 for( int i=0; i<upValues.length; i++ ) { |
6db8f286fa6c
_ENV is per module, not global
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
78
diff
changeset
|
20 upValues[i] = upValueGetters[i].get(luan); |
32
c3eab5a3ce3c
implement closures
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
31
diff
changeset
|
21 } |
21
c93d8c781853
add functions
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
22 } |
c93d8c781853
add functions
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
23 |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
49
diff
changeset
|
24 private Closure(Closure c) { |
86
6db8f286fa6c
_ENV is per module, not global
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
78
diff
changeset
|
25 this.fnDef = c.fnDef; |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
49
diff
changeset
|
26 } |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
49
diff
changeset
|
27 |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
49
diff
changeset
|
28 @Override public Closure shallowClone() { |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
49
diff
changeset
|
29 return new Closure(this); |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
49
diff
changeset
|
30 } |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
49
diff
changeset
|
31 |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
301
diff
changeset
|
32 @Override public void deepenClone(DeepCloneable clone,DeepCloner cloner) { |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
301
diff
changeset
|
33 ((Closure)clone).upValues = (UpValue[])cloner.deepClone(upValues); |
78
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
34 } |
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
35 |
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
36 UpValue[] upValues() { |
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
37 return upValues; |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
49
diff
changeset
|
38 } |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
49
diff
changeset
|
39 |
111
2428ecfed375
change LuanFunction.call() from returning Object[] to returning Object, to reduce garbage collection
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
86
diff
changeset
|
40 @Override public Object call(LuanState luan,Object[] args) throws LuanException { |
592
1c64b1fd882b
handle StackOverflowError
Franklin Schmidt <fschmidt@gmail.com>
parents:
433
diff
changeset
|
41 try { |
1c64b1fd882b
handle StackOverflowError
Franklin Schmidt <fschmidt@gmail.com>
parents:
433
diff
changeset
|
42 return call(this,(LuanStateImpl)luan,args); |
1c64b1fd882b
handle StackOverflowError
Franklin Schmidt <fschmidt@gmail.com>
parents:
433
diff
changeset
|
43 } catch(StackOverflowError e) { |
646
cdc70de628b5
simplify LuanException
Franklin Schmidt <fschmidt@gmail.com>
parents:
645
diff
changeset
|
44 throw new LuanException( "stack overflow", e ); |
592
1c64b1fd882b
handle StackOverflowError
Franklin Schmidt <fschmidt@gmail.com>
parents:
433
diff
changeset
|
45 } |
32
c3eab5a3ce3c
implement closures
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
31
diff
changeset
|
46 } |
c3eab5a3ce3c
implement closures
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
31
diff
changeset
|
47 |
111
2428ecfed375
change LuanFunction.call() from returning Object[] to returning Object, to reduce garbage collection
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
86
diff
changeset
|
48 private static Object call(Closure closure,LuanStateImpl luan,Object[] args) throws LuanException { |
659
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
49 FnDef fnDef = closure.fnDef; |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
50 Object[] varArgs = null; |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
51 if( fnDef.isVarArg ) { |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
52 if( args.length > fnDef.numArgs ) { |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
53 varArgs = new Object[ args.length - fnDef.numArgs ]; |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
54 for( int i=0; i<varArgs.length; i++ ) { |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
55 varArgs[i] = args[fnDef.numArgs+i]; |
24
7ee247560db5
add VarArgs
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
22
diff
changeset
|
56 } |
659
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
57 } else { |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
58 varArgs = LuanFunction.NOTHING; |
24
7ee247560db5
add VarArgs
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
22
diff
changeset
|
59 } |
659
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
60 } |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
61 Object[] stack = luan.newFrame(closure,fnDef.stackSize,varArgs); |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
62 final int n = Math.min(args.length,fnDef.numArgs); |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
63 for( int i=0; i<n; i++ ) { |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
64 stack[i] = args[i]; |
21
c93d8c781853
add functions
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
65 } |
659
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
66 Object returnValues; |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
67 try { |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
68 fnDef.block.eval(luan); |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
69 } catch(ReturnException e) { |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
70 } finally { |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
71 returnValues = luan.returnValues; |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
72 luan.popFrame(); |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
73 } |
f1150518c467
remove tail recursion
Franklin Schmidt <fschmidt@gmail.com>
parents:
646
diff
changeset
|
74 return returnValues; |
21
c93d8c781853
add functions
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
75 } |
c93d8c781853
add functions
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
76 |
c93d8c781853
add functions
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
77 } |