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 }