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,559
 
   
   
  