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