Mercurial Hosting > luan
comparison 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 |
comparison
equal
deleted
inserted
replaced
194:08df375e2e5f | 195:24ede40ee0aa |
---|---|
19 private static class Frame { | 19 private static class Frame { |
20 final Frame previousFrame; | 20 final Frame previousFrame; |
21 final Closure closure; | 21 final Closure closure; |
22 final Object[] stack; | 22 final Object[] stack; |
23 final Object[] varArgs; | 23 final Object[] varArgs; |
24 MtGetterLink mtGetterLink; | |
24 UpValue[] downValues = null; | 25 UpValue[] downValues = null; |
25 | 26 |
26 Frame( Frame previousFrame, Closure closure, int stackSize, Object[] varArgs) { | 27 Frame( Frame previousFrame, Closure closure, int stackSize, Object[] varArgs) { |
27 this.previousFrame = previousFrame; | 28 this.previousFrame = previousFrame; |
28 this.closure = closure; | 29 this.closure = closure; |
29 this.stack = new Object[stackSize]; | 30 this.stack = new Object[stackSize]; |
30 this.varArgs = varArgs; | 31 this.varArgs = varArgs; |
32 this.mtGetterLink = closure.mtGetterLink(); | |
31 } | 33 } |
32 | 34 |
33 void stackClear(int start,int end) { | 35 void stackClear(int start,int end) { |
34 if( downValues != null ) { | 36 if( downValues != null ) { |
35 for( int i=start; i<end; i++ ) { | 37 for( int i=start; i<end; i++ ) { |
50 downValues = new UpValue[stack.length]; | 52 downValues = new UpValue[stack.length]; |
51 if( downValues[index] == null ) | 53 if( downValues[index] == null ) |
52 downValues[index] = new UpValue(stack,index); | 54 downValues[index] = new UpValue(stack,index); |
53 return downValues[index]; | 55 return downValues[index]; |
54 } | 56 } |
57 | |
58 void addMetatableGetter(MetatableGetter mg) { | |
59 if( mtGetterLink==null || !mtGetterLink.contains(mg) ) | |
60 mtGetterLink = new MtGetterLink(mg,mtGetterLink); | |
61 } | |
55 } | 62 } |
56 | 63 |
57 private Frame frame = null; | 64 private Frame frame = null; |
58 Object returnValues; | 65 Object returnValues; |
59 Closure tailFn; | 66 Closure tailFn; |
67 MtGetterLink mtGetterLink = null; | |
60 | 68 |
61 LuanStateImpl() {} | 69 LuanStateImpl() {} |
62 | |
63 private LuanStateImpl(LuanStateImpl luan) { | |
64 super(luan); | |
65 } | |
66 | 70 |
67 @Override public LuanState shallowClone() { | 71 @Override public LuanState shallowClone() { |
68 // if( frame != null ) | 72 // if( frame != null ) |
69 // throw new IllegalStateException("frame isn't null"); | 73 // throw new IllegalStateException("frame isn't null"); |
70 return new LuanStateImpl(this); | 74 return new LuanStateImpl(); |
71 } | 75 } |
72 | 76 |
73 // returns stack | 77 // returns stack |
74 Object[] newFrame(Closure closure, int stackSize, Object[] varArgs) { | 78 Object[] newFrame(Closure closure, int stackSize, Object[] varArgs) { |
75 returnValues = LuanFunction.NOTHING; | 79 returnValues = LuanFunction.NOTHING; |
79 } | 83 } |
80 | 84 |
81 void popFrame() { | 85 void popFrame() { |
82 returnValues = LuanFunction.NOTHING; | 86 returnValues = LuanFunction.NOTHING; |
83 tailFn = null; | 87 tailFn = null; |
88 mtGetterLink = frame.mtGetterLink; | |
84 frame = frame.previousFrame; | 89 frame = frame.previousFrame; |
85 } | 90 } |
86 | 91 |
87 Object stackGet(int index) { | 92 Object stackGet(int index) { |
88 return frame.stack[index]; | 93 return frame.stack[index]; |
112 if( frame==null ) | 117 if( frame==null ) |
113 return null; | 118 return null; |
114 return (LuanTable)frame.closure.upValues()[0].get(); | 119 return (LuanTable)frame.closure.upValues()[0].get(); |
115 } | 120 } |
116 | 121 |
122 MtGetterLink mtGetterLink() { | |
123 return frame==null ? null : frame.mtGetterLink; | |
124 } | |
125 | |
126 @Override public LuanTable getMetatable(Object obj,MetatableGetter beforeThis) { | |
127 if( obj instanceof LuanTable ) { | |
128 LuanTable table = (LuanTable)obj; | |
129 return table.getMetatable(); | |
130 } | |
131 MtGetterLink mtGetterLink = mtGetterLink(); | |
132 return mtGetterLink==null ? null : mtGetterLink.getMetatable(obj,beforeThis); | |
133 } | |
134 | |
135 @Override public void addMetatableGetter(MetatableGetter mg) { | |
136 frame.addMetatableGetter(mg); | |
137 } | |
138 | |
117 } | 139 } |