背景
谢邀,出于好奇,稍微翻阅了一下nashron相关的的文章和源码。由于本人对java的理解不是特别深入,因此只能大概描述一下nashron的工作原理。如有问题,请直接指出。
使用
下面大致说一下nashron的使用方式java调用javascirpt
// Main.javapackage gxg;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class Main {
public static void main(String[] args) throws Exception {
ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine engine = engineManager.getEngineByName("nashorn");
engine.eval("function sum(a, b) { return a + b; }");
System.out.println(engine.eval("sum(1, 2)")); // 3.0 }
}javascript调用java
// A.javapackage gxg;
public class A {
private int a;
public A(int a) {
this.a = a;
}
public void setA(int a) {
this.a = a;
}
public int getA() {
return this.a;
}
}
// Main.javapackage gxg;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class Main {
public static void main(String[] args) throws Exception {
ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine engine = engineManager.getEngineByName("nashorn");
engine.eval("var A = Java.type(\"gxg.A\")");
engine.eval("var a = new A(1)");
System.out.println(engine.eval("a.getA()")); // 1 }
}jjs原理类似engine.eval,下面就不在详述。
原理
建议先看一下R大之前的回答
token stream ast ir class
scanner --------------> parser -----> code generation ----> loader -------> runtime在源码中,ast和ir用的都是同一套类
问题1:nashron如何将javascript编译为jvm字节码的
对应上面的scanner,parser和code generation。但是这不够,还需要使用asm把ir转化成bytecode:
token stream ast ir bytecode
scanner --------------> parser -----> code generation ----> asm ----------> loader
问题2:nashron如何载入和运行jvm字节码载入(loader):通过asm的defineClass把之前生成的bytecode转化成对应的类,并载入内存,但是遇到一些native的javascript的类,loader会专门把预先定义好的相应的的java类载入进来(纯属个人猜测)
token stream ast ir bytecode asm defineClass generate class
scanner --------------> parser -----> code generation ----> asm ----------> loader -------------------------------------> runtime
| ^ | ^
| ir | | load predefined native class |
|-------------------------------| |-------------------------------------运行(runtime):使用method handlers和反射机制来调用类的方法
问题3:两个语言类型转换的部分是如何实现的
通过问题2的回答,我们看到在loader完之后javascript类型会和java类型对齐
javascript类型的调用就会和java类型的调用对齐
这样两者就可以融合和互操了。
其他
在nashorn的wiki在jsr292中提出,并在java8中引入nashron
在jsr223中提出:nashron旨在把javascrpit嵌入到java里,并可以作为单独的javascript引擎运行
在jep335中提出,并在java11中废弃nashron
在jep372中提出,并在java15中移除nashron
现在GraalJS作为GraalVM的子项目,已经代替了nashron
参考