一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

将ST代码编译为WebAssembly代码的方法及装置与流程

2022-07-09 22:27:20 来源:中国专利 TAG:
将st代码编译为webassembly代码的方法及装置
技术领域
:1.本技术涉及工业控制
技术领域
:和计算机
技术领域
:,尤其涉及一种将st代码编译为webassembly代码的方法及装置。
背景技术
::2.plc(可编程逻辑控制器,programmablelogiccontroller)在工业控制领域具有广泛的应用,iec61131-3规范定义了5种标准的plc编程语言,包含顺序功能图(sfc)、梯形图(ld)、功能模块图(fbd)三种图形化语言和语句表(il)、结构化文本语言(st,structuredtext)两种文本语言。3.目前已有一些编译iec61131-3plc语言的方法。一些方法中将plc语言直接编译为控制器平台的机器指令,这种方式和控制器的硬件架构严格绑定,不利于在多种不同硬件架构的控制器上分发。另一些方法中将st语言编译成自定义的字节码格式,然后在控制器上实现这些字节码的解释器,从而摆脱对硬件架构的依赖。但是,自定义的字节码与编译器的实现具有紧密的耦合关系,一些现有的编程语言无法编译成自定义的字节码,因此难以复用其他语言的生态,从而限制了工程师的开发效率。技术实现要素:4.本技术实施例提供一种将st代码编译为webassembly代码的方法及装置,用以解决现有技术中存在的如何将st代码编译为webassembly代码的问题。5.本技术实施例提供一种将st代码编译为webassembly代码的方法,包括:6.按照st的词法及语法规则,对待编译的st代码进行词法及语法解析,得到所述st代码包括的各语法单元,以及所述各语法单元的代码类型,每个语法单元为一段代码片段;7.针对所述各语法单元包括的每个语法单元,当该语法单元的代码类型为预设的第一类指定类型时,按照该语法单元的代码类型对应的代码生成方式,生成与该语法单元具有相同代码逻辑的webassembly代码块;8.将得到的多个webassembly代码块,按照所述各语法单元之间的逻辑关系进行拼装,得到与所述st代码具有相同代码逻辑的webassembly代码。9.进一步的,在所述针对所述各语法单元包括的每个语法单元,当该语法单元的代码类型为预设的第一类指定类型时,按照该语法单元的代码类型对应的代码生成方式,生成与该语法单元具有相同代码逻辑的webassembly代码块之前,还包括:10.基于所述各语法单元生成表示所述st代码的语法树,所述语法树包括分别表示所述各语法单元的各节点,且所述各节点的节点类型为各自所表示的语法单元的代码类型;11.所述针对所述各语法单元包括的每个语法单元,当该语法单元的代码类型为预设的第一类指定类型时,按照该语法单元的代码类型对应的代码生成方式,生成与该语法单元具有相同代码逻辑的webassembly代码块,包括:12.针对所述语法树包括的表示语法单元的每个节点,当该节点的节点类型为预设的第一类指定类型时,按照该节点的节点类型对应的代码生成方式,生成与该节点表示的语法单元具有相同代码逻辑的webassembly代码块。13.进一步的,每个表示语法单元的节点具有子节点,包括:表示该语法单元的代码信息的子节点,和/或,表示该语法单元所包含的语法单元的子节点;14.所述针对所述语法树包括的表示语法单元的每个节点,当该节点的节点类型为预设的第一类指定类型时,按照该节点的节点类型对应的代码生成方式,生成与该节点表示的语法单元具有相同代码逻辑的webassembly代码块,包括:15.针对所述语法树包括的表示语法单元的每个节点,当该节点的节点类型为预设的第一类指定类型时,基于该节点的子节点的节点内容,按照该节点的节点类型对应的代码生成方式,生成与该节点表示的语法单元具有相同代码逻辑的webassembly代码块。16.进一步的,所述各语法单元至少包括如下类型的语法单元之一:17.类型定义单元、变量定义单元、程序组织单元pou、语句和表达式;18.表示类型定义单元的节点为类型定义节点;19.表示变量定义单元的节点为变量定义节点;20.表示pou的节点为pou定义节点;21.表示语句的节点为语句节点;22.表示表达式的节点为表达式节点;23.所述语法树中,类型定义节点、表示全局变量的变量定义节点和pou定义节点为根节点的子节点;24.pou定义节点的子节点包括:表示局部变量的变量定义节点、表示直接地址变量的变量定义节点、表示引用全局变量的变量定义节点和语句节点;25.语句节点的子节点包括:表达式节点;当该语句节点表示的语句还包括其他语句时,该语句节点的子节点还包括:表示其他语句的语句节点;26.当表达式节点表示的表达式还包括其他表达式时,表达式节点的子节点包括:表示其他表达式的表达式节点。27.进一步的,类型定义节点具有子节点,包括表示类型名称的子节点和表示类型描述的子节点;28.变量定义节点具有子节点,包括表示变量名称的子节点、表示变量数据类型的子节点和表示变量使用类型的子节点;29.pou定义节点具有子节点,还包括表示pou名称的子节点、表示pou的返回值类型的子节点。30.进一步的,第一类指定类型的语法单元包括:pou、语句和表达式;31.所述针对所述各语法单元包括的每个语法单元,当该语法单元的代码类型为预设的第一类指定类型时,按照该语法单元的代码类型对应的代码生成方式,生成与该语法单元具有相同代码逻辑的webassembly代码块,包括:32.针对所述各语法单元包括的每个语法单元,当该语法单元为pou时,生成与该pou具有相同代码逻辑的webassembly函数,且该webassembly函数包括:与该pou包括的语句具有相同代码逻辑的webassembly代码块;33.针对所述各语法单元包括的每个语法单元,当该语法单元为语句时,生成与该语句具有相同代码逻辑的webassembly代码块,且该webassembly代码块包括:与该语句包括的表达式具有相同代码逻辑的webassembly代码块,当该语句还包括其他语句时,还包括:与其他语句具有相同代码逻辑的webassembly代码块;34.针对所述各语法单元包括的每个语法单元,当该语法单元为表达式时,生成与该表达式具有相同代码逻辑的webassembly代码块,当该表达式还包括其他表达式时,该webassembly代码块包括:与其他表达式具有相同代码逻辑的webassembly代码块。35.进一步的,当该pou为函数时,生成的与该pou具有相同代码逻辑的webassembly函数的返回值,为该函数的返回值类型对应的webassembly中的类型;36.当该pou为程序或功能块时,生成的与该pou具有相同代码逻辑的webassembly函数,具有类型为指针的参数,且该参数是为该pou分配的内存空间的首地址。37.进一步的,还包括:38.当该pou为程序或功能块时,针对该程序或功能块生成初始化函数,用于初始化为该pou分配的内存空间。39.进一步的,第二类指定类型的语法单元包括:类型定义单元和变量定义单元;40.所述当该语法单元为语句时,生成与该语句具有相同代码逻辑的webassembly代码块,包括:41.当该语法单元为语句时,获取该语句包括的变量定义单元中的变量的名称信息,如果需要获取该变量的类型信息,从类型定义单元中获取该变量的类型信息;42.基于该语句包括的变量定义单元中的该变量的名称信息和类型信息,生成与该语句具有相同代码逻辑的webassembly代码块。43.本技术实施例还提供一种将st代码编译为webassembly代码的装置,包括:44.代码解析模块,用于按照st的词法及语法规则,对待编译的st代码进行词法及语法解析,得到所述st代码包括的各语法单元,以及所述各语法单元的代码类型,每个语法单元为一段代码片段;45.代码生成模块,用于针对所述各语法单元包括的每个语法单元,当该语法单元的代码类型为预设的第一类指定类型时,按照该语法单元的代码类型对应的代码生成方式,生成与该语法单元具有相同代码逻辑的webassembly代码块;46.代码拼装模块,用于将得到的多个webassembly代码块,按照所述各语法单元之间的逻辑关系进行拼装,得到与所述st代码具有相同代码逻辑的webassembly代码。47.本技术实施例还提供一种电子设备,包括处理器和机器可读存储介质,所述机器可读存储介质存储有能够被所述处理器执行的机器可执行指令,所述处理器被所述机器可执行指令促使:实现上述任一将st代码编译为webassembly代码的方法。48.本技术实施例还提供一种计算机可读存储介质,所述计算机可读存储介质内存储有计算机程序,所述计算机程序被处理器执行时实现上述任一将st代码编译为webassembly代码的方法。49.本技术实施例还提供了一种包含指令的计算机程序产品,当其在计算机上运行时,使得计算机执行上述任一将st代码编译为webassembly代码的方法。50.本技术有益效果包括:51.本技术实施例提供的方法中,按照st的词法及语法规则,对待编译的st代码进行词法及语法解析,得到该st代码包括的各语法单元,以及各语法单元的代码类型,每个语法单元为一段代码片段;针对各语法单元包括的每个语法单元,当该语法单元的代码类型为预设的第一类指定类型时,按照该语法单元的代码类型对应的代码生成方式,生成与该语法单元具有相同代码逻辑的webassembly代码块;将得到的多个webassembly代码块,按照各语法单元之间的逻辑关系进行拼装,得到与该st代码具有相同代码逻辑的webassembly代码。采用该方案,通过将st代码拆分成各语法单元,并针对语法单元的每种代码类型预设对应的代码生成方式,从而实现了将st代码编译为webassembly代码。52.本技术的其它特征和优点将在随后的说明书中阐述,并且,部分地从说明书中变得显而易见,或者通过实施本技术而了解。本技术的目的和其他优点可通过在所写的说明书、权利要求书、以及附图中所特别指出的结构来实现和获得。附图说明53.附图用来提供对本技术的进一步理解,并且构成说明书的一部分,与本技术实施例一起用于解释本技术,并不构成对本技术的限制。在附图中:54.图1为本技术实施例提供的将st代码编译为webassembly代码的方法的流程图;55.图2为本技术另一实施例提供的将st代码编译为webassembly代码的方法的流程图;56.图3为本技术实施例中语法树的结构示意图;57.图4为本技术实施例中针对程序和功能块生成webassembly代码块的示意图;58.图5-1为本技术实施例提供的将st代码编译为webassembly代码的装置的结构示意图;59.图5-2为本技术另一实施例提供的将st代码编译为webassembly代码的装置的结构示意图;60.图6为本技术实施例提供的电子设备的结构示意图。具体实施方式61.为了给出将st代码编译为webassembly代码的实现方案,本技术实施例提供了一种将st代码编译为webassembly代码的方法及装置,以下结合说明书附图对本技术的优选实施例进行说明,应当理解,此处所描述的优选实施例仅用于说明和解释本技术,并不用于限定本技术。并且在不冲突的情况下,本技术中的实施例及实施例中的特征可以相互组合。62.本技术实施例提供一种将st代码编译为webassembly代码的方法,如图1所示,包括:63.步骤11、按照st的词法及语法规则,对待编译的st代码进行词法及语法解析,得到该st代码包括的各语法单元,以及各语法单元的代码类型,每个语法单元为一段代码片段;64.步骤12、针对各语法单元包括的每个语法单元,当该语法单元的代码类型为预设的第一类指定类型时,按照该语法单元的代码类型对应的代码生成方式,生成与该语法单元具有相同代码逻辑的webassembly代码块;65.步骤13、将得到的多个webassembly代码块,按照各语法单元之间的逻辑关系进行拼装,得到与该st代码具有相同代码逻辑的webassembly代码。66.采用上述方法,通过将st代码拆分成各语法单元,并针对语法单元的每种代码类型预设对应的代码生成方式,从而实现了将st代码编译为webassembly代码。67.webassembly是一个可移植、体积小、加载快、安全的字节码规范,其可以作为多种高级语言的编译目标,从而复用大量的语言生态。将st代码的plc程序代码编译为webassembly代码后,使得plc可以利用webassembly高效、轻量、安全的特性以及其丰富的语言生态。68.下面结合附图,用具体实施例对本技术提供的方法及装置进行详细描述。69.本技术实施例提供一种将st代码编译为webassembly代码的方法,如图2所示,包括:70.步骤21、按照st的词法及语法规则,对待编译的st代码进行词法及语法解析,得到该st代码包括的各语法单元,以及各语法单元的代码类型,每个语法单元为一段代码片段。71.本技术实施例中,st的词法和语法规则,可以基于st的规范设置。72.本技术实施例中,各语法单元至少包括如下类型的语法单元之一:73.类型定义单元、变量定义单元、pou(程序组织单元)、语句和表达式;74.类型定义单元为st代码中用于定义类型的代码片段,可以包含类型名称和类型描述。75.变量定义单元为st代码中用于定义变量的代码片段,可以包含变量名称、变量数据类型和变量使用类型;其中,变量数据类型是一个字符串,表示该变量所属的数据类型的名称,变量使用类型也可以称作“关键字”,可以是“var_input”、“var_in_out”、“var_output”、“var”、“var_temp”、“var_gloabl”和“var_external”中的一个,用于修饰变量的属性及作用域;对于直接地址变量(io变量)而言,除了上述变量名称和变量数据类型外,还可以包含变量地址。76.pou作为一段代码片段,其可以是程序(program)、功能块(functionblock)、函数(function)之一,内容可以包含pou名称、类型,如果pou为函数,还可以包含返回值类型,此外,pou还可以包含一系列的变量定义单元和语句。77.语句为st代码中用于描述具体代码逻辑(也可以称作程序逻辑)的代码片段,st语法中可以包括多种语句,例如,赋值语句、if-else语句、循环语句和swith语句等。语句的内容可以包含表达式,也可以包含其他语句。78.表达式作为一段代码片段,其往往作为语句的一部分,并且,表达式的内容也可以包含其他表达式,st语法中可以包括多种表达式,例如,算术表达式、逻辑表达式、调用表达式、常量表达式和变量表达式,其中,算术表达式和逻辑表达式一般包含一个或多个操作数和操作码,操作数可以是常量表达式、变量表达式和其他类型表达式。79.步骤22、基于各语法单元生成表示该st代码的语法树,该语法树包括分别表示各语法单元的各节点,且各节点的节点类型为各自所表示的语法单元的代码类型。80.如图3所示,语法树包括根节点,作为整个语法树的根,其他所有节点都是这个根节点的子节点或孙节点。一个语法树只有一个根节点。81.进一步的,每个表示语法单元的节点还可以具有子节点,其子节点可以包括:表示该语法单元的代码信息的子节点,和/或,表示该语法单元所包含的语法单元的子节点,例如,pou包含语句,语句包含表达式,那么,表示pou的节点可以具有表示该pou包含的语句的子节点,表示语句的节点可以具有表示该语句包含的表达式的子节点。82.如图3所示,针对类型定义单元,表示类型定义单元的节点为类型定义节点;进一步的,类型定义节点还可以具有子节点,其子节点可以包括表示类型名称的子节点和表示类型描述的子节点;类型定义节点为根节点的子节点;83.针对变量定义单元,表示变量定义单元的节点为变量定义节点;进一步的,变量定义节点还可以具有子节点,其子节点可以包括表示变量名称的子节点、表示变量数据类型的子节点和表示变量使用类型的子节点;对于全局变量而言,表示全局变量的变量定义节点为根节点的子节点;84.针对pou,表示pou的节点为pou定义节点;pou定义节点为根节点的子节点;进一步的,pou定义节点可以具有子节点,其子节点可以包括表示pou名称的子节点,当pou为函数时,表示该函数的返回值类型的子节点。85.针对语句,表示语句的节点为语句节点;86.针对表达式,表示表达式的节点为表达式节点;87.pou定义节点的子节点可以包括:表示局部变量的变量定义节点、表示直接地址变量的变量定义节点、表示引用全局变量的变量定义节点和语句节点;进一步的,pou定义节点具有子节点,还可以包括表示pou名称的子节点、表示pou的返回值类型的子节点;88.语句节点的子节点可以包括:表达式节点;当该语句节点表示的语句还包括其他语句时,该语句节点的子节点还包括:表示其他语句的语句节点;89.当表达式节点表示的表达式还包括其他表达式时,表达式节点的子节点可以包括:表示其他表达式的表达式节点。90.步骤23、针对语法树包括的表示语法单元的每个节点,当该节点的节点类型为预设的第一类指定类型时,按照该节点的节点类型对应的代码生成方式,生成与该节点表示的语法单元具有相同代码逻辑的webassembly代码块。91.进一步的,当该节点具有子节点时,可以基于该节点的子节点的节点内容,按照该节点的节点类型对应的代码生成方式,生成与该节点表示的语法单元具有相同代码逻辑的webassembly代码块。92.本技术实施例中,预设的第一类指定类型的语法单元,可以包括:pou、语句和表达式,即具有一定代码逻辑的语法单元,并在编译过程中,将生成对应的具有相同代码逻辑的webassembly代码块;93.预设的第二类指定类型的语法单元,可以包括:类型定义单元和变量定义单元,在编译过程中,不会直接生成对应的具有相同代码逻辑的webassembly代码块,但是将获取类型定义单元和变量定义单元的信息,用于针对第一类指定类型的语法单元,生成对应的具有相同代码逻辑的webassembly代码块。94.本技术实施例中,可以从根节点开始,遍历上述语法树包含的各节点,并基于每个节点表示的语法单元的类型,进行相应的处理,包括编译和获取语法单元的信息等。95.针对每种语法单元,详细描述如下:96.针对pou定义节点表示的pou:97.当该语法单元为pou时,生成与该pou具有相同代码逻辑的webassembly函数,且该webassembly函数包括:与该pou包括的语句具有相同代码逻辑的webassembly代码块;98.更具体的,当该pou为函数时,生成的与该pou具有相同代码逻辑的webassembly函数的返回值,为该函数的返回值类型对应的webassembly中的类型。99.并且,与该pou具有相同代码逻辑的webassembly函数中的参数和局部变量,可以通过遍历表示该函数的pou定义节点的子节点中的变量定义节点确定,即针对表示该函数的pou定义节点的子节点中的每个变量定义节点,基于该变量定义节点的变量使用类型(也可以称作关键字)确定,具体可以如下:100.当变量使用类型为“var_input”:该变量将作为将要生成的webassembly函数中的一个参数,若该变量的类型是基本类型,则该参数的类型为该基本类型对应的webassembly中的类型;若该变量的类型是非基本类型,则该参数的类型为指针类型;101.当变量使用类型为“var_in_out”或”var_output”:该变量将作为将要生成的webassembly函数的一个参数,该参数的类型为指针类型;102.当变量使用类型为“var”或”var_temp”:该变量不作为将要生成的webassembly函数的参数。若该变量的类型为基本类型,则生成该webassembly函数中对应类型的局部内存(local),并分配一个local的索引。若该变量的类型为非基本类型,则在将要生成的webassembly函数开始的地方插入“用于预留辅助栈空间”的字节码指令,该预留空间的大小为该非基本类型所需占用的空间大小;103.当变量使用类型为“var_external”:该变量表示在该函数中引用一个全局变量,既不作为参数也不作为局部变量,因此在将要生成的webassembly函数时忽略该变量定义节点。104.当该pou为程序或功能块时,生成的与该pou具有相同代码逻辑的webassembly函数,具有类型为指针的参数,且该参数是为该pou分配的内存空间的首地址。105.进一步的,当该pou为程序或功能块时,还可以针对该程序或功能块生成初始化函数,用于初始化为该pou分配的内存空间,相应的,生成的与该pou具有相同代码逻辑的webassembly函数也可以称作入口函数。106.在生成的与该pou具有相同代码逻辑的webassembly函数的过程中,还可以针对表示该程序或功能块的pou定义节点的子节点中的每个变量定义节点,基于该变量定义节点的变量使用类型(也可以称作关键字)执行如下操作:107.当变量使用类型为“var_temp”:若该变量的类型为基本类型,则生成该webassembly函数中对应类型的局部内存(local),并分配一个local的索引。若该变量的类型为非基本类型,则在将要生成的webassembly函数开始的地方插入“用于预留辅助栈空间”的字节码指令,该预留空间的大小为该非基本类型所需占用的空间大小;108.当变量使用类型为“var_external”:该变量表示在程序或功能块中引用一个全局变量,既不作为参数也不作为局部变量,因此在将要生成的webassembly函数时忽略该变量定义节点。109.当变量使用类型为其他类型:所有其他使用类型的变量定义节点用于计算该程序或功能块的实例所占用的内存空间的大小,因此在生成该pou对应的webassembly函数时忽略该变量定义节点。110.无论pou是函数、程序或功能块,除按照上述处理方式确定将要生成的webassembly函数中的参数和变量之外,还将遍历该pou定义节点所包含的所有语句子节点,并生成对应的webassembly代码块。111.针对语句节点表示的语句:112.当该语法单元为语句时,生成与该语句具有相同代码逻辑的webassembly代码块,且该webassembly代码块包括:与该语句包括的表达式具有相同代码逻辑的webassembly代码块,当该语句还包括其他语句时,还包括:与其他语句具有相同代码逻辑的webassembly代码块;113.进一步的,由于语句中可能包含各种数据类型的各种变量,所以,当该语法单元为语句时,具体可以获取该语句包括的变量定义单元中的变量的名称信息,如果需要获取该变量的类型信息,从类型定义单元中获取该变量的类型信息;并基于该语句包括的变量定义单元中的该变量的名称信息和类型信息,生成与该语句具有相同代码逻辑的webassembly代码块。114.本技术实施例中,具体可以从变量定义节点及其子节点,获取变量的变量名称、变量数据类型和变量使用类型,从类型定义节点及其子节点,获取st代码中定义的类型名称和类型描述信息,用于针对第一类指定类型的语法单元生成webassembly代码块。115.针对表达式节点表示的表达式:116.当该语法单元为表达式时,生成与该表达式具有相同代码逻辑的webassembly代码块,当该表达式还包括其他表达式时,该webassembly代码块包括:与其他表达式具有相同代码逻辑的webassembly代码块。117.步骤24、生成接口函数。118.本技术实施例中,st代码为plc程序代码时,还可以生成用于plc运行的接口函数,接口函数也是webassembly代码块。119.本步骤中生成接口函数为可选的,如下三种接口函数,也是可选的生成如下至少一种。120.具体的,本步骤中,可以生成如下接口函数:121.用于初始化所有作为程序的语法单元的接口函数;如果上述步骤23中,针对类型为程序的pou,已经生成了初始化函数,则可以直接将生成的接口函数与该初始化函数进行关联;122.具体的,可以生成一个webassembly函数,其名称是固定的,用于依次完成对各程序的初始化工作。若初始化函数使用动态内存分配,则使用一个数组来记录每个程序内存空间的首地址。123.用于获取为程序分配的内存空间的程序地址的接口函数;124.具体的,可以生成一个webassembly函数,其名称是固定的,该接口函数可以根据入口参数返回一个或多个程序的内存空间首地址。125.用于初始化为直接地址变量分配的io区域的接口函数;126.具体的,可以生成一个webassembly函数,其名称是固定的,用于完成对io区域大小以及初始化值的设定。127.步骤25、将得到的多个webassembly代码块,以及生成的各接口函数,按照各语法单元之间的逻辑关系进行拼装,得到与待编译的该st代码具有相同代码逻辑的webassembly代码。128.本步骤中,所得到的webassembly代码,可以是webassembly字节码,也可以是webassembly文本程序。129.采用上述图2所示的编译方法,将st代码拆分成各语法单元,并生成包含表示各语法单元的节点的语法树,通过遍历语法树中各节点,并基于针对语法单元的每种代码类型预设对应的代码生成方式,实现将st代码编译为webassembly代码。通过遍历语法树中的节点进行编译,可以更快速、有效的确定语法单元之间的逻辑关系,提高编译的效率。130.实施例1:131.本实施例1中,针对类型为函数的pou生成webassembly代码块进行详细描述。132.st中规定的函数的语法如下所示:[0133][0134]编译过程如下:[0135]第一步:在webassembly的类型section中创建对应的函数类型[0136]st函数每一个入口参数在创建的webassembly函数类型定义中有一个对应的参数。如果st中的参数类型是其他基本类型,将会生成其对应的webassembly类型,其对应关系如下表1所示:[0137][0138]表1[0139]若st函数中的参数类型是非基本类型,则其在webassembly函数中对应的类型始终为i32(在webassembly中指针类型即为i32类型),其存储的是该变量的在线性空间中地址而非值。[0140]st函数的返回值类型按照上表1在创建的webassembly函数类型有对应的返回类型。[0141]针对上述st的函数示例,对应的webassembly函数类型定义如下:[0142](func$test(type1)(parami32)(resulti32))[0143]第二步:创建webassembly函数定义,该webassembly函数引用上面函数类型。执行结果为在webassembly函数表中创建一个对应的函数记录。[0144]第三步:如果st的函数的局部变量包含非基本数据类型,在webassembly函数内部入口生成webassembly代码片段,用于更新线性内存中辅助栈栈顶位置。本函数在辅助栈上预留空间大小{stack_size}的实际值,由编译器根据本函数所定义的所有局部变量计算而来。生成的对应的webassembly代码块如下例所示:[0145]global.get$head[0146]i32.const{stack_size}[0147]i32.sub[0148]local.tee1[0149]global.set$head[0150]webassembly中使用一个global$head用于存储辅助栈当前的栈顶指针,上述指令序列通过global.get获取当前栈顶指针,将它减去一定大小(局部变量的大小)再通过global.set更新栈顶指针,这样便实现了在辅助栈上为所述非基本类型的局部变量预留空间。[0151]实施例2:[0152]本实施例2中,针对类型为程序或功能块的pou生成webassembly代码块进行详细描述。[0153]针对每个程序/功能块,都会对应在webassembly中生成一个“入口函数”,包含程序/功能块的具体逻辑;同时,可选择地生成一个“初始化函数”包含初始化逻辑。[0154]生成的初始化函数至少包含一个指针类型的参数,其值是该程序或功能块实例在内存中的空间的首地址。[0155]生成的入口函数至少包含一个指针类型的参数,记作“parameter_self”,其值是该程序或功能块实例在内存中的空间的首地址。如图4所示。[0156]例如,st中的程序代码如下:[0157][0158]对应生成的webassembly代码块如下:[0159][0160]对于生成的webassembly入口函数,除了函数类型按照本实施例2特定描述,其它具体生成webassembly代码块的方法和实施例1中定义的处理方式基本一致。[0161]实施例3:[0162]本实施例3中,针对表达式生成webassembly代码块进行详细描述。[0163]针对所有表达式生成的webassembly代码块,都会在执行后将计算结果存放于webassembly操作栈的顶端。下面针对不同类型的表达式描述如下:[0164]常量表达式:[0165]生成webassembly中的i32.const/i64.const/f32.const/f64.const(取决于该常量的类型)操作码,对常量数值编码,生成webassembly立即数。[0166]变量表达式:[0167]根据st代码的变量名称,遍历该变量表达式在所属的pou定义节点下的所有变量定义节点,找到该变量对应的变量定义节点,从而获取变量的信息。[0168]根据不同变量类型,处理方式分别如下:[0169]针对局部变量:[0170]根据实施例1和实施例2,若该变量被生成为webassembly函数中的局部变量:(即pou为函数且变量使用类型为var或var_temp,或pou为程序或功能块且变量使用类型为var_temp),按照如下方法生成webassembly代码块:[0171]若该变量为基本类型(生成为local并分配local索引),则生成webassembly中的“get_local”指令,该指令的操作数为上述为该变量分配的local索引,该指令的作用是获取该变量的值。[0172]若该变量为非基本类型,则使用在辅助栈上预留空间,按照下述方式生成一段字节码指令用于访问变量:[0173]获取该变量在辅助栈上的地址,生成一段指令,包含:通过get_global指令获取辅助栈栈顶指针,通过i32.add指令获取栈顶指针加上该变量在辅助栈中的偏移量。[0174]在上述“用于获取地址”的指令后面,接着生成一系列iload指令,这些指令的作用是获取该变量的值(“iload指令”代指i32.load/i64.load/f32.load/f64.load等各种类型的load指令,具体使用的指令取决于该变量的类型)[0175]针对全局变量(即变量使用类型为var_external):[0176]全局变量在内存中的地址是一个分配好的固定值,因此直接生成iload指令获取该变量的值。[0177]针对io变量:[0178]首先插入get_global指令,该指令的作用是获取io区域的首地址,随后插入i32.add指令,该指令的作用是计算io区域首地址加上该io变量的偏移量后的地址,随后插入iload指令,该指令的作用是获取该变量的值。[0179]针对函数的参数:[0180]若变量使用类型为var_input且变量类型为基本类型,则根据实施例1,其在webassembly函数中是一个对应类型的参数。webassembly中的参数也是一个local,也有一个分配好的local索引,因此该变量与上述基本类型的局部变量处理方式一致。[0181]若变量使用类型为var_input且变量类型为非基本类型;或者变量使用类型为var_in_out或var_output,则生成一个get_local指令获取该变量对应的webassembly函数中参数的值,该指令的操作数是上述分配好的local索引,这个参数的值则是该变量在辅助栈上的地址,接着生成一系列iload指令,这些指令的作用是获取该变量的值。[0182]针对程序或功能块的成员变量:[0183]第一步:生成一个get_local指令,使用实施例2中标记为parameter_self的参数作为该指令的立即数。[0184]根据实施例1,程序或功能块对应的webassembly中的函数包含一个指针类型的参数,上述get_local指令即为获取该参数的值,该值表示当前pou的实例在内存中占用空间的首地址。[0185]第二步:生成一个i32.const指令,以当前变量在当前pou中的偏移量作为该指令的立即数。[0186]第三步:生成webassembly的i32.add指令,该指令的执行结果是该变量在线性内存中的地址。[0187]第四步:生成iload指令,用于获取变量的值。[0188]算术表达式和逻辑表达式:[0189]一般包含一个或者多个操作数和一个操作码。使用以下步骤转换成对应的webassembly代码块:[0190]第一步:逐个为表达式中所有的操作数生成对应的webassembly指令,具体方法如下(在执行后将st操作数内容上存放至webassembly的操作栈最顶部):[0191]如果操作数为常量或者变量类型表示式,使用本实施例中对应方法生成对应的webassembly代码块[0192]其他类型的表达式则嵌套调用本实施例中定义的步骤,直到最后的操作数为变量或者常量类型表达式。[0193]第二步:生成st运算操作对应的webassembly操作码,使用下表2所示的映射关系生成对应的webassembly操作码,其在执行后结果将存放于webassembly操作栈的顶部。[0194][0195]表2[0196]函数调用表达式:[0197]函数调用表达式包含一个函数名称和若干表达式作为参数。按照以下步骤生成对应的webassembly代码块:[0198]第一步:依次处理每个函数调用的参数,按照其表达式类型生成对应的webassembly代码块;[0199]第二步:生成webassembly中的call指令,其立即数为被调用函数在函数表中的索引号。(参考实施例1)[0200]实施例4:[0201]本实施例4中,针对语句生成webassembly代码块进行详细描述。[0202]根据语句类型生成对应的webassembly代码块,具体如下:[0203]针对赋值语句:[0204]第一步:生成赋值操作符右侧表达式对应的webassembly代码块:具体方法采用实施例3所描述的方式,确保其操作结果存放于webassembly操作栈顶端。[0205]第二步:确定赋值符号左侧st变量对应的webassembly内存类型[0206]第三步:根据上一步确定的内存类型,生成对应的变量赋值webassembly操作码。[0207]内存类型为local:生成set_local指令,使用为该变量所分配的local索引作为立即数。[0208]内存类型为辅助栈:生成获取该变量地址的字节码指令(该步骤与“算术表达式和逻辑表达式”中获取变量地址的步骤一致);[0209]生成istore指令(“istore指令”代指i32.store/i64.store/f32.store/f64.store等各种类型的store指令,具体使用的指令取决于该变量的类型)[0210]针对if-else语句:[0211]st语法中对if-else语句的定义如下:[0212][0213]对于没有else分支的语句,使用以下方法生成对应的webassembly字节码:[0214]第一步:创建一个webassembly中的block;[0215]第二步:在block开始的位置生成“条件判断表达式”对应的代码块;[0216]第三步:随后插入一条br_if代码块;[0217]第四步:为if内的每个语句生成对应的webassembly代码块;[0218]第五步:插入一个end字节码表示这个block的结束。[0219]输出的webassembly代码块如下所示:[0220][0221][0222]本技术实施例中,针对语句生成webassembly代码块,可以循环调用本实施例中的每种语句类型的处理方法,直到不存在对其他语句的依赖。[0223]针对switch语句:[0224]st语法中对switch语句的定义如下:[0225][0226]生成对应的webassembly代码块的过程如下:[0227]第一步:生成一个webassembly中的block;[0228]第二步:为每一个case分支和else分支各生成一个webassembly中的block这些block是嵌套的;[0229]第三步:在最内层的block中生成br_table字节码;(跳转到各个case所对应的block中执行相应的逻辑)[0230]第四步:每个case对应的block中,生成该case分支逻辑对应的代码块,然后生成一个br指令跳转到上述最外层block的结束处。[0231]输出的webassembly代码块如下所示:[0232][0233]针对循环语句:[0234]st语法中对循环语句的定义如下:[0235]forx:=0to100byydo[0236]loop:=loop x;[0237]end_for[0238]生成对应的webassembly代码块的过程如下:[0239]第一步:创建一个webassembly中的loop块;[0240]第二步:生成循环条件判断表达式对应的代码块;[0241]第三步:生成一个br_if代码块;[0242]第四步:生成循环内部的逻辑对应的代码块;[0243]第五步:生成一条br代码块,其作用是跳转到loop块的开头。[0244]其对应生成如下webassembly代码块:[0245][0246]基于同一发明构思,根据本技术上述实施例提供的将st代码编译为webassembly代码的方法,相应地,本技术另一实施例还提供了一种将st代码编译为webassembly代码的装置,其结构示意图如图5-1所示,具体包括:[0247]代码解析模块51,用于按照st的词法及语法规则,对待编译的st代码进行词法及语法解析,得到所述st代码包括的各语法单元,以及所述各语法单元的代码类型,每个语法单元为一段代码片段;[0248]代码生成模块52,用于针对所述各语法单元包括的每个语法单元,当该语法单元的代码类型为预设的第一类指定类型时,按照该语法单元的代码类型对应的代码生成方式,生成与该语法单元具有相同代码逻辑的webassembly代码块;[0249]代码拼装模块53,用于将得到的多个webassembly代码块,按照所述各语法单元之间的逻辑关系进行拼装,得到与所述st代码具有相同代码逻辑的webassembly代码。[0250]进一步的,如图5-2,还包括:[0251]语法树生成模块54,用于基于所述各语法单元生成表示所述st代码的语法树,所述语法树包括分别表示所述各语法单元的各节点,且所述各节点的节点类型为各自所表示的语法单元的代码类型;[0252]所述代码生成模块52,具体用于针对所述语法树包括的表示语法单元的每个节点,当该节点的节点类型为预设的第一类指定类型时,按照该节点的节点类型对应的代码生成方式,生成与该节点表示的语法单元具有相同代码逻辑的webassembly代码块。[0253]进一步的,每个表示语法单元的节点具有子节点,包括:表示该语法单元的代码信息的子节点,和/或,表示该语法单元所包含的语法单元的子节点;[0254]所述代码生成模块52,具体用于针对所述语法树包括的表示语法单元的每个节点,当该节点的节点类型为预设的第一类指定类型时,基于该节点的子节点的节点内容,按照该节点的节点类型对应的代码生成方式,生成与该节点表示的语法单元具有相同代码逻辑的webassembly代码块。[0255]进一步的,所述各语法单元至少包括如下类型的语法单元之一:[0256]类型定义单元、变量定义单元、程序组织单元pou、语句和表达式;[0257]表示类型定义单元的节点为类型定义节点;[0258]表示变量定义单元的节点为变量定义节点;[0259]表示pou的节点为pou定义节点;[0260]表示语句的节点为语句节点;[0261]表示表达式的节点为表达式节点;[0262]所述语法树中,类型定义节点、表示全局变量的变量定义节点和pou定义节点为根节点的子节点;[0263]pou定义节点的子节点包括:表示局部变量的变量定义节点、表示直接地址变量的变量定义节点、表示引用全局变量的变量定义节点和语句节点;[0264]语句节点的子节点包括:表达式节点;当该语句节点表示的语句还包括其他语句时,该语句节点的子节点还包括:表示其他语句的语句节点;[0265]当表达式节点表示的表达式还包括其他表达式时,表达式节点的子节点包括:表示其他表达式的表达式节点。[0266]进一步的,类型定义节点具有子节点,包括表示类型名称的子节点和表示类型描述的子节点;[0267]变量定义节点具有子节点,包括表示变量名称的子节点、表示变量数据类型的子节点和表示变量使用类型的子节点;[0268]pou定义节点具有子节点,还包括表示pou名称的子节点、表示pou的返回值类型的子节点。[0269]进一步的,第一类指定类型的语法单元包括:pou、语句和表达式;[0270]所述代码生成模块52,具体用于针对所述各语法单元包括的每个语法单元,当该语法单元为pou时,生成与该pou具有相同代码逻辑的webassembly函数,且该webassembly函数包括:与该pou包括的语句具有相同代码逻辑的webassembly代码块;[0271]针对所述各语法单元包括的每个语法单元,当该语法单元为语句时,生成与该语句具有相同代码逻辑的webassembly代码块,且该webassembly代码块包括:与该语句包括的表达式具有相同代码逻辑的webassembly代码块,当该语句还包括其他语句时,还包括:与其他语句具有相同代码逻辑的webassembly代码块;[0272]针对所述各语法单元包括的每个语法单元,当该语法单元为表达式时,生成与该表达式具有相同代码逻辑的webassembly代码块,当该表达式还包括其他表达式时,该webassembly代码块包括:与其他表达式具有相同代码逻辑的webassembly代码块。[0273]进一步的,当该pou为函数时,生成的与该pou具有相同代码逻辑的webassembly函数的返回值,为该函数的返回值类型对应的webassembly中的类型;[0274]当该pou为程序或功能块时,生成的与该pou具有相同代码逻辑的webassembly函数,具有类型为指针的参数,且该参数是为该pou分配的内存空间的首地址。[0275]进一步的,所述代码生成模块52,还用于当该pou为程序或功能块时,针对该程序或功能块生成初始化函数,用于初始化为该pou分配的内存空间。[0276]进一步的,第二类指定类型的语法单元包括:类型定义单元和变量定义单元;[0277]所述代码生成模块52,具体用于当该语法单元为语句时,获取该语句包括的变量定义单元中的变量的名称信息,如果需要获取该变量的类型信息,从类型定义单元中获取该变量的类型信息;[0278]基于该语句包括的变量定义单元中的该变量的名称信息和类型信息,生成与该语句具有相同代码逻辑的webassembly代码块。[0279]进一步的,所述代码生成模块52,具体用于当该语法单元为变量表达式,且该变量表达式表示局部变量时,如果该局部变量为基本类型,生成webassembly中的get_local指令,该get_local指令的操作数为已经为该局部变量分配的local索引,用于获取该局部变量的值;[0280]如果该局部变量为非基本类型,生成webassembly中的get_global指令、i32.add指令和iload指令,该get_global指令用于获取辅助栈栈顶指针,该i32.add指令用于获取栈顶指针加上该局部变量在辅助栈中的偏移量,该iload指令用于获取该局部变量的值;[0281]当该语法单元为变量表达式,且该变量表达式表示全局变量时,生成webassembly中的iload指令,用于获取在内存中为该全局变量分配的地址;[0282]当该语法单元为变量表达式,且该变量表达式表示直接地址变量时,生成webassembly中的get_global指令、i32.add指令和iload指令,该get_global指令用于获取io区域的首地址,该i32.add指令用于获取io区域的首地址加上该直接地址变量的偏移量后的地址,该iload指令用于获取该直接地址变量的值。[0283]进一步的,代码生成模块52,还用于生成如下接口函数:[0284]用于初始化所有作为程序的语法单元的接口函数;[0285]用于获取为程序分配的内存空间的程序地址的接口函数;[0286]用于初始化为直接地址变量分配的io区域的接口函数;[0287]所述代码拼装模块53,具体用于将得到的多个webassembly代码块,以及生成的各接口函数,按照所述各语法单元之间的逻辑关系进行拼装。[0288]上述各模块的功能可对应于图1-图4所示流程中的相应处理步骤,在此不再赘述。[0289]本技术的实施例所提供的将st代码编译为webassembly代码的装置可通过计算机程序实现。本领域技术人员应该能够理解,上述的模块划分方式仅是众多模块划分方式中的一种,如果划分为其他模块或不划分模块,只要将st代码编译为webassembly代码的装置具有上述功能,都应该在本技术的保护范围之内。[0290]本技术实施例还提供一种电子设备,如图6所示,包括处理器61和机器可读存储介质62,所述机器可读存储介质62存储有能够被所述处理器61执行的机器可执行指令,所述处理器61被所述机器可执行指令促使:实现上述任一将st代码编译为webassembly代码的方法。[0291]本技术实施例还提供一种计算机可读存储介质,所述计算机可读存储介质内存储有计算机程序,所述计算机程序被处理器执行时实现上述任一将st代码编译为webassembly代码的方法。[0292]本技术实施例还提供了一种包含指令的计算机程序产品,当其在计算机上运行时,使得计算机执行上述任一将st代码编译为webassembly代码的方法。[0293]上述电子设备中的机器可读存储介质可以包括随机存取存储器(randomaccessmemory,ram),也可以包括非易失性存储器(non-volatilememory,nvm),例如至少一个磁盘存储器。可选的,存储器还可以是至少一个位于远离前述处理器的存储装置。[0294]上述的处理器可以是通用处理器,包括中央处理器(centralprocessingunit,cpu)、网络处理器(networkprocessor,np)等;还可以是数字信号处理器(digitalsignalprocessing,dsp)、专用集成电路(applicationspecificintegratedcircuit,asic)、现场可编程门阵列(field-programmablegatearray,fpga)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件。[0295]本说明书中的各个实施例均采用相关的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于装置、电子设备、计算机可读存储介质,计算机程序产品实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。[0296]需要说明的是,在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者设备中还存在另外的相同要素。[0297]本技术是参照根据本技术实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。[0298]这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。[0299]这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。[0300]显然,本领域的技术人员可以对本技术进行各种改动和变型而不脱离本技术的精神和范围。这样,倘若本技术的这些修改和变型属于本技术权利要求及其等同技术的范围之内,则本技术也意图包含这些改动和变型在内。当前第1页12当前第1页12
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献