in src/main/java/org/apache/commons/jexl3/internal/Interpreter.java [854:918]
public Object interpret(final JexlNode node) {
JexlContext.ThreadLocal tcontext = null;
JexlEngine tjexl = null;
Interpreter tinter = null;
try {
tinter = putThreadInterpreter(this);
if (tinter != null) {
fp = tinter.fp + 1;
}
if (context instanceof JexlContext.ThreadLocal) {
tcontext = jexl.putThreadLocal((JexlContext.ThreadLocal) context);
}
tjexl = jexl.putThreadEngine(jexl);
if (fp > jexl.stackOverflow) {
throw new JexlException.StackOverflow(node.jexlInfo(), "jexl (" + jexl.stackOverflow + ")", null);
}
cancelCheck(node);
return arithmetic.controlReturn(node.jjtAccept(this, null));
} catch (final StackOverflowError xstack) {
final JexlException xjexl = new JexlException.StackOverflow(node.jexlInfo(), "jvm", xstack);
if (!isSilent()) {
throw xjexl.clean();
}
if (logger.isWarnEnabled()) {
logger.warn(xjexl.getMessage(), xjexl.getCause());
}
} catch (final JexlException.Return xreturn) {
return xreturn.getValue();
} catch (final JexlException.Cancel xcancel) {
// cancelled |= Thread.interrupted();
cancelled.weakCompareAndSet(false, Thread.interrupted());
if (isCancellable()) {
throw xcancel.clean();
}
} catch (final JexlException xjexl) {
if (!isSilent()) {
throw xjexl.clean();
}
if (logger.isWarnEnabled()) {
logger.warn(xjexl.getMessage(), xjexl.getCause());
}
} finally {
// clean functors at top level
if (fp == 0) {
synchronized (this) {
if (functors != null) {
for (final Object functor : functors.values()) {
closeIfSupported(functor);
}
functors.clear();
functors = null;
}
}
}
jexl.putThreadEngine(tjexl);
if (context instanceof JexlContext.ThreadLocal) {
jexl.putThreadLocal(tcontext);
}
if (tinter != null) {
fp = tinter.fp - 1;
}
putThreadInterpreter(tinter);
}
return null;
}