Dynamic Analysis With Babel
Matt Zeunert
What is Dynamic Analysis?
if (arr.length = 1){
// do something
}if (arr.length === 1){
// do something
}if (arr.length === 1){
// do something
}var a = 5
console.log(a)
a = 10
console.log(a)Instrumentation
var a = 5
a = 10var a = 5
console.log(a)
a = 10
console.log(a)Babel
Babel
6to5
var square = (n) => n * n
"use strict";
var square = function (n) {
return n * n;
};Babel
ES6
ES7
JSX
...
.babelrc
{
"plugins": [
"check-es2015-constants",
"transform-es2015-arrow-functions",
"transform-es2015-block-scoped-functions",
"transform-es2015-block-scoping",
"transform-es2015-classes",
"transform-es2015-computed-properties",
"transform-es2015-destructuring",
"transform-es2015-duplicate-keys",
"transform-es2015-for-of",
"transform-es2015-function-name",
"transform-es2015-literals",
"transform-es2015-modules-commonjs",
"and 9 other plugins"
]
}
.babelrc
{
"plugins": [],
"presets": ["es2015"]
}
Compilation
Parse
Traverse & Transform
Generate
Plugins
Plugin Example
var greeting = "Hello"
var greeting = "Hi";Parse
var greeting = "Hello"

Traverse & Transform
module.exports = function(babel) {
return {
visitor: {
StringLiteral: function(path) {
path.node.value = "Hi"
}
}
}
}
Generate
var greeting = "Hi";

StringLiteral: function(path) {
}
var greeting = getGreeting()
var greeting = "Hi";
var call = babel.types.callExpression(
babel.types.identifier("getGreeting"),
[]
)
path.replaceWith(call)
Dynamic Analysis With Babel




How It Should Work


Problem
Where did the commitsByAuthor object change?

Our End Goal
obj.a = 55obj.a = 55
trackAssignment(obj, "a", 55)obj.a = 55assignProperty(obj, "a", 55)obj.a = 55
AssignmentExpression
Left
Right
obj.a
MemberExpression
Object
Property
Demo
AssignmentExpression(path) {
var assignmentExpression = path.node
if (assignmentExpression.left.type !== "MemberExpression") {
return
}
var memberExpression = assignmentExpression.left
var value = assignmentExpression.right
var propertyName = memberExpression.property
if (!memberExpression.computed) {
propertyName = t.stringLiteral(propertyName.name)
}
var call = t.callExpression(
t.identifier("assignProperty"), [
memberExpression.object,
propertyName,
assignmentExpression.right
]
)
path.replaceWith(call)
}function assignProperty(obj, propName, value){
obj[propName] = value
if (!obj[propName + "__history__"]){
Object.defineProperty(obj, propName + "__history__", {
enumerable: false,
value: []
})
}
obj[propName + "__history__"].push({
value: value,
stack: Error().stack
})
}Other Examples
Visualizing Program Execution - Jan Paul Posma

DLint
https://github.com/Berkeley-Correctness-Group/DLint

JITProf


FromJS


Instrumentation
Compilation
Method Patching
Instrumentation Through Method Patching
var nativeCreateElement = document.createElement
document.createElement = function(tagName){
var el = nativeCreateElement.call(document, tagName)
el.createdAtStackTrace = Error().stack
return el
}
Limitations
Execution Speed
Memory
Breaking Functionality
Node-ChakraCore

node -TTRecord:log test.js

Jan Paul Posma: Visualizing program execution
Ariya Hidayat: Dynamic Code Analysis for JavaScript
Time-Travel Debugging for JavaScript/HTML Applications
Resources
FromJS
Twitter: @mattzeunert

Thank You
Slides
Dynamic Analysis with Babel - Rolling Scopes Minks
By Matt Zeunert
Dynamic Analysis with Babel - Rolling Scopes Minks
- 1,584