@@ -213,6 +213,22 @@ private List<ImExpr> collectSideEffects(ImExpr expr, SideEffectAnalyzer analyzer
213213 }
214214
215215 private boolean mayTrapAtRuntime (Element elem ) {
216+ return mayTrapAtRuntime (elem , new HashMap <>(), new LinkedHashSet <>());
217+ }
218+
219+ private boolean mayTrapAtRuntime (Element elem , Map <ImFunction , Boolean > functionCache , Set <ImFunction > inProgress ) {
220+ if (elem instanceof ImFunctionCall ) {
221+ ImFunction calledFunc = ((ImFunctionCall ) elem ).getFunc ();
222+ if (functionMayTrapAtRuntime (calledFunc , functionCache , inProgress )) {
223+ return true ;
224+ }
225+ } else if (elem instanceof ImMethodCall ) {
226+ ImFunction calledFunc = ((ImMethodCall ) elem ).getMethod ().getImplementation ();
227+ if (calledFunc == null || functionMayTrapAtRuntime (calledFunc , functionCache , inProgress )) {
228+ return true ;
229+ }
230+ }
231+
216232 if (elem instanceof ImOperatorCall ) {
217233 ImOperatorCall opCall = (ImOperatorCall ) elem ;
218234 WurstOperator op = opCall .getOp ();
@@ -226,10 +242,31 @@ private boolean mayTrapAtRuntime(Element elem) {
226242 }
227243 for (int i = 0 ; i < elem .size (); i ++) {
228244 Element child = elem .get (i );
229- if (mayTrapAtRuntime (child )) {
245+ if (mayTrapAtRuntime (child , functionCache , inProgress )) {
230246 return true ;
231247 }
232248 }
233249 return false ;
234250 }
251+
252+ private boolean functionMayTrapAtRuntime (ImFunction function , Map <ImFunction , Boolean > functionCache , Set <ImFunction > inProgress ) {
253+ if (function .isNative ()) {
254+ return false ;
255+ }
256+
257+ Boolean cachedResult = functionCache .get (function );
258+ if (cachedResult != null ) {
259+ return cachedResult ;
260+ }
261+
262+ if (!inProgress .add (function )) {
263+ // Recursive cycles are conservatively treated as potentially trapping.
264+ return true ;
265+ }
266+
267+ boolean mayTrap = mayTrapAtRuntime (function .getBody (), functionCache , inProgress );
268+ inProgress .remove (function );
269+ functionCache .put (function , mayTrap );
270+ return mayTrap ;
271+ }
235272}
0 commit comments