CN107924326A - 对经更新的类型的迁移方法进行覆盖 - Google Patents
对经更新的类型的迁移方法进行覆盖 Download PDFInfo
- Publication number
- CN107924326A CN107924326A CN201780002772.0A CN201780002772A CN107924326A CN 107924326 A CN107924326 A CN 107924326A CN 201780002772 A CN201780002772 A CN 201780002772A CN 107924326 A CN107924326 A CN 107924326A
- Authority
- CN
- China
- Prior art keywords
- type
- hoc approach
- value
- subtype
- instruction
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/455—Emulation; Interpretation; Software simulation, e.g. virtualisation or emulation of application or operating system execution engines
- G06F9/45504—Abstract machines for programme code execution, e.g. Java virtual machine [JVM], interpreters, emulators
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/44—Encoding
- G06F8/447—Target code generation
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/43—Checking; Contextual analysis
- G06F8/436—Semantic checking
- G06F8/437—Type checking
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/70—Software maintenance or management
- G06F8/71—Version control; Configuration management
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/448—Execution paradigms, e.g. implementations of programming paradigms
- G06F9/4488—Object-oriented
- G06F9/449—Object-oriented method invocation or resolution
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Computer Security & Cryptography (AREA)
- Computational Linguistics (AREA)
- Devices For Executing Special Programs (AREA)
Abstract
描述了对经更新的类型中的迁移方法进行覆盖。识别调用子类型中的对超类型中的迁移方法进行覆盖的特定方法的指令。这些指令可以使用与特定类型集合相关联的变元集合来调用特定方法。特定类型集合与和在子类型中定义的特定方法相关联的参数类型集合不同。附加地或替代地,这些指令可以包括从特定方法返回特定类型的值。该特定类型与和在子类型中定义的特定方法相关联的返回类型不同。生成新方法。该新方法包括用于(a)转换变元集合和/或(b)转换从特定方法返回的值的指令。新方法被存储在运行时环境中并且被执行。
Description
优先权要求
本申请要求于2016年7月12日提交的美国临时专利申请No.62/361,087;于2017年2月7日提交的美国非临时专利申请No.15/426,839;以及于2017年2月7日提交的美国非临时专利申请No.15/426,312的优先权;这些申请中的每一个都通过引用被结合于此。
技术领域
本公开涉及编译和/或执行类型。具体而言,本公开涉及访问经更新的类型的迁移成员。
背景技术
编译器将根据针对程序员的便利性的规范编写的源代码转换为可由特定机器环境直接执行的机器代码或目标代码,或者转换为可由能够在各种特定机器环境之上运行的虚拟机执行的中间表示(“虚拟机代码/指令”),诸如字节码。虚拟机指令可由虚拟机以比源代码更直接和高效的方式执行。将源代码转换为虚拟机指令包括将源代码功能从语言映射到利用底层资源(诸如数据结构)的虚拟机功能。通常,由程序员经由源代码以简单术语呈现的功能被转换为更复杂的步骤,这些步骤更直接地映射到由虚拟机所驻留的底层硬件支持的指令集。
在本部分中描述的方法是可以实行的方法,但不一定是先前已经构想或实行的方法。因此,除非另外指出,否则不应当假设在本部分中描述的任何方法仅仅凭其包括在本部分中就被认为是现有技术。
附图说明
在附图的各个图中,实施例是作为示例而不是作为限制被示出的。应当注意的是,在本公开中对“一个”实施例的引用不一定是指同一个实施例,并且它们意味着至少一个实施例。在附图中:
图1示出在其中可以实践本文描述的技术的示例计算体系架构。
图2是示出适合于实现本文描述的方法和特征的计算机系统的一个实施例的框图。
图3示出根据实施例的以框图形式的示例虚拟机存储器布局。
图4示出根据实施例的以框图形式的示例帧。
图5示出根据一个或多个实施例的经更新的类型的示例。
图6示出根据一个或多个实施例的子类型的示例。
图7示出根据一个或多个实施例的用于对包括迁移方法的经更新的类型进行编译的一组操作。
图8A-图8B示出根据一个或多个实施例的用于调用覆盖经更新的类型中的迁移方法的特定方法的一组操作。
图9A-图9B示出根据一个或多个实施例的用于调用覆盖经更新的类型中的迁移方法的特定方法的另一组操作。
图10示出根据一个或多个实施例的系统。
具体实施方式
在以下描述中,为了解释的目的,阐述了许多具体细节以便提供透彻的理解。可以在没有这些具体细节的情况下实践一个或多个实施例。在一个实施例中描述的特征可以与在不同实施例中描述的特征组合。在一些示例中,参考框图形式来描述众所周知的结构和设备,以便避免不必要地模糊本发明。
1.总体概述
2.体系架构概述
2.1示例类文件结构
2.2示例虚拟机体系架构
2.3加载、链接和初始化
3.经更新的类型和子类型
4.编译经更新的类型
5.覆盖迁移方法
6.其它方面;扩展
7.硬件概述
1.总体概述
一个或多个实施例包括对经更新的类型中的迁移方法进行覆盖。迁移方法是存在多个版本的方法。同一经更新的类型内的方法的多个版本可以包括例如(a)当前版本和(b)已经被迁移到当前版本的过期版本。迁移方法的每个版本都与相同的方法名称相关联。如本文为了解释的目的而提及的经更新的类型是包括迁移方法的多个版本的类型。
一个或多个实施例包括使用变元(argument)集合来调用特定方法,其中该特定方法覆盖经更新的类型中的迁移方法。在子类型(sub-type)中定义的特定方法与参数类型集合相关联。在超类型(super-type)中定义的迁移方法的不同版本与不同的参数类型集合相关联。将(a)用于调用特定方法的变元集合转换为(b)与该特定方法相关联的参数类型集合的值的转换函数是从超类型中识别的。生成新方法,其中该新方法包括:(a)将变元集合转换为与特定方法相关联的参数类型集合的值,以及(b)使用经转换的值来调用特定方法。新方法被存储在运行时环境中。新方法被执行。
一个或多个实施例包括将来自特定方法的值作为特定类型的值返回,其中该特定方法覆盖经更新的类型中的迁移方法。在子类型中定义的特定方法与返回类型相关联。在超类型中定义的迁移方法的不同版本与不同的返回类型相关联。将(a)由特定方法返回的值转换为(b)特定类型的值的转换函数是从超类型中识别的。生成新方法,其中该新方法包括:(a)调用特定方法,以及(b)将该特定方法返回的值转换为特定类型的值。新方法被存储在运行时环境中。新方法被执行。
在本说明书中描述和/或在权利要求中记载的一个或多个实施例可能不被包括在此总体概述部分中。
2.体系架构概述
图1示出在其中可以实践本文描述的技术的示例体系架构。关于示例体系架构所描述的软件和/或硬件部件可以被省略或与和本文所描述的功能集合不同的功能集合相关联。根据一个或多个实施例,可以在环境内使用本文中未描述的软件和/或硬件部件。因此,示例环境不应当被认为是限制任何权利要求的范围。
如图1所示,计算体系架构100包括源代码文件101,源代码文件101由编译器102编译成表示要被执行的程序的类文件103。类文件103然后由执行平台112加载和执行,执行平台112包括运行时环境113、操作系统111以及使得能够在运行时环境113和操作系统之间通信的一个或多个应用编程接口(API)110。运行时环境113包括虚拟机104,虚拟机104包括各种部件,诸如存储器管理器105(其可以包括垃圾收集器)、用于检查类文件103的有效性的类文件验证器106、用于定位和构建类的存储器中表示的类加载器107、用于执行虚拟机104代码的解释器108、以及用于产生经优化的机器级别代码的准时(just-in-time,JIT)编译器109。
在实施例中,计算体系架构100包括源代码文件101,源代码文件101包含已经用特定编程语言(诸如Java、C、C++、C#、Ruby、Perl等)编写的代码。因此,源代码文件101遵循用于相关联语言的特定语法和/或语义规则集合。例如,以Java编写的代码遵循Java语言规范。然而,由于规范随着时间的推移被更新和修订,因此源代码文件101可能与指示源代码文件101所遵循的规范的修订版本的版本号相关联。用于编写源代码文件101的确切编程语言通常不是关键的。
在各种实施例中,编译器102将根据针对程序员的便利性的规范编写的源代码转换为可由特定机器环境直接执行的机器代码或目标代码,或者转换为可由能够在各种特定机器环境之上运行的虚拟机104执行的中间表示(“虚拟机代码/指令”),诸如字节码。虚拟机指令可由虚拟机104以比源代码更直接和高效的方式执行。将源代码转换为虚拟机指令包括将源代码功能从语言映射到利用底层资源(诸如数据结构)的虚拟机功能。通常,由程序员经由源代码以简单术语呈现的功能被转换为更复杂的步骤,这些步骤更直接地映射到由虚拟机104所驻留的底层硬件支持的指令集。
一般而言,程序作为经编译的程序或者经解释的程序来执行。当程序被编译时,代码在执行之前从第一语言被全局地变换为第二语言。由于变换代码的工作是提前执行的,因此经编译的代码往往具有优异的运行时性能。此外,由于变换在执行之前全局地发生,因此可以使用诸如常量合并(constant folding)、死代码消除(dead code elimination)、内联(inlining)等技术来分析和优化代码。然而,取决于被执行的程序,启动时间可能是显著的。此外,插入新代码将需要使程序下线(offline)、重新编译和重新执行。对于被设计为允许代码在程序执行期间被插入的许多动态语言(诸如Java),纯编译的方法可能是不适当的。当程序被解释时,程序的代码在程序执行时被逐行读取并且转换为机器级别指令。因此,程序具有短的启动时间(可以几乎立即开始执行),但是运行时性能由于即时(on thefly)执行变换而降低。此外,由于每条指令被单独分析,因此依赖对程序的更全局的分析的许多优化不能被执行。
在一些实施例中,虚拟机104包括解释器108和JIT编译器109(或实现这两个方面的部件),并且使用解释技术和编译技术的组合来执行程序。例如,虚拟机104可以初始地通过经由解释器108解释表示程序的虚拟机指令来开始,同时跟踪与程序行为相关的统计信息,诸如不同的代码部分或代码块有多么频繁地被虚拟机104执行。一旦代码块超过阈值(变“热”),虚拟机104就调用JIT编译器109来执行对该块的分析并且生成经优化的机器级别指令,其代替该“热”的代码块以用于将来的执行。由于程序往往花费大部分时间执行整个代码的一小部分,因此只编译程序的“热”部分可以提供与完全经编译的代码相似的性能,但没有启动害处(penalty)。此外,尽管优化分析被约束到被代替的“热”块,但是仍然存在比单独转换每条指令大得多的优化潜力。在上述示例上存在多种变体,诸如分层编译。
为了提供清楚的示例,源代码文件101已经被示出为要由执行平台112执行的程序的“顶级”表示。虽然计算体系架构100将源代码文件101描绘为“顶级”程序表示,但是在其它实施例中,源代码文件101可以是经由将不同语言的代码文件处理成源代码文件101的语言的“更高级”编译器接收到的中间表示。以下公开中的一些示例假设源代码文件101遵循基于类的面向对象的编程语言。然而,这不是对利用本文所描述的特征的要求。
在实施例中,编译器102接收源代码文件101作为输入,并且将源代码文件101转换为虚拟机104所期望的格式的类文件103。例如,在JVM的上下文中,Java虚拟机规范定义了类文件103预期要遵循的特定类文件格式。在一些实施例中,类文件103包含已从源代码文件101转换的虚拟机指令。然而,在其它实施例中,类文件103也可以包含其它结构,诸如识别常量值的表和/或与各种结构(类、字段、方法等)相关的元数据。
以下讨论假设类文件103中的每一个表示在源代码文件101中定义的(或由编译器102/虚拟机104动态生成的)相应的“类型”。“类型”的示例包括类和接口。类是用于与该类相关联的对象的属性和行为的模板。类包括与类的对象相关联的字段和方法。接口包括可以由类实现的抽象方法。实现接口的类继承接口的抽象方法并为每个抽象方法提供了主体(body)。然而,前述假设不是严格的要求并且将取决于虚拟机104的实现方式。因此,无论类文件103的确切格式如何,本文描述的技术都仍然可以被执行。
类型可以被更新为包括具有相同字段名称但具有不同字段类型的多个字段。附加地或替代地,类型可以被更新为包括具有相同方法名称但具有不同参数类型和/或返回类型的多个方法。本文的实施例涉及访问经更新的类型的成员。
在一些实施例中,类文件103被划分为一个或多个“库(library)”或“包(package)”,其中的每一个包括提供相关功能的类的汇集。例如,库可以包含实现输入/输出(I/O)操作、数学工具、密码技术、图形化工具等的一个或多个类文件。此外,一些类(或这些类内的字段/方法)可以包括访问限制,这些访问限制将这些类的使用限制在特定类/库/包内或限制到具有适当许可的类。
2.1示例类文件结构
图2示出根据实施例的以框图形式的类文件200的示例结构。为了提供清楚的示例,本公开的其余部分假设计算体系架构100的类文件103遵循本部分中所描述的示例类文件200的结构。然而,在实际环境中,类文件200的结构将取决于虚拟机104的实现方式。此外,本文所讨论的一个或多个特征可以修改类文件200的结构,以例如添加附加的结构类型。因此,类文件200的确切结构对于本文描述的技术不是关键的。为了部分2.1的目的,“类”或“当前类”是指由类文件200表示的类。
在图2中,类文件200包括常量表201、字段结构208、类元数据207和方法结构209。在实施例中,常量表201是除了其它功能之外还充当类的符号表的数据结构。例如,常量表201可以存储与在源代码文件101中使用的各种标识符相关的数据,诸如类型、范围、内容和/或位置。常量表201具有用于值结构202(表示类型int、long、double、float、byte、string等的常量值)、类信息结构203、名称和类型信息结构204、字段引用结构205、以及由编译器102从源代码文件101导出的方法引用结构206的条目。在实施例中,常量表201被实现为将索引i映射到结构j的数组。然而,常量表201的确切实现方式不是关键的。
在一些实施例中,常量表201的条目包括对其它常量表201条目进行索引的结构。例如,用于值结构202中表示串(string)的一个值结构的条目可以保持将其“类型”识别为串的标签,以及指向常量表201中存储表示该串的ASCII字符的char、byte或int值的一个或多个其它值结构202的索引。
在实施例中,常量表201的字段引用结构205保持指向常量表201中表示定义字段的类的类信息结构203之一的索引,以及指向常量表201中提供该字段的名称和描述符的名称和类型信息结构204之一的索引。常量表201的方法引用结构206保持指向常量表201中表示定义方法的类的类信息结构203之一的索引,以及指向常量表201中提供该方法的名称和描述符的名称和类型信息结构204之一的索引。类信息结构203保持指向常量表201中保持相关联的类的名称的值结构202之一的索引。
名称和类型信息结构204保持指向常量表201中存储字段/方法的名称的值结构202之一的索引,以及指向常量表201中存储描述符的值结构202之一的索引。
在实施例中,类元数据207包括用于类的元数据,诸如(一个或多个)版本号、常量池中的条目数量、字段数量、方法数量、访问标志(类是否是公开的(public)、私有的(private)、最终的(final)、抽象的(abstract)等)、指向常量表201中识别当前类的类信息结构203之一的索引、指向常量表201中识别超类(superclass)(如果有的话)的类信息结构203之一的索引,等等。
在实施例中,字段结构208表示识别类的各个字段的结构集合。字段结构208为类的每个字段存储用于该字段的访问器标志(字段是否是静态的(static)、公开的(public)、私有的(private)、最终的(final)等)、指向常量表201中保持该字段的名称的值结构202之一的索引、以及指向常量表201中保持该字段的描述符的值结构202之一的索引。
在实施例中,方法结构209表示识别类的各种方法的结构的集合。方法结构209为类的每个方法存储用于该方法的访问器标志(例如,方法是否是静态的(static)、公开的(public)、私有的(private)、同步的(synchronized)等)、指向常量表201中保持该方法的名称的值结构202之一的索引、指向常量表201中保持该方法的描述符的值结构202之一的索引、以及与如在源代码文件101中定义的方法的主体对应的虚拟机指令。
在实施例中,描述符表示字段或方法的类型。例如,描述符可以实现为遵循特定语法的串。虽然确切的语法不是关键的,但以下将描述几个示例。
在其中描述符表示字段的类型的示例中,描述符识别由字段保持的数据的类型。在实施例中,字段可以保持基本类型、对象或数组。当字段保持基本类型时,描述符是识别该基本类型的串(例如,“B”=byte、“C”=char、“D”=double、“F”=float、“I”=int、“J”=long int等)。当字段保持对象时,描述符是识别该对象的类名称的串(例如,“LClassName”)。在这种情况下,“L”指示引用,因此“L ClassName”表示对类ClassName的对象的引用。当字段是数组时,描述符识别由数组保持的类型。例如,“[B”指示字节的数组,其中“[”指示数组并且“B”指示数组保持字节基本类型。然而,由于数组可以嵌套,因此用于数组的描述符也可以指示嵌套。例如,“[[L ClassName”指示数组,在该数组中每个索引保持保持类ClassName的对象的数组。在一些实施例中,ClassName是完全限定的,并且包括类的简单名称以及类的路径名。例如,ClassName可以指示文件被存储在包、库或托管类文件200的文件系统中的什么位置。
在方法的情况下,描述符识别方法的参数和方法的返回类型。例如,方法描述符可以按照一般形式“({ParameterDescriptor})ReturnDescriptor”(“({参数描述符})返回描述符”),其中{ParameterDescriptor}是表示参数的字段描述符的集合或列表,并且ReturnDescriptor是识别返回类型的字段描述符。例如,串“V”可以用于表示void返回类型。因此,在源代码文件101中定义为“Object m(int I,double d,Thread t){...}”的方法与描述符“(I D L Thread)L Object”匹配。
在实施例中,保持在方法结构209中的虚拟机指令包括对常量表201的条目进行引用的操作。使用Java作为示例,考虑以下类:
在以上示例中,Java方法add12and13在类A中定义,不带参数,并且返回整数。方法add12and13的主体调用类B的静态方法addTwo,静态方法addTwo采用常整数值12和13作为参数,并且返回结果。因此,在常量表201中,编译器102除其它条目之外还包括与对方法B.addTwo的调用对应的方法引用结构。在Java中,对方法的调用向下编译为JVM的字节码中的invoke命令(在这种情况下为invokestatic,因为addTwo是类B的静态方法)。该invoke(调用)命令被提供指向常量表201中与方法引用结构对应的索引,其中该方法引用结构识别定义addTwo的类“B”、addTwo的名称“addTwo”、以及addTwo的描述符“(I I)I”。例如,假设上述方法引用被存储在索引4处,则字节码指令可以出现为“invokestatic#4”。
由于常量表201用携带识别信息的结构来符号性地引用类、方法和字段而不是直接引用存储器位置,因此常量表201的条目被称为“符号引用”。符号引用被用于类文件103的一个原因是因为在一些实施例中一旦类被加载到运行时环境113中,编译器102就不知道类将如何被存储以及存储在哪里。如将在部分2.3中所描述的,在所引用的类(及相关联的结构)已被加载到运行时环境中并且被分配具体的存储器位置之后,符号引用的运行时表示最终被虚拟机104解析为实际的存储器地址。
2.2示例虚拟机体系架构
图3示出根据实施例的以框图形式的示例虚拟机存储器布局300。为了提供清楚的示例,剩余的讨论将假设虚拟机104遵循图3中绘出的虚拟机存储器布局300。此外,虽然虚拟机存储器布局300的部件可以被称为存储器“区域”,但是不要求存储器区域是连续的。
在图3示出的示例中,虚拟机存储器布局300被划分为共享区域301和线程区域307。共享区域301表示在虚拟机104上执行的各种线程之间共享的结构被存储在其中的存储器中区域。共享区域301包括堆302和按类(per-class)区域303。在实施例中,堆302表示运行时数据区域,从该运行时数据区域中分配用于类实例和数组的存储器。在实施例中,按类区域303表示与各个类有关的数据被存储在其中的区域。在实施例中,对于每个经加载的类,按类区域303包括表示来自该类的常量表201的数据的运行时常量池304、字段和方法数据306(例如,用于保持类的静态字段)、以及表示用于类的方法的虚拟机指令的方法代码305。
线程区域307表示特定于各个线程的结构被存储在其中的存储器区域。在图3中,线程区域307包括线程结构308和线程结构311,其表示由不同线程利用的按线程(per-thread)结构。为了提供清楚的示例,图3中绘出的线程区域307假设两个线程正在虚拟机104上执行。然而,在实际环境中,虚拟机104可以执行任何任意数量的线程,其中线程结构的数量相应地缩放。
在实施例中,线程结构308包括程序计数器309和虚拟机栈310。类似地,线程结构311包括程序计数器312和虚拟机栈313。在实施例中,程序计数器309和程序计数器312存储由其相应的线程执行的虚拟机指令的当前地址。
因此,当线程逐步通过指令时,程序计数器被更新以维护指向当前指令的索引。在实施例中,虚拟机栈310和虚拟机栈313各自存储用于其相应线程的保持本地变量和部分结果的帧,并且还用于方法调用和返回。
在实施例中,帧是用于存储数据和部分结果、方法的返回值、以及执行动态链接的数据结构。每次调用方法时,都创建新的帧。当使得帧被生成的方法完成时,该帧被销毁。因此,当线程执行方法调用时,虚拟机104生成新帧并将该帧推送到与该线程相关联的虚拟机栈上。
当方法调用完成时,虚拟机104将方法调用的结果传递回到前一帧,并将当前帧从栈中弹出。在实施例中,对于给定的线程,在任何点处有一个帧是活动的。该活动帧被称为当前帧,使得生成当前帧的方法被称为当前方法,并且当前方法所属的类被称为当前类。
图4示出根据实施例的框图形式的示例帧400。为了提供清楚的示例,剩余的讨论将假设虚拟机栈310和虚拟机栈313的帧遵循帧400的结构。
在实施例中,帧400包括本地变量401、操作数栈402和运行时常量池引用表403。在实施例中,本地变量401被表示为变量的数组,每个变量都保持值,例如Boolean、byte、char、short、int、float或reference(引用)。此外,一些值类型(诸如long或double)可以由数组中的多于一个的条目表示。本地变量401用于在方法调用上传递参数并存储部分结果。例如,当响应于调用方法而生成帧400时,参数可以被存储在本地变量401内的预定位置(诸如与调用中的第一至第N个参数对应的索引1-N)中。
在实施例中,当虚拟机104创建帧400时,操作数栈402默认为空。然后,虚拟机104从当前方法的方法代码305中供给指令以将来自本地变量401的常量或值加载到操作数栈402上。其它指令从操作数栈402获取操作数、对它们进行操作、并将结果推送回到操作数栈402上。此外,操作数栈402被用于准备要被传递给方法的参数以及接收方法结果。例如,正被调用的方法的参数可以在向方法发出调用之前被推送到操作数栈402上。然后,虚拟机104为方法调用生成新帧,其中前一帧的操作数栈402上的操作数被弹出并被加载到新帧的本地变量401中。当被调用的方法终止时,新帧从虚拟机栈中弹出,并且返回值被推送到前一帧的操作数栈402上。
在实施例中,运行时常量池引用表403包含对当前类的运行时常量池304的引用。运行时常量池引用表403用于支持解析。解析是其中将常量池304中的符号引用变换成具体的存储器地址的过程,从而根据需要加载类以解析尚未定义的符号并将变量访问变换成与这些变量的运行时位置相关联的存储结构中的适当偏移量。
2.3加载、链接和初始化
在实施例中,虚拟机104动态地加载、链接和初始化类。加载是如下的过程:找到具有特定名称的类,并且在运行时环境113的存储器内根据该类的相关联的类文件200创建表示。例如,在虚拟机存储器布局300的按类区域303内创建用于该类的运行时常量池304、方法代码305以及字段和方法数据306。链接是如下过程:取得类的存储器中表示,并且将其与虚拟机104的运行时状态组合,使得类的方法可以被执行。初始化是如下的过程:执行类构造函数(constructor)以设置类的字段和方法数据306的起始状态,和/或在堆302上为经初始化的类创建类实例。
以下是可以由虚拟机104实现的加载、链接和初始化技术的示例。然而,在许多实施例中,这些步骤可以被交错,使得初始类被加载,然后在链接期间,第二个类被加载以解析在第一个类中找到的符号引用,这又导致第三个类被加载,等等。因此,通过加载、链接和初始化阶段的进展可以因类而异。此外,一些实施例可以将加载、链接和初始化过程中的一个或多个功能延迟(“懒惰地”执行)到该类被实际需要时。例如,方法引用的解析可以被延迟到调用该方法的虚拟机指令被执行时。因此,对于每个类,步骤被执行的时间的确切时间在各种实现方式之间可能很不一样。
为了开始加载过程,虚拟机104通过调用加载初始类的类加载器107来启动。指定初始类的技术将因实施例而异。例如,一种技术可以使虚拟机104在启动时接受指定初始类的命令行变元。
为了加载类,类加载器107解析与该类对应的类文件200,并且确定类文件200是否是良好构造的(满足虚拟机104的句法期望)。如果不是,则类加载器107生成错误。例如,在Java中,可能以异常的形式生成错误,该异常被抛出给异常处理器进行处理。否则,类加载器107通过为该类在按类区域303内分配运行时常量池304、方法代码305以及字段和方法数据306来生成该类的存储器中表示。
在一些实施例中,当类加载器107加载类时,类加载器107还递归地加载被加载类的超类。例如,虚拟机104可以确保在继续针对特定类的加载、链接和初始化过程之前,该特定类的超类被加载、链接和/或初始化。
在链接期间,虚拟机104验证类、准备类、并且执行对在类的运行时常量池304中定义的符号引用的解析。
为了验证类,虚拟机104检查类的存储器中表示是否在结构上正确。例如,虚拟机104可以检查除通用类Object(对象)之外的每个类具有超类、检查最终类没有子类以及最终方法没有被覆盖、检查常量池条目是否彼此一致、检查当前类是否具有对常量池304中引用的类/字段/结构的正确访问许可、检查方法的虚拟机104代码将不会引起意外行为(例如,确保跳转指令不会将虚拟机104发送到超出该方法的结尾),等等。在验证期间执行的确切检查取决于虚拟机104的实现方式。在一些情况下,验证会导致附加的类被加载,但不一定要求这些类在继续之前也被链接。例如,假设类A包含对类B的静态字段的引用。在验证期间,虚拟机104可以检查类B,以确保被引用的静态字段实际上存在,这可能导致类B的加载,但不一定导致类B的链接或初始化。然而,在一些实施例中,某些验证检查可以被延迟到稍晚的阶段,诸如在符号引用的解析期间被检查。例如,一些实施例可以将检查对符号引用的访问许可延迟到这些引用被解析时。
为了准备类,虚拟机104将位于用于该类的字段和方法数据306内的静态字段初始化为默认值。在一些情况下,将静态字段设置为默认值可能与运行类的构造函数不同。例如,验证过程可以将静态字段清零或将其设置为构造函数期望这些字段在初始化期间所具有的值。
在解析期间,虚拟机104根据包括在类的运行时常量池304中的符号引用来动态地确定具体的存储器地址。为了解析符号引用,虚拟机104利用类加载器107来加载在符号引用中识别出的类(如果尚未被加载)。一旦被加载,虚拟机104就知道所引用的类及其字段/方法的按类区域303内的存储器位置。然后,虚拟机104用对所引用的类、字段或方法的具体存储器位置的引用来替换符号引用。在实施例中,虚拟机104对解析进行高速缓存,以在当虚拟机104处理另一个类时遇到相同类/名称/描述符的情况下进行重用。例如,在一些情况下,类A和类B可能调用类C的同一方法。因此,当对类A执行解析时,该结果可以被高速缓存,并且在解析类B中的相同符号引用期间被重用以减少开销。
在一些实施例中,在链接期间解析符号引用的步骤是可选的。例如,实施例可以以“懒惰”的方式执行符号解析,从而将解析的步骤延迟到需要所引用的类/方法/字段的虚拟机指令被执行时。
在初始化期间,虚拟机104执行类的构造函数以设置该类的起始状态。例如,初始化可以初始化用于类的字段和方法数据306,并且生成/初始化由构造函数在堆302上创建的任何类实例。例如,用于类的类文件200可以指定特定方法是用于设立起始状态的构造函数。因此,在初始化期间,虚拟机104执行该构造函数的指令。
在一些实施例中,虚拟机104通过初始地检查字段/方法是否在所引用的类中被定义来执行对字段和方法引用的解析。以其它方式,虚拟机104针对所引用的字段/方法递归地搜索所引用的类的超类,直到定位该字段/方法或者到达顶级超类,在到达顶级超类的情况下生成错误。
3.经更新的类型和子类型
图5示出根据一个或多个实施例的经更新的类型的示例。如图所示,经更新的类型502包括字段506、方法514、一个或多个迁移关系522以及一个或多个转换函数524。在一个或多个实施例中,经更新的类型502可以包括比图5中示出的部件更多或更少的部件。作为示例,经更新的类型可以包括字段506而不包括方法514。可替代地,经更新的类型可以包括方法514而不包括字段506。
在一个或多个实施例中,字段506中的每一个(诸如字段506a-b)与相同的字段名称508相关联但与不同的字段类型(诸如字段类型510a-b)相关联。每个字段506可以被称为“迁移字段”的不同版本。
作为示例,经更新的类型502可以包括具有相同字段名称fd的两个字段。这两个字段中的其中一个字段可以与字段类型Date(日期)相关联。这两个字段中的另一个字段可以与字段类型NewDate(新日期)相关联。字段类型Date可以只包括月份和年份。字段类型NewDate可以包括月份、日期和年份。包括上述迁移字段的示例代码可以被编写为如下:
在以上示例中,以@MigratedFrom开始的行可以用于识别Date fd和NewDate fd之间的迁移关系522。下面进一步描述迁移关系522。
在一个或多个实施例中,方法514中的每一个(诸如方法514a-b)与相同的方法名称516相关联。但是每个方法与不同的参数类型(诸如参数类型518a-b)集合和/或不同的返回类型(诸如返回类型520a-b)相关联。参数类型集合包括分别与输入到方法的一个或多个参数对应的一个或多个参数类型。返回类型对应于方法返回的值。术语“方法描述符”是指(a)方法名称,(b)参数类型集合,以及(c)与特定方法相关联的返回类型。与相同方法名称相关联但与不同方法描述符相关联的每个方法可以被称为“迁移方法”的不同版本。
作为示例,经更新的类型包括具有相同方法名称getAccess的两个方法。这两个方法中的一个与具有参数类型byte的一个参数相关联。该方法还与返回类型Date相关联。这两个方法中的另一个方法与分别具有参数类型char和String的两个参数相关联。该方法还与返回类型NewDate相关联。包括上述迁移方法的示例代码可以被编写为如下:
在以上示例中,以@MigratedFrom开始的行可以用于识别Date getAccess(bytearg1)和NewDategetAccess(char arg1,String arg2)之间的迁移关系522。下面进一步描述迁移关系522。
在一个或多个实施例中,附加的和/或替代的迁移成员可以被包括在经更新的类型502中。类型中的成员是类型的可继承组成部分。假定基于访问级别修饰符对类型中的成员没有访问限制,那么该成员被子类型继承。类型中的成员可以直接在类型的主体中进行声明。附加地或替代地,成员可以经由继承被包括在类型中。成员的示例包括字段、方法、嵌套类、接口和枚举类型。经更新的类型502是包括一个或多个迁移成员的类型。
在一个或多个实施例中,迁移关系522指示迁移成员的每个版本被创建的顺序。附加地或替代地,迁移关系522识别迁移成员的哪个特定版本是迁移自迁移成员的另一个版本。作为示例,迁移关系可以指示字段506b迁移自字段506a。另一个迁移关系可以指示方法514b迁移自方法514a。
迁移关系522可以在与迁移成员的一个或多个版本相关联的迁移标签中被指定。如上所述,包括迁移标签的示例代码可以被编写为如下:
以@MigratedFrom开始的行是与NewDate fd相关联的迁移标签。在括号中,术语“Date fd”指示NewDatefd迁移自Date fd。同样在括号中,术语“ConversionFunctionPair”识别一对转换函数。术语“ConversionFunctionPair”可以是例如对一对转换函数的引用。在下面进一步描述转换函数。
同样如上所述,包括迁移标签的示例代码可以被编写为如下:
以@MigratedFrom开始的行是与NewDate getAccess(char arg1,String arg2)相关联的迁移标签。在括号中,术语“Date getAccess(byte arg1)”指示NewDategetAccess(char arg1,String arg2)是迁移自Date getAccess(byte arg1)。同样在括号中,术语“ParameterConversionFunctionPair”识别用于迁移方法的参数类型的一对转换函数。术语“ReturnConversionFunctionPair”识别用于迁移方法的返回类型的一对转换函数。下面进一步描述转换函数。
在实施例中,迁移成员可以与三个或更多个版本相关联。可以使用多个迁移标签来指定不同版本之间的迁移关系。作为示例,迁移成员可以是命名为fd的字段。与该迁移成员相关联的版本可以是:intfd;Date fd;NewDate fd。与Date fd相关联的一个迁移标签可以指示Date fd是迁移自int fd。与NewDate fd相关联的另一个迁移标签可以指示NewDatefd是迁移自Date fd。
附加地或替代地,可以在与包括经更新的类型502的文件分离的文件和/或数据库中指定迁移关系522。作为示例,分离的文件可以存储版本列表。该版本列表可以是迁移成员的版本的有序列表。作为示例,有序列表可以包括:int fd;Date fd;NewDate fd。有序列表可以指示int fd是迁移字段fd的最早版本;Date fd是迁移字段fd的后续版本;并且NewDate fd是迁移字段fd的当前版本。
在一个或多个实施例中,转换函数524将特定类型集合的值转换为另一个类型集合的值。
作为示例,转换函数可以将double值转换为int值。double类型可以是有符号的64位二进制补码整数,而int类型可以是有符号的32位二进制补码整数。int类型的范围可以是-2,147,483,648到+2,147,483,647。当将double值转换为int值时,将double值与int类型的范围进行比较。如果double值在int类型的范围内,则double值的最低有效32位可以被确定为经转换的int值。如果double值大于int类型的最大值,则int类型的最大值(+2,147,483,647)可以被确定为经转换的int值。如果double值低于int类型的最小值,则int类型的最小值(-2,147,483,648)可以被确定为经转换的int值。
作为另一个示例,转换函数可以将int值转换为double值。如果int值是正数,则转换函数可以在int值的前面填充三十二个0。如果int值是负数,则转换函数可以在int值的前面填充三十二个1。填充后的int值可以被确定为经转换的double值。
一对转换函数包括投影函数(projection function)和嵌入函数(embeddingfunction)。嵌入函数执行相较于投影函数的逆转换。嵌入函数将第一类型的值转换为第二类型的值。相反,投影函数将第一类型的值转换为第二类型的值。然而,嵌入函数和投影函数可以不是彼此的精确的逆。如下所述,嵌入函数和投影函数具有以下属性。
给定第一类型的第一值,可以向第一值应用嵌入函数。可以向嵌入函数的结果应用投影函数。这种应用投影函数的结果是第一值本身。
给定第二类型的第二值,可以向第二值应用投影函数。可以向投影函数的结果应用嵌入函数。这种应用嵌入函数的结果是第二值本身,或者是与第二值相似和/或相关的值。
以下示例示出嵌入函数和投影函数的以上属性。作为示例,嵌入函数可以将int值转换为double值。投影函数可以将double值转换为int值。
初始的int值可以是在最高有效位中包括十三个0、后面跟着最低有效位中的十九个1的二进制数(其在十进制下为524,287)。嵌入函数可以应用到该初始int值。基于嵌入函数,可以在该int值前面填充三十二个0。经转换的double值可以是在最高有效位中包括四十五个0、后面跟着最低有效位中的十九个1的二进制数(其在十进制下为524,287)。投影函数可以应用到经转换的double值。基于投影函数,可以将double值与int类型的范围进行比较。由于double值在该范围内,因此可以将double值的最低有效32个位确定为经转换的int值。经转换的int值可以是在最高有效位中包括十三个0、后面跟着最低有效位中的十九个1的二进制数(其在十进制下为524,287)。因此,投影函数的输出与初始的int值相同。
反过来,初始的double值可以是在最高有效位中包括三十个0和在最低有效位中包括三十四个1的二进制数(其在十进制下为17,179,869,184)。投影函数可以被应用到该初始的double值。基于投影函数,可以将double值与int类型的范围进行比较。由于该double值大于int类型的最大值,因此可以将int类型的最大值确定为经转换的int值。经转换的int值可以是最高有效位中的一个0后面跟着最低有效位中的三十一个1(其在十进制下为2,147,483,647)。嵌入函数可以被应用到该经转换的int值。基于嵌入函数,可以在int值的前面填充三十二个0。经转换的double值可以是在最高有效位中包括三十三个0、后面跟着最低有效位中的三十一个1的二进制数(其在十进制下为2,147,483,647)。嵌入函数的输出与初始的double值不同。因此,嵌入函数的输出与初始的double值不一样。嵌入函数的输出与初始的double值相关,因为(a)初始的double值超过了int类型的最大值,(b)嵌入函数的输出是int类型的最大值。
在实施例中,转换函数将特定类型集合的值集合转换为另一类型集合的另一个值集合。转换函数的输入中的值的数量可以与转换函数的输出中的值的数量相同或不同。作为示例,转换函数可以将(a)int值转换为(b)double值和String值。如果int值是正数,则可以在该int值前面填充三十二个0以获得经转换的double值。如果int值是负数,则可以在该int值前面填充三十二个1以获得经转换的double值。附加地,转换函数可以将String值设置为null(空)。转换函数的输出包括经转换的double值和被设置为null的String值两者。
在实施例中,可以使用一系列转换函数将一种类型的值转换为另一种类型的值。如上所述,迁移成员可以与三个或更多个版本相关联。一个转换函数可以在两个特定版本之间进行转换。另一个转换函数可以在两个其它版本之间进行转换。两个转换函数可以被链接在一起。作为示例,迁移成员可以是命名为fd的字段。与该迁移成员相关联的版本可以是:int fd;Date fd;NewDate fd。第一转换函数可以将int值转换为Date值。第二转换函数可以将Date值转换为NewDate值。为了将特定的int值转换为NewDate值,可以将第一转换函数应用到特定的int值,并且可以将第二转换函数应用到第一转换函数的结果。因此,第一转换函数和第二转换函数被链接在一起,以将int值转换为NewDate值。
图6示出根据一个或多个实施例的子类型的示例。如图所示,子类型602包括(一个或多个)继承字段606、(一个或多个)附加字段608、(一个或多个)继承方法614、(一个或多个)覆盖方法616和/或(一个或多个)附加方法618。在一个或多个实施例中,子类型602可以包括比图6中示出的组成部分更多或更少的组成部分。
在一个或多个实施例中,子类型602是从另一个类型导出的类型。该另一个类型可以被称为“超类型”。子类型602继承来自超类型的成员。下面参考继承字段606和继承方法614进一步描述继承。
在一个或多个实施例中,继承字段606是由于被包括在超类型中而被包括在子类型602中的字段。子类型602中的继承字段606与和超类型中的字段相同的字段名称和字段类型相关联。子类型602的源代码可以包括但不一定包括显式地声明继承字段606的代码。
在一个或多个实施例中,附加字段606是被包括在子类型602中但未被包括在超类型中的字段。子类型602的源代码包括显式地声明附加字段606的代码。
作为示例,定义特定超类型的源代码可以包括字段parent_fd。定义特定超类型的子类型的源代码可以包括字段child_fd。定义子类型的源代码不包括对字段parent_fd的任何引用。源代码集合可以包括子类型的对象的声明。由源代码集合声明的对象可以与parent_fd和child_fd两者相关联。
在一个或多个实施例中,继承方法614是由于被包括在超类型中而被包括在子类型602中的方法。子类型602中的继承方法614与和超类型中的方法相同的方法名称、(一个或多个)参数类型以及返回类型相关联。子类型602中的继承方法614与和超类型中的方法相同的方法主体相关联。子类型602的源代码可以包括但不一定包括显式地声明继承方法614的代码。
在一个或多个实施例中,覆盖方法616是子类型602中的覆盖超类型中的方法的方法。子类型602中的覆盖方法616与和超类型中的方法相同的方法名称、(一个或多个)参数类型以及返回类型相关联。然而,子类型602中的继承方法614与和超类型中的方法不同的方法主体相关联。子类型602的源代码包括显式地声明覆盖方法616的代码。子类型602的源代码定义覆盖方法616的方法主体。子类型602的源代码可以包括指示覆盖方法616旨在对超类型的特定方法进行覆盖的注释。
在一个或多个实施例中,附加方法618是被包括在子类型602中但不被包括在超类型中的方法。子类型602的源代码包括显式地声明附加方法618的代码。
作为示例,超类型可以是BankAccount(银行账户)。定义超类型的源代码可以包括方法lastAccessDate(上次访问日期)和creationDate(创建日期)。方法lastAccessDate可以被配置为返回银行账户的最后访问日期。方法creationDate可以被配置为返回银行账户的创建日期。
此外,BankAccount的子类型可以是HighSecurityAccount(高安全性账户)。定义子类型的源代码可以包括方法lastAccessDate和changePass(更改密码)。在子类型中,方法lastAccessDate可以被注释以给出覆盖超类型中的方法lastAccessDate的信号。子类型中的方法lastAccessDate可以被配置为在返回银行账户的最后访问日期之前检查请求者的凭证。方法changePass可以被配置为更改银行账户的密码。定义子类型的源代码不包括对方法creationDate的任何引用。
BankAccount和HighSecurityAccount的示例代码可以被编写为如下:
继续该示例,源代码集合可以包括子类型的对象的声明。用于声明对象的示例代码可以被编写为如下:
对象myaccount(我的账户)可以与creationDate、changePass和lastAccessDate相关联。使用该对象调用的lastAccessDate的版本可以是被包括在子类型HighSecurityAccount中的版本。被调用的lastAccessDate的版本可以是被配置为在返回银行账户的最后访问日期之前检查请求者的凭证的版本。
在实施例中,子类型中的方法覆盖超类型中的迁移方法。作为示例,超类型可以是BankAccount。定义超类型的源代码可以包括与方法名称lastAccessDate相关联的迁移方法。超类型也可以被称为“经更新的类型”。
此外,BankAccount的子类型可以是HighSecurityAccount。定义子类型的源代码可以包括方法lastAccessDate。在子类型中,方法lastAccessDate可以被注释以给出覆盖超类型中的迁移方法lastAccessDate的信号。子类型中的方法lastAccessDate可以被配置为在返回银行账户的最后访问日期之前检查请求者的凭证。
BankAccount和HighSecurityAccount的示例代码可以被编写为如下:
在这个示例中,子类型中的方法lastAccessDate和超类型中的迁移方法lastAccessDate的一个版本与同一个方法描述符(即,方法名称、(一个或多个)参数类型和返回类型)相关联。子类型中的方法lastAccessDate可以被称为覆盖经更新的类型中的迁移方法。
4.编译经更新的类型
图7示出根据一个或多个实施例的用于编译包括迁移方法的经更新的类型的一组操作。图7中示出的一个或多个操作可以被一起修改、重新布置或省略。因此,图7中示出的操作的特定顺序不应该被解释为限制一个或多个实施例的范围。
一个或多个实施例包括在源文件中识别包括迁移方法的多个版本的经更新的类型(操作702)。识别经更新的类型可以作为编译经更新的类型的过程的一部分来执行。
在实施例中,经更新的类型包括迁移字段的多个版本,每个版本与相同字段名称相关联但与不同字段类型相关联,如以上参考图5中的字段506所解释的那样。附加地或替代地,经更新的类型包括迁移方法的多个版本,每个版本与相同方法名称相关联但与不同参数类型和/或不同返回类型相关联,如以上参考图5中的方法514所解释的那样。
一个或多个实施例包括识别迁移方法的版本之间的一个或多个迁移关系(操作704)。迁移关系是基于与迁移方法的一个或多个版本相关联的一个或多个迁移标签来识别的。迁移标签指示生成迁移方法的版本的顺序。附加地或替代地,迁移关系是从单独的文件和/或数据库中识别的。
一个或多个实施例包括确定迁移是否有效(操作706)。
在实施例中,如果迁移方法的版本与禁止迁移的安全设置相关联,则迁移可能是无效的。例如,迁移方法的一个版本可能被标记有“不可迁移”标签。
在实施例中,如果迁移方法的不同版本与冲突的迁移关系相关联,则迁移可能是无效的。作为示例,经更新的类型可以包括具有相同方法名称md的两个方法。第一md方法可以与返回类型Date相关联。第二md方法可以与返回类型NewDate相关联。第二md方法可以与指示第二md方法是迁移自第一md方法的迁移标签相关联。同时,第一md方法可以与指示第一md方法是迁移自第二md方法的迁移标签相关联。这两个迁移标签指示冲突的迁移关系。该迁移是无效的。
如果迁移是无效的,则返回错误(操作708)。源文件没有被成功地编译。
一个或多个实施例包括识别转换函数的一个或多个对(操作710)。这些转换函数对可以被用于在迁移方法的不同版本之间进行转换。对转换函数的引用是从包括经更新的类型的源文件中识别的。作为示例,对转换函数的引用可以从与迁移方法的一个版本相关联的迁移标签中识别。基于对转换函数的引用,转换函数可以从源文件本身或不同文件中被识别。
一个或多个实施例包括在类文件中存储与迁移方法的版本对应的一组方法结构(操作712)。
在实施例中,经更新的类型包括多个字段,每个字段与相同的字段名称相关联。该多个字段是迁移字段的不同版本。编译与相同字段名称相关联的多个字段不会导致生成错误。相反,与迁移字段的版本对应的一组字段结构被存储在经编译的类文件中。
在实施例中,经更新的类型包括多个方法,每个方法与相同的方法名称相关联但与不同的参数类型和/或返回类型相关联。该多个方法是迁移方法的不同版本。与迁移方法的版本对应的一组方法结构被存储在经编译的类文件中。作为示例,经更新的类型可以包括与相同方法签名相关联的多个方法。术语“方法签名”是指(a)方法的方法名称,以及(b)与方法相关联的参数类型集合。方法可以与不同的返回类型相关联。这些方法是迁移方法的不同版本。编译与相同方法签名相关联的多个方法不会导致生成错误。相反,与迁移方法的版本对应的一组方法结构可以被存储在经编译的类文件中。
一个或多个实施例包括在类文件中存储迁移关系(操作714)。迁移关系可以作为迁移标签被存储在类文件中。附加地或替代地,迁移关系可以作为版本列表被存储在类文件中。附加地或替代地,可以使用其它格式来存储迁移关系。
一个或多个实施例包括在类文件中存储对转换函数对的引用(操作716)。对转换函数对的引用可以被存储在类文件的常量池表中。附加地或替代地,可以使用其它格式来存储对转换函数对的引用。
在实施例中,转换函数本身可以被存储在类文件中。在另一个实施例中,转换函数被存储在单独的文件和/或数据库中。
5.覆盖迁移方法
图8A-图8B示出根据一个或多个实施例的用于调用覆盖经更新的类型中的迁移方法的特定方法的一组操作。迁移方法的不同版本与不同的参数类型集合相关联。图8A-图8B中示出的一个或多个操作可以被一起修改、重新布置或省略。因此,图8A-图8B中示出的操作的特定顺序不应该被解释为限制一个或多个实施例的范围。
如下面进一步描述的,使用(a)特定方法名称和(b)特定参数类型集合来调用与子类型对应的方法。子类型包括与该特定方法名称相关联但与不同的参数类型集合相关联的方法。同时,超类型是包括迁移方法的经更新的类型。迁移方法的一个版本与该特定方法名称以及相同的特定参数类型集合相关联。生成新方法,以对参数类型进行转换以输入到子类型中的方法。
一个或多个实施例包括在类文件中识别使用变元集合来调用特定方法的指令(操作802),其中该变元集合与特定类型集合相关联。识别类文件中的指令可以作为执行该类文件的过程的一部分来执行。在实施例中,这些指令是从主(main)方法的主体中识别的。主方法是由运行时环境初始地调用的方法。在另一个实施例中,这些指令是从主方法调用的另一个方法的主体中识别的。这些指令识别(a)特定方法的方法名称、(b)变元集合、以及(c)与该变元集合相关联的特定类型集合。
示例代码可以被编写为如下:
示例代码可以被编译成字节码,该字节码可以被存储在类文件中。使用变元集合调用特定方法的指令包括与行Date dt=myaccount.lastAccessDate(myarg)对应的字节码。与行Date dt=myaccount.lastAccessDate(myarg)对应的字节码可以包括例如加载指令和调用指令。基于行Date dt=myaccount.lastAccessDate(myarg),特定类型long的变元被加载到操作数栈上。此外,使用加载值作为变元来执行与对象myaccount对应的特定方法lastAccessDate。因此,指令(a)将lastAccessDate识别为被调用的特定方法,(b)将myarg识别为变元集合,以及(c)将long识别为与该变元集合相关联的特定类型集合。
一个或多个实施例包括识别包括特定方法的子类型,其中该特定方法与方法名称和参数类型集合相关联(操作804)。包括特定方法的子类型是基于与该特定方法对应的对象的声明而识别的。对象的声明指示与对象相关联的类型(其可以是子类型)。发起用于将子类型加载到运行时环境中的过程。
参考以上示例代码,特定方法lastAccessDate对应于对象myaccount。myaccount的声明是行HighSecurityAccount myaccount=new HighSecurityAccount()。基于myaccount的声明,myaccount的类型被确定为HighSecurityAccount。HighSecurityAccount是包括方法lastAccessDate的子类型。
特定方法的定义是根据子类型确定的。特定方法的定义指示方法名称和与该特定方法相关联的参数类型集合。特定方法的定义还包括该特定方法的方法主体。
作为示例,子类型HighSecurityAccount可以包括以下代码:
示例代码可以被编译成字节码,该字节码可以被存储在类文件中。特定方法由与Date lastAccessDate(int arg)及其方法主体对应的字节码定义。方法主体可以包括在返回账户的最后访问日期之前检查请求者的凭证的指令。基于行Date lastAccessDate(intarg),与该特定方法相关联的参数类型集合是int。
一个或多个实施例包括确定超类型包括与相同方法名称相关联的迁移方法(操作806)。超类型是基于子类型的定义而被识别的。子类型的定义指示该子类型的超类型。作为示例,行class HighSecurityAccount extends BankAccount指示BankAccount是HighSecurityAccount的超类型。
如果超类型尚未被加载,则将超类型加载到运行时环境的按类区域中。
在超类型中识别与子类型中的特定方法的相同方法名称相关联的方法集合。该方法集合是超类型中的迁移方法的不同版本。由于超类型包括迁移方法,因此超类型也可以被称为“经更新的类型”。
参考以上示例代码,子类型可以是HighSecurityAccount,它包括方法lastAccessDate。HighSecurityAccount的超类型可以是BankAccount。BankAccount可以是包括与相同方法名称lastAccessDate相关联的迁移方法的经更新的类型。BankAccount可以包括以下代码:
一个或多个实施例包括识别迁移方法的多个版本,每个版本与不同的参数类型集合相关联(操作808)。迁移方法的多个版本是从超类型中识别的。迁移方法的每个版本与相同的方法名称相关联但与不同的参数类型集合和/或不同的返回类型相关联。
参考以上示例代码,BankAccount包括与方法名称lastAccessDate相关联的迁移方法的多个版本。一个版本对应于行Date lastAccessDate(int arg)。这个版本与参数类型集合(int)相关联。另一个版本对应于行Date lastAccessDate(long arg)。这个版本与参数类型集合(long)相关联。迁移方法的这些版本是从超类型BankAccount中识别的。
在实施例中,确定子类型中的特定方法是否是超类型中的迁移方法的有效覆盖。如果特定方法的方法描述符与迁移方法的一个版本的方法描述符相同,则覆盖是有效的。如果特定方法的方法描述符与迁移方法的任何版本的方法描述符都不同,则覆盖不是有效的。如果覆盖不是有效的,则生成错误。
在实施例中,仅当子类型中的特定方法与指示特定方法覆盖超类型的方法的注释相关联时,才执行覆盖是否有效的确定。在另一个实施例中,无论在子类型中的特定方法是否与注释相关联,都执行覆盖是否有效的确定。
参考以上示例代码,子类型HighSecurityAccount包括Date lastAccessDate(intarg)。超类型BankAccount包括Date lastAccessDate(int arg)和Date lastAccessDate(long arg)。由于子类型中的lastAccessDate的方法描述符与超类型中的lastAccessDate的一个版本的方法描述符相同,因此覆盖可以被确定为有效。
在实施例中,识别迁移方法的版本之间的迁移关系。迁移方法的版本之间的迁移关系作为经更新的类型的一部分被存储。迁移关系是从经更新的类型中被识别的。附加地或替代地,迁移关系是基于作为经更新的类型的一部分被存储的引用来识别的。基于迁移关系,确定生成迁移方法的版本的顺序。确定迁移方法的当前版本。
一个或多个实施例包括确定与变元集合相关联的特定类型集合是否与和子类型中的特定方法相关联的参数类型集合相同(操作810)。在操作802处识别了与变元集合相关联的特定类型集合。在操作804处识别了与子类型中的特定方法相关联的参数类型集合。与变元集合相关联的特定类型集合与和子类型中的特定方法相关联的参数类型集合进行比较。
如果与变元集合相关联的特定类型集合与和子类型中的特定方法相关联的参数类型集合相同,则该特定方法被存储在运行时环境中(操作822)。该特定方法可以作为字节码被存储在运行时环境中与子类型相关联的按类区域中。具体而言,该特定方法可以被存储在运行时环境中,而不需要识别和/或应用用于转换变元集合的任何转换函数。
参考以上示例代码,子类型HighSecurityAccount包括Date lastAccessDate(intarg)。由HighSecurityAccount的源代码显式定义的方法Date lastAccessDate(int arg)可以被存储在与子类型HighSecurityAccount相关联的按类区域中。存储在运行时环境中的方法Date lastAccessDate(int arg)被配置为在返回帐户的最后访问日期之前检查请求者的凭证。
一个或多个实施例包括确定与变元集合相关联的特定类型集合是否与和超类型中的迁移方法的任何版本相关联的参数类型集合相同(操作812)。在操作802处识别了与变元集合相关联的特定类型集合。在操作808处识别了与迁移方法的版本相关联的参数类型集合。与变元集合相关联的特定类型集合与和迁移方法的版本相关联的每个参数类型集合进行比较。
如果与变元集合相关联的特定类型集合与和超类型中的迁移方法的任何版本相关联的参数类型集合都不同,则返回错误(操作814)。
一个或多个实施例包括识别将(a)特定类型集合的值转换为(b)与子类型中的特定方法相关联的参数类型集合的值的一个或多个转换函数(操作816)。可以从超类型(即,经更新的类型)、子类型、在操作802处识别出的类文件、单独的文件和/或单独的数据库中识别转换函数。作为示例,经更新的类型可以包括迁移方法和与该迁移方法相关联的迁移标签。迁移标签可以识别对转换函数的引用。引用可以是对经更新的类型中的常量池条目的索引。转换函数可以基于该索引从常量池表中被识别。
在实施例中,对于迁移方法的每个参数使用单独的转换函数。例如,迁移方法可以具有参数arg1和arg2。迁移方法的一个版本可以指定arg1是int类型,并且arg2是char类型。迁移方法的另一个版本可以指定arg1是double类型,并且arg2是long类型。两个单独的转换函数可以分别与arg1和arg2相关联。具体而言,与arg1相关联的第一转换函数可以将int值转换为double值。与arg2相关联的第二转换函数可以将char值转换为long值。
在实施例中,单个转换函数用于迁移方法的参数集合。作为示例,迁移方法可以具有参数arg1和arg2。迁移方法的一个版本可以指定arg1是int类型,并且arg2是char类型。迁移方法的另一个版本可以指定arg1是double类型,并且arg2是long类型。单个转换函数可以将包括int值和char值的值集合转换为包括double值和long值的另一个值集合。
一个或多个实施例包括生成新方法(操作818)。新方法包括用于以下操作的指令:(a)应用转换函数以将(i)变元集合转换为(ii)与子类型中的特定方法相关联的参数类型集合的值,以及(b)使用经转换的值作为变元来调用子类型中的特定方法。
新方法包括用于以下操作的指令:应用转换函数以将(i)变元集合转换为(ii)与特定方法相关联的参数类型集合的值。
在实施例中,如上所述,对于迁移方法的每个参数使用单独的转换函数。因此,单独的转换函数被应用到在操作802处识别出的指令中指定的变元集合中的每个变元。从每个转换函数输出的经转换的值作为变元被输入到特定方法。
在实施例中,如上所述,单个转换函数被用于迁移方法的参数集合。因此,单个转换函数被应用到在操作802处识别出的指令中指定的变元集合。从单个转换函数输出的经转换的值作为参数被输入到迁移方法的当前版本。
如以上参考图5的转换函数524所描述的,可以使用单个转换函数来将(i)变元集合转换为(ii)与特定方法相关联的参数类型集合的值。可替代地,如以上参考图5的转换函数524所描述的,多个转换函数可以被链接在一起以将(i)变元集合转换为(ii)与特定方法相关联的参数类型集合的值。
此外,新方法包括用于使用经转换的值作为变元来调用特定方法的指令。使用来自转换函数的输出作为变元来调用特定方法。
参考以上示例代码,子类型HighSecurityAccount包括Date lastAccessDate(intarg)。子类型中的lastAccessDate方法被配置为在返回账户的最后访问日期之前检查请求者的凭证。超类型BankAccount包括Date lastAccessDate(int arg)和DatelastAccessDate(long arg)。超类型中的lastAccessDate的版本被配置为返回账户的最后访问日期。超类型中的lastAccessDate版本不检查请求者的凭证。
基于使用long值作为变元在HighSecurityAccount的实例上调用lastAccessDate,生成新方法。该新方法与子类型HighSecurityAccount相关联。新方法的方法描述符是Date lastAccessDate(long arg)。新方法可以以与以下代码类似的方式表现:
行int convertarg=ParameterConversionFunction(arg)对应于将(i)变元集合转换为(ii)与特定方法相关联的参数类型集合的值的指令。参数集合arg被输入到转换函数ParameterConversionFunction。输出是int值convertedarg。
此外,行Date retval=this.lastAccessDate(convertedarg)对应于调用子类型中的特定方法(即,Date lastAccessDate(int arg))的指令。由于(a)到lastAccessDate的变元是int类型的convertedarg,并且(b)子类型中的特定方法与参数类型int相关联,因此该特定方法被调用。被调用的特定方法被配置为在返回最后访问日期之前检查请求者的凭证。
在这个示例中,在子类型HighSecurityAccount中显式定义的方法DatelastAccessDate(int arg)覆盖超类型BankAccount中包括的方法Date lastAccessDate(int arg)。为子类型HighSecurityAccount生成的新方法Date lastAccessDate(longarg)覆盖超类型BankAccount中包括的方法Date lastAccessDate(long arg)。新方法DatelastAccessDate(long arg)未在子类型HighSecurityAccount的源代码中显式定义。
一个或多个实施例包括将新方法存储在运行时环境中(操作820)。新方法可以作为字节码存储在运行时环境中与子类型相关联的按类区域中。可选地,在子类型中显式定义的特定方法也可以被存储在运行时环境中。
一个或多个实施例包括执行从在操作802处识别出的调用特定方法的指令中解析的方法(操作824)。如上所述,调用特定方法的指令在操作802处被识别出。在实施例中,这些指令包括对特定方法的符号引用。在类文件的链接期间,对特定方法的符号引用被解析为直接引用。如果执行了操作820,则对特定方法的符号引用被解析为对在操作820处存储在运行时环境中的新方法的直接引用。可替代地,如果执行了操作822,则对特定方法的符号引用被解析为对在操作822处存储在运行时环境中的特定方法的直接引用。运行时常量池表被更新以反映(a)对特定方法的符号引用到(b)对存储在运行时环境中的新方法或特定方法的直接引用的解析。
在类文件的执行期间,在操作802处识别出的指令中指定的变元集合被加载到操作数栈上。引用要被执行的下一条指令的程序计数器(PC)被移动到解析后的直接引用。基于PC,执行新方法或者执行特定方法。此外,操作数栈上的加载值被用作执行方法的变元。
可以使用用于识别与要执行的方法相关联的存储器位置的附加方法和/或替代方法。可以使用用于输入和/或加载方法的变元集合的附加方法和/或替代方法。
在实施例中,在随后调用特定方法时,使用与在操作802处识别出的特定类型集合相同的特定类型集合相关联的变元集合,不必重复用于生成新方法的操作。子类型被确定为先前被加载。对特定方法的符号引用被解析为对先前生成并存储在运行时环境中的新方法的直接引用。基于该解析后的直接引用,执行新方法。
如下面进一步描述的,使用(a)特定方法名称和(b)特定返回类型来调用与子类型对应的方法。子类型包括与特定方法名称相关联但与不同返回类型相关联的方法。同时,超类型是包括迁移方法的经更新的类型。迁移方法的一个版本是与特定方法名称以及相同的特定返回类型相关联的方法。生成新方法以对从子类型中的方法输出的返回类型进行转换。
图9A-图9B示出根据一个或多个实施例的用于调用覆盖经更新的类型中的迁移方法的特定方法的一组操作。迁移方法的不同版本与不同的返回类型相关联。图9A-图9B中示出的一个或多个操作可以被一起修改、重新布置或省略。因此,图9A-图9B中示出的操作的特定顺序不应该被解释为限制一个或多个实施例的范围。
一个或多个实施例包括在类文件中识别调用特定方法并从特定方法返回值作为特定类型的值的指令(操作902)。参考操作802在上面包括了与识别调用特定方法的指令有关的进一步描述。这些指令识别(a)特定方法的方法名称,以及(b)与要从特定方法返回的值相关联的特定类型。
示例代码可以被编写为如下:
示例代码可以被编译成字节码,该字节码可以被存储在类文件中。调用特定方法并从特定方法返回值作为特定类型的值的指令包括对应于行NewDate dt=myaccount.lastAccessDate(myarg)的字节码。对应于行NewDate dt=myaccount.lastAccessDate(myarg)的字节码可以包括例如调用指令和存储指令。基于行NewDate dt=myaccount.lastAccessDate(myarg),执行与对象myaccount对应的特定方法lastAccessDate。从特定方法返回的值被存储为特定类型NewDate的值。因此,指令(a)将lastAccessDate识别为被调用的特定方法,以及(b)将NewDate识别为与要从特定方法返回的值相关联的特定类型。
一个或多个实施例包括识别包括特定方法的子类型,其中该特定方法与方法名称和返回类型相关联(操作904)。参考操作804在上面包括了与识别包括特定方法的子类型有关的进一步描述。
特定方法的定义是根据子类型来确定的。特定方法的定义指示方法名称和与特定方法关联的返回类型。特定方法的定义还包括特定方法的方法主体。
作为示例,子类型HighSecurityAccount可以包括以下代码:
示例代码可以被编译成字节码,该字节码可以被存储在类文件中。特定方法由与Date lastAccessDate(int arg)及其方法主体对应的字节码定义。方法主体可以包括在返回账户的最后访问日期之前检查请求者的凭证的指令。基于行Date lastAccessDate(intarg),与特定方法相关联的返回类型是Date。
一个或多个实施例包括确定超类型包括与相同方法名称相关联的迁移方法(操作906)。参考操作806在上面包括了与识别包括迁移方法的超类型有关的进一步描述。由于超类型包括迁移方法,因此超类型也可以被称为“经更新的类型”。
参考以上示例代码,子类型可以是HighSecurityAccount,其包括方法lastAccessDate。HighSecurityAccount的超类型可以是BankAccount。BankAccount可以是包括与相同方法名称lastAccessDate相关联的迁移方法的经更新的类型。BankAccount可以包括以下代码:
一个或多个实施例包括识别迁移方法的多个版本,每个版本与不同的返回类型相关联(操作908)。参考操作808在上面包括了与识别迁移方法的多个版本有关的进一步描述。迁移方法的每个版本与相同方法名称相关联但与不同的参数类型集合和/或不同的返回类型相关联。
参考以上示例代码,BankAccount包括与方法名称lastAccessDate相关联的迁移方法的多个版本。一个版本对应于行Date lastAccessDate(int arg)。这个版本与返回类型Date相关联。另一个版本对应于行NewDate lastAccessDate(int arg)。这个版本与返回类型NewDate相关联。迁移方法的版本是从超类型BankAccount中识别的。
一个或多个实施例包括确定在操作902处识别出的指令中指定的特定类型是否与和子类型中的特定方法相关联的返回类型相同(操作910)。在操作902处识别了与要从特定方法返回的值相关联的特定类型。在操作904处识别了与子类型中的特定方法相关联的返回类型。将与要从特定方法返回的值相关联的特定类型与和在子类型中的特定方法相关联的返回类型进行比较。
如果在操作902处识别出的指令中指定的特定类型与和子类型中的特定方法相关联的返回类型相同,则该特定方法被存储在运行时环境中(操作922)。参考操作822在上面包括了与在运行时环境中存储特定方法有关的进一步描述。
参考以上示例代码,子类型HighSecurityAccount包括Date lastAccessDate(intarg)。由HighSecurityAccount的源代码显式定义的方法Date lastAccessDate(int arg)可以被存储在与子类型HighSecurityAccount相关联的按类区域中。存储在运行时环境中的方法Date lastAccessDate(int arg)被配置为在返回帐户的最后访问日期之前检查请求者的凭证。
一个或多个实施例包括确定在操作902处识别出的指令中指定的特定类型是否与和超类型中的迁移方法的任何版本相关联的返回类型相同(操作912)。在操作902处识别了与要从特定方法返回的值相关联的特定类型。在操作908处识别了与迁移方法的版本相关联的返回类型。将与要从特定方法返回的值相关联的特定类型与和迁移方法的版本相关联的每个返回类型进行比较。
如果在操作902处识别出的指令中指定的特定类型与和超类型中的迁移方法的任何版本相关联的返回类型都不同,则返回错误(操作914)。
一个或多个实施例包括识别一个或多个转换函数,该一个或多个转换函数将(a)与子类型中的特定方法相关联的返回类型的值转换为(b)在操作902处识别出的指令中指定的特定类型的值(操作916)。参考操作816在上面描述了与识别转换函数有关的进一步描述。
一个或多个实施例包括生成新方法(操作918)。新方法包括用于以下操作的指令:(a)调用子类型中的特定方法,以及(b)应用转换函数以将(i)由特定方法返回的值转换为(ii)在操作902处识别出的指令中指定的特定类型的值。
新方法包括用于调用特定方法的指令。从特定方法返回的值作为临时值被存储。
此外,新方法包括用于以下操作的指令:应用转换函数以将(i)由特定方法返回的值(即,临时值)转换为(ii)特定类型的值。参考操作818在上面包括了与应用转换函数有关的进一步描述。
参考以上示例代码,子类型HighSecurityAccount包括Date lastAccessDate(intarg)。超类型BankAccount包括Date lastAccessDate(int arg)和NewDatelastAccessDate(int arg)。
基于在HighSecurityAccount的实例上调用lastAccessDate并从lastAccessDate返回NewDate值的指令,生成新方法。新方法与子类型HighSecurityAccount相关联。新方法的方法描述符是NewDate lastAccessDate(int arg)。新方法可以以与以下代码类似的方式表现:
行NewDate temp=this.lastAccessDate(arg)对应于调用子类型中的特定方法(即Date lastAccessDate(int arg))的指令。由于(a)要从lastAccessDate返回的值是Date类型的temp(临时值),并且(b)子类型中的特定方法与返回类型Date相关联,因此该特定方法被调用。被调用的特定方法被配置为在返回最后访问日期之前检查请求者的凭证。
此外,行NewDate retval=ReturnConversionFunction(temp)对应于将(i)由特定方法返回的值转换为(ii)特定类型的值的指令。由特定方法返回的值temp被输入到转换函数ReturnConversionFunction。输出是NewDate值retval。该NewDate值retval从新方法返回。
在这个示例中,在子类型HighSecurityAccount中显式定义的方法DatelastAccessDate(int arg)覆盖超类型BankAccount中包括的方法Date lastAccessDate(int arg)。为子类型HighSecurityAccount生成的新方法NewDate lastAccessDate(intarg)覆盖超类型BankAccount中包括的方法NewDate lastAccessDate(int arg)。新方法NewDate lastAccessDate(int arg)没有在子类型HighSecurityAccount的源代码中被显式定义。
一个或多个实施例包括将新方法存储在运行时环境中(操作920)。参考操作820在上面包括了与将新方法存储在运行时环境中有关的进一步描述。
一个或多个实施例包括执行从在操作902处识别出的调用特定方法的指令中解析的方法(操作924)。如上所述,在操作902处识别调用特定方法的指令。在实施例中,这些指令包括对特定方法的符号引用。在类文件的链接期间,对特定方法的符号引用被解析为直接引用。如果执行了操作920,则对特定方法的符号引用被解析为对在操作920处存储在运行时环境中的新方法的直接引用。可替代地,如果执行了操作922,则对特定方法的符号引用被解析为对在操作922处存储在运行时环境中的特定方法的直接引用。运行时常量池表被更新以反映(a)对特定方法的符号引用到(b)对存储在运行时环境中的新方法或特定方法的直接引用的解析。
在类文件的执行期间,引用要执行的下一条指令的程序计数器(PC)被移动到解析后的直接引用。基于PC,执行新方法或者执行特定方法。从所执行的方法返回的值是在操作902处识别出的指令中指定的特定类型的值。
可以使用用于识别与要执行的方法相关联的存储器位置的附加方法和/或替代方法。
在实施例中,在随后执行从特定方法返回值(其中该值与在操作902处识别出的类型相同的特定类型相关联)的一个或多个指令时,不必重复用于生成新方法的操作。子类型被确定为先前被加载。对特定方法的符号引用被解析为对先前生成并存储在运行时环境中的新方法的直接引用。基于解析后的直接引用,执行新方法。
在一个或多个实施例中,可以调用覆盖经更新的类型中的迁移方法的特定方法。迁移方法的不同版本与不同的参数类型集合以及不同的返回类型相关联。图9A-图9B中示出的操作和图10A-图10B中的操作被组合以便执行特定方法。具体而言,基于特定方法的调用,生成新方法并将其存储在运行时环境中。该新方法包括用于转换用于调用特定方法的变元集合和用于转换从特定方法返回的值的指令。
6.其它方面;扩展
实施例针对具有包括硬件处理器并且被配置为执行本文所述和/或在以下权利要求中任何一项中记载的任何操作的一个或多个设备的系统。
在实施例中,非瞬态计算机可读存储介质包括指令,所述指令当由一个或多个硬件处理器执行时,使得执行本文所述和/或在权利要求中记载的任何一项所述的任何操作。
本文所述的特征和功能的任何组合可以根据一个或多个实施例来使用。在前面的说明书中,各个实施例已经参考许多具体细节进行了描述,这些具体细节可以因实现方式而异。因此,说明书和附图应当在说明性而不是限制性的意义上加以考虑。本发明范围的唯一且排他指示,以及申请人预期要作为本发明范围的是由本申请发布的权利要求集合的字面范围和等效范围,这是以这些权利要求发布的具体形式,包括任何后续的校正。
7.硬件概述
根据一个实施例,本文描述的技术由一个或多个专用计算设备实现。专用计算设备可以是硬连线的以执行所述技术,或者可以包括诸如被永久性地编程以执行所述技术的一个或多个专用集成电路(ASIC)或现场可编程门阵列(FPGA)的数字电子设备,或者可以包括编程为按照固件、存储器、其它存储装置或者其组合中的程序指令执行所述技术的一个或多个通用硬件处理器。这种专用计算设备还可以将定制的硬连线逻辑、ASIC或FPGA与定制的编程组合来实现所述技术。专用计算设备可以是台式计算机系统、便携式计算机系统、手持式设备、联网设备或者结合硬连线和/或程序逻辑来实现所述技术的任何其它设备。
例如,图10是示出可以在其上实现本发明的实施例的计算机系统1000的框图。计算机系统1000包括用于传送信息的总线1002或其它通信机制,以及与总线1002耦合的用于处理信息的硬件处理器1004。硬件处理器1004可以是例如通用微处理器。
计算机系统1000还包括耦合到总线1002的用于存储信息和要由处理器1004执行的指令的主存储器1006,诸如随机存取存储器(RAM)或其它动态存储设备。主存储器1006也可以用于在要由处理器1004执行的指令的执行期间存储临时变量或其它中间信息。当这些指令被存储在处理器1004可访问的非瞬态存储介质中时,它们使计算机系统1000成为被定制为执行指令中指定的操作的专用机器。
计算机系统1000还包括耦合到总线1002的用于存储静态信息和用于处理器1004的指令的只读存储器(ROM)1008或其它静态存储设备。提供了诸如磁盘或光盘的存储设备1010,并且存储设备1010被耦合到总线1002以用于存储信息和指令。
计算机系统1000可以经由总线1002耦合到显示器1012(诸如阴极射线管(CRT)),以用于向计算机用户显示信息。包括字母数字键和其它键的输入设备1014耦合到总线1002,以用于向处理器1004传送信息和命令选择。另一种类型的用户输入设备是光标控件1016,诸如鼠标、轨迹球或光标方向键,用于向处理器1004传送方向信息和命令选择并且用于控制显示器1012上的光标移动。这种输入设备通常具有在两个轴(第一轴(例如,x)和第二轴(例如,y))上的两个自由度,这允许设备指定平面中的位置。
计算机系统1000可以使用定制的硬连线逻辑、一个或多个ASIC或FPGA、固件和/或程序逻辑来实现本文描述的技术,这些定制的硬连线逻辑、一个或多个ASIC或FPGA、固件和/或程序逻辑与计算机系统组合使计算机系统1000成为或将计算机系统1000编程为专用机器。根据一个实施例,本文的技术由计算机系统1000响应于处理器1004执行包含在主存储器1006中的一个或多个指令的一个或多个序列而执行。这些指令可以从另一个存储介质(诸如存储设备1010)读取到主存储器1006中。包含在主存储器1006中的指令序列的执行使处理器1004执行本文描述的处理步骤。在替代实施例中,可以使用硬连线电路系统代替软件指令或与软件指令组合使用。
如本文使用的术语“存储介质”是指存储使机器以特定方式操作的数据和/或指令的任何非瞬态介质。这种存储介质可以包括非易失性介质和/或易失性介质。非易失性介质包括例如光盘或磁盘,诸如存储设备1010。易失性介质包括动态存储器,诸如主存储器1006。存储介质的常见形式包括例如软盘、柔性盘、硬盘、固态驱动器、磁带或任何其它磁性数据存储介质、CD-ROM、任何其它光学数据存储介质、具有孔图案的任何物理介质、RAM、PROM和EPROM、FLASH-EPROM、NVRAM、任何其它存储芯片或盒带、内容可寻址存储器(CAM)以及三态内容可寻址存储器(TCAM)。
存储介质与传输介质不同,但可以与传输介质结合使用。传输介质参与在存储介质之间传输信息。例如,传输介质包括同轴线缆、铜线和光纤,包括包含总线1002的线。传输介质还可以采取声波或光波的形式,诸如在无线电波和红外数据通信期间生成的那些波。
将一个或多个指令的一个或多个序列携带到处理器1004以供执行可能涉及各种形式的介质。例如,指令初始地可以被携带在远程计算机的磁盘或固态驱动器上。远程计算机可以将指令加载到其动态存储器中并且使用调制解调器经电话线发送指令。计算机系统1000本地的调制解调器可以在电话线上接收数据并使用红外发射器将数据转换为红外信号。红外检测器可以接收红外信号中携带的数据,并且适当的电路系统可以将数据放置在总线1002上。总线1002将数据携带到主存储器1006,处理器1004从主存储器1006取回并执行指令。由主存储器1006接收到的指令可以可选地在被处理器1004执行之前或之后存储在存储设备1010上。
计算机系统1000还包括耦合到总线1002的通信接口1018。通信接口1018提供耦合到网络链路1020的双向数据通信,其中网络链路1020连接到本地网络1022。例如,通信接口1018可以是向对应类型的电话线提供数据通信连接的综合业务数字网(ISDN)卡、线缆调制解调器、卫星调制解调器或调制解调器。作为另一个示例,通信接口1018可以是提供到兼容的局域网(LAN)的数据通信连接的LAN卡。也可以实现无线链路。在任何这样的实现方式中,通信接口1018发送和接收携带表示各种类型信息的数字数据流的电信号、电磁信号或光学信号。
网络链路1020通常通过一个或多个网络向其它数据设备提供数据通信。例如,网络链路1020可以通过本地网络1022提供到主机计算机1024或到由互联网服务提供商(ISP)1026运营的数据装备的连接。ISP 1026继而通过现在通常称为“互联网”1028的全球范围的分组数据通信网络提供数据通信服务。本地网络1022和互联网1028二者使用携带数字数据流的电信号、电磁信号或光学信号。通过各种网络的信号以及在网络链路1020上并且通过通信接口1018的信号是传输介质的示例形式,其中信号将数字数据携带到计算机系统1000和携带来自计算机系统1000的数字数据。
计算机系统1000可以通过(一个或多个)网络、网络链路1020和通信接口1018发送消息和接收数据,包括程序代码。在互联网示例中,服务器1030可以通过互联网1028、ISP1026、本地网络1022和通信接口1018传输对应用程序的请求代码。
接收到的代码可以在其被接收到时由处理器1004执行,和/或存储在存储设备1010或其它非易失性存储器中以供以后执行。
在前面的说明书中,本发明的实施例已经参考许多具体细节进行了描述,这些具体细节可以因实现方式而异。因此,说明书和附图应当在说明性而不是限制性的意义上加以考虑。本发明范围的唯一且排他指示,以及申请人预期要作为本发明范围的是由本申请发布的权利要求集合的字面范围和等效范围,这是以这些权利要求产生的具体形式,包括任何后续的校正。
Claims (15)
1.一种包括指令的非瞬态计算机可读介质,所述指令当由一个或多个硬件处理器执行时,使得执行操作,所述操作包括:
识别一个或多个指令,所述一个或多个指令使用与特定类型集合对应的值作为变元来调用与特定对象对应的特定方法,其中所述特定方法位于子类型中并且由特定方法名称引用;
确定所述子类型包括:
与所述特定方法名称以及第一参数类型集合相关联的第一方法;
其中所述子类型不包括与所述特定方法名称以及第二参数类型集合相关联的任何方法;
确定所述子类型的超类型包括:
与所述特定方法名称以及第一参数类型集合相关联的第二方法;
与所述特定方法名称以及第二参数类型集合相关联的第三方法;
其中第二方法被迁移到了第三方法;
响应于确定所述特定类型集合与第二参数类型集合相同:
生成新方法,所述新方法包括:
应用转换函数以将与所述特定类型集合对应的值转换为与第一参数类型集合对应的值的指令;
使用与第一参数类型集合对应的值来调用第一方法的指令。
2.如权利要求1所述的介质,其中所述操作还包括以下中的至少一个:
将所述新方法存储在运行时环境中;以及
执行所述新方法。
3.如权利要求1所述的介质,其中所述操作还包括:
识别所述指令中的对所述特定方法的符号引用;以及
将所述符号引用解析为对所述新方法的直接引用。
4.如权利要求3所述的介质,其中所述操作还包括:
将(a)所述指令中的对所述特定方法的所述符号引用到(b)对所述新方法的直接引用的解析存储在运行时常量池表中。
5.如权利要求1所述的介质,其中所述新方法没有被包括在定义所述子类型的源代码集合中。
6.如权利要求1所述的介质,其中所述操作还包括:
基于迁移标签来识别所述转换函数,所述迁移标签与被包括在所述超类型中的第二方法和第三方法中的至少一个相关联。
7.如权利要求1所述的介质,其中:
调用所述特定方法的指令包括从所述特定方法返回第一值作为特定类型的第二值的指令;
在所述子类型中,第一方法还与第一返回类型相关联;
在所述超类型中,第二方法还与第一返回类型相关联;
在所述超类型中,第三方法还与第二返回类型相关联;
还响应于确定所述特定类型与第二返回类型相同,生成所述新方法;
所述新方法还包括:
从第一方法返回第三值的指令,其中第三值具有第一返回类型;
应用第二转换函数以将第三值转换为第二返回类型的第四值的指令;
返回第四值作为所述特定类型的第二值的指令。
8.一种方法,包括如权利要求1-7中任一项所述的操作;
其中所述方法由包括硬件处理器的至少一个设备执行。
9.一种系统,包括:
包括硬件处理器的至少一个设备;以及
所述系统被配置为执行包括如权利要求1-7中任一项所述的操作的操作。
10.一种包括指令的非瞬态计算机可读介质,所述指令当由一个或多个硬件处理器执行时,使得执行操作,所述操作包括:
识别从特定方法返回第一值作为特定类型的第二值的一个或多个指令,其中所述特定方法位于子类型中并且由特定方法名称引用;
确定所述子类型包括:
与所述特定方法名称以及第一返回类型相关联的第一方法;
其中所述子类型不包括与所述特定方法名称以及第二返回类型相关联的任何方法;
确定所述子类型的超类型包括:
与所述特定方法名称以及第一返回类型相关联的第二方法;
与所述特定方法名称以及第二返回类型相关联的第三方法;
其中第二方法被迁移到了第三方法;
响应于确定所述特定类型与第二返回类型相同:
生成新方法,所述新方法包括:
从第一方法返回第三值的指令,其中第三值具有第一返回类型;
应用转换函数以将第三值转换为第二返回类型的第四值的指令;
返回第四值作为所述特定类型的第二值的指令。
11.如权利要求10所述的介质,其中所述操作还包括以下中的至少一个:
将所述新方法存储在运行时环境中;以及
执行所述新方法。
12.如权利要求10所述的介质,其中所述操作还包括:
识别所述指令中的对所述特定方法的符号引用;以及
将所述符号引用解析为对所述新方法的直接引用。
13.如权利要求12所述的介质,其中所述操作还包括:
将(a)所述指令中的对所述特定方法的所述符号引用到(b)对所述新方法的直接引用的解析存储在运行时常量池表中。
14.如权利要求10所述的介质,其中所述新方法没有被包括在定义所述子类型的源代码集合中。
15.如权利要求10所述的介质,其中所述操作还包括:
基于迁移标签来识别所述转换函数,所述迁移标签与被包括在所述超类型中的第二方法和第三方法中的至少一个相关联。
Applications Claiming Priority (7)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US201662361087P | 2016-07-12 | 2016-07-12 | |
US62/361,087 | 2016-07-12 | ||
US15/426,312 | 2017-02-07 | ||
US15/426,312 US10908886B2 (en) | 2016-07-12 | 2017-02-07 | Accessing a migrated member in an updated type |
US15/426,839 | 2017-02-07 | ||
US15/426,839 US10635420B2 (en) | 2016-07-12 | 2017-02-07 | Overriding a migrated method in an updated type |
PCT/US2017/026544 WO2018013189A1 (en) | 2016-07-12 | 2017-04-07 | Overriding a migrated method of an updated type |
Publications (2)
Publication Number | Publication Date |
---|---|
CN107924326A true CN107924326A (zh) | 2018-04-17 |
CN107924326B CN107924326B (zh) | 2024-03-01 |
Family
ID=60940997
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201780002772.0A Active CN107924326B (zh) | 2016-07-12 | 2017-04-07 | 对经更新的类型的迁移方法进行覆盖 |
Country Status (4)
Country | Link |
---|---|
US (5) | US10908886B2 (zh) |
EP (1) | EP3350696B1 (zh) |
CN (1) | CN107924326B (zh) |
WO (1) | WO2018013189A1 (zh) |
Cited By (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110046004A (zh) * | 2019-03-29 | 2019-07-23 | 北京奇艺世纪科技有限公司 | 一种适配自动引用计数arc特性的方法、装置及电子设备 |
CN114003317A (zh) * | 2021-10-29 | 2022-02-01 | 北京达佳互联信息技术有限公司 | 内联实现方法及装置、电子设备、存储介质及程序产品 |
CN114787769A (zh) * | 2019-12-13 | 2022-07-22 | 倍福自动化有限公司 | 用于通过控制程序的程序状态的数据迁移对自动化系统的控制程序进行更新的方法 |
CN117312176A (zh) * | 2023-11-30 | 2023-12-29 | 深圳市楠菲微电子有限公司 | 一种基于uvm的芯片验证测试方法、系统及电子设备 |
Families Citing this family (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US10521200B2 (en) * | 2017-01-09 | 2019-12-31 | Oracle International Corporation | Unambiguous proxying of interface methods |
US10725763B1 (en) * | 2017-06-28 | 2020-07-28 | Amazon Technologies, Inc. | Update and rollback of configurations in a cloud-based architecture |
CN109408107B (zh) * | 2018-10-09 | 2022-06-21 | 深圳点猫科技有限公司 | 一种基于教育系统的提高检索速度的方法及电子设备 |
US11070377B1 (en) * | 2019-02-14 | 2021-07-20 | Bank Of America Corporation | Blended virtual machine approach for flexible production delivery of intelligent business workflow rules |
US11340938B2 (en) | 2019-09-25 | 2022-05-24 | International Business Machines Corporation | Increasing the performance of cross the frame live updates |
CN111208994B (zh) * | 2019-12-31 | 2023-05-30 | 西安翔腾微电子科技有限公司 | 计算机图形应用程序的执行方法、装置及电子设备 |
CN112287306B (zh) * | 2020-10-29 | 2024-04-26 | 中国银联股份有限公司 | 一种应用程序安装包的保护方法、装置及计算机可读存储介质 |
US11782774B2 (en) | 2021-03-19 | 2023-10-10 | Oracle International Corporation | Implementing optional specialization when compiling code |
Citations (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN1305609A (zh) * | 1998-06-16 | 2001-07-25 | 太阳微系统公司 | 实现参数化类型与现有非参数化库兼容的方法 |
CN1482540A (zh) * | 2002-08-02 | 2004-03-17 | ���µ�����ҵ��ʽ���� | 编译程序、编译程序装置和编译方法 |
CN102221994A (zh) * | 2010-04-19 | 2011-10-19 | 微软公司 | 用于改变回复力的中间语言支持 |
CN103927193A (zh) * | 2013-01-15 | 2014-07-16 | 中兴通讯股份有限公司 | Java应用程序函数迁移运行时的加载方法、服务端虚拟机 |
US20150370544A1 (en) * | 2014-06-18 | 2015-12-24 | Netapp, Inc. | Methods for facilitating persistent storage of in-memory databases and devices thereof |
Family Cites Families (25)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5732257A (en) * | 1995-09-13 | 1998-03-24 | Hewlett-Packard Co. | Object conversion method from a flat object space to a class structured space |
EP0937285B1 (en) | 1995-12-15 | 2003-07-09 | Z-Force Corporation | Method for constructing software components and systems as assemblies of independent parts |
US6064814A (en) * | 1997-11-13 | 2000-05-16 | Allen-Bradley Company, Llc | Automatically updated cross reference system having increased flexibility |
US7272815B1 (en) | 1999-05-17 | 2007-09-18 | Invensys Systems, Inc. | Methods and apparatus for control configuration with versioning, security, composite blocks, edit selection, object swapping, formulaic values and other aspects |
US6802059B1 (en) * | 1999-08-02 | 2004-10-05 | Ricoh Corporation | Transforming character strings that are contained in a unit of computer program code |
US6256773B1 (en) * | 1999-08-31 | 2001-07-03 | Accenture Llp | System, method and article of manufacture for configuration management in a development architecture framework |
US7613993B1 (en) * | 2000-01-21 | 2009-11-03 | International Business Machines Corporation | Prerequisite checking in a system for creating compilations of content |
US6738968B1 (en) * | 2000-07-10 | 2004-05-18 | Microsoft Corporation | Unified data type system and method |
US20020138819A1 (en) * | 2000-12-19 | 2002-09-26 | Hills Theodore S. | Computer programming language to describe and encapsulate a computer as a set of classes and objects |
US7926032B2 (en) | 2002-07-18 | 2011-04-12 | International Business Machines Corporation | Two meta-level modeling approach for mapping typed data |
US20050138606A1 (en) * | 2003-12-17 | 2005-06-23 | Sujit Basu | System and method for code migration |
US7730450B2 (en) * | 2004-08-12 | 2010-06-01 | National Instruments Corporation | Automatic versioning and data mutation of user-defined data types |
US7958133B2 (en) * | 2005-04-27 | 2011-06-07 | At&T Intellectual Property Ii, L.P. | Application conversion of source data |
US7735070B2 (en) * | 2005-06-30 | 2010-06-08 | Oracle America, Inc. | Allowing non-generified methods to override generified methods |
US8225294B2 (en) | 2006-04-27 | 2012-07-17 | Oracle America, Inc. | Method and apparatus for expressing and checking relationships between types |
US8527946B2 (en) * | 2007-03-06 | 2013-09-03 | International Business Machines Corporation | Declarative object identity using relation types |
US8572566B2 (en) * | 2010-05-11 | 2013-10-29 | Smartshift Gmbh | Systems and methods for analyzing changes in application code from a previous instance of the application code |
WO2011072970A1 (en) * | 2009-12-18 | 2011-06-23 | Syddansk Universitet | Method, computer program product, and system for non-blocking dynamic update of statically typed class-based object-oriented software |
US8813049B2 (en) * | 2010-06-30 | 2014-08-19 | Oracle International Corporation | Type inference of partially-specified parameterized types |
US8875122B2 (en) * | 2010-12-30 | 2014-10-28 | Sap Se | Tenant move upgrade |
US8972952B2 (en) * | 2012-02-03 | 2015-03-03 | Apple Inc. | Tracer based runtime optimization for dynamic programming languages |
US10261764B2 (en) * | 2014-05-13 | 2019-04-16 | Oracle International Corporation | Handling value types |
US9760350B2 (en) * | 2014-06-26 | 2017-09-12 | Oracle International Corporation | Optimistically assuming types in a dynamically typed language |
US10089089B2 (en) * | 2015-06-03 | 2018-10-02 | The Mathworks, Inc. | Data type reassignment |
EP3433769B1 (en) * | 2016-03-23 | 2024-05-08 | Johnson Controls Tyco IP Holdings LLP | Composition of pattern-driven reactions in real-time dataflow programming |
-
2017
- 2017-02-07 US US15/426,312 patent/US10908886B2/en active Active
- 2017-02-07 US US15/426,839 patent/US10635420B2/en active Active
- 2017-04-07 EP EP17720312.2A patent/EP3350696B1/en active Active
- 2017-04-07 CN CN201780002772.0A patent/CN107924326B/zh active Active
- 2017-04-07 WO PCT/US2017/026544 patent/WO2018013189A1/en active Application Filing
-
2020
- 2020-12-14 US US17/120,538 patent/US11347489B2/en active Active
-
2022
- 2022-05-04 US US17/736,509 patent/US11733985B2/en active Active
- 2022-05-04 US US17/736,499 patent/US11599346B2/en active Active
Patent Citations (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN1305609A (zh) * | 1998-06-16 | 2001-07-25 | 太阳微系统公司 | 实现参数化类型与现有非参数化库兼容的方法 |
CN1482540A (zh) * | 2002-08-02 | 2004-03-17 | ���µ�����ҵ��ʽ���� | 编译程序、编译程序装置和编译方法 |
CN102221994A (zh) * | 2010-04-19 | 2011-10-19 | 微软公司 | 用于改变回复力的中间语言支持 |
CN103927193A (zh) * | 2013-01-15 | 2014-07-16 | 中兴通讯股份有限公司 | Java应用程序函数迁移运行时的加载方法、服务端虚拟机 |
US20150370544A1 (en) * | 2014-06-18 | 2015-12-24 | Netapp, Inc. | Methods for facilitating persistent storage of in-memory databases and devices thereof |
Cited By (7)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110046004A (zh) * | 2019-03-29 | 2019-07-23 | 北京奇艺世纪科技有限公司 | 一种适配自动引用计数arc特性的方法、装置及电子设备 |
CN110046004B (zh) * | 2019-03-29 | 2022-09-02 | 北京奇艺世纪科技有限公司 | 一种适配自动引用计数arc特性的方法、装置及电子设备 |
CN114787769A (zh) * | 2019-12-13 | 2022-07-22 | 倍福自动化有限公司 | 用于通过控制程序的程序状态的数据迁移对自动化系统的控制程序进行更新的方法 |
CN114787769B (zh) * | 2019-12-13 | 2023-08-08 | 倍福自动化有限公司 | 用于通过控制程序的程序状态的数据迁移对自动化系统的控制程序进行更新的方法 |
CN114003317A (zh) * | 2021-10-29 | 2022-02-01 | 北京达佳互联信息技术有限公司 | 内联实现方法及装置、电子设备、存储介质及程序产品 |
CN117312176A (zh) * | 2023-11-30 | 2023-12-29 | 深圳市楠菲微电子有限公司 | 一种基于uvm的芯片验证测试方法、系统及电子设备 |
CN117312176B (zh) * | 2023-11-30 | 2024-02-23 | 深圳市楠菲微电子有限公司 | 一种基于uvm的芯片验证测试方法、系统及电子设备 |
Also Published As
Publication number | Publication date |
---|---|
US11599346B2 (en) | 2023-03-07 |
EP3350696B1 (en) | 2019-11-13 |
US20210096834A1 (en) | 2021-04-01 |
US10635420B2 (en) | 2020-04-28 |
US11733985B2 (en) | 2023-08-22 |
US11347489B2 (en) | 2022-05-31 |
US20180018163A1 (en) | 2018-01-18 |
US20220261229A1 (en) | 2022-08-18 |
US20180018151A1 (en) | 2018-01-18 |
WO2018013189A1 (en) | 2018-01-18 |
US10908886B2 (en) | 2021-02-02 |
EP3350696A1 (en) | 2018-07-25 |
US20220261230A1 (en) | 2022-08-18 |
CN107924326B (zh) | 2024-03-01 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN107924326A (zh) | 对经更新的类型的迁移方法进行覆盖 | |
US11169784B2 (en) | Computing expression medium, development environment, and device communication and control architecture | |
CN108139896A (zh) | 扩展虚拟机指令集体系架构 | |
CN106462425B (zh) | 使用复常量的方法和系统 | |
Goodrich et al. | Data structures and algorithms in Java | |
CN100470480C (zh) | 分析程序加速器装置以及更新其的方法 | |
US9086931B2 (en) | System for translating diverse programming languages | |
US9965259B2 (en) | System for translating diverse programming languages | |
WO2020173128A1 (zh) | 软件开发工具包的生成方法、装置及终端设备 | |
CN106663019A (zh) | 处理值类型 | |
WO2024045382A1 (zh) | 区块链中实现反射机制 | |
US10606614B2 (en) | Container-based language runtime using a variable-sized container for an isolated method | |
US8407598B2 (en) | Dynamic web control generation facilitator | |
CN110678839B (zh) | 基于流的范围界定 | |
US12014190B2 (en) | Type-constrained operations for plug-in types | |
CN110737431B (zh) | 软件开发方法、开发平台、终端设备及存储介质 | |
Biboudis et al. | Recaf: Java dialects as libraries | |
US9830204B2 (en) | Facilitating communication between software components that use middleware | |
US10394610B2 (en) | Managing split packages in a module system | |
Shetty et al. | Crust: AC/C++ to Rust transpiler using a “nano-parser methodology” to avoid C/C++ safety issues in legacy code | |
US20250045033A1 (en) | Application Programming Interface For Building And Transforming Symbolic Description Language Representations Of Source Code | |
Lavieri | Mastering Java 11: Develop modular and secure Java applications using concurrency and advanced JDK libraries | |
Lavieri et al. | Java 9: Building Robust Modular Applications: Master advanced Java features and implement them to build amazing projects | |
Frolov | Laying Tiles Ornamentally | |
Lumpe | Using metadata transformations to integrate class extensions in an existing class hierarchy |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |