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 }