nashorn预编译_Java 8:在新的Nashorn JS引擎中编译Lambda表达式

nashorn预编译

在最近的一篇文章中,我了解了Java 8和Scala如何实现Lambda表达式。 众所周知,Java 8不仅引入了对Javac编译器的改进,而且还引入了全新的解决方案-Nashorn。

这个新引擎旨在替代Java现有JavaScript解释器Rhino。 这为我们带来了JVM的前列,当谈到在速度与世界的V8引擎执行JavaScript,在那里(我希望我们会最终得到过去那种汽车地毯的事情 :))所以,我认为这将是一个很好的时机,也可以通过深入了解Nashorn,看看它如何编译Lambda表达式(尤其是与Java和Scala相比)。

我们将要看的lambda表达式类似于我们用Java和Scala测试过的表达式。

这是代码:

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");String js;js = "var map = Array.prototype.map \n";
js += "var names = [\"john\", \"jerry\", \"bob\"]\n";
js += "var a = map.call(names, function(name) { return name.length() })\n";
js += "print(a)";engine.eval(js);

您似乎觉得足够纯真。 但是,请稍等...

进入字节码

我们的第一个挑战是获取JVM看到的实际字节码。 与Java和Scala的编译器具有持久性(即将.class / jar文件生成到磁盘)不同,Nashorn会编译内存中的所有内容,并将字节码直接传递给JVM。 幸运的是,我们已经有了Java代理来进行救援。 我编写了一个简单的Java代理来捕获并保留生成的字节码。 从那里开始,有一个简单的javap可以打印代码。

如果您还记得的话,我很高兴看到新的Java 8编译器如何使用Java 7中引入的invokeDynamic指令链接到Lambda函数代码。 好吧,与Nashorn一起,他们真的参加了比赛。 现在一切都完全基于它。 看看下面。

读取字节码

invokeDynamic 。 就像我们都在同一页面上一样,Java 7中添加了invokeDynamic指令,以允许人们编写自己的动态语言来在运行时决定如何链接代码。

对于Java和Scala之类的静态语言,编译器在编译时决定将调用哪种方法(在JVM运行时的帮助下,用于多态)。 运行时链接是通过标准ClassLoader完成的,以查找类。 甚至方法重载解析之类的事情都在编译时完成。

动态与静态链接 。 不幸的是,对于本质上更具动态性的语言(并且JS是一个很好的例子),静态解析可能是不可能的。 当我们在Java中说obj.foo()时,obj类具有foo()方法,否则就没有。 在像JS这样的语言中,它将取决于运行时obj引用的实际对象,这是静态编译器的噩梦。 在这种情况下,编译时的链接方法行不通。 但是invokeDynamic确实可以。

InvokeDynamic允许在运行时将链接推迟回该语言的编写者,因此他们可以根据自己的语言语义,指导JVM确定要调用哪种方法。 这是双赢的局面。 JVM获得了一种链接,优化和执行的实际方法,并且语言制造商可以控制其解析度。 动态链接是我们在Takipi中必须努力支持的工作 。

Nashorn如何链接

Nashorn确实有效地利用了这一点。 让我们看一下示例,以了解其工作原理。 这是Lambda代码中的第一条invokeDynamic指令,用于检索JS Array类的值–

invokedynamic 0 "dyn:getProp|getElem|getMethod:prototype":(Ljava/lang/Object;)Ljava/lang/Object;

Nashorn要求JVM在运行时将其传递给该字符串,作为交换,它将返回一个方法的句柄,该方法接受一个Object并返回一个。 只要JVM获取此类方法的句柄,它就可以链接。

.class文件的特殊部分中指定了负责返回此句柄的方法(也称为引导程序方法),该文件中包含可用的引导程序方法列表。 您看到的0值是该方法在该表中的索引,JVM将调用该索引来获取将链接到的方法句柄。

在我看来,Nashorn的人们做了一件很酷的事情,他们没有编写自己的库来解析和链接代码, 而是继续集成了dynalink这个开源项目,该项目旨在帮助动态语言基于统一平台链接代码。 这就是为什么您在每个字符串的开头看到“ dyn:”前缀的原因。

实际流量

现在我们已经掌握了Nashorn所使用的方法,现在让我们看一下实际流程。 为了简洁起见,我删除了一些说明。 完整的代码可以在这里找到。

1.第一组指令将数组映射函数加载到脚本中。

//load JS array
invokedynamic 0 "dyn:getProp|getElem|getMethod:Array":(Ljava/lang/Object;)Ljava/lang/Object;//load its prototype element
invokedynamic 0 "dyn:getProp|getElem|getMethod:prototype":(Ljava/lang/Object;)Ljava/lang/Object;//load the map method
invokedynamic 0 "dyn:getProp|getElem|getMethod:map":(Ljava/lang/Object;)Ljava/lang/Object;//set it to the map local
invokedynamic 0 #0:"dyn:setProp|setElem:map":(Ljava/lang/Object;Ljava/lang/Object;)V

2.接下来,我们分配名称数组

//allocate the names array as a JS object
invokestatic jdk/nashorn/internal/objects/Global.allocate:([Ljava/lang/Object;)Ljdk/nashorn/internal/objects/NativeArray;//places it into names
invokedynamic 0 #0:"dyn:setProp|setElem:names":(Ljava/lang/Object;Ljava/lang/Object;)Vinvokedynamic 0 #0:"dyn:getProp|getElem|getMethod:names":(Ljava/lang/Object;)Ljava/lang/Object;

3.查找并加载Lambda函数

//load the constants field for this script compiled and filled at runtime by Nashorn
getstatic constants//refer to the 2nd entry, where Nashorn will place a handle to the lambda code
iconst_2//get it from the constants array
aaload//ensure it’s a JS function object
checkcast class jdk/nashorn/internal/runtime/RecompilableScriptFunctionData

4.使用名称和Lambda调用map,然后将结果放入

//call the map function, passing it names and the Lambda function from the stackinvokedynamic 0 #1:"dyn:call":(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljdk/nashorn/internal/runtime/ScriptFunction ;)Ljava/lang/Object;//put the result in a
invokedynamic 0 #0:"dyn:setProp|setElem:a":(Ljava/lang/Object;Ljava/lang/Object;)V

5.找到打印功能并在打印机上调用

//load the print function
invokedynamic 0 #0:"dyn:getMethod|getProp|getElem:print":(Ljava/lang/Object;)Ljava/lang/Object;//load a
invokedynamic 0 #0:"dyn:getProp|getElem|getMethod:a":(Ljava/lang/Object;)Ljava/lang/Object;// call print on it
invokedynamic 0 #2:"dyn:call":(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;

lambda函数本身被编译并作为私有函数放在与脚本相同的类中。 这与Java 8 lambda非常相似。 代码本身很简单。 我们加载字符串,找到其长度函数并调用它。

//Load the name argument (var #1)
aload_1//find its length() function
invokedynamic 0 "dyn:getMethod|getProp|getElem:length":(Ljava/lang/Object;)Ljava/lang/Object;//call length
invokedynamic 0 "dyn:call":(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;//return the result
areturn

奖金回合–最终字节码

到目前为止,我们一直在处理的代码实际上并不是JVM在运行时将执行的代码。 请记住,每个invokeDynamic指令都将解析为物理字节码方法,然后JVM将其编译为机器代码并执行。

为了查看JVM运行的实际字节码,我使用了一个简单的技巧。 我在类中用一个简单的Java方法调用包装了对length()的调用。 这使我可以放置一个断点,并查看JVM执行以进入Lambda的最终调用堆栈。

这是代码–

js += "var a = map.call(names, function(name) {
return Java.type("LambdaTest”).wrap(name.length())
})";

包好了–

public static int wrap(String s)
{
return s.length();
}

现在让我们玩一个游戏。 该堆栈中有几帧? 想一想。 如果您猜到少于<100 –您欠我一杯啤酒。 完整的调用堆栈可以在这里找到。

之所以如此,也是非常有趣的原因,这是关于即将发布的全新帖子的一个故事。

参考: Java 8:在Takipi博客上由我们的JCG合作伙伴 Iris Shoor 在New Nashorn JS引擎中编译Lambda表达式 。

翻译自: https://www.javacodegeeks.com/2014/02/java-8-compiling-lambda-expressions-in-the-new-nashorn-js-engine.html

nashorn预编译

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/344113.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

光端机各种类型的接口介绍

光端机的接口类型还是比较多的&#xff0c;常见的物理接口类型有BNC接口、光纤接口、RJ-45接口、RS-232接口、RJ-11接口。那么&#xff0c;你对这五种典型的物理接口类型是否有所了解呢&#xff1f;接下来就由飞畅科技的小编一起来详细了解下吧&#xff01; 光端机的典型物理接…

[渝粤教育] 中国地质大学 事故应急救援 复习题

《事故应急救援》模拟题 一单选题 1.()是城市的整体预案从总体上阐述城市的应急方针政策应急组织机构及响应的职责应急行动的思路. A.综合预案 B.专项预案 C.总体预案 D.现场预案 2.()是在专项预案的基础上根据具体情况需要而编制的. A.综合预案 B.专项预案 C.现场预案 D.应急…

微服务升级优点_微服务–——定义, 原则 和 优点

微服务是业界最新的流行语&#xff0c;似乎每个人都在以这样或那样的方式谈论它。让我们理解一下什么是微服务&#xff1f;通过这篇教程我们将理解微服务的定义&#xff0c;概念以及微服务的原理。微服务的定义如今&#xff0c;微服务是SOA(面向服务的架构)之后越来越流行的架构…

[渝粤教育] 中国地质大学 企业文化建设与管理 复习题

《企业文化建设与管理》模拟题 一单选题 1.组织文化包括 A.物质文化&#xff0c;社会文化&#xff0c;精神文化 B.物质文化&#xff0c;精神文化&#xff0c;政治文化 C.物质文化&#xff0c;行为文化&#xff0c;制度文化 D.物质文化&#xff0c;社会文化&#xff0c;政治文化…

五金反引号

五种琴弦 从Java 1.0开始&#xff0c;我们就有了字符串文字"like this" 。 我们还想要其他什么字符串&#xff1f; 其他编程语言为我们提供&#xff1a; 表达式插值&#xff1a; s"I am ${age - 10} years old." 插值格式&#xff1a; f"Price: $pr…

多功能视频光端机_多业务光端机的功能特性

视频光端机&#xff0c;就是把1到多路的模拟视频信号通过各种编码转换成光信号通过光纤介质来传输的设备&#xff0c;由于视频信号转换成光信号的过程中会通过模拟转换和数字转换两种技术&#xff0c;所以视频光端机又分为模拟光端机和数字光端机。光端机原理就是把信号调制到光…

[渝粤教育] 中国地质大学 信息资源管理 复习题 (2)

《信息资源管理》模拟题 一.单选题 1.目前在我国各级政府部门在信息资源管理过程中的主要职责是(). A.向社会提供信息服务 B从政策上指导信息资源的开发和利用 C.直接从事信息资源的开发和管理 D.研究制定信息资源开发的标准和规范 2.研究与制定信息资源开发的标准与规范的责…

curl_exec() 执行的时候发送不出去_为什么端口明明开着,nmap却扫描不出来,看老司机怎么指点迷津...

大家应该都知道&#xff0c;nmap是用来扫描端口的标杆级神器&#xff0c;我们经常在运维工作或安全评估中使用到它。在使用的时候&#xff0c;我们可能会碰到明明目标IP端口有开着&#xff0c;但是nmap却死活扫描不出来&#xff0c;等了大半天却得到一些不可靠的结果。那到底是…

[渝粤教育] 中国地质大学 地球科学概论 复习题 (2)

《地球科学概论》模拟题 一.单选题 1.有一种岩石其SiO2含量为69%中粗粒粒状结晶结构片麻状构造主要由长石石英和角闪石等矿物组成这种岩石应该是() A.花岗岩; B.流纹岩; C.片麻岩; D.闪长岩 2.安山岩的化学成分相似于() A.橄榄岩 B.闪长岩 C.花岗岩 D.辉长岩 3.下列描述正确的…

4路视频+4路百电(物理隔离)+8路电话+开关量+串口+电话光端机 武警光端机

产品描述 本系列产品&#xff0c;是在该公司研制的专用超大规模集成电路的基础上&#xff0c;研发的点对点多业务光传输设备。此款产品提供4路视频&#xff0c;1-8路电话接口&#xff1b;1-16路开关量接口/1-8路RS232-422-485接口&#xff1b;4路百兆以太网接口&#xff0c;4路…

[渝粤教育] 中国地质大学 大学英语(6) 复习题

《大学英语(3)》模拟题 一.单选题 1.Are you sure about that?(). A.You needn’t worry about that. B.I like the idea. C.Ohno.I’m afraid of that. D.Ohyes.I’m absolutely positive. 2.Before I got to the cinemathe film(). A.had begun B.has begun C.is begun D.w…

yuki翻译器钩子_git hooks钩子

GIT HOOKS钩子(hooks)是一些在"$GIT-DIR/hooks"目录的脚本,在被特定的事件(certain points)触发后被调用。当"git init"命令被调用后,一些非常有用的示例钩子文件(hooks)被拷到新仓库的hooks目录中;但是在默认情况下这些钩子(hooks)是不生效的。 把这些钩子…

返回值是内置类型 不能更改_选择通过更改内容类型返回的详细程度,第二部分...

返回值是内置类型 不能更改在上一篇文章中 &#xff0c;我们研究了如何使用MOXy的功能来控制特定实体的数据输出级别。 这篇文章着眼于Jersey 2.x提供的抽象&#xff0c;它允许您定义一组自定义的批注以具有相同的效果。 与之前一样&#xff0c;我们几乎没有什么琐碎的资源可以…

[渝粤教育] 中国地质大学 嵌入式操作系统 复习题 (2)

《嵌入式操作系统》模拟题 一.单选题 1./babys目录属于project群组(group)并设置了1770的访问权限.而project群组的成员如下: #group dog cat foxdog: dog projectcat:cat project fox:fox project请问以上每一个用户具有对/babys目录中其他用户的文件和目录的有效访问权限是哪…

武警多业务光端机,五防光端机产品介绍

产品描述 本系列产品&#xff0c;是在该公司研制的专用超大规模集成电路的基础上&#xff0c;研发的点对点多业务光传输设备。此款产品提供4路视频&#xff0c;1-4路电话接口&#xff1b;1-16路开关量接口/1-8路RS232-422-485接口&#xff1b;4路千兆以太网接口&#xff08;共享…

sts 创建webservice项目_Eclipse Maven生成WebService客户端代码及测试

条件:1. Eclipse安装Axis2插件2. 导入Web Service相关包创建Maven项目导入axis2相关jar包xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">4.0.0com.soapsoap0.0.1-SNAPSHOTsoap-clientdom4jdom4j1.6.1org.a…

[渝粤教育] 中国地质大学 建筑艺术赏析 复习题

《建筑材料赏析》模拟题 一.单选题 1.离狮身人面像最近的金字塔是() A.胡夫金字塔 B.海夫拉金字塔 C.门卡乌拉金字塔 2.中国的古典建筑属于() A.砖石结构系统 B.木结构系统 C.水泥结构系统 3.伊什达门是巴比伦城的()门 A.东 B.南 C.西 D.北 4.底比斯的卡纳克阿蒙神庙是在古埃…

J2Pay –入门

入门将指导您如何通过非常简单的步骤快速开始使用J2pay。 下载 J2Pay在Maven上可用。 <dependency><groupId>com.tranxactive</groupId><artifactId>j2pay</artifactId><version>2.4.0</version></dependency>您也可以在此…

[渝粤教育] 中国地质大学 操作系统原理(新) 复习题

《操作系统原理》模拟题 选择题 1.UNIX操作系统是一个()操作系统. A.实时 B.单用户多任务 C.多道批处理 D.多用户多任务 2.Unix系统采用的文件目录结构是(). A.一级目录结构 B.二级目录结构 C.多级目录结构 D.索引目录结构 3.操作系统是一组()程序 A.文件管理 B.中断处理 C.资…

[渝粤教育] 中国地质大学 材料力学 复习题 (2)

《材料力学》模拟题 一单选题 1.直径为d的圆截面拉伸试件其标距是(). A.试件两端面之间的距离 B.试件中段等截面部分的长度 C.在试件中段的等截面部分中选取的”工作段”的长度其值为5d或10d D.在试件中段的等截面部分中选取的”工作段”的长度其值应大于10d 2.轴向拉伸的应力…