maierfelix / Iroh

Dynamic code analysis tool - Exploit, record and analyze running JavaScript
https://maierfelix.github.io/Iroh/
MIT License
926 stars 45 forks source link

Speed up patch phase #1

Open maierfelix opened 7 years ago

maierfelix commented 7 years ago

Currently the patch phase is splitted into 8 parts, means we re-walk the whole AST 8 times from scratch. Consider writing an own AST walker to better keep track about scopes and to prevent colliding between patch states.

hex13 commented 7 years ago

Or maybe using different AST library? estraverse could be more flexible. Estraverse visitor has just enter and exit methods: https://github.com/estools/estraverse so you could catch every AST node in one function and making something like this:


const stages = [STAGE1, STAGE2, STAGE....... 

estraverse.traverse(ast, {
    enter: function (node, parent) {
         stages.forEach(stage => {
                 // run each stage
                stage[node.type] &&  stage[node.type](node)
         });
    },
    leave: function (node, parent) {
       // similar code
    }
});

So you could pass all eight stages in one AST pass :)

maierfelix commented 7 years ago

The main problem here is not acorn's walker itself, but the colliding patch states. Due to the recursive nature of JS walkers, insertions like adding temporary variables into a scope breaks upper loops (e.g. FunctionExpression.body) and acorn's walker. So I just splitted everything to get it working, it's stable but pretty inefficient. I think looking into Babel's sauce could be helpful.

Edit: I dont think this is a problem with acorn's walker only - inserting new nodes into the raw AST could possibly break other walkers too if they don't expect it.