comparison src/luan/interp/Closure.java @ 86:6db8f286fa6c

_ENV is per module, not global git-svn-id: https://luan-java.googlecode.com/svn/trunk@87 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Wed, 27 Feb 2013 08:03:51 +0000
parents 7c08b611125d
children 2428ecfed375
comparison
equal deleted inserted replaced
85:b2551f00bc51 86:6db8f286fa6c
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<Closure> { 11 final class Closure extends LuanFunction implements DeepCloneable<Closure> {
12 private final Chunk chunk; 12 private final FnDef fnDef;
13 private UpValue[] upValues; 13 private UpValue[] upValues;
14 private final static UpValue[] NO_UP_VALUES = new UpValue[0];
15 14
16 Closure(LuanStateImpl luan,Chunk chunk) { 15 Closure(LuanStateImpl luan,FnDef fnDef) throws LuanException {
17 this.chunk = chunk; 16 this.fnDef = fnDef;
18 UpValue.Getter[] upValueGetters = chunk.upValueGetters; 17 UpValue.Getter[] upValueGetters = fnDef.upValueGetters;
19 if( upValueGetters.length==0 ) { 18 upValues = new UpValue[upValueGetters.length];
20 upValues = NO_UP_VALUES; 19 for( int i=0; i<upValues.length; i++ ) {
21 } else { 20 upValues[i] = upValueGetters[i].get(luan);
22 upValues = new UpValue[upValueGetters.length];
23 for( int i=0; i<upValues.length; i++ ) {
24 upValues[i] = upValueGetters[i].get(luan);
25 }
26 } 21 }
27 } 22 }
28 23
29 private Closure(Closure c) { 24 private Closure(Closure c) {
30 this.chunk = c.chunk; 25 this.fnDef = c.fnDef;
31 } 26 }
32 27
33 @Override public Closure shallowClone() { 28 @Override public Closure shallowClone() {
34 return new Closure(this); 29 return new Closure(this);
35 } 30 }
46 return call(this,(LuanStateImpl)luan,args); 41 return call(this,(LuanStateImpl)luan,args);
47 } 42 }
48 43
49 private static Object[] call(Closure closure,LuanStateImpl luan,Object[] args) throws LuanException { 44 private static Object[] call(Closure closure,LuanStateImpl luan,Object[] args) throws LuanException {
50 while(true) { 45 while(true) {
51 Chunk chunk = closure.chunk; 46 FnDef fnDef = closure.fnDef;
52 Object[] varArgs = null; 47 Object[] varArgs = null;
53 if( chunk.isVarArg ) { 48 if( fnDef.isVarArg ) {
54 if( args.length > chunk.numArgs ) { 49 if( args.length > fnDef.numArgs ) {
55 varArgs = new Object[ args.length - chunk.numArgs ]; 50 varArgs = new Object[ args.length - fnDef.numArgs ];
56 for( int i=0; i<varArgs.length; i++ ) { 51 for( int i=0; i<varArgs.length; i++ ) {
57 varArgs[i] = args[chunk.numArgs+i]; 52 varArgs[i] = args[fnDef.numArgs+i];
58 } 53 }
59 } else { 54 } else {
60 varArgs = LuanFunction.EMPTY_RTN; 55 varArgs = LuanFunction.EMPTY;
61 } 56 }
62 } 57 }
63 Object[] stack = luan.newFrame(closure,chunk.stackSize,varArgs); 58 Object[] stack = luan.newFrame(closure,fnDef.stackSize,varArgs);
64 final int n = Math.min(args.length,chunk.numArgs); 59 final int n = Math.min(args.length,fnDef.numArgs);
65 for( int i=0; i<n; i++ ) { 60 for( int i=0; i<n; i++ ) {
66 stack[i] = args[i]; 61 stack[i] = args[i];
67 } 62 }
68 Object[] returnValues; 63 Object[] returnValues;
69 Closure tailFn; 64 Closure tailFn;
70 try { 65 try {
71 chunk.block.eval(luan); 66 fnDef.block.eval(luan);
72 } catch(ReturnException e) { 67 } catch(ReturnException e) {
73 } finally { 68 } finally {
74 returnValues = luan.returnValues; 69 returnValues = luan.returnValues;
75 closure = luan.tailFn; 70 closure = luan.tailFn;
76 luan.popFrame(); 71 luan.popFrame();