![Page 1: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/1.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Rhino & RingoJS: JavaScript on the JVM
Hannes Wallnöferhttp://hns.github.com
@hannesw
![Page 2: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/2.jpg)
Hannes Wallnöfer - Rhino and RingoJS
"Overall, JavaScript as a system programming language feels a lot like Lisp must have for the programming generation before mine: minimal syntax, very powerful and orthogonal core
abstractions, and (dare I say it) not much type-checking or busy-work to get in your way."
C. Scott Ananian (litl)http://cananian.livejournal.com/58744.html
![Page 3: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/3.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Rhino and RingoJS
Rhino Started at Netscape in 1997 Part of Navigator port to Java Mozilla project
RingoJS Started by me in 2009 Provide the parts missing for real world software
development, especially web applications
![Page 4: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/4.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Rhino and RingoJS
![Page 5: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/5.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Rhino
Robust, optimized codebase but showing its age very complete
interpreter mode compiled mode debugger follows ECMAScript spec rigorously implements JS 1.7 (almost 1.8) implements most of ECMAScript 5
![Page 6: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/6.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Optimimization
Rhino used to be one of the faster JVM languages
But not much movement in the last few years Browser JS implementations have roared past
Rhino
![Page 7: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/7.jpg)
Hannes Wallnöfer - Rhino and RingoJS
InvokeDynamic
Rémi probably told you all about it John Rose (Oracle): "Thundering Rhinos" at
JavaOne 2010
http://blogs.sun.com/jrose/entry/javaone_in_2010
4x speedup of Richards benchmark (part of V8 benchmark suite) within 50% of V8 by manually editing bytecode
![Page 8: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/8.jpg)
Hannes Wallnöfer - Rhino and RingoJS
JavaScript objects...
… are hashtablesvar x = {foo: 3}
no notion of classesx["baz"] = 7;
… have prototypesfunction Foo() {...}
Foo.prototype.bar = 3;
var y = new Foo();
var y = Object.create
![Page 9: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/9.jpg)
Hannes Wallnöfer - Rhino and RingoJS
How to implement JS objects?
Obvious solution: hashtables works, but rather slow
Ideally JS properties are mapped to Java fields easy for the simple case fails for common cases (multiple scripts,
dynamic code...)
Rhino hack: idgen
![Page 10: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/10.jpg)
Hannes Wallnöfer - Rhino and RingoJS
idgen – custom property handling in Rhino
Used for built-in types (Object, Array, Function)
Requires pre-processing of code:
// #generated# Last update: 2007-05-09 08:15:15 EDT L0: { id = 0; String X = null; int c; L: switch (s.length()) { case 4: X="name";id=Id_name; break L; case 5: X="arity";id=Id_arity; break L; case 6: X="length";id=Id_length; break L; case 9: c=s.charAt(0); if (c=='a') { X="arguments";id=Id_arguments; } else if (c=='p') { X="prototype";id=Id_prototype; } break L; } if (X!=null && X!=s && !X.equals(s)) id = 0; break L0; }// #/generated#
Not faster anymore
![Page 11: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/11.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Rhino-opt
Experimental Rhino branch
https://github.com/hns/rhino-opt
Various branches: companion-scopes native-callsites non-object-this
![Page 12: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/12.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Anatomy of a running JS program
![Page 13: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/13.jpg)
Hannes Wallnöfer - Rhino and RingoJS
companion-scopesfunction outer(x) { var y; for (var i = 0; i < 10000000; i++) { y = inner(); } function inner() { return x; } return inner();}
0
200
400
600
800
1000
1200
1400
1600
1800
2000
RhinoRhino-optV8
![Page 14: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/14.jpg)
Hannes Wallnöfer - Rhino and RingoJS
companion-scopes
Unfortunately, improvement is not very relevant for Google V8 Benchmark, which is heavy on objects/classes, not scopes.
0
500
1000
1500
2000
2500
3000
3500
4000
4500
RhinoRhino-optV8
![Page 15: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/15.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Generic mapping of JS objects to Java class
Use "mixed" approach Generate custom Java classes for JS objects But still allow dynamic property access
Store Rhino property slots as Java fields Generate bytecode to access Java field if
defined
![Page 16: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/16.jpg)
Hannes Wallnöfer - Rhino and RingoJS
RingoJS
Adds features to Rhino for real-world application development
Modules Packages Filesystem Testing HTTP
and much more
![Page 17: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/17.jpg)
Hannes Wallnöfer - Rhino and RingoJS
CommonJS
Started by Kevin Dangoor in 01/2009 Good inital progress Stalled above sync/async divide Ratified standards for Modules, Packages,
Web Server API Proposals for binary data, IO, filesystem
![Page 18: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/18.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Example: reading lines from a file
var fs = require("fs");var txt = fs.read("git/ringojs/README.md");
![Page 19: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/19.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Example: reading lines from a file
var fs = require("fs");var file = fs.open("git/ringojs/README.md");
var lines = [line for each (line in file)];
lines.filter(function(line) { return line.indexOf("build") > -1}).map(String.toUpperCase).join("\n");
![Page 20: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/20.jpg)
Hannes Wallnöfer - Rhino and RingoJS
POSIX
Borrowed functionality from JRuby (jnr-posix) - thank you!
Provides features for getting/setting file permissions and ownership, handling symbolic links.
![Page 21: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/21.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Web App: JSGI
A web application is a JavaScript function that takes a request object and returns a response objectfunction app(request) { return { status: 200, headers: {}, body: ["hello world"] };}
Similar to Rack (Ruby) and WSGI (Python), not Java Servlets
![Page 22: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/22.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Asynchronous JSGI
Non-standard extension Works with Jetty Continuations/Servlet 3.0function app(request) { var response = defer(); setTimeout(function() { response.resolve({ status: 200, headers: {}, body: ["hello world"] }); }, 2000); return response;}
![Page 23: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/23.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Accessing Java
LiveConnect: direct mapping between Java and JavaScriptvar file = new java.io.File("test.txt")f.exists()f.getName()
Easy, natural mapping for 97% of cases Except:
method overloads creating Java arrays
![Page 24: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/24.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Implementing Java interfaces
obj = { run: function () {
print("\nrunning"); }
}r = new java.lang.Runnable(obj)t = new java.lang.Thread(r)t.start()
![Page 25: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/25.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Implementing Java interfaces
impl = function () {print("running");
}new java.lang.Thread(impl).start()
![Page 26: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/26.jpg)
Hannes Wallnöfer - Rhino and RingoJS
JavaAdapter
Allows subclassing in addition to implementing interfaces
Allows implementing multiple interfaces More verboseJavaAdapter(
javaIntfOrClass, [javaIntf, ..., javaIntf,]javascriptObject)
Classes must have zero-arg constructor
![Page 27: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/27.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Using Java's Security Framework
Scripts can have CodeSource Scripts can execute PrivilegedAction on behalf
of untrusted codeprivileged(function() { ...}
Unsolved issues due to dynamic nature of JavaScript
![Page 28: Rhino & RingoJS: JavaScript on the JVMhns.github.io/slides/fosdem-js-jvm.pdf · follows ECMAScript spec rigorously ... objects/classes, not scopes. 0 500 1000 1500 2000 2500 3000](https://reader034.vdocuments.site/reader034/viewer/2022042915/5f53ffc41940923c510bb0ee/html5/thumbnails/28.jpg)
Hannes Wallnöfer - Rhino and RingoJS
Thanks!