[Pkg-javascript-commits] [uglifyjs] 119/228: transform String.charAt() to index access (#1620)

Jonas Smedegaard dr at jones.dk
Sat Apr 15 14:25:22 UTC 2017


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository uglifyjs.

commit 274331d0ea05197ea7cb531ccd1d78e0c7b8662c
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Sun Mar 19 02:17:15 2017 +0800

    transform String.charAt() to index access (#1620)
    
    Guarded by `unsafe` as `charAt()` can be overridden.
---
 lib/compress.js           | 22 +++++++++----
 test/compress/evaluate.js | 78 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+), 6 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index c3f1254..66a4120 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -2656,7 +2656,7 @@ merge(Compressor.prototype, {
                     if (self.args.length != 1) {
                         return make_node(AST_Array, self, {
                             elements: self.args
-                        }).transform(compressor);
+                        }).optimize(compressor);
                     }
                     break;
                   case "Object":
@@ -2674,7 +2674,7 @@ merge(Compressor.prototype, {
                         left: self.args[0],
                         operator: "+",
                         right: make_node(AST_String, self, { value: "" })
-                    }).transform(compressor);
+                    }).optimize(compressor);
                     break;
                   case "Number":
                     if (self.args.length == 0) return make_node(AST_Number, self, {
@@ -2683,7 +2683,7 @@ merge(Compressor.prototype, {
                     if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
                         expression: self.args[0],
                         operator: "+"
-                    }).transform(compressor);
+                    }).optimize(compressor);
                   case "Boolean":
                     if (self.args.length == 0) return make_node(AST_False, self);
                     if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
@@ -2692,7 +2692,7 @@ merge(Compressor.prototype, {
                             operator: "!"
                         }),
                         operator: "!"
-                    }).transform(compressor);
+                    }).optimize(compressor);
                     break;
                   case "Function":
                     // new Function() => function(){}
@@ -2757,7 +2757,7 @@ merge(Compressor.prototype, {
                     left: make_node(AST_String, self, { value: "" }),
                     operator: "+",
                     right: exp.expression
-                }).transform(compressor);
+                }).optimize(compressor);
             }
             else if (exp instanceof AST_Dot && exp.expression instanceof AST_Array && exp.property == "join") EXIT: {
                 var separator;
@@ -2811,7 +2811,7 @@ merge(Compressor.prototype, {
                             left     : prev,
                             right    : el
                         });
-                    }, first).transform(compressor);
+                    }, first).optimize(compressor);
                 }
                 // need this awkward cloning to not affect original element
                 // best_of will decide which one to get through.
@@ -2821,6 +2821,16 @@ merge(Compressor.prototype, {
                 node.expression.expression.elements = elements;
                 return best_of(compressor, self, node);
             }
+            else if (exp instanceof AST_Dot && exp.expression.is_string(compressor) && exp.property == "charAt") {
+                var arg = self.args[0];
+                var index = arg ? arg.evaluate(compressor) : 0;
+                if (index !== arg) {
+                    return make_node(AST_Sub, exp, {
+                        expression: exp.expression,
+                        property: make_node_from_constant(index | 0, arg || exp)
+                    }).optimize(compressor);
+                }
+            }
         }
         if (exp instanceof AST_Function) {
             if (exp.body[0] instanceof AST_Return) {
diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js
index 6873950..3d0d886 100644
--- a/test/compress/evaluate.js
+++ b/test/compress/evaluate.js
@@ -200,6 +200,7 @@ negative_zero: {
             1 / (-0)
         );
     }
+    expect_stdout: true
 }
 
 positive_zero: {
@@ -220,6 +221,7 @@ positive_zero: {
             1 / (0)
         );
     }
+    expect_stdout: true
 }
 
 unsafe_constant: {
@@ -411,6 +413,7 @@ unsafe_integer_key: {
             1["1"] + 1
         );
     }
+    expect_stdout: true
 }
 
 unsafe_integer_key_complex: {
@@ -438,6 +441,7 @@ unsafe_integer_key_complex: {
             2
         );
     }
+    expect_stdout: true
 }
 
 unsafe_float_key: {
@@ -465,6 +469,7 @@ unsafe_float_key: {
             1["3.14"] + 1
         );
     }
+    expect_stdout: true
 }
 
 unsafe_float_key_complex: {
@@ -492,6 +497,7 @@ unsafe_float_key_complex: {
             2
         );
     }
+    expect_stdout: true
 }
 
 unsafe_array: {
@@ -554,6 +560,7 @@ unsafe_string: {
             "11"
         );
     }
+    expect_stdout: true
 }
 
 unsafe_array_bad_index: {
@@ -575,6 +582,7 @@ unsafe_array_bad_index: {
             [1, 2, 3, 4][3.14] + 1
         );
     }
+    expect_stdout: true
 }
 
 unsafe_string_bad_index: {
@@ -596,6 +604,7 @@ unsafe_string_bad_index: {
             "1234"[3.14] + 1
         );
     }
+    expect_stdout: true
 }
 
 unsafe_prototype_function: {
@@ -701,3 +710,72 @@ in_boolean_context: {
         );
     }
 }
+
+unsafe_charAt: {
+    options = {
+        evaluate  : true,
+        unsafe    : true
+    }
+    input: {
+        console.log(
+            "1234" + 1,
+            "1234".charAt(0) + 1,
+            "1234".charAt(6 - 5) + 1,
+            ("12" + "34").charAt(0) + 1,
+            ("12" + "34").charAt(6 - 5) + 1,
+            [1, 2, 3, 4].join("").charAt(0) + 1
+        );
+    }
+    expect: {
+        console.log(
+            "12341",
+            "11",
+            "21",
+            "11",
+            "21",
+            "11"
+        );
+    }
+    expect_stdout: true
+}
+
+unsafe_charAt_bad_index: {
+    options = {
+        evaluate  : true,
+        unsafe    : true
+    }
+    input: {
+        console.log(
+            "1234".charAt() + 1,
+            "1234".charAt("a") + 1,
+            "1234".charAt(3.14) + 1
+        );
+    }
+    expect: {
+        console.log(
+            "11",
+            "11",
+            "41"
+        );
+    }
+    expect_stdout: true
+}
+
+unsafe_charAt_noop: {
+    options = {
+        evaluate  : true,
+        unsafe    : true
+    }
+    input: {
+        console.log(
+            s.charAt(0),
+            "string".charAt(x)
+        );
+    }
+    expect: {
+        console.log(
+            s.charAt(0),
+            "string".charAt(x)
+        );
+    }
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git



More information about the Pkg-javascript-commits mailing list