Mercurial Hosting > luan
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); + } + }