diff src/luan/LuanTable.java @ 1578:c922446f53aa

immutable threading
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 08 Feb 2021 14:16:19 -0700
parents 364859d29ff5
children fa066aaa068c
line wrap: on
line diff
--- a/src/luan/LuanTable.java	Sun Jan 31 16:04:39 2021 -0700
+++ b/src/luan/LuanTable.java	Mon Feb 08 14:16:19 2021 -0700
@@ -13,14 +13,12 @@
 import java.util.HashSet;
 
 
-public final class LuanTable implements LuanCloneable {
+public final class LuanTable implements LuanMutable {
 	private Map map = null;
 	private List list = null;
 	private LuanTable metatable = null;
 	public LuanClosure closure;
-	private LuanCloner cloner;
 	private boolean immutable = false;
-	private Luan luan;
 
 	public LuanTable() {}
 
@@ -71,59 +69,23 @@
 		this.metatable = tbl.metatable;
 	}
 
-	@Override public LuanTable shallowClone() {
-		if(immutable) throw new RuntimeException();
-		return new LuanTable();
-	}
-
-	@Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) {
-		check();
-		LuanTable clone = (LuanTable)dc;
-		switch( cloner.type ) {
-		case COMPLETE:
-			completeClone(clone,cloner);
-			return;
-		case INCREMENTAL:
-			clone.cloner = cloner;
-			clone.map = map;
-			clone.list = list;
-			clone.metatable = metatable;
-			clone.closure = closure;
-			return;
-		}
+	@Override public boolean isImmutable() {
+		return immutable;
 	}
 
-	private void check() {
-		if( cloner != null ) {
-			completeClone(this,cloner);
-			cloner = null;
-		}
-	}
-
-	private void checkLuan(Luan luan) {
-		check();
-		if( this.luan==null ) {
-			this.luan = luan;
-		} else if( this.luan != luan ) {
-			throw new RuntimeException("wrong luan");
-		}
+	@Override public void makeImmutable() {
+		if(immutable)
+			return;
+		immutable = true;
+		LuanMutable.makeImmutable(map);
+		LuanMutable.makeImmutable(list);
+		LuanMutable.makeImmutable(metatable);
+		LuanMutable.makeImmutable(closure);
 	}
 
-	private void completeClone(LuanTable clone,LuanCloner cloner) {
-		clone.map = cloner.clone(map);
-		clone.list = (List)cloner.clone(list);
-		clone.metatable = (LuanTable)cloner.clone(metatable);
-		clone.closure = (LuanClosure)cloner.clone(closure);
-		clone.luan = (Luan)cloner.clone(luan);
-	}
-
-	@Override public void makeImmutable(LuanImmutabler immutabler) throws LuanException {
-		check();
-		immutabler.makeImmutable(map);
-		immutabler.makeImmutable(list);
-		immutabler.makeImmutable(metatable);
-		immutabler.makeImmutable(closure);
-		immutable = true;
+	private void checkMutable() throws LuanException {
+		if( immutable )
+			throw new LuanException("table is immutable");
 	}
 
 	public boolean isList() {
@@ -135,17 +97,15 @@
 	}
 
 	public List<Object> asList() {
-		check();
 		return list!=null ? list : Collections.emptyList();
 	}
 
 	public Map rawMap() {
-		check();
 		return map!=null ? map : Collections.emptyMap();
 	}
 
 	public String toStringLuan(Luan luan) throws LuanException {
-		Object h = getHandler("__to_string");
+		Object h = getHandler(luan,"__to_string");
 		if( h == null )
 			return rawToString();
 		LuanFunction fn = Luan.checkFunction(h);
@@ -161,7 +121,7 @@
 		Object value = rawGet(key);
 		if( value != null )
 			return value;
-		Object h = getHandler("__index");
+		Object h = getHandler(luan,"__index");
 		if( h==null )
 			return null;
 		if( h instanceof LuanFunction ) {
@@ -172,7 +132,6 @@
 	}
 
 	public Object rawGet(Object key) {
-		check();
 		if( list != null ) {
 			Integer iT = Luan.asInteger(key);
 			if( iT != null ) {
@@ -192,7 +151,7 @@
 
 	public void put(Luan luan,Object key,Object value) throws LuanException {
 		//checkLuan(luan);
-		Object h = getHandler("__new_index");
+		Object h = getHandler(luan,"__new_index");
 		if( h==null || rawGet(key)!=null ) {
 			rawPut(key,value);
 			return;
@@ -211,9 +170,7 @@
 	}
 
 	public Object rawPut(Object key,Object val) throws LuanException {
-		if( immutable )
-			throw new LuanException("table is immutable");
-		check();
+		checkMutable();
 		if( key==null )
 			throw new LuanException("table index is nil");
 		Integer iT = Luan.asInteger(key);
@@ -284,34 +241,34 @@
 		return list;
 	}
 
-	public void rawInsert(int pos,Object value) {
-		check();
+	public void rawInsert(int pos,Object value) throws LuanException {
+		checkMutable();
 		if( value==null )
 			throw new IllegalArgumentException("can't insert a nil value");
 		list().add(pos-1,value);
 		mapToList();
 	}
 
-	public void rawAdd(Object value) {
-		check();
+	public void rawAdd(Object value) throws LuanException {
+		checkMutable();
 		if( value==null )
 			throw new IllegalArgumentException("can't insert a nil value");
 		list().add(value);
 		mapToList();
 	}
 
-	public Object removeFromList(int pos) {
-		check();
+	public Object removeFromList(int pos) throws LuanException {
+		checkMutable();
 		return list().remove(pos-1);
 	}
 
-	public void rawSort(Comparator<Object> cmp) {
-		check();
+	public void rawSort(Comparator<Object> cmp) throws LuanException {
+		checkMutable();
 		Collections.sort(list(),cmp);
 	}
 
 	public int length(Luan luan) throws LuanException {
-		Object h = getHandler("__len");
+		Object h = getHandler(luan,"__len");
 		if( h != null ) {
 			LuanFunction fn = Luan.checkFunction(h);
 			return (Integer)Luan.first(fn.call(luan,this));
@@ -320,7 +277,6 @@
 	}
 
 	public int rawLength() {
-		check();
 		return list==null ? 0 : list.size();
 	}
 
@@ -343,7 +299,7 @@
 	}
 
 	public Iterator<Map.Entry> iterator(final Luan luan) throws LuanException {
-		if( getHandler("__pairs") == null )
+		if( getHandler(luan,"__pairs") == null )
 			return rawIterator();
 		final LuanFunction fn = pairs(luan);
 		return new Iterator<Map.Entry>() {
@@ -380,7 +336,7 @@
 	}
 
 	public LuanFunction pairs(Luan luan) throws LuanException {
-		Object h = getHandler("__pairs");
+		Object h = getHandler(luan,"__pairs");
 		if( h != null ) {
 			if( h instanceof LuanFunction ) {
 				LuanFunction fn = (LuanFunction)h;
@@ -408,7 +364,6 @@
 	}
 
 	public Iterator<Map.Entry> rawIterator() {
-		check();
 		if( list == null ) {
 			if( map == null )
 				return Collections.<Map.Entry>emptyList().iterator();
@@ -462,25 +417,22 @@
 	}
 
 	public LuanTable rawSubList(int from,int to) {
-		check();
 		LuanTable tbl = new LuanTable();
 		tbl.list = new ArrayList<Object>(list().subList(from-1,to-1));
 		return tbl;
 	}
 
 	public LuanTable getMetatable() {
-		check();
 		return metatable;
 	}
 
 	public void setMetatable(LuanTable metatable) throws LuanException {
-		check();
+		checkMutable();
 		this.metatable = metatable;
 	}
 
-	public Object getHandler(String op) throws LuanException {
-		check();
-		return metatable==null ? null : metatable.rawGet(op);
+	public Object getHandler(Luan luan,String op) throws LuanException {
+		return metatable==null ? null : luan==null ? metatable.rawGet(op) : metatable.get(luan,op);
 	}
 
 	private static Map<Object,Object> newMap() {
@@ -511,8 +463,8 @@
 		return map;
 	}
 
-	public void rawClear() {
-		check();
+	public void rawClear() throws LuanException {
+		checkMutable();
 		map = null;
 		list = null;
 	}
@@ -540,15 +492,14 @@
 	}
 
 	public Object remove(Object key) throws LuanException {
-		if( immutable )
-			throw new LuanException("table is immutable");
+		checkMutable();
 		Object old = rawGet(key);
 		rawPut(key,null);
 		return old;
 	}
 
 	protected void finalize() throws Throwable {
-		Object h = getHandler("__gc");
+		Object h = getHandler(null,"__gc");
 		if( h != null ) {
 			LuanFunction fn = Luan.checkFunction(h);
 			fn.call(new Luan(),this);  // ??? should be immutable