首页> 中国专利> 一种在JavaScript脚本语言中预生成机器码指令的方法和装置

一种在JavaScript脚本语言中预生成机器码指令的方法和装置

摘要

本发明实施例公开了一种在JavaScript脚本语言中预生成机器码指令的方法和装置,涉及动态语言编译领域,解决了提高机器码的生成速度这一问题。具体方案为:获取JavaScript脚本的中间代码,通过查询与所述中间代码对应的机器码指令的指令总长度,申请能容纳所述指令总长度的指令存储空间,将中间代码对应的机器码模板中的机器码指令复制到指令存储空间,根据中间代码,对与伪寄存器和立即数信息相关的机器码指令进行更改。本发明用于将中间代码生成机器码指令。

著录项

  • 公开/公告号CN103077011A

    专利类型发明专利

  • 公开/公告日2013-05-01

    原文格式PDF

  • 申请/专利权人 华为技术有限公司;

    申请/专利号CN201210379940.7

  • 发明设计人 张振龙;

    申请日2012-10-09

  • 分类号G06F9/44(20060101);

  • 代理机构11274 北京中博世达专利商标代理有限公司;

  • 代理人申健

  • 地址 518129 广东省深圳市龙岗区坂田华为总部办公楼

  • 入库时间 2024-02-19 18:33:18

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2019-09-24

    未缴年费专利权终止 IPC(主分类):G06F9/44 授权公告日:20151209 终止日期:20181009 申请日:20121009

    专利权的终止

  • 2015-12-09

    授权

    授权

  • 2013-06-05

    实质审查的生效 IPC(主分类):G06F9/44 申请日:20121009

    实质审查的生效

  • 2013-05-01

    公开

    公开

说明书

技术领域

本发明涉及动态语言编译领域,特别涉及一种在JavaScript脚本语言中预生成机器码指令的方法和装置。 

背景技术

JS(JavaScript)是一种可以嵌入Web页面中的基于对象和事件驱动的解释性的脚本语言。主要在Web浏览器上解释执行,可以使网页有动态的效果(如:图片、文字的滚动;层的动态切换,显示及隐藏;对HTML(HypertextMarkup Language,超文本标记语言)元素的操作);可以进行表单的输入验证(如:邮箱、电话、邮编的合法性,输入内容长度及内容验证等)。 

当Web浏览器进行JS引擎操作时,会从网上下载JavaScript脚本,然后根据脚本中的源程序进行解析生成语法树,根据语法树生成中间代码即字节码,根据中间代码生成机器码,最后运行机器码。中间代码到机器码生成的步骤包括: 

1申请128字节的连续内存空间,此内存空间称为buffer,用来存放机器代码。 

2解析中间代码,生成对应的机器码指令,其中每条中间代码可以生成多条机器码指令。 

3计算机器码指令的长度为code_length,确定buffer中是否有code_length的空间。 

4如果buffer中仍然有code_length的空间,将机器码指令保存到buffer中。 

5如果buffer中之前所申请的内存空间不足,将会重新进行申请buffer_length+buffer_length/2的内存空间,即192字节的内存空间。 

6将当前buffer的内容拷贝到新申请的buffer中。 

7回到上面第2步,继续进行下一条机器码指令的内存申请以及计算机器码指令长度的动作,并确定是否需要重新申请内存并且保存该机器代码。 

在实现上述根据中间代码生成机器码的过程中,发明人发现现有技术中存在两个缺陷:一方面,如果两条中间代码的指令类型相同,那么其生成的 机器码指令会出现对相同的机器码指令的重复生成动作,效率不高。另一方面,一条中间代码可能生成很多条机器码指令,这样当申请的内存空间不足时会导致进行若干次重新申请指令存储空间的动作,并且需要拷贝旧的指令存储空间的内容到新的指令存储空间,导致耗时较高。 

发明内容

本发明的实施例提供一种在JavaScript脚本语言中预生成机器码指令的方法和装置,以简化机器码指令的生成过程,提高机器码指令的生成效率,减少耗时。 

为达到上述目的,本发明的实施例采用如下技术方案: 

第一方面,提供了一种在JavaScript脚本语言中预生成机器码指令的方法,包括: 

获取JavaScript脚本的中间代码;所述中间代码通过对JavaScript脚本的源程序解析得到; 

从机器码模板中查询与所述中间代码对应的机器码指令的指令总长度,并申请能容纳所述机器码指令的指令存储空间;所述指令存储空间用于保存所述中间代码对应的机器码指令;所述机器码模板包含有所述机器码指令和所述机器码指令的指令总长度; 

将所述中间代码对应的机器码指令复制到所述指令存储空间; 

根据所述中间代码中的立即数和/或伪寄存器,对与伪寄存器和立即数信息相关的机器码指令进行修改;所述与伪寄存器和立即数信息相关的机器码指令,包含在复制到所述指令存储空间的、与所述中间代码对应的机器码指令中; 

继续执行上述将所述中间代码对应的机器码模板中的机器码指令复制到所述指令存储空间,以及更改与伪寄存器和立即数信息相关的机器码指令的动作,直至生成所有中间代码对应的机器码指令。 

在第一方面的第一种可能的实现方式中,所述机器码模板还包含:需要修改的机器码指令偏移地址,所述方法还包括: 

根据所述中间代码中的立即数和/或伪寄存器,以及所述当前中间代码对应的机器码模板中的需要修改的机器码指令偏移地址,更改与伪寄存器和立即数信息相关的机器码指令。 

在第一方面的第二种可能的实现方式中,所述根据所述中间代码中的立即数和/或伪寄存器,对与伪寄存器和立即数信息相关的机器码 指令进行修改,具体包括: 

获取所述中间代码的操作数以及目标寄存器;所述操作数包括伪寄存器或立即数,所述目标寄存器包括伪寄存器; 

将所述机器码指令中的伪寄存器修改为所述中间代码的伪寄存器;和/或 

将所述机器码指令中的立即数修改为所述中间代码的立即数。 

第二方面,本发明实施例提供了一种在JavaScript脚本语言中预生成机器码指令的装置,包括: 

获取模块,用于获取JavaScript脚本中的中间代码;所述中间代码通过对JavaScript脚本的源程序解析得到; 

申请模块,用于从机器码模板中查询与所述中间代码对应的机器码指令的指令总长度,申请能容纳所述机器码指令的指令存储空间;所述指令存储空间用于保存所述中间代码对应的机器码指令;所述机器码模板包含有所述机器码指令和所述机器码指令的指令总长度; 

指令复制模块,用于将所述中间代码对应的机器码指令复制到所述指令存储空间; 

指令更改模块,用于根据所述中间代码中的立即数和/或伪寄存器,对与伪寄存器和立即数信息相关的机器码指令进行修改;所述与伪寄存器和立即数信息相关的机器码指令,包含在复制到所述指令存储空间的、与所述中间代码对应的机器码指令中; 

所述指令复制模块还用于继续执行上述将所述中间代码对应的机器码模板中的机器码指令复制到所述指令存储空间,所述指令更改模块还用于在所述申请模块复制所述机器码指令后,继续更改与伪寄存器和立即数信息相关的机器码指令的动作,直至生成所有中间代码对应的机器码指令。 

本发明实施例提供的在JavaScript脚本语言中预生成机器码指令的方法和装置,根据中间代码对应的机器码模板中的机器码指令总长度,计算指令存储空间的长度,并申请所述长度的指令存储空间,然后将当前中间代码对应的机器码模板中的机器码指令复制到所述指令存储空间,对与伪寄存器和立即数信息相关的机器码指令进行更改,从而避免了现有技术中对相同机器码指令的重复生成动作,并且实现一次性分配内存空间,无需重复申请内存和复制机器码指令,提高了机器码指令的生成速度。 

附图说明

图1为本发明实施例提供的一种在JavaScript脚本语言中预生成机器码指令的方法的流程图; 

图2为本发明实施例提供的另一种在JavaScript脚本语言中预生成机器码指令的方法的流程图; 

图3为本发明实施例提供的一种在JavaScript脚本语言中预生成机器码指令的装置的框图; 

图4为本发明实施例提供的一种指令更改模块的框图; 

图5为本发明实施例提供的一种计算机系统的示意图; 

图6为本发明实施例提供的一种JavaScriptcore的模块框图。 

具体实施方式

下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。 

实施例1: 

本发明实施例提供了一种在JavaScript脚本语言中预生成机器码指令的方法,如图1所示,该方法包括: 

101、获取JavaScript脚本中的中间代码。 

在实际的应用场景中,当Web浏览器进行JS引擎操作时,会从网上下载JavaScript脚本,然后根据脚本中的源程序进行解析生成语法树,再根据语法树生成中间代码即字节码。 

102、从机器码模板中查询与所述中间代码对应的机器码指令的指令总长度,申请能容纳所述机器码指令的指令存储空间。 

所述指令存储空间用于保存中间代码对应的机器码指令。所述机器码模板是预先配置的并保存在计算机中的文件,在机器码模板中,包含了机器码指令和机器码指令的指令总长度。 

根据查询出来的指令存储空间的长度,从内存储器中申请与指令存储空间的长度相当的指令存储空间。 

103、将中间代码对应的机器码指令复制到所述指令存储空间。 

104、根据中间代码中的立即数和/或伪寄存器,对与伪寄存器和立即 数信息相关的机器码指令进行修改。 

所述与伪寄存器和立即数信息相关的机器码指令,包含在复制到所述指令存储空间的、与所述当前中间代码对应的机器码指令中。通过修改与伪寄存器和立即数信息相关的机器码指令,使得修改后的机器码指令符合中间代码的解析结果。 

在已经复制到指令存储空间的机器码指令中,可能会存在与伪寄存器和立即数信息相关的机器码指令,因此需要根据当前中间代码,对这些与伪寄存器和立即数信息相关的机器码指令进行更改。举例来说,中间代码Mov,对应的机器码模板中的机器码指令,具体为: 

002A0844 mov dword ptr[edi],0 

002A084A mov dword ptr[edi+4],0FFFFFFFCh 

上述中间代码Mov所对应的机器码模板中的两条机器码指令分别是与伪寄存器和立即数信息相关的机器码指令,因此两条机器码指令都需要更改。 

在执行完步骤104后,如果存在未生成机器码指令的中间代码,则继续执行步骤103和104,直至生成所有中间代码对应的机器码指令。举例来说,如果存在一系列中间代码,依次为: 

enter 

mov 

put_global_var 

put_global_var 

get_global_var 

get_global_var 

add 

put_global_var 

end 

那么,首先处理的是中间代码enter,将中间代码enter所对应的机器码模板中的机器码指令复制到指令存储空间,不妨假设与中间代码enter对应的复制到指令存储空间的机器码指令为code1;然后根据中间代码enter,对code1中的的与伪寄存器和立即数信息相关的机器码指令进行更 改。更改完成后,继续对中间代码mov执行机器码指令复制及更改的操作,直至生成所有中间代码对应的机器码指令。 

本发明实施例提供了一种在JavaScript脚本语言中预生成机器码指令的方法,根据中间代码对应的机器码模板中的机器码指令总长度,计算指令存储空间的长度,并申请所述长度的指令存储空间,然后将当前中间代码对应的机器码模板中的机器码指令复制到所述指令存储空间,对与伪寄存器和立即数信息相关的机器码指令进行更改,从而避免了现有技术中对相同机器码指令的重复生成动作,并且实现一次性分配内存空间,无需重复申请内存和复制机器码指令,提高了机器码指令的生成速度。 

实施例2: 

本发明实施例提供了一种在JavaScript脚本语言中预生成机器码指令的方法,如图2所示,该方法包括: 

201、获取JavaScript脚本中的中间代码。 

在实际的应用场景中,当Web浏览器进行JS引擎操作时,会从网上下载JavaScript脚本,然后根据脚本中的源程序进行解析生成语法树,再根据语法树生成中间代码即字节码。 

202、通过查询与所述中间代码对应的机器码指令的指令总长度,申请能容纳所述指令总长度的指令存储空间。 

所述指令存储空间用于保存中间代码对应的机器码指令。所述机器码模板是预先配置的并保存在计算机中的文件,在机器码模板中,包含了机器码指令和机器码指令的指令总长度,并且还包含了需要修改的机器码指令偏移地址。 

根据查询的指令存储空间的指令总长度,从内存储器中申请与指令存储空间的长度相当的指令存储空间。 

203、将中间代码对应的机器码模板中的机器码指令复制到所述指令存储空间。 

204、根据所述中间代码,以及所述中间代码对应的机器码模板中的需要修改的机器码指令偏移地址,修改与伪寄存器和立即数信息相关的机器码指令。 

具体的,步骤204中,对与伪寄存器和立即数信息相关的机器码指令进行修改,包括以下步骤: 

2041、获取所述中间代码的操作数以及目标寄存器。 

所述操作数包括伪寄存器或立即数,所述目标寄存器包括伪寄存器。 

2042、将所述机器码指令中的伪寄存器修改为所述中间代码的伪寄存器;和/或 

将所述机器码指令中的立即数修改为所述中间代码的立即数。 

下面对2041至2042进行详细说明。中间代码的构成格式为: 

指令类型,操作数,目标寄存器 

比如:mov ecx,eax 

其中的操作数可以是伪寄存器或立即数,目标寄存器可以是伪寄存器。在获取所述中间代码的操作数以及目标寄存器后,一方面将机器码指令中的伪寄存器修改为所述中间代码的伪寄存器;另一方面,将机器码指令中的立即数修改为所述中间代码的立即数。这样就完成了对机器码模板中的机器码指令的修改。 

在执行完步骤204后,如果存在未生成机器码指令的中间代码,则继续执行步骤203和204,直至生成所有中间代码对应的机器码指令。 

所述与伪寄存器和立即数信息相关的机器码指令,包含在复制到所述指令存储空间的、与中间代码对应的机器码指令中。 

其中,需要指出的是,在机器码模板中,还可以包含修改机器码指令的函数。那么,本发明实施例提供的在JavaScript脚本语言中预生成机器码指令的方法,在进行对与伪寄存器和立即数信息相关的机器码指令进行更改时的具体方式为:根据所述当前中间代码,以及所述当前中间代码对应的机器码模板中的修改机器码指令的函数,更改与伪寄存器和立即数信息相关的机器码指令。 

进一步的,在本发明实施例中,所述机器码模板可以预先保存在后缀名为.c的文件中。 

此外,需要说明的是,本发明实施例中的中间代码的指令类型包括:Enter指令、Add指令和End指令。举例来说,中间代码Add,所对应的机器码模板中的机器码指令,具体为: 

[01]00380A91 mov ecx,eax 

[02]00380A93 mov ebx,edx 

[03]00380A95 mov eax,dword ptr[edi+8] 

[04]00380A98 mov edx,dword ptr[edi+0Ch] 

[05]00380A9B cmp edx,0FFFFFFFFh 

[06]00380A9E jne 00380AC3 

[07]00380AA4 cmp ebx,0FFFFFFFFh 

[08]00380AA7 jne 00380AFE 

[09]00380AAD add eax,ecx 

[10]00380AAF jo 00380B2F 

…… 

[11]00380AF9 jmp 00380B18 

[12]00380AFE cvtsi2sd xmm0,eax 

[13]00380B02 cmp ebx,0FFFFFFF9h 

[14]00380B05 ja 00380B2F 

[15]00380B0B movsd xmm2,mmword ptr[edi+10h] 

[16]00380B10 addsd xmm0,xmm2 

[17]00380B14 movsd mmword ptr[edi],xmm0 

在上述中间代码Add所对应的机器码模板中的机器码指令中,根据所述当前中间代码,以及所述当前中间代码对应的机器码模板中的修改机器码指令的函数,更改与伪寄存器和立即数信息相关的机器码指令,即上述例子中机器码指令[03][04][10][14][15][17]。 

本发明实施例提供了一种在JavaScript脚本语言中预生成机器码指令的方法,在实际的应用场景中,当Web浏览器进行JS引擎操作时,会从网上下载JavaScript脚本,然后根据脚本中的源程序进行解析生成语法树,再根据语法树生成中间代码即字节码,获取中间代码。根据所述获取中间代码对应的机器码模板中的机器码指令总长度计算出指令存储空间的长度,根据所述计算出来的机器码指令的长度进行指令存储空间的申请,这样避免了重复申请指令存储空间的动作,将当前中间代码所对应的已经保存在机器码模板中的机器码指令复制到所述指令存储空间,更改与伪寄存器和立即数信息相关的机器码指令,这样避免了其余机器码指令的重复生成动作,从而提高了机器码的生成速度。 

实施例3: 

基于上述方法实施例,本发明实施例还提供一种在JavaScript脚本语言中预生成机器码指令的装置,如图3所示,包括: 

获取模块31,用于获取JavaScript脚本中的中间代码。 

在实际的应用场景中,当Web浏览器进行JS引擎操作时,会从网上下载JavaScript脚本,然后根据脚本中的源程序进行解析生成语法树,再根 据语法树生成中间代码即字节码,获取JavaScript脚本中的中间代码。 

申请模块32,用于从机器码模板中查询与所述中间代码对应的机器码指令的指令总长度,申请能容纳所述机器码指令的指令存储空间;所述指令存储空间用于保存所述中间代码对应的机器码指令;所述机器码模板包含有所述机器码指令和所述机器码指令的指令总长度;。 

指令复制模块33,用于将中间代码对应的机器码指令复制到所述指令存储空间。 

指令更改模块34,用于根据中间代码中的立即数和/或伪寄存器,对与伪寄存器和立即数信息相关的机器码指令进行修改,以便于修改后的机器码指令符合所述中间代码的解析结果。所述与伪寄存器和立即数信息相关的机器码指令,包含在复制到所述指令存储空间的、与所述当前中间代码对应的机器码指令中。 

其中所述指令复制模块33还用于继续执行上述将中间代码对应的机器码模板中的机器码指令复制到所述指令存储空间,所述指令更改模块34还用于在所述指令复制模块33复制所述机器码指令后,继续更改与伪寄存器和立即数信息相关的机器码指令的动作,直至生成所有中间代码对应的机器码指令。 

在机器码模板中,还可以包含需要修改的机器码指令偏移地址,以及修改机器码指令的函数。 

所述指令更改模块34具体用于根据所述当前中间代码,以及所述当前中间代码对应的机器码模板中的需要修改的机器码指令偏移地址,更改与伪寄存器和立即数信息相关的机器码指令。 

进一步的,如图4所示,所述指令更改模块34具体包括: 

操作数及目标寄存器获取单元341,用于获取所述中间代码的操作数以及目标寄存器。所述操作数包括伪寄存器或立即数,所述目标寄存器包括伪寄存器。 

修改单元342,用于将所述机器码指令中的伪寄存器修改为所述中间代码的伪寄存器。 

所述修改单元342还用于将所述机器码指令中的立即数修改为所述中间代码的立即数。 

在本发明实施例中,机器码模板可以预先保存在后缀名为.c的文件中。本发明实施例中的中间代码的指令类型包括ENTER指令,ADD指令和END 指令。 

需要说明的是,本发明实施例提供的预生成机器码指令的装置中各个模块的具体工作流程,可以参照上述方法实施例中的对应步骤,此处不再赘述。 

本发明实施例提供了一种在JavaScript脚本语言中预生成机器码指令的装置,申请模块根据获取模块所获取的中间代码对应的机器码模板中的机器码指令总长度计算出指令存储空间的长度并根据计算出来的机器码指令的长度进行指令存储空间的申请,这样避免了重复申请指令存储空间的动作,指令复制模块将当前中间代码所对应的已经保存在机器码模板中的机器码指令复制到所述指令存储空间,指令更改模块进行与伪寄存器和立即数信息相关的机器码指令的更改,这样避免了其余机器码指令的重复生成动作,从而提高了机器码的生成速度。 

实施例4: 

图5为本发明又一实施例提供的计算机系统的结构示意图。如图5所示,本实施例的设备包括:至少一个处理器602、存储器603和总线601。处理器602、存储器603通过总线601连接并完成相互间的通信。所述总线可以是工业标准体系结构(Industry Standard Architecture,简称为ISA)总线、外部设备互连(Peripheral Component,简称为PCI)总线或扩展工业标准体系结构(Extended Industry Standard Architecture,简称为EISA)总线等。所述总线可以分为地址总线、数据总线、控制总线等。为便于表示,图6中仅用一条粗线表示,但并不表示仅有一根总线或一种类型的总线;实际应用中,可以是一条总线串联的,还可以是集中式的多条线连接的,本发明实施例不作特别限定;其中: 

存储器603用于存储可执行程序代码,该程序代码包括计算机操作指令。存储器603可能包含高速RAM存储器,也可能还包括非易失性存储器(non-volatile memory),例如至少一个磁盘存储器。 

处理器602通过读取存储器603中存储的可执行程序代码来运行与所述可执行程序代码对应的程序,以用于: 

获取JavaScript脚本的中间代码,根据所述中间代码对应的机器码模板中的机器码指令总长度,计算指令存储空间的长度;所述指令存储空间用于保存中间代码对应的机器码指令;所述机器码模板中包含机器码指令和机器码指令总长度; 

向所述存储器603申请所述长度的指令存储空间,并将当前中间 代码对应的机器码模板中的机器码指令复制到所述指令存储空间; 

根据所述当前中间代码,对与伪寄存器和立即数信息相关的机器码指令进行更改;所述与伪寄存器和立即数信息相关的机器码指令,包含在复制到所述指令存储空间的、与所述当前中间代码对应的机器码指令中; 

继续执行上述将当前中间代码对应的机器码模板中的机器码指令复制到所述指令存储空间,以及更改与伪寄存器和立即数信息相关的机器码指令的动作,直至生成所有中间代码对应的机器码指令。 

处理器602可能是一个中央处理器(Central Processing Unit,简称为CPU),或者是特定集成电路(Application Specific Integrated Circuit,简称为ASIC),或者是被配置成实施本发明实施例的一个或多个集成电路。 

在开源的浏览器引擎webkit中,包括网页引擎(webcore)和脚本引擎(javascriptcore)。Javascriptcore的示意图如图6所示。 

在图6所示的javascriptcore中,包含runtime(运行环境),interpreter(解释器模式),parse(语法解析),bytecompiler(字节编译),JIT(机器码指令生成)以及runn(运行)。其中,处理器通过parse解析生成语法树,根据语法树,经由bytecompiler生成中间代码,即字节码(bytecode),然后再根据JIT,将中间代码解析生成机器码指令,即图6中的machinecode,最后运行机器码指令。 

本发明实施例提供了一种计算机系统,处理器根据获取的中间代码所对应的机器码模板中的机器码指令总长度计算出指令存储空间的长度,并根据计算出来的机器码指令的长度进行指令存储空间的申请,这样避免了重复申请指令存储空间的动作,将当前中间代码所对应的已经保存在机器码模板中的机器码指令复制到所述指令存储空间,并进行与伪寄存器和立即数信息相关的机器码指令的更改,这样避免了其余机器码指令的重复生成动作,从而提高了机器码的生成速度。 

本领域普通技术人员可以理解:实现上述方法实施例的全部或部分步骤可以通过程序指令相关的硬件来完成,也可以通过硬件逻辑的方式来实现,并且前述的程序可以存储于一计算机可读取存储介质中,该程序在执行时,执行包括上述方法实施例的步骤;而前述的存储介质包括:ROM、RAM、磁碟或者光盘等各种可以存储程序代码的介质。 

以上所述,仅为本发明的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应所述以权利要求的保护范围为准。 

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号