CN110609687A - 一种编译方法、装置、电子设备和存储介质 - Google Patents
一种编译方法、装置、电子设备和存储介质 Download PDFInfo
- Publication number
- CN110609687A CN110609687A CN201910295245.4A CN201910295245A CN110609687A CN 110609687 A CN110609687 A CN 110609687A CN 201910295245 A CN201910295245 A CN 201910295245A CN 110609687 A CN110609687 A CN 110609687A
- Authority
- CN
- China
- Prior art keywords
- instruction
- access
- operation object
- function
- target function
- 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.)
- Pending
Links
- 238000000034 method Methods 0.000 title claims abstract description 140
- 230000006870 function Effects 0.000 claims abstract description 189
- 230000003068 static effect Effects 0.000 claims description 43
- 238000012986 modification Methods 0.000 claims description 8
- 230000004048 modification Effects 0.000 claims description 8
- 238000012216 screening Methods 0.000 claims description 7
- 238000001914 filtration Methods 0.000 claims description 4
- 238000011161 development Methods 0.000 abstract description 11
- 238000010586 diagram Methods 0.000 description 13
- 238000012545 processing Methods 0.000 description 9
- 238000004590 computer program Methods 0.000 description 7
- 238000005538 encapsulation Methods 0.000 description 5
- 230000003287 optical effect Effects 0.000 description 4
- 238000004891 communication Methods 0.000 description 3
- 238000005516 engineering process Methods 0.000 description 2
- 230000000644 propagated effect Effects 0.000 description 2
- 101100078188 Saccharomyces cerevisiae (strain ATCC 204508 / S288c) MST27 gene Proteins 0.000 description 1
- 230000006399 behavior Effects 0.000 description 1
- 230000009286 beneficial effect Effects 0.000 description 1
- 238000010276 construction Methods 0.000 description 1
- 238000012217 deletion Methods 0.000 description 1
- 230000037430 deletion Effects 0.000 description 1
- 238000011423 initialization method Methods 0.000 description 1
- 239000004973 liquid crystal related substance Substances 0.000 description 1
- 238000012423 maintenance Methods 0.000 description 1
- 239000013307 optical fiber Substances 0.000 description 1
- 238000004806 packaging method and process Methods 0.000 description 1
- 239000004065 semiconductor Substances 0.000 description 1
Classifications
-
- 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
Landscapes
- Engineering & Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Devices For Executing Special Programs (AREA)
Abstract
本公开公开了一种编译方法、装置、电子设备和存储介质。该方法包括:获取编译器生成的字节码文件;确定字节码文件中的目标函数,该目标函数为由编译器生成用于内部类和外部类互相访问彼此的私有成员的函数;将字节码文件中调用目标函数的指令修改为对目标函数的操作对象的访问指令,以访问操作对象。本技术方案通过在编译过程中自动删除目标函数,并将调用字节码文件中目标函数的指令修改为直接访问操作对象的指令,减少了字节码文件中目标函数数量,缓解了分包压力,并降低了字节码文件的体积,减小了字节码文件对应的应用程序的APK大小,提高了字节码的执行效率以及开发人员的开发效率。
Description
技术领域
本公开实施例涉及编译技术,尤其涉及一种编译方法、装置、电子设备和存储介质。
背景技术
Java语言的封装性要求一个类的私有成员不能被其他类直接访问,而Java的源代码中内部类和外部类可以直接访问对方的私有成员,这个现象违反了Java封装性的要求,其中,源代码文件中包含源代码,而字节码文件中包含字节码,并且字节码为源代码编译后得到。为了提供内部类和外部类直接访问对方的私有成员的能力,又不违反封装性要求,Java编译器在编译过程中自动生成一个函数(或者称为方法),比如,该函数名称可设置为access$001,内部类或外部类通过该access方法访问对方的私有成员。由于在编译过程中会自动生成大量的access方法,而由于安卓dex文件格式对方法数目的限制,当方法数目超过65536时需进行分包处理,并且大量的access方法的生成使得字节码文件体积增加,以及字节码文件对应的应用软件安装包(AndroidPackage,APK)文件大小也会变大。
为了减少方法数目,降低字节码文件的体积和减小APK文件的大小,在开发过程中,开发人员需要人为的分析哪些private关键字会导致编译器生成access方法,然后避免在源代码文件中编写private关键字,以避免在编译过程中自动生成access方法。
但在实际的开发过程中,开发人员需要人工对源代码进行分析,以判断在编译过程中是否会自动生成access方法,从而降低了开发人员的开发效率;并且为了避免自动生成access方法,需要将这种分析过程进行总结,并要求开发团队中的其他开发人员共同遵守,人工成本较大;并且,在源代码中提升操作对象的访问级别,会破坏了源代码的封装性,造成后续维护困难。
发明内容
本公开实施例提供一种编译方法、装置、电子设备和存储介质,减少了字节码文件中的方法数目,降低了字节码文件的体积,提高了字节码的执行效率以及开发人员的开发效率。
第一方面,本公开实施例提供了一种编译方法,包括:
获取编译器生成的字节码文件;
确定所述字节码文件中的目标函数,所述目标函数用于内部类和外部类互相访问彼此的私有成员的函数;
将所述字节码文件中调用所述目标函数的指令修改为对所述目标函数的操作对象的访问指令,以访问所述操作对象。
进一步的,所述确定所述字节码文件中的目标函数,包括:
查找所述字节码文件中符合预设筛选条件的目标函数。
进一步的,在所述确定所述字节码文件中的目标函数之后,在将所述字节码文件中调用所述目标函数的指令修改为访问所述目标函数的操作对象之前,还包括:
扫描所述目标函数对应的目标函数体,以得到操作指令;
根据所述操作指令确定对应的操作对象;
将所述操作对象的当前访问级别修改为目标访问级别,所述目标访问级别高于所述当前访问级别。
进一步的,当操作对象为非静态方法时,在所述将所述操作对象的当前访问级别修改为目标访问级别之后,还包括:
获取定义所述操作对象的类;
将所述类中所述操作对象的访问指令修改为INVOKEVIRTUAL操作指令。
进一步的,在所述根据所述操作指令确定对应的操作对象之后,还包括:
删除所述目标函数。
进一步的,所述将所述操作对象的当前访问级别修改为目标访问级别,包括:
获取所述操作对象的当前访问级别对应的当前标志位;
修改所述当前标志位,得到目标访问级别。
进一步的,所述将所述字节码文件中调用所述目标函数的指令修改为访问所述目标函数的操作对象,包括:
删除所述字节码文件中调用所述目标函数的指令;
采用预设指令访问所述目标函数的操作对象。
进一步的,所述预设筛选条件为静态的、访问级别为package的、函数名为access$开头的以及通过预设操作指令访问外部类或内部类的私有成员的函数。
进一步的,所述预设操作指令包括下述一项:GETFIELD、PUTFIELD、GETSTATIC、PUTSTATIC、INVOKESPECIAL、INVOKESTATIC。
第二方面,本公开实施例还提供了一种编译装置,包括:
第一获取模块,用于获取编译器生成的字节码文件;
第一确定模块,用于确定所述字节码文件中的目标函数,所述目标函数用于内部类和外部类互相访问彼此的私有成员的函数;
第一修改模块,用于将所述字节码文件中调用所述目标函数的指令修改为对所述目标函数的操作对象的访问指令,以访问所述操作对象。
进一步的,第一确定模块,具体用于:
查找所述字节码文件中符合预设筛选条件的目标函数。
进一步的,所述编译装置,还包括:
第二确定模块,用于在所述确定所述字节码文件中的目标函数之后,在将所述字节码文件中调用所述目标函数的指令修改为访问所述目标函数的操作对象之前,扫描所述目标函数对应的目标函数体,以得到操作指令;
第三确定模块,用于根据所述操作指令确定对应的操作对象;
第二修改模块,用于将所述操作对象的当前访问级别修改为目标访问级别,所述目标访问级别高于所述当前访问级别。
进一步的,所述编译装置,还包括:
第二获取模块,用于当操作对象为非静态方法时,在所述将所述操作对象的当前访问级别修改为目标访问级别之后,获取定义所述操作对象的类;
第三修改模块,用于将所述类中所述操作对象的访问指令修改为INVOKEVIRTUAL操作指令。
进一步的,所述编译装置,还包括:
删除模块,用于在所述根据所述操作指令确定对应的操作对象之后,删除所述目标函数。
进一步的,所述第二修改模块,包括:
获取单元,用于获取所述操作对象的当前访问级别对应的当前标志位;
修改单元,用于修改所述当前标志位,得到目标访问级别。
进一步的,所述将所述字节码文件中调用所述目标函数的指令修改为访问所述目标函数的操作对象,具体用于:
删除所述字节码文件中调用所述目标函数的指令;
采用预设指令访问所述目标函数的操作对象。
进一步的,所述预设筛选条件为静态的、访问级别为package的、函数名为access$开头的以及通过预设操作指令访问外部类或内部类的私有成员的函数。
进一步的,所述预设操作指令包括下述一项:GETFIELD、PUTFIELD、GETSTATIC、PUTSTATIC、INVOKESPECIAL、INVOKESTATIC。
第三方面,本公开实施例还提供了一种电子设备,包括:存储器以及一个或多个处理器;
所述存储器,用于存储一个或多个程序;
当所述一个或多个程序被所述一个或多个处理器执行,使得所述一个或多个处理器实现如第一方面所述的编译方法。
第四方面,本公开实施例还提供了一种包含计算机可执行指令的存储介质,所述计算机可执行指令在由计算机处理器执行时用于执行如第一方面所述的编译方法。
本公开实施例通过获取编译器所生成的字节码文件,并确定字节码文件中的目标函数,然后将字节码文件中调用目标函数的指令修改为对目标函数的操作对象的访问指令。本技术方案通过在编译过程中自动删除目标函数,并将调用字节码文件中目标函数的指令修改为直接访问操作对象的指令,减少了字节码文件中目标函数数量,缓解了分包压力,并降低了字节码文件的体积,减小了字节码文件对应的应用程序的APK大小,提高了字节码的执行效率,以及开发人员的开发效率。
附图说明
图1是本公开实施例提供的一种编译方法的流程图;
图2是本公开实施例提供的一种编译方法的流程图;
图3是本公开实施例提供的一种调整操作对象的访问级别之前标志位的显示示意图;
图4是本公开实施例提供的一种编译方法的流程图;
图5是本公开实施例提供的一种编译装置的结构框图;
图6是本公开实施例提供的一种电子设备的结构框图。
具体实施方式
下面结合附图和实施例对本公开作进一步的详细说明。可以理解的是,此处所描述的具体实施例仅仅用于解释本公开,而非对本公开的限定。另外还需要说明的是,为了便于描述,附图中仅示出了与本公开相关的部分而非全部结构。
在此需要说明的是,编译器自动生成access方法的情况有多种,而内部类和外部类访问对方的私有成员而生成access方法的情况最为常见。在实施例中,以目标函数为编译器生成的用于内部类和外部类访问对方的私有成员的函数为例,对本方案的编译方法进行具体说明。当然,当内部类访问其外部类的非同包父类的protected方法时,也会生成access方法。此时,也可采用本方案实现access方法的自动删除,以对操作对象进行直接访问。
图1是本公开实施例提供的一种编译方法的流程图,本实施例中提供的编译方法可以由编译装置来执行,该编译装置可以通过软件和/或硬件的方式实现,该编译装置可以配置在电子设备中,该电子设备可以是两个或多个物理实体构成,也可以是一个物理实体构成。本实施例中电子设备为具备开发功能的终端设备,比如,电子设备可以为台式电脑、笔记本电脑等。
参考图1,该编译方法具体包括如下步骤:
步骤110、获取编译器生成的字节码文件。
其中,字节码文件是一种包含执行程序的二进制文件。在实施例中,在开发人员完成源代码的编写之后,可通过编译器对源代码进行编译,以生成字节码,并将包含字节码的文件称为字节码文件。
步骤120、确定字节码文件中的目标函数。
其中,目标函数为由编译器生成的用于内部类和外部类互相访问彼此的私有成员的函数。在实施例中,目标函数为背景技术中所描述的access方法。具体来说,通过编译器对源代码进行编译之后,扫描编译得到的所有文件,得到字节码文件;然后分析字节码文件,以得到字节码文件中的目标函数。
在实施例中,确定字节码文件中的目标函数的方式,具体包括:查找字节码文件中符合预设筛选条件的目标函数。其中,预设筛选条件为静态的、访问级别为package的、函数名为access$开头的以及通过预设操作指令访问外部类或者内部类的私有成员的函数。其中,预设操作指令包括下述一项:GETFIELD、PUTFIELD、GETSTATIC、PUTSTATIC、INVOKESPECIAL、INVOKESTATIC。其中,GETFIELD操作指令用于获取指定类的实例域,并将其值压入操作数栈的栈顶;PUTFIELD操作指令用于为指定的类的实例域赋值;GETSTATIC操作指令用于获取指定类的静态域,并将其值压入操作数栈的栈顶;PUTSTATIC操作指令用于为指定的类的静态域赋值;INVOKESPECIAL操作指令用于调用超类构造方法,实例初始化方法,私有方法和父类方法;INVOKESTATIC操作指令用于调用类的静态方法。其中,域指的是字段,即实例域和静态域分别指的是实例字段和静态字段。在此需要说明的是,函数可以理解为方法;函数名可以理解为方法名。具体来说,以预设筛选条件为依据,对字节码文件中的所有函数进行筛选,以筛选得到由编译器生成的、静态的、访问级别为package的、函数名为access$开头的以及内部是通过GETFIELD、PUTFIELD、GETSTATIC、PUTSTATIC、INVOKESPECIAL、INVOKESTATIC等操作指令访问其外部类或者内部类的私有成员的函数,并将该函数作为字节码文件中的目标函数。
步骤130、将字节码文件中调用目标函数的指令修改为对目标函数的操作对象的访问指令,以访问操作对象。
在此需要说明的是,操作对象可以包括:方法和字段。当然,操作对象可以为静态,也可以为非静态。相应的,操作对象可以为静态方法、非静态方法,也可为静态字段和非静态字段。需要理解的是,对于静态和非静态操作对象,对应的访问指令也是不同的。示例性地,在实施例中,可通过ASM的visitFieldInsn方法实现插入字段访问的字节码指令;通过ASM的visitMethodInsn方法实现插入方法访问的字节码指令。其中,ASM是一种常用的Java字节码操作库。
在实施例中,将所有调用目标函数的指令修改为目标函数中操作对象的访问,以实现对操作对象的直接访问。具体来说,可删除目标函数的调用指令,并在调用目标函数的位置替换为访问目标函数中操作对象的指令,以对操作对象进行直接访问。其中,具体的替换过程见下述实施例的具体描述,在此不再赘述。
本实施例的技术方案,通过获取编译器所生成的字节码文件,并确定字节码文件中的目标函数,然后将字节码文件中调用目标函数的指令修改为对目标函数的操作对象的访问指令。本实施例通过在编译过程中自动删除目标函数,并将调用字节码文件中目标函数的指令修改为直接访问操作对象的指令,减少了字节码中目标函数数量,缓解了分包压力,并降低了字节码文件的体积,减小了字节码文件对应的应用程序的APK大小,提升了字节码的执行效率,并且,无需人为的分析private关键字是否会导致编译器生成access方法,提升了开发人员的开发效率。
图2是本公开实施例提供的一种编译方法的流程图。本实施例是在上述实施例的基础上,为了能够直接访问目标函数中的操作对象,需在将字节码文件中调用目标函数的指令修改为访问目标函数的操作对象之前,对操作对象的当前访问级别进行修改。参照图2,该编译方法具体包括如下步骤:
步骤210、获取编译器生成的字节码文件。
步骤220、确定所述字节码文件中的目标函数。
其中,目标函数为由编译器生成的用于内部类和外部类互相访问彼此的私有成员的函数。
步骤230、扫描目标函数对应的目标函数体,以得到操作指令。
其中,目标函数可以理解为一个方法;而目标函数体可以理解为方法的内容。比如,static int access$001(){},其中,大括号里的就是方法体,即本方案中的目标函数体,而access$001()就是目标函数。
在实施例中,对目标函数中的内容进行扫描分析,以得到操作指令。其中,操作指令可以为GETFIELD、GETSTATIC、PUTFIELD、PUTSTATIC、INVOKESPECIAL、INVOKESTATIC。
步骤240、根据操作指令确定对应的操作对象。
在此需要说明的是,当目标函数中具有不同操作对象时,目标函数中的操作指令也是不同的。具体来说,当目标函数中通过GETFIELD、GETSTATIC、PUTFIELD、PUTSTATIC操作指令对操作对象进行操作时,则可确定目标函数中的操作对象为字段,即目标函数的产生是为了处理字段访问操作;当目标函数中通过INVOKESPECIAL、INVOKESTATIC操作指令对操作对象进行操作时,则可确定目标函数中的操作对象为方法,即目标函数的产生是为了处理方法访问操作。其中,若操作指令为GETFIELD,则操作对象是非静态字段,并执行读取操作;若操作指令为PUTFIELD,则操作对象是非静态字段,并执行写入操作;若操作指令为GETSTATIC,则操作对象是静态字段,并执行读取操作;若操作指令为PUTSTATIC,则操作对象是静态字段,并执行写入操作;若操作指令为INVOKESTATIC,则操作对象是静态方法;若操作指令为INVOKESPECIAL,则操作对象是非静态方法。
步骤250、将操作对象的当前访问级别修改为目标访问级别。
其中,目标访问级别高于当前访问级别。在此需要说明的是,在步骤230中所确定的真实操作对象的访问级别为private,即操作对象的当前访问级别为private。为了在后续能够实现对操作对象的直接访问,需提升操作对象的当前访问级别。在实施例中,目标访问级别为package。
步骤260、将字节码文件中调用目标函数的指令修改为对目标函数的操作对象的访问指令,以访问操作对象。
本实施例的技术方案,在上述实施例的基础上,通过扫描目标函数体,以得到操作指令,并根据操作指令确定对应的操作对象,将操作对象的当前访问级别修改为目标访问级别,实现了提升操作对象的访问级别,以便于后续可直接访问操作对象。
在上述实施例的基础上,将操作对象的当前访问级别修改为目标访问级别这个步骤具体可包括步骤2501-2502:
步骤2501、获取操作对象的当前访问级别对应的当前标志位。
在此需要说明的是,Java中操作对象的访问级别存储于access flag中,而accessflag是由2个字节(即16个比特位)组成的。在实施例中,Java的字节码是按大端字节序进行存储的,并且,access flag中从右边起第2位用来表示操作对象是否为private。若操作对象的当前访问级别为private,则从access flag中所获取到的比特位为1。
步骤2502、修改当前标志位,得到目标访问级别。
在实施例中,在确定表示操作对象的访问级别对应的标志位之后,将当前标志位对应的比特位调整为0,以实现操作对象的访问级别的调整。在此需要说明的是,对于一个访问级别为private的操作对象,如果将access flag中表示private的比特位设置为0后,操作对象的访问级别就变为package。
在此需要说明的是,当确定操作对象为非静态方法时,为了保证在定义类中对操作对象的正常调用,在步骤250之后,还包括:
S10、获取定义所述操作对象的类。
在此需要说明的是,在创建一个操作对象时,需在一个类中对该操作对象进行定义。在实施例中,为了减少字节码文件中的方法数目,以及降低APK文件的大小,在编译过程中,通过本公开技术方案自动删除access方法,并且在调用access方法的位置修改为对操作对象的直接访问。为了保证在将操作对象的访问级别提升之后,不影响在定义该操作对象的类中对该操作对象的调用,需获取定义该操作对象的类,并修改该类中对该操作对象的调用指令。
S20、将类中操作对象的访问指令修改为INVOKEVIRTUAL操作指令。
在实施例中,在提升操作对象的访问级别之前,定义该操作对象的类中的其它方法可通过INVOKESPECIAL操作指令对其进行直接访问。但在将操作对象的当前访问级别修改为目标访问级别之后,操作对象的访问级别得到提升,为了保证对操作对象的正常访问,需将INVOKESPECIAL操作指令调整为INVOKEVIRTUAL操作指令。其中,INVOKEVIRTUAL操作指令用于调用实例方法。
图3是本公开实施例提供的一种调整操作对象的访问级别之前标志位的显示示意图。在实施例中,在access flag中的从右边起第2位用于表示操作对象是否为private。如图3中的第一个图所示,若操作对象的当前访问级别为private,则从右边起第2位的当前标志位为1。若将从右边起第2位的标志位设置为0,就实现了将操作对象的访问级别由private提升为package的目的,如图3中的第二个图所示,将从右边起第2位的当前标志位由1修改为0即可。
在上述实施例的基础上,在根据操作指令确定对应的操作对象之后,删除目标函数。但在删除目标函数之前,需将操作对象的当前访问级别提升为package,以使操作对象具备包级的访问,即操作对象只能被同一个包下的类访问。
在此需要说明的是,在实际操作过程中,为了提升处理速度,删除目标函数,与将操作对象的当前访问级别修改为目标访问级别,以及在操作对象为非静态方法时,将调用指令由INVOKESPECIAL操作指令修改为INVOKEVIRTUAL操作指令这三个步骤可以并发执行。其中,将INVOKESPECIAL操作指令修改为INVOKEVIRTUAL操作指令的过程见下述实施例的描述,在此不再赘述。
在上述实施例的基础上,将字节码文件中调用目标函数的指令修改为访问目标函数的操作对象,可包括:删除字节码文件中调用所述目标函数的指令;采用预设指令访问目标函数的操作对象。
图4是本公开实施例提供的一种编译方法的流程图。如图4所示,该实施例中的编译方法具体步骤如下:
步骤310、获取编译器生成的字节码文件。
步骤320、确定字节码文件中的目标函数。
其中,目标函数为由编译器生成的用于内部类和外部类访问对方的私有成员的函数。
步骤330、根据目标函数对应的目标函数体,以得到操作指令。
步骤340、根据操作指令确定对应的操作对象。
步骤350、将操作对象的当前访问级别修改为目标访问级别。
其中,目标访问级别高于当前访问级别。
步骤360、删除字节码文件中调用目标函数的指令。
步骤370、采用预设指令访问目标函数的操作对象。
其中,预设指令,可以理解为可访问操作对象的相关指令。在实施例中,当操作对象为不同类型时,对应的预设指令也是不同的。比如,当操作对象为非静态方法时,采用INVOKEVIRTUAL操作指令。在此需要说明的是,在目标函数中调用该操作对象时使用的是INVOKESPECIAL指令,因为该操作对象的访问级别原本是private的,当通过修改accessflag中表示private访问级别的比特位之后,即将该操作对象的访问级别提升到package之后,就需要将调用指令改为INVOKEVIRTUAL;当操作对象为静态方法时,使用INVOKESTATIC操作指令。当操作对象为静态字段并且执行读取操作时,使用GETSTATIC操作指令。当操作对象为静态字段并且执行写入操作时,使用PUTSTATIC操作指令。当操作对象为非静态字段并且执行读取操作时,使用GETFIELD操作指令。当操作对象为非静态字段并且执行写入操作时,使用PUTFIELD操作指令。
在此需要说明的是,对于字段的处理,以Oracle官方发布的Java编译器为例,当为字段写操作而生成的access方法具有返回值时,在删除目标函数的调用指令之后,以及采用预设指令访问操作对象之前,需增加当前操作数栈栈顶元素的复制操作。具体操作为:对于非静态字段,如果是double或者long类型,则通过DUP2_X1指令复制操作数栈栈顶的两个元素并插入到操作数栈栈顶三个元素的下方;否则通过DUP_X1指令复制操作数栈栈顶的一个元素并插入到操作数栈栈顶两个元素的下方。对于静态字段,如果是double或者long类型,则通过DUP2指令复制操作数栈栈顶的两个元素并放入操作数栈栈顶;否则通过DUP指令复制操作数栈栈顶的一个元素并放入操作数栈栈顶。
在此需要说明的是,本技术方案中涉及到的编译方法的所有实施例均是在将jar包转换为dex文件之前进行操作的。
本实施例的技术方案,在编译过程中,采用本技术方案自动删除字节码文件中的access方法,提升access方法中操作对象的访问级别,并在调用access方法的位置替换为对操作对象的直接调用,无需开发人员对源代码中操作对象的访问级别进行修改,有效避免了破坏源代码的封装性。
在此需要说明的是,为了避免在提升操作对象的访问级别时,造成错误的重写(override)行为,当出现如下三种情况时,无需采用本公开实施例中的技术方案,对字节码文件进行处理。
首先,在描述三种情况之前,需先确定API Level值的标准阈值。其中,API Level值的范围为正整数,是用于描述移动应用对应的软件开发工具包(Software DevelopmentKit,SDK)开放给移动的应用程序编程接口(Application Programming Interface,API)等级。具体来说,若API Level值在21以下,系统使用的是Dalvik虚拟机,而Dalvik虚拟机在多态处理上存在bug,为了规避Dalvik虚拟机所产生的bug,将API Level值的标准阈值设置为21。其中,Dalvik和ART虚拟机用于执行dex字节码,Android 5.0以下的系统使用Dalvik虚拟机,Android 5.0以上(包含5.0)系统使用ART虚拟机。
在确定API Level值的标准阈值之后,对三种情况进行具体描述。具体如下:
第一种情况:若API Level>=21,并且同一个包中存在一个子类,并且存在非private、非static的方法,以及该方法名和方法描述符与目标函数(access方法)中的操作对象的方法名和方法描述符一致,则不采用本方案的编译方法。
第二种情况:若API Level<21,并且存在一个子类,并且该子类中存在非private、非static的方法,以及该方法名和方法描述符与目标函数(access方法)中的操作对象的方法名和方法描述符一致,则不采用本方案的编译方法。
第三种情况:若API Level<21,并且存在一个不同包的父类,其中有非static、并且package可见性的方法,以及该方法名和方法描述符与目标函数(access方法)中的操作对象的方法名和方法描述符一致,则不采用本方案的编译方法。
在此需要说明的是,方法名和方法描述符是用字符串表示的,方法名是否一致以及方法描述符是否一致可以通过字符串匹配来判断。
图5是本公开实施例提供的一种编译装置的结构框图,本实施例可适用于自动删除编译器生成的用于内部类和外部类访问对方的私有成员的目标函数的情况,该装置可以采用软件和/或硬件的方式实现,该装置可以配置于电子设备中,本实施例中电子设备为具备开发功能的终端设备,比如,电子设备可以为台式电脑、笔记本电脑等。如图5所示,该编译装置具体包括:第一获取模块410、第一确定模块420和第一修改模块430。
其中,第一获取模块410,用于获取编译器生成的字节码文件;
第一确定模块420,用于确定字节码文件中的目标函数,该目标函数为由编译器生成的用于内部类和外部类互相访问彼此的私有成员的函数;
第一修改模块430,用于将字节码文件中调用目标函数的指令修改为对目标函数的操作对象的访问指令,以访问操作对象。
本实施例的技术方案,通过获取编译器所生成的字节码文件,并确定字节码文件中的目标函数,然后将字节码文件中调用目标函数的指令修改为访问目标函数的操作对象的指令。本实施例通过在编译过程中自动删除目标函数,并将调用字节码文件中目标函数的指令修改为直接访问操作对象的指令,减少了字节码文件中目标函数数量,缓解了分包压力,并降低了字节码文件的体积,减小了字节码文件对应的应用程序的APK大小,提高了字节码的执行效率以及开发人员的开发效率。
在上述实施例的基础上,第一确定模块420,具体用于:
查找字节码文件中符合预设筛选条件的目标函数。
在上述实施例的基础上,编译装置,还包括:
第二确定模块,用于在确定字节码文件中的目标函数之后,在将字节码文件中调用目标函数的指令修改为访问目标函数的操作对象之前,扫描目标函数对应的目标函数体,以得到操作指令;
第三确定模块,用于根据操作指令确定对应的操作对象;
第二修改模块,用于将操作对象的当前访问级别修改为目标访问级别,目标访问级别高于当前访问级别。
在上述实施例的基础上,编译装置,还包括:
第二获取模块,用于当操作对象为非静态方法时,在所述将所述操作对象的当前访问级别修改为目标访问级别之后,获取定义所述操作对象的类;
第三修改模块,用于将所述类中所述操作对象的访问指令修改为INVOKEVIRTUAL操作指令。
在上述实施例的基础上,编译装置,还包括:
删除模块,用于在根据操作指令确定对应的操作对象之后,删除目标函数。
在上述实施例的基础上,第二修改模块,包括:
获取单元,用于获取操作对象的当前访问级别对应的当前标志位;
修改单元,用于修改当前标志位,得到目标访问级别。
在上述实施例的基础上,将字节码文件中调用目标函数的指令修改为访问目标函数的操作对象,具体用于:
删除字节码文件中调用目标函数的指令;
采用预设指令访问目标函数的操作对象。
在上述实施例的基础上,预设筛选条件为静态的、访问级别为package的、函数名为access$开头的以及通过预设操作指令访问外部类或内部类的私有成员的函数。
在上述实施例的基础上,所述预设操作指令包括下述一项:GETFIELD、PUTFIELD、GETSTATIC、PUTSTATIC、INVOKESPECIAL、INVOKESTATIC。
本公开实施例提供的编译装置可执行本公开任意实施例所提供的编译方法,具备执行方法相应的功能模块和有益效果。
图6是本公开实施例提供的一种电子设备的结构框图。参考图6,其示出了适于用来实现本公开实施例的电子设备(例如终端设备或服务器)500的结构示意图。本公开实施例中的终端设备可以包括但不限于诸如台式电脑、笔记本电脑、数字广播接收器、PDA(个人数字助理)、PAD(平板电脑)、PMP(便携式多媒体播放器)、车载终端(例如车载导航终端)等等的移动终端以及诸如数字TV、台式计算机等等的固定终端。图6示出的电子设备仅仅是一个示例,不应对本公开实施例的功能和使用范围带来任何限制。
如图6所示,电子设备500可以包括处理装置(例如中央处理器、图形处理器等)501,其可以根据存储在只读存储器(ROM)502中的程序或者从存储装置508加载到随机访问存储器(RAM)503中的程序而执行各种适当的动作和处理。在RAM 503中,还存储有电子设备500操作所需的各种程序和数据。处理装置501、ROM 502以及RAM 503通过总线504彼此相连。输入/输出(I/O)接口505也连接至总线504。
通常,以下装置可以连接至I/O接口505:包括例如触摸屏、触摸板、键盘、鼠标、摄像头、麦克风、加速度计、陀螺仪等的输入装置506;包括例如液晶显示器(LCD)、扬声器、振动器等的输出装置507;包括例如磁带、硬盘等的存储装置508;以及通信装置509。通信装置509可以允许电子设备500与其他设备进行无线或有线通信以交换数据。虽然图6示出了具有各种装置的电子设备500,但是应理解的是,并不要求实施或具备所有示出的装置。可以替代地实施或具备更多或更少的装置。
特别地,根据本公开的实施例,上文参考流程图描述的过程可以被实现为计算机软件程序。例如,本公开的实施例包括一种计算机程序产品,其包括承载在计算机可读介质上的计算机程序,该计算机程序包含用于执行流程图所示的方法的程序代码。在这样的实施例中,该计算机程序可以通过通信装置509从网络上被下载和安装,或者从存储装置508被安装,或者从ROM 502被安装。在该计算机程序被处理装置501执行时,执行本公开实施例的编译方法中限定的上述功能。
需要说明的是,本公开上述的计算机可读介质可以是计算机可读信号介质或者计算机可读存储介质或者是上述两者的任意组合。计算机可读存储介质例如可以是——但不限于——电、磁、光、电磁、红外线、或半导体的系统、装置或器件,或者任意以上的组合。计算机可读存储介质的更具体的例子可以包括但不限于:具有一个或多个导线的电连接、便携式计算机磁盘、硬盘、随机访问存储器(RAM)、只读存储器(ROM)、可擦式可编程只读存储器(EPROM或闪存)、光纤、便携式紧凑磁盘只读存储器(CD-ROM)、光存储器件、磁存储器件、或者上述的任意合适的组合。在本公开中,计算机可读存储介质可以是任何包含或存储程序的有形介质,该程序可以被指令执行系统、装置或者器件使用或者与其结合使用。而在本公开中,计算机可读信号介质可以包括在基带中或者作为载波一部分传播的数据信号,其中承载了计算机可读的程序代码。这种传播的数据信号可以采用多种形式,包括但不限于电磁信号、光信号或上述的任意合适的组合。计算机可读信号介质还可以是计算机可读存储介质以外的任何计算机可读介质,该计算机可读信号介质可以发送、传播或者传输用于由指令执行系统、装置或者器件使用或者与其结合使用的程序。计算机可读介质上包含的程序代码可以用任何适当的介质传输,包括但不限于:电线、光缆、RF(射频)等等,或者上述的任意合适的组合。
上述计算机可读介质可以是上述电子设备中所包含的;也可以是单独存在,而未装配入该电子设备中。
上述计算机可读介质承载有一个或者多个程序,当上述一个或者多个程序被该电子设备执行时,使得该电子设备:获取编译器生成的字节码文件;确定字节码文件中的目标函数,该目标函数为由编译器生成的用于内部类和外部类互相访问彼此的私有成员的函数;将字节码文件中调用目标函数的指令修改为对目标函数的操作对象的访问指令,以访问操作对象。
可以以一种或多种程序设计语言或其组合来编写用于执行本公开的操作的计算机程序代码,上述程序设计语言包括面向对象的程序设计语言—诸如Java、Smalltalk、C++,还包括常规的过程式程序设计语言—诸如“C”语言或类似的程序设计语言。程序代码可以完全地在用户计算机上执行、部分地在用户计算机上执行、作为一个独立的软件包执行、部分在用户计算机上部分在远程计算机上执行、或者完全在远程计算机或服务器上执行。在涉及远程计算机的情形中,远程计算机可以通过任意种类的网络——包括局域网(LAN)或广域网(WAN)—连接到用户计算机,或者,可以连接到外部计算机(例如利用因特网服务提供商来通过因特网连接)。
附图中的流程图和框图,图示了按照本公开各种实施例的系统、方法和计算机程序产品的可能实现的体系架构、功能和操作。在这点上,流程图或框图中的每个方框可以代表一个模块、程序段、或代码的一部分,该模块、程序段、或代码的一部分包含一个或多个用于实现规定的逻辑功能的可执行指令。也应当注意,在有些作为替换的实现中,方框中所标注的功能也可以以不同于附图中所标注的顺序发生。例如,两个接连地表示的方框实际上可以基本并行地执行,它们有时也可以按相反的顺序执行,这依所涉及的功能而定。也要注意的是,框图和/或流程图中的每个方框、以及框图和/或流程图中的方框的组合,可以用执行规定的功能或操作的专用的基于硬件的系统来实现,或者可以用专用硬件与计算机指令的组合来实现。
描述于本公开实施例中所涉及到的单元可以通过软件的方式实现,也可以通过硬件的方式来实现。其中,单元的名称在某种情况下并不构成对该单元本身的限定,例如,第一获取单元还可以被描述为“获取至少两个网际协议地址的单元”。
以上描述仅为本公开的较佳实施例以及对所运用技术原理的说明。本领域技术人员应当理解,本公开中所涉及的公开范围,并不限于上述技术特征的特定组合而成的技术方案,同时也应涵盖在不脱离上述公开构思的情况下,由上述技术特征或其等同特征进行任意组合而形成的其它技术方案。例如上述特征与本公开中公开的(但不限于)具有类似功能的技术特征进行互相替换而形成的技术方案。
Claims (12)
1.一种编译方法,其特征在于,包括:
获取编译器生成的字节码文件;
确定所述字节码文件中的目标函数,所述目标函数为由编译器生成的用于内部类和外部类互相访问彼此的私有成员的函数;
将所述字节码文件中调用所述目标函数的指令修改为对所述目标函数的操作对象的访问指令,以访问所述操作对象。
2.根据权利要求1所述的编译方法,其特征在于,所述确定所述字节码文件中的目标函数,包括:
查找所述字节码文件中符合预设筛选条件的目标函数。
3.根据权利要求1所述的编译方法,其特征在于,在所述确定所述字节码文件中的目标函数之后,在将所述字节码文件中调用所述目标函数的指令修改为访问所述目标函数的操作对象之前,还包括:
扫描所述目标函数对应的目标函数体,以得到操作指令;
根据所述操作指令确定对应的操作对象;
将所述操作对象的当前访问级别修改为目标访问级别,所述目标访问级别高于所述当前访问级别。
4.根据权利要求3所述的编译方法,其特征在于,当操作对象为非静态方法时,在所述将所述操作对象的当前访问级别修改为目标访问级别之后,还包括:
获取定义所述操作对象的类;
将所述类中所述操作对象的访问指令修改为INVOKEVIRTUAL操作指令。
5.根据权利要求3所述的编译方法,其特征在于,在所述根据所述操作指令确定对应的操作对象之后,还包括:
删除所述目标函数。
6.根据权利要求3所述的编译方法,其特征在于,所述将所述操作对象的当前访问级别修改为目标访问级别,包括:
获取所述操作对象的当前访问级别对应的当前标志位;
修改所述当前标志位,得到目标访问级别。
7.根据权利要求1所述的编译方法,其特征在于,所述将所述字节码文件中调用所述目标函数的指令修改为访问所述目标函数的操作对象,包括:
删除所述字节码文件中调用所述目标函数的指令;
采用预设指令访问所述目标函数的操作对象。
8.根据权利要求2所述的编译方法,其特征在于,所述预设筛选条件为静态的、访问级别为package的、函数名为access$开头的以及通过预设操作指令访问外部类或内部类的私有成员的函数。
9.根据权利要求8所述的编译方法,其特征在于,所述预设操作指令包括下述一项:GETFIELD、PUTFIELD、GETSTATIC、PUTSTATIC、INVOKESPECIAL、INVOKESTATIC。
10.一种编译装置,其特征在于,包括:
获取模块,用于获取编译器生成的字节码文件;
确定模块,用于确定所述字节码文件中的目标函数,所述目标函数用于内部类和外部类互相访问彼此的私有成员的函数;
第一修改模块,用于将所述字节码文件中调用所述目标函数的指令修改为对所述目标函数的操作对象的访问指令,以访问所述操作对象。
11.一种电子设备,其特征在于,包括:存储器以及一个或多个处理器;
所述存储器,用于存储一个或多个程序;
当所述一个或多个程序被所述一个或多个处理器执行,使得所述一个或多个处理器实现如权利要求1-9中任一所述的编译方法。
12.一种包含计算机可执行指令的存储介质,其特征在于,所述计算机可执行指令在由计算机处理器执行时用于执行如权利要求1-9中任一所述的编译方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201910295245.4A CN110609687A (zh) | 2019-04-12 | 2019-04-12 | 一种编译方法、装置、电子设备和存储介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201910295245.4A CN110609687A (zh) | 2019-04-12 | 2019-04-12 | 一种编译方法、装置、电子设备和存储介质 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN110609687A true CN110609687A (zh) | 2019-12-24 |
Family
ID=68889632
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201910295245.4A Pending CN110609687A (zh) | 2019-04-12 | 2019-04-12 | 一种编译方法、装置、电子设备和存储介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN110609687A (zh) |
Cited By (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111240738A (zh) * | 2020-01-20 | 2020-06-05 | 北京无限光场科技有限公司 | 文件处理方法、装置、设备及介质 |
CN111309334A (zh) * | 2020-02-18 | 2020-06-19 | 北京奇艺世纪科技有限公司 | 生成软件安装包的方法、装置、计算机设备及存储介质 |
CN111796865A (zh) * | 2020-06-28 | 2020-10-20 | 北京字节跳动网络技术有限公司 | 一种字节码文件修改方法、装置、终端设备及介质 |
CN111949336A (zh) * | 2020-08-03 | 2020-11-17 | 中国民用航空华东地区空中交通管理局 | 函数文件的调整方法、装置、计算机设备和存储介质 |
CN113448585A (zh) * | 2020-12-11 | 2021-09-28 | 北京新氧科技有限公司 | 一种对线程池的优化方法、装置、电子设备和存储介质 |
Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20120311531A1 (en) * | 2011-05-30 | 2012-12-06 | International Business Machines Corporation | Optimizing an object-oriented program by transforming invocations of synthetic accessor methods |
CN108089870A (zh) * | 2016-11-21 | 2018-05-29 | 百度在线网络技术(北京)有限公司 | 用于修复应用的方法和装置 |
CN108614702A (zh) * | 2016-12-28 | 2018-10-02 | 阿里巴巴集团控股有限公司 | 字节码优化方法及装置 |
-
2019
- 2019-04-12 CN CN201910295245.4A patent/CN110609687A/zh active Pending
Patent Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20120311531A1 (en) * | 2011-05-30 | 2012-12-06 | International Business Machines Corporation | Optimizing an object-oriented program by transforming invocations of synthetic accessor methods |
CN108089870A (zh) * | 2016-11-21 | 2018-05-29 | 百度在线网络技术(北京)有限公司 | 用于修复应用的方法和装置 |
CN108614702A (zh) * | 2016-12-28 | 2018-10-02 | 阿里巴巴集团控股有限公司 | 字节码优化方法及装置 |
Cited By (9)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111240738A (zh) * | 2020-01-20 | 2020-06-05 | 北京无限光场科技有限公司 | 文件处理方法、装置、设备及介质 |
CN111240738B (zh) * | 2020-01-20 | 2023-11-21 | 北京有竹居网络技术有限公司 | 文件处理方法、装置、设备及介质 |
CN111309334A (zh) * | 2020-02-18 | 2020-06-19 | 北京奇艺世纪科技有限公司 | 生成软件安装包的方法、装置、计算机设备及存储介质 |
CN111309334B (zh) * | 2020-02-18 | 2023-09-01 | 北京奇艺世纪科技有限公司 | 生成软件安装包的方法、装置、计算机设备及存储介质 |
CN111796865A (zh) * | 2020-06-28 | 2020-10-20 | 北京字节跳动网络技术有限公司 | 一种字节码文件修改方法、装置、终端设备及介质 |
CN111796865B (zh) * | 2020-06-28 | 2024-04-16 | 北京字节跳动网络技术有限公司 | 一种字节码文件修改方法、装置、终端设备及介质 |
CN111949336A (zh) * | 2020-08-03 | 2020-11-17 | 中国民用航空华东地区空中交通管理局 | 函数文件的调整方法、装置、计算机设备和存储介质 |
CN113448585A (zh) * | 2020-12-11 | 2021-09-28 | 北京新氧科技有限公司 | 一种对线程池的优化方法、装置、电子设备和存储介质 |
CN113448585B (zh) * | 2020-12-11 | 2024-01-16 | 北京新氧科技有限公司 | 一种线程池的编译方法、装置、电子设备和存储介质 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN110096338B (zh) | 智能合约执行方法、装置、设备及介质 | |
CN110609687A (zh) | 一种编译方法、装置、电子设备和存储介质 | |
JP6195849B2 (ja) | ソフトウェア・コードの生成およびキャッシング | |
CN110502222B (zh) | 外发依赖内部基础库的aar方法、装置、介质和设备 | |
US9530006B2 (en) | Method and system for performing a memory safety check of a program written in an unmanaged programming language | |
CN108984174B (zh) | 跨平台的应用创建方法、装置、服务器和存储介质 | |
US10481964B2 (en) | Monitoring activity of software development kits using stack trace analysis | |
US8561045B2 (en) | Constructing runtime state for inlined code | |
KR20150024842A (ko) | 적응식 이식가능 라이브러리 | |
US8650537B2 (en) | Optimizing an object-oriented program by transforming invocations of synthetic accessor methods | |
CN111796865B (zh) | 一种字节码文件修改方法、装置、终端设备及介质 | |
CN110764748B (zh) | 代码调用方法、装置、终端及存储介质 | |
US20190095181A1 (en) | Easy-To-Use Type Of Compile-Time Dependency Injection Method And Device In The Java Platform | |
CN113407165B (zh) | Sdk的生成和自升级方法、装置、可读介质和设备 | |
CN109739582B (zh) | 函数调用方法、装置、电子设备和计算机可读存储介质 | |
CN112882694A (zh) | 一种程序编译方法、装置、电子设备及可读存储介质 | |
CN110489180B (zh) | 一种埋点上报方法、装置、介质和电子设备 | |
US10620916B2 (en) | Read-only communication operator | |
CN111045746B (zh) | 代码扩展方法和框架 | |
CN112416303B (zh) | 软件开发工具包热修复方法、装置及电子设备 | |
CN107133169B (zh) | 应用测试包生成方法及生成装置 | |
CN117668781A (zh) | 一种授权验证包生成方法、装置、终端及存储介质 | |
CN113448585B (zh) | 一种线程池的编译方法、装置、电子设备和存储介质 | |
US20110321009A1 (en) | Implementing encryption via aspect oriented programming | |
CN112068814A (zh) | 可执行文件的生成方法、装置、系统及介质 |
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 | ||
RJ01 | Rejection of invention patent application after publication |
Application publication date: 20191224 |
|
RJ01 | Rejection of invention patent application after publication |