jdk.dynalink is here! Attila Szegedi, Fauna Inc.

Similar documents
Dynalink. Dynamic Linker Framework for Languages on the JVM. Attila Szegedi, Software Engineer, Twitter

Weiss Chapter 1 terminology (parenthesized numbers are page numbers)

invokedynamic IN 45 MINUTES!!! Wednesday, February 6, 13

<Insert Picture Here> Implementing lambda expressions in Java

Contents. Figures. Tables. Examples. Foreword. Preface. 1 Basics of Java Programming 1. xix. xxi. xxiii. xxvii. xxix

invokedynamic under the hood

Let's talk about invokedynamic

Copyright 2012, Oracle and/or its affiliates. All rights reserved. Insert Information Protection Policy Classification from Slide 16

MethodHandle implemention tips and tricks

Agenda. Objects and classes Encapsulation and information hiding Documentation Packages

OBJECT ORIENTED PROGRAMMING

Subclass Gist Example: Chess Super Keyword Shadowing Overriding Why? L10 - Polymorphism and Abstract Classes The Four Principles of Object Oriented

Frequently Asked Questions

JSR-305: Annotations for Software Defect Detection

Java SE7 Fundamentals

April 15, 2009 John R. Rose, Sr. Staff Engineer

Fundamentals of Programming (Python) Object-Oriented Programming. Ali Taheri Sharif University of Technology Spring 2018

JSR 292 and companions Rémi Forax FOSDEM'09

From C++ to Java. Duke CPS

Introduction to Programming Using Java (98-388)

Course Description. Learn To: : Intro to JAVA SE7 and Programming using JAVA SE7. Course Outline ::

The following presentation is provided under DHMB license. (Do Not Hurt My Brain). Lecturer is not responsible for the financial and moral

Object Oriented Programming is a programming method that combines: Advantage of Object Oriented Programming

Copyright 2013, Oracle and/or its affiliates. All rights reserved.

Reflection (in fact, Java introspection)

Part I. Wei Tianwen. A Brief Introduction to Python. Part I. Wei Tianwen. Basics. Object Oriented Programming

(800) Toll Free (804) Fax Introduction to Java and Enterprise Java using Eclipse IDE Duration: 5 days

Introduction to Visual Basic and Visual C++ Introduction to Java. JDK Editions. Overview. Lesson 13. Overview

Index COPYRIGHTED MATERIAL

MethodHandle Introspection: Internals

Week 8 Lecture: Programming

JAVASCRIPT AND JQUERY: AN INTRODUCTION (WEB PROGRAMMING, X452.1)

CS 251 Intermediate Programming Methods and Classes

The Pyth Language. Administrivia

CS 251 Intermediate Programming Methods and More

CMSC131. Inheritance. Object. When we talked about Object, I mentioned that all Java classes are "built" on top of that.

Using Scala for building DSL s

MethodHandlesArrayElementGetterBench.testCreate Analysis. Copyright 2016, Oracle and/or its affiliates. All rights reserved.

Atelier Java - J1. Marwan Burelle. EPITA Première Année Cycle Ingénieur.

the gamedesigninitiative at cornell university Lecture 7 C++ Overview

Data Structures (list, dictionary, tuples, sets, strings)

2012 Oracle Corporation. Monday, July 30, 12

DESIGN PATTERN - INTERVIEW QUESTIONS

JSR 292 Cookbook: Fresh Recipes with New Ingredients

Overview of OOP. Dr. Zhang COSC 1436 Summer, /18/2017

Week 2. Classes and Objects

Python A Technical Introduction. James Heliotis Rochester Institute of Technology December, 2009

Java Overview An introduction to the Java Programming Language

Java 1.8 Programming

GIS 4653/5653: Spatial Programming and GIS. More Python: Statements, Types, Functions, Modules, Classes

Brief Summary of Java

Introflection. Dave Landers BEA Systems, Inc.

Language Features. 1. The primitive types int, double, and boolean are part of the AP

CSE P 501 Compilers. Java Implementation JVMs, JITs &c Hal Perkins Winter /11/ Hal Perkins & UW CSE V-1

Java 11 and MAKING ECLIPSE JDT FUTURE READY MANOJ PALAT IBM

CS321 Languages and Compiler Design I. Winter 2012 Lecture 2

Invokedynamic in Practice. Adding invokedynamic support to JRuby

Java Fundamentals (II)

Java Primer 1: Types, Classes and Operators

Supporting Class / C++ Lecture Notes

Chapter 4 Defining Classes I

Subtype Polymorphism

Upcoming Features in C# Mads Torgersen, MSFT

Rules and syntax for inheritance. The boring stuff

BEAAquaLogic. Service Bus. Interoperability With EJB Transport

A final method is a method which cannot be overridden by subclasses. A class that is declared final cannot be inherited.

CH. 2 OBJECT-ORIENTED PROGRAMMING

Introduction to Python programming, II

Chapter 5 Object-Oriented Programming

Interfaces. An interface forms a contract between the object and the outside world.

Java Programming Training for Experienced Programmers (5 Days)

Java Classes. Produced by. Introduction to the Java Programming Language. Eamonn de Leastar

1 Shyam sir JAVA Notes

Object Model Comparisons

JavaScript: Sort of a Big Deal,

Argument Passing All primitive data types (int etc.) are passed by value and all reference types (arrays, strings, objects) are used through refs.

Day 4. COMP1006/1406 Summer M. Jason Hinek Carleton University

BFlat. Classes. A list of features: - Classes. - Static Types and Type Checking. - Static Scoping. - Metaclasses

Agenda. CSE P 501 Compilers. Java Implementation Overview. JVM Architecture. JVM Runtime Data Areas (1) JVM Data Types. CSE P 501 Su04 T-1

Java Programming with Eclipse

Class Design (Section 9 of 17)

Introduction to Runtime User s Guide. Version 3.5

Pace University. Fundamental Concepts of CS121 1

Introduction to Computer Programming in Python Dr. William C. Bulko. Data Types

Chair of Software Engineering. Java and C# in depth. Carlo A. Furia, Marco Piccioni, Bertrand Meyer. Java: reflection

This is an introductory tutorial, which covers the basics of Jython and explains how to handle its various modules and sub-modules.

Cross-platform daemonization tools.

Contents. I. Classes, Superclasses, and Subclasses. Topic 04 - Inheritance

<Insert Picture Here> Adventures in JSR-292 or How To Be A Duck Without Really Trying

Exam 1 Format, Concepts, What you should be able to do, and Sample Problems

COP 3330 Final Exam Review

Operators and Expressions

Java: framework overview and in-the-small features

Computer Components. Software{ User Programs. Operating System. Hardware

Programming. Syntax and Semantics

MARS AREA SCHOOL DISTRICT Curriculum TECHNOLOGY EDUCATION

\n is used in a string to indicate the newline character. An expression produces data. The simplest expression

CONTENTS. PART 1 Structured Programming 1. 1 Getting started 3. 2 Basic programming elements 17

Lecture 9 : Basics of Reflection in Java

Core Java - SCJP. Q2Technologies, Rajajinagar. Course content

Transcription:

jdk.dynalink is here! Attila Szegedi, Fauna Inc. 1

Part I: Overview 2

Dynalink in the JDK In JDK 9 as jdk.dynalink package and module. Nashorn uses it. Available for integration with other language runtimes and tools. 3

What Changed? Dynalink was presented at conferences before. The JDK version is very similar, but the API was simplified and clarified: class hierarchies were flattened some speculative functionality was removed new type safe representation of operations 4

What is Dynalink? A library for dynamic linking of high-level operations on objects ("read a property", "write a property", "invoke a function" etc). Useful for implementing programming languages that have: at least some expressions with dynamic types, or object models that differ from the JVM static class model, or type conversions above and beyond the JLS ones. Operations are call sites and will be linked to target method handles at run time based on actual types of the evaluated expressions. These can change between invocations, necessitating relinking the call site multiple times for new types. Dynalink handles all that and more. 5

Why is Dynalink useful? When expressions are statically typed and the object model matches that of JVM, you can just use getfield, invokevirtual, etc. instructions and let the JVM link them. Otherwise, use invokedynamic and let Dynalink link them. 6

Nashorn Example public class A { public String color; public A(String color) { this.color = color; public class B { private String color; public B(String color) { this.color = color; public String getcolor() { return color; public class C { private int color; public C(int color) { this.color = color; public int getcolor() { return color; 7

Nashorn Example var objs = [ new (Java.type("A"))("red"), new (Java.type("B"))("green"), new (Java.type("C"))(0x0000ff) ] for each(var obj in objs) { print(obj.color); In bytecode, the.color accessor becomes: aload 4 // obj invokedynamic "color" (Object;)Object; flags(get_property) 8

Operation Encoding Dynalink used to prescribe string encoding of operations in call site name ( dyn:getprop:color ). Not anymore. It now uses type safe Operation objects. Decoding the operation from call site is left to the language runtime s bootstrap method. Nashorn now uses only 3 bits in its bootstrap method s int static argument to represent its operations. 9

Operation Encoding Example What used to be: "dyn:getprop getelem getmethod:color" is now: new NamedOperation( new NamespaceOperation( StandardOperation.GET, StandardNamespace.PROPERTY, StandardNamespace.ELEMENT, StandardNamespace.METHOD), "color") 10

Operation Encoding Example What used to be: "dyn:getprop getelem getmethod:color" is now with fluent API: StandardOperation.GET.withNamespaces( StandardNamespace.PROPERTY, StandardNamespace.ELEMENT, StandardNamespace.METHOD).named("color") 11

Operation Encoding Example What used to be: "dyn:getprop getelem getmethod:color" is now with fluent API and static imports: import static jdk.dynalink.standardoperation.*; import static jdk.dynalink.standardnamespace.*; GET.withNamespaces(PROPERTY, ELEMENT, METHOD).named("color") 12

Nashorn Operation Encoding public final class NashornCallSiteDescriptor extends CallSiteDescriptor { public static final int GET_PROPERTY = 0; /** Property getter: obj.prop */ public static final int GET_ELEMENT = 1; /** Element getter: obj[index] */ public static final int GET_METHOD_PROPERTY = 2; /** Property getter, invoked: obj.prop() */ public static final int GET_METHOD_ELEMENT = 3; /** Element getter, invoked: obj[index]() */ public static final int SET_PROPERTY = 4; /** Property setter: obj.prop = value */ public static final int SET_ELEMENT = 5; /** Element setter: obj[index] = value */ public static final int CALL = 6; /** Call: fn(args...) */ public static final int NEW = 7; /** New: new Constructor(args...) */ // Correspond to the operation indices above. private static final Operation[] OPERATIONS = new Operation[] { GET.withNamespaces(PROPERTY, ELEMENT, METHOD), GET.withNamespaces(ELEMENT, PROPERTY, METHOD), GET.withNamespaces(METHOD, PROPERTY, ELEMENT), GET.withNamespaces(METHOD, ELEMENT, PROPERTY), SET.withNamespaces(PROPERTY, ELEMENT), SET.withNamespaces(ELEMENT, PROPERTY), StandardOperation.CALL, StandardOperation.NEW ; 13

Dynalink and Bytecode Dynalink does not mandate bytecode-generating language runtimes. CallSite objects usually come from bytecode invokedynamic instructions, but can also be arbitrarily created by Java code (so-called free floating call sites). Dynalink handles CallSite objects no matter where they came from. A Dynalink-based interpreter would need to maintain its own CallSite objects associated with its interpreted program representations (e.g. AST). 14

Simplest Dynalink Use Simplest Dynalink use is for a language with: its own dynamic expressions, but no object model of its own, nor type conversions of its own. Think something BeanShell-like. 15

Simplest Dynalink Use import java.lang.invoke.*; import jdk.dynalink.*; import jdk.dynalink.support.*; class MyLanguageRuntime { private static final DynamicLinker dynamiclinker = new DynamicLinkerFactory().createLinker(); public static CallSite bootstrap(methodhandles.lookup lookup, String name, MethodType type) { return dynamiclinker.link( new SimpleRelinkableCallSite( new CallSiteDescriptor(lookup, decodeoperation(name), type))); private static Operation decodeoperation(string name) {... 16

Simplest Dynalink Use import java.lang.invoke.*; import jdk.dynalink.*; import jdk.dynalink.support.*; class MyLanguageRuntime { private static final DynamicLinker dynamiclinker = new DynamicLinkerFactory().createLinker(); public static CallSite bootstrap(methodhandles.lookup lookup, String name, MethodType type) { return dynamiclinker.link( new SimpleRelinkableCallSite( new CallSiteDescriptor(lookup, decodeoperation(name), type))); private static Operation decodeoperation(string name) {... Bootstrap methods delegate to a DynamicLinker s link() method. DynamicLinker is created through a DynamicLinkerFactory. 17

Simplest Dynalink Use import java.lang.invoke.*; import jdk.dynalink.*; import jdk.dynalink.support.*; class MyLanguageRuntime { private static final DynamicLinker dynamiclinker = new DynamicLinkerFactory().createLinker(); public static CallSite bootstrap(methodhandles.lookup lookup, String name, MethodType type) { return dynamiclinker.link( new SimpleRelinkableCallSite( new CallSiteDescriptor(lookup, decodeoperation(name), type))); private static Operation decodeoperation(string name) {... DynamicLinker links CallSite objects that implement Dynalink RelinkableCallSite interface. DynamicLinker comes with two relinkable call site implementations, SimpleRelinkableCallSite and ChainedCallSite, both subclasses of j.l.invoke.mutablecallsite. You can also roll your own. 18

Simplest Dynalink Use import java.lang.invoke.*; import jdk.dynalink.*; import jdk.dynalink.support.*; class MyLanguageRuntime { private static final DynamicLinker dynamiclinker = new DynamicLinkerFactory().createLinker(); public static CallSite bootstrap(methodhandles.lookup lookup, String name, MethodType type) { return dynamiclinker.link( new SimpleRelinkableCallSite( new CallSiteDescriptor(lookup, decodeoperation(name), type))); private static Operation decodeoperation(string name) {... Relinkable call sites carry CallSiteDescriptors, immutable triples of Lookup, Dynalink Operation, and MethodType. Dynalink internally passes descriptors to linkers and never exposes the call sites so their settarget can t be invoked. Language runtimes can subclass CallSiteDescriptor to carry additional static bootstrap arguments. 19

Simplest Dynalink Use import java.lang.invoke.*; import jdk.dynalink.*; import jdk.dynalink.support.*; class MyLanguageRuntime { private static final DynamicLinker dynamiclinker = new DynamicLinkerFactory().createLinker(); public static CallSite bootstrap(methodhandles.lookup lookup, String name, MethodType type) { return dynamiclinker.link( new SimpleRelinkableCallSite( new CallSiteDescriptor(lookup, decodeoperation(name), type))); private static Operation decodeoperation(string name) {... Dynalink defines a StandardOperation enum as well as NamespaceOperation and NamedOperation classes. 20

Standard Operations Expression Operation Expected arguments obj[x] obj["foo"] obj.foo obj[x] = y obj[ foo"] = y obj.foo = y StandardOperation.GET.withNamespace(StandardNamespace.ELEMENT) StandardOperation.GET.withNamespace(StandardNamespace.ELEMENT).named("foo") StandardOperation.GET.withNamespace(StandardNamespace.PROPERTY).named("foo") StandardOperation.SET.withNamespace(StandardNamespace.ELEMENT) StandardOperation.SET.withNamespace(StandardNamespace.ELEMENT).named("foo") StandardOperation.SET.withNamespace(StandardNamespace.PROPERTY).named("foo") (obj, x) (obj) (obj) (obj, x, y) (obj, y) (obj, y) 21

Standard Operations Expression Operation Expected arguments obj.fn(x, y) 1. StandardOperation.GET.withNamespace(StandardNamespace.METHOD).named("foo") 2. StandardOperation.CALL 1. (obj) 2. (fn, obj, x, y) new Ctor(x, y) StandardOperation.NEW (Ctor, x, y) 22

Bring Your Own Linker If your language has : its own object model, or its own type conversions then you need to define your own linker. 23

Bring Your Own Linker import java.lang.invoke.*; import jdk.dynalink.*; import jdk.dynalink.support.*; class MyLanguageRuntime { private static final DynamicLinker dynamiclinker; static { DynamicLinkerFactory factory = new DynamicLinkerFactory(); factory.setprioritizedlinker(new MyLanguageLinker()); dynamiclinker = factory.createlinker(); public static CallSite bootstrap(methodhandles.lookup lookup, String name, MethodType type) { return dynamiclinker.link( new SimpleRelinkableCallSite( new CallSiteDescriptor(lookup, decodeoperation(name), type))); private static Operation decodeoperation(string name) {... You need to pass your own linker to the factory. You can have more than one. Nashorn has nine! 24

Linker Examples in Nashorn jdk9/nashorn/samples/dynalink has some linkers that extend Nashorn s functionality. You can just use javac *.java and then jjs any_example.js from the same directory ( cause current dir is on classpath). Let s inspect an example linker that adds a.stream property to Java arrays. 25

Linker Examples in Nashorn public final class ArrayStreamLinkerExporter extends GuardingDynamicLinkerExporter { public List<GuardingDynamicLinker> get() { final ArrayList<GuardingDynamicLinker> linkers = new ArrayList<>(); linkers.add(new TypeBasedGuardingDynamicLinker() { @Override public boolean canlinktype(final Class<?> type) { return type == Object[].class type == int[].class type == long[].class type == double[].class; @Override public GuardedInvocation getguardedinvocation(linkrequest request, final LinkerServices linkerservices) throws Exception { final Object self = request.getreceiver(); if (self == null!canlinktype(self.getclass())) { return null; final CallSiteDescriptor desc = request.getcallsitedescriptor(); final Operation op = desc.getoperation(); final Object name = NamedOperation.getName(op); final boolean getprop = NamespaceOperation.contains( NamedOperation.getBaseOperation(op), StandardOperation.GET, StandardNamespace.PROPERTY); if (getprop && "stream".equals(name)) { return new GuardedInvocation(ARRAY_TO_STREAM, Guards.isOfClass(self.getClass(), GUARD_TYPE)); return null; ); return linkers; public static Object arraytostream(object array) { if (array instanceof int[]) { return IntStream.of((int[])array); else if (array instanceof long[]) { return LongStream.of((long[])array); else if (array instanceof double[]) {... private static final MethodType GUARD_TYPE = MethodType.methodType(Boolean.TYPE, Object.class); private static final MethodHandle ARRAY_TO_STREAM = Lookup.PUBLIC.findStatic(ArrayStreamLinkerExporter.class, arraytostream", MethodType.methodType(Object.class, Object.class)); 26

Linker Examples in Nashorn public final class ArrayStreamLinkerExporter extends GuardingDynamicLinkerExporter { public List<GuardingDynamicLinker> get() { final ArrayList<GuardingDynamicLinker> linkers = new ArrayList<>(); linkers.add(new TypeBasedGuardingDynamicLinker() { @Override public boolean canlinktype(final Class<?> type) { return type == Object[].class type == int[].class type == long[].class type == double[].class; @Override public GuardedInvocation getguardedinvocation(linkrequest request, final LinkerServices linkerservices) throws Exception { final Object self = request.getreceiver(); if (self == null!canlinktype(self.getclass())) { return null; final CallSiteDescriptor desc = request.getcallsitedescriptor(); final Operation op = desc.getoperation(); final Object name = NamedOperation.getName(op); final boolean getprop = NamespaceOperation.contains( NamedOperation.getBaseOperation(op), StandardOperation.GET, StandardNamespace.PROPERTY); if (getprop && "stream".equals(name)) { return new GuardedInvocation(ARRAY_TO_STREAM, Guards.isOfClass(self.getClass(), GUARD_TYPE)); return null; ); return linkers; public static Object arraytostream(object array) { if (array instanceof int[]) { return IntStream.of((int[])array); else if (array instanceof long[]) { return LongStream.of((long[])array); else if (array instanceof double[]) {... 27 GuardingDynamicLinkerExporters are automatically loaded by Dynalink dynamic linker factories when declared in META-INF/services. Exporters are Suppliers for a List of GuardingDynamicLinkers. A TypeBasedGuardingDynamicLinker declares it can link operations based on the Java type (class) of the target. A guarding dynamic linker receives a LinkRequest and produces a GuardedInvocation. A guarded invocation is a tuple of an invocation MethodHandle for the operation and a guard MethodHandle that defines the condition of validity of the invocation (a class test etc.). private static final MethodType GUARD_TYPE = MethodType.methodType(Boolean.TYPE, Object.class); private static final MethodHandle ARRAY_TO_STREAM = Lookup.PUBLIC.findStatic(ArrayStreamLinkerExporter.class, arraytostream", MethodType.methodType(Object.class, Object.class));

Linker Examples in Nashorn public final class ArrayStreamLinkerExporter extends GuardingDynamicLinkerExporter { public List<GuardingDynamicLinker> get() { final ArrayList<GuardingDynamicLinker> linkers = new ArrayList<>(); linkers.add(new TypeBasedGuardingDynamicLinker() { @Override public boolean canlinktype(final Class<?> type) { return type == Object[].class type == int[].class type == long[].class type == double[].class; @Override public GuardedInvocation getguardedinvocation(linkrequest request, final LinkerServices linkerservices) throws Exception { final Object self = request.getreceiver(); if (self == null!canlinktype(self.getclass())) { return null; final CallSiteDescriptor desc = request.getcallsitedescriptor(); final Operation op = desc.getoperation(); final Object name = NamedOperation.getName(op); final boolean getprop = NamespaceOperation.contains( NamedOperation.getBaseOperation(op), StandardOperation.GET, StandardNamespace.PROPERTY); if (getprop && "stream".equals(name)) { return new GuardedInvocation(ARRAY_TO_STREAM, Guards.isOfClass(self.getClass(), GUARD_TYPE)); return null; ); return linkers; public static Object arraytostream(object array) { if (array instanceof int[]) { return IntStream.of((int[])array); else if (array instanceof long[]) { return LongStream.of((long[])array); else if (array instanceof double[]) {... LinkRequest gives access to receiver, arguments, and the call site descriptor. NamedOperation and NamespaceOperation have utility methods for common operations. Guards is a utility class for creating widely useful guard method handles. private static final MethodType GUARD_TYPE = MethodType.methodType(Boolean.TYPE, Object.class); private static final MethodHandle ARRAY_TO_STREAM = Lookup.PUBLIC.findStatic(ArrayStreamLinkerExporter.class, arraytostream", MethodType.methodType(Object.class, Object.class)); 28

What Goes Into a DynamicLinker When a factory creates a DynamicLinker, it ll compose it from various GuardingDynamicLinkers: explicitly set prioritized linkers, any linkers from exporters declared in META-INF/services, DynamicLinkerFactory Prioritized linkers Automatically loaded linkers Fallback linkers and explicitly set fallback linkers. When no fallback is set, BeansLinker is used as a default fallback. 29

BeansLinker Default fallback linker, used to link objects that weren t linked by anything else. Provides common sense operation semantics for POJOs: setxxx(), getxxx() and isxxx() methods are treated as property setters/getters public methods can be invoked public fields also act as properties, and so on. 30

BeansLinker Finer Points Supports overloaded method invocation based on argument types. It even takes into account your language runtime allowed type conversions. Supports variable arity method invocation. Caller sensitive methods are linked in a secure manner. Behavior for missing method is pluggable allowing language-specific semantics for handling them on POJOs. 31

Representation of Statics Static methods and fields on classes are represented by objects of class jdk.dynalink.beans.staticclass. There s one StaticClass instance for every java.lang.class object. BeansLinker recognizes them and links access to static members and invocation as constructor on them accordingly. They re distinct from java.lang.class; j.l.class is a runtime class object, StaticClass is a namespace for class static members as well as a stand-in for its constructors. Just like in Java language you understand the distinction between BitSet and BitSet.class 32

Dynalink Security New RuntimePermissions are required for some operations: "dynalink.exportlinkersautomatically" for a GuardingDynamicLinkerExporter to load automatically from META-INF/services "dynalink.getlookup" for invoking CallSiteDescriptor.getLookup() 33

Part II: Advanced Topics 34

Rhinoceros and Snake Our colleague Sundar wrote a demo Jython linker. As a result, you can use Jython objects in Nashorn. Or in any other language that uses Dynalink. 35

Rhinoceros and Snake var JythonFactory = Java.type("org.python.jsr223.PyScriptEngineFactory"); var jythonengine = new JythonFactory().getScriptEngine(); jythonengine.eval(<<eof import math class Point: def init (self, x, y): self.x = x self.y = y def distance(self, other = None): if other == None: other = Point(0.0, 0.0); return math.sqrt((self.x - other.x)**2 + (self.y - other.y)**2) def show(self): print(self.x, self.y) def move(self, dx, dy): self.x += dx self.y += dy point = Point(4, 5) list = ["hello", "world"] dict = { 'foo' : 'bar' EOF); var p = jythonengine.get("point") // fetch attribute "x" and "y" print("p.x = " + p.x) print("p.y = " + p.y) // call distance method on the point print("p's distance from origin = " + p.distance()) // call other methods on point object p.show() p.move(1, 1) p.show() We re reading Python properties and invoking Python methods from Nashorn! 36

Rhinoceros and Snake jjs -cp jython_linker.jar:jython-standalone-2.7.0.jar jython_sample.js What s in the JAR? Few classes and a service manifest. JythonLinkerExporter$1.class JythonLinkerExporter$2.class JythonLinkerExporter.class META-INF/services/ META-INF/services/jdk.dynalink.linker.GuardingDynamicLinkerExporter There s more stuff in the sample JS file. 37

Other Dynalink Samples Sundar prepared a bunch of samples: https://blogs.oracle.com/sundararajan/tags/ dynalink jdk9/nashorn/samples/dynalink in OpenJDK Mercurial 38

Other Dynalink Samples Sample XML DOM linker allows access to child elements and text using underscore prefix. Here s code for generating HTML from a RSS feed in Nashorn with sample DOM linker: function getbookshtml() { var doc = parsexml("http://www.gutenberg.org/cache/epub/feeds/today.rss"); // wrap document root Element as script convenient object var rss = doc.documentelement; var str = <<HEAD <html> <title>${rss._channel._title._</title> <body> <h1>${rss._channel._description._</h1> <p> Published on ${rss._channel._pubdate._ </p> HEAD... 39

Custom Linker Advantages Great things about custom linkers are: you can effectively create DSLs without the target objects being aware of them; all the logic is in the linker. Efficient: linking is one-time-per-call site cost, after that it s a guard test and direct invoke of a method handle. DOM, JDBC ResultSets, anything goes. 40

Part III: Even More Advanced Topics 41

Less Obvious APIs DynamicLinkerFactory has methods for some non-obvious behavioral customizations of the DynamicLinker it creates: setautoconversionstrategy setinternalobjectsfilter setprelinktransformer What are these oddities for? 42

Full Linking Flow DynamicLinker.link.. GuardingDynamicLinker.getGuardedInvocation typeconverters.astype autoconversionstrategy.astype internalobjectfilters.transform prelinktransformer.filter callsite.settarget 43

Auto Conversion Strategy DynamicLinker.link.. GuardingDynamicLinker.getGuardedInvocation typeconverters.astype autoconversionstrategy.astype When call site type and internalobjectfilters.transform method handle type need to be matched, Dynalink automatically handles all JLS method invocation conversions and all custom type conversions defined prelinktransformer.filter by linkers. However, some runtimes will need to customize even JLS method invocation conversions. GuardWithTest Example: unboxing of null values. callsite.settarget To follow JS semantics, invocation Nashorn fallback needs to be able to unbox null to primitive values without a NPE. 44

Internal Object Filters DynamicLinker.link Some language runtime will have internal objects that must not escape the internal scope of the runtime.. Example: Nashorn GuardingDynamicLinker.getGuardedInvocation needs to hide ConsString. which is a CharSequence of a delayed string concatenations and ScriptObject from the outside world. InternalObjectFilters add typeconverters.astype filters to method handles that collapse ConsString into a j.l.string and wrap ScriptObject in a JSObject (public API of Nashorn objects). autoconversionstrategy.astype internalobjectfilters.transform prelinktransformer.filter callsite.settarget 45

Pre-Link Transform Pre-link transformer is given DynamicLinker.link the final chance to transform the GuardedInvocation s method handles before they re linked into the call site. Nashorn uses a pre-link transformer. to add converting filters for optimistic types to method GuardingDynamicLinker.getGuardedInvocation handle return types.. GuardingDynamicLinkers should refrain from applying non-jls type conversions on method handles typeconverters.astype return types to match them to call site s type and should leave such conversions to the pre-link filter of the runtime that owns the call site. autoconversionstrategy.astype That way, a language runtime with optimistic typing can have it work correctly even when linking method handles from a foreign linker into its own call sites. internalobjectfilters.transform prelinktransformer.filter callsite.settarget 46

Resources Dynalink is in the JDK 9 builds. OpenJDK Mercurial repository has: the source code in jdk9/nashorn/src/jdk.dynalink examples in jdk9/nashorn/samples/dynalink JavaDoc: http://download.java.net/java/jdk9/docs/jdk/api/dynalink/index.html Sundar s Dynalink blog posts: https://blogs.oracle.com/sundararajan/tags/dynalink 47

Questions? 48