Mercurial Hosting > luan
comparison core/src/luan/impl/Closure.java @ 667:08966099aa6d
implement Closure directly
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 08 Apr 2016 07:00:17 -0600 |
parents | 71f8f5075df8 |
children | 7780cafca27f |
comparison
equal
deleted
inserted
replaced
666:2f449ccf54d2 | 667:08966099aa6d |
---|---|
6 import luan.LuanException; | 6 import luan.LuanException; |
7 import luan.DeepCloner; | 7 import luan.DeepCloner; |
8 import luan.DeepCloneable; | 8 import luan.DeepCloneable; |
9 | 9 |
10 | 10 |
11 final class Closure extends LuanFunction implements DeepCloneable { | 11 public abstract class Closure extends LuanFunction implements DeepCloneable, Cloneable { |
12 final FnDef fnDef; | 12 private final int stackSize; |
13 private final int numArgs; | |
14 private final boolean isVarArg; | |
13 private UpValue[] upValues; | 15 private UpValue[] upValues; |
14 | 16 |
15 Closure(LuanStateImpl luan,FnDef fnDef) throws LuanException { | 17 public Closure(LuanStateImpl luan,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) throws LuanException { |
16 this.fnDef = fnDef; | 18 this.stackSize = stackSize; |
17 UpValue.Getter[] upValueGetters = fnDef.upValueGetters; | 19 this.numArgs = numArgs; |
20 this.isVarArg = isVarArg; | |
18 this.upValues = new UpValue[upValueGetters.length]; | 21 this.upValues = new UpValue[upValueGetters.length]; |
19 for( int i=0; i<upValues.length; i++ ) { | 22 for( int i=0; i<upValues.length; i++ ) { |
20 upValues[i] = upValueGetters[i].get(luan); | 23 upValues[i] = upValueGetters[i].get(luan); |
21 } | 24 } |
22 } | 25 } |
23 | 26 |
24 private Closure(Closure c) { | |
25 this.fnDef = c.fnDef; | |
26 } | |
27 | |
28 @Override public Closure shallowClone() { | 27 @Override public Closure shallowClone() { |
29 return new Closure(this); | 28 try { |
29 return (Closure)clone(); | |
30 } catch(CloneNotSupportedException e) { | |
31 throw new RuntimeException(e); | |
32 } | |
30 } | 33 } |
31 | 34 |
32 @Override public void deepenClone(DeepCloneable clone,DeepCloner cloner) { | 35 @Override public void deepenClone(DeepCloneable clone,DeepCloner cloner) { |
33 ((Closure)clone).upValues = (UpValue[])cloner.deepClone(upValues); | 36 ((Closure)clone).upValues = (UpValue[])cloner.deepClone(upValues); |
34 } | 37 } |
38 } | 41 } |
39 | 42 |
40 @Override public Object call(LuanState ls,Object[] args) throws LuanException { | 43 @Override public Object call(LuanState ls,Object[] args) throws LuanException { |
41 LuanStateImpl luan = (LuanStateImpl)ls; | 44 LuanStateImpl luan = (LuanStateImpl)ls; |
42 Object[] varArgs = null; | 45 Object[] varArgs = null; |
43 if( fnDef.isVarArg ) { | 46 if( isVarArg ) { |
44 if( args.length > fnDef.numArgs ) { | 47 if( args.length > numArgs ) { |
45 varArgs = new Object[ args.length - fnDef.numArgs ]; | 48 varArgs = new Object[ args.length - numArgs ]; |
46 for( int i=0; i<varArgs.length; i++ ) { | 49 for( int i=0; i<varArgs.length; i++ ) { |
47 varArgs[i] = args[fnDef.numArgs+i]; | 50 varArgs[i] = args[numArgs+i]; |
48 } | 51 } |
49 } else { | 52 } else { |
50 varArgs = LuanFunction.NOTHING; | 53 varArgs = LuanFunction.NOTHING; |
51 } | 54 } |
52 } | 55 } |
53 Object[] stack = luan.newFrame(this,fnDef.stackSize,varArgs); | 56 Object[] stack = luan.newFrame(this,stackSize,varArgs); |
54 final int n = Math.min(args.length,fnDef.numArgs); | 57 final int n = Math.min(args.length,numArgs); |
55 for( int i=0; i<n; i++ ) { | 58 for( int i=0; i<n; i++ ) { |
56 stack[i] = args[i]; | 59 stack[i] = args[i]; |
57 } | 60 } |
58 Object returnValues; | 61 Object returnValues; |
59 try { | 62 try { |
60 return fnDef.run(luan); | 63 return run(luan); |
61 } catch(StackOverflowError e) { | 64 } catch(StackOverflowError e) { |
62 throw new LuanException( "stack overflow", e ); | 65 throw new LuanException( "stack overflow", e ); |
63 } finally { | 66 } finally { |
64 luan.popFrame(); | 67 luan.popFrame(); |
65 } | 68 } |
66 } | 69 } |
67 | 70 |
71 public abstract Object run(LuanStateImpl luan) throws LuanException; | |
68 } | 72 } |