20
eval4j compiling expressions to be evaluated by the debugger andrey.breslav@

Eval4j @ JVMLS 2014

Embed Size (px)

DESCRIPTION

eval4j: a JVM bytecode interpreter written in Java, used to implement "Evaluate Expression" functionality in debuggers for JVM Languages

Citation preview

Page 1: Eval4j @ JVMLS 2014

eval4j

compiling expressions to be evaluated by the debugger

andrey.breslav@ .com

Page 2: Eval4j @ JVMLS 2014
Page 3: Eval4j @ JVMLS 2014

Stop at a breakpoint

Inspect memoryInspect call stacks

Page 4: Eval4j @ JVMLS 2014

Evaluate given expression

Evaluate given expression

Page 5: Eval4j @ JVMLS 2014
Page 6: Eval4j @ JVMLS 2014

Working Horse: Bare JDI

• Access Variables• Access Fields• Call Methods

• No Evaluate Expression out-of-the-box JDI

Page 7: Eval4j @ JVMLS 2014

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

Page 8: Eval4j @ JVMLS 2014

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…

Page 9: Eval4j @ JVMLS 2014

Reuse the Compiler (Take 1)

a + b.class

fileDebugeeprocess

compile

loadrun

IllegalAccessError

Page 10: Eval4j @ JVMLS 2014

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

JDI

Page 11: Eval4j @ JVMLS 2014

Compiling an expression

free variables

Extract Method Refactoring

Page 12: Eval4j @ JVMLS 2014

Summary so far

Extract Method +

Compiler +

eval4j =

Evaluate Expression

Page 13: Eval4j @ JVMLS 2014

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

Page 14: Eval4j @ JVMLS 2014

Challenge: New Classes

private?

• Also: How do you load a class into the debugee?

?

Page 15: Eval4j @ JVMLS 2014

Loading a class…

• protected Class<?> defineClass(byte[], …)

Page 16: Eval4j @ JVMLS 2014

How Privates Work Normally

• Special synthetic accessor methods– INVOKESTATIC Foo.access$001()– can’t insert a new method into the outer class

Page 17: Eval4j @ JVMLS 2014

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;

}

Page 18: Eval4j @ JVMLS 2014

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

Page 19: Eval4j @ JVMLS 2014

Workaround

• Start a special thread

while (true) { nop();}• To stop:

boolean done = false;while (!done) {

nop();}

Page 20: Eval4j @ JVMLS 2014

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