Skip to content

Commit de89a29

Browse files
committed
Runtime: improve eval functions
- Use indirect eval (faster and avoid variable captures) - Put expressions within parentheses to allow arbitrary expressions without confusion with statements. Add a `"use strict"` directive since this is not inherited from the enclosing function with indirect eval.
1 parent 27c593b commit de89a29

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

runtime/js/jslib.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ function caml_js_var(x) {
280280
//console.error("Js.Unsafe.eval_string")
281281
}
282282
// biome-ignore lint/security/noGlobalEval:
283-
return eval(x);
283+
return eval?.(x);
284284
}
285285
//Provides: caml_js_call (const, mutable, shallow)
286286
//Requires: caml_js_from_array
@@ -478,24 +478,32 @@ function caml_js_strict_equals(x, y) {
478478
//Provides: caml_js_eval_string (const)
479479
//Requires: caml_jsstring_of_string
480480
function caml_js_eval_string(s) {
481+
// Uses an indirect eval through the optional chaining operator.
482+
// (see https://mdn.dev/docs/Web/JavaScript/Reference/Global_Objects/eval)
483+
// This is faster and avoid variable captures.
484+
// Also prepends `"use strict"` directive since this is not inherited
485+
// from the enclosing function with an indirect eval.
481486
// biome-ignore lint/security/noGlobalEval:
482-
return eval(caml_jsstring_of_string(s));
487+
return eval?.('"use strict";' + caml_jsstring_of_string(s));
483488
}
484489

485490
//Provides: caml_js_expr (const)
486491
//Requires: caml_jsstring_of_string
487492
function caml_js_expr(s) {
488493
console.error("caml_js_expr: fallback to runtime evaluation\n");
494+
// We add parentheses to avoid the ambiguity between expressions
495+
// and statements. This means that we accept invalid inputs like
496+
// "a)(b", but this is unlikely to be an issue in practice.
489497
// biome-ignore lint/security/noGlobalEval:
490-
return eval(caml_jsstring_of_string(s));
498+
return eval?.('"use strict";(' + caml_jsstring_of_string(s) + ")");
491499
}
492500

493501
//Provides: caml_pure_js_expr const (const)
494502
//Requires: caml_jsstring_of_string
495503
function caml_pure_js_expr(s) {
496504
console.error("caml_pure_js_expr: fallback to runtime evaluation\n");
497505
// biome-ignore lint/security/noGlobalEval:
498-
return eval(caml_jsstring_of_string(s));
506+
return eval?.('"use strict";(' + caml_jsstring_of_string(s) + ")");
499507
}
500508

501509
//Provides: caml_js_object (object_literal)

0 commit comments

Comments
 (0)