<?xml version="1.0" encoding="UTF-8"?>
<TEI xml:space="preserve" xmlns="http://www.tei-c.org/ns/1.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.tei-c.org/ns/1.0 https://raw.githubusercontent.com/kermitt2/grobid/master/grobid-home/schemas/xsd/Grobid.xsd"
 xmlns:xlink="http://www.w3.org/1999/xlink">
	<teiHeader xml:lang="en">
		<fileDesc>
			<titleStmt>
				<title level="a" type="main">Aran: JavaScript Instrumentation for Heavyweight Dynamic Analysis</title>
			</titleStmt>
			<publicationStmt>
				<publisher/>
				<availability status="unknown"><licence/></availability>
			</publicationStmt>
			<sourceDesc>
				<biblStruct>
					<analytic>
						<author>
							<persName><forename type="first">Laurent</forename><surname>Christophe</surname></persName>
							<affiliation key="aff0">
								<orgName type="laboratory">Software Languages Lab</orgName>
								<orgName type="institution">Vrije Universiteit Brussel</orgName>
								<address>
									<country key="BE">Belgium</country>
								</address>
							</affiliation>
							<affiliation key="aff0">
								<orgName type="laboratory">Software Languages Lab</orgName>
								<orgName type="institution">Vrije Universiteit Brussel</orgName>
								<address>
									<country key="BE">Belgium</country>
								</address>
							</affiliation>
						</author>
						<author>
							<persName><forename type="first">Coen</forename><surname>De Roover</surname></persName>
							<affiliation key="aff0">
								<orgName type="laboratory">Software Languages Lab</orgName>
								<orgName type="institution">Vrije Universiteit Brussel</orgName>
								<address>
									<country key="BE">Belgium</country>
								</address>
							</affiliation>
						</author>
						<author>
							<persName><forename type="first">Wolfgang</forename><surname>De Meuter</surname></persName>
							<affiliation key="aff0">
								<orgName type="laboratory">Software Languages Lab</orgName>
								<orgName type="institution">Vrije Universiteit Brussel</orgName>
								<address>
									<country key="BE">Belgium</country>
								</address>
							</affiliation>
						</author>
						<author>
							<persName><forename type="first">Workshop</forename><surname>Ceur</surname></persName>
							<affiliation key="aff0">
								<orgName type="laboratory">Software Languages Lab</orgName>
								<orgName type="institution">Vrije Universiteit Brussel</orgName>
								<address>
									<country key="BE">Belgium</country>
								</address>
							</affiliation>
						</author>
						<author>
							<persName><surname>Proceedings</surname></persName>
							<affiliation key="aff0">
								<orgName type="laboratory">Software Languages Lab</orgName>
								<orgName type="institution">Vrije Universiteit Brussel</orgName>
								<address>
									<country key="BE">Belgium</country>
								</address>
							</affiliation>
						</author>
						<title level="a" type="main">Aran: JavaScript Instrumentation for Heavyweight Dynamic Analysis</title>
					</analytic>
					<monogr>
						<idno type="ISSN">1613-0073</idno>
					</monogr>
					<idno type="MD5">61BF6B5C1270425027F55E165C32ABBD</idno>
				</biblStruct>
			</sourceDesc>
		</fileDesc>
		<encodingDesc>
			<appInfo>
				<application version="0.7.2" ident="GROBID" when="2025-04-23T19:00+0000">
					<desc>GROBID - A machine learning software for extracting information from scholarly documents</desc>
					<ref target="https://github.com/kermitt2/grobid"/>
				</application>
			</appInfo>
		</encodingDesc>
		<profileDesc>
			<textClass>
				<keywords>
					<term>JavaScript</term>
					<term>Dynamic Program Analysis</term>
					<term>Shadow Execution</term>
					<term>Source Code Instrumentation</term>
					<term>Aspect-Oriented Programming</term>
				</keywords>
			</textClass>
			<abstract>
<div xmlns="http://www.tei-c.org/ns/1.0"><p>We introduce aran, a novel approach for developing heavyweight dynamic analyses of JavaScript programs. Our approach is broadly applicable, relying solely on source code instrumentation. It also supports complex customization through an intuitive aspect-oriented API, which consists of 31 entry points. With about 300 lines of code, our API can express an analysis that computes the symbolic execution tree of run-time values. Importantly, our approach preserves the semantics of the program under analysis. We implemented this approach in a tool and validated it using Test262, the official JavaScript conformance test suite, achieving a 99.7% success rate and observing performance slowdowns rarely exceeding 10x.</p></div>
			</abstract>
		</profileDesc>
	</teiHeader>
	<text xml:lang="en">
		<body>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="1.">Introduction</head><p>JavaScript is a popular and versatile programming language that is the de facto standard for web development. It is also infamously known to be hard to analyze statically due to its dynamic nature. And so, insights into the behavior of JavaScript programs must often be gathered dynamically. In practice, only so-called "lightweight" dynamic program analyses, such as code coverage and profiling, are commonly deployed. Nonetheless, there exists another class of so-called "heavyweight" dynamic analyses. Examples include: taint analysis which is capable of detecting violations of security policies, and concolic testing which is capable of automatically generating test cases. These analyses share the need to track values at run-time especially primitive values -e.g., tracking strings such as password data is crucial for taint analysis. This is commonly achieved through a technique called shadow execution, which involves mirroring part of the program state with meta information. Although these heavyweight dynamic analyses have their merits, they are rarely used in practice. We hypothesize three main reasons for this lack of adoption: Narrow Applicability: Academic approaches are often unsuitable for real-world deployment because they depend on a modified JavaScript runtime. While this may be effective for controlled experiments on a specific corpus of programs, it is typically impractical for real-world scenarios. JavaScript is deployed across a diverse and rapidly evolving ecosystem of runtimes, both on the client and server sides. For broader adoption, analyses must be applicable across a wide range of use cases.</p><p>Complex Customization: Heavyweight dynamic analyses are inherently complex and demand a high level of customization to yield meaningful results. For example, taint analysis involves specifying sources and sinks, while concolic testing requires mechanisms to generate new inputs. To encourage adoption, such analyses must offer an expressive interface that supports extensive customization while remaining concise and easy to understand.</p><p>BENEVOL24: The 23rd Belgium-Netherlands Software Evolution Workshop, November 21-22, Namur, Belgium laurent.christophe@vub.be (L. Christophe); coen.de.roover@vub.be (C. De Roover); wolfgang.de.meuter@vub.be (W. De Meuter) https://lachrist.github.io (L. Christophe); https://soft.vub.ac.be/~cderoove (C. De Roover) 0009-0001-5294-0585 (L. Christophe); 0000-0002-1710-1268 (C. De Roover); 0000-0002-5229-5627 (W. De Meuter)</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.">aran's Overview</head><p>The main idea behind aran is to express analysis as logic. So during analysis, two layers will coexist inside the same JavaScript program: the layer of the program under analysis, which we call the base layer and the layer of the analysis, which we call the meta layer. A natural way to weave the logic of the analysis into the target program is to rely on aspect-oriented programming [1] which entails expressing the logic of the analysis in JavaScript as well. In this paradigm, behaviors which are collectively called advice are inserted at execution points called join points according to a specification called pointcut. This action is called weaving. The combination of an advice and a pointcut is called an aspect. Hence, in our approach, an analysis is expressed as an aspect. In Listing 1, we present a simple aspect that logs the call stack of a program by inserting logic around every function application of the target program. aran focuses on weaving the user analysis into the target program by performing source code transformation while the actual deployment is left to the user. This is a design choice that we made to ensure that the approach remains broadly applicable. Indeed, integrating an analysis into a build system or a CI/CD pipeline is a non-trivial task and goes beyond the scope of this paper. We envision two main architectures for deploying aran.</p><p>First is offline deployment, which is depicted in Figure <ref type="figure" target="#fig_0">1</ref>. In this architecture, the analysis happens in two separate processes that run sequentially. In the first process, the target program is instrumented based on the pointcut of the analysis, and the setup code is generated. Then, these two parts are bundled with the advice of the analysis, which creates a standalone JavaScript program. The analysis will be performed once this program is executed as it would have been originally. This architecture is useful to reduce the memory footprint and performance overhead of the analysis.</p><p>Second is online deployment, which is depicted in Figure <ref type="figure" target="#fig_2">2</ref>. In this architecture, everything happens in a single JavaScript process. That is, the runtime must be parameterized to preload aran and instrument the target program at load-time. This architecture is more likely to impact the behavior of the target program and requires engine parameterization, but it enables instrumentation of dynamically generated code. While global code does not necessarily need to be instrumented, code evaluated by a direct eval export const initialState = { depth: 0 }; export const aspect = { pointcut: ["apply@around"], advice: { "apply@around": (state, callee, thisArgument, argumentList, path) =&gt; { state.depth += 1; try { console.log(".".repeat(state.depth) + " &gt;&gt; " + callee.name + " at " + path); const result = Reflect.apply(callee, thisArgument, argumentList); console.log(".".repeat(state.depth) + " &lt;&lt; " + callee.name + " at " + path); return result; } catch (error) { console.log(".".repeat(state.depth) + " !! " + callee.name + " at " + path);   call imperatively does. Otherwise, the base layer of the target program will be able to access the meta layer of the analysis. It follows that direct eval calls are only supported in this architecture.</p><p>We are aware that these architectures are work-intensive for the user. In the future, we plan to investigate how relevant functionalities could be provided for common workflows. For instance, offline architecture could benefit from a CLI that would expect a selection of files to instrument and would bundle the standalone JavaScript program. And the online architecture could benefit from a tool able to parameterize various JavaScript runtimes to instrument the target program at load-time.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.">aran's Intermediate Language</head><p>Instead of directly weaving the analysis logic in JavaScript, our approach performs weaving in an intermediate language instead. If weaving were to be performed directly in JavaScript, the aspectoriented API would require such a high number of different join points that it would make the approach hard to customize. This is due to the fact that JavaScript has become quite a complex language over the years. Indeed, since 2015, the TC39 committee, which is in charge of maintaining ECMAScript -i.e., the de facto standard specification of JavaScript -has accelerated the rate at which new features are introduced and switched to a yearly release cycle. While this has kept JavaScript fresh and relevant, it has also rendered it more difficult to analyze. Our intermediate language is called aran-lang and was designed with the following three criteria in mind:</p><p>Minimal: aran-lang should be as simple as possible to enable the user to express complex analyses that require shadow execution in a clear and concise manner. The ultimate goal of aran-lang is to restore the core simplicity of JavaScript, but it is constrained by the other two criteria.</p><p>JavaScript Subset: aran-lang should be reasonably close to a subset of JavaScript so that aran's API remains understandable to JavaScript developers. We do not want developers to have to study this intermediate language to be able to properly use our approach.</p><p>Expressive: aran-lang should be sufficiently expressive to support the full ECMAScript specification without requiring excessive additional logic. Indeed, while additional logic is necessary to express complex features using simpler ones, it should be kept to a minimum to reduce code bloat and performance overhead. Also, this additional logic will look unfamiliar to the end user of the analysis and could make the results of the analysis hard to interpret.</p><p>Being an intermediate compilation language, aran-lang does not require an actual syntax. Instead, in Appendix B, we present the AST format of aran-lang as a TypeScript type definition. In the remainder of this section, we discuss several points of interest regarding the language.</p><p>Strict Mode Only JavaScript can be executed in two modes: strict mode and sloppy mode. In strict mode, some errors are thrown instead of being ignored, and some features, such as the with statement are disabled. These features are often considered legacy and preclude JavaScript runtimes from carrying out important optimizations. We made the design decision to always output instrumented code in strict mode. While this completely hides the complexity of dealing with two modes from the user, it forces us to remove all the sloppy-only features of JavaScript from aran-lang.</p><p>Intrinsic Record Often, logic added by aran involves accessing pre-existing values from the global object. These values are usually referred to as intrinsic values. For instance, the regexp literal /pattern/u can be expressed as new • RegExp("pattern","u"). In doing so, we have to ensure that the variable RegExp still refers to the intrinsic %RegExp%. In aran-lang, intrinsic values can be retrieved by name with No Imported Variable In a JavaScript module, values from external modules are imported as local variables. These variables are one-way bound to the external value -i.e., they are locally immutable, but mutations from within their source module are reflected. Hence, they can be viewed as syntactic sugar for their external location and be removed from the local scope. In aran-lang, this is made explicit by ImportExpression, which contains a Source and a Specifier.</p><p>No Exported Variable In a JavaScript module, local variables can be exported, and any modification to those variables will be visible from other modules. In aran-lang, this coupling is made explicit through an ExportEffect which contains a Specifier for the name of the export and an Expression for the new value of the export. Note that export operations are made into effects for the same reason as write operations.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Explicit Variable Hoisting</head><p>In JavaScript, variables are actually declared earlier than where their declaration appears. This process is referred to as hoisting and is a common source of confusion. In aran-lang, variables are always declared at the beginning of the block where they are hoisted. This translates in aran-lang by the absence of declaration statements and the presence of a list of bindings in RoutineBlock and ControlBlock. An important behavior that we had to recreate is the temporal deadzone. This timing window spans the moment from where a variable is hoisted to where the declaration statement actually resides. Accessing variables in this temporal deadzone should result in a run-time error, which we implemented through run-time checks. Note that variables in aran-lang have no kind, and that their immutability is also enforced with run-time checks.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Static Variable Access</head><p>In JavaScript, different types of dynamic frames can reside in a scope. The global object which is at the root every scope and the global declarative record which sits just after the global object are both important instances of dynamic frame. However, the with construct and direct calls to %eval% can also introduce dynamic frames. In aran-lang, we decided to make the scope static by reifying dynamic frames. Combined with immutability checks and deadzone checks, this means that read and write operations cannot throw exceptions and cannot trigger arbitrary code. This is an important property of aran-lang because it enables the analysis to not check for the result of these operations.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Hard-Coded Parameter Set</head><p>For the sake of simplicity, aran-lang does not allow for parameter renaming. Instead, all parameters have a fixed name. Some of these parameters already exist in JavaScript -e.g., this, new.target, and import.meta. Some other parameters had to be introduced -e.g., function.callee, function.arguments, and catch.error. We introduced function.arguments to replace the traditional arguments parameter for two reasons: it is sometimes missing, and it is plagued by legacy features -e.g., 'arguments.callee' and index binding with parameters. Finally, some parameters are functions that are introduced to simplify the language and its associated weaving API -e.g., import for representing dynamic import expressions. However, this is not a silver bullet because the analysis must still reason about the meaning of these functions.</p><p>Explicit this Argument JavaScript implements object-oriented programming by passing a hidden argument that is assigned to the this parameter. In aran-lang, the this argument is explicitly provided to ApplyExpression. Thus, xs.map(f) becomes something like apply((_this_=xs).map,_this_,[f])<ref type="foot" target="#foot_0">1</ref> .</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Mandatory Result Value</head><p>In JavaScript, programs complete with a value based on their last value statement, and functions return a value provided by an optional return statement. Because this behavior is hard to reason about, aran-lang represents the body of these two constructs as a RoutineBlock, which is parameterized by an expression that is evaluated last and provides the result value of the program or the function. break statements are used to model the control flow of return statements.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Preserved Generator Head</head><p>In JavaScript, the code in the parameters of functions can be arbitrarily complex. Our parameter system allowed us to move that logic into the body of functions, which simplifies analysis. Unfortunately, we were not able to apply this simplification for generator functions. This is because the code in the parameters of generator functions is not executed at the same time as the code in its body <ref type="bibr" target="#b1">2</ref> . Consequently, we had to add an array of Effect nodes into RoutineBlock to store the head of generator functions.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4.">aran's Aspect-Oriented API</head><p>The main parameter of the weaving process is the pointcut, which can be seen as a predicate for deciding which join points should be intercepted. There is another important option that dictates whether the instrumented code should access the built-in original global declarative record or use a plain object that reifies it. To preserve the safety of variable access, if the built-in global declarative record is used, global variables will be accessed with custom intrinsic functions such as %aran.readGlobal%. These functions become unnecessary if the global declarative record is emulated. This is an advantage because the advice will not have to reason about these aran-specific intrinsic functions. However, emulating the global declarative record requires instrumenting every single bit of code from the target program to ensure the emulation is not bypassed. As selective instrumentation is an important feature, we envisioned both options.</p><p>Interestingly, the logic of the analysis is not directly woven into the target program. Instead, the advice is called by the instrumented code and is expected to adhere to the advice interface presented in Appendix A. Because aran-lang was designed to enable shadow execution, this interface is almost a one-to-one mapping with the aran-lang AST format. The only weaving that is not straightforward is related to blocks:</p><p>• First, analyses should be able to reason about the scope and should receive a reified frame upon entering each block. This is provided as a mapping from local variables and parameters to initial values. Variables declared with the var and function keywords are initialized with the %undefined% intrinsic while variables declared through the let and const keywords are initialized with the %aran.deadzone% intrinsic. Reified block frames are provided to both block@declaration and block@declaration-overwrite. These two join points are similar, but the latter enables the analysis to overwrite the initial value of a variable which is useful for analysis based on wrappers.</p><p>• Second, analyses should be able to reason about control flow. To that end, we provide the block@throwing join point which is triggered when the block throws an exception. And, we provide the block@teardown join point which is triggered upon exiting the block regardless of how it terminated. If either of these join points is intercepted, the block will have to be wrapped inside a try statement.</p><p>To facilitate state management, every single advice receives a local state as the first argument. This local state can be updated upon entering a block with the block@setup advice. This makes it easy to implement list-like data structures and mirror the scope of the program. Local states are also useful for restoring the context of the analysis after a hiatus in the control flow caused by yield and await expressions.</p><p>To locate the AST node that triggered the advice, every single advice receives the path of its triggering node as the last argument. More precisely, this argument is a string that represents the chain of properties leading to the triggering node -e.g., "$.body.0.expression". Other approaches, such as Jalangi [2], use indices instead. While indices should be faster in theory, they also make the overall interface more complex. We decided this was not worth the performance improvement which is likely to be minor thanks to optimizations such as string interning. Listing 2: The shadow state of our track-origin analysis.</p><p>To evaluate the expressiveness of our approach, we implemented an analysis called track-origin that records the execution tree of run-time values <ref type="bibr" target="#b2">3</ref> . This analysis can be leveraged to carry out analyses based on symbolic execution such as concolic testing. Our analysis consists of approximately 300 LoC and can handle all the corner cases of JavaScript. Listing 2 defines the state of the analysis as a TypeScript type definition that mirrors both the value stack and the scope. The code of the analysis is clear and concise; the only logic that we needed to implement involved the transient tracking of shadow values before and after calls to instrumented functions.</p><p>It remains an open question whether our API is suitable for implementing analyses truly on a per-project basis. In the negative, we could introduce a domain-specific language for defining the analyses. Alternatively, we could provide a suite of JavaScript APIs, each designed for a specific class of heavyweight dynamic analysis.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="5.">Evaluating aran Against Test262</head><p>To evaluate the reliability of our approach, we implemented it in a tool <ref type="bibr">4 5</ref> and tested it against Test262<ref type="foot" target="#foot_5">6</ref> , which is the official conformance test suite of ECMAScript. It contains about 50, 000 test cases that cover the entire ECMAScript specification and even upcoming proposals. We conducted our experiment on the setup described in Table <ref type="table">1</ref>. It consists of applying increasingly complex instrumentation to Test262 cases. At every stage, we excluded the test cases that failed in the previous stages. This helped us to triage failures and diagnose bugs. We describe below our six instrumentation stages <ref type="bibr" target="#b6">7</ref> ; each based on the online architecture depicted in Figure <ref type="figure" target="#fig_2">2</ref>.</p><p>1. engine: Leaves test cases intact. This stage is intended to uncover the technical limitations of either the underlying node runtime or our custom test runner. It also provides a basis to compute the slowdown factors for subsequent stages.</p><p>Laurent Christophe et al.</p><note type="other">CEUR Workshop Proceedings 1-18</note><p>Hardware Apple Air M2, 2022 node Version v22.3.0 Test262 Commit SHA: 18ebac81 <ref type="bibr" target="#b7">8</ref> aran Commit SHA: 664f0a30 9 acorn Version 8.12.1 10 astring Version 1.9.0 11</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Table 1</head><p>Setup for testing aran against Test262  3. main-min: Applies minimal aran instrumentation to the main file of each test case. Test fixtures, module dependencies, and dynamic global code are not instrumented. However, dynamic local code must be instrumented at the eval@before join point which is the only pointcut of this stage. Note that even though weaving is minimal, the source code undergoes many during its transformation from JavaScript to aran-lang.</p><p>4. full-min: Still applies minimal aran instrumentation, but on every single bit of the code of each test case. This provides us with the opportunity to test the emulation of the global declarative record. This requires advising not only eval@before but also apply@around and construct@around to intercept and instrument dynamic global code provided to the %eval% intrinsic and %Function% intrinsic. Note that this simple access control system does not intercept indirect applications of intrinsic functions -e.g., eval.call("code").</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="5.">part-max:</head><p>Applies maximal aran instrumentation to the main file of each test case. In this stage, every join point is advised by a function that contains no logic. -e.g., apply@around is advised by (ste,fct,ths,args)=&gt;Reflect.apply(fct,ths,args).</p><p>6. track-origin: Our analysis for recording the execution tree of run-time values as presented in Section 4. It is applied to the main file of each test case.</p><p>Figure <ref type="figure" target="#fig_4">3</ref> depicts an overview of the results of our experiment. (i) Stage engine introduces about 15k failures, which corresponds to a failure rate of about 12%; by far the highest. Most of these failures were due to features that have not yet been implemented in node such as the new Temporal API, which accounts for more than 4k failures. Other failures were due to our test runner not entirely adhering to the interface prescribed by Test262 <ref type="bibr" target="#b11">12</ref> . For instance, some parts of this interface relate to inter-realm communication which occurs via built-in function calls. Whereas, we are interested in preserving the semantics of syntactic constructs. We also discovered actual bugs in node, and we reported some of them <ref type="bibr">13 14 15</ref> . (ii) Stage parsing introduces 198 failures, which were mostly due to acorn not correctly handling corner cases. (iii) The failures introduced by subsequent stages which actually deploy aran are limited in number (143). They provide a good overview of the limitations of our tool as they highlight the semantics that we were not able to preserve. We discuss these discrepancies below and their incidence on the observed failure count.</p><p>• Missing iterable return in pattern (42 ⇒ 29%): Array destructuring assignments -e.g., [x0,x1]=xs -are carried out via the iterable protocol <ref type="bibr" target="#b15">16</ref> . It prescribes calling the return method of the iterator when exiting the destructuring assignment; regardless of its outcome. However, after aran instrumentation, this method will not be called if an exception is thrown during the iteration. This semantics is challenging to restore because destructuring assignments occur in an expression context and cannot be directly wrapped in a try statement.e</p><p>• Corrupt code reification (34 ⇒ 24%): There exist two ways for JavaScript programs to inspect their own source code: the stack property of Error instances and the toString method of %Function.prototype%. After instrumentation by aran, these two mechanisms will provide a representation of the instrumentation code instead of the original code. This semantics could be restored with some engineering effort. However, we decided against it because the ECMAScript specification does not actually specify the output format of these two mechanisms. As a result, code reification is not guaranteed to be stable across different JavaScript engines and is primarily used for debugging purposes. One might wonder how this discrepancy accounted for 34 failures since it is not part of the specification. The reason is that two functions with the same source code should cause %Function.prototype.toString% to produce the same string. Unfortunately, this is not guaranteed after instrumentation because of the compilation variables introduced by aran.</p><p>• No two-way bindings for arguments (32 ⇒ 22%): In sloppy mode, functions with a simple list of parameters will have them two-way bound with the arguments object. This means that changes to the arguments object are reflected in the values of the parameters and vice versa. In a previous version of our tool, we preserved this behavior by leveraging the Proxy API [3]. However, we decided to remove this feature because it caused performance overhead and because dynamic argument binding is considered legacy.</p><p>• Hoisted root declarations (20 ⇒ 14%): To simplify its API, aran hoists export declarations and variable declarations to the beginning of the sources. Although the temporal deadzone is enforced inside the source, other sources will be able to bypass it. For modules, this is only an issue in the case of circular dependencies. For scripts, this is only an issue if the script synchronously executes another script that uses its own declared global variables. Additionally, because the value of global const declarations is not available, aran has to turn global const declarations into let declarations. Although the immutability of the variables will be enforced in the current source, other sources will be able to bypass it.</p><p>• No dynamic function properties (2 ⇒ 1%): Functions created in sloppy mode contain two properties that change dynamically as the function is being called: arguments and caller. We decided not to preserve this feature because it is technically challenging and because these properties have been deprecated (although they are still part of the ECMAScript 2024 specification). • Other Discrepancies (13 ⇒ 9%): We observe other discrepancies that require code that is so convoluted that it is unlikely to cause issues in practice. For instance, after aran instrumentation of a derived class, the prototype property of the parent class is accessed twice instead of once. This could be observed with a getter or with the Proxy API. A detailed list of the discrepancies can be found in the repository of our tool <ref type="bibr" target="#b16">17</ref> .</p><p>To prevent flakiness, Test262 was designed to be independent of performance. However, performance overhead is the discrepancy most likely to cause issues in practice. Indeed, as the performance overhead of the analysis increases, so does the chance that time-sensitive applications will be affected. For instance, some event interleaving might be observed by the analysis, whereas such interleaving may never occur without it. To provide insight into the performance overhead of our approach, we recorded the time required to execute each test case in each stage. Figure <ref type="figure" target="#fig_6">4</ref> depicts the distribution of slowdown factors that were observed in each stage compared to the initial engine stage. It appears that slowdown factors rarely exceed 10x, which is corroborated by the total time of each stage shown in Figure <ref type="figure" target="#fig_4">3</ref>.</p><p>Although not depicted in Figure <ref type="figure" target="#fig_4">3</ref>, outliers can reach a slowdown factor of up to 800x. They were removed from the graph because they made it hard to read. We selected the set of pathological test cases that made the slowdown factor of stage part-min exceed 100x. This selection contains 32 test cases, among which 31 were large and probably generated files of several thousands lines of code -e.g., <ref type="bibr" target="#b17">18</ref> . This made us suspect that the overhead was largely due to the instrumentation. Figure <ref type="figure" target="#fig_7">5</ref> depicts the distribution of the time spent instrumenting code compared to the total time required to execute each test case. It appears that instrumentation accounts for about half of the time required to execute a typical test case. However, Figure <ref type="figure" target="#fig_8">6</ref> depicts the same data but only for the pathological selection. It appears that instrumentation accounts for almost all the time required to run a pathological test case. This is a positive outcome because instrumentation overhead can be lifted by performing instrumentation statically via the offline architecture depicted in Figure <ref type="figure" target="#fig_0">1</ref>.</p><p>We are aware that Test262 is not tailored to benchmark performance. Hence, the 10x slowdown factor we observed is a crude approximation of how our approach could perform in practice. Further work is required to establish the transparency of our approach for real-world time-sensitive applications. <ref type="bibr" target="#b16">17</ref> https://github.com/lachrist/aran/blob/664f0a30/doc/issues/missing-iterable-return-call-in-pattern.md 18 https://github.com/tc39/test262/blob/867ca540/test/language/identifiers/start-unicode-10.0.0-class-escaped.js  </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="6.">Related Work</head><p>Driven by the popularity and dynamic nature of JavaScript, the research community has proposed a wealth of approaches for dynamically analyzing JavaScript programs. By far, the most successful class of dynamic program analysis for JavaScript is the so-called "lightweight" dynamic analyses such as: code coverage <ref type="bibr" target="#b18">19</ref> , profiling [4, 5]  <ref type="bibr" target="#b19">20</ref> , and dynamic linting [6, 7, 8]. In this section, we briefly review the state-of-the-art approaches that are capable of supporting shadow execution of JavaScript and implementing so-called "heavyweight" dynamic analyses.</p><p>Linvail Most importantly, the work we presented in this paper iterates on previous work presented in [9]. While this earlier work also relies on source code instrumentation to carry out shadow execution, it focuses on an interesting technique called membrane, which involves using the Proxy JavaScript API [3] to enforce an access control system between instrumented and non-instrumented code areas. This membrane was leveraged to track primitive values for longer periods of time. This approach was implemented in a library <ref type="bibr" target="#b20">21</ref> which can still be integrated into our approach. This paper proposes several novelties. First, we came up with an aspect-oriented API to define the logic of the analysis which is more flexible than our previous API. Second, we crafted an intermediate language that strikes an interesting balance between expressiveness and simplicity. Third, we confronted our approach against the complexity of the ECMAScript specification.</p><p>Jalangi Apart from our own work, the closest related work is Jalangi [2]. It is another approach for building heavyweight dynamic analyses through JavaScript source code instrumentation. It is however unclear how Jalangi can handle the current complexity of JavaScript. While the first version of Jalangi 22 has been archived, the second version of Jalangi 23 is still maintained. However, is has not kept pace with ECMAScript's fast release cycle as it only supports ECMAScript 5.1 24 which dates back to June 2011. Dynamic Taint Analysis A prime application of shadow execution is dynamic taint analysis which enforces security policies at run-time by propagating security-related labels along with run-time values. As security is an important concern for JavaScript programs, multiple taint analysis approaches have been proposed [10, 11, 12]. Most of these approaches rely on a modified runtime to carry out the analysis. While runtime instrumentation is attractive for conducting experiments, we believe it is not suitable for wide adoption. In contrast, our tool is based on source code instrumentation and is designed to be deployed on any JavaScript runtime. To the best of our knowledge only Ichnaea [12] is based on source code instrumentation. There are two major differences between their work and ours. First, they provide an API that forces the user into a specific shadow execution model optimized for taint analysis, whereas we provide a flexible aspect-oriented API. Second, similarly to Jalangi, Ichnaea only supports ECMAScript 5.1.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Dynamic Symbolic Execution</head><p>Another prominent application of shadow execution is dynamic symbolic execution which attempts to provide inputs to a program that will lead it to a specific execution path by labeling run-time values with symbols. It is often used to generate test inputs, an approach known as concolic testing [13, 14]. Multiple dynamic symbolic execution frameworks have been proposed for JavaScript [15, 16, 17]. Similar to dynamic taint analysis, these approaches often rely on a modified runtime, whereas we explored source code instrumentation for applicability reasons. The only symbolic execution framework based on source code instrumentation that we are aware of is Kudzu [15], which relies on Jalangi instrumentation and suffers from its limitations.</p><p>Value Virtualization There has been some work on virtualizing values in JavaScript which could provide the basis for shadow execution [18, 19, 20, 21]. However, these approaches require executing JavaScript code in a virtual machine, which may limit their applicability and explain why they have not been adopted in practice. Actually, ECMAScript provides its own standard virtualization API called Proxy [3]. Unfortunately, this API focuses on object values and is cannot virtualize primitive values. Despite shown interest <ref type="bibr">25</ref> , there is little chance that the Proxy API will be extended to primitive values due to performance implications.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Low-Level Shadow Execution</head><p>There is also an interesting body of work on performing shadow execution on the lower-level representation of programs. For instance, Valgrind [22] is a popular framework for instrumenting binaries for the purpose of dynamic analysis and is fully capable of carrying out shadow execution. However, because JavaScript is primarily interpreted, and although it is sometimes JIT-compiled, it is unclear how this approach could be applied to a wide range of rapidly evolving runtimes.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="7.">Conclusion</head><p>We introduced aran, an approach for implementing heavyweight dynamic program analyses. Our method is broadly applicable, relying exclusively on source code instrumentation. However, further research is needed to explore deployment infrastructures that do not compromise this applicability. Our approach is also expressive, featuring an aspect-oriented API that facilitates shadow execution of complex JavaScript programs with just 31 entry points. Furthermore, it maintains transparency by preserving the semantics of the analyzed program, achieving a 99.7% success rate on Test262. Future work should also examine whether the performance overhead remains acceptable in real-world applications.</p></div><figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_0"><head>Listing 1 :</head><label>1</label><figDesc>A simple analysis that records the call stack of programs.</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_1"><head>Figure 1 :</head><label>1</label><figDesc>Figure 1: Offline architecture for deploying aran.</figDesc><graphic coords="3,72.00,286.61,451.23,132.07" type="bitmap" /></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_2"><head>Figure 2 :</head><label>2</label><figDesc>Figure 2: Online architecture for deploying aran.</figDesc><graphic coords="3,72.00,450.13,451.24,176.92" type="bitmap" /></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_3"><head>type</head><label></label><figDesc>Variable = string; type Parameter = string; type Intrinsic = string; type Path = string; type Primitive = number | string | boolean | null | { bigint: string }; type TreeLeaf = | { type: "primitive"; primitive: Primitive; path: Path; } | { type: "closure", kind: string, path: Path } | { type: "intrinsic", name: Intrinsic, path: Path } | { type: "initial", variable: Variable | Parameter, path: Path } | { type: "import", source: string, specifier: string | null, path: Path } | { type: "resume", path: Path }; type TreeNode = | { type: "apply", function: Tree, this: Tree; arguments: Tree[]; path: Path } | { type: "construct", function: Tree, this: Tree[], arguments: Path } | { type: "arguments", members: Tree[], path: Path; } type Tree = TreeLeaf | TreeNode; type ShadowState = { parent: ShadowState | null; frame: { [key in Variable | Parameter]?: Tree }; stack: Tree[]; };</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_4"><head>Figure 3 :</head><label>3</label><figDesc>Figure 3: Overview of testing aran against Test262 in 6 stages.</figDesc><graphic coords="8,162.25,180.61,270.76,143.81" type="bitmap" /></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_5"><head></head><label></label><figDesc>2. parsing: Parses and directly re-generates static code without manipulating syntactic nodes. This stage is intended to encover the technical limitations either the acorn parser or the astring generator which are relied upon in the subsequent stages. It also provides insight into the composition of the instrumentation overhead.</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_6"><head>Figure 4 :</head><label>4</label><figDesc>Figure 4: Distribution of the slowdown factor of each stage compared to the calibrating engine stage.</figDesc><graphic coords="10,139.69,65.61,315.91,236.93" type="bitmap" /></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_7"><head>Figure 5 :</head><label>5</label><figDesc>Figure 5: Distribution of instrumentation time ratio of the entire test suite.</figDesc><graphic coords="11,72.00,66.16,225.64,169.23" type="bitmap" /></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_8"><head>Figure 6 :</head><label>6</label><figDesc>Figure 6: Distribution of instrumentation time ratio of pathological test cases.</figDesc><graphic coords="11,297.64,65.61,225.64,169.23" type="bitmap" /></figure>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="1" xml:id="foot_0">To eliminate the compilation variable, we explored the idea of introducing a dedicated invoke expression into the language. That would have translated into something like invoke(xs,"map",[f]). Unfortunately, this does not work in the presence of side effects because the method must be fetched from the object before evaluating the arguments.</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="2" xml:id="foot_1">We explored the idea of also moving the head of generator functions into their body, but decided against it as we observed too many failures during validation against Test262.</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="3" xml:id="foot_2">https://github.com/lachrist/aran/blob/664f0a30/test/aspects/track-origin.mjs</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="4" xml:id="foot_3">https://github.com/lachrist/aran</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="5" xml:id="foot_4">https://www.npmjs.com/package/aran</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="6" xml:id="foot_5">https://github.com/tc39/test262</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="7" xml:id="foot_6">https://github.com/lachrist/aran/tree/664f0a30/test/262/stages</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="8" xml:id="foot_7">https://github.com/tc39/test262/tree/18ebac8122117bdc55a0d4bba972ba80c0194b41</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="9" xml:id="foot_8">https://github.com/lachrist/aran/tree/664f0a304b555bcb106f24e72734ad8c88dac429</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="10" xml:id="foot_9">https://github.com/acornjs/acorn/releases/tag/8.12.1</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="11" xml:id="foot_10">https://github.com/davidbonnet/astring/releases/tag/v1.9.0</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="12" xml:id="foot_11">https://github.com/tc39/test262/blob/main/INTERPRETING.md</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="13" xml:id="foot_12">https://github.com/nodejs/node/issues/52720</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="14" xml:id="foot_13">https://github.com/nodejs/node/issues/53575</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="15" xml:id="foot_14">https://github.com/nodejs/node/issues/52737</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="16" xml:id="foot_15">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="19" xml:id="foot_16">https://github.com/bcoe/c8</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="20" xml:id="foot_17">https://www.dynatrace.com</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="21" xml:id="foot_18">https://github.com/lachrist/linvail</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="22" xml:id="foot_19">https://github.com/SRA-SiliconValley/jalangi</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="23" xml:id="foot_20">https://github.com/Samsung/jalangi2</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="24" xml:id="foot_21">https://github.com/Samsung/jalangi2#supported-ecmascript-versions</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="25" xml:id="foot_22">https://github.com/hugoattal/tc39-proposal-primitive-proxy</note>
		</body>
		<back>
			<div type="annex">
<div xmlns="http://www.tei-c.org/ns/1.0"><head>A. aran's Advice API</head><p>"closure-block@before": (s:S, k:ClosureKind, p:Path) =&gt; void;</p><p>"control-block@before": (s:S, k:ControlKind, ls:Label[], p:Path) =&gt; void;</p><p>"block@declaration": (s:S, k:BlockKind, f:Frame, p:Path) =&gt; void;</p><p>"block@declaration-overwrite": (s:S, k:BlockKind, f:Frame, p:Path) =&gt; Frame;</p><p>"generator-block@suspension": (s:S, k:GeneratorKind, p:Path) =&gt; void;</p><p>"generator-block@resumption": (s:S, k:GeneratorKind, p:Path) =&gt; void;</p><p>"program-block@after": (s:S, k:ProgramKind, v:StackValue, p:Path) =&gt; OtherValue;</p><p>"closure-block@after": (s:S, k:ClosureKind, v:StackValue, p:Path) =&gt; OtherValue;</p><p>"control-block@after": (s:S, k:ControlKind, p:Path) =&gt; void;</p><p>"block@throwing": (s:S, k:BlockKind, v:OtherValue, p:Path) =&gt; void;</p><p>"block@teardown": (s:S, k:BlockKind, p:Path) =&gt; void;</p><p>"break@before": (s:S, l:Label, p:Path) =&gt; void;</p><p>"test@before": (s:S, k:TestKind, v:StackValue, p:Path) =&gt; boolean;</p><p>"intrinsic@after": (s:S, i:Intrinsic, v:OtherValue, p:Path) =&gt; StackValue;</p><p>"primitive@after": (s:S, v:Primitive, p:Path) =&gt; StackValue;</p><p>"import@after": (s:S, r:Source, k:Specifier|null, v:OtherValue, p:Path) =&gt; StackValue;</p><p>"closure@after": (s:S, k:ClosureKind, f:Function, p:Path) =&gt; StackValue;</p><p>"read@after": (s:S, k:Key, v:ScopeValue, p:Path) =&gt; StackValue;</p><p>"eval@before": (s:S, c:DeepLocalSitu, v:StackValue, p:Path) =&gt; StackValue|OtherValue;</p><p>"eval@after": (s:S, v:OtherValue, p:Path) =&gt; StackValue;</p><p>"await@before": (s:S, v:StackValue, p:Path) =&gt; OtherValue;</p><p>"await@after": (s:S, v:OtherValue, p:Path) =&gt; StackValue;</p><p>"yield@before": (s:S, d:Delegate, v:StackValue, p:Path) =&gt; OtherValue;</p><p>"yield@after": (s:S, d:Delegate, v:OtherValue, p:Path) =&gt; StackValue;</p><p>"drop@before": (s:S, v:StackValue, p:Path) =&gt; OtherValue;</p><p>"export@before": (s:S, k:Specifier, v:StackValue, p:Path) =&gt; OtherValue;</p><p>"write@before": (s:S, k:Key, v:StackValue, p:Path) =&gt; ScopeValue;</p><p>"apply@around": (s: </p></div>			</div>
			<div type="references">

				<listBibl>

<biblStruct xml:id="b0">
	<monogr>
		<author>
			<persName><forename type="first">G</forename><surname>Kiczales</surname></persName>
		</author>
		<author>
			<persName><forename type="first">J</forename><surname>Lamping</surname></persName>
		</author>
		<author>
			<persName><forename type="first">A</forename><surname>Mendhekar</surname></persName>
		</author>
		<author>
			<persName><forename type="first">C</forename><surname>Maeda</surname></persName>
		</author>
		<author>
			<persName><forename type="first">C</forename><surname>Lopes</surname></persName>
		</author>
		<author>
			<persName><forename type="first">J.-M</forename><surname>Loingtier</surname></persName>
		</author>
		<author>
			<persName><forename type="first">J</forename><surname>Irwin</surname></persName>
		</author>
		<title level="m">ECOOP&apos;97-Object-Oriented Programming: 11th European Conference</title>
				<meeting><address><addrLine>Jyväskylä, Finland</addrLine></address></meeting>
		<imprint>
			<publisher>Springer</publisher>
			<date type="published" when="1997">June 9-13, 1997. 1997</date>
			<biblScope unit="page" from="220" to="242" />
		</imprint>
	</monogr>
	<note>Proceedings 11</note>
</biblStruct>

<biblStruct xml:id="b1">
	<analytic>
		<title level="a" type="main">Jalangi: A selective record-replay and dynamic analysis framework for javascript</title>
		<author>
			<persName><forename type="first">K</forename><surname>Sen</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Kalasapur</surname></persName>
		</author>
		<author>
			<persName><forename type="first">T</forename><surname>Brutch</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Gibbs</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 2013 9th Joint Meeting on Foundations of Software Engineering</title>
				<meeting>the 2013 9th Joint Meeting on Foundations of Software Engineering</meeting>
		<imprint>
			<date type="published" when="2013">2013</date>
			<biblScope unit="page" from="488" to="498" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b2">
	<analytic>
		<title level="a" type="main">Proxies: design principles for robust object-oriented intercession apis</title>
		<author>
			<persName><forename type="first">T</forename><surname>Van Cutsem</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><forename type="middle">S</forename><surname>Miller</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">ACM Sigplan Notices</title>
		<imprint>
			<biblScope unit="volume">45</biblScope>
			<biblScope unit="page" from="59" to="72" />
			<date type="published" when="2010">2010</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b3">
	<analytic>
		<title level="a" type="main">Meminsight: platform-independent memory debugging for javascript</title>
		<author>
			<persName><forename type="first">S</forename><forename type="middle">H</forename><surname>Jensen</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><surname>Sridharan</surname></persName>
		</author>
		<author>
			<persName><forename type="first">K</forename><surname>Sen</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Chandra</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 2015 10th Joint Meeting on Foundations of Software Engineering</title>
				<meeting>the 2015 10th Joint Meeting on Foundations of Software Engineering</meeting>
		<imprint>
			<date type="published" when="2015">2015</date>
			<biblScope unit="page" from="345" to="356" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b4">
	<analytic>
		<title level="a" type="main">Jitprof: Pinpointing jit-unfriendly javascript code</title>
		<author>
			<persName><forename type="first">L</forename><surname>Gong</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><surname>Pradel</surname></persName>
		</author>
		<author>
			<persName><forename type="first">K</forename><surname>Sen</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 2015 10th joint meeting on foundations of software engineering</title>
				<meeting>the 2015 10th joint meeting on foundations of software engineering</meeting>
		<imprint>
			<date type="published" when="2015">2015</date>
			<biblScope unit="page" from="357" to="368" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b5">
	<analytic>
		<title level="a" type="main">Jsnose: Detecting javascript code smells</title>
		<author>
			<persName><forename type="first">A</forename><forename type="middle">M</forename><surname>Fard</surname></persName>
		</author>
		<author>
			<persName><forename type="first">A</forename><surname>Mesbah</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">IEEE 13th international working conference on Source Code Analysis and Manipulation (SCAM), IEEE</title>
				<imprint>
			<date type="published" when="2013">2013. 2013</date>
			<biblScope unit="page" from="116" to="125" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b6">
	<analytic>
		<title level="a" type="main">Dlint: Dynamically checking bad coding practices in javascript</title>
		<author>
			<persName><forename type="first">L</forename><surname>Gong</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><surname>Pradel</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><surname>Sridharan</surname></persName>
		</author>
		<author>
			<persName><forename type="first">K</forename><surname>Sen</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 2015 International Symposium on Software Testing and Analysis</title>
				<meeting>the 2015 International Symposium on Software Testing and Analysis</meeting>
		<imprint>
			<date type="published" when="2015">2015</date>
			<biblScope unit="page" from="94" to="105" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b7">
	<analytic>
		<title level="a" type="main">Typedevil: Dynamic type inconsistency analysis for javascript</title>
		<author>
			<persName><forename type="first">M</forename><surname>Pradel</surname></persName>
		</author>
		<author>
			<persName><forename type="first">P</forename><surname>Schuh</surname></persName>
		</author>
		<author>
			<persName><forename type="first">K</forename><surname>Sen</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">IEEE/ACM 37th IEEE International Conference on Software Engineering</title>
				<imprint>
			<publisher>IEEE</publisher>
			<date type="published" when="2015">2015. 2015</date>
			<biblScope unit="volume">1</biblScope>
			<biblScope unit="page" from="314" to="324" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b8">
	<analytic>
		<title level="a" type="main">Linvail: A general-purpose platform for shadow execution of javascript</title>
		<author>
			<persName><forename type="first">L</forename><surname>Christophe</surname></persName>
		</author>
		<author>
			<persName><forename type="first">E</forename><forename type="middle">G</forename><surname>Boix</surname></persName>
		</author>
		<author>
			<persName><forename type="first">W</forename><surname>De Meuter</surname></persName>
		</author>
		<author>
			<persName><forename type="first">C</forename><forename type="middle">De</forename><surname>Roover</surname></persName>
		</author>
		<idno type="DOI">10.1109/SANER.2016.91</idno>
	</analytic>
	<monogr>
		<title level="m">IEEE 23rd International Conference on Software Analysis, Evolution, and Reengineering (SANER)</title>
				<imprint>
			<date type="published" when="2016">2016. 2016</date>
			<biblScope unit="volume">1</biblScope>
			<biblScope unit="page" from="260" to="270" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b9">
	<analytic>
		<title level="a" type="main">Practical blended taint analysis for javascript</title>
		<author>
			<persName><forename type="first">S</forename><surname>Wei</surname></persName>
		</author>
		<author>
			<persName><forename type="first">B</forename><forename type="middle">G</forename><surname>Ryder</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 2013 International Symposium on Software Testing and Analysis</title>
				<meeting>the 2013 International Symposium on Software Testing and Analysis</meeting>
		<imprint>
			<date type="published" when="2013">2013</date>
			<biblScope unit="page" from="336" to="346" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b10">
	<analytic>
		<title level="a" type="main">Precise client-side protection against dom-based cross-site scripting</title>
		<author>
			<persName><forename type="first">B</forename><surname>Stock</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Lekies</surname></persName>
		</author>
		<author>
			<persName><forename type="first">T</forename><surname>Mueller</surname></persName>
		</author>
		<author>
			<persName><forename type="first">P</forename><surname>Spiegel</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><surname>Johns</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">USENIX Security Symposium (USENIX Security 14)</title>
				<imprint>
			<date type="published" when="2014">2014</date>
			<biblScope unit="page" from="655" to="670" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b11">
	<analytic>
		<title level="a" type="main">Platform-independent dynamic taint analysis for javascript</title>
		<author>
			<persName><forename type="first">R</forename><surname>Karim</surname></persName>
		</author>
		<author>
			<persName><forename type="first">F</forename><surname>Tip</surname></persName>
		</author>
		<author>
			<persName><forename type="first">A</forename><surname>Sochůrková</surname></persName>
		</author>
		<author>
			<persName><forename type="first">K</forename><surname>Sen</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">IEEE Transactions on Software Engineering</title>
		<imprint>
			<biblScope unit="volume">46</biblScope>
			<biblScope unit="page" from="1364" to="1379" />
			<date type="published" when="2018">2018</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b12">
	<analytic>
		<title level="a" type="main">Dart: Directed automated random testing</title>
		<author>
			<persName><forename type="first">P</forename><surname>Godefroid</surname></persName>
		</author>
		<author>
			<persName><forename type="first">N</forename><surname>Klarlund</surname></persName>
		</author>
		<author>
			<persName><forename type="first">K</forename><surname>Sen</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 2005 ACM SIGPLAN conference on Programming language design and implementation</title>
				<meeting>the 2005 ACM SIGPLAN conference on Programming language design and implementation</meeting>
		<imprint>
			<date type="published" when="2005">2005</date>
			<biblScope unit="page" from="213" to="223" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b13">
	<analytic>
		<title level="a" type="main">Concolic testing</title>
		<author>
			<persName><forename type="first">K</forename><surname>Sen</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 22nd IEEE/ACM international conference on Automated software engineering</title>
				<meeting>the 22nd IEEE/ACM international conference on Automated software engineering</meeting>
		<imprint>
			<date type="published" when="2007">2007</date>
			<biblScope unit="page" from="571" to="572" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b14">
	<analytic>
		<title level="a" type="main">A symbolic execution framework for javascript</title>
		<author>
			<persName><forename type="first">P</forename><surname>Saxena</surname></persName>
		</author>
		<author>
			<persName><forename type="first">D</forename><surname>Akhawe</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Hanna</surname></persName>
		</author>
		<author>
			<persName><forename type="first">F</forename><surname>Mao</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Mccamant</surname></persName>
		</author>
		<author>
			<persName><forename type="first">D</forename><surname>Song</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">2010 IEEE Symposium on Security and Privacy, IEEE</title>
				<imprint>
			<date type="published" when="2010">2010</date>
			<biblScope unit="page" from="513" to="528" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b15">
	<analytic>
		<title level="a" type="main">Expose: practical symbolic execution of standalone javascript</title>
		<author>
			<persName><forename type="first">B</forename><surname>Loring</surname></persName>
		</author>
		<author>
			<persName><forename type="first">D</forename><surname>Mitchell</surname></persName>
		</author>
		<author>
			<persName><forename type="first">J</forename><surname>Kinder</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 24th ACM SIGSOFT International SPIN Symposium on Model Checking of Software</title>
				<meeting>the 24th ACM SIGSOFT International SPIN Symposium on Model Checking of Software</meeting>
		<imprint>
			<date type="published" when="2017">2017</date>
			<biblScope unit="page" from="196" to="199" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b16">
	<analytic>
		<title level="a" type="main">Symbolic execution for javascript</title>
		<author>
			<persName><forename type="first">J</forename><forename type="middle">F</forename><surname>Santos</surname></persName>
		</author>
		<author>
			<persName><forename type="first">P</forename><surname>Maksimović</surname></persName>
		</author>
		<author>
			<persName><forename type="first">T</forename><surname>Grohens</surname></persName>
		</author>
		<author>
			<persName><forename type="first">J</forename><surname>Dolby</surname></persName>
		</author>
		<author>
			<persName><forename type="first">P</forename><surname>Gardner</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 20th International Symposium on Principles and Practice of Declarative Programming</title>
				<meeting>the 20th International Symposium on Principles and Practice of Declarative Programming</meeting>
		<imprint>
			<date type="published" when="2018">2018</date>
			<biblScope unit="page" from="1" to="14" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b17">
	<analytic>
		<title level="a" type="main">Virtual browser: a web-level sandbox to secure third-party javascript without sacrificing functionality</title>
		<author>
			<persName><forename type="first">Y</forename><surname>Cao</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Z</forename><surname>Li</surname></persName>
		</author>
		<author>
			<persName><forename type="first">V</forename><surname>Rastogi</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Y</forename><surname>Chen</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 17th ACM conference on Computer and communications security</title>
				<meeting>the 17th ACM conference on Computer and communications security</meeting>
		<imprint>
			<date type="published" when="2010">2010</date>
			<biblScope unit="page" from="654" to="656" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b18">
	<analytic>
		<title level="a" type="main">Virtual values for language extension</title>
		<author>
			<persName><forename type="first">T</forename><forename type="middle">H</forename><surname>Austin</surname></persName>
		</author>
		<author>
			<persName><forename type="first">T</forename><surname>Disney</surname></persName>
		</author>
		<author>
			<persName><forename type="first">C</forename><surname>Flanagan</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 26th International Conference on Object Oriented Programming Systems Languages and Applications (OOPSLA11)</title>
				<meeting>the 26th International Conference on Object Oriented Programming Systems Languages and Applications (OOPSLA11)</meeting>
		<imprint>
			<date type="published" when="2011">2011</date>
			<biblScope unit="page" from="921" to="938" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b19">
	<analytic>
		<title level="a" type="main">A framework for constructing javascript virtual machines with customized datatype representations</title>
		<author>
			<persName><forename type="first">T</forename><surname>Kataoka</surname></persName>
		</author>
		<author>
			<persName><forename type="first">T</forename><surname>Ugawa</surname></persName>
		</author>
		<author>
			<persName><forename type="first">H</forename><surname>Iwasaki</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 33rd Annual ACM Symposium on Applied Computing</title>
				<meeting>the 33rd Annual ACM Symposium on Applied Computing</meeting>
		<imprint>
			<date type="published" when="2018">2018</date>
			<biblScope unit="page" from="1238" to="1247" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b20">
	<analytic>
		<title level="a" type="main">ejstk: Building javascript virtual machines with customized datatypes for embedded systems</title>
		<author>
			<persName><forename type="first">T</forename><surname>Ugawa</surname></persName>
		</author>
		<author>
			<persName><forename type="first">H</forename><surname>Iwasaki</surname></persName>
		</author>
		<author>
			<persName><forename type="first">T</forename><surname>Kataoka</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Journal of Computer Languages</title>
		<imprint>
			<biblScope unit="volume">51</biblScope>
			<biblScope unit="page" from="261" to="279" />
			<date type="published" when="2019">2019</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b21">
	<analytic>
		<title level="a" type="main">Valgrind: a framework for heavyweight dynamic binary instrumentation</title>
		<author>
			<persName><forename type="first">N</forename><surname>Nethercote</surname></persName>
		</author>
		<author>
			<persName><forename type="first">J</forename><surname>Seward</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 2007 Conference on Programming Language Design and Implementation (PLDI07)</title>
				<meeting>the 2007 Conference on Programming Language Design and Implementation (PLDI07)</meeting>
		<imprint>
			<date type="published" when="2007">2007</date>
			<biblScope unit="page" from="89" to="100" />
		</imprint>
	</monogr>
</biblStruct>

				</listBibl>
			</div>
		</back>
	</text>
</TEI>
