Is recursive use of eval () the right way to verify program execution?

I have been creating the javascript core development environment for live evaluation (I call it WEPL .) In the last few days, and realized that it would be nice to be able to associate error messages with line numbers. Unfortunately, eval () does not provide a good way to do this, which I can find.

The solution I came up with so far is to convert the source to eval (), so that it is a set of nested wrapper calls for eval (), which writes some information before eval, checks if eval matches successfully, and then uses this information to provide the user with more useful troubleshooting information.

My question is: why might this be a bad idea? What problems do I need to solve to make sure this works well?

An example of such a transformation, I mean, just to make it concrete.

it

if (cond) {
  return foo + bar;
}
else {
  return baz + quux;
}

becomes this

if (myEval('cond')) {
  return myEval("myEval(\"foo\") + myEval(\"bar\")");
else {
  return myEval("myEval(\"baz\") + myEval(\"quux\")");
}

Where I, obviously, did not occupy the highest level, although I could, and the software version.

+5
source share
2 answers

This will not work if you want to accept even remote complex scripts. A few potential problems:

Scale

var i = 1; // global scope
!function() {
    var i = 2; // function scope
}();
alert(i); // 1

against.

myEval('var i = 1;'); // global scope
myEval('!function() {
    myEval(\'var i = 2;\'); // eval has global scope, always
}();');
myEval('alert(i);'); // 2

Shutters

!function() {
    var i = 1; // local to outer function
    !function() { // inherits context from outer function
        alert(i); // 1
    }();
}();

against.

myEval('!function() {
    myEval(\'var i = 1;\'); // local to outer function
    myEval(\'!function() { // eval has global scope; myEval inherits from wherever it was defined
        myEval(\\\'alert(i);\\\'); // undefined
    }();\');
}();');

var obj = {
    n: 1,
    f: function() {
        return this.n; // this is the object f is called from
    }
}
alert(obj.f()); // 1

against.

myEval('var obj = {
    n: myEval(\'1\'),
    f: myEval(\'function() {
           return myEval(\\\'this.n\\\'); // this is always the window in eval
       }')
}');
myEval('alert(obj.f());'); // undefined

Escaping slide

You need to avoid every quote, and you also need to avoid escape characters. In code with many objects, closure, internal functions, etc. This will cause the escape characters to become unmanageable:

!function() {
    $(function() {
        $('#foo').click(function() {
            setTimeout(function() {
                $.post('/', function(res) {
                     log(res);
                });
            }, 1000);
        });
    });
}();

( , , )

myEval('!function() {
    myEval(\'$(myEval(\\\'function() {
        myEval(\\\\\\\'$(\\\\\\\'#foo\\\\\\\').click(myEval(\\\\\\\\\\\\\\\'function() {
            myEval(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'setTimeout(myEval(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'function() {
                myEval(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'$.post('/', myEval(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'function(res) {
                     myEval(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'log(res);\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\');
                }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'));\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\');
            }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'), 1000);\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\');
        }\\\\\\\\\\\\\\\'));\\\\\\\');
    }\\\'));\');
}();');

, , .

+3

- IE. , 'lineNumber', , :

lineNumber = 1; if (cond) {
  lineNumber = 2; return foo + bar;
}
else {
  lineNumber = 5; return baz + quux;
}

, , , , , - .

+2

All Articles