Skip to content
This repository
Browse code

no null check for type-tested unapply arg

pattern matching on case classes where pattern
is not known to be a subclass of the unapply's argument type
used to result in code like:

```
if (x1.isInstanceOf[Foo]) {
  val x2 = x1.asInstanceOf[Foo]
  if (x2 != null) { // redundant
    ...
  }
}
```

this wastes byte code on the redundant null check
with this patch, when previous type tests imply
the variable cannot be null, there's no null check
  • Loading branch information...
commit 71ea3e8278aad030cbe8c9093fe49790a4e419cb 1 parent 62b37dd
Adriaan Moors authored January 25, 2013
35  src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -409,6 +409,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
409 409
 
410 410
         // example check: List[Int] <:< ::[Int]
411 411
         // TODO: extractor.paramType may contain unbound type params (run/t2800, run/t3530)
  412
+        // `patBinderOrCasted` is assigned the result of casting `patBinder` to `extractor.paramType`
412 413
         val (typeTestTreeMaker, patBinderOrCasted, binderKnownNonNull) =
413 414
           if (needsTypeTest(patBinder.info.widen, extractor.paramType)) {
414 415
             // chain a type-testing extractor before the actual extractor call
@@ -416,7 +417,11 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
416 417
             // TODO: the outer check is mandated by the spec for case classes, but we do it for user-defined unapplies as well [SPEC]
417 418
             // (the prefix of the argument passed to the unapply must equal the prefix of the type of the binder)
418 419
             val treeMaker = TypeTestTreeMaker(patBinder, patBinder, extractor.paramType, extractor.paramType)(pos, extractorArgTypeTest = true)
419  
-            (List(treeMaker), treeMaker.nextBinder, false)
  420
+
  421
+            // check whether typetest implies patBinder is not null,
  422
+            // even though the eventual null check will be on patBinderOrCasted
  423
+            // it'll be equal to patBinder casted to extractor.paramType anyway (and the type test is on patBinder)
  424
+            (List(treeMaker), treeMaker.nextBinder, treeMaker.impliesBinderNonNull(patBinder))
420 425
           } else {
421 426
             // no type test needed, but the tree maker relies on `patBinderOrCasted` having type `extractor.paramType` (and not just some type compatible with it)
422 427
             // SI-6624 shows this is necessary because apparently patBinder may have an unfortunate type (.decls don't have the case field accessors)
@@ -773,11 +778,16 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
773 778
       def resultType = tpe.finalResultType
774 779
       def isSeq      = extractorCall.symbol.name == nme.unapplySeq
775 780
 
776  
-       /** Create the TreeMaker that embodies this extractor call
777  
-        *
778  
-        * `binder` has been casted to `paramType` if necessary
779  
-        * `binderKnownNonNull` is not used in this subclass
780  
-        */
  781
+      /** Create the TreeMaker that embodies this extractor call
  782
+       *
  783
+       *  `binder` has been casted to `paramType` if necessary
  784
+       *  `binderKnownNonNull` is not used in this subclass
  785
+       *
  786
+       *  TODO: implement review feedback by @retronym:
  787
+       *    Passing the pair of values around suggests:
  788
+       *       case class Binder(sym: Symbol, knownNotNull: Boolean).
  789
+       *    Perhaps it hasn't reached critical mass, but it would already clean things up a touch.
  790
+       */
781 791
       def treeMaker(patBinderOrCasted: Symbol, binderKnownNonNull: Boolean, pos: Position): TreeMaker = {
782 792
         // the extractor call (applied to the binder bound by the flatMap corresponding to the previous (i.e., enclosing/outer) pattern)
783 793
         val extractorApply = atPos(pos)(spliceApply(patBinderOrCasted))
@@ -1177,6 +1187,17 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
1177 1187
         def eqTest(pat: Tree, testedBinder: Symbol): Result           = false
1178 1188
         def and(a: Result, b: Result): Result                         = false // we don't and type tests, so the conjunction must include at least one false
1179 1189
       }
  1190
+
  1191
+      def nonNullImpliedByTestChecker(binder: Symbol) = new TypeTestCondStrategy {
  1192
+        type Result = Boolean
  1193
+
  1194
+        def typeTest(testedBinder: Symbol, expectedTp: Type): Result  = testedBinder eq binder
  1195
+        def outerTest(testedBinder: Symbol, expectedTp: Type): Result = false
  1196
+        def nonNullTest(testedBinder: Symbol): Result                 = testedBinder eq binder
  1197
+        def equalsTest(pat: Tree, testedBinder: Symbol): Result       = false // could in principle analyse pat and see if it's statically known to be non-null
  1198
+        def eqTest(pat: Tree, testedBinder: Symbol): Result           = false // could in principle analyse pat and see if it's statically known to be non-null
  1199
+        def and(a: Result, b: Result): Result                         = a || b
  1200
+      }
1180 1201
     }
1181 1202
 
1182 1203
     /** implements the run-time aspects of (§8.2) (typedPattern has already done the necessary type transformations)
@@ -1260,6 +1281,8 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
1260 1281
       // is this purely a type test, e.g. no outer check, no equality tests (used in switch emission)
1261 1282
       def isPureTypeTest = renderCondition(pureTypeTestChecker)
1262 1283
 
  1284
+      def impliesBinderNonNull(binder: Symbol) = renderCondition(nonNullImpliedByTestChecker(binder))
  1285
+
1263 1286
       override def toString = "TT"+(expectedTp, testedBinder.name, nextBinderTp)
1264 1287
     }
1265 1288
 
1  test/files/jvm/patmat_opt_no_nullcheck.check
... ...
@@ -0,0 +1 @@
  1
+bytecode identical
1  test/files/jvm/patmat_opt_no_nullcheck.flags
... ...
@@ -0,0 +1 @@
  1
+-optimize
25  test/files/jvm/patmat_opt_no_nullcheck/Analyzed_1.scala
... ...
@@ -0,0 +1,25 @@
  1
+// this class's bytecode, compiled under -optimize is analyzed by the test
  2
+// method a's bytecode should be identical to method b's bytecode
  3
+case class Foo(x: Any)
  4
+
  5
+class SameBytecode {
  6
+  def a = 
  7
+    (Foo(1): Any) match {
  8
+      case Foo(_: String) =>
  9
+    }
  10
+
  11
+  // there's no null check
  12
+  def b: Unit = {
  13
+    val x1: Any = Foo(1)
  14
+    if (x1.isInstanceOf[Foo]) {
  15
+      val x3 = x1.asInstanceOf[Foo]
  16
+      if (x3.x.isInstanceOf[String]) {
  17
+        val x4 = x3.x.asInstanceOf[String]
  18
+        val x = ()
  19
+        return
  20
+      }
  21
+    }
  22
+
  23
+    throw new MatchError(x1)
  24
+  }
  25
+}
8  test/files/jvm/patmat_opt_no_nullcheck/test.scala
... ...
@@ -0,0 +1,8 @@
  1
+import scala.tools.partest.BytecodeTest
  2
+
  3
+object Test extends BytecodeTest {
  4
+  def show: Unit = {
  5
+    val classNode = loadClassNode("SameBytecode")
  6
+    sameBytecode(getMethod(classNode, "a"), getMethod(classNode, "b"))
  7
+  }
  8
+}
206  test/files/run/inline-ex-handlers.check
@@ -26,54 +26,55 @@
26 26
 ---
27 27
 >   locals: value args, variable result, value ex6, value x4, value x5, value x
28 28
 397c393
29  
-<   blocks: [1,2,3,4,5,8,11,13,14,16]
  29
+<   blocks: [1,2,3,4,5,8,10,11,13]
30 30
 ---
31  
->   blocks: [1,2,3,5,8,11,13,14,16,17]
  31
+>   blocks: [1,2,3,5,8,10,11,13,14]
32 32
 421c417,426
33 33
 <     103	THROW(MyException)
34 34
 ---
35 35
 >     ?	STORE_LOCAL(value ex6)
36  
->     ?	JUMP 17
  36
+>     ?	JUMP 14
37 37
 >     
38  
->   17: 
  38
+>   14: 
39 39
 >     101	LOAD_LOCAL(value ex6)
40 40
 >     101	STORE_LOCAL(value x4)
41 41
 >     101	SCOPE_ENTER value x4
42 42
 >     106	LOAD_LOCAL(value x4)
43 43
 >     106	IS_INSTANCE REF(class MyException)
44  
->     106	CZJUMP (BOOL)NE ? 5 : 11
  44
+>     106	CZJUMP (BOOL)NE ? 5 : 8
45 45
 434,436d438
46 46
 <     101	JUMP 4
47 47
 <     
48 48
 <   4: 
49  
-450,453d451
  49
+446,449d447
50 50
 <     106	LOAD_LOCAL(value x5)
51 51
 <     106	CALL_METHOD MyException.message (dynamic)
52 52
 <     106	STORE_LOCAL(value message)
53 53
 <     106	SCOPE_ENTER value message
54  
-455c453,454
  54
+451c449,450
55 55
 <     106	LOAD_LOCAL(value message)
56 56
 ---
57 57
 >     ?	LOAD_LOCAL(value x5)
58 58
 >     106	CALL_METHOD MyException.message (dynamic)
59  
-527c526
  59
+523c522
60 60
 <   blocks: [1,2,3,4,6,7,8,9,10]
61 61
 ---
62 62
 >   blocks: [1,2,3,4,6,7,8,9,10,11,12,13]
63  
-556c555,560
  63
+552c551
64 64
 <     306	THROW(MyException)
65 65
 ---
66 66
 >     ?	JUMP 11
67  
->     
  67
+553a553,557
68 68
 >   11: 
69 69
 >     ?	LOAD_LOCAL(variable monitor4)
70 70
 >     305	MONITOR_EXIT
71 71
 >     ?	JUMP 12
72  
-562c566
  72
+>     
  73
+558c562
73 74
 <     ?	THROW(Throwable)
74 75
 ---
75 76
 >     ?	JUMP 12
76  
-568c572,579
  77
+564c568,575
77 78
 <     ?	THROW(Throwable)
78 79
 ---
79 80
 >     ?	STORE_LOCAL(value t)
@@ -84,7 +85,7 @@
84 85
 >     304	MONITOR_EXIT
85 86
 >     ?	STORE_LOCAL(value t)
86 87
 >     ?	JUMP 13
87  
-583a595,606
  88
+579a591,602
88 89
 >   13: 
89 90
 >     310	LOAD_MODULE object Predef
90 91
 >     310	CALL_PRIMITIVE(StartConcat)
@@ -97,35 +98,35 @@
97 98
 >     310	CALL_METHOD scala.Predef.println (dynamic)
98 99
 >     310	JUMP 2
99 100
 >     
100  
-592c615
  101
+588c611
101 102
 <     catch (Throwable) in ArrayBuffer(7, 8, 9, 10) starting at: 6
102 103
 ---
103 104
 >     catch (Throwable) in ArrayBuffer(7, 8, 9, 10, 11) starting at: 6
104  
-595c618
  105
+591c614
105 106
 <     catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10) starting at: 3
106 107
 ---
107 108
 >     catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10, 11, 12) starting at: 3
108  
-627c650
  109
+623c646
109 110
 <   blocks: [1,2,3,4,5,6,7,9,10]
110 111
 ---
111 112
 >   blocks: [1,2,3,4,5,6,7,9,10,11,12]
112  
-651c674,675
  113
+647c670,671
113 114
 <     78	THROW(IllegalArgumentException)
114 115
 ---
115 116
 >     ?	STORE_LOCAL(value e)
116 117
 >     ?	JUMP 11
117  
-652a677,681
  118
+648a673,677
118 119
 >   11: 
119 120
 >     81	LOAD_LOCAL(value e)
120 121
 >     ?	STORE_LOCAL(variable exc1)
121 122
 >     ?	JUMP 12
122 123
 >     
123  
-680c709,710
  124
+676c705,706
124 125
 <     81	THROW(Exception)
125 126
 ---
126 127
 >     ?	STORE_LOCAL(variable exc1)
127 128
 >     ?	JUMP 12
128  
-696a727,739
  129
+692a723,735
129 130
 >   12: 
130 131
 >     83	LOAD_MODULE object Predef
131 132
 >     83	CONSTANT("finally")
@@ -139,88 +140,88 @@
139 140
 >     84	LOAD_LOCAL(variable exc1)
140 141
 >     84	THROW(Throwable)
141 142
 >     
142  
-702c745
  143
+698c741
143 144
 <     catch (<none>) in ArrayBuffer(4, 6, 7, 9) starting at: 3
144 145
 ---
145 146
 >     catch (<none>) in ArrayBuffer(4, 6, 7, 9, 11) starting at: 3
146  
-726c769
  147
+722c765
147 148
 <   locals: value args, variable result, value ex6, variable exc2, value x4, value x5, value message, value x, value ex6, value x4, value x5, value message, value x
148 149
 ---
149 150
 >   locals: value args, variable result, value ex6, variable exc2, value x4, value x5, value x, value ex6, value x4, value x5, value x
150  
-728c771
151  
-<   blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31]
  151
+724c767
  152
+<   blocks: [1,2,3,4,5,6,9,11,14,15,16,19,21,22,24,25]
152 153
 ---
153  
->   blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31,32,33,34]
154  
-752c795,802
  154
+>   blocks: [1,2,3,4,5,6,9,11,14,15,16,19,21,22,24,25,26,27,28]
  155
+748c791,798
155 156
 <     172	THROW(MyException)
156 157
 ---
157 158
 >     ?	STORE_LOCAL(value ex6)
158  
->     ?	JUMP 32
  159
+>     ?	JUMP 26
159 160
 >     
160  
->   32: 
  161
+>   26: 
161 162
 >     170	LOAD_LOCAL(value ex6)
162 163
 >     170	STORE_LOCAL(value x4)
163 164
 >     170	SCOPE_ENTER value x4
164  
->     170	JUMP 18
165  
-799,802d848
  165
+>     170	JUMP 15
  166
+791,794d840
166 167
 <     175	LOAD_LOCAL(value x5)
167 168
 <     175	CALL_METHOD MyException.message (dynamic)
168 169
 <     175	STORE_LOCAL(value message)
169 170
 <     175	SCOPE_ENTER value message
170  
-804c850,851
  171
+796c842,843
171 172
 <     176	LOAD_LOCAL(value message)
172 173
 ---
173 174
 >     ?	LOAD_LOCAL(value x5)
174 175
 >     176	CALL_METHOD MyException.message (dynamic)
175  
-808c855,856
  176
+800c847,848
176 177
 <     177	LOAD_LOCAL(value message)
177 178
 ---
178 179
 >     ?	LOAD_LOCAL(value x5)
179 180
 >     177	CALL_METHOD MyException.message (dynamic)
180  
-810c858,859
  181
+802c850,851
181 182
 <     177	THROW(MyException)
182 183
 ---
183 184
 >     ?	STORE_LOCAL(value ex6)
184  
->     ?	JUMP 33
185  
-814c863,864
  185
+>     ?	JUMP 27
  186
+806c855,856
186 187
 <     170	THROW(Throwable)
187 188
 ---
188 189
 >     ?	STORE_LOCAL(value ex6)
189  
->     ?	JUMP 33
190  
-823a874,879
191  
->   33: 
  190
+>     ?	JUMP 27
  191
+815a866,871
  192
+>   27: 
192 193
 >     169	LOAD_LOCAL(value ex6)
193 194
 >     169	STORE_LOCAL(value x4)
194 195
 >     169	SCOPE_ENTER value x4
195 196
 >     169	JUMP 5
196 197
 >     
197  
-838,841d893
  198
+826,829d881
198 199
 <     180	LOAD_LOCAL(value x5)
199 200
 <     180	CALL_METHOD MyException.message (dynamic)
200 201
 <     180	STORE_LOCAL(value message)
201 202
 <     180	SCOPE_ENTER value message
202  
-843c895,896
  203
+831c883,884
203 204
 <     181	LOAD_LOCAL(value message)
204 205
 ---
205 206
 >     ?	LOAD_LOCAL(value x5)
206 207
 >     181	CALL_METHOD MyException.message (dynamic)
207  
-847c900,901
  208
+835c888,889
208 209
 <     182	LOAD_LOCAL(value message)
209 210
 ---
210 211
 >     ?	LOAD_LOCAL(value x5)
211 212
 >     182	CALL_METHOD MyException.message (dynamic)
212  
-849c903,904
  213
+837c891,892
213 214
 <     182	THROW(MyException)
214 215
 ---
215 216
 >     ?	STORE_LOCAL(variable exc2)
216  
->     ?	JUMP 34
217  
-853c908,909
  217
+>     ?	JUMP 28
  218
+841c896,897
218 219
 <     169	THROW(Throwable)
219 220
 ---
220 221
 >     ?	STORE_LOCAL(variable exc2)
221  
->     ?	JUMP 34
222  
-869a926,938
223  
->   34: 
  222
+>     ?	JUMP 28
  223
+857a914,926
  224
+>   28: 
224 225
 >     184	LOAD_MODULE object Predef
225 226
 >     184	CONSTANT("finally")
226 227
 >     184	CALL_METHOD scala.Predef.println (dynamic)
@@ -233,159 +234,158 @@
233 234
 >     185	LOAD_LOCAL(variable exc2)
234 235
 >     185	THROW(Throwable)
235 236
 >     
236  
-875c944
237  
-<     catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30) starting at: 4
  237
+863c932
  238
+<     catch (Throwable) in ArrayBuffer(14, 15, 16, 19, 21, 22, 24) starting at: 4
238 239
 ---
239  
->     catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30, 32) starting at: 4
240  
-878c947
241  
-<     catch (<none>) in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30) starting at: 3
  240
+>     catch (Throwable) in ArrayBuffer(14, 15, 16, 19, 21, 22, 24, 26) starting at: 4
  241
+866c935
  242
+<     catch (<none>) in ArrayBuffer(4, 5, 6, 9, 14, 15, 16, 19, 21, 22, 24) starting at: 3
242 243
 ---
243  
->     catch (<none>) in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30, 32, 33) starting at: 3
244  
-902c971
  244
+>     catch (<none>) in ArrayBuffer(4, 5, 6, 9, 14, 15, 16, 19, 21, 22, 24, 26, 27) starting at: 3
  245
+890c959
245 246
 <   locals: value args, variable result, value e, value ex6, value x4, value x5, value message, value x
246 247
 ---
247 248
 >   locals: value args, variable result, value e, value ex6, value x4, value x5, value x
248  
-904c973
249  
-<   blocks: [1,2,3,6,7,8,11,14,16,17,19]
  249
+892c961
  250
+<   blocks: [1,2,3,6,7,8,11,13,14,16]
250 251
 ---
251  
->   blocks: [1,2,3,6,7,8,11,14,16,17,19,20]
252  
-928c997,1004
  252
+>   blocks: [1,2,3,6,7,8,11,13,14,16,17]
  253
+916c985,992
253 254
 <     124	THROW(MyException)
254 255
 ---
255 256
 >     ?	STORE_LOCAL(value ex6)
256  
->     ?	JUMP 20
  257
+>     ?	JUMP 17
257 258
 >     
258  
->   20: 
  259
+>   17: 
259 260
 >     122	LOAD_LOCAL(value ex6)
260 261
 >     122	STORE_LOCAL(value x4)
261 262
 >     122	SCOPE_ENTER value x4
262 263
 >     122	JUMP 7
263  
-957,960d1032
  264
+941,944d1016
264 265
 <     127	LOAD_LOCAL(value x5)
265 266
 <     127	CALL_METHOD MyException.message (dynamic)
266 267
 <     127	STORE_LOCAL(value message)
267 268
 <     127	SCOPE_ENTER value message
268  
-962c1034,1035
  269
+946c1018,1019
269 270
 <     127	LOAD_LOCAL(value message)
270 271
 ---
271 272
 >     ?	LOAD_LOCAL(value x5)
272 273
 >     127	CALL_METHOD MyException.message (dynamic)
273  
-991c1064
274  
-<     catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19) starting at: 3
  274
+975c1048
  275
+<     catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 13, 14, 16) starting at: 3
275 276
 ---
276  
->     catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19, 20) starting at: 3
277  
-1015c1088
  277
+>     catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 13, 14, 16, 17) starting at: 3
  278
+999c1072
278 279
 <   locals: value args, variable result, value ex6, value x4, value x5, value message, value x, value e
279 280
 ---
280 281
 >   locals: value args, variable result, value ex6, value x4, value x5, value x, value e
281  
-1017c1090
282  
-<   blocks: [1,2,3,4,5,8,11,15,16,17,19]
  282
+1001c1074
  283
+<   blocks: [1,2,3,4,5,8,12,13,14,16]
283 284
 ---
284  
->   blocks: [1,2,3,5,8,11,15,16,17,19,20]
285  
-1041c1114,1123
  285
+>   blocks: [1,2,3,5,8,12,13,14,16,17]
  286
+1025c1098,1107
286 287
 <     148	THROW(MyException)
287 288
 ---
288 289
 >     ?	STORE_LOCAL(value ex6)
289  
->     ?	JUMP 20
  290
+>     ?	JUMP 17
290 291
 >     
291  
->   20: 
  292
+>   17: 
292 293
 >     145	LOAD_LOCAL(value ex6)
293 294
 >     145	STORE_LOCAL(value x4)
294 295
 >     145	SCOPE_ENTER value x4
295 296
 >     154	LOAD_LOCAL(value x4)
296 297
 >     154	IS_INSTANCE REF(class MyException)
297  
->     154	CZJUMP (BOOL)NE ? 5 : 11
298  
-1062,1064d1143
  298
+>     154	CZJUMP (BOOL)NE ? 5 : 8
  299
+1046,1048d1127
299 300
 <     145	JUMP 4
300 301
 <     
301 302
 <   4: 
302  
-1078,1081d1156
  303
+1058,1061d1136
303 304
 <     154	LOAD_LOCAL(value x5)
304 305
 <     154	CALL_METHOD MyException.message (dynamic)
305 306
 <     154	STORE_LOCAL(value message)
306 307
 <     154	SCOPE_ENTER value message
307  
-1083c1158,1159
  308
+1063c1138,1139
308 309
 <     154	LOAD_LOCAL(value message)
309 310
 ---
310 311
 >     ?	LOAD_LOCAL(value x5)
311 312
 >     154	CALL_METHOD MyException.message (dynamic)
312  
-1300c1376
  313
+1280c1356
313 314
 <   blocks: [1,2,3,4,5,7]
314 315
 ---
315 316
 >   blocks: [1,2,3,4,5,7,8]
316  
-1324c1400,1401
  317
+1304c1380,1387
317 318
 <     38	THROW(IllegalArgumentException)
318 319
 ---
319 320
 >     ?	STORE_LOCAL(value e)
320 321
 >     ?	JUMP 8
321  
-1325a1403,1408
  322
+>     
322 323
 >   8: 
323 324
 >     42	LOAD_MODULE object Predef
324 325
 >     42	CONSTANT("IllegalArgumentException")
325 326
 >     42	CALL_METHOD scala.Predef.println (dynamic)
326 327
 >     42	JUMP 2
327  
->     
328  
-1371c1454
  328
+1351c1434
329 329
 <   locals: value args, variable result, value ex6, value x4, value x5, value message, value x
330 330
 ---
331 331
 >   locals: value args, variable result, value ex6, value x4, value x5, value x
332  
-1373c1456
333  
-<   blocks: [1,2,3,4,5,8,11,13,14,16,17,19]
  332
+1353c1436
  333
+<   blocks: [1,2,3,4,5,8,10,11,13,14,16]
334 334
 ---
335  
->   blocks: [1,2,3,5,8,11,13,14,16,17,19,20]
336  
-1397c1480,1481
  335
+>   blocks: [1,2,3,5,8,10,11,13,14,16,17]
  336
+1377c1460,1461
337 337
 <     203	THROW(MyException)
338 338
 ---
339 339
 >     ?	STORE_LOCAL(value ex6)
340  
->     ?	JUMP 20
341  
-1417c1501,1510
  340
+>     ?	JUMP 17
  341
+1397c1481,1490
342 342
 <     209	THROW(MyException)
343 343
 ---
344 344
 >     ?	STORE_LOCAL(value ex6)
345  
->     ?	JUMP 20
  345
+>     ?	JUMP 17
346 346
 >     
347  
->   20: 
  347
+>   17: 
348 348
 >     200	LOAD_LOCAL(value ex6)
349 349
 >     200	STORE_LOCAL(value x4)
350 350
 >     200	SCOPE_ENTER value x4
351 351
 >     212	LOAD_LOCAL(value x4)
352 352
 >     212	IS_INSTANCE REF(class MyException)
353  
->     212	CZJUMP (BOOL)NE ? 5 : 11
354  
-1430,1432d1522
  353
+>     212	CZJUMP (BOOL)NE ? 5 : 8
  354
+1410,1412d1502
355 355
 <     200	JUMP 4
356 356
 <     
357 357
 <   4: 
358  
-1446,1449d1535
  358
+1422,1425d1511
359 359
 <     212	LOAD_LOCAL(value x5)
360 360
 <     212	CALL_METHOD MyException.message (dynamic)
361 361
 <     212	STORE_LOCAL(value message)
362 362
 <     212	SCOPE_ENTER value message
363  
-1451c1537,1538
  363
+1427c1513,1514
364 364
 <     213	LOAD_LOCAL(value message)
365 365
 ---
366 366
 >     ?	LOAD_LOCAL(value x5)
367 367
 >     213	CALL_METHOD MyException.message (dynamic)
368  
-1495c1582
  368
+1471c1558
369 369
 <   blocks: [1,2,3,4,5,7]
370 370
 ---
371 371
 >   blocks: [1,2,3,4,5,7,8]
372  
-1519c1606,1607
  372
+1495c1582,1583
373 373
 <     58	THROW(IllegalArgumentException)
374 374
 ---
375 375
 >     ?	STORE_LOCAL(value e)
376 376
 >     ?	JUMP 8
377  
-1520a1609,1614
  377
+1496a1585,1590
378 378
 >   8: 
379 379
 >     62	LOAD_MODULE object Predef
380 380
 >     62	CONSTANT("RuntimeException")
381 381
 >     62	CALL_METHOD scala.Predef.println (dynamic)
382 382
 >     62	JUMP 2
383 383
 >     
384  
-1568c1662
  384
+1544c1638
385 385
 <   blocks: [1,2,3,4]
386 386
 ---
387 387
 >   blocks: [1,2,3,4,5]
388  
-1588c1682,1687
  388
+1564c1658,1663
389 389
 <     229	THROW(MyException)
390 390
 ---
391 391
 >     ?	JUMP 5
@@ -394,19 +394,19 @@
394 394
 >     ?	LOAD_LOCAL(variable monitor1)
395 395
 >     228	MONITOR_EXIT
396 396
 >     228	THROW(Throwable)
397  
-1594c1693
  397
+1570c1669
398 398
 <     ?	THROW(Throwable)
399 399
 ---
400 400
 >     228	THROW(Throwable)
401  
-1622c1721
  401
+1598c1697
402 402
 <   locals: value args, variable result, variable monitor2, variable monitorResult1
403 403
 ---
404 404
 >   locals: value exception$1, value args, variable result, variable monitor2, variable monitorResult1
405  
-1624c1723
  405
+1600c1699
406 406
 <   blocks: [1,2,3,4]
407 407
 ---
408 408
 >   blocks: [1,2,3,4,5]
409  
-1647c1746,1754
  409
+1623c1722,1730
410 410
 <     245	THROW(MyException)
411 411
 ---
412 412
 >     ?	STORE_LOCAL(value exception$1)
@@ -418,7 +418,7 @@
418 418
 >     ?	LOAD_LOCAL(variable monitor2)
419 419
 >     244	MONITOR_EXIT
420 420
 >     244	THROW(Throwable)
421  
-1653c1760
  421
+1629c1736
422 422
 <     ?	THROW(Throwable)
423 423
 ---
424 424
 >     244	THROW(Throwable)

0 notes on commit 71ea3e8

Please sign in to comment.
Something went wrong with that request. Please try again.