While JavaScript programs have become pervasive in web applications, they remain hard to reason about. In this context, most static analyses for JavaScript programs require precise call graph information, since the presence of large numbers of spurious callees significantly deteriorates precision. One of the most challenging JavaScript features that complicate the inference of precise static call graph information is read/write accesses to object fields, the names of which are computed at runtime. JavaScript framework libraries often exploit this facility to build objects from other objects, as a way to simulate sophisticated high-level programming constructions. Such code patterns are difficult to analyze precisely, due to weak updates and limitations of unrolling techniques. In this paper, we observe that precise field origination relations can be inferred by locally reasoning about object copies, both regarding to the object and to the program structure, and we propose an abstraction that allows to separately reason about field read/write access patterns working on different fields and to carefully handle the sets of JavaScript object fields. We formalize and implement an analysis based on this technique. We evaluate the performance and precision of the analysis on the computation of call graph information for examples from jQuery tutorials.
KEYWORDSabstract interpretation, JavaScript, object abstraction, static analysis, string abstraction, trace partitioning abstractionThe results in this paper are based in part on findings presented in the proceeding of APLAS'17. 840 FIGURE 1 A simplified excerpt from jQuery 1.7.2 and an example use case [Colour figure can be viewed at wileyonlinelibrary.com]One of the problematic JavaScript features that complicate the precise static call graph construction is read/write accesses to object fields, the names of which are computed at runtime. In JavaScript, an object has a set of fields, each of which consists of a name and value pair, and the field lookup and update operations take the value of an expression as an index that designates the field to read or write. JavaScript framework libraries often exploit this facility to build an object from another object by copying all the fields one by one (shallow copy) or by computing values using the fields in the source object (eg, to simulate accessor methods). To reason over such field copy or transformation patterns (for short, FCT patterns), analysis tools need to resolve precisely the fields of objects, and the relations among them.As an example, we consider the jQuery implementation of class inheritance using field copies of an object, as shown in Figure 1. To achieve that, function fix copies the fields of oE designated by the elements of array copy into array e. This copy of the fields of object oE takes place in the loop at lines 3-7. More generally, an FCT pattern boils down to an assignment of the form o1where v is a variable, o1 and o2 are two objects, f is a function over field names, and g is a function over values. ...