diff 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
line wrap: on
line diff
--- a/core/src/luan/impl/Closure.java	Thu Apr 07 23:36:56 2016 -0600
+++ b/core/src/luan/impl/Closure.java	Fri Apr 08 07:00:17 2016 -0600
@@ -8,25 +8,28 @@
 import luan.DeepCloneable;
 
 
-final class Closure extends LuanFunction implements DeepCloneable {
-	final FnDef fnDef;
+public abstract class Closure extends LuanFunction implements DeepCloneable, Cloneable {
+	private final int stackSize;
+	private final int numArgs;
+	private final boolean isVarArg;
 	private UpValue[] upValues;
 
-	Closure(LuanStateImpl luan,FnDef fnDef) throws LuanException {
-		this.fnDef = fnDef;
-		UpValue.Getter[] upValueGetters = fnDef.upValueGetters;
+	public Closure(LuanStateImpl luan,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) throws LuanException {
+		this.stackSize = stackSize;
+		this.numArgs = numArgs;
+		this.isVarArg = isVarArg;
 		this.upValues = new UpValue[upValueGetters.length];
 		for( int i=0; i<upValues.length; i++ ) {
 			upValues[i] = upValueGetters[i].get(luan);
 		}
 	}
 
-	private Closure(Closure c) {
-		this.fnDef = c.fnDef;
-	}
-
 	@Override public Closure shallowClone() {
-		return new Closure(this);
+		try {
+			return (Closure)clone();
+		} catch(CloneNotSupportedException e) {
+			throw new RuntimeException(e);
+		}
 	}
 
 	@Override public void deepenClone(DeepCloneable clone,DeepCloner cloner) {
@@ -40,24 +43,24 @@
 	@Override public Object call(LuanState ls,Object[] args) throws LuanException {
 		LuanStateImpl luan = (LuanStateImpl)ls;
 		Object[] varArgs = null;
-		if( fnDef.isVarArg ) {
-			if( args.length > fnDef.numArgs ) {
-				varArgs = new Object[ args.length - fnDef.numArgs ];
+		if( isVarArg ) {
+			if( args.length > numArgs ) {
+				varArgs = new Object[ args.length - numArgs ];
 				for( int i=0; i<varArgs.length; i++ ) {
-					varArgs[i] = args[fnDef.numArgs+i];
+					varArgs[i] = args[numArgs+i];
 				}
 			} else {
 				varArgs = LuanFunction.NOTHING;
 			}
 		}
-		Object[] stack = luan.newFrame(this,fnDef.stackSize,varArgs);
-		final int n = Math.min(args.length,fnDef.numArgs);
+		Object[] stack = luan.newFrame(this,stackSize,varArgs);
+		final int n = Math.min(args.length,numArgs);
 		for( int i=0; i<n; i++ ) {
 			stack[i] = args[i];
 		}
 		Object returnValues;
 		try {
-			return fnDef.run(luan);
+			return run(luan);
 		} catch(StackOverflowError e) {
 			throw new LuanException( "stack overflow", e );
 		} finally {
@@ -65,4 +68,5 @@
 		}
 	}
 
+	public abstract Object run(LuanStateImpl luan) throws LuanException;
 }