diff src/luan/impl/LuanStateImpl.java @ 166:4eaee12f6c65

move luan/interp to impl git-svn-id: https://luan-java.googlecode.com/svn/trunk@167 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Sun, 22 Jun 2014 04:17:38 +0000
parents src/luan/interp/LuanStateImpl.java@14281d5bd36f
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/impl/LuanStateImpl.java	Sun Jun 22 04:17:38 2014 +0000
@@ -0,0 +1,137 @@
+package luan.impl;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import luan.Luan;
+import luan.LuanState;
+import luan.LuanTable;
+import luan.LuanFunction;
+import luan.MetatableGetter;
+import luan.LuanException;
+import luan.LuanElement;
+import luan.DeepCloner;
+
+
+final class LuanStateImpl extends LuanState {
+
+	private static class Frame {
+		final Frame previousFrame;
+		final Closure closure;
+		final Object[] stack;
+		final Object[] varArgs;
+		UpValue[] downValues = null;
+
+		Frame( Frame previousFrame, Closure closure, int stackSize, Object[] varArgs) {
+			this.previousFrame = previousFrame;
+			this.closure = closure;
+			this.stack = new Object[stackSize];
+			this.varArgs = varArgs;
+		}
+
+		void stackClear(int start,int end) {
+			if( downValues != null ) {
+				for( int i=start; i<end; i++ ) {
+					UpValue downValue = downValues[i];
+					if( downValue != null ) {
+						downValue.close();
+						downValues[i] = null;
+					}
+				}
+			}
+			for( int i=start; i<end; i++ ) {
+				stack[i] = null;
+			}
+		}
+
+		UpValue getUpValue(int index) {
+			if( downValues==null )
+				downValues = new UpValue[stack.length];
+			if( downValues[index] == null )
+				downValues[index] = new UpValue(stack,index);
+			return downValues[index];
+		}
+	}
+
+	private Frame frame = null;
+	Object returnValues;
+	Closure tailFn;
+	Map<UpValue.EnvGetter,UpValue> envs = new HashMap<UpValue.EnvGetter,UpValue>();
+
+	LuanStateImpl() {}
+
+	private LuanStateImpl(LuanStateImpl luan) {
+		super(luan);
+	}
+
+	@Override public LuanState shallowClone() {
+//		if( frame != null )
+//			throw new IllegalStateException("frame isn't null");
+		return new LuanStateImpl(this);
+	}
+
+	@Override public void deepenClone(LuanState clone,DeepCloner cloner) {
+		super.deepenClone(clone,cloner);
+		LuanStateImpl cloneImpl = (LuanStateImpl)clone;
+		cloneImpl.envs = new HashMap<UpValue.EnvGetter,UpValue>();
+		for( Map.Entry<UpValue.EnvGetter,UpValue> entry : envs.entrySet() ) {
+			cloneImpl.envs.put( entry.getKey(), cloner.deepClone(entry.getValue()) );
+		}
+	}
+
+	// returns stack
+	Object[] newFrame(Closure closure, int stackSize, Object[] varArgs) {
+		returnValues = LuanFunction.NOTHING;
+		tailFn = null;
+		frame = new Frame(frame,closure,stackSize,varArgs);
+		return frame.stack;
+	}
+
+	void popFrame() {
+		returnValues = LuanFunction.NOTHING;
+		tailFn = null;
+		frame = frame.previousFrame;
+	}
+
+	Object stackGet(int index) {
+		return frame.stack[index];
+	}
+
+	void stackSet(int index,Object value) {
+		frame.stack[index] = value;
+	}
+
+	void stackClear(int start,int end) {
+		frame.stackClear(start,end);
+	}
+
+	Object[] varArgs() {
+		return frame.varArgs;
+	}
+
+	Closure closure() {
+		return frame.closure;
+	}
+
+	UpValue getUpValue(int index) {
+		return frame.getUpValue(index);
+	}
+
+	UpValue getUpValue(UpValue.EnvGetter getter) throws LuanException {
+		UpValue uv = envs.get(getter);
+		if( uv == null ) {
+			LuanTable env = new LuanTable();
+			uv = new UpValue(env);
+			envs.put(getter,uv);
+		}
+		return uv;
+	}
+
+	@Override public LuanTable currentEnvironment() {
+		if( frame==null )
+			return null;
+		return (LuanTable)frame.closure.upValues()[0].get();
+	}
+
+}