eval4j
compiling expressions to be
evaluated by the debugger
andrey.breslav@ .com
Stop at a
breakpoint
Inspect memoryInspect call stacks
Evaluate given
expression
Evaluate given
expression
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
– written from scratch
– yet another definition of semantics
– may disagree with the compiler’s semantics
• Well, IntelliJ’s not very intimate with javac
When you have your own compiler?
• Eclipse Java DT still has an interpreter
• Scala IDE (Eclipse) — no Evaluate Expression
• Ceylon IDE (Eclipse) — no Evaluate Expression
• There’s some room for improvement…
Reuse the Compiler (Take 1)
a + b
.class
file
Debugee
process
compile
load
run
Eval4j: Bytecode Interpreter
• foo.x + 2
– ALOAD 1
– GETFIELD Foo.x : I
– ICONST_2
– IADD
– INVOKESTATIC kotlin/io/IoPackage.println (I)V
• https://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 synthetic 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!
– https://github.com/abreslav/eval4j

Eval4j @ JVMLS 2014

  • 1.
    eval4j compiling expressions tobe evaluated by the debugger andrey.breslav@ .com
  • 3.
    Stop at a breakpoint InspectmemoryInspect call stacks
  • 4.
  • 6.
    Working Horse: BareJDI • Access Variables • Access Fields • Call Methods • No Evaluate Expression out-of-the-box
  • 7.
    How it’s donefor Java • IntelliJ has an intepreter for Java expressions – written from scratch – yet another definition of semantics – may disagree with the compiler’s semantics • Well, IntelliJ’s not very intimate with javac
  • 8.
    When you haveyour own compiler? • Eclipse Java DT still has an interpreter • Scala IDE (Eclipse) — no Evaluate Expression • Ceylon IDE (Eclipse) — no Evaluate Expression • There’s some room for improvement…
  • 9.
    Reuse the Compiler(Take 1) a + b .class file Debugee process compile load run
  • 10.
    Eval4j: Bytecode Interpreter •foo.x + 2 – ALOAD 1 – GETFIELD Foo.x : I – ICONST_2 – IADD – INVOKESTATIC kotlin/io/IoPackage.println (I)V • https://github.com/abreslav/eval4j • Re-uses ASM’s Interpreter
  • 11.
    Compiling an expression freevariables Extract Method Refactoring
  • 12.
    Summary so far ExtractMethod + Compiler + eval4j = Evaluate Expression
  • 13.
    Challenge: Lambdas/Anonymous Classes • Notsupported 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
  • 14.
    Challenge: New Classes private? •Also: How do you load a class into the debugee?
  • 15.
    Loading a class… •protected Class<?> defineClass(byte[], …)
  • 16.
    How Privates WorkNormally • Special synthetic accessor methods – INVOKESTATIC Foo.access$001() – can’t insert a new method into the outer class
  • 17.
    Prepare the methodsof 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; }
  • 18.
    What happens toyour 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
  • 19.
    Workaround • Start aspecial thread while (true) { nop(); } • To stop: boolean done = false; while (!done) { nop(); }
  • 20.
    Summary • Prerequisites – Extractmethod – Ability to compile with some tweaks • Results – Any expressions/statements – Lambdas/local classes • Use it for your language! – https://github.com/abreslav/eval4j