JS引擎(2):Java平台上JavaScript引擎—Rhino/Nashorn概述
可以后端开发的 javascript引擎有
Chrome V8 基于C++
java的Rhino引擎(JDK6被植入),Java8 被替换为Nashorn
Rhino和Nashorn都是用Java实现的JavaScript引擎。它们自身都是普通的Java程序,运行在JVM上
Rhino简介
Rhino [ˈraɪnəʊ]是一种使用 Java 语言编写的 JavaScript 的开源实现,原先由Mozilla开发。
Rhino 是一种动态类型的、基于对象的脚本语言,它可以简单地访问各种 Java 类库。
当时Netscape想用纯Java来实现新版浏览器,自然需要一个Java版的JavaScript引擎实现;另外也希望能在服务器端把JavaScript当作Java应用里的脚本语言使用。于是Rhino就诞生了。
官网自带Rhino历史,跟Wikipedia上的Rhino词条基本上一样,有兴趣的话可以去看看。
Parser是从SpiderMonkey移植过来的。自然也是手写的纯递归下降式。
JavaScript对象的接口是org.mozilla.javascript.Scriptable。主要实现类是IdScriptableObject、ScriptableObject。用Object[]来存字段,挺高效的。
IdScriptableObject {
Object[] valueArray;
short[] attributeArray;
// ...
}
Rhino可以通过参数从11个预设的优化基本中选择一个使用。只从JVM以上的层面看,Rhino既可以工作于纯解释模式(-1),也可以工作于纯编译模式(0-9)。这11个级别分别是:
Rhino 优化级别
当优化级别为-1时,Rhino使用一个用Java写的字节码解释器来解释执行JavaScript。
此时,Rhino的工作流程简单说是:( [ ... ]表示数据实体,( ... )表示Rhino处理数据的程序)
[ JavaScript源码 ] -> ( 语法分析器 Parser ) -> [ 抽象语法树(AST) ast ] -> ( Rhino内部表现形式生成器 IRFactory ) -> [ Rhino内部表现形式 ScriptNode ] -> ( Rhino字节码生成器 CodeGenerator ) -> [ Rhino字节码 Icode ] -> ( Rhino解释器 Interpreter ) -> [ 运行结果 ]
这里说的Rhino字节码是Rhino内部用来表示JavaScript程序语义的一套字节码,跟JVM所支持的Java字节码没关系。
当优化级别为0~9时,Rhino使用一个用Java写的编译器将JavaScript编译为Java字节码;生成出来的Java字节码交由JVM直接执行。至于底下的JVM是解释执行Java字节码,还是将Java字节码编译为机器码再执行,Rhino并不关心。
此时,Rhino的工作流程简单说是:
[ JavaScript源码 ] -> ( 语法分析器 Parser ) -> [ 抽象语法树(AST) ast ] -> ( Rhino内部表现形式生成器 IRFactory ) -> [ Rhino内部表现形式 ScriptNode ] -> ( 可选优化 Optimizer ) -> ( Java字节码生成器 Codegen ) -> [ Java Class文件(包含Java字节码) ] -> JVM加载和执行生成的字节码 -> [ 运行结果 ]
只从JVM以上的层面看,Nashorn是一种单层的纯编译型JavaScript实现。所有JavaScript代码在首次实际执行前都会被编译为Java字节码交由JVM执行。
这种以编译的方式模式执行JavaScript,跟一个Java源码编译器(例如javac)把Java源码编译为Class文件然后交由JVM执行,过程是类似的。只不过Rhino做的优化不够多而且JavaScript的语义也远比Java动态,所以此时Rhino上运行JavaScript的性能仍然无法跟Java的性能比。
JDK6 JDK7 Rhino区别
顺带一提,Sun/Oracle JDK6 / OpenJDK6中自带的Rhino是经过裁剪的,去掉了Mozilla Rhino中的部分功能。其中一个被去掉的功能就是Rhino的编译模式。这意味着JDK6自带的Rhino只能用解释模式运行。
而Oracle JDK7 / OpenJDK7放宽了这一限制,当有SecurityManager时只能用解释模式,否则可以配置"rhino.opt.level"系统属性来设置Rhino的优化级别;默认仍然是用解释模式(优化级别默认为-1)。
Nashorn起初是Oracle内部一个实验项目,用于验证JSR 292功能的完整性、可用性、易用性。后来得到了内部的关注,决定将其产品化,作为默认的JavaScript实现替换掉从JDK6开始包含在JDK之中的Rhino。
Nashorn
Nashorn(读作Naz-horn[naːsˌɔn])是Oracle全新开发的JavaScript实现。高度兼容ECMAScript 5标准,并尽可能兼容Rhino。它使用Java语言实现,运行在JVM上,借助JDK7开始包含的JSR 292(invokedynamic)新功能达到较高的性能,同时保持代码的相对整洁
在2012年底Nashorn就已经达到可以完全通过test262测试套件的兼容性,就这点说它甚至比SpiderMonkey、V8更佳兼容于标准。
邮件列表: http://mail.openjdk.java.net/mailman/listinfo/nashorn-dev
兼容标准: ECMAScript 5.1
实现语言: Java
代码版本控制工具: Mercurial
开源许可证: GPLv2
Nashorn是一个纯编译的JavaScript引擎。它没有用Java实现的JavaScript解释器,而只有把JavaScript编译为Java字节码再交由JVM执行这一种流程,跟Rhino的编译流程类似。
Nashorn还在快速开发中,日新月异,所以它的工作流程在不断变化。简单来说,Nashorn的编译入口可以从Context.compile()开始看:
[ JavaScript源码 ] -> ( 语法分析器 Parser ) -> [ 抽象语法树(AST) ir ] -> ( 编译优化 Compiler ) -> [ 优化后的AST + Java Class文件(包含Java字节码) ] -> JVM加载和执行生成的字节码 -> [ 运行结果 ]
只从JVM以上的层面看,Nashorn是一种单层的纯编译型JavaScript实现。所有JavaScript代码在首次实际执行前都会被编译为Java字节码交由JVM执行。
(当然JVM自身可能是混合执行模式的,例如HotSpot VM与J9 VM。所以Nashorn在实际运行中可能需要一定预热才会达到最高速度)
Nashorn不但可以执行JavaScript,还可以当作库为其它工具提供一些基础服务。例如说它现在为NetBeans IDE中的JavaScript编辑器提供语法高亮支持和调试支持。
从Oracle JDK 8 build 82开始,Nashorn已经作为JDK8的一部分包含在安装包中。安装后可以在JDK安装目录的jre/lib/ext/nashorn.jar找到Nashorn的实现。
直接使用Java类的实例来容纳JavaScript对象的字段,在对象内嵌入字段而不放在spill array里的好处是:
对象更加紧凑,数据离得更近,局部性更好
数组访问有边界检查,而对象字段访问则没有,后者效率更高
参考内容:
Rhino 和 Nashorn 到底怎么运行? - RednaxelaFX的回答 - 知乎 https://www.zhihu.com/question/27631001/answer/37407481
各JavaScript引擎的简介,及相关资料/博客收集帖 https://hllvm-group.iteye.com/group/topic/37596
转载本站文章《JS引擎(2):Java平台上JavaScript引擎—Rhino/Nashorn概述》,
请注明出处:https://www.zhoulujun.cn/html/webfront/browser/webkit/2020_0718_8520.html
JS引擎(2):Java平台上JavaScript引擎—Rhino/Nashorn概述的更多相关文章
- Servlet Servlet是Java平台上的CGI技术
Servlet Servlet是Java平台上的CGI技术.Servlet在服务器端运行,动态地生成Web页面.与传统的CGI和许多其它类似CGI的技术相比,Java Servlet具有更高的效率并更 ...
- Java平台上的AOP实现机制
Java平台上的AOP实现机制 动态代理(Dynamic Proxy)机制,在运行期间动态的为相应接口生成对应的代理对象.SpringAop默认情况下采用这种机制来实现AOP机能.缺点:相对于编译后的 ...
- js:我们应该如何去了解JavaScript引擎的工作原理(转)
http://www.nowamagic.net/librarys/veda/detail/1579 昨天收到一封来自深圳的一位前端童鞋的邮件,邮件内容如下(很抱歉,未经过他的允许,公开邮件内容,不过 ...
- 【sping揭秘】11、Java 平台上的AOP实现机制
动态代理 Jdk1.3只有引入的动态代理机制,可以再运行期间,为相应的接口(必须得有接口)动态生成对应的代理对象 基于以上问题,我们可以将横切关注点逻辑封装到动态代理的invocationhandle ...
- 理解WebKit和Chromium: JavaScript引擎简介
转载请注明原文地址:http://blog.csdn.net/milado_nju 1. 什么是JavaScript引擎 什么是JavaScript引擎?简单来讲,就是能够提供执行JavaScript ...
- 【转】理解WebKit和Chromium: JavaScript引擎简介
转载请注明原文地址:http://blog.csdn.net/milado_nju1. 什么是JavaScript引擎什么是JavaScript引擎?简单来讲,就是能够提供执行JavaScript代码 ...
- 简介浏览器内核与JavaScript引擎
本文介绍了常用浏览器内核与JavaScript引擎 一.浏览器内核 Rending Engine, 顾名思义,称之为渲染网页内容的,将网页的代码转换为你看得见的页面,因为是排版,所以排版,所以肯定会有 ...
- 关于浏览器内核与javascript引擎的一些小知识
浏览器是我们每天几乎都必须使用的软件产品,可是对于自己每天都接触的浏览器,很多同学其实对其一无所知.今天异次元就跟大家说说关于浏览器内核的一些事儿吧,好让你了解多一点稍微内在的东西. 在下面的文章中主 ...
- 对JavaScript 引擎基础:Shapes 和 Inline Caches
全文有5个部分组成 1.JavaScript 引擎工作流程:介绍 JavaScript 引擎的处理流水线,这一部分会涉及到解释器/编译器的内容,且会分点介绍不同引擎间的差别与共同点: 2.JavaSc ...
- JavaScript 引擎基础:Shapes 和 Inline Caches
JavaScript 引擎基础:Shapes 和 Inline Caches hijiangtao 中国科学院大学 计算机应用技术硕士 260 人赞同了该文章 前言:本文也可以被称做 “JavaS ...
随机推荐
- 如何卸载inventor 2023?怎么把inventor彻底卸载删除干净重新安装的方法【转载】
inventor 2023卸载重新安装方法,使用清理卸载工具箱完全彻底删除干净inventor 2023各种残留注册表和文件.inventor 2023显示已安装或者报错出现提示安装未完成某些产品无法 ...
- 理解 Shell
理解 Shell shell 的父子关系 用于登录的某个虚拟控制器终端,或在 GUI 中运行终端仿真器时所启动的默认的交互 shell,是一个父 shell.本书到目前为止都是父 shell 提供 C ...
- FII-PRX100-D开发板FPGA的烧录和RISC-V 软件代码下载
1. 生成*.bit文件之前先RESET结果 首先,打开Vivado FII_RISCV_V2.01工程(这里以V2.01版本为例),如图1所示. 图1 FII_RISCV_V2.01工程 要生成相应 ...
- obj文件格式解读
学习了很长一段时间的建模,obj文件一直都在使用,但是却很少去研究过,只是知道这是软件之间的通用格式,直到最近因为刚好要在python中加载obj文件,才发现原来obj文件是如此的有规律 随便用记事本 ...
- 第五章 散列表(哈希表)(hash表)
散列表 特点 键和值一一对应 可以快速找到对应值,不需要进行查找 运用场景 模拟映射关系 防止重复 缓存记住数据,以免服务器再通过处理来生成它们 例如: 电话簿 用缓存记录url和对应的静态页面,存在 ...
- yapi的一些基本操作
一.yapi能干什么 强大的接口管理平台 提供mock功能 提供测试功能 项目管理功能 插件齐全 二.yapi的权限 项目权限 操作 游客 项目开发者 项目组长 超级管理员 浏览公开项目与接口 √ √ ...
- .net Core5.0使用IdentityServer4 进行权限控制
.net Core5.0使用IdentityServer4 进行权限控制 IdentityServer4 ASP.NET Core的一个包含OpenID Connect和OAuth 2.0协议的框架 ...
- 5G如何加速无人快递?5G智能网关新应用
网上购物已经是现代生活的主流消费方式之一,伴随网购的繁荣,物流快递行业也进入到一个最火热的时期.而在这之中,有限的快递配送能力和日益增长的配送需求的矛盾持续凸显,因此无人快递车一类的创新应用也应运而生 ...
- 在linux下创建KVM虚拟机
Kernel-based Virtual Machine的简称,是一个开源的系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中.它使用Linux自身的调度器进行管理,所 ...
- mysqld_safe Directory '/tmp/mysql' for UNIX socket file don't exists.
报错版本:mysql-5.7.35 1.报错完整提示信息: [root@localhost bin]# 2022-11-15T04:04:43.122905Z mysqld_safe Logging ...