Add the AST rewriting framework/skeleton
Re-engineer the AST rewriting framework to never require any casts
Declare some move pure virtual Accept methods
Implement null AST rewriter

It does not rewrite anything, but just traverses the tree in a correct manner.
Tweak the rewriting infrastructure

We have three kinds of AST nodes, as far as rewriting is concerned:

  -- "fixed rewrite" nodes, which are rewritten to the same type of
     node, or not rewritten at all

  -- "polymorophic rewrite" nodes, which are rewriten to the same type
     of node, but its typr is generally not known at the caller site,
     e.g. a Statement is always rewriten into a Statement, but the
     caller need not to know what specific kind of a
     Statatement(IfStatement, WhileStatement, etc) is that.

  -- and there are the special cases of VariableProxy and Property (and
     maybe others), which are rewritten into something that is not a
     VariableProxy or Property.
Write a couple of function templates to make rewriting simpler/nicer
Add a flag to enable/disable ER instrumentation
Add missing field initialization in CallRuntime ctor
Instrument reads of variable and object properties

Variable references (represented in the AST via the class VariableProxy)
are rewritten like |g => ER_read("g", g)|. This is done only for the
properties of the global object - references to function scope, block
scope, parameter, etc. variables are not modified.

Read of object properties is rewritten like

  obj.key  => function() { let $o = obj, $k = key;
                           return ER_readProp($o, $k, $o.$k); }()

The anonymous function is needed so we can ensure |obj| and |key| are
evaluated exactly once and the resulting construct is still an
Expression. In the common case of |key| being a literal, the last
parameter of |ER_read| looks like |$o.key|.

The rewriting itself proceeds in two phases: before and after name
resolution and variable allocation (done by |Scope::Analyze|. The object
properties access is rewritten before scope analysis. Then the scope
analysis is run, which determines which variables are global and also
allocates local variables, including the ones introduced by the
preceding rewrite. Then the second rewriting pass is run, to modify the
global variable reads, now that we know, which are the global variables.
Add stub versions of |ER_read|, etc. to |runtime.js|

This allows to run instrumented programs with |d8|. Chrome overwrites
these stubs with the real functions as properties of the window objects.
Add a pass over the AST to reassign feedback and literal slot indices

These indices are assigned during parsing, however the ER rewriter
corrupts this information in several ways, mainly, it introduces new
function scopes, which may move materialized literals and objects, which
require feedback slots, from one function to another. Therefore, these
objects and literals have to get new slot indices in the new function
and it's nice to eliminate unused slots in the old function.
Correctly check if a variable read should be logged or not