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