126 if (classReader.context().passLineNumbers())
127 inflateLineNumbers();
128 inflateJumpTargets();
129 inflateTypeAnnotations();
130 inflated = true;
131 }
132 }
133
134 // CodeAttribute
135
136 @Override
137 public List<Attribute<?>> attributes() {
138 if (attributes == null) {
139 attributes = BoundAttribute.readAttributes(this, classReader, attributePos, classReader.customAttributes());
140 }
141 return attributes;
142 }
143
144 @Override
145 public void writeTo(BufWriterImpl buf) {
146 if (buf.canWriteDirect(classReader)) {
147 super.writeTo(buf);
148 }
149 else {
150 DirectCodeBuilder.build((MethodInfo) enclosingMethod,
151 Util.writingAll(this),
152 (SplitConstantPool)buf.constantPool(),
153 buf.context(),
154 null).writeTo(buf);
155 }
156 }
157
158 // CodeModel
159
160 @Override
161 public Optional<MethodModel> parent() {
162 return Optional.of(enclosingMethod);
163 }
164
165 @Override
166 public void forEach(Consumer<? super CodeElement> consumer) {
167 Objects.requireNonNull(consumer);
168 inflateMetadata();
169 boolean doLineNumbers = (lineNumbers != null);
170 generateCatchTargets(consumer);
275 }
276 case TABLE_SWITCH -> {
277 var ts = (TableSwitchInstruction) i;
278 ts.defaultTarget();
279 ts.cases();
280 }
281 default -> {}
282 }
283 pos += i.sizeInBytes();
284 }
285 }
286 return;
287 }
288 int stackMapPos = ((BoundAttribute<StackMapTableAttribute>) a.get()).payloadStart;
289
290 int bci = -1; //compensate for offsetDelta + 1
291 int nEntries = classReader.readU2(stackMapPos);
292 int p = stackMapPos + 2;
293 for (int i = 0; i < nEntries; ++i) {
294 int frameType = classReader.readU1(p);
295 int offsetDelta;
296 if (frameType <= SAME_FRAME_END) {
297 offsetDelta = frameType;
298 ++p;
299 }
300 else if (frameType <= SAME_LOCALS_1_STACK_ITEM_FRAME_END) {
301 offsetDelta = frameType & 0x3f;
302 p = adjustForObjectOrUninitialized(p + 1);
303 }
304 else
305 switch (frameType) {
306 case SAME_LOCALS_1_STACK_ITEM_EXTENDED -> {
307 offsetDelta = classReader.readU2(p + 1);
308 p = adjustForObjectOrUninitialized(p + 3);
309 }
310 case CHOP_FRAME_START, CHOP_FRAME_START + 1, CHOP_FRAME_END, SAME_FRAME_EXTENDED -> {
311 offsetDelta = classReader.readU2(p + 1);
312 p += 3;
313 }
314 case APPEND_FRAME_START, APPEND_FRAME_START + 1, APPEND_FRAME_END -> {
315 offsetDelta = classReader.readU2(p + 1);
316 int k = frameType - APPEND_FRAME_START + 1;
317 p += 3;
318 for (int c = 0; c < k; ++c) {
319 p = adjustForObjectOrUninitialized(p);
320 }
321 }
322 case FULL_FRAME -> {
323 offsetDelta = classReader.readU2(p + 1);
324 p += 3;
325 int k = classReader.readU2(p);
326 p += 2;
327 for (int c = 0; c < k; ++c) {
328 p = adjustForObjectOrUninitialized(p);
329 }
330 k = classReader.readU2(p);
331 p += 2;
332 for (int c = 0; c < k; ++c) {
333 p = adjustForObjectOrUninitialized(p);
334 }
335 }
336 default -> throw new IllegalArgumentException("Bad frame type: " + frameType);
337 }
338 bci += offsetDelta + 1;
339 inflateLabel(bci);
340 }
341 }
342
343 private void inflateTypeAnnotations() {
344 findAttribute(Attributes.runtimeVisibleTypeAnnotations()).ifPresent(RuntimeVisibleTypeAnnotationsAttribute::annotations);
345 findAttribute(Attributes.runtimeInvisibleTypeAnnotations()).ifPresent(RuntimeInvisibleTypeAnnotationsAttribute::annotations);
346 }
347
348 private void generateCatchTargets(Consumer<? super CodeElement> consumer) {
349 // We attach all catch targets to bci zero, because trying to attach them
350 // to their range could subtly affect the order of exception processing
351 iterateExceptionHandlers(new ExceptionHandlerAction() {
352 @Override
353 public void accept(int s, int e, int h, int c) {
354 ClassEntry catchType = c == 0
355 ? null
356 : classReader.entryByIndex(c, ClassEntry.class);
357 consumer.accept(new AbstractPseudoInstruction.ExceptionCatchImpl(getLabel(h), getLabel(s), getLabel(e), catchType));
|
126 if (classReader.context().passLineNumbers())
127 inflateLineNumbers();
128 inflateJumpTargets();
129 inflateTypeAnnotations();
130 inflated = true;
131 }
132 }
133
134 // CodeAttribute
135
136 @Override
137 public List<Attribute<?>> attributes() {
138 if (attributes == null) {
139 attributes = BoundAttribute.readAttributes(this, classReader, attributePos, classReader.customAttributes());
140 }
141 return attributes;
142 }
143
144 @Override
145 public void writeTo(BufWriterImpl buf) {
146 var methodInfo = (MethodInfo) enclosingMethod;
147 if (Util.canSkipMethodInflation(classReader, methodInfo, buf)) {
148 super.writeTo(buf);
149 }
150 else {
151 DirectCodeBuilder.build(methodInfo,
152 Util.writingAll(this),
153 (SplitConstantPool)buf.constantPool(),
154 buf.context(),
155 null).writeTo(buf);
156 }
157 }
158
159 // CodeModel
160
161 @Override
162 public Optional<MethodModel> parent() {
163 return Optional.of(enclosingMethod);
164 }
165
166 @Override
167 public void forEach(Consumer<? super CodeElement> consumer) {
168 Objects.requireNonNull(consumer);
169 inflateMetadata();
170 boolean doLineNumbers = (lineNumbers != null);
171 generateCatchTargets(consumer);
276 }
277 case TABLE_SWITCH -> {
278 var ts = (TableSwitchInstruction) i;
279 ts.defaultTarget();
280 ts.cases();
281 }
282 default -> {}
283 }
284 pos += i.sizeInBytes();
285 }
286 }
287 return;
288 }
289 int stackMapPos = ((BoundAttribute<StackMapTableAttribute>) a.get()).payloadStart;
290
291 int bci = -1; //compensate for offsetDelta + 1
292 int nEntries = classReader.readU2(stackMapPos);
293 int p = stackMapPos + 2;
294 for (int i = 0; i < nEntries; ++i) {
295 int frameType = classReader.readU1(p);
296 int offsetDelta = -1;
297 if (frameType <= SAME_FRAME_END) {
298 offsetDelta = frameType;
299 ++p;
300 }
301 else if (frameType <= SAME_LOCALS_1_STACK_ITEM_FRAME_END) {
302 offsetDelta = frameType & 0x3f;
303 p = adjustForObjectOrUninitialized(p + 1);
304 }
305 else {
306 switch (frameType) {
307 case EARLY_LARVAL -> {
308 int numberOfUnsetFields = classReader.readU2(p + 1);
309 p += 3;
310 p += 2 * numberOfUnsetFields;
311 i--; // one more enclosed frame
312 continue;
313 }
314 case SAME_LOCALS_1_STACK_ITEM_EXTENDED -> {
315 offsetDelta = classReader.readU2(p + 1);
316 p = adjustForObjectOrUninitialized(p + 3);
317 }
318 case CHOP_FRAME_START, CHOP_FRAME_START + 1, CHOP_FRAME_END, SAME_FRAME_EXTENDED -> {
319 offsetDelta = classReader.readU2(p + 1);
320 p += 3;
321 }
322 case APPEND_FRAME_START, APPEND_FRAME_START + 1, APPEND_FRAME_END -> {
323 offsetDelta = classReader.readU2(p + 1);
324 int k = frameType - APPEND_FRAME_START + 1;
325 p += 3;
326 for (int c = 0; c < k; ++c) {
327 p = adjustForObjectOrUninitialized(p);
328 }
329 }
330 case FULL_FRAME -> {
331 offsetDelta = classReader.readU2(p + 1);
332 p += 3;
333 int k = classReader.readU2(p);
334 p += 2;
335 for (int c = 0; c < k; ++c) {
336 p = adjustForObjectOrUninitialized(p);
337 }
338 k = classReader.readU2(p);
339 p += 2;
340 for (int c = 0; c < k; ++c) {
341 p = adjustForObjectOrUninitialized(p);
342 }
343 }
344 default -> throw new IllegalArgumentException("Bad frame type: " + frameType);
345 }
346 }
347 bci += offsetDelta + 1;
348 inflateLabel(bci);
349 }
350 }
351
352 private void inflateTypeAnnotations() {
353 findAttribute(Attributes.runtimeVisibleTypeAnnotations()).ifPresent(RuntimeVisibleTypeAnnotationsAttribute::annotations);
354 findAttribute(Attributes.runtimeInvisibleTypeAnnotations()).ifPresent(RuntimeInvisibleTypeAnnotationsAttribute::annotations);
355 }
356
357 private void generateCatchTargets(Consumer<? super CodeElement> consumer) {
358 // We attach all catch targets to bci zero, because trying to attach them
359 // to their range could subtly affect the order of exception processing
360 iterateExceptionHandlers(new ExceptionHandlerAction() {
361 @Override
362 public void accept(int s, int e, int h, int c) {
363 ClassEntry catchType = c == 0
364 ? null
365 : classReader.entryByIndex(c, ClassEntry.class);
366 consumer.accept(new AbstractPseudoInstruction.ExceptionCatchImpl(getLabel(h), getLabel(s), getLabel(e), catchType));
|