view src/luan/interp/UpValue.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 3c404a296995
line wrap: on
line source

package luan.interp;

import luan.DeepCloner;
import luan.DeepCloneable;
import luan.LuanException;


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 = cloner.deepClone(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) throws LuanException;
	}

	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 class EnvGetter implements Getter {

		public UpValue get(LuanStateImpl luan) throws LuanException {
			return luan.getUpValue(this);
		}
	}

	static final class ValueGetter implements Getter {
		private final UpValue upValue;

		ValueGetter(Object value) {
			this.upValue = new UpValue(value);
		}

		public UpValue get(LuanStateImpl luan) {
			return upValue;
		}
	}

}