diff core/src/luan/impl/LuanStateImpl.java @ 195:24ede40ee0aa

make MetatableGetter DeepCloneable, scoped, and secure git-svn-id: https://luan-java.googlecode.com/svn/trunk@196 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Thu, 03 Jul 2014 08:19:48 +0000
parents 08df375e2e5f
children 9fb218211763
line wrap: on
line diff
--- a/core/src/luan/impl/LuanStateImpl.java	Wed Jul 02 04:52:25 2014 +0000
+++ b/core/src/luan/impl/LuanStateImpl.java	Thu Jul 03 08:19:48 2014 +0000
@@ -21,6 +21,7 @@
 		final Closure closure;
 		final Object[] stack;
 		final Object[] varArgs;
+		MtGetterLink mtGetterLink;
 		UpValue[] downValues = null;
 
 		Frame( Frame previousFrame, Closure closure, int stackSize, Object[] varArgs) {
@@ -28,6 +29,7 @@
 			this.closure = closure;
 			this.stack = new Object[stackSize];
 			this.varArgs = varArgs;
+			this.mtGetterLink = closure.mtGetterLink();
 		}
 
 		void stackClear(int start,int end) {
@@ -52,22 +54,24 @@
 				downValues[index] = new UpValue(stack,index);
 			return downValues[index];
 		}
+
+		void addMetatableGetter(MetatableGetter mg) {
+			if( mtGetterLink==null || !mtGetterLink.contains(mg) )
+				mtGetterLink = new MtGetterLink(mg,mtGetterLink);
+		}
 	}
 
 	private Frame frame = null;
 	Object returnValues;
 	Closure tailFn;
+	MtGetterLink mtGetterLink = null;
 
 	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);
+		return new LuanStateImpl();
 	}
 
 	// returns stack
@@ -81,6 +85,7 @@
 	void popFrame() {
 		returnValues = LuanFunction.NOTHING;
 		tailFn = null;
+		mtGetterLink = frame.mtGetterLink;
 		frame = frame.previousFrame;
 	}
 
@@ -114,4 +119,21 @@
 		return (LuanTable)frame.closure.upValues()[0].get();
 	}
 
+	MtGetterLink mtGetterLink() {
+		return frame==null ? null : frame.mtGetterLink;
+	}
+
+	@Override public LuanTable getMetatable(Object obj,MetatableGetter beforeThis) {
+		if( obj instanceof LuanTable ) {
+			LuanTable table = (LuanTable)obj;
+			return table.getMetatable();
+		}
+		MtGetterLink mtGetterLink = mtGetterLink();
+		return mtGetterLink==null ? null : mtGetterLink.getMetatable(obj,beforeThis);
+	}
+
+	@Override public void addMetatableGetter(MetatableGetter mg) {
+		frame.addMetatableGetter(mg);
+	}
+
 }