| // Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| package com.android.tools.r8.ir; | |
| import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage; | |
| import static org.hamcrest.CoreMatchers.allOf; | |
| import static org.hamcrest.CoreMatchers.containsString; | |
| import com.android.tools.r8.TestBase; | |
| import com.android.tools.r8.TestParameters; | |
| import com.android.tools.r8.TestParametersCollection; | |
| import com.google.common.collect.ImmutableList; | |
| import org.junit.Test; | |
| import org.junit.runner.RunWith; | |
| import org.junit.runners.Parameterized; | |
| import org.junit.runners.Parameterized.Parameters; | |
| import org.objectweb.asm.AnnotationVisitor; | |
| import org.objectweb.asm.ClassWriter; | |
| import org.objectweb.asm.Label; | |
| import org.objectweb.asm.MethodVisitor; | |
| import org.objectweb.asm.Opcodes; | |
| @RunWith(Parameterized.class) | |
| public class DebugLocalStackMapTest extends TestBase { | |
| private final TestParameters parameters; | |
| @Parameters(name = "{0}") | |
| public static TestParametersCollection data() { | |
| return getTestParameters().withDexRuntimes().withAllApiLevels().build(); | |
| } | |
| public DebugLocalStackMapTest(TestParameters parameters) { | |
| this.parameters = parameters; | |
| } | |
| @Test | |
| public void testInvalidDebugLocals() throws Exception { | |
| testForD8(parameters.getBackend()) | |
| .addProgramClassFileData(TestKtDump.dump()) | |
| .setMinApi(parameters.getApiLevel()) | |
| .compileWithExpectedDiagnostics( | |
| diagnostics -> { | |
| diagnostics.assertInfosMatch( | |
| ImmutableList.of( | |
| diagnosticMessage( | |
| containsString("Stripped invalid locals information from 1 method")), | |
| diagnosticMessage( | |
| allOf( | |
| containsString( | |
| "java.lang.Object" | |
| + " TestKt.suspendHere(kotlin.coroutines.Continuation)"), | |
| containsString( | |
| "Information in locals-table is invalid with respect to the" | |
| + " stack map table"))), | |
| diagnosticMessage( | |
| containsString( | |
| "Some warnings are typically a sign of using an outdated Java" | |
| + " toolchain")))); | |
| }); | |
| } | |
| public static class TestKtDump implements Opcodes { | |
| public static byte[] dump() { | |
| ClassWriter classWriter = new ClassWriter(0); | |
| MethodVisitor methodVisitor; | |
| AnnotationVisitor annotationVisitor0; | |
| classWriter.visit( | |
| V1_8, ACC_PUBLIC | ACC_FINAL | ACC_SUPER, "TestKt", null, "java/lang/Object", null); | |
| classWriter.visitSource( | |
| "test.kt", | |
| "SMAP\n" | |
| + "test.kt\n" | |
| + "Kotlin\n" | |
| + "*S Kotlin\n" | |
| + "*F\n" | |
| + "+ 1 test.kt\n" | |
| + "TestKt\n" | |
| + "*L\n" | |
| + "1#1,17:1\n" | |
| + "4#1,4:18\n" | |
| + "10#1:22\n" | |
| + "4#1,4:23\n" | |
| + "*S KotlinDebug\n" | |
| + "*F\n" | |
| + "+ 1 test.kt\n" | |
| + "TestKt\n" | |
| + "*L\n" | |
| + "10#1:18,4\n" | |
| + "12#1:22\n" | |
| + "12#1:23,4\n" | |
| + "*E\n"); | |
| { | |
| annotationVisitor0 = classWriter.visitAnnotation("Lkotlin/Metadata;", true); | |
| annotationVisitor0.visit("mv", new int[] {1, 5, 0}); | |
| annotationVisitor0.visit("k", new Integer(2)); | |
| annotationVisitor0.visit("xi", new Integer(50)); | |
| { | |
| AnnotationVisitor annotationVisitor1 = annotationVisitor0.visitArray("d1"); | |
| annotationVisitor1.visit( | |
| null, | |
| "\u0000\u0012\n" | |
| + "\u0000\n" | |
| + "\u0002\u0010\u0002\n" | |
| + "\u0002\u0008\u0002\n" | |
| + "\u0002\u0010\u000e\n" | |
| + "\u0002\u0008\u0004\u001a\u0011\u0010\u0000\u001a\u00020\u0001H\u0086@\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\u0002\u001a\u0011\u0010\u0003\u001a\u00020\u0004H\u0086@\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\u0002\u001a\u0011\u0010\u0005\u001a\u00020\u0004H\u0086H\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\u0002\u001a\u0019\u0010\u0006\u001a\u00020\u00042\u0006\u0010\u0007\u001a\u00020\u0004H\u0086H\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\u0008\u0082\u0002\u0004\n" | |
| + "\u0002\u0008\u0019"); | |
| annotationVisitor1.visitEnd(); | |
| } | |
| { | |
| AnnotationVisitor annotationVisitor1 = annotationVisitor0.visitArray("d2"); | |
| annotationVisitor1.visit(null, "main"); | |
| annotationVisitor1.visit(null, ""); | |
| annotationVisitor1.visit(null, "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;"); | |
| annotationVisitor1.visit(null, "mainSuspend"); | |
| annotationVisitor1.visit(null, ""); | |
| annotationVisitor1.visit(null, "suspendHere"); | |
| annotationVisitor1.visit(null, "suspendThere"); | |
| annotationVisitor1.visit(null, "v"); | |
| annotationVisitor1.visit( | |
| null, "(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;"); | |
| annotationVisitor1.visitEnd(); | |
| } | |
| annotationVisitor0.visitEnd(); | |
| } | |
| { | |
| methodVisitor = | |
| classWriter.visitMethod( | |
| ACC_PUBLIC | ACC_FINAL | ACC_STATIC, | |
| "suspendHere", | |
| "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", | |
| "(Lkotlin/coroutines/Continuation<-Ljava/lang/String;>;)Ljava/lang/Object;", | |
| null); | |
| { | |
| annotationVisitor0 = | |
| methodVisitor.visitAnnotation("Lorg/jetbrains/annotations/Nullable;", false); | |
| annotationVisitor0.visitEnd(); | |
| } | |
| methodVisitor.visitAnnotableParameterCount(1, false); | |
| { | |
| annotationVisitor0 = | |
| methodVisitor.visitParameterAnnotation( | |
| 0, "Lorg/jetbrains/annotations/NotNull;", false); | |
| annotationVisitor0.visitEnd(); | |
| } | |
| methodVisitor.visitCode(); | |
| methodVisitor.visitVarInsn(ALOAD, 0); | |
| methodVisitor.visitTypeInsn(INSTANCEOF, "TestKt$suspendHere$1"); | |
| Label label0 = new Label(); | |
| methodVisitor.visitJumpInsn(IFEQ, label0); | |
| methodVisitor.visitVarInsn(ALOAD, 0); | |
| methodVisitor.visitTypeInsn(CHECKCAST, "TestKt$suspendHere$1"); | |
| methodVisitor.visitVarInsn(ASTORE, 13); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitFieldInsn(GETFIELD, "TestKt$suspendHere$1", "label", "I"); | |
| methodVisitor.visitLdcInsn(new Integer(-2147483648)); | |
| methodVisitor.visitInsn(IAND); | |
| methodVisitor.visitJumpInsn(IFEQ, label0); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitInsn(DUP); | |
| methodVisitor.visitFieldInsn(GETFIELD, "TestKt$suspendHere$1", "label", "I"); | |
| methodVisitor.visitLdcInsn(new Integer(-2147483648)); | |
| methodVisitor.visitInsn(ISUB); | |
| methodVisitor.visitFieldInsn(PUTFIELD, "TestKt$suspendHere$1", "label", "I"); | |
| Label label1 = new Label(); | |
| methodVisitor.visitJumpInsn(GOTO, label1); | |
| methodVisitor.visitLabel(label0); | |
| methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null); | |
| methodVisitor.visitTypeInsn(NEW, "TestKt$suspendHere$1"); | |
| methodVisitor.visitInsn(DUP); | |
| methodVisitor.visitVarInsn(ALOAD, 0); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESPECIAL, | |
| "TestKt$suspendHere$1", | |
| "<init>", | |
| "(Lkotlin/coroutines/Continuation;)V", | |
| false); | |
| methodVisitor.visitVarInsn(ASTORE, 13); | |
| methodVisitor.visitLabel(label1); | |
| methodVisitor.visitFrame( | |
| Opcodes.F_FULL, | |
| 14, | |
| new Object[] { | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| "TestKt$suspendHere$1" | |
| }, | |
| 0, | |
| new Object[] {}); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitFieldInsn( | |
| GETFIELD, "TestKt$suspendHere$1", "result", "Ljava/lang/Object;"); | |
| methodVisitor.visitVarInsn(ASTORE, 12); | |
| Label label2 = new Label(); | |
| methodVisitor.visitLabel(label2); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, | |
| "kotlin/coroutines/intrinsics/IntrinsicsKt", | |
| "getCOROUTINE_SUSPENDED", | |
| "()Ljava/lang/Object;", | |
| false); | |
| Label label3 = new Label(); | |
| methodVisitor.visitLabel(label3); | |
| methodVisitor.visitLineNumber(10, label3); | |
| methodVisitor.visitVarInsn(ASTORE, 14); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitFieldInsn(GETFIELD, "TestKt$suspendHere$1", "label", "I"); | |
| Label label4 = new Label(); | |
| Label label5 = new Label(); | |
| Label label6 = new Label(); | |
| Label label7 = new Label(); | |
| methodVisitor.visitTableSwitchInsn(0, 2, label7, new Label[] {label4, label5, label6}); | |
| methodVisitor.visitLabel(label4); | |
| methodVisitor.visitFrame( | |
| Opcodes.F_FULL, | |
| 15, | |
| new Object[] { | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| "java/lang/Object", | |
| "TestKt$suspendHere$1", | |
| "java/lang/Object" | |
| }, | |
| 0, | |
| new Object[] {}); | |
| methodVisitor.visitVarInsn(ALOAD, 12); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, "kotlin/ResultKt", "throwOnFailure", "(Ljava/lang/Object;)V", false); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 1); | |
| Label label8 = new Label(); | |
| methodVisitor.visitLabel(label8); | |
| methodVisitor.visitLineNumber(10, label8); | |
| methodVisitor.visitLdcInsn("O"); | |
| methodVisitor.visitVarInsn(ASTORE, 2); | |
| Label label9 = new Label(); | |
| methodVisitor.visitLabel(label9); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 3); | |
| Label label10 = new Label(); | |
| methodVisitor.visitLabel(label10); | |
| methodVisitor.visitLineNumber(18, label10); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitVarInsn(ALOAD, 2); | |
| methodVisitor.visitFieldInsn(PUTFIELD, "TestKt$suspendHere$1", "L$0", "Ljava/lang/Object;"); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitInsn(ICONST_1); | |
| methodVisitor.visitFieldInsn(PUTFIELD, "TestKt$suspendHere$1", "label", "I"); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitTypeInsn(CHECKCAST, "kotlin/coroutines/Continuation"); | |
| methodVisitor.visitVarInsn(ASTORE, 4); | |
| Label label11 = new Label(); | |
| methodVisitor.visitLabel(label11); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 5); | |
| Label label12 = new Label(); | |
| methodVisitor.visitLabel(label12); | |
| methodVisitor.visitLineNumber(19, label12); | |
| methodVisitor.visitVarInsn(ALOAD, 4); | |
| methodVisitor.visitVarInsn(ASTORE, 6); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 7); | |
| methodVisitor.visitVarInsn(ALOAD, 6); | |
| methodVisitor.visitFieldInsn( | |
| GETSTATIC, "kotlin/Result", "Companion", "Lkotlin/Result$Companion;"); | |
| methodVisitor.visitVarInsn(ASTORE, 8); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 9); | |
| methodVisitor.visitVarInsn(ALOAD, 2); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, | |
| "kotlin/Result", | |
| "constructor-impl", | |
| "(Ljava/lang/Object;)Ljava/lang/Object;", | |
| false); | |
| methodVisitor.visitMethodInsn( | |
| INVOKEINTERFACE, | |
| "kotlin/coroutines/Continuation", | |
| "resumeWith", | |
| "(Ljava/lang/Object;)V", | |
| true); | |
| Label label13 = new Label(); | |
| methodVisitor.visitLabel(label13); | |
| methodVisitor.visitLineNumber(20, label13); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, | |
| "kotlin/coroutines/intrinsics/IntrinsicsKt", | |
| "getCOROUTINE_SUSPENDED", | |
| "()Ljava/lang/Object;", | |
| false); | |
| Label label14 = new Label(); | |
| methodVisitor.visitLabel(label14); | |
| methodVisitor.visitLineNumber(18, label14); | |
| methodVisitor.visitInsn(DUP); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, | |
| "kotlin/coroutines/intrinsics/IntrinsicsKt", | |
| "getCOROUTINE_SUSPENDED", | |
| "()Ljava/lang/Object;", | |
| false); | |
| Label label15 = new Label(); | |
| methodVisitor.visitJumpInsn(IF_ACMPNE, label15); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitTypeInsn(CHECKCAST, "kotlin/coroutines/Continuation"); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, | |
| "kotlin/coroutines/jvm/internal/DebugProbesKt", | |
| "probeCoroutineSuspended", | |
| "(Lkotlin/coroutines/Continuation;)V", | |
| false); | |
| methodVisitor.visitLabel(label15); | |
| methodVisitor.visitFrame( | |
| Opcodes.F_FULL, | |
| 15, | |
| new Object[] { | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.INTEGER, | |
| "java/lang/String", | |
| Opcodes.INTEGER, | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.INTEGER, | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.INTEGER, | |
| "kotlin/Result$Companion", | |
| Opcodes.INTEGER, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| "java/lang/Object", | |
| "TestKt$suspendHere$1", | |
| "java/lang/Object" | |
| }, | |
| 1, | |
| new Object[] {"java/lang/Object"}); | |
| methodVisitor.visitInsn(DUP); | |
| methodVisitor.visitVarInsn(ALOAD, 14); | |
| Label label16 = new Label(); | |
| methodVisitor.visitJumpInsn(IF_ACMPNE, label16); | |
| Label label17 = new Label(); | |
| methodVisitor.visitLabel(label17); | |
| methodVisitor.visitLineNumber(10, label17); | |
| methodVisitor.visitVarInsn(ALOAD, 14); | |
| methodVisitor.visitInsn(ARETURN); | |
| methodVisitor.visitLabel(label5); | |
| methodVisitor.visitFrame( | |
| Opcodes.F_FULL, | |
| 15, | |
| new Object[] { | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| "java/lang/Object", | |
| "TestKt$suspendHere$1", | |
| "java/lang/Object" | |
| }, | |
| 0, | |
| new Object[] {}); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 1); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 3); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitFieldInsn(GETFIELD, "TestKt$suspendHere$1", "L$0", "Ljava/lang/Object;"); | |
| methodVisitor.visitTypeInsn(CHECKCAST, "java/lang/String"); | |
| methodVisitor.visitVarInsn(ASTORE, 2); | |
| methodVisitor.visitVarInsn(ALOAD, 12); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, "kotlin/ResultKt", "throwOnFailure", "(Ljava/lang/Object;)V", false); | |
| methodVisitor.visitVarInsn(ALOAD, 12); | |
| methodVisitor.visitLabel(label16); | |
| methodVisitor.visitLineNumber(21, label16); | |
| methodVisitor.visitFrame( | |
| Opcodes.F_FULL, | |
| 15, | |
| new Object[] { | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.INTEGER, | |
| "java/lang/String", | |
| Opcodes.INTEGER, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| "java/lang/Object", | |
| "TestKt$suspendHere$1", | |
| "java/lang/Object" | |
| }, | |
| 1, | |
| new Object[] {"java/lang/Object"}); | |
| methodVisitor.visitInsn(NOP); | |
| Label label18 = new Label(); | |
| methodVisitor.visitLabel(label18); | |
| methodVisitor.visitTypeInsn(CHECKCAST, "java/lang/String"); | |
| Label label19 = new Label(); | |
| methodVisitor.visitLabel(label19); | |
| methodVisitor.visitLineNumber(10, label19); | |
| methodVisitor.visitLdcInsn("K"); | |
| methodVisitor.visitVarInsn(ASTORE, 2); | |
| methodVisitor.visitVarInsn(ASTORE, 10); | |
| Label label20 = new Label(); | |
| methodVisitor.visitLabel(label20); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 3); | |
| Label label21 = new Label(); | |
| methodVisitor.visitLabel(label21); | |
| methodVisitor.visitLineNumber(18, label21); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitVarInsn(ALOAD, 2); | |
| methodVisitor.visitFieldInsn(PUTFIELD, "TestKt$suspendHere$1", "L$0", "Ljava/lang/Object;"); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitVarInsn(ALOAD, 10); | |
| methodVisitor.visitFieldInsn(PUTFIELD, "TestKt$suspendHere$1", "L$1", "Ljava/lang/Object;"); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitInsn(ICONST_2); | |
| methodVisitor.visitFieldInsn(PUTFIELD, "TestKt$suspendHere$1", "label", "I"); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitTypeInsn(CHECKCAST, "kotlin/coroutines/Continuation"); | |
| methodVisitor.visitVarInsn(ASTORE, 4); | |
| Label label22 = new Label(); | |
| methodVisitor.visitLabel(label22); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 5); | |
| Label label23 = new Label(); | |
| methodVisitor.visitLabel(label23); | |
| methodVisitor.visitLineNumber(19, label23); | |
| methodVisitor.visitVarInsn(ALOAD, 4); | |
| methodVisitor.visitVarInsn(ASTORE, 6); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 7); | |
| methodVisitor.visitVarInsn(ALOAD, 6); | |
| methodVisitor.visitFieldInsn( | |
| GETSTATIC, "kotlin/Result", "Companion", "Lkotlin/Result$Companion;"); | |
| methodVisitor.visitVarInsn(ASTORE, 8); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 9); | |
| methodVisitor.visitVarInsn(ALOAD, 2); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, | |
| "kotlin/Result", | |
| "constructor-impl", | |
| "(Ljava/lang/Object;)Ljava/lang/Object;", | |
| false); | |
| methodVisitor.visitMethodInsn( | |
| INVOKEINTERFACE, | |
| "kotlin/coroutines/Continuation", | |
| "resumeWith", | |
| "(Ljava/lang/Object;)V", | |
| true); | |
| Label label24 = new Label(); | |
| methodVisitor.visitLabel(label24); | |
| methodVisitor.visitLineNumber(20, label24); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, | |
| "kotlin/coroutines/intrinsics/IntrinsicsKt", | |
| "getCOROUTINE_SUSPENDED", | |
| "()Ljava/lang/Object;", | |
| false); | |
| Label label25 = new Label(); | |
| methodVisitor.visitLabel(label25); | |
| methodVisitor.visitLineNumber(18, label25); | |
| methodVisitor.visitInsn(DUP); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, | |
| "kotlin/coroutines/intrinsics/IntrinsicsKt", | |
| "getCOROUTINE_SUSPENDED", | |
| "()Ljava/lang/Object;", | |
| false); | |
| Label label26 = new Label(); | |
| methodVisitor.visitJumpInsn(IF_ACMPNE, label26); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitTypeInsn(CHECKCAST, "kotlin/coroutines/Continuation"); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, | |
| "kotlin/coroutines/jvm/internal/DebugProbesKt", | |
| "probeCoroutineSuspended", | |
| "(Lkotlin/coroutines/Continuation;)V", | |
| false); | |
| methodVisitor.visitLabel(label26); | |
| methodVisitor.visitFrame( | |
| Opcodes.F_FULL, | |
| 15, | |
| new Object[] { | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.INTEGER, | |
| "java/lang/String", | |
| Opcodes.INTEGER, | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.INTEGER, | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.INTEGER, | |
| "kotlin/Result$Companion", | |
| Opcodes.INTEGER, | |
| "java/lang/String", | |
| Opcodes.TOP, | |
| "java/lang/Object", | |
| "TestKt$suspendHere$1", | |
| "java/lang/Object" | |
| }, | |
| 1, | |
| new Object[] {"java/lang/Object"}); | |
| methodVisitor.visitInsn(DUP); | |
| methodVisitor.visitVarInsn(ALOAD, 14); | |
| Label label27 = new Label(); | |
| methodVisitor.visitJumpInsn(IF_ACMPNE, label27); | |
| Label label28 = new Label(); | |
| methodVisitor.visitLabel(label28); | |
| methodVisitor.visitLineNumber(10, label28); | |
| methodVisitor.visitVarInsn(ALOAD, 14); | |
| methodVisitor.visitInsn(ARETURN); | |
| methodVisitor.visitLabel(label6); | |
| methodVisitor.visitFrame( | |
| Opcodes.F_FULL, | |
| 15, | |
| new Object[] { | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| "java/lang/Object", | |
| "TestKt$suspendHere$1", | |
| "java/lang/Object" | |
| }, | |
| 0, | |
| new Object[] {}); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 1); | |
| methodVisitor.visitInsn(ICONST_0); | |
| methodVisitor.visitVarInsn(ISTORE, 3); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitFieldInsn(GETFIELD, "TestKt$suspendHere$1", "L$1", "Ljava/lang/Object;"); | |
| methodVisitor.visitTypeInsn(CHECKCAST, "java/lang/String"); | |
| methodVisitor.visitVarInsn(ASTORE, 10); | |
| methodVisitor.visitVarInsn(ALOAD, 13); | |
| methodVisitor.visitFieldInsn(GETFIELD, "TestKt$suspendHere$1", "L$0", "Ljava/lang/Object;"); | |
| methodVisitor.visitTypeInsn(CHECKCAST, "java/lang/String"); | |
| methodVisitor.visitVarInsn(ASTORE, 2); | |
| methodVisitor.visitVarInsn(ALOAD, 12); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, "kotlin/ResultKt", "throwOnFailure", "(Ljava/lang/Object;)V", false); | |
| methodVisitor.visitVarInsn(ALOAD, 12); | |
| methodVisitor.visitLabel(label27); | |
| methodVisitor.visitLineNumber(21, label27); | |
| methodVisitor.visitFrame( | |
| Opcodes.F_FULL, | |
| 15, | |
| new Object[] { | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.INTEGER, | |
| "java/lang/String", | |
| Opcodes.INTEGER, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| "java/lang/String", | |
| Opcodes.TOP, | |
| "java/lang/Object", | |
| "TestKt$suspendHere$1", | |
| "java/lang/Object" | |
| }, | |
| 1, | |
| new Object[] {"java/lang/Object"}); | |
| methodVisitor.visitInsn(NOP); | |
| Label label29 = new Label(); | |
| methodVisitor.visitLabel(label29); | |
| methodVisitor.visitVarInsn(ASTORE, 11); | |
| methodVisitor.visitVarInsn(ALOAD, 10); | |
| methodVisitor.visitVarInsn(ALOAD, 11); | |
| Label label30 = new Label(); | |
| methodVisitor.visitLabel(label30); | |
| methodVisitor.visitLineNumber(10, label30); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESTATIC, | |
| "kotlin/jvm/internal/Intrinsics", | |
| "stringPlus", | |
| "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", | |
| false); | |
| methodVisitor.visitInsn(ARETURN); | |
| methodVisitor.visitLabel(label7); | |
| methodVisitor.visitFrame( | |
| Opcodes.F_FULL, | |
| 15, | |
| new Object[] { | |
| "kotlin/coroutines/Continuation", | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| Opcodes.TOP, | |
| "java/lang/Object", | |
| "TestKt$suspendHere$1", | |
| "java/lang/Object" | |
| }, | |
| 0, | |
| new Object[] {}); | |
| methodVisitor.visitTypeInsn(NEW, "java/lang/IllegalStateException"); | |
| methodVisitor.visitInsn(DUP); | |
| methodVisitor.visitLdcInsn("call to 'resume' before 'invoke' with coroutine"); | |
| methodVisitor.visitMethodInsn( | |
| INVOKESPECIAL, | |
| "java/lang/IllegalStateException", | |
| "<init>", | |
| "(Ljava/lang/String;)V", | |
| false); | |
| methodVisitor.visitInsn(ATHROW); | |
| methodVisitor.visitLocalVariable("v$iv", "Ljava/lang/String;", null, label9, label15, 2); | |
| methodVisitor.visitLocalVariable("v$iv", "Ljava/lang/String;", null, label20, label26, 2); | |
| methodVisitor.visitLocalVariable( | |
| "x$iv", "Lkotlin/coroutines/Continuation;", null, label11, label14, 4); | |
| methodVisitor.visitLocalVariable( | |
| "x$iv", "Lkotlin/coroutines/Continuation;", null, label22, label25, 4); | |
| methodVisitor.visitLocalVariable( | |
| "$i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$suspendThere$2$iv", | |
| "I", | |
| null, | |
| label12, | |
| label14, | |
| 5); | |
| methodVisitor.visitLocalVariable("$i$f$suspendThere", "I", null, label10, label18, 3); | |
| methodVisitor.visitLocalVariable( | |
| "$i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$suspendThere$2$iv", | |
| "I", | |
| null, | |
| label23, | |
| label25, | |
| 5); | |
| methodVisitor.visitLocalVariable("$i$f$suspendThere", "I", null, label21, label29, 3); | |
| methodVisitor.visitLocalVariable("$i$f$suspendHere", "I", null, label8, label7, 1); | |
| methodVisitor.visitLocalVariable( | |
| "$continuation", "Lkotlin/coroutines/Continuation;", null, label1, label7, 13); | |
| methodVisitor.visitLocalVariable("$result", "Ljava/lang/Object;", null, label2, label7, 12); | |
| methodVisitor.visitMaxs(3, 15); | |
| methodVisitor.visitEnd(); | |
| } | |
| classWriter.visitEnd(); | |
| return classWriter.toByteArray(); | |
| } | |
| } | |
| } |