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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }