8144841: Add a sample for pluggable dynalink linker for stream property on arrays and a REAMDE for linker samples
Reviewed-by: mhaupt, attila
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/ArrayStreamLinkerExporter.java Tue Dec 08 17:16:10 2015 +0530
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+import jdk.dynalink.CallSiteDescriptor;
+import jdk.dynalink.CompositeOperation;
+import jdk.dynalink.NamedOperation;
+import jdk.dynalink.Operation;
+import jdk.dynalink.StandardOperation;
+import jdk.dynalink.linker.GuardingDynamicLinker;
+import jdk.dynalink.linker.GuardingDynamicLinkerExporter;
+import jdk.dynalink.linker.GuardedInvocation;
+import jdk.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.dynalink.linker.LinkRequest;
+import jdk.dynalink.linker.LinkerServices;
+import jdk.dynalink.linker.support.Guards;
+import jdk.dynalink.linker.support.Lookup;
+
+/**
+ * This is a dynalink pluggable linker (see http://openjdk.java.net/jeps/276).
+ * This linker adds "stream" property to Java arrays. The appropriate Stream
+ * type object is returned for "stream" property on Java arrays. Note that
+ * the dynalink beans linker just adds "length" property and Java array objects
+ * don't have any other property. "stream" property does not conflict with anything
+ * else!
+ */
+public final class ArrayStreamLinkerExporter extends GuardingDynamicLinkerExporter {
+ static {
+ System.out.println("pluggable dynalink array stream linker loaded");
+ }
+
+ 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[]) {
+ return DoubleStream.of((double[])array);
+ } else if (array instanceof Object[]) {
+ return Stream.of((Object[])array);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ 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));
+
+ @Override
+ 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,
+ LinkerServices linkerServices) throws Exception {
+ final Object self = request.getReceiver();
+ if (self == null || !canLinkType(self.getClass())) {
+ return null;
+ }
+
+ CallSiteDescriptor desc = request.getCallSiteDescriptor();
+ Operation op = desc.getOperation();
+ Object name = NamedOperation.getName(op);
+ boolean getProp = CompositeOperation.contains(
+ NamedOperation.getBaseOperation(op),
+ StandardOperation.GET_PROPERTY);
+ if (getProp && "stream".equals(name)) {
+ return new GuardedInvocation(ARRAY_TO_STREAM,
+ Guards.isOfClass(self.getClass(), GUARD_TYPE));
+ }
+
+ return null;
+ }
+ });
+ return linkers;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/BufferIndexingLinkerExporter.java Tue Dec 08 17:16:10 2015 +0530
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.List;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.nio.ShortBuffer;
+import jdk.dynalink.CallSiteDescriptor;
+import jdk.dynalink.CompositeOperation;
+import jdk.dynalink.NamedOperation;
+import jdk.dynalink.Operation;
+import jdk.dynalink.StandardOperation;
+import jdk.dynalink.linker.GuardingDynamicLinker;
+import jdk.dynalink.linker.GuardingDynamicLinkerExporter;
+import jdk.dynalink.linker.GuardedInvocation;
+import jdk.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.dynalink.linker.LinkRequest;
+import jdk.dynalink.linker.LinkerServices;
+import jdk.dynalink.linker.support.Guards;
+import jdk.dynalink.linker.support.Lookup;
+
+/**
+ * This is a dynalink pluggable linker (see http://openjdk.java.net/jeps/276).
+ * This linker adds array-like indexing and "length" property to nio Buffer objects.
+ */
+public final class BufferIndexingLinkerExporter extends GuardingDynamicLinkerExporter {
+ static {
+ System.out.println("pluggable dynalink buffer indexing linker loaded");
+ }
+
+ private static final MethodHandle BUFFER_LIMIT;
+ private static final MethodHandle BYTEBUFFER_GET;
+ private static final MethodHandle BYTEBUFFER_PUT;
+ private static final MethodHandle CHARBUFFER_GET;
+ private static final MethodHandle CHARBUFFER_PUT;
+ private static final MethodHandle SHORTBUFFER_GET;
+ private static final MethodHandle SHORTBUFFER_PUT;
+ private static final MethodHandle INTBUFFER_GET;
+ private static final MethodHandle INTBUFFER_PUT;
+ private static final MethodHandle LONGBUFFER_GET;
+ private static final MethodHandle LONGBUFFER_PUT;
+ private static final MethodHandle FLOATBUFFER_GET;
+ private static final MethodHandle FLOATBUFFER_PUT;
+ private static final MethodHandle DOUBLEBUFFER_GET;
+ private static final MethodHandle DOUBLEBUFFER_PUT;
+
+ // guards
+ private static final MethodHandle IS_BUFFER;
+ private static final MethodHandle IS_BYTEBUFFER;
+ private static final MethodHandle IS_CHARBUFFER;
+ private static final MethodHandle IS_SHORTBUFFER;
+ private static final MethodHandle IS_INTBUFFER;
+ private static final MethodHandle IS_LONGBUFFER;
+ private static final MethodHandle IS_FLOATBUFFER;
+ private static final MethodHandle IS_DOUBLEBUFFER;
+
+ private static final MethodType GUARD_TYPE;
+
+ static {
+ Lookup look = Lookup.PUBLIC;
+ BUFFER_LIMIT = look.findVirtual(Buffer.class, "limit", MethodType.methodType(int.class));
+ BYTEBUFFER_GET = look.findVirtual(ByteBuffer.class, "get",
+ MethodType.methodType(byte.class, int.class));
+ BYTEBUFFER_PUT = look.findVirtual(ByteBuffer.class, "put",
+ MethodType.methodType(ByteBuffer.class, int.class, byte.class));
+ CHARBUFFER_GET = look.findVirtual(CharBuffer.class, "get",
+ MethodType.methodType(char.class, int.class));
+ CHARBUFFER_PUT = look.findVirtual(CharBuffer.class, "put",
+ MethodType.methodType(CharBuffer.class, int.class, char.class));
+ SHORTBUFFER_GET = look.findVirtual(ShortBuffer.class, "get",
+ MethodType.methodType(short.class, int.class));
+ SHORTBUFFER_PUT = look.findVirtual(ShortBuffer.class, "put",
+ MethodType.methodType(ShortBuffer.class, int.class, short.class));
+ INTBUFFER_GET = look.findVirtual(IntBuffer.class, "get",
+ MethodType.methodType(int.class, int.class));
+ INTBUFFER_PUT = look.findVirtual(IntBuffer.class, "put",
+ MethodType.methodType(IntBuffer.class, int.class, int.class));
+ LONGBUFFER_GET = look.findVirtual(LongBuffer.class, "get",
+ MethodType.methodType(long.class, int.class));
+ LONGBUFFER_PUT = look.findVirtual(LongBuffer.class, "put",
+ MethodType.methodType(LongBuffer.class, int.class, long.class));
+ FLOATBUFFER_GET = look.findVirtual(FloatBuffer.class, "get",
+ MethodType.methodType(float.class, int.class));
+ FLOATBUFFER_PUT = look.findVirtual(FloatBuffer.class, "put",
+ MethodType.methodType(FloatBuffer.class, int.class, float.class));
+ DOUBLEBUFFER_GET = look.findVirtual(DoubleBuffer.class, "get",
+ MethodType.methodType(double.class, int.class));
+ DOUBLEBUFFER_PUT = look.findVirtual(DoubleBuffer.class, "put",
+ MethodType.methodType(DoubleBuffer.class, int.class, double.class));
+
+ GUARD_TYPE = MethodType.methodType(boolean.class, Object.class);
+ IS_BUFFER = Guards.isInstance(Buffer.class, GUARD_TYPE);
+ IS_BYTEBUFFER = Guards.isInstance(ByteBuffer.class, GUARD_TYPE);
+ IS_CHARBUFFER = Guards.isInstance(CharBuffer.class, GUARD_TYPE);
+ IS_SHORTBUFFER = Guards.isInstance(ShortBuffer.class, GUARD_TYPE);
+ IS_INTBUFFER = Guards.isInstance(IntBuffer.class, GUARD_TYPE);
+ IS_LONGBUFFER = Guards.isInstance(LongBuffer.class, GUARD_TYPE);
+ IS_FLOATBUFFER = Guards.isInstance(FloatBuffer.class, GUARD_TYPE);
+ IS_DOUBLEBUFFER = Guards.isInstance(DoubleBuffer.class, GUARD_TYPE);
+ }
+
+ // locate the first standard operation from the call descriptor
+ private static StandardOperation getFirstStandardOperation(final CallSiteDescriptor desc) {
+ final Operation base = NamedOperation.getBaseOperation(desc.getOperation());
+ if (base instanceof StandardOperation) {
+ return (StandardOperation)base;
+ } else if (base instanceof CompositeOperation) {
+ final CompositeOperation cop = (CompositeOperation)base;
+ for(int i = 0; i < cop.getOperationCount(); ++i) {
+ final Operation op = cop.getOperation(i);
+ if (op instanceof StandardOperation) {
+ return (StandardOperation)op;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public List<GuardingDynamicLinker> get() {
+ final ArrayList<GuardingDynamicLinker> linkers = new ArrayList<>();
+ linkers.add(new TypeBasedGuardingDynamicLinker() {
+ @Override
+ public boolean canLinkType(final Class<?> type) {
+ return Buffer.class.isAssignableFrom(type);
+ }
+
+ @Override
+ public GuardedInvocation getGuardedInvocation(LinkRequest request,
+ LinkerServices linkerServices) throws Exception {
+ final Object self = request.getReceiver();
+ if (self == null || !canLinkType(self.getClass())) {
+ return null;
+ }
+
+ CallSiteDescriptor desc = request.getCallSiteDescriptor();
+ StandardOperation op = getFirstStandardOperation(desc);
+ if (op == null) {
+ return null;
+ }
+
+ switch (op) {
+ case GET_ELEMENT:
+ return linkGetElement(self);
+ case SET_ELEMENT:
+ return linkSetElement(self);
+ case GET_PROPERTY: {
+ Object name = NamedOperation.getName(desc.getOperation());
+ if ("length".equals(name)) {
+ return linkLength();
+ }
+ }
+ }
+
+ return null;
+ }
+ });
+ return linkers;
+ }
+
+ private static GuardedInvocation linkGetElement(Object self) {
+ MethodHandle method = null;
+ MethodHandle guard = null;
+ if (self instanceof ByteBuffer) {
+ method = BYTEBUFFER_GET;
+ guard = IS_BYTEBUFFER;
+ } else if (self instanceof CharBuffer) {
+ method = CHARBUFFER_GET;
+ guard = IS_CHARBUFFER;
+ } else if (self instanceof ShortBuffer) {
+ method = SHORTBUFFER_GET;
+ guard = IS_SHORTBUFFER;
+ } else if (self instanceof IntBuffer) {
+ method = INTBUFFER_GET;
+ guard = IS_INTBUFFER;
+ } else if (self instanceof LongBuffer) {
+ method = LONGBUFFER_GET;
+ guard = IS_LONGBUFFER;
+ } else if (self instanceof FloatBuffer) {
+ method = FLOATBUFFER_GET;
+ guard = IS_FLOATBUFFER;
+ } else if (self instanceof DoubleBuffer) {
+ method = DOUBLEBUFFER_GET;
+ guard = IS_DOUBLEBUFFER;
+ }
+
+ return method != null? new GuardedInvocation(method, guard) : null;
+ }
+
+ private static GuardedInvocation linkSetElement(Object self) {
+ MethodHandle method = null;
+ MethodHandle guard = null;
+ if (self instanceof ByteBuffer) {
+ method = BYTEBUFFER_PUT;
+ guard = IS_BYTEBUFFER;
+ } else if (self instanceof CharBuffer) {
+ method = CHARBUFFER_PUT;
+ guard = IS_CHARBUFFER;
+ } else if (self instanceof ShortBuffer) {
+ method = SHORTBUFFER_PUT;
+ guard = IS_SHORTBUFFER;
+ } else if (self instanceof IntBuffer) {
+ method = INTBUFFER_PUT;
+ guard = IS_INTBUFFER;
+ } else if (self instanceof LongBuffer) {
+ method = LONGBUFFER_PUT;
+ guard = IS_LONGBUFFER;
+ } else if (self instanceof FloatBuffer) {
+ method = FLOATBUFFER_PUT;
+ guard = IS_FLOATBUFFER;
+ } else if (self instanceof DoubleBuffer) {
+ method = DOUBLEBUFFER_PUT;
+ guard = IS_DOUBLEBUFFER;
+ }
+
+ return method != null? new GuardedInvocation(method, guard) : null;
+ }
+
+ private static GuardedInvocation linkLength() {
+ return new GuardedInvocation(BUFFER_LIMIT, IS_BUFFER);
+ }
+}
--- a/nashorn/samples/META-INF/services/jdk.dynalink.linker.GuardingDynamicLinkerExporter Thu Dec 03 19:04:39 2015 +0530
+++ b/nashorn/samples/META-INF/services/jdk.dynalink.linker.GuardingDynamicLinkerExporter Tue Dec 08 17:16:10 2015 +0530
@@ -1,3 +1,5 @@
DOMLinkerExporter
UnderscoreNameLinkerExporter
MissingMethodLinkerExporter
+ArrayStreamLinkerExporter
+BufferIndexingLinkerExporter
--- a/nashorn/samples/MissingMethodExample.java Thu Dec 03 19:04:39 2015 +0530
+++ b/nashorn/samples/MissingMethodExample.java Tue Dec 08 17:16:10 2015 +0530
@@ -38,7 +38,7 @@
@Override
public Object doesNotUnderstand(String name, Object... args) {
- // This dummy doesNotUnderstand just prints method name and args.
+ // This simple doesNotUnderstand just prints method name and args.
// You can put useful method routing logic here.
System.out.println("you called " + name);
if (args.length != 0) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/README_dynalink.txt Tue Dec 08 17:16:10 2015 +0530
@@ -0,0 +1,52 @@
+In addition to samples for Nashorn javascript engine, this directory contains
+samples for Dynalink API (http://openjdk.java.net/jeps/276) as well. Dynalink
+linker samples require a jar file to be built and such jars be placed in the
+classpath of the jjs tool. Linker samples are named with the naming pattern
+"xyz_linker.js". These scripts build dynalink linker jar from java code and exec
+another jjs process with appropriate classpath set.
+
+Note: you need to build jdk9 forest and put "images/jdk/bin" in your PATH to use
+these scripts. This is because these scripts use javac to build dynalink jar and
+exec another jjs with classpath set! Alternatively, you can also manually build
+dynalink linker jars and invoke sample scripts by putting linker jar in jjs tool's
+classpath as well.
+
+Dynalink samples:
+
+* array_stream_linker.js
+
+This sample builds ArrayStreamLinkerExporter.java and uses it in a sample script
+called "array_stream.js". This linker adds "stream" property to Java array
+objects. The "stream" property returns appropriate Stream type for the given
+Java array (IntStream, DoubleStream ...).
+
+* buffer_indexing_linker.js
+
+This sample builds BufferIndexingLinkerExporter.java and uses it in a sample script
+called "buffer_index.js". This linker adds array-like indexed access, indexed assignment
+and "length" property to Java NIO Buffer objects. Script can treat NIO Buffer objects
+as if those are just array objects.
+
+* dom_linker.js
+
+This sample builds DOMLinkerExporter.java and uses it in a sample script
+called "dom_linker_gutenberg.js". This linker handles DOM Element objects to add
+properties to access child elements of a given element by child element tag name.
+This simplifies script access of parsed XML DOM Documents.
+
+* missing_method_linker.js
+
+This sample builds MissingMethodLinkerExporter.java and uses it in a sample script
+called "missing_method.js". This linker supports Smalltalk-style "doesNotUnderstand"
+calls on Java objects. i.e., A Java class can implement MissingMethodHandler interface
+with one method named "doesNotUnderstand". When script accesses a method on such
+object and if that method does not exist in the Java class (or any of it's supertypes),
+then "doesNotUnderstand" method is invoked.
+
+* underscore_linker.js
+
+This sample builds UnderscoreNameLinkerExporter.java and uses it in a sample script
+called "underscore.js". This linker converts underscore separated names to Camel Case
+names (as used in Java APIs). You can call Java APIs using Ruby-like naming convention
+and this linker converts method names to CamelCase!
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/array_stream.js Tue Dec 08 17:16:10 2015 +0530
@@ -0,0 +1,54 @@
+# Usage: jjs -cp array_stream_linker.jar array_stream.js
+
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This script depends on array stream dynalink linker
+// to work as expected. Without that linker in jjs classpath,
+// this script will fail to run.
+
+// Object[] and then Stream
+var s = Java.to(["hello", "world"]).stream
+s.map(function(s) s.toUpperCase()).forEach(print)
+
+// IntStream
+var is = Java.to([3, 56, 4, 23], "int[]").stream
+print(is.map(function(x) x*x).sum())
+
+// DoubleStream
+var arr = [];
+for (var i = 0; i < 100; i++)
+ arr.push(Math.random())
+
+var ds = Java.to(arr, "double[]").stream
+print(ds.summaryStatistics())
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/array_stream_linker.js Tue Dec 08 17:16:10 2015 +0530
@@ -0,0 +1,49 @@
+#! array stream linker example
+
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This script assumes you've built jdk9 or using latest
+// jdk9 image and put the 'bin' directory in the PATH
+
+$EXEC.throwOnError=true
+
+// compile ArrayStreamLinkerExporter
+`javac -cp ../dist/nashorn.jar ArrayStreamLinkerExporter.java`
+
+// make a jar file out of pluggable linker
+`jar cvf array_stream_linker.jar ArrayStreamLinkerExporter*.class META-INF/`
+
+// run a sample script that uses pluggable linker
+// but make sure classpath points to the pluggable linker jar!
+
+`jjs -cp array_stream_linker.jar array_stream.js`
+print($OUT)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/buffer_index.js Tue Dec 08 17:16:10 2015 +0530
@@ -0,0 +1,65 @@
+# Usage: jjs -cp buffer_indexing_linker.jar buffer_index.js
+
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This script depends on buffer indexing dynalink linker. Without that
+// linker in classpath, this script will fail to run properly.
+
+function str(buf) {
+ var s = ''
+ for (var i = 0; i < buf.length; i++)
+ s += buf[i] + ","
+ return s
+}
+
+var ByteBuffer = Java.type("java.nio.ByteBuffer")
+var bb = ByteBuffer.allocate(10)
+for (var i = 0; i < bb.length; i++)
+ bb[i] = i*i
+print(str(bb))
+
+var CharBuffer = Java.type("java.nio.CharBuffer")
+var cb = CharBuffer.wrap("hello world")
+print(str(cb))
+
+var RandomAccessFile = Java.type("java.io.RandomAccessFile")
+var raf = new RandomAccessFile("buffer_index.js", "r")
+var chan = raf.getChannel()
+var fileSize = chan.size()
+var buf = ByteBuffer.allocate(fileSize)
+chan.read(buf)
+chan.close()
+
+var str = ''
+for (var i = 0; i < buf.length; i++)
+ str += String.fromCharCode(buf[i])
+print(str)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/buffer_indexing_linker.js Tue Dec 08 17:16:10 2015 +0530
@@ -0,0 +1,49 @@
+# buffer indexing linker example
+
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This script assumes you've built jdk9 or using latest
+// jdk9 image and put the 'bin' directory in the PATH
+
+$EXEC.throwOnError=true
+
+// compile BufferIndexingLinkerExporter
+`javac -cp ../dist/nashorn.jar BufferIndexingLinkerExporter.java`
+
+// make a jar file out of pluggable linker
+`jar cvf buffer_indexing_linker.jar BufferIndexingLinkerExporter*.class META-INF/`
+
+// run a sample script that uses pluggable linker
+// but make sure classpath points to the pluggable linker jar!
+
+`jjs -cp buffer_indexing_linker.jar buffer_index.js`
+print($OUT)