changeset 78:7c08b611125d

better deep cloning git-svn-id: https://luan-java.googlecode.com/svn/trunk@79 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Fri, 15 Feb 2013 22:29:16 +0000
parents 4bf3d0c0b6b9
children 805929c3c6e1
files src/luan/DeepCloner.java src/luan/interp/Closure.java src/luan/interp/GetUpVar.java src/luan/interp/SetUpVar.java src/luan/interp/UpValue.java
diffstat 5 files changed, 24 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/DeepCloner.java	Fri Feb 15 09:55:17 2013 +0000
+++ b/src/luan/DeepCloner.java	Fri Feb 15 22:29:16 2013 +0000
@@ -18,10 +18,21 @@
 		return rtn;
 	}
 
-	public void deepenClone(Object[] a) {
-		for( int i=0; i<a.length; i++ ) {
-			a[i] = get(a[i]);
+	public <T> T[] deepClone(T[] obj) {
+		if( obj.length == 0 )
+			return obj;
+		@SuppressWarnings("unchecked")
+		T[] rtn = (T[])cloned.get(obj);
+		if( rtn == null ) {
+			rtn = obj.clone();
+			cloned.put(obj,rtn);
+			for( int i=0; i<rtn.length; i++ ) {
+				@SuppressWarnings("unchecked")
+				T t = (T)get(rtn[i]);
+				rtn[i] = t;
+			}
 		}
+		return rtn;
 	}
 
 	public Object get(Object obj) {
--- a/src/luan/interp/Closure.java	Fri Feb 15 09:55:17 2013 +0000
+++ b/src/luan/interp/Closure.java	Fri Feb 15 22:29:16 2013 +0000
@@ -10,7 +10,7 @@
 
 final class Closure extends LuanFunction implements DeepCloneable<Closure> {
 	private final Chunk chunk;
-	final UpValue[] upValues;
+	private UpValue[] upValues;
 	private final static UpValue[] NO_UP_VALUES = new UpValue[0];
 
 	Closure(LuanStateImpl luan,Chunk chunk) {
@@ -28,7 +28,6 @@
 
 	private Closure(Closure c) {
 		this.chunk = c.chunk;
-		this.upValues = c.upValues==NO_UP_VALUES ? NO_UP_VALUES : c.upValues.clone();
 	}
 
 	@Override public Closure shallowClone() {
@@ -36,7 +35,11 @@
 	}
 
 	@Override public void deepenClone(Closure clone,DeepCloner cloner) {
-		cloner.deepenClone(clone.upValues);
+		clone.upValues = cloner.deepClone(upValues);
+	}
+
+	UpValue[] upValues() {
+		return upValues;
 	}
 
 	public Object[] call(LuanState luan,Object[] args) throws LuanException {
--- a/src/luan/interp/GetUpVar.java	Fri Feb 15 09:55:17 2013 +0000
+++ b/src/luan/interp/GetUpVar.java	Fri Feb 15 22:29:16 2013 +0000
@@ -12,6 +12,6 @@
 	}
 
 	@Override public Object eval(LuanStateImpl luan) {
-		return luan.closure().upValues[index].get();
+		return luan.closure().upValues()[index].get();
 	}
 }
--- a/src/luan/interp/SetUpVar.java	Fri Feb 15 09:55:17 2013 +0000
+++ b/src/luan/interp/SetUpVar.java	Fri Feb 15 22:29:16 2013 +0000
@@ -9,6 +9,6 @@
 	}
 
 	@Override public void set(LuanStateImpl luan,Object value) {
-		luan.closure().upValues[index].set(value);
+		luan.closure().upValues()[index].set(value);
 	}
 }
--- a/src/luan/interp/UpValue.java	Fri Feb 15 09:55:17 2013 +0000
+++ b/src/luan/interp/UpValue.java	Fri Feb 15 22:29:16 2013 +0000
@@ -31,8 +31,7 @@
 		if( isClosed ) {
 			clone.value = cloner.get(value);
 		} else {
-			clone.stack = stack.clone();
-			cloner.deepenClone(clone.stack);
+			clone.stack = cloner.deepClone(stack);
 			clone.index = index;
 		}
 	}
@@ -79,7 +78,7 @@
 		}
 
 		public UpValue get(LuanStateImpl luan) {
-			return luan.closure().upValues[index];
+			return luan.closure().upValues()[index];
 		}
 	}