Closure three-address code conversion method based on static analysis

By generating three address codes and building an explicit closure structure, the problems of closure variable transmission and memory layout conflicts in dynamic languages ​​are solved, precise capture and memory optimization of closure variables are realized, and the reliability and execution efficiency of static analysis are improved.

CN120508280APending Publication Date: 2025-08-19BEIHANG UNIV
View PDF 0 Cites 0 Cited by

Patent Information

Application Number
CN202510632694.9
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2025-05-16
Publication Date
2025-08-19

AI Technical Summary

Technical Problem

When handling closure variables in dynamic typed languages, the prior art has problems such as mismatch in the delivery mechanism, memory layout conflicts and missing intermediate representations, resulting in limited code quality assurance and performance optimization.

Method used

Through static analysis, three address codes are generated, closure variable dependencies are identified, explicit closure structure is constructed and parameter passing instructions are injected to realize accurate capture of closure variables and efficient memory utilization, and adapt to dynamic language features.

Benefits of technology

It significantly improves the capture accuracy and memory efficiency of closure variables, supports cross-language compatibility, improves the reliability and execution efficiency of static analysis, and reduces memory footprint and garbage collection pressure.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN120508280A_ABST
    Figure CN120508280A_ABST
Patent Text Reader

Abstract

The invention discloses a closure three-address code conversion method based on static analysis, belongs to the technical field of computer software, and aims to solve the problem of static analysis of dynamic type language closure processing. A three-address code intermediate representation is generated through function-level modeling, a closure variable dependency relationship is searched and judged through a recursive action domain, a closure structural body is explicitly constructed, and a parameter transmission instruction is injected, so that the problems that a fixed memory layout of a traditional compiler is incompatible with a dynamic language characteristic, and an intermediate representation of a static analysis tool is missing are solved; accurate capture of closure variables, efficient memory utilization and cross-language analysis compatibility are realized, and code quality detection and performance optimization capability during operation are remarkably improved.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present invention relates to the technical field of computer software, and in particular to a closure three-address code conversion method based on static analysis. Background Art

[0002] With the prevalence of the functional programming paradigm in modern programming languages, closures, as a core feature, have been widely used in dynamically typed languages such as JavaScript, TypeScript, and ArkTS. Closures allow inner functions to capture and access variables (free variables) in outer scopes, providing powerful flexibility for scenarios such as higher-order functions and deferred execution. However, this feature also poses significant challenges for static code analysis, especially when generating intermediate representations (such as three-address code). Accurately identifying and propagating closure variables has become a pressing technical challenge.

[0003] Current static analysis techniques primarily rely on parsing the intermediate representation of a program (e.g., three-address code). When processing closures, traditional compilers (e.g., LLVM) typically store captured variables in a structure with a fixed memory layout, accessing them via offsets determined at compile time. This approach is highly efficient in statically typed languages, but it exhibits significant flaws in dynamically typed languages: dynamically typed variables may change structure at runtime (e.g., through access via the obj[key] dynamic attribute or the a?.b optional chaining operation), rendering the fixed memory layout incompatible. Furthermore, LLVM relies on manual memory management (e.g., malloc / free), which presents compatibility issues with the automatic garbage collection mechanisms of dynamic languages (e.g., the V8 engine's mark-and-sweep algorithm), further complicating closure processing.

[0004] While existing static analysis tools for dynamic languages (such as TAJS and ESLint) can perform syntax checking, type inference, and error detection, their analysis level is limited to the abstract syntax tree (AST) and lacks support for three-address code. For example, TAJS infers type information through abstract interpretation but does not generate an intermediate representation, making it difficult to support deep optimizations such as data flow analysis. ESLint focuses on code style and common errors and cannot identify cross-scope dependencies of closure variables. This lack of an intermediate representation makes it difficult for higher-level tools (such as vulnerability detection and performance optimizers) to accurately analyze the lifecycle of closure variables, scope escape, and other issues, making it impossible to effectively detect potential defects such as uninitialized variables and memory leaks.

[0005] In summary, there are two core problems in the existing technology:

[0006] 1. Insufficient static adaptation of the closure variable transfer mechanism: The fixed memory model of traditional compilers conflicts with the runtime flexibility of dynamic languages, resulting in inaccurate or inefficient capture of closure variables.

[0007] 2. Limitations of intermediate representation generation: Existing analysis tools lack the ability to generate three-address codes, making it difficult to construct explicit dependencies of closure variables, which restricts the implementation of deep static analysis.

[0008] These defects have caused bottlenecks in code quality assurance and performance optimization of dynamic languages in large-scale projects, and there is an urgent need for a closure processing solution that takes into account both dynamic characteristics and static accuracy. Summary of the Invention

[0009] The present invention aims to overcome the defects of the prior art and provides a closure three-address code conversion method based on static analysis.

[0010] In order to achieve the above object of the invention, the technical solution adopted by the present invention is as follows:

[0011] A closure three-address code conversion method based on static analysis includes the following steps:

[0012] S1. Perform static analysis on each independent function in the target code and generate a three-address code intermediate representation, including:

[0013] Assign unique identifiers to variables within the function and record the location of the variable's definition statement;

[0014] Mark variables not defined in a function as GlobalRef type and record them in the global variable table;

[0015] S2. Traverse the nested structure of functions and identify the closure dependencies between inner and outer functions, including:

[0016] Extract GlobalRef type variables from the global variable table of the internal function;

[0017] Recursively compare the local variable tables of the current outer function and the upper-level function, and establish a closure variable triple set C = {variable g, outer function m, inner function mi};

[0018] S3. Construct closure environment parameters and inject three-address code, including:

[0019] Generate a closure structure in the outer function, which contains only the outer variables actually referenced by the inner function;

[0020] Pass the closure structure as an explicit parameter to the inner function call statement;

[0021] Insert the closure variable initialization instruction into the entry code block of the inner function to bind the variables in the closure structure to the inner function scope.

[0022] Furthermore, the three-address code generation rule in step S1 includes:

[0023] Operand types include constants, local variables, reference types, and expression types;

[0024] The reference type is an intermediate representation of attribute access ab or array element access c[0].

[0025] Furthermore, the closure variable determination rules in step S2 include:

[0026] When the global variable g of the inner function mi has the same name as the local variable l of the outer function m, replace the variable g in mi with l and add the closure relation (g, m, mi) to the set C;

[0027] If no variable with the same name is found, recursively search the upper function until the project global variable table;

[0028] If the global scope does not match, an undefined variable exception is triggered.

[0029] Furthermore, the closure structure generation rules in step S3 include:

[0030] Dynamically build the memory layout based on the closure variable set C, which only includes the external variables actually referenced by the internal function;

[0031] Generate closure initialization instruction %closureX=[var1,var2,...], where X is the closure instance number and var is the captured local variable;

[0032] The closure structure is a structure or a hash table type, which are respectively applicable to statically typed languages and dynamically typed languages.

[0033] Furthermore, the parameter transfer rules in step S3 include:

[0034] When the inner function contains formal parameters, the closure structure parameters are inserted first in the parameter list;

[0035] The transfer of the closure structure is explicitly declared through a three-address code call statement, the format of which is call function name (closure parameters, original parameters...).

[0036] Furthermore, the generation rules of the closure variable initialization instruction in step S3 include:

[0037] Insert variable binding instruction at the header of the internal function entry basic block, the format is $variable name=%closureX.field name;

[0038] Generates sequential initialization instructions for multiple closure variables, with priority arranged from near to far along the scope chain.

[0039] The present invention also discloses a computer-readable storage medium storing a computer program, characterized in that when the program is executed by a processor, the steps of the closure three-address code conversion method described in any one of claims 1-6 are implemented.

[0040] Compared with the prior art, the advantages of the present invention are:

[0041] 1. Realize accurate capture and scope binding of closure variables

[0042] By leveraging a global variable table (GlobalRef) and a recursive scope search mechanism, this paper effectively identifies closure dependencies between nested functions, avoiding the variable omissions and misjudgments often encountered by traditional methods due to dynamic language type changes. In projects like JavaScript and TypeScript, this paper accurately tracks cross-scope variable references, significantly reducing code defects caused by undefined closure variables or scope escapes, and improving the reliability of static analysis.

[0043] 2. Optimize the memory efficiency and dynamic adaptability of the closure environment

[0044] Explicitly generated closure structures (e.g., %closureX) encapsulate only external variables that are actually referenced, reducing memory usage by over 30% compared to the full variable capture strategy of traditional compilers (e.g., LLVM). Furthermore, this structure supports dynamically typed language features (e.g., dynamic property access and optional chaining), avoiding runtime performance degradation or crashes caused by memory layout conflicts.

[0045] 3. Provide a standardized intermediate representation basis

[0046] By standardizing the three-address code generation rules (such as operand type restrictions and variable unique identifier assignment), this invention provides a unified intermediate representation format for higher-level tools such as vulnerability detection and performance optimization. Tools can directly perform in-depth processing such as data flow analysis and dead code elimination based on the three-address code, reducing the development cost of adapting to the grammatical characteristics of different languages.

[0047] 4. Enhance cross-language and multi-tool compatibility

[0048] The closure structure supports both statically typed languages (structs) and dynamically typed languages (hash tables), seamlessly adapting to multiple languages such as JavaScript, TypeScript, and ArkTS. This design allows for rapid integration of the invention with existing compilers (such as LLVM) and analysis tools (such as ESLint), extending closure processing capabilities without refactoring the underlying architecture.

[0049] 5. Significantly improve code analysis and execution efficiency

[0050] The explicit initialization mechanism for closure variables replaces the traditional lazy loading strategy, reducing runtime dynamic parsing overhead. In closure-intensive scenarios (such as nested high-order function calls), static analysis speeds are increased by 20%-40%. Accurate dependency analysis also reduces redundant memory allocations, lowers garbage collection pressure, and optimizes overall resource utilization. BRIEF DESCRIPTION OF THE DRAWINGS

[0051] Figure 1 This is a schematic diagram of the static analysis modeling structure of the function in an embodiment of the present invention;

[0052] Figure 2 This is a diagram of a closure variable determination algorithm according to an embodiment of the present invention;

[0053] Figure 3 Schematic diagram of three-address code injection of closure information according to an embodiment of the present invention. DETAILED DESCRIPTION

[0054] In order to make the objectives, technical solutions and advantages of the present invention more clearly understood, the present invention is further described in detail below with reference to the accompanying drawings and examples.

[0055] The present invention provides a closure three-address code conversion method based on static analysis, which fills closure information into the three-address code through the following steps:

[0056] 1. Use static analysis techniques to independently analyze and model each function in the project, construct each Stmt and convert it into three-address code. For the needs of upper-level analysis, instantiate the variables in each Stmt and record the def information within the function (that is, the definition statement of the variable within the function). If the variable does not have definition information in the function, it is temporarily regarded as a global variable, initialized to a special variable type GlobalRef, and added to the global variable table of the function.

[0057] 2. After generating the three-address code statements for all functions, determine whether there are inner functions. If so, closure variable processing is required. In this case, the original function is called the "outer function," and the functions inside the outer function (defined functions, arrow functions, anonymous functions) become the "inner functions." First, traverse the global variable table of the inner function. If there are variables with the same name as the local variables of the outer function, it means that the inner function uses the variables of the outer function, and closure is used.

[0058] 3. Next, count all variables used by the inner function, store them in the closure variable, and pass the closure information to the inner function through function parameters. Add a new three-address code statement at the beginning of the inner function's code block, which initializes the closure and the closure variables through the closure.

[0059] The details of the above steps are described in detail below;

[0060] 4.1 Function-level static analysis and three-address code generation

[0061] like Figure 1 As shown, the present invention first performs static analysis and modeling on all independent functions (including ordinary functions, arrow functions, and anonymous functions) in the project. Each function (Method) consists of multiple basic code blocks (Block), each code block contains a series of statements (Stmt) executed sequentially, and each statement consists of several variables or operands (Value). During the modeling process, a unique identifier is assigned to each variable, and its basic information, including name, type, and definition information (def), is recorded. The definition information is used to identify the definition position of the variable in the function, that is, the statement where it is first assigned or declared. If a variable does not find definition information in the function, it is determined to be a potential global variable and initialized to a special type GlobalRef, indicating that the variable may belong to the global scope or the outer closure environment. Such variables will be recorded in the global variable table of the function, which contains the name of the variable, the reference location, and the scope level at which it first appears, so as to facilitate subsequent closure analysis and accurate identification of variable dependencies.

[0062] After completing the function modeling, the present invention converts the statements (Stmt) in the source code into a three-address code form. The three-address code is a low-complexity intermediate representation, which is characterized by each instruction containing a maximum of three operands and only supporting fixed types of operation types, such as assignment statements, function call statements, and control flow jump statements. The operands (Value) in the three-address code are divided into multiple types, including constants (Constant, such as the numeric constant 5 or the string constant 's'), local variables (Local), references (Ref, such as attribute access ab or array element access c[0]) and expressions (Expr, such as function call expressions or arithmetic expressions). By converting the source code into three-address code, the present invention realizes the standardization of the intermediate representation and provides a unified input format for subsequent static analysis and optimization. In addition, during the generation of the three-address code, each variable and operand is assigned a unique identifier to ensure its uniqueness and traceability in the intermediate representation, thereby supporting accurate variable tracking and closure variable capture.

[0063] Through the above functions, the present invention can accurately identify the variable definitions and reference relationships within the function, and the generated intermediate representation is highly standardized and scalable, which facilitates further analysis and processing by upper-level tools (such as vulnerability detection and performance optimization).

[0064] 4.2 Closure variable determination

[0065] After the three-address code statements of all functions are generated, it is necessary to start collecting the closure variables used by all functions in the project. The algorithm is as follows Figure 2 As shown. The input of the algorithm is the set M of all functions in the project, and the output is the set C of closure variables used, where each element of C is a ternary table, representing closure variables, external functions, and internal functions respectively. For each function m, first use the method innerMethod to find its internal function mi (i.e., nested function). If it exists, closure variable processing is required. At this time, the original function is called an "external function", and the function defined inside the external function (including ordinary defined functions, arrow functions, and anonymous functions) is called an "internal function". Next, process the internal variables of mi

[0066] Specifically, the present invention realizes the identification and processing of closure variables through the following steps: First, all variables marked as GlobalRef are extracted from the global variable table of the internal function. These variables are not defined in the internal function, but may belong to the scope of the external function and are stored in the global variable table globals(mi) of the internal function. The present invention first traverses each variable g in globals(mi) and uses the method sameName to check whether there is a variable l in the local variable table locals(m) of the external function with the same name as g. If there is a variable with the same name, it means that the internal function references the local variable of the external function, that is, there is the use of closure variables. This reference relationship indicates that the internal function depends on the scope of the external function and needs to be captured and passed through the closure mechanism. At this time, all the variables g in the internal function mi are updated to l, and the element (g, m, mi) is added to the closure set C.

[0067] If there are no identically named variables in globals(mi) and local(m), this indicates that g likely originated from a function in a higher level. Therefore, the outerMethod method is used to continue traversing the outer functions of m, returning to line 6 to continue the algorithm until the corresponding variable is found. If no outer functions exist and no closure variable is found, the algorithm determines whether a global variable G with the same name as g exists in the project's global variable table, GLOBALS. If so, G replaces the variable g in the inner function mi. Otherwise, the variable g in that function has no defined source, and an exception is thrown. Once all functions have been processed, the algorithm terminates, returning the closure variable set C.

[0068] 4.3 Closure variable construction and three-address code injection

[0069] Next, the present invention fills the closure information collected according to the previous steps into the three-address code. First, for each function, generate the external variables used by its internal functions and generate the corresponding closure variables. For example Figure 3In the example in the upper part, function f2 is an inner function of function f1, and uses variable x of f1. After the initial generation of the three-address code, function f2 directly uses the undefined variable x, which is obviously incorrect. Therefore, it is necessary to generate a closure variable %closure0 in f1, which records the local variable x of f1 used in f2 (corresponding to the statement %closure0=[x]), and pass %closure0 as a parameter to f2 when calling function f2 (corresponding to the statement f2(%closure0)). In function f2, %closure0 and variable x need to be initialized at the beginning (corresponding to the statement x=%closure0.x) to avoid the situation where undefined variables are used directly.

[0070] Figure 3 The complex example in the second half further demonstrates the universality and refined processing capabilities of this invention. Function f3 defines three number-type variables, num1, num2, and num3. It then defines an arrow function that assigns a value to the variable add. The arrow function takes a parameter a and returns a + num1 + num2. Finally, function f3 calls the add function, passing it parameter 2, and prints the return value. This example is more complex than the previous one in several ways. First, the inner function is an arrow function and is not explicitly defined. To address this, it must be explicitly declared as %Af3 in the three-address code (corresponding to the declaration def %Af3). Second, the outer function f3 defines multiple variables, two of which are used by the inner function. This requires the closure variable %closure to be defined with multiple variables and not with unused variables (corresponding to the statement %closure0 = [num1, num2]). Each outer variable must also be defined separately when the inner function is initialized (corresponding to the statements num1 = %closure0.num1 and num2 = %closure0.num2). Furthermore, the inner function itself contains a parameter a, so the closure variable is inserted at the first position. This requires changing the position of parameter a and the statement assigning a value in the three-address code (corresponding to the statement a = %parameter1). This process not only resolves the problem of multiple variable capture and parameter position conflicts, but also achieves a minimal construction of the closure environment through precise variable screening and memory layout optimization, significantly reducing runtime memory overhead while ensuring full compatibility of the three-address code with dynamic language features.

[0071] In another embodiment of the present invention, a storage medium is provided, specifically a computer-readable storage medium (Memory), which is a memory device in a terminal device for storing programs and data. It can be understood that the computer-readable storage medium here can include both the built-in storage medium in the terminal device and, of course, the extended storage medium supported by the terminal device. The computer-readable storage medium provides a storage space, which stores the operating system of the terminal. In addition, one or more instructions suitable for being loaded and executed by the processor are also stored in the storage space. These instructions can be one or more computer programs (including program codes). It should be noted that the computer-readable storage medium here can be a high-speed RAM memory or a non-volatile memory, such as at least one disk memory.

[0072] One or more instructions stored in a computer-readable storage medium can be loaded and executed by a processor to implement the corresponding steps of a closure three-address code conversion method based on static analysis in the above embodiment; one or more instructions in a computer-readable storage medium are loaded and executed by a processor.

[0073] It will be understood by those skilled in the art that embodiments of the present invention may be provided as methods, systems, or computer program products. Thus, the present invention may take the form of an entirely hardware embodiment, an entirely software embodiment, or an embodiment combining software and hardware. Furthermore, the present invention may take the form of a computer program product implemented on one or more computer-usable storage media (including but not limited to magnetic disk storage, CD-ROM, optical storage, etc.) containing computer-usable program code.

[0074] The present invention is described with reference to flowcharts and / or block diagrams of methods, devices (systems), and computer program products according to embodiments of the present invention. It should be understood that each process and / or block in the flowcharts and / or block diagrams, as well as combinations of processes and / or blocks in the flowcharts and / or block diagrams, can be implemented by computer program instructions. These computer program instructions can be provided to a processor of a general-purpose computer, a special-purpose computer, an embedded processor, or other programmable data processing device to produce a machine, so that the instructions executed by the processor of the computer or other programmable data processing device generate instructions for implementing the processes in the flowcharts and / or block diagrams. Figure 1 a process or multiple processes and / or boxes Figure 1 A device that provides the functions specified in a block or multiple blocks.

[0075] These computer program instructions may also be stored in a computer readable memory that can direct a computer or other programmable data processing device to work in a specific manner, so that the instructions stored in the computer readable memory produce an article of manufacture comprising an instruction device, which implements the process Figure 1 a process or multiple processes and / or boxes Figure 1 The function specified in one or more boxes.

[0076] These computer program instructions can also be loaded onto a computer or other programmable data processing device so that a series of operational steps are executed on the computer or other programmable device to produce a computer-implemented process, thereby providing the instructions executed on the computer or other programmable device for implementing the process. Figure 1 a process or multiple processes and / or boxes Figure 1 A step that specifies a function in one or more boxes.

[0077] Those skilled in the art will appreciate that the embodiments described herein are intended to help readers understand the implementation methods of the present invention, and it should be understood that the scope of protection of the present invention is not limited to such specific descriptions and embodiments. Those skilled in the art can make various other specific variations and combinations based on the technical teachings disclosed in the present invention without departing from the essence of the present invention, and such variations and combinations are still within the scope of protection of the present invention.

Claims

1. A closure three-address code conversion method based on static analysis, characterized in that: The following steps are involved: S1. Perform static analysis on each independent function in the target code and generate a three-address code intermediate representation, including: Assign unique identifiers to variables within the function and record the location of the variable's definition statement; Mark variables not defined in a function as GlobalRef type and record them in the global variable table; S2. Traverse the nested structure of functions and identify the closure dependencies between inner and outer functions, including: Extract GlobalRef type variables from the global variable table of the internal function; Recursively compare the local variable tables of the current outer function and the upper-level function, and establish a closure variable triple set C = {variable g, outer function m, inner function mi}; S3. Construct closure environment parameters and inject three-address code, including: Generate a closure structure in the outer function, which contains only the outer variables actually referenced by the inner function; Pass the closure structure as an explicit parameter to the inner function call statement; Insert the closure variable initialization instruction into the entry code block of the inner function to bind the variables in the closure structure to the inner function scope.

2. The closure three-address code conversion method according to claim 1, characterized in that: The three-address code generation rules in step S1 include: Operand types include constants, local variables, reference types, and expression types; The reference type is an intermediate representation of attribute access ab or array element access c[0].

3. The closure three-address code conversion method according to claim 1, characterized in that: The closure variable determination rules in step S2 include: When the global variable g of the inner function mi has the same name as the local variable l of the outer function m, replace the variable g in mi with l and add the closure relation (g, m, mi) to the set C; If no variable with the same name is found, recursively search the upper function until the project global variable table; If the global scope does not match, an undefined variable exception is triggered.

4. The closure three-address code conversion method according to claim 1, characterized in that: The closure structure generation rules in step S3 include: Dynamically build the memory layout based on the closure variable set C, which only includes the external variables actually referenced by the internal function; Generate closure initialization instruction %closureX=[var1,var2,...], where X is the closure instance number and var is the captured local variable; The closure structure is a structure or a hash table type, which are respectively applicable to statically typed languages and dynamically typed languages.

5. The closure three-address code conversion method according to claim 1, characterized in that: The parameter transfer rules in step S3 include: When the inner function contains formal parameters, the closure structure parameters are inserted first in the parameter list; The transfer of the closure structure is explicitly declared through a three-address code call statement, the format of which is call function name (closure parameters, original parameters...).

6. The closure three-address code conversion method according to claim 1, characterized in that: The generation rules of the closure variable initialization instruction in step S3 include: Insert variable binding instruction at the header of the internal function entry basic block, the format is $variable name=%closureX.field name; Generates sequential initialization instructions for multiple closure variables, with priority arranged from near to far along the scope chain.

7. A computer-readable storage medium storing a computer program, characterized in that: When the program is executed by a processor, the steps of the closed three-address code conversion method according to any one of claims 1 to 6 are implemented.