The Source for Java Technology Collaboration
User: Password:
Register | Login help    

Search

Online Books:
java.net on MarkMail:


DLR Expression Tree like in Java

Posted by forax on July 31, 2009 at 3:33 PM PDT

Two months ago, I was discussing with a friend about dynamic languages and JSR 292 when he mentions DLR Expression Trees. At that time, I had a vague memory, mostly because I was under the effect of a persisting jet lag, when I attend the talk of Mads Torgersen about it at last year JVM Summit.
By the way, I will attend the next JVM Summit in September, I have some good results with JSR 292 backport.
I had finished the debate with my friend saying that an expression tree like that can be easily implemented in one hour on top of JSR 292 API.
In fact, it takes me a little more than one day to just sketch a prototype. And Yes, I have some free times, I'm in vacation and my wife allow me to took my laptop with me :)

An Expression Tree

The main idea is to be able to create an AST and to transform it into runnable code at runtime.
The following example create a kind of anonymous method (a lambda, etc) that takes two integers and returns their sum.
The class ExprBuilder use a stack based notation like by example the PostScript language because I'm too lenient to implement a real AST (with automatic type conversions).

  MethodType methodType = MethodType.make(int.class, int.class, int.class);
    
  ExprBuilder builder = new ExprBuilder(methodType);
  Var a = builder.parameter(0);
  Var b = builder.parameter(1);
  builder.
    load(a).
    load(b).
    add();
    
  MethodHandle mh = builder.createMethodHandle(Main.class);
  System.out.println(mh.invoke(2, 3));

Also notice that createMethodhandle takes a class as argument because the anonymous method will be able to access to all fields, methods, etc even if they are declared private (thanks to the anonymous class loader) like a classical member of this class.

If you want to play with it, the code is available here and works with current jdk7 binaries (b67).
Run it with a command line like this one

/usr/jdk/jdk1.7.0/bin/java -cp classes:lib/asm-all-3.2.jar -XX:+EnableInvokeDynamic Main

Cheers,
Rémi

Related Topics >> Open JDK      
Comments
Comments are listed in date ascending order (oldest first)

Wait.. did you just implement a simple closure/lambda using invokedynamic? Or is this more of a mixin/method injection example? I don't quite understand all of it yet but it looks interesting.

Better later than never... @aberrant, it's not closure by example you can't capture a field, so it's more a lambda generator using method handle (not invokedynamic). You're right that it allows a kind of method (or function) injection. @4bugzilla, you are right, I use ASM. It's as clean as DLR expression tree implementation which heavily relies on namespace System.Reflection.Emit. I agree that bytecode manipulation is not standard, there is no package java.reflection.emit in jdk7 but it's fairly usual, in jdk7, reflection use bytecode generation to speed up method invocation, implement java.lang.reflect.Proxy or to speed up XSLT transformation. Also Hibernate or Toplink use bytecode manipulation. At last, in this example, the bytecode generator is fairly trivial. Rémi

As far as I can see you are using asm bytecode manipulation library to create some bytecode on the fly. Please correct me if I am wrong. Tha is why it looks to me like this is not very "clean" and "true" implementation of Expression Tree using jdk 7 features. For me it is some sort of "simulation" which requires non standard and non-trivial hacks like bytecode manipulation.

The main idea is to be able

The main idea is to be able to create an AST and to transform it into runnable code at runtime. ed hardy,