1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl3.internal;
18
19 import java.util.Arrays;
20 import java.util.concurrent.atomic.AtomicReference;
21
22
23
24
25
26 public class Frame {
27
28 private final Scope scope;
29
30 protected final Object[] stack;
31
32 private final int curried;
33
34
35
36
37
38
39
40 protected Frame(final Scope s, final Object[] r, final int c) {
41 scope = s;
42 stack = r;
43 curried = c;
44 }
45
46
47
48
49
50
51 Frame assign(final Object... values) {
52 if (stack != null) {
53 final int nparm = scope.getArgCount();
54 final Object[] copy = stack.clone();
55 int ncopy = 0;
56 if (values != null && values.length > 0) {
57 ncopy = Math.min(nparm - curried, Math.min(nparm, values.length));
58 System.arraycopy(values, 0, copy, curried, ncopy);
59 }
60
61 Arrays.fill(copy, curried + ncopy, nparm, null);
62 return newFrame(scope, copy, curried + ncopy);
63 }
64 return this;
65 }
66
67
68
69
70
71
72
73
74 Frame newFrame(final Scope s, final Object[] r, final int c) {
75 return new Frame(s, r, c);
76 }
77
78
79
80
81
82
83 Object capture(final int s) {
84 return stack[s];
85 }
86
87
88
89
90
91
92 Object get(final int s) {
93 return stack[s];
94 }
95
96
97
98
99
100
101 void set(final int r, final Object value) {
102 stack[r] = value;
103 }
104
105
106
107
108
109 public Scope getScope() {
110 return scope;
111 }
112
113
114
115
116
117 public String[] getUnboundParameters() {
118 return scope.getParameters(curried);
119 }
120
121
122
123
124
125
126 boolean has(final int s) {
127 return s >= 0 && s < stack.length && stack[s] != Scope.UNDECLARED;
128 }
129
130
131
132
133
134
135
136
137 Object[] nocycleStack(final Closure closure) {
138 Object[] ns = stack;
139 for(int i = 0; i < stack.length; ++i) {
140 if (stack[i] == closure) {
141 if (ns == stack) {
142 ns = stack.clone();
143 }
144
145 ns[i] = Closure.class.hashCode() + i;
146 }
147 }
148 return ns;
149 }
150 }
151
152
153
154
155 class ReferenceFrame extends Frame {
156 ReferenceFrame(final Scope s, final Object[] r, final int c) {
157 super(s, r, c);
158 }
159
160 @Override
161 Frame newFrame(final Scope s, final Object[] r, final int c) {
162 return new ReferenceFrame(s, r, c);
163 }
164
165 @Override
166 CaptureReference capture(final int s) {
167 final Object o = stack[s];
168 if (o instanceof CaptureReference) {
169 return (CaptureReference) o;
170 }
171
172 final CaptureReference captured = new CaptureReference(o);
173 stack[s] = captured;
174 return captured;
175 }
176
177 @Override
178 Object get(final int s) {
179 final Object o = stack[s];
180 return o instanceof CaptureReference ? ((CaptureReference) o).get() : o;
181 }
182
183 @Override
184 void set(final int r, final Object value) {
185 final Object o = stack[r];
186 if (o instanceof CaptureReference) {
187 if (value != Scope.UNDEFINED && value != Scope.UNDECLARED) {
188 ((CaptureReference) o).set(value);
189 }
190 } else {
191 stack[r] = value;
192 }
193 }
194 }
195
196
197
198
199 class CaptureReference extends AtomicReference<Object> {
200 CaptureReference(final Object o) {
201 super(o);
202 }
203 }