@@ -117,13 +117,53 @@ public class UseChecker extends AbstractStmtSwitch {
117
117
private ITyping tg ;
118
118
private IUseVisitor uv ;
119
119
120
- private LocalDefs defs = null ;
121
- private LocalUses uses = null ;
122
-
123
120
private static final Logger logger = LoggerFactory .getLogger (UseChecker .class );
124
121
122
+ public static class UseCheckerCache {
123
+ private LocalDefs defs = null ;
124
+ private LocalUses uses = null ;
125
+
126
+ private final Type objectType = Scene .v ().getObjectType ();
127
+ private final JimpleBody body ;
128
+
129
+ public UseCheckerCache (JimpleBody body ) {
130
+ this .body = body ;
131
+ }
132
+
133
+ public Type getObjectType () {
134
+ return objectType ;
135
+ }
136
+
137
+ public LocalDefs getDefs () {
138
+ LocalDefs d = defs ;
139
+ if (d == null ) {
140
+ d = G .v ().soot_toolkits_scalar_LocalDefsFactory ().newLocalDefs (body );
141
+ defs = d ;
142
+ }
143
+ return d ;
144
+ }
145
+
146
+ public LocalUses getUses () {
147
+ LocalUses u = uses ;
148
+ if (u != null ) {
149
+ return u ;
150
+ }
151
+ u = LocalUses .Factory .newLocalUses (body , getDefs ());
152
+ uses = u ;
153
+ return u ;
154
+ }
155
+ }
156
+
157
+ private UseCheckerCache cache ;
158
+
125
159
public UseChecker (JimpleBody jb ) {
126
160
this .jb = jb ;
161
+ cache = new UseCheckerCache (jb );
162
+ }
163
+
164
+ public UseChecker (JimpleBody jb , UseCheckerCache cache ) {
165
+ this .jb = jb ;
166
+ this .cache = cache ;
127
167
}
128
168
129
169
public void check (ITyping tg , IUseVisitor uv ) {
@@ -203,6 +243,9 @@ public void caseAssignStmt(AssignStmt stmt) {
203
243
Value lhs = stmt .getLeftOp ();
204
244
Value rhs = stmt .getRightOp ();
205
245
Type tlhs = null ;
246
+ LocalDefs defs = cache .defs ;
247
+ LocalUses uses = cache .uses ;
248
+ final IUseVisitor uv = this .uv ;
206
249
207
250
if (lhs instanceof Local ) {
208
251
tlhs = this .tg .get ((Local ) lhs );
@@ -221,10 +264,10 @@ public void caseAssignStmt(AssignStmt stmt) {
221
264
// is java.lang.Object
222
265
if (rhs instanceof Local ) {
223
266
Type rhsType = this .tg .get ((Local ) rhs );
224
- if ((tgType == Scene . v () .getObjectType () && rhsType instanceof PrimType ) || tgType instanceof WeakObjectType ) {
267
+ if ((tgType == cache .getObjectType () && rhsType instanceof PrimType ) || tgType instanceof WeakObjectType ) {
225
268
if (defs == null ) {
226
- defs = G . v (). soot_toolkits_scalar_LocalDefsFactory (). newLocalDefs ( jb );
227
- uses = LocalUses . Factory . newLocalUses ( jb , defs );
269
+ defs = cache . getDefs ( );
270
+ uses = cache . getUses ( );
228
271
}
229
272
230
273
// Check the original type of the array from the alloc site
@@ -254,9 +297,9 @@ public void caseAssignStmt(AssignStmt stmt) {
254
297
255
298
this .handleArrayRef (aref , stmt );
256
299
257
- aref .setBase ((Local ) this . uv .visit (aref .getBase (), at , stmt ));
258
- stmt .setRightOp (this . uv .visit (rhs , tlhs , stmt ));
259
- stmt .setLeftOp (this . uv .visit (lhs , tlhs , stmt ));
300
+ aref .setBase ((Local ) uv .visit (aref .getBase (), at , stmt ));
301
+ stmt .setRightOp (uv .visit (rhs , tlhs , stmt ));
302
+ stmt .setLeftOp (uv .visit (lhs , tlhs , stmt ));
260
303
} else if (lhs instanceof FieldRef ) {
261
304
tlhs = ((FieldRef ) lhs ).getFieldRef ().type ();
262
305
if (lhs instanceof InstanceFieldRef ) {
@@ -269,7 +312,7 @@ public void caseAssignStmt(AssignStmt stmt) {
269
312
rhs = stmt .getRightOp ();
270
313
271
314
if (rhs instanceof Local ) {
272
- stmt .setRightOp (this . uv .visit (rhs , tlhs , stmt ));
315
+ stmt .setRightOp (uv .visit (rhs , tlhs , stmt ));
273
316
} else if (rhs instanceof ArrayRef ) {
274
317
ArrayRef aref = (ArrayRef ) rhs ;
275
318
Local base = (Local ) aref .getBase ();
@@ -287,11 +330,11 @@ public void caseAssignStmt(AssignStmt stmt) {
287
330
// For some fixed type T, we assume that we can fix the array to T[].
288
331
if (bt instanceof RefType || bt instanceof NullType ) {
289
332
String btName = bt instanceof NullType ? null : ((RefType ) bt ).getSootClass ().getName ();
290
- if (btName == null || Scene . v () .getObjectType ().toString ().equals (btName ) || "java.io.Serializable" .equals (btName )
333
+ if (btName == null || cache .getObjectType ().toString ().equals (btName ) || "java.io.Serializable" .equals (btName )
291
334
|| "java.lang.Cloneable" .equals (btName )) {
292
335
if (defs == null ) {
293
- defs = G . v (). soot_toolkits_scalar_LocalDefsFactory (). newLocalDefs ( jb );
294
- uses = LocalUses . Factory . newLocalUses ( jb , defs );
336
+ defs = cache . getDefs ( );
337
+ uses = cache . getUses ( );
295
338
}
296
339
// First, we check the definitions. If we can see the definitions and know the array type
297
340
// that way, we are safe.
@@ -409,39 +452,39 @@ public void caseAssignStmt(AssignStmt stmt) {
409
452
410
453
this .handleArrayRef (aref , stmt );
411
454
412
- aref .setBase ((Local ) this . uv .visit (aref .getBase (), at , stmt ));
413
- stmt .setRightOp (this . uv .visit (rhs , trhs , stmt ));
455
+ aref .setBase ((Local ) uv .visit (aref .getBase (), at , stmt ));
456
+ stmt .setRightOp (uv .visit (rhs , trhs , stmt ));
414
457
} else if (rhs instanceof InstanceFieldRef ) {
415
458
this .handleInstanceFieldRef ((InstanceFieldRef ) rhs , stmt );
416
- stmt .setRightOp (this . uv .visit (rhs , tlhs , stmt ));
459
+ stmt .setRightOp (uv .visit (rhs , tlhs , stmt ));
417
460
} else if (rhs instanceof BinopExpr ) {
418
461
this .handleBinopExpr ((BinopExpr ) rhs , stmt , tlhs );
419
462
} else if (rhs instanceof InvokeExpr ) {
420
463
this .handleInvokeExpr ((InvokeExpr ) rhs , stmt );
421
- stmt .setRightOp (this . uv .visit (rhs , tlhs , stmt ));
464
+ stmt .setRightOp (uv .visit (rhs , tlhs , stmt ));
422
465
} else if (rhs instanceof CastExpr ) {
423
- stmt .setRightOp (this . uv .visit (rhs , tlhs , stmt ));
466
+ stmt .setRightOp (uv .visit (rhs , tlhs , stmt ));
424
467
} else if (rhs instanceof InstanceOfExpr ) {
425
468
InstanceOfExpr ioe = (InstanceOfExpr ) rhs ;
426
- ioe .setOp (this . uv .visit (ioe .getOp (), Scene .v ().getObjectType (), stmt ));
427
- stmt .setRightOp (this . uv .visit (rhs , tlhs , stmt ));
469
+ ioe .setOp (uv .visit (ioe .getOp (), Scene .v ().getObjectType (), stmt ));
470
+ stmt .setRightOp (uv .visit (rhs , tlhs , stmt ));
428
471
} else if (rhs instanceof NewArrayExpr ) {
429
472
NewArrayExpr nae = (NewArrayExpr ) rhs ;
430
- nae .setSize (this . uv .visit (nae .getSize (), IntType .v (), stmt ));
431
- stmt .setRightOp (this . uv .visit (rhs , tlhs , stmt ));
473
+ nae .setSize (uv .visit (nae .getSize (), IntType .v (), stmt ));
474
+ stmt .setRightOp (uv .visit (rhs , tlhs , stmt ));
432
475
} else if (rhs instanceof NewMultiArrayExpr ) {
433
476
NewMultiArrayExpr nmae = (NewMultiArrayExpr ) rhs ;
434
477
for (int i = 0 , e = nmae .getSizeCount (); i < e ; i ++) {
435
- nmae .setSize (i , this . uv .visit (nmae .getSize (i ), IntType .v (), stmt ));
478
+ nmae .setSize (i , uv .visit (nmae .getSize (i ), IntType .v (), stmt ));
436
479
}
437
- stmt .setRightOp (this . uv .visit (rhs , tlhs , stmt ));
480
+ stmt .setRightOp (uv .visit (rhs , tlhs , stmt ));
438
481
} else if (rhs instanceof LengthExpr ) {
439
- stmt .setRightOp (this . uv .visit (rhs , tlhs , stmt ));
482
+ stmt .setRightOp (uv .visit (rhs , tlhs , stmt ));
440
483
} else if (rhs instanceof NegExpr ) {
441
- ((NegExpr ) rhs ).setOp (this . uv .visit (((NegExpr ) rhs ).getOp (), tlhs , stmt ));
484
+ ((NegExpr ) rhs ).setOp (uv .visit (((NegExpr ) rhs ).getOp (), tlhs , stmt ));
442
485
} else if (rhs instanceof Constant ) {
443
486
if (!(rhs instanceof NullConstant )) {
444
- stmt .setRightOp (this . uv .visit (rhs , tlhs , stmt ));
487
+ stmt .setRightOp (uv .visit (rhs , tlhs , stmt ));
445
488
}
446
489
}
447
490
}
0 commit comments