[IR] Add MFVC generation tests

#KT-1179
This commit is contained in:
Evgeniy.Zhelenskiy
2022-05-07 00:03:39 +03:00
committed by teamcity
parent 894cdc2307
commit 765c212327
23 changed files with 1399 additions and 233 deletions
@@ -0,0 +1,68 @@
// CHECK_BYTECODE_LISTING
// WITH_STDLIB
// TARGET_BACKEND: JVM_IR
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses
@JvmInline
value class A<T : Any>(val x: List<T>)
@JvmInline
value class B(val x: UInt)
@JvmInline
value class C(val x: Int, val y: B, val z: String = "3")
@JvmInline
value class D(val x: C) {
constructor(x: Int, y: UInt, z: Int) : this(C(x, B(y), z.toString()))
init {
println(x.x)
}
}
fun functionWithoutBoxes(x: D, y: D) {
var z: D = x
val t: D = D(C(1, B(3U), "4"))
z = t
require(z == y)
}
// 2 public static toString-impl\(IILjava/lang/String;\)Ljava/lang/String;
// 2 INVOKESTATIC C.toString-impl \(IILjava/lang/String;\)Ljava/lang/String;
// 1 INVOKESTATIC D.toString-impl \(IILjava/lang/String;\)Ljava/lang/String;
// 2 public static hashCode-impl\(IILjava/lang/String;\)I
// 2 INVOKESTATIC C.hashCode-impl \(IILjava/lang/String;\)I
// 1 INVOKESTATIC D.hashCode-impl \(IILjava/lang/String;\)I
// 2 public static equals-impl\(IILjava/lang/String;Ljava/lang/Object;\)Z
// 2 public final static equals-impl0\(IILjava/lang/String;IILjava/lang/String;\)Z
// 1 public final static constructor-impl\(III\)LD;
// 2 public final static constructor-impl\(IILjava/lang/String;\)V
// 2 INVOKESTATIC D.constructor-impl \(IILjava/lang/String;\)V
// 2 INVOKESTATIC C.constructor-impl \(IILjava/lang/String;\)V
// 1 public final getX\(\)LC;
// 1 public final getX\$x\(\)I
// 1 public final getX\$y\(\)I
// 1 public final getX\$z\(\)Ljava/lang/String;
// 2 private synthetic <init>\(IILjava/lang/String;\)V
// 1 public final static synthetic box-impl\(IILjava/lang/String;\)LD;
// 1 public final static synthetic box-impl\(IILjava/lang/String;\)LC;
// 2 public final synthetic unbox-impl0\(\)I
// 2 public final synthetic unbox-impl1\(\)I
// 2 public final synthetic unbox-impl2\(\)Ljava/lang/String;
// 1 private I x\$x
// 1 private I x\$y
// 1 private Ljava/lang/String; x\$z
// 0 private LC; x
// 3 private I x
// 1 private I y
// 1 private Ljava/lang/String; z
// 1 INVOKESPECIAL C.<init> \(IILjava/lang/String;\)V
// 1 INVOKESPECIAL D.<init> \(IILjava/lang/String;\)V
// 1 INVOKESTATIC D.box-impl \(IILjava/lang/String;\)LD;
// 1 INVOKESTATIC D.box-impl \(IILjava/lang/String;\)LD;\n ARETURN
// 1 INVOKESTATIC C.box-impl \(IILjava/lang/String;\)LC;
// 1 INVOKESTATIC C.box-impl \(IILjava/lang/String;\)LC;\n ARETURN
// 1 public final static functionWithoutBoxes-GPBa7dw-AYZo7_8\(IILjava/lang/String;IILjava/lang/String;\)V
// 0 functionWithoutBoxes.*(\n {3}.*)*(\n {4}(NEW [ABCD]|.*(box|[ABCD]\.<init>|LA;|LB;|LC;|LD;)))
@@ -0,0 +1,73 @@
// CHECK_BYTECODE_LISTING
// WITH_STDLIB
// TARGET_BACKEND: JVM_IR
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses
@JvmInline
value class DPoint(val x: Double, val y: Double)
class Box(var value: DPoint)
fun supplier(index: Int) {} // to make usage of the argument
fun supplier(index: Int, x: DPoint) {} // to make usage of the argument
fun reassignVariable(x: DPoint, box: Box) {
supplier(100)
var p = DPoint(1.0, 2.0) // should not use temporary variables
supplier(101, p)
p = p // should not use temporary variables
supplier(102, p)
p = DPoint(3.0, 4.0) // should use tempVars
supplier(103, p)
p = x // should not use temporary variables
supplier(104, p)
p = box.value // should use temporary variables
supplier(105, p)
p = listOf(p)[0] // should use temporary variables
supplier(106, p)
}
fun reassignField(x: DPoint, box: Box) {
supplier(107)
val p = DPoint(5.0, 6.0)
supplier(108, p)
var b = Box(p) // should not use temporary variables
supplier(109)
b.value = b.value // should not use temporary variables
supplier(110)
b.value = DPoint(7.0, 8.0) // should use tempVars
supplier(111)
b.value = x // should not use temporary variables
supplier(112)
b.value = box.value // should not use temporary variables
supplier(113)
b.value = listOf(p)[0] // should use temporary variables
supplier(114)
}
// 1 100(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}101
// 0 100(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}101
// 1 101(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}102
// 0 101(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}102
// 1 102(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){4}103
// 0 102(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){5}103
// 1 103(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}104
// 0 103(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}104
// 1 104(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){4}105
// 0 104(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){5}105
// 1 105(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){4}106
// 0 105(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){5}106
// 1 107(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}108
// 0 107(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}108
// 0 108(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){1}109
// 1 109(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}110
// 0 109(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}110
// 1 110(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}111
// 0 110(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}111
// 0 111(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){1}112
// 1 112(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}113
// 0 112(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}113
// 1 113(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){2}114
// 0 113(\D|\d\D|\d\d\D)*(DSTORE(\D|\d\D|\d\d\D)*){3}114
@@ -0,0 +1,42 @@
// CHECK_BYTECODE_LISTING
// WITH_STDLIB
// TARGET_BACKEND: JVM_IR
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses
@JvmInline
value class DPoint(val x: Double, val y: Double)
fun require(index: Int, condition: Boolean) = require(condition) { "$index" }
fun DPoint.toObject() = this as Any
fun DPoint.toDPointOrNull() = this as DPoint?
fun Nothing?.toDPointOrNull() = this as DPoint?
fun equalsChecks(left: DPoint, right: DPoint) {
require(100, left == right)
require(101, left.toObject() == right)
require(102, left == right.toObject())
require(103, left.toObject() == right.toObject())
require(104, null == right)
require(105, left == null)
require(106, null as Any? == right)
require(107, left == null as Any?)
require(108, null.toDPointOrNull() == right)
require(109, left == null.toDPointOrNull())
require(110, left.toDPointOrNull() == right)
require(111, left == right.toDPointOrNull())
}
// 1 BIPUSH 100\n {4}DLOAD 0\n {4}DLOAD 2\n {4}DLOAD 4\n {4}DLOAD 6\n {4}INVOKESTATIC .*equals-impl0.*\n {4}INVOKESTATIC .*require
// 1 BIPUSH 101\n {4}DLOAD 0\n {4}DLOAD 2\n {4}.*toObject.*\n {4}DLOAD 4\n {4}DLOAD 6\n {4}.*box-impl.*\n {4}INVOKESTATIC .*Intrinsics.areEqual.*\n {4}INVOKESTATIC .*require
// 1 BIPUSH 102\n {4}DLOAD 0\n {4}DLOAD 2\n {4}DLOAD 4\n {4}DLOAD 6\n {4}.*toObject.*\n {4}INVOKESTATIC .*equals-impl .*\n {4}INVOKESTATIC .*require
// 1 BIPUSH 103\n {4}DLOAD 0\n {4}DLOAD 2\n {4}.*toObject.*\n {4}DLOAD 4\n {4}DLOAD 6\n {4}.*toObject.*\n {4}INVOKESTATIC .*Intrinsics.areEqual.*\n {4}INVOKESTATIC .*require
// 1 BIPUSH 104\n {4}ICONST_0\n {4}INVOKESTATIC .*require
// 1 BIPUSH 105\n {4}DLOAD 0\n {4}DLOAD 2\n {4}ACONST_NULL\n {4}INVOKESTATIC .*equals-impl .*\n {4}INVOKESTATIC .*require
// 1 BIPUSH 106\n {4}ACONST_NULL\n {4}DLOAD 4\n {4}DLOAD 6\n {4}.*box.*\n {4}INVOKESTATIC .*Intrinsics.areEqual.*\n {4}INVOKESTATIC .*require
// 1 BIPUSH 107\n {4}DLOAD 0\n {4}DLOAD 2\n {4}ACONST_NULL\n {4}INVOKESTATIC .*equals-impl .*\n {4}INVOKESTATIC .*require
// 1 BIPUSH 108\n {4}ACONST_NULL\n {4}.*toDPointOrNull.*\n {4}DUP\n {4}IFNONNULL.*(\n {3}([^b\n]|b[^o\n]|bo[^x\n]|box-impl\d)*)*\n {4}INVOKESTATIC .*require
// 1 BIPUSH 109\n {4}DLOAD 0\n {4}DLOAD 2\n {4}ACONST_NULL\n {4}.*toDPointOrNull.*\n {4}INVOKESTATIC .*equals-impl .*\n {4}INVOKESTATIC .*require
// 1 BIPUSH 110\n {4}DLOAD 0\n {4}DLOAD 2\n {4}.*toDPointOrNull.*\n {4}DUP\n {4}IFNONNULL.*(\n {3}([^b\n]|b[^o\n]|bo[^x\n]|box-impl\d)*)*\n {4}INVOKESTATIC .*require
// 1 BIPUSH 111\n {4}DLOAD 0\n {4}DLOAD 2\n {4}DLOAD 4\n {4}DLOAD 6\n {4}.*toDPointOrNull.*\n {4}INVOKESTATIC .*equals-impl .*\n {4}INVOKESTATIC .*require
@@ -0,0 +1,49 @@
// CHECK_BYTECODE_LISTING
// WITH_STDLIB
// TARGET_BACKEND: JVM_IR
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses
@JvmInline
value class DPoint(val x: Double, val y: Double)
fun acceptBoxed(x: Any?) {}
fun acceptFlattened(x: DPoint) {}
fun returnBoxed() = DPoint(3.0, 4.0)
fun testFlattened2Boxed() {
acceptBoxed(DPoint(1.0, 2.0))
}
fun testBoxed2Boxed() {
acceptBoxed(returnBoxed())
}
fun testFlattened2Flattened() {
acceptFlattened(DPoint(1.0, 2.0))
}
fun testBoxed2Flattened() {
acceptFlattened(returnBoxed())
}
fun testIgnoredFlattened() {
DPoint(1.0, 2.0)
DPoint(1.0, 2.0)
}
fun testIgnoredBoxed() {
returnBoxed()
}
// 1 testFlattened2Boxed\(\)V(\n {3}.*)*((\n {3}.*box-impl .*)(\n {3}.*)*){1}
// 0 testFlattened2Boxed\(\)V(\n {3}.*)*((\n {3}.*box-impl.*)(\n {3}.*)*){2}
// 0 testBoxed2Boxed\(\)V(\n {3}.*)*((\n {3}.*(box-impl|DSTORE|DLOAD).*)(\n {3}.*)*){1}
// 0 testFlattened2Flattened\(\)V(\n {3}.*)*((\n {3}.*box-impl.*)(\n {3}.*)*){1}
// 1 testFlattened2Flattened\(\)V(\n {3}.*)*((\n {3}.*DSTORE.*)(\n {3}.*)*){2}
// 0 testFlattened2Flattened\(\)V(\n {3}.*)*((\n {3}.*DSTORE.*)(\n {3}.*)*){3}
// 0 testBoxed2Flattened\(\)V(\n {3}.*)*((\n {3}.*box-impl .*)(\n {3}.*)*){1}
// 1 testBoxed2Flattened\(\)V(\n {3}.*)*((\n {3}.*unbox-impl.*)(\n {3}.*)*){2}
// 0 testBoxed2Flattened\(\)V(\n {3}.*)*((\n {3}.*unbox-impl.*)(\n {3}.*)*){3}
// 0 testIgnoredFlattened\(\)V(\n {3}.*)*((\n {3}.*box-impl.*)(\n {3}.*)*){1}
// 0 testIgnoredBoxed\(\)V(\n {3}.*)*((\n {3}.*box-impl.*)(\n {3}.*)*){1}
@@ -0,0 +1,149 @@
// CHECK_BYTECODE_LISTING
// WITH_STDLIB
// TARGET_BACKEND: JVM_IR
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses
@JvmInline
value class DPoint(val x: Double, val y: Double) {
val opposite: DPoint
get() = DPoint(-x, -y)
}
class DSegment(var p1: DPoint, var p2: DPoint) {
val center: DPoint
get() = DPoint(p1.x / 2 + p2.x / 2, p1.y / 2 + p2.y / 2)
var notImplemented: DPoint
get() = TODO()
set(_) = TODO()
var point1WithBackingFieldAndDefaultGetter: DPoint = p1
var point2WithBackingFieldAndDefaultGetter: DPoint = p1
get() = field
set(value) {
field = value
require("${2 + 2}" == "4")
}
var pointWithBackingFieldAndCustomGetter: DPoint = p1
get() = field.also { require("${2 + 2}" == "4") }
set(value) {
field = value
require("${2 + 2}" == "4")
}
init {
p1 = p1
}
}
fun tryGetSegment(segment: DSegment) {
segment.p1
segment.p1.x
segment.p1.y
segment.p2
segment.p2.x
segment.p2.y
segment.center
segment.center.x
segment.center.y
segment.notImplemented
segment.notImplemented.x
segment.notImplemented.y
segment.point1WithBackingFieldAndDefaultGetter
segment.point1WithBackingFieldAndDefaultGetter.x
segment.point1WithBackingFieldAndDefaultGetter.y
segment.point2WithBackingFieldAndDefaultGetter
segment.point2WithBackingFieldAndDefaultGetter.x
segment.point2WithBackingFieldAndDefaultGetter.y
segment.pointWithBackingFieldAndCustomGetter
segment.pointWithBackingFieldAndCustomGetter.x
segment.pointWithBackingFieldAndCustomGetter.y
}
fun trySetSegment(segment: DSegment) {
segment.notImplemented = segment.p1
segment.point1WithBackingFieldAndDefaultGetter = segment.p1
segment.point2WithBackingFieldAndDefaultGetter = segment.p1
segment.pointWithBackingFieldAndCustomGetter = segment.p1
segment.p1 = segment.p1
segment.p2 = segment.p2
}
// 0 public final getOpposite\(\)LDPoint;
// 1 public final static getOpposite-impl\(DD\)LDPoint;
// 1 private D p1\$x
// 1 private D p1\$y
// 0 private DPoint; p1
// 1 private D p2\$x
// 1 private D p2\$y
// 0 private DPoint; p2
// 1 private D point1WithBackingFieldAndDefaultGetter\$x
// 1 private D point1WithBackingFieldAndDefaultGetter\$y
// 0 private DPoint; point1WithBackingFieldAndDefaultGetter
// 1 private D point2WithBackingFieldAndDefaultGetter\$x
// 1 private D point2WithBackingFieldAndDefaultGetter\$y
// 0 private DPoint; point2WithBackingFieldAndDefaultGetter
// 1 private D pointWithBackingFieldAndCustomGetter\$x
// 1 private D pointWithBackingFieldAndCustomGetter\$y
// 0 private DPoint; pointWithBackingFieldAndCustomGetter
// 0 private DPoint; notImplemented
// 0 private D notImplemented
// 0 private DPoint; center
// 0 private D center
// 1 public <init>\(DDDD\)V
// 0 public <init>\(DDDD\)V.*(\n {3}.*)*(\n {4}.*box)
// 1 public final getP1\(\)LDPoint;
// 1 public final setP1-sUp7gFk\(DD\)V
// 1 public final getP2\(\)LDPoint;
// 1 public final setP2-sUp7gFk\(DD\)V
// 1 public final getCenter\(\)LDPoint;
// 1 public final getNotImplemented\(\)LDPoint;
// 1 public final setNotImplemented-sUp7gFk\(DD\)V
// 1 public final getPoint1WithBackingFieldAndDefaultGetter\(\)LDPoint;
// 1 public final setPoint1WithBackingFieldAndDefaultGetter-sUp7gFk\(DD\)V
// 1 public final getPoint2WithBackingFieldAndDefaultGetter\(\)LDPoint;
// 1 public final setPoint2WithBackingFieldAndDefaultGetter-sUp7gFk\(DD\)V
// 1 public final getPointWithBackingFieldAndCustomGetter\(\)LDPoint;
// 1 public final setPointWithBackingFieldAndCustomGetter-sUp7gFk\(DD\)V
// 1 public final getP1\$x\(\)D
// 1 public final getP1\$y\(\)D
// 1 public final getP2\$x\(\)D
// 1 public final getP2\$y\(\)D
// 1 public final getPoint1WithBackingFieldAndDefaultGetter\$x\(\)D
// 1 public final getPoint1WithBackingFieldAndDefaultGetter\$y\(\)D
// 1 public final getPoint2WithBackingFieldAndDefaultGetter\$x\(\)D
// 1 public final getPoint2WithBackingFieldAndDefaultGetter\$y\(\)D
// 0 public final getCenter\$
// 0 public final getNotImplemented\$
// 0 public final getPointWithBackingFieldAndCustomGetter\$
// 0 ^ {2}\b.*get.*\$.*(\n {3}.*)*(\n {4}.*\.box)
// 1 tryGetSegment\(LDSegment;\)V
// 0 try[GS]etSegment\(LDSegment;\)V.*(\n {3}.*)*(\n {4}.*\.box)
// 1 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}.*LDPoint;)){13}
// 0 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}.*LDPoint;)){14}
// 0 trySetSegment\(LDSegment;\)V.*(\n {3}.*)*(\n {4}.*LDPoint;)
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setNotImplemented-sUp7gFk \(DD\)V)){1}
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setNotImplemented-sUp7gFk \(DD\)V)){2}
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPoint1WithBackingFieldAndDefaultGetter-sUp7gFk \(DD\)V)){1}
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPoint1WithBackingFieldAndDefaultGetter-sUp7gFk \(DD\)V)){2}
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPoint2WithBackingFieldAndDefaultGetter-sUp7gFk \(DD\)V)){1}
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPoint2WithBackingFieldAndDefaultGetter-sUp7gFk \(DD\)V)){2}
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPointWithBackingFieldAndCustomGetter-sUp7gFk \(DD\)V)){1}
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setPointWithBackingFieldAndCustomGetter-sUp7gFk \(DD\)V)){2}
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setP1-sUp7gFk \(DD\)V)){1}
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setP1-sUp7gFk \(DD\)V)){2}
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setP2-sUp7gFk \(DD\)V)){1}
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DSegment\.setP2-sUp7gFk \(DD\)V)){2}
// 1 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DPoint\.getX \(\)D)){3}
// 0 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DPoint\.getX \(\)D)){4}
// 0 trySetSegment\(LDSegment;\)V.*(\n {3}.*)*(\n {4}INVOKEVIRTUAL DPoint\.getX \(\)D)
// 1 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DPoint\.getY \(\)D)){3}
// 0 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*(\n {4}INVOKEVIRTUAL DPoint\.getY \(\)D)){4}
// 0 trySetSegment\(LDSegment;\)V.*(\n {3}.*)*(\n {4}INVOKEVIRTUAL DPoint\.getY \(\)D)
// 1 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*?(\n {4}INVOKEVIRTUAL DSegment\.get.*\$[xy] \(\)D)){8}
// 0 tryGetSegment\(LDSegment;\)V.*((\n {3}.*)*?(\n {4}INVOKEVIRTUAL DSegment\.get.*\$[xy] \(\)D)){9}
// 1 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*?(\n {4}INVOKEVIRTUAL DSegment\.get.*\$[xy] \(\)D)){12}
// 0 trySetSegment\(LDSegment;\)V.*((\n {3}.*)*?(\n {4}INVOKEVIRTUAL DSegment\.get.*\$[xy] \(\)D)){13}