Mercurial Hosting > luan
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(); |