From 6b9aeb5325203a9f4c8e3bdd6bd3f45f8520ee2e Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Mon, 10 Sep 2012 18:25:52 +0300 Subject: adaptive base54 digits depending on char frequency (WIP) --- lib/scope.js | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 5 deletions(-) (limited to 'lib/scope.js') diff --git a/lib/scope.js b/lib/scope.js index adf36493..e3433340 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -296,14 +296,19 @@ AST_Scope.DEFMETHOD("next_mangled", function(){ } }); +AST_SymbolDeclaration.DEFMETHOD("unmangleable", function(){ + return this.global || this.scope.uses_eval || this.scope.uses_with; +}); + +AST_Label.DEFMETHOD("unmangleable", function(){ + return false; +}); + AST_SymbolDeclaration.DEFMETHOD("mangle", function(){ - if (this.uniq) { + if (this.uniq && this.uniq !== this) { this.uniq.mangle(); } - else if (!(this.global - || this.scope.uses_eval - || this.scope.uses_with - || this.mangled_name)) { + else if (!(this.mangled_name || this.unmangleable())) { this.mangled_name = this.scope.next_mangled(); } }); @@ -354,3 +359,103 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(){ }); this.walk(tw); }); + +AST_Toplevel.DEFMETHOD("compute_char_frequency", function(){ + var tw = new TreeWalker(function(node){ + if (node instanceof AST_Constant) + base54.consider(node.print_to_string()); + else if (node instanceof AST_Debugger) + base54.consider("debugger"); + else if (node instanceof AST_Directive) + base54.consider(node.value); + else if (node instanceof AST_While) + base54.consider("while"); + else if (node instanceof AST_Do) + base54.consider("dowhile"); + else if (node instanceof AST_If) { + base54.consider("if"); + if (node.alternative) base54.consider("else"); + } + else if (node instanceof AST_Var) + base54.consider("var"); + else if (node instanceof AST_Const) + base54.consider("const"); + else if (node instanceof AST_Lambda) + base54.consider("function"); + else if (node instanceof AST_For) + base54.consider("for"); + else if (node instanceof AST_ForIn) + base54.consider("forin"); + else if (node instanceof AST_Switch) + base54.consider("switch"); + else if (node instanceof AST_Case) + base54.consider("case"); + else if (node instanceof AST_Default) + base54.consider("default"); + else if (node instanceof AST_With) + base54.consider("with"); + else if (node instanceof AST_ObjectSetter) + base54.consider("set" + node.key); + else if (node instanceof AST_ObjectGetter) + base54.consider("get" + node.key); + else if (node instanceof AST_ObjectKeyVal) + base54.consider(node.key); + else if (node instanceof AST_New) + base54.consider("new"); + else if (node instanceof AST_This) + base54.consider("this"); + else if (node instanceof AST_Try) + base54.consider("try"); + else if (node instanceof AST_Catch) + base54.consider("catch"); + else if (node instanceof AST_Finally) + base54.consider("finally"); + else if (node instanceof AST_SymbolDeclaration && node.unmangleable()) + base54.consider(node.name); + else if (node instanceof AST_SymbolRef && !node.uniq && !(node instanceof AST_LabelRef)) + base54.consider(node.name); + else if (node instanceof AST_Unary || node instanceof AST_Binary) + base54.consider(node.operator); + else if (node instanceof AST_Dot) + base54.consider(node.property); + }); + this.walk(tw); + base54.sort(); +}); + +var base54 = (function() { + var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789"; + var chars, frequency; + function reset() { + frequency = {}; + chars = string.split(""); + chars.map(function(ch){ frequency[ch] = 0 }); + } + base54.consider = function(str){ + for (var i = str.length; --i >= 0;) { + var ch = str.charAt(i); + if (string.indexOf(ch)) + ++frequency[ch]; + } + }; + base54.sort = function() { + chars.sort(function(a, b){ + if (is_digit(a) && !is_digit(b)) return 1; + if (is_digit(b) && !is_digit(a)) return -1; + return frequency[b] - frequency[a]; + }); + }; + base54.reset = reset; + reset(); + base54.get = function(){ return chars }; + function base54(num) { + var ret = "", base = 54; + do { + ret += chars[num % base]; + num = Math.floor(num / base); + base = 64; + } while (num > 0); + return ret; + }; + return base54; +})(); -- cgit v1.2.3