7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package jdk.internal.classfile.impl.verifier;
26
27 import java.util.ArrayList;
28 import java.util.List;
29
30 import static jdk.internal.classfile.impl.StackMapGenerator.*;
31
32 /// From `stackMapTable.cpp`.
33 class VerificationTable {
34
35 private final int _code_length;
36 private final int _frame_count;
37 private final List<VerificationFrame> _frame_array;
38 private final VerifierImpl _verifier;
39
40 int get_frame_count() {
41 return _frame_count;
42 }
43
44 int get_offset(int index) {
45 return _frame_array.get(index).offset();
46 }
47
48 static class StackMapStream {
110 boolean match_stackmap(VerificationFrame frame, int target, int frame_index, boolean match, boolean update) {
111 if (frame_index < 0 || frame_index >= _frame_count) {
112 _verifier.verifyError(String.format("Expecting a stackmap frame at branch target %d", target));
113 }
114 VerificationFrame stackmap_frame = _frame_array.get(frame_index);
115 boolean result = true;
116 if (match) {
117 result = frame.is_assignable_to(stackmap_frame);
118 }
119 if (update) {
120 int lsize = stackmap_frame.locals_size();
121 int ssize = stackmap_frame.stack_size();
122 if (frame.locals_size() > lsize || frame.stack_size() > ssize) {
123 frame.reset();
124 }
125 frame.set_locals_size(lsize);
126 frame.copy_locals(stackmap_frame);
127 frame.set_stack_size(ssize);
128 frame.copy_stack(stackmap_frame);
129 frame.set_flags(stackmap_frame.flags());
130 }
131 return result;
132 }
133
134 void check_jump_target(VerificationFrame frame, int target) {
135 boolean match = match_stackmap(frame, target, true, false);
136 if (!match || (target < 0 || target >= _code_length)) {
137 _verifier.verifyError(String.format("Inconsistent stackmap frames at branch target %d", target));
138 }
139 }
140
141 static class StackMapReader {
142
143 private final VerificationWrapper.ConstantPoolWrapper _cp;
144 private final StackMapStream _stream;
145 private final byte[] _code_data;
146 private final int _code_length;
147 private final int _frame_count;
148 private int _parsed_frame_count;
149 private VerificationFrame _prev_frame;
150 char _max_locals, _max_stack;
151 boolean _first;
152
153 void check_verification_type_array_size(int size, int max_size) {
154 if (size < 0 || size > max_size) {
155 _verifier.classError("StackMapTable format error: bad type array size");
156 }
157 }
158
159 public int get_frame_count() {
160 return _frame_count;
161 }
162
163 public VerificationFrame prev_frame() {
164 return _prev_frame;
165 }
166
167 public byte[] code_data() {
168 return _code_data;
169 }
170
180 _parsed_frame_count++;
181 check_size();
182 VerificationFrame frame = next_helper();
183 if (frame != null) {
184 check_offset(frame);
185 _prev_frame = frame;
186 }
187 return frame;
188 }
189
190 public void check_end() {
191 if (_frame_count != _parsed_frame_count) {
192 _verifier.verifyError("wrong attribute size");
193 }
194 }
195
196 private final VerifierImpl _verifier;
197
198 public StackMapReader(byte[] stackmapData, byte[] code_data, int code_len,
199 VerificationFrame init_frame, char max_locals, char max_stack,
200 VerificationWrapper.ConstantPoolWrapper cp, VerifierImpl context) {
201 this._verifier = context;
202 _stream = new StackMapStream(stackmapData, _verifier);
203 _code_data = code_data;
204 _code_length = code_len;
205 _parsed_frame_count = 0;
206 _prev_frame = init_frame;
207 _max_locals = max_locals;
208 _max_stack = max_stack;
209 _first = true;
210 if (stackmapData != null) {
211 _cp = cp;
212 _frame_count = _stream.get_u2();
213 } else {
214 _cp = null;
215 _frame_count = 0;
216 }
217 }
218
219 void check_offset(VerificationFrame frame) {
220 int offset = frame.offset();
221 if (offset >= _code_length || _code_data[offset] == 0) {
222 _verifier.verifyError("StackMapTable error: bad offset");
223 }
224 }
225
226 void check_size() {
227 if (_frame_count < _parsed_frame_count) {
228 _verifier.verifyError("wrong attribute size");
261 flags[0] |= VerificationFrame.FLAG_THIS_UNINIT;
262 }
263 return VerificationType.uninitialized_this_type;
264 }
265 if (tag == ITEM_UNINITIALIZED) {
266 int offset = _stream.get_u2();
267 if (offset >= _code_length || _code_data[offset] != VerifierImpl.NEW_OFFSET) {
268 _verifier.classError("StackMapTable format error: bad offset for Uninitialized");
269 }
270 return VerificationType.uninitialized_type(offset);
271 }
272 _verifier.classError("bad verification type");
273 return VerificationType.bogus_type;
274 }
275
276 VerificationFrame next_helper() {
277 VerificationFrame frame;
278 int offset;
279 VerificationType[] locals = null;
280 int frame_type = _stream.get_u1();
281 if (frame_type <= SAME_FRAME_END) {
282 if (_first) {
283 offset = frame_type;
284 if (_prev_frame.locals_size() > 0) {
285 locals = new VerificationType[_prev_frame.locals_size()];
286 }
287 } else {
288 offset = _prev_frame.offset() + frame_type + 1;
289 locals = _prev_frame.locals();
290 }
291 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), 0, _max_locals, _max_stack, locals, null, _verifier);
292 if (_first && locals != null) {
293 frame.copy_locals(_prev_frame);
294 }
295 _first = false;
296 return frame;
297 }
298 if (frame_type <= SAME_LOCALS_1_STACK_ITEM_FRAME_END) {
299 if (_first) {
300 offset = frame_type - SAME_LOCALS_1_STACK_ITEM_FRAME_START;
301 if (_prev_frame.locals_size() > 0) {
302 locals = new VerificationType[_prev_frame.locals_size()];
303 }
304 } else {
305 offset = _prev_frame.offset() + frame_type - SAME_LOCALS_1_STACK_ITEM_FRAME_START + 1;
306 locals = _prev_frame.locals();
307 }
308 VerificationType[] stack = new VerificationType[2];
309 int stack_size = 1;
310 stack[0] = parse_verification_type(null);
311 if (stack[0].is_category2()) {
312 stack[1] = stack[0].to_category2_2nd(_verifier);
313 stack_size = 2;
314 }
315 check_verification_type_array_size(stack_size, _max_stack);
316 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), stack_size, _max_locals, _max_stack, locals, stack, _verifier);
317 if (_first && locals != null) {
318 frame.copy_locals(_prev_frame);
319 }
320 _first = false;
321 return frame;
322 }
323 int offset_delta = _stream.get_u2();
324 if (frame_type < SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
325 _verifier.classError("reserved frame type");
326 }
327 if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
328 if (_first) {
329 offset = offset_delta;
330 if (_prev_frame.locals_size() > 0) {
331 locals = new VerificationType[_prev_frame.locals_size()];
332 }
333 } else {
334 offset = _prev_frame.offset() + offset_delta + 1;
335 locals = _prev_frame.locals();
336 }
337 VerificationType[] stack = new VerificationType[2];
338 int stack_size = 1;
339 stack[0] = parse_verification_type(null);
340 if (stack[0].is_category2()) {
341 stack[1] = stack[0].to_category2_2nd(_verifier);
342 stack_size = 2;
343 }
344 check_verification_type_array_size(stack_size, _max_stack);
345 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), stack_size, _max_locals, _max_stack, locals, stack, _verifier);
346 if (_first && locals != null) {
347 frame.copy_locals(_prev_frame);
348 }
349 _first = false;
350 return frame;
351 }
352 if (frame_type <= SAME_FRAME_EXTENDED) {
353 locals = _prev_frame.locals();
354 int length = _prev_frame.locals_size();
355 int chops = SAME_FRAME_EXTENDED - frame_type;
356 int new_length = length;
357 int flags = _prev_frame.flags();
358 if (chops != 0) {
359 new_length = chop(locals, length, chops);
360 check_verification_type_array_size(new_length, _max_locals);
361 flags = 0;
362 for (int i=0; i<new_length; i++) {
363 if (locals[i].is_uninitialized_this(_verifier)) {
364 flags |= VerificationFrame.FLAG_THIS_UNINIT;
365 break;
366 }
367 }
368 }
369 if (_first) {
370 offset = offset_delta;
371 if (new_length > 0) {
372 locals = new VerificationType[new_length];
373 } else {
374 locals = null;
375 }
376 } else {
377 offset = _prev_frame.offset() + offset_delta + 1;
378 }
379 frame = new VerificationFrame(offset, flags, new_length, 0, _max_locals, _max_stack, locals, null, _verifier);
380 if (_first && locals != null) {
381 frame.copy_locals(_prev_frame);
382 }
383 _first = false;
384 return frame;
385 } else if (frame_type <= APPEND_FRAME_END) {
386 int appends = frame_type - APPEND_FRAME_START + 1;
387 int real_length = _prev_frame.locals_size();
388 int new_length = real_length + appends*2;
389 locals = new VerificationType[new_length];
390 VerificationType[] pre_locals = _prev_frame.locals();
391 int i;
392 for (i=0; i< _prev_frame.locals_size(); i++) {
393 locals[i] = pre_locals[i];
394 }
395 int[] flags = new int[]{_prev_frame.flags()};
396 for (i=0; i<appends; i++) {
397 locals[real_length] = parse_verification_type(flags);
398 if (locals[real_length].is_category2()) {
399 locals[real_length + 1] = locals[real_length].to_category2_2nd(_verifier);
400 ++real_length;
401 }
402 ++real_length;
403 }
404 check_verification_type_array_size(real_length, _max_locals);
405 if (_first) {
406 offset = offset_delta;
407 } else {
408 offset = _prev_frame.offset() + offset_delta + 1;
409 }
410 frame = new VerificationFrame(offset, flags[0], real_length, 0, _max_locals, _max_stack, locals, null, _verifier);
411 _first = false;
412 return frame;
413 }
414 if (frame_type == FULL_FRAME) {
415 int flags[] = new int[]{0};
416 int locals_size = _stream.get_u2();
417 int real_locals_size = 0;
418 if (locals_size > 0) {
419 locals = new VerificationType[locals_size*2];
420 }
421 int i;
422 for (i=0; i<locals_size; i++) {
423 locals[real_locals_size] = parse_verification_type(flags);
424 if (locals[real_locals_size].is_category2()) {
425 locals[real_locals_size + 1] =
426 locals[real_locals_size].to_category2_2nd(_verifier);
427 ++real_locals_size;
428 }
429 ++real_locals_size;
430 }
432 int stack_size = _stream.get_u2();
433 int real_stack_size = 0;
434 VerificationType[] stack = null;
435 if (stack_size > 0) {
436 stack = new VerificationType[stack_size*2];
437 }
438 for (i=0; i<stack_size; i++) {
439 stack[real_stack_size] = parse_verification_type(null);
440 if (stack[real_stack_size].is_category2()) {
441 stack[real_stack_size + 1] = stack[real_stack_size].to_category2_2nd(_verifier);
442 ++real_stack_size;
443 }
444 ++real_stack_size;
445 }
446 check_verification_type_array_size(real_stack_size, _max_stack);
447 if (_first) {
448 offset = offset_delta;
449 } else {
450 offset = _prev_frame.offset() + offset_delta + 1;
451 }
452 frame = new VerificationFrame(offset, flags[0], real_locals_size, real_stack_size, _max_locals, _max_stack, locals, stack, _verifier);
453 _first = false;
454 return frame;
455 }
456 _verifier.classError("reserved frame type");
457 return null;
458 }
459 }
460 }
|
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package jdk.internal.classfile.impl.verifier;
26
27 import java.lang.classfile.constantpool.NameAndTypeEntry;
28 import java.util.ArrayList;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Set;
32
33 import static jdk.internal.classfile.impl.StackMapGenerator.*;
34
35 /// From `stackMapTable.cpp`.
36 class VerificationTable {
37
38 private final int _code_length;
39 private final int _frame_count;
40 private final List<VerificationFrame> _frame_array;
41 private final VerifierImpl _verifier;
42
43 int get_frame_count() {
44 return _frame_count;
45 }
46
47 int get_offset(int index) {
48 return _frame_array.get(index).offset();
49 }
50
51 static class StackMapStream {
113 boolean match_stackmap(VerificationFrame frame, int target, int frame_index, boolean match, boolean update) {
114 if (frame_index < 0 || frame_index >= _frame_count) {
115 _verifier.verifyError(String.format("Expecting a stackmap frame at branch target %d", target));
116 }
117 VerificationFrame stackmap_frame = _frame_array.get(frame_index);
118 boolean result = true;
119 if (match) {
120 result = frame.is_assignable_to(stackmap_frame);
121 }
122 if (update) {
123 int lsize = stackmap_frame.locals_size();
124 int ssize = stackmap_frame.stack_size();
125 if (frame.locals_size() > lsize || frame.stack_size() > ssize) {
126 frame.reset();
127 }
128 frame.set_locals_size(lsize);
129 frame.copy_locals(stackmap_frame);
130 frame.set_stack_size(ssize);
131 frame.copy_stack(stackmap_frame);
132 frame.set_flags(stackmap_frame.flags());
133 frame.set_assert_unset_fields(stackmap_frame.assert_unset_fields());
134 }
135 return result;
136 }
137
138 void check_jump_target(VerificationFrame frame, int target) {
139 boolean match = match_stackmap(frame, target, true, false);
140 if (!match || (target < 0 || target >= _code_length)) {
141 _verifier.verifyError(String.format("Inconsistent stackmap frames at branch target %d", target));
142 }
143 }
144
145 static class StackMapReader {
146
147 private final VerificationWrapper.ConstantPoolWrapper _cp;
148 private final StackMapStream _stream;
149 private final byte[] _code_data;
150 private final int _code_length;
151 private final int _frame_count;
152 private int _parsed_frame_count;
153 private VerificationFrame _prev_frame;
154 char _max_locals, _max_stack;
155 final Set<NameAndTypeEntry> strictFields;
156 Set<NameAndTypeEntry> _assert_unset_fields_buffer;
157 boolean _first;
158
159 void check_verification_type_array_size(int size, int max_size) {
160 if (size < 0 || size > max_size) {
161 _verifier.classError("StackMapTable format error: bad type array size");
162 }
163 }
164
165 public int get_frame_count() {
166 return _frame_count;
167 }
168
169 public VerificationFrame prev_frame() {
170 return _prev_frame;
171 }
172
173 public byte[] code_data() {
174 return _code_data;
175 }
176
186 _parsed_frame_count++;
187 check_size();
188 VerificationFrame frame = next_helper();
189 if (frame != null) {
190 check_offset(frame);
191 _prev_frame = frame;
192 }
193 return frame;
194 }
195
196 public void check_end() {
197 if (_frame_count != _parsed_frame_count) {
198 _verifier.verifyError("wrong attribute size");
199 }
200 }
201
202 private final VerifierImpl _verifier;
203
204 public StackMapReader(byte[] stackmapData, byte[] code_data, int code_len,
205 VerificationFrame init_frame, char max_locals, char max_stack,
206 Set<NameAndTypeEntry> initial_strict_fields,
207 VerificationWrapper.ConstantPoolWrapper cp, VerifierImpl context) {
208 this._verifier = context;
209 _stream = new StackMapStream(stackmapData, _verifier);
210 _code_data = code_data;
211 _code_length = code_len;
212 _parsed_frame_count = 0;
213 _prev_frame = init_frame;
214 _max_locals = max_locals;
215 _max_stack = max_stack;
216 strictFields = Set.copyOf(initial_strict_fields);
217 _assert_unset_fields_buffer = initial_strict_fields;
218 _first = true;
219 if (stackmapData != null) {
220 _cp = cp;
221 _frame_count = _stream.get_u2();
222 } else {
223 _cp = null;
224 _frame_count = 0;
225 }
226 }
227
228 void check_offset(VerificationFrame frame) {
229 int offset = frame.offset();
230 if (offset >= _code_length || _code_data[offset] == 0) {
231 _verifier.verifyError("StackMapTable error: bad offset");
232 }
233 }
234
235 void check_size() {
236 if (_frame_count < _parsed_frame_count) {
237 _verifier.verifyError("wrong attribute size");
270 flags[0] |= VerificationFrame.FLAG_THIS_UNINIT;
271 }
272 return VerificationType.uninitialized_this_type;
273 }
274 if (tag == ITEM_UNINITIALIZED) {
275 int offset = _stream.get_u2();
276 if (offset >= _code_length || _code_data[offset] != VerifierImpl.NEW_OFFSET) {
277 _verifier.classError("StackMapTable format error: bad offset for Uninitialized");
278 }
279 return VerificationType.uninitialized_type(offset);
280 }
281 _verifier.classError("bad verification type");
282 return VerificationType.bogus_type;
283 }
284
285 VerificationFrame next_helper() {
286 VerificationFrame frame;
287 int offset;
288 VerificationType[] locals = null;
289 int frame_type = _stream.get_u1();
290 if (frame_type == EARLY_LARVAL) {
291 int num_unset_fields = _stream.get_u2();
292 Set<NameAndTypeEntry> new_fields = new HashSet<>();
293 for (int i = 0; i < num_unset_fields; i++) {
294 int index = _stream.get_u2();
295 if (!_cp.is_within_bounds(index) || _cp.tagAt(index) != VerifierImpl.JVM_CONSTANT_NameAndType) {
296 _prev_frame.verifier().verifyError("Invalid use of strict instance fields %d %s %s".formatted(_prev_frame.offset(), _prev_frame,
297 "Invalid constant pool index in early larval frame: %d".formatted(index)));
298 }
299 var tmp = _cp.cp.entryByIndex(index, NameAndTypeEntry.class);
300 if (!strictFields.contains(tmp)) {
301 _prev_frame.verifier().verifyError("Invalid use of strict instance fields %d %s %s".formatted(_prev_frame.offset(), _prev_frame,
302 "Strict fields not a subset of initial strict instance fields: %s".formatted(tmp)));
303 } else {
304 new_fields.add(tmp);
305 }
306 }
307 // Only modify strict instance fields the frame has uninitialized this
308 if (_prev_frame.flag_this_uninit()) {
309 _assert_unset_fields_buffer = _prev_frame.merge_unset_fields(new_fields);
310 } else if (!new_fields.isEmpty()) {
311 _prev_frame.verifier().verifyError("Invalid use of strict instance fields %d %s %s".formatted(_prev_frame.offset(), _prev_frame,
312 "Cannot have uninitialized strict fields after class initialization"));
313 }
314 // Continue reading frame data
315 if (at_end()) {
316 _prev_frame.verifier().verifyError("Invalid use of strict instance fields %d %s %s".formatted(_prev_frame.offset(), _prev_frame,
317 "Early larval frame must be followed by a base frame"));
318 }
319 frame_type = _stream.get_u1();
320 if (frame_type == EARLY_LARVAL) {
321 _prev_frame.verifier().verifyError("Invalid use of strict instance fields %d %s %s".formatted(_prev_frame.offset(), _prev_frame,
322 "Early larval frame must be followed by a base frame"));
323 }
324 }
325 if (frame_type <= SAME_FRAME_END) {
326 if (_first) {
327 offset = frame_type;
328 if (_prev_frame.locals_size() > 0) {
329 locals = new VerificationType[_prev_frame.locals_size()];
330 }
331 } else {
332 offset = _prev_frame.offset() + frame_type + 1;
333 locals = _prev_frame.locals();
334 }
335 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), 0, _max_locals, _max_stack, locals, null, _assert_unset_fields_buffer, _verifier);
336 if (_first && locals != null) {
337 frame.copy_locals(_prev_frame);
338 }
339 _first = false;
340 return frame;
341 }
342 if (frame_type <= SAME_LOCALS_1_STACK_ITEM_FRAME_END) {
343 if (_first) {
344 offset = frame_type - SAME_LOCALS_1_STACK_ITEM_FRAME_START;
345 if (_prev_frame.locals_size() > 0) {
346 locals = new VerificationType[_prev_frame.locals_size()];
347 }
348 } else {
349 offset = _prev_frame.offset() + frame_type - SAME_LOCALS_1_STACK_ITEM_FRAME_START + 1;
350 locals = _prev_frame.locals();
351 }
352 VerificationType[] stack = new VerificationType[2];
353 int stack_size = 1;
354 stack[0] = parse_verification_type(null);
355 if (stack[0].is_category2()) {
356 stack[1] = stack[0].to_category2_2nd(_verifier);
357 stack_size = 2;
358 }
359 check_verification_type_array_size(stack_size, _max_stack);
360 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), stack_size, _max_locals, _max_stack, locals, stack, _assert_unset_fields_buffer, _verifier);
361 if (_first && locals != null) {
362 frame.copy_locals(_prev_frame);
363 }
364 _first = false;
365 return frame;
366 }
367 int offset_delta = _stream.get_u2();
368 if (frame_type <= RESERVED_END) {
369 _verifier.classError("reserved frame type");
370 }
371 if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
372 if (_first) {
373 offset = offset_delta;
374 if (_prev_frame.locals_size() > 0) {
375 locals = new VerificationType[_prev_frame.locals_size()];
376 }
377 } else {
378 offset = _prev_frame.offset() + offset_delta + 1;
379 locals = _prev_frame.locals();
380 }
381 VerificationType[] stack = new VerificationType[2];
382 int stack_size = 1;
383 stack[0] = parse_verification_type(null);
384 if (stack[0].is_category2()) {
385 stack[1] = stack[0].to_category2_2nd(_verifier);
386 stack_size = 2;
387 }
388 check_verification_type_array_size(stack_size, _max_stack);
389 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), stack_size, _max_locals, _max_stack, locals, stack, _assert_unset_fields_buffer, _verifier);
390 if (_first && locals != null) {
391 frame.copy_locals(_prev_frame);
392 }
393 _first = false;
394 return frame;
395 }
396 if (frame_type <= SAME_FRAME_EXTENDED) {
397 locals = _prev_frame.locals();
398 int length = _prev_frame.locals_size();
399 int chops = SAME_FRAME_EXTENDED - frame_type;
400 int new_length = length;
401 int flags = _prev_frame.flags();
402 if (chops != 0) {
403 new_length = chop(locals, length, chops);
404 check_verification_type_array_size(new_length, _max_locals);
405 flags = 0;
406 for (int i=0; i<new_length; i++) {
407 if (locals[i].is_uninitialized_this(_verifier)) {
408 flags |= VerificationFrame.FLAG_THIS_UNINIT;
409 break;
410 }
411 }
412 }
413 if (_first) {
414 offset = offset_delta;
415 if (new_length > 0) {
416 locals = new VerificationType[new_length];
417 } else {
418 locals = null;
419 }
420 } else {
421 offset = _prev_frame.offset() + offset_delta + 1;
422 }
423 frame = new VerificationFrame(offset, flags, new_length, 0, _max_locals, _max_stack, locals, null, _assert_unset_fields_buffer, _verifier);
424 if (_first && locals != null) {
425 frame.copy_locals(_prev_frame);
426 }
427 _first = false;
428 return frame;
429 } else if (frame_type <= APPEND_FRAME_END) {
430 int appends = frame_type - APPEND_FRAME_START + 1;
431 int real_length = _prev_frame.locals_size();
432 int new_length = real_length + appends*2;
433 locals = new VerificationType[new_length];
434 VerificationType[] pre_locals = _prev_frame.locals();
435 int i;
436 for (i=0; i< _prev_frame.locals_size(); i++) {
437 locals[i] = pre_locals[i];
438 }
439 int[] flags = new int[]{_prev_frame.flags()};
440 for (i=0; i<appends; i++) {
441 locals[real_length] = parse_verification_type(flags);
442 if (locals[real_length].is_category2()) {
443 locals[real_length + 1] = locals[real_length].to_category2_2nd(_verifier);
444 ++real_length;
445 }
446 ++real_length;
447 }
448 check_verification_type_array_size(real_length, _max_locals);
449 if (_first) {
450 offset = offset_delta;
451 } else {
452 offset = _prev_frame.offset() + offset_delta + 1;
453 }
454 frame = new VerificationFrame(offset, flags[0], real_length, 0, _max_locals, _max_stack, locals, null, _assert_unset_fields_buffer, _verifier);
455 _first = false;
456 return frame;
457 }
458 if (frame_type == FULL_FRAME) {
459 int flags[] = new int[]{0};
460 int locals_size = _stream.get_u2();
461 int real_locals_size = 0;
462 if (locals_size > 0) {
463 locals = new VerificationType[locals_size*2];
464 }
465 int i;
466 for (i=0; i<locals_size; i++) {
467 locals[real_locals_size] = parse_verification_type(flags);
468 if (locals[real_locals_size].is_category2()) {
469 locals[real_locals_size + 1] =
470 locals[real_locals_size].to_category2_2nd(_verifier);
471 ++real_locals_size;
472 }
473 ++real_locals_size;
474 }
476 int stack_size = _stream.get_u2();
477 int real_stack_size = 0;
478 VerificationType[] stack = null;
479 if (stack_size > 0) {
480 stack = new VerificationType[stack_size*2];
481 }
482 for (i=0; i<stack_size; i++) {
483 stack[real_stack_size] = parse_verification_type(null);
484 if (stack[real_stack_size].is_category2()) {
485 stack[real_stack_size + 1] = stack[real_stack_size].to_category2_2nd(_verifier);
486 ++real_stack_size;
487 }
488 ++real_stack_size;
489 }
490 check_verification_type_array_size(real_stack_size, _max_stack);
491 if (_first) {
492 offset = offset_delta;
493 } else {
494 offset = _prev_frame.offset() + offset_delta + 1;
495 }
496 frame = new VerificationFrame(offset, flags[0], real_locals_size, real_stack_size, _max_locals, _max_stack, locals, stack, _assert_unset_fields_buffer, _verifier);
497 _first = false;
498 return frame;
499 }
500 _verifier.classError("reserved frame type");
501 return null;
502 }
503 }
504 }
|