if (value instanceof AST_Array) return native_fns.Array[name];
if (value instanceof AST_Function) return native_fns.Function[name];
if (value instanceof AST_Object) return native_fns.Object[name];
- if (value instanceof AST_RegExp) return native_fns.RegExp[name];
+ if (value instanceof AST_RegExp) return native_fns.RegExp[name] && !value.value.global;
}
function is_modified(compressor, tw, node, value, level, immutable) {
].concat(object_fns),
Object: object_fns,
RegExp: [
+ "exec",
"test",
].concat(object_fns),
String: [
cached.forEach(function(node) {
delete node._eval;
});
+ if (ignore_side_effects) return val;
if (!val || val instanceof RegExp) return val;
if (typeof val == "function" || typeof val == "object") return this;
return val;
if (val == null || val === e) return this;
var native_fn = native_fns[val.constructor.name];
if (!native_fn || !native_fn[key]) return this;
+ if (val instanceof RegExp && val.global && !(e instanceof AST_RegExp)) return this;
}
var args = eval_args(this.args);
if (!args) return this;
"false true",
]
}
+
+exec: {
+ options = {
+ evaluate: true,
+ loops: true,
+ unsafe: true,
+ }
+ input: {
+ while (/a/.exec("AAA"))
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect: {
+ for (;null;)
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect_stdout: "PASS"
+}
+
+exec_global: {
+ options = {
+ evaluate: true,
+ loops: true,
+ unsafe: true,
+ }
+ input: {
+ while (/a/g.exec("AAA"))
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect: {
+ for (;null;)
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect_stdout: "PASS"
+}
+
+test: {
+ options = {
+ evaluate: true,
+ unsafe: true,
+ }
+ input: {
+ while (/a/.test("AAA"))
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect: {
+ while (false)
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect_stdout: "PASS"
+}
+
+test_global: {
+ options = {
+ evaluate: true,
+ unsafe: true,
+ }
+ input: {
+ while (/a/g.test("AAA"))
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect: {
+ while (false)
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect_stdout: "PASS"
+}
+
+var_exec: {
+ options = {
+ evaluate: true,
+ loops: true,
+ reduce_vars: true,
+ toplevel: true,
+ unsafe: true,
+ }
+ input: {
+ var r = /a/;
+ while (r.exec("AAA"))
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect: {
+ var r = /a/;
+ for (;null;)
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect_stdout: "PASS"
+}
+
+var_exec_global: {
+ options = {
+ evaluate: true,
+ loops: true,
+ reduce_vars: true,
+ toplevel: true,
+ unsafe: true,
+ }
+ input: {
+ var r = /a/g;
+ while (r.exec("aaa"))
+ console.log("PASS");
+ }
+ expect: {
+ var r = /a/g;
+ for (;r.exec("aaa");)
+ console.log("PASS");
+ }
+ expect_stdout: [
+ "PASS",
+ "PASS",
+ "PASS",
+ ]
+}
+
+var_test: {
+ options = {
+ evaluate: true,
+ reduce_vars: true,
+ toplevel: true,
+ unsafe: true,
+ }
+ input: {
+ var r = /a/;
+ while (r.test("AAA"))
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect: {
+ var r = /a/;
+ while (false)
+ console.log("FAIL");
+ console.log("PASS");
+ }
+ expect_stdout: "PASS"
+}
+
+var_test_global: {
+ options = {
+ evaluate: true,
+ reduce_vars: true,
+ toplevel: true,
+ unsafe: true,
+ }
+ input: {
+ var r = /a/g;
+ while (r.test("aaa"))
+ console.log("PASS");
+ }
+ expect: {
+ var r = /a/g;
+ while (r.test("aaa"))
+ console.log("PASS");
+ }
+ expect_stdout: [
+ "PASS",
+ "PASS",
+ "PASS",
+ ]
+}
return " ((" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ") || a || 3).toString() ";
case p++:
return " /[abc4]/.test(((" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ") || b || 5).toString()) ";
+ case p++:
+ return " /[abc4]/g.exec(((" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ") || b || 5).toString()) ";
case p++:
return " ((" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) +
") || " + rng(10) + ").toString()[" +