view src/luan/interp/UpValue.java @ 77:4bf3d0c0b6b9

make LuanState cloneable git-svn-id: https://luan-java.googlecode.com/svn/trunk@78 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Fri, 15 Feb 2013 09:55:17 +0000
parents f86e4f77ef32
children 7c08b611125d
line wrap: on
line source

package luan.interp;

import luan.DeepCloner;
import luan.DeepCloneable;


final class UpValue implements DeepCloneable<UpValue> {
	private Object[] stack;
	private int index;
	private boolean isClosed = false;
	private Object value;

	UpValue(Object[] stack,int index) {
		this.stack = stack;
		this.index = index;
	}

	UpValue(Object value) {
		this.value = value;
		this.isClosed = true;
	}

	private UpValue() {}

	@Override public UpValue shallowClone() {
		return new UpValue();
	}

	@Override public void deepenClone(UpValue clone,DeepCloner cloner) {
		clone.isClosed = isClosed;
		if( isClosed ) {
			clone.value = cloner.get(value);
		} else {
			clone.stack = stack.clone();
			cloner.deepenClone(clone.stack);
			clone.index = index;
		}
	}

	Object get() {
		return isClosed ? value : stack[index];
	}

	void set(Object value) {
		if( isClosed ) {
			this.value = value;
		} else {
			stack[index] = value;
		}
	}

	void close() {
		value = stack[index];
		isClosed = true;
		stack = null;
	}

	static interface Getter {
		public UpValue get(LuanStateImpl luan);
	}

	static final class StackGetter implements Getter {
		private final int index;

		StackGetter(int index) {
			this.index = index;
		}

		public UpValue get(LuanStateImpl luan) {
			return luan.getUpValue(index);
		}
	}

	static final class NestedGetter implements Getter {
		private final int index;

		NestedGetter(int index) {
			this.index = index;
		}

		public UpValue get(LuanStateImpl luan) {
			return luan.closure().upValues[index];
		}
	}

	static final Getter globalGetter = new Getter() {
		public UpValue get(LuanStateImpl luan) {
			return new UpValue(luan.global());
		}
	};

}