[Pkg-mozext-commits] [adblock-plus] 108/464: Added script to rewrite ABP code

David Prévot taffit at moszumanska.debian.org
Tue Jul 22 20:44:08 UTC 2014


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

taffit pushed a commit to branch master
in repository adblock-plus.

commit 78e5fd1bd558634c0d4e604b49d25811dc8b738d
Author: Wladimir Palant <trev at adblockplus.org>
Date:   Tue Dec 7 18:08:48 2010 +0100

    Added script to rewrite ABP code
---
 scripts/abprewrite.js | 425 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 425 insertions(+)

diff --git a/scripts/abprewrite.js b/scripts/abprewrite.js
new file mode 100644
index 0000000..88cab99
--- /dev/null
+++ b/scripts/abprewrite.js
@@ -0,0 +1,425 @@
+// This script rewrites AST to be compatible with JavaScript 1.5 and decompiles
+// the modified tree then
+
+include("decompile.js");
+
+function Node(props)
+{
+  for (var k in props)
+  {
+    this[k] = props[k];
+  }
+}
+Node.prototype =
+{
+  visit: function(visitor)
+  {
+    return walkAST(this, visitor);
+  }
+};
+
+function IdentifierExpression(varname)
+{
+  Node.call(this, {
+    name: varname
+  });
+}
+IdentifierExpression.prototype =
+{
+  __proto__: Node.prototype,
+  type: "IdentifierExpression",
+  precedence: 0
+};
+
+function LiteralExpression(constant)
+{
+  Node.call(this, {
+    objtype: typeof constant,
+    value: constant
+  });
+}
+LiteralExpression.prototype =
+{
+  __proto__: Node.prototype,
+  type: "LiteralExpression",
+  precedence: 0
+};
+
+function MemberExpression(object, member, isConst)
+{
+  if (typeof object == "string")
+    object = new IdentifierExpression(object);
+
+  if (isConst)
+  {
+    Node.call(this, {
+      container: object,
+      constmember: member
+    });
+  }
+  else
+  {
+    if (typeof member != "object")
+      member = new LiteralExpression(member);
+    Node.call(this, {
+      container: object,
+      member: member
+    });
+  }
+}
+MemberExpression.prototype =
+{
+  __proto__: Node.prototype,
+  type: "MemberExpression",
+  precedence: 1
+};
+
+function VarDeclaration(varname, initializer)
+{
+  obj = {
+    name: varname
+  }
+  if (typeof initializer != "undefined" && initializer != null)
+  {
+    if (typeof initializer == "object")
+      obj.initializer = initializer;
+    else
+      obj.initializer = new LiteralExpression(initializer);
+  }
+  Node.call(this, obj);
+}
+VarDeclaration.prototype =
+{
+  __proto__: Node.prototype,
+  type: "VarDeclaration"
+};
+
+function VarStatement(varname, initializer)
+{
+  Node.call(this, {
+    variables: [new VarDeclaration(varname, initializer)]
+  });
+}
+VarStatement.prototype =
+{
+  __proto__: Node.prototype,
+  type: "VarStatement",
+  vartype: "var"
+};
+
+let modifier =
+{
+  _tempVarCount: 0,
+  _extendFunctionName: null,
+  _extendVarName: null,
+  _potentialConstructors: {},
+
+  _shouldRemoveStatement: function(stmt)
+  {
+    if (stmt.type == "ExpressionStatement" && stmt.expr && stmt.expr.type == "CallExpression" && stmt.expr.func)
+    {
+      funcName = decompile(stmt.expr.func);
+
+      // Remove import calls:
+      // Cu.import(...);
+      if (funcName == "Cu.import" || funcName == "Components.utils.import")
+        return true;
+
+      // Remove timeline calls:
+      // TimeLine.foobar(...);
+      if (/^TimeLine\./.test(funcName))
+        return true;
+    }
+
+    if (stmt.type == "VarStatement" && stmt.variables && stmt.variables.length == 1)
+    {
+      // Remove export declaration:
+      // var EXPORTED_SYMBOLS = [];
+      if (stmt.variables[0].name == "EXPORTED_SYMBOLS")
+        return true;
+
+      // Remove base URL assignment:
+      // var baseURL = ...;
+      if (stmt.variables[0].name == "baseURL")
+        return true;
+
+      // Remove declarations of XPCOM shortcuts:
+      // const Cc = Components.classes;
+      // const Ci = Components.interfaces;
+      // const Cr = Components.results;
+      // const Cu = Components.utils;
+      if (/^C[ciru]/.test(stmt.variables[0].name))
+        return true;
+    }
+
+    return false;
+  },
+
+  _shouldReplaceStatement: function(stmt)
+  {
+    if (stmt.type == "ExpressionStatement" && stmt.expr && stmt.expr.type == "AssignmentExpression" && stmt.expr.lhs && stmt.expr.lhs.type == "ArrayLiteral")
+    {
+      // Convert destructuring assignment:
+      // [foo, bar] = [1, 2];
+      //
+      // Change into:
+      // var _tempVar44 = [1, 2];
+      // foo = _tempVar44[0];
+      // bar = _tempVar44[1];
+      let tempVar = "_tempVar" + this._tempVarCount++;
+      let result = [new VarStatement(tempVar, stmt.expr.rhs)];
+      for (let i = 0; i < stmt.expr.lhs.members.length; i++)
+      {
+        result.push(new Node({
+          type: "ExpressionStatement",
+          expr: new Node({
+            type: "AssignmentExpression",
+            precedence: 16,
+            operator: "",
+            lhs: stmt.expr.lhs.members[i],
+            rhs: new MemberExpression(tempVar, i)
+          })
+        }));
+      }
+      return result;
+    }
+
+    if (stmt.type == "ForInStatement" && stmt.itertype == "for each")
+    {
+      // Convert "for each" loops:
+      // for each (var foo in fooList)
+      // {
+      //   ...
+      // }
+      //
+      // Change into:
+      // for (var _loopIndex44 = 0; _loopIndex44 < fooList.length; _loopIndex44++)
+      // {
+      //   var foo = fooList[_loopIndex44];
+      //   ...
+      // }
+      if (!stmt.itervar || stmt.itervar.type != "VarStatement" || !stmt.itervar.variables ||
+          stmt.itervar.variables.length != 1 || stmt.itervar.variables[0].type != "VarDeclaration" ||
+          !stmt.itervar.variables[0].name)
+      {
+        throw "Unexpected loop variable in for each loop";
+      }
+      let loopVar = stmt.itervar.variables[0].name;
+      let loopIndex = "_loopIndex" + this._tempVarCount++;
+
+      if (!stmt.body || !stmt.body.type == "BlockStatement")
+        throw "Unexpected: loop body isn't a block statement";
+      if (!stmt.body.statements)
+        stmt.body.statements = [];
+      stmt.body.statements.unshift(new VarStatement(loopVar, new MemberExpression(stmt.iterrange, new IdentifierExpression(loopIndex))));
+
+      return [new Node({
+        type: "ForStatement",
+        init: new VarStatement(loopIndex, 0),
+        cond: new Node({
+          type: "BinaryExpression",
+          precedence: 8,
+          operator: "<",
+          lhs: new IdentifierExpression(loopIndex),
+          rhs: new MemberExpression(stmt.iterrange, "length", true)
+        }),
+        inc: new Node({
+          type: "UnaryExpression",
+          precedence: 3,
+          operator: "++",
+          operand: new IdentifierExpression(loopIndex)
+        }),
+        body: stmt.body
+      })];
+    }
+
+    return null;
+  },
+
+  _checkStatements: function(statements)
+  {
+    for (let i = 0; i < statements.length; i++)
+    {
+      if (this._shouldRemoveStatement(statements[i]))
+      {
+        statements.splice(i--, 1);
+      }
+      else
+      {
+        replacement = this._shouldReplaceStatement(statements[i]);
+        if (replacement)
+        {
+          replacement.unshift(i, 1);
+          statements.splice.apply(statements, replacement);
+          i += replacement.length - 3;
+        }
+      }
+    }
+  },
+
+  visitBlockStatement: function(stmt)
+  {
+    this._checkStatements(stmt.statements);
+  },
+
+  visitProgram: function(stmt)
+  {
+    this._checkStatements(stmt.sourceElements);
+  },
+
+  visitVarStatement: function(stmt)
+  {
+    // Change let variables into "regular" variables
+    if (stmt.vartype == "let")
+      stmt.vartype = "var";
+  },
+
+  visitFunctionDeclaration: function(stmt)
+  {
+    // This might be a constructor, store it so that visitAssignmentExpression
+    // can look it up later
+    this._potentialConstructors[stmt.name] = stmt;
+  },
+
+  visitAssignmentExpression: function(stmt)
+  {
+    if (stmt.rhs && stmt.rhs.type == "ObjectLiteral" && stmt.rhs.setters)
+    {
+      let parent = null;
+      for (let i = 0; i < stmt.rhs.setters.length; i++)
+      {
+        let setter = stmt.rhs.setters[i];
+        if (setter.type == "PropertyLiteral" && setter.property && setter.property.type == "IdentifierExpression" && setter.property.name == "__proto__")
+        {
+          stmt.rhs.setters.splice(i--, 1);
+          if (setter.value && setter.value.type == "MemberExpression" && setter.value.constmember == "prototype" &&
+              setter.value.container && setter.value.container.type == "IdentifierExpression")
+          {
+            parent = setter.value.container;
+          }
+        }
+      }
+      if (parent)
+      {
+        if (this._extendFunctionName == null)
+        {
+          this._extendVarName = "_extendInitiated" + this._tempVarCount++;
+          this._extendFunctionName = "_extend" + this._tempVarCount++;
+          _print("var " + this._extendVarName + " = {};");
+          _print("function " + this._extendFunctionName + "(baseClass, props) {");
+          _print("  var result = new baseClass(" + this._extendVarName + ");");
+          _print("  for (var k in props)");
+          _print("    result[k] = props[k];");
+          _print("  return result;");
+          _print("}");
+        }
+
+        if (parent.name in this._potentialConstructors)
+        {
+          var body = this._potentialConstructors[parent.name].body;
+          if (body.type != "BlockStatement" || !body.statements)
+            throw "Unexpected body found in function " + parent.name;
+          body.statements.unshift(new Node({
+            type: "IfStatement",
+            cond: new Node({
+              type: "BinaryExpression",
+              precedence: 9,
+              operator: "===",
+              lhs: new MemberExpression("arguments", 0),
+              rhs: new IdentifierExpression(this._extendVarName)
+            }),
+            body: new Node({
+              type: "BlockStatement",
+              statements: [new Node({
+                type: "ReturnStatement"
+              })]
+            })
+          }));
+          delete this._potentialConstructors[parent.name];
+        }
+
+        let call = new Node({
+          type: "CallExpression",
+          precedence: 2,
+          func: new IdentifierExpression(this._extendFunctionName),
+          arguments: [parent, stmt.rhs]
+        });
+        stmt.rhs = call;
+      }
+    }
+  },
+
+  _disabled_visitObjectLiteral: function(stmt)
+  {
+    // Drop __proto__ from object initializers
+    for (let i = 0; i < stmt.setters.length; i++)
+      if (stmt.setters[i].type == "PropertyLiteral" && stmt.setters[i].property && decompile(stmt.setters[i].property) == "__proto__")
+        stmt.setters.splice(i--, 1);
+  }
+};
+
+let origOutput = output;
+let origFlush = flush;
+let origIndent = indent;
+let decompileBuffer;
+function fakeOutput(str)
+{
+  decompileBuffer += str;
+  return global;
+}
+function fakeFlush()
+{
+  return global;
+}
+function fakeIndent()
+{
+  return global;
+}
+function decompile(node)
+{
+  decompileBuffer = "";
+  [output, flush, indent] = [fakeOutput, fakeFlush, fakeIndent];
+  node.visit(visitor);
+  [output, flush, indent] = [origOutput, origFlush, origIndent];
+  return decompileBuffer;
+}
+
+// Output license header
+_print('/* ***** BEGIN LICENSE BLOCK *****');
+_print(' * Version: MPL 1.1');
+_print(' *');
+_print(' * The contents of this file are subject to the Mozilla Public License Version');
+_print(' * 1.1 (the "License"); you may not use this file except in compliance with');
+_print(' * the License. You may obtain a copy of the License at');
+_print(' * http://www.mozilla.org/MPL/');
+_print(' *');
+_print(' * Software distributed under the License is distributed on an "AS IS" basis,');
+_print(' * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License');
+_print(' * for the specific language governing rights and limitations under the');
+_print(' * License.');
+_print(' *');
+_print(' * The Original Code is Adblock Plus.');
+_print(' *');
+_print(' * The Initial Developer of the Original Code is');
+_print(' * Wladimir Palant.');
+_print(' * Portions created by the Initial Developer are Copyright (C) 2006-2010');
+_print(' * the Initial Developer. All Rights Reserved.');
+_print(' *');
+_print(' * Contributor(s):');
+_print(' *');
+_print(' * ***** END LICENSE BLOCK ***** */');
+_print();
+_print('//');
+_print('// This file has been generated automatically from Adblock Plus source code');
+_print('//');
+_print();
+
+process_js = function(ast)
+{
+  if (!ast)
+    return;
+
+  ast = makeAST(ast);
+  walkAST(ast, modifier);
+  walkAST(ast, visitor);
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/adblock-plus.git



More information about the Pkg-mozext-commits mailing list