eval4j compiling expressions to be evaluated by the debugger andrey.breslav@
.com
Stop at a breakpoint Inspect call stacks Inspect memory Evaluate given Evaluate given expression expression Debugger Features • Stopping at breakpoints – step over/into/out • Inspec?ng memory contents – variables on stack – object fields/array cells • Evalua?ng expressions – watches – condi?onal breakpoints – logging breakpoints Working Horse: Bare JDI • Access Variables • Access Fields • Call Methods • No Evaluate Expression out-‐of-‐the-‐box How it’s done for Java • IntelliJ has an intepreter for Java expressions – wriOen from scratch – yet another defini?on of seman?cs – may disagree with the compiler’s seman?cs • Well, IntelliJ’s not very in?mate with javac
When you have your own compiler? • Eclipse Java DT s?ll has an interpreter • Scala IDE (Eclipse) — no Evaluate Expression • Ceylon IDE (Eclipse) — no Evaluate Expression • There’s some room for improvement… What we don’t want • Re-‐implement the seman?cs just for this task – Use what we already have – In case of Kotlin/Java/Scala – the compiler What actually happens for Java • IntelliJ – interpreter for Java expressions – Understandable: javac is run as an external process • NetBeans – dedicated interpreter – Umm… • Eclipse – dedicated interpreter – Huh? What happens for others • Scala – IntelliJ – dedicated interpreter • Same story: scalac is an external process – Eclipse – Evaluate Expression is not supported • Ceylon – ??? Reuse the Compiler (Take 1) a + b compile .class file load run Debugee process Eval4j: Bytecode Interpreter • foo.x + 2 –
–
–
–
ALOAD 1
GETFIELD Foo.x : I
ICONST_2
IADD
– INVOKESTATIC kotlin/io/IoPackage.println (I)V • hOps://github.com/abreslav/eval4j • Re-‐uses ASM’s Interpreter Compiling an expression free variables Extract Method Refactoring Summary so far Extract Method + Compiler + eval4j = Evaluate Expression Challenge: Lambdas/Anonymous Classes • Not supported for Java/Scala • Problems: – New class that is not available in the debugee process – That class may access privates that it’s not allowed to access Challenge: New Classes private? • Also: How do you load a class into the debugee? Loading a class… • protected Class<?> defineClass(byte[], …) How Privates Work Normally • Special synthe?c accessor methods – INVOKESTATIC Foo.access$001()
– can’t insert a new method into the outer class Prepare the methods of the lambda • Evaluate the body of the method public Object invoke() {
Object result = null;
Throwable exception = null;
if (exception == null)
return result;
else throw exception;
}
What happens to your thread • You stopped on a bp1 • You evaluated an expression – Set another bp – Stopped on it – Computed something – Resulmed – => you are not on bp1 any more Workaround • Start a special thread while (true) {
nop();
}
• To stop: boolean done = false;
while (!done) {
nop();
}
Summary • Prerequisites – Extract method – Ability to compile with some tweaks • Results – Any expressions/statements – Lambdas/local classes • Use it for your language! – hOps://github.com/abreslav/eval4j
© Copyright 2026 Paperzz