Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the Function() constructor not optimized by V8, like eval?

We are trying a way to receive web components via WebSockets. Those components contains custom scripts and they should be run in a context inside the component.

In short, we have some script strings and want to run them.

Right now we are using eval for this, something like this:

function ctxEval(ctx, __script) {
    eval(__script);
    // return things with the ctx
}

and works as expected, but I'm reading that any function containing eval is not optimized by V8. I thought into converting it to new Function() like this:

new Function("ctx", __script)(ctx);

this way I can achieve the same as the ctxEval function above.

We know that Function is eval() because they act almost equally, but the question now is, until which point Function is eval()? Maybe because Function() has its own scope instead of the eval one which runs the code in the same scope, the function containing the Function call is actually optimized by V8. Also, here they talk about eval but not about Function constructor.

And another question implied in this one is, is the script that runs inside Function() optimized by V8?

like image 632
Jorge Fuentes González Avatar asked Jun 02 '17 15:06

Jorge Fuentes González


People also ask

Is function better than eval?

An alternative to eval is Function() . Just like eval() , Function() takes some expression as a string for execution, except, rather than outputting the result directly, it returns an anonymous function to you that you can call. `Function() is a faster and more secure alternative to eval().

Why eval is not recommended?

Malicious code : invoking eval can crash a computer. For example: if you use eval server-side and a mischievous user decides to use an infinite loop as their username. Terribly slow : the JavaScript language is designed to use the full gamut of JavaScript types (numbers, functions, objects, etc)… Not just strings!

What is the purpose of the function eval?

The Eval function evaluates the string expression and returns its value. For example, Eval("1 + 1") returns 2. If you pass to the Eval function a string that contains the name of a function, the Eval function returns the return value of the function.

Is eval good to use?

Security risksUsage of eval involves pretty high risks of running malicious code. Let us say you are accepting an expression from the user in an input box. And some mischievous user types in an infinite loop. This is going to be very dangerous especially if eval is used on the server-side.


1 Answers

I just tested this with this code

const adder = new Function('a', 'b', 'return b%2 ? a + b : b%3 ? a - b : b%5 ? b / a : a * b');
let b = 0, b2 = 0;
function _throw() {
    throw new Error('Ups');
}
function _catch() {
    try {_throw()} catch(e) {}
}
function printStatus(fn) {
    switch (%GetOptimizationStatus(fn)) {
        case 1: console.log(fn.name, "function is optimized"); break;
        case 2: console.log(fn.name, "function is not optimized"); break;
        case 3: console.log(fn.name, "function is always optimized"); break;
        case 4: console.log(fn.name, "function is never optimized"); break;
        case 6: console.log(fn.name, "function is maybe deoptimized"); break;
    }
}
eval('function evil(a,b) {return b%2 ? a + b : b%3 ? a - b : b%5 ? b / a : a * b}');
printStatus(adder);
printStatus(evil);
printStatus(_throw);
printStatus(_catch);
// Call the function
for(let i = 0; i < 2000; i++) {
    b = adder(Math.random() * 10, b);
    b2 = evil(i, b2);
    _catch();
}
printStatus(adder);
printStatus(evil);
printStatus(_throw);
printStatus(_catch);

run command

$ node --allow-natives-syntax js.js

and the output is

anonymous function is not optimized
evil function is not optimized
_throw function is not optimized
_catch function is not optimized

anonymous function is optimized
evil function is optimized
_throw function is not optimized
_catch function is not optimized

EDIT:

I modified this test code to check other bailots and im realy surprised because it looks that eval is also optimized :>

EDIT 2:

After some additional research I found this https://blog.sqreen.io/optimize-your-node-app-by-simply-upgrading-node-js/

like image 110
ponury-kostek Avatar answered Sep 30 '22 06:09

ponury-kostek