< prev index next >

src/java.base/share/classes/jdk/internal/classfile/impl/verifier/VerificationTable.java

Print this page

  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.verifier.VerificationType.ITEM_Object;
 31 import static jdk.internal.classfile.impl.verifier.VerificationType.ITEM_Uninitialized;
 32 import static jdk.internal.classfile.impl.verifier.VerificationType.ITEM_UninitializedThis;
 33 
 34 /// From `stackMapTable.cpp`.
 35 class VerificationTable {
 36 
 37     private final int _code_length;
 38     private final int _frame_count;
 39     private final List<VerificationFrame> _frame_array;
 40     private final VerifierImpl _verifier;
 41 
 42     int get_frame_count() {
 43         return _frame_count;
 44     }
 45 
 46     int get_offset(int index) {
 47         return _frame_array.get(index).offset();
 48     }

112     boolean match_stackmap(VerificationFrame frame, int target, int frame_index, boolean match, boolean update) {
113         if (frame_index < 0 || frame_index >= _frame_count) {
114             _verifier.verifyError(String.format("Expecting a stackmap frame at branch target %d", target));
115         }
116         VerificationFrame stackmap_frame = _frame_array.get(frame_index);
117         boolean result = true;
118         if (match) {
119             result = frame.is_assignable_to(stackmap_frame);
120         }
121         if (update) {
122             int lsize = stackmap_frame.locals_size();
123             int ssize = stackmap_frame.stack_size();
124             if (frame.locals_size() > lsize || frame.stack_size() > ssize) {
125                 frame.reset();
126             }
127             frame.set_locals_size(lsize);
128             frame.copy_locals(stackmap_frame);
129             frame.set_stack_size(ssize);
130             frame.copy_stack(stackmap_frame);
131             frame.set_flags(stackmap_frame.flags());

132         }
133         return result;
134     }
135 
136     void check_jump_target(VerificationFrame frame, int target) {
137         boolean match = match_stackmap(frame, target, true, false);
138         if (!match || (target < 0 || target >= _code_length)) {
139             _verifier.verifyError(String.format("Inconsistent stackmap frames at branch target %d", target));
140         }
141     }
142 
143     static class StackMapReader {
144 
145         private final VerificationWrapper.ConstantPoolWrapper _cp;
146         private final StackMapStream _stream;
147         private final byte[] _code_data;
148         private final int _code_length;
149         private final int _frame_count;
150         private int _parsed_frame_count;
151         private VerificationFrame _prev_frame;
152         char _max_locals, _max_stack;


153         boolean _first;
154 
155         void check_verification_type_array_size(int size, int max_size) {
156             if (size < 0 || size > max_size) {
157                 _verifier.classError("StackMapTable format error: bad type array size");
158             }
159         }
160 
161         private static final int

162                         SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247,
163                         SAME_EXTENDED = 251,
164                         FULL = 255;

165 
166         public int get_frame_count() {
167             return _frame_count;
168         }
169 
170         public VerificationFrame prev_frame() {
171             return _prev_frame;
172         }
173 
174         public byte[] code_data() {
175             return _code_data;
176         }
177 
178         public int code_length() {
179             return _code_length;
180         }
181 
182         public boolean at_end() {
183             return _stream.at_end();
184         }

187             _parsed_frame_count++;
188             check_size();
189             VerificationFrame frame = next_helper();
190             if (frame != null) {
191                 check_offset(frame);
192                 _prev_frame = frame;
193             }
194             return frame;
195         }
196 
197         public void check_end() {
198             if (_frame_count != _parsed_frame_count) {
199                 _verifier.verifyError("wrong attribute size");
200             }
201         }
202 
203         private final VerifierImpl _verifier;
204 
205         public StackMapReader(byte[] stackmapData, byte[] code_data, int code_len,
206                               VerificationFrame init_frame, char max_locals, char max_stack,

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             _first = true;
217             if (stackmapData != null) {
218                 _cp = cp;
219                 _frame_count = _stream.get_u2();
220             } else {
221                 _cp = null;
222                 _frame_count = 0;
223             }
224         }
225 
226         void check_offset(VerificationFrame frame) {
227             int offset = frame.offset();
228             if (offset >= _code_length || _code_data[offset] == 0) {
229                 _verifier.verifyError("StackMapTable error: bad offset");
230             }
231         }
232 
233         void check_size() {
234             if (_frame_count < _parsed_frame_count) {
235                 _verifier.verifyError("wrong attribute size");

268                     flags[0] |= VerificationFrame.FLAG_THIS_UNINIT;
269                 }
270                 return VerificationType.uninitialized_this_type;
271             }
272             if (tag == ITEM_Uninitialized) {
273                 int offset = _stream.get_u2();
274                 if (offset >= _code_length || _code_data[offset] != VerifierImpl.NEW_OFFSET) {
275                     _verifier.classError("StackMapTable format error: bad offset for Uninitialized");
276                 }
277                 return VerificationType.uninitialized_type(offset);
278             }
279             _verifier.classError("bad verification type");
280             return VerificationType.bogus_type;
281         }
282 
283         VerificationFrame next_helper() {
284             VerificationFrame frame;
285             int offset;
286             VerificationType[] locals = null;
287             int frame_type = _stream.get_u1();



































288             if (frame_type < 64) {
289                 if (_first) {
290                     offset = frame_type;
291                     if (_prev_frame.locals_size() > 0) {
292                         locals = new VerificationType[_prev_frame.locals_size()];
293                     }
294                 } else {
295                     offset = _prev_frame.offset() + frame_type + 1;
296                     locals = _prev_frame.locals();
297                 }
298                 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), 0, _max_locals, _max_stack, locals, null, _verifier);
299                 if (_first && locals != null) {
300                     frame.copy_locals(_prev_frame);
301                 }
302                 _first = false;
303                 return frame;
304             }
305             if (frame_type < 128) {
306                 if (_first) {
307                     offset = frame_type - 64;
308                     if (_prev_frame.locals_size() > 0) {
309                         locals = new VerificationType[_prev_frame.locals_size()];
310                     }
311                 } else {
312                     offset = _prev_frame.offset() + frame_type - 63;
313                     locals = _prev_frame.locals();
314                 }
315                 VerificationType[] stack = new VerificationType[2];
316                 int stack_size = 1;
317                 stack[0] = parse_verification_type(null);
318                 if (stack[0].is_category2()) {
319                     stack[1] = stack[0].to_category2_2nd(_verifier);
320                     stack_size = 2;
321                 }
322                 check_verification_type_array_size(stack_size, _max_stack);
323                 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), stack_size, _max_locals, _max_stack, locals, stack, _verifier);
324                 if (_first && locals != null) {
325                     frame.copy_locals(_prev_frame);
326                 }
327                 _first = false;
328                 return frame;
329             }
330             int offset_delta = _stream.get_u2();
331             if (frame_type < SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
332                 _verifier.classError("reserved frame type");
333             }
334             if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
335                 if (_first) {
336                     offset = offset_delta;
337                     if (_prev_frame.locals_size() > 0) {
338                         locals = new VerificationType[_prev_frame.locals_size()];
339                     }
340                 } else {
341                     offset = _prev_frame.offset() + offset_delta + 1;
342                     locals = _prev_frame.locals();
343                 }
344                 VerificationType[] stack = new VerificationType[2];
345                 int stack_size = 1;
346                 stack[0] = parse_verification_type(null);
347                 if (stack[0].is_category2()) {
348                     stack[1] = stack[0].to_category2_2nd(_verifier);
349                     stack_size = 2;
350                 }
351                 check_verification_type_array_size(stack_size, _max_stack);
352                 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), stack_size, _max_locals, _max_stack, locals, stack, _verifier);
353                 if (_first && locals != null) {
354                     frame.copy_locals(_prev_frame);
355                 }
356                 _first = false;
357                 return frame;
358             }
359             if (frame_type <= SAME_EXTENDED) {
360                 locals = _prev_frame.locals();
361                 int length = _prev_frame.locals_size();
362                 int chops = SAME_EXTENDED - frame_type;
363                 int new_length = length;
364                 int flags = _prev_frame.flags();
365                 if (chops != 0) {
366                     new_length = chop(locals, length, chops);
367                     check_verification_type_array_size(new_length, _max_locals);
368                     flags = 0;
369                     for (int i=0; i<new_length; i++) {
370                         if (locals[i].is_uninitialized_this(_verifier)) {
371                             flags |= VerificationFrame.FLAG_THIS_UNINIT;
372                             break;
373                         }
374                     }
375                 }
376                 if (_first) {
377                     offset = offset_delta;
378                     if (new_length > 0) {
379                         locals = new VerificationType[new_length];
380                     } else {
381                         locals = null;
382                     }
383                 } else {
384                     offset = _prev_frame.offset() + offset_delta + 1;
385                 }
386                 frame = new VerificationFrame(offset, flags, new_length, 0, _max_locals, _max_stack, locals, null, _verifier);
387                 if (_first && locals != null) {
388                     frame.copy_locals(_prev_frame);
389                 }
390                 _first = false;
391                 return frame;
392             } else if (frame_type < SAME_EXTENDED + 4) {
393                 int appends = frame_type - SAME_EXTENDED;
394                 int real_length = _prev_frame.locals_size();
395                 int new_length = real_length + appends*2;
396                 locals = new VerificationType[new_length];
397                 VerificationType[] pre_locals = _prev_frame.locals();
398                 int i;
399                 for (i=0; i< _prev_frame.locals_size(); i++) {
400                     locals[i] = pre_locals[i];
401                 }
402                 int[] flags = new int[]{_prev_frame.flags()};
403                 for (i=0; i<appends; i++) {
404                     locals[real_length] = parse_verification_type(flags);
405                     if (locals[real_length].is_category2()) {
406                         locals[real_length + 1] = locals[real_length].to_category2_2nd(_verifier);
407                         ++real_length;
408                     }
409                     ++real_length;
410                 }
411                 check_verification_type_array_size(real_length, _max_locals);
412                 if (_first) {
413                     offset = offset_delta;
414                 } else {
415                     offset = _prev_frame.offset() + offset_delta + 1;
416                 }
417                 frame = new VerificationFrame(offset, flags[0], real_length, 0, _max_locals, _max_stack, locals, null, _verifier);
418                 _first = false;
419                 return frame;
420             }
421             if (frame_type == FULL) {
422                 int flags[] = new int[]{0};
423                 int locals_size = _stream.get_u2();
424                 int real_locals_size = 0;
425                 if (locals_size > 0) {
426                     locals = new VerificationType[locals_size*2];
427                 }
428                 int i;
429                 for (i=0; i<locals_size; i++) {
430                     locals[real_locals_size] = parse_verification_type(flags);
431                     if (locals[real_locals_size].is_category2()) {
432                         locals[real_locals_size + 1] =
433                                 locals[real_locals_size].to_category2_2nd(_verifier);
434                         ++real_locals_size;
435                     }
436                     ++real_locals_size;
437                 }

439                 int stack_size = _stream.get_u2();
440                 int real_stack_size = 0;
441                 VerificationType[] stack = null;
442                 if (stack_size > 0) {
443                     stack = new VerificationType[stack_size*2];
444                 }
445                 for (i=0; i<stack_size; i++) {
446                     stack[real_stack_size] = parse_verification_type(null);
447                     if (stack[real_stack_size].is_category2()) {
448                         stack[real_stack_size + 1] = stack[real_stack_size].to_category2_2nd(_verifier);
449                         ++real_stack_size;
450                     }
451                     ++real_stack_size;
452                 }
453                 check_verification_type_array_size(real_stack_size, _max_stack);
454                 if (_first) {
455                     offset = offset_delta;
456                 } else {
457                     offset = _prev_frame.offset() + offset_delta + 1;
458                 }
459                 frame = new VerificationFrame(offset, flags[0], real_locals_size, real_stack_size, _max_locals, _max_stack, locals, stack, _verifier);
460                 _first = false;
461                 return frame;
462             }
463             _verifier.classError("reserved frame type");
464             return null;
465         }
466     }
467 }

  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.verifier.VerificationType.ITEM_Object;
 34 import static jdk.internal.classfile.impl.verifier.VerificationType.ITEM_Uninitialized;
 35 import static jdk.internal.classfile.impl.verifier.VerificationType.ITEM_UninitializedThis;
 36 
 37 /// From `stackMapTable.cpp`.
 38 class VerificationTable {
 39 
 40     private final int _code_length;
 41     private final int _frame_count;
 42     private final List<VerificationFrame> _frame_array;
 43     private final VerifierImpl _verifier;
 44 
 45     int get_frame_count() {
 46         return _frame_count;
 47     }
 48 
 49     int get_offset(int index) {
 50         return _frame_array.get(index).offset();
 51     }

115     boolean match_stackmap(VerificationFrame frame, int target, int frame_index, boolean match, boolean update) {
116         if (frame_index < 0 || frame_index >= _frame_count) {
117             _verifier.verifyError(String.format("Expecting a stackmap frame at branch target %d", target));
118         }
119         VerificationFrame stackmap_frame = _frame_array.get(frame_index);
120         boolean result = true;
121         if (match) {
122             result = frame.is_assignable_to(stackmap_frame);
123         }
124         if (update) {
125             int lsize = stackmap_frame.locals_size();
126             int ssize = stackmap_frame.stack_size();
127             if (frame.locals_size() > lsize || frame.stack_size() > ssize) {
128                 frame.reset();
129             }
130             frame.set_locals_size(lsize);
131             frame.copy_locals(stackmap_frame);
132             frame.set_stack_size(ssize);
133             frame.copy_stack(stackmap_frame);
134             frame.set_flags(stackmap_frame.flags());
135             frame.set_assert_unset_fields(stackmap_frame.assert_unset_fields());
136         }
137         return result;
138     }
139 
140     void check_jump_target(VerificationFrame frame, int target) {
141         boolean match = match_stackmap(frame, target, true, false);
142         if (!match || (target < 0 || target >= _code_length)) {
143             _verifier.verifyError(String.format("Inconsistent stackmap frames at branch target %d", target));
144         }
145     }
146 
147     static class StackMapReader {
148 
149         private final VerificationWrapper.ConstantPoolWrapper _cp;
150         private final StackMapStream _stream;
151         private final byte[] _code_data;
152         private final int _code_length;
153         private final int _frame_count;
154         private int _parsed_frame_count;
155         private VerificationFrame _prev_frame;
156         char _max_locals, _max_stack;
157         final Set<NameAndTypeEntry> strictFields;
158         Set<NameAndTypeEntry> _assert_unset_fields_buffer;
159         boolean _first;
160 
161         void check_verification_type_array_size(int size, int max_size) {
162             if (size < 0 || size > max_size) {
163                 _verifier.classError("StackMapTable format error: bad type array size");
164             }
165         }
166 
167         private static final int
168                         EARLY_LARVAL = 246,
169                         SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247,
170                         SAME_EXTENDED = 251,
171                         FULL = 255;
172         private static final int RESERVED_TAGS_UPPER_LIMIT = EARLY_LARVAL; // not inclusive
173 
174         public int get_frame_count() {
175             return _frame_count;
176         }
177 
178         public VerificationFrame prev_frame() {
179             return _prev_frame;
180         }
181 
182         public byte[] code_data() {
183             return _code_data;
184         }
185 
186         public int code_length() {
187             return _code_length;
188         }
189 
190         public boolean at_end() {
191             return _stream.at_end();
192         }

195             _parsed_frame_count++;
196             check_size();
197             VerificationFrame frame = next_helper();
198             if (frame != null) {
199                 check_offset(frame);
200                 _prev_frame = frame;
201             }
202             return frame;
203         }
204 
205         public void check_end() {
206             if (_frame_count != _parsed_frame_count) {
207                 _verifier.verifyError("wrong attribute size");
208             }
209         }
210 
211         private final VerifierImpl _verifier;
212 
213         public StackMapReader(byte[] stackmapData, byte[] code_data, int code_len,
214                               VerificationFrame init_frame, char max_locals, char max_stack,
215                               Set<NameAndTypeEntry> initial_strict_fields,
216                               VerificationWrapper.ConstantPoolWrapper cp, VerifierImpl context) {
217             this._verifier = context;
218             _stream = new StackMapStream(stackmapData, _verifier);
219             _code_data = code_data;
220             _code_length = code_len;
221             _parsed_frame_count = 0;
222             _prev_frame = init_frame;
223             _max_locals = max_locals;
224             _max_stack = max_stack;
225             strictFields = Set.copyOf(initial_strict_fields);
226             _assert_unset_fields_buffer = initial_strict_fields;
227             _first = true;
228             if (stackmapData != null) {
229                 _cp = cp;
230                 _frame_count = _stream.get_u2();
231             } else {
232                 _cp = null;
233                 _frame_count = 0;
234             }
235         }
236 
237         void check_offset(VerificationFrame frame) {
238             int offset = frame.offset();
239             if (offset >= _code_length || _code_data[offset] == 0) {
240                 _verifier.verifyError("StackMapTable error: bad offset");
241             }
242         }
243 
244         void check_size() {
245             if (_frame_count < _parsed_frame_count) {
246                 _verifier.verifyError("wrong attribute size");

279                     flags[0] |= VerificationFrame.FLAG_THIS_UNINIT;
280                 }
281                 return VerificationType.uninitialized_this_type;
282             }
283             if (tag == ITEM_Uninitialized) {
284                 int offset = _stream.get_u2();
285                 if (offset >= _code_length || _code_data[offset] != VerifierImpl.NEW_OFFSET) {
286                     _verifier.classError("StackMapTable format error: bad offset for Uninitialized");
287                 }
288                 return VerificationType.uninitialized_type(offset);
289             }
290             _verifier.classError("bad verification type");
291             return VerificationType.bogus_type;
292         }
293 
294         VerificationFrame next_helper() {
295             VerificationFrame frame;
296             int offset;
297             VerificationType[] locals = null;
298             int frame_type = _stream.get_u1();
299             if (frame_type == EARLY_LARVAL) {
300                 int num_unset_fields = _stream.get_u2();
301                 Set<NameAndTypeEntry> new_fields = new HashSet<>();
302                 for (int i = 0; i < num_unset_fields; i++) {
303                     int index = _stream.get_u2();
304                     if (!_cp.is_within_bounds(index) || _cp.tagAt(index) != VerifierImpl.JVM_CONSTANT_NameAndType) {
305                         _prev_frame.verifier().verifyError("Invalid use of strict instance fields %d %s %s".formatted(_prev_frame.offset(), _prev_frame,
306                                 "Invalid constant pool index in early larval frame: %d".formatted(index)));
307                     }
308                     var tmp = _cp.cp.entryByIndex(index, NameAndTypeEntry.class);
309                     if (!strictFields.contains(tmp)) {
310                         _prev_frame.verifier().verifyError("Invalid use of strict instance fields %d %s %s".formatted(_prev_frame.offset(), _prev_frame,
311                                 "Strict fields not a subset of initial strict instance fields: %s".formatted(tmp)));
312                     } else {
313                         new_fields.add(tmp);
314                     }
315                 }
316                 // Only modify strict instance fields the frame has uninitialized this
317                 if (_prev_frame.flag_this_uninit()) {
318                     _assert_unset_fields_buffer = _prev_frame.merge_unset_fields(new_fields);
319                 } else if (!new_fields.isEmpty()) {
320                     _prev_frame.verifier().verifyError("Invalid use of strict instance fields %d %s %s".formatted(_prev_frame.offset(), _prev_frame,
321                             "Cannot have uninitialized strict fields after class initialization"));
322                 }
323                 // Continue reading frame data
324                 if (at_end()) {
325                     _prev_frame.verifier().verifyError("Invalid use of strict instance fields %d %s %s".formatted(_prev_frame.offset(), _prev_frame,
326                             "Early larval frame must be followed by a base frame"));
327                 }
328                 frame_type = _stream.get_u1();
329                 if (frame_type == EARLY_LARVAL) {
330                     _prev_frame.verifier().verifyError("Invalid use of strict instance fields %d %s %s".formatted(_prev_frame.offset(), _prev_frame,
331                             "Early larval frame must be followed by a base frame"));
332                 }
333             }
334             if (frame_type < 64) {
335                 if (_first) {
336                     offset = frame_type;
337                     if (_prev_frame.locals_size() > 0) {
338                         locals = new VerificationType[_prev_frame.locals_size()];
339                     }
340                 } else {
341                     offset = _prev_frame.offset() + frame_type + 1;
342                     locals = _prev_frame.locals();
343                 }
344                 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), 0, _max_locals, _max_stack, locals, null, _assert_unset_fields_buffer, _verifier);
345                 if (_first && locals != null) {
346                     frame.copy_locals(_prev_frame);
347                 }
348                 _first = false;
349                 return frame;
350             }
351             if (frame_type < 128) {
352                 if (_first) {
353                     offset = frame_type - 64;
354                     if (_prev_frame.locals_size() > 0) {
355                         locals = new VerificationType[_prev_frame.locals_size()];
356                     }
357                 } else {
358                     offset = _prev_frame.offset() + frame_type - 63;
359                     locals = _prev_frame.locals();
360                 }
361                 VerificationType[] stack = new VerificationType[2];
362                 int stack_size = 1;
363                 stack[0] = parse_verification_type(null);
364                 if (stack[0].is_category2()) {
365                     stack[1] = stack[0].to_category2_2nd(_verifier);
366                     stack_size = 2;
367                 }
368                 check_verification_type_array_size(stack_size, _max_stack);
369                 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), stack_size, _max_locals, _max_stack, locals, stack, _assert_unset_fields_buffer, _verifier);
370                 if (_first && locals != null) {
371                     frame.copy_locals(_prev_frame);
372                 }
373                 _first = false;
374                 return frame;
375             }
376             int offset_delta = _stream.get_u2();
377             if (frame_type < RESERVED_TAGS_UPPER_LIMIT) {
378                 _verifier.classError("reserved frame type");
379             }
380             if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
381                 if (_first) {
382                     offset = offset_delta;
383                     if (_prev_frame.locals_size() > 0) {
384                         locals = new VerificationType[_prev_frame.locals_size()];
385                     }
386                 } else {
387                     offset = _prev_frame.offset() + offset_delta + 1;
388                     locals = _prev_frame.locals();
389                 }
390                 VerificationType[] stack = new VerificationType[2];
391                 int stack_size = 1;
392                 stack[0] = parse_verification_type(null);
393                 if (stack[0].is_category2()) {
394                     stack[1] = stack[0].to_category2_2nd(_verifier);
395                     stack_size = 2;
396                 }
397                 check_verification_type_array_size(stack_size, _max_stack);
398                 frame = new VerificationFrame(offset, _prev_frame.flags(), _prev_frame.locals_size(), stack_size, _max_locals, _max_stack, locals, stack, _assert_unset_fields_buffer, _verifier);
399                 if (_first && locals != null) {
400                     frame.copy_locals(_prev_frame);
401                 }
402                 _first = false;
403                 return frame;
404             }
405             if (frame_type <= SAME_EXTENDED) {
406                 locals = _prev_frame.locals();
407                 int length = _prev_frame.locals_size();
408                 int chops = SAME_EXTENDED - frame_type;
409                 int new_length = length;
410                 int flags = _prev_frame.flags();
411                 if (chops != 0) {
412                     new_length = chop(locals, length, chops);
413                     check_verification_type_array_size(new_length, _max_locals);
414                     flags = 0;
415                     for (int i=0; i<new_length; i++) {
416                         if (locals[i].is_uninitialized_this(_verifier)) {
417                             flags |= VerificationFrame.FLAG_THIS_UNINIT;
418                             break;
419                         }
420                     }
421                 }
422                 if (_first) {
423                     offset = offset_delta;
424                     if (new_length > 0) {
425                         locals = new VerificationType[new_length];
426                     } else {
427                         locals = null;
428                     }
429                 } else {
430                     offset = _prev_frame.offset() + offset_delta + 1;
431                 }
432                 frame = new VerificationFrame(offset, flags, new_length, 0, _max_locals, _max_stack, locals, null, _assert_unset_fields_buffer, _verifier);
433                 if (_first && locals != null) {
434                     frame.copy_locals(_prev_frame);
435                 }
436                 _first = false;
437                 return frame;
438             } else if (frame_type < SAME_EXTENDED + 4) {
439                 int appends = frame_type - SAME_EXTENDED;
440                 int real_length = _prev_frame.locals_size();
441                 int new_length = real_length + appends*2;
442                 locals = new VerificationType[new_length];
443                 VerificationType[] pre_locals = _prev_frame.locals();
444                 int i;
445                 for (i=0; i< _prev_frame.locals_size(); i++) {
446                     locals[i] = pre_locals[i];
447                 }
448                 int[] flags = new int[]{_prev_frame.flags()};
449                 for (i=0; i<appends; i++) {
450                     locals[real_length] = parse_verification_type(flags);
451                     if (locals[real_length].is_category2()) {
452                         locals[real_length + 1] = locals[real_length].to_category2_2nd(_verifier);
453                         ++real_length;
454                     }
455                     ++real_length;
456                 }
457                 check_verification_type_array_size(real_length, _max_locals);
458                 if (_first) {
459                     offset = offset_delta;
460                 } else {
461                     offset = _prev_frame.offset() + offset_delta + 1;
462                 }
463                 frame = new VerificationFrame(offset, flags[0], real_length, 0, _max_locals, _max_stack, locals, null, _assert_unset_fields_buffer, _verifier);
464                 _first = false;
465                 return frame;
466             }
467             if (frame_type == FULL) {
468                 int flags[] = new int[]{0};
469                 int locals_size = _stream.get_u2();
470                 int real_locals_size = 0;
471                 if (locals_size > 0) {
472                     locals = new VerificationType[locals_size*2];
473                 }
474                 int i;
475                 for (i=0; i<locals_size; i++) {
476                     locals[real_locals_size] = parse_verification_type(flags);
477                     if (locals[real_locals_size].is_category2()) {
478                         locals[real_locals_size + 1] =
479                                 locals[real_locals_size].to_category2_2nd(_verifier);
480                         ++real_locals_size;
481                     }
482                     ++real_locals_size;
483                 }

485                 int stack_size = _stream.get_u2();
486                 int real_stack_size = 0;
487                 VerificationType[] stack = null;
488                 if (stack_size > 0) {
489                     stack = new VerificationType[stack_size*2];
490                 }
491                 for (i=0; i<stack_size; i++) {
492                     stack[real_stack_size] = parse_verification_type(null);
493                     if (stack[real_stack_size].is_category2()) {
494                         stack[real_stack_size + 1] = stack[real_stack_size].to_category2_2nd(_verifier);
495                         ++real_stack_size;
496                     }
497                     ++real_stack_size;
498                 }
499                 check_verification_type_array_size(real_stack_size, _max_stack);
500                 if (_first) {
501                     offset = offset_delta;
502                 } else {
503                     offset = _prev_frame.offset() + offset_delta + 1;
504                 }
505                 frame = new VerificationFrame(offset, flags[0], real_locals_size, real_stack_size, _max_locals, _max_stack, locals, stack, _assert_unset_fields_buffer, _verifier);
506                 _first = false;
507                 return frame;
508             }
509             _verifier.classError("reserved frame type");
510             return null;
511         }
512     }
513 }
< prev index next >