[Pkg-mozext-commits] [adblock-plus] 124/464: True AST decompiler, and a more forceful check script.

David Prévot taffit at moszumanska.debian.org
Tue Jul 22 20:44:09 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 ca88e3060aaff2be98f7921cfafb13c0e699a576
Author: Joshua Cranmer <Pidgeot18 at gmail.com>
Date:   Wed Jan 12 22:54:58 2011 -0500

    True AST decompiler, and a more forceful check script.
---
 Makefile                |  13 +-
 check.py                |  19 ++
 jshydra_bridge.cpp      |   1 +
 scripts/astDecompile.js | 486 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 514 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index 1a55d31..c752c9b 100644
--- a/Makefile
+++ b/Makefile
@@ -47,11 +47,14 @@ echo-variable-%:
 	@echo "$($*)"
 
 full-check:: jshydra$(BIN_SUFFIX)
-	@cp -R $(MOZ_SRCDIR)/js/src/tests jstest
+	@cp -R $(srcdir)/tests jstest
+	@cp check.py jstest
 	@echo "Decompiling JS ASTs.."
-	set -e; \
-	for f in $$(find jstest -name '*.js'); do \
+	@set -e; \
+	for f in $$(cd jstest && python check.py | grep -v '^warning:'); do \
 		echo $$f; \
-		./jshydra$(BIN_SUFFIX) scripts/astDecompile.js --trueast "$(MOZ_SRCDIR)/js/src/tests$${f#jstest}" >$$f; \
+		./jshydra$(BIN_SUFFIX) scripts/astDecompile.js --trueast "$(srcdir)/tests/$$f" >jstest/$$f; \
 	done
-	#python jstest/jstests.py --tinderbox fake_js.sh
+	python $(srcdir)/tests/jstest.py --tinderbox $(objdir)/js > before.log
+	python jstest/jstests.py --tinderbox $(objdir)/js > after.log
+	diff before.log after.log
diff --git a/check.py b/check.py
new file mode 100644
index 0000000..4c4bdb5
--- /dev/null
+++ b/check.py
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+
+banned = ["js1_5/Regress/regress-31255.js",
+	"js1_5/Regress/regress-351515.js",
+	"js1_5/Regress/regress-89443.js",
+	"js1_5/Regress/regress-98901.js",
+	"js1_8/regress/regress-366941.js",
+	"js1_8/regress/regress-459185.js",
+	"js1_8_1/regress/regress-452498-052.js",
+	"js1_8_1/regress/regress-452498-053.js",
+	"js1_8_1/regress/regress-452498-098.js",
+	"js1_8_1/regress/regress-452498-117.js"]
+
+import manifest
+xul_tester = manifest.NullXULInfoTester()
+test_list = manifest.parse('jstests.list', xul_tester)
+for test in test_list:
+	if test.enable and test.path[-5:] != '-n.js' and test.path not in banned:
+		print test.path
diff --git a/jshydra_bridge.cpp b/jshydra_bridge.cpp
index cc7fdbe..ecaab81 100644
--- a/jshydra_bridge.cpp
+++ b/jshydra_bridge.cpp
@@ -67,6 +67,7 @@ void jshydra_init(const char *file) {
   rt = JS_NewRuntime (0x9000000L);
   cx = JS_NewContext (rt, 8192);
   JS_BeginRequest(cx);
+  JS_SetVersion(cx, JSVERSION_LATEST);
   //JS_SetGCZeal(cx, 2);
 
   //JS_SetContextPrivate (this->cx, this);
diff --git a/scripts/astDecompile.js b/scripts/astDecompile.js
new file mode 100644
index 0000000..02dce1e
--- /dev/null
+++ b/scripts/astDecompile.js
@@ -0,0 +1,486 @@
+let global = this;
+function decompileAST(ast) {
+  let func = global["decompile" + ast.type];
+  if (!func)
+    throw "Unknown type " + ast.type;
+  return func(ast);
+}
+
+function decompileProgram(ast) {
+  return [decompileAST(stmt) for each (stmt in ast.body)].join('\n');
+}
+
+/* Statements */
+function decompileEmptyStatement(ast) {
+  return ";"
+}
+function decompileBlockStatement(ast) {
+  return '{\n' + [decompileAST(stmt) for each (stmt in ast.body)].join('\n') +
+    '\n}\n';
+}
+
+function decompileExpressionStatement(ast) {
+  return decompileAST(ast.expression) + ";";
+}
+
+function decompileIfStatement(ast) {
+  let str = "if (" + decompileAST(ast.test) + ")\n";
+  str += decompileAST(ast.consequent);
+  if (ast.alternate)
+    str += " else\n" + decompileAST(ast.alternate);
+  return str;
+}
+
+function decompileLabeledStatement(ast) {
+  return ast.label.name + ": " + decompileAST(ast.body);
+}
+
+function decompileBreakStatement(ast) {
+  return "break" + (ast.label ? " " + ast.label.name : "") + ";";
+}
+
+function decompileContinueStatement(ast) {
+  return "continue" + (ast.label ? " " + ast.label.name : "") + ";";
+}
+
+function decompileWithStatement(ast) {
+  return "with (" + decompileAST(ast.object) + ") " + decompileAST(ast.body);
+}
+
+function decompileSwitchStatement(ast) {
+  let str = "switch (" + decompileAST(ast.discriminant) + ") {\n";
+  let cases = [];
+  for each (let scase in ast.cases) {
+	let casestr = scase.test ? "case " + decompileAST(scase.test) : "default";
+	casestr += ":\n";
+    casestr += [decompileAST(stmt) for each (stmt in scase.consequent)]
+      .join('\n');
+	cases.push(casestr);
+  }
+  str += cases.join('\n') + '\n}\n';
+  return str;
+}
+
+function decompileReturnStatement(ast) {
+  return "return" + (ast.argument ? " " + decompileAST(ast.argument) :
+      "") + ";";
+}
+
+function decompileThrowStatement(ast) {
+  return "throw " + decompileAST(ast.argument);
+}
+
+function decompileTryStatement(ast) {
+  let str = "try " + decompileAST(ast.block);
+  
+  let handlers = [];
+  if (ast.handler && "type" in ast.handler)
+	handlers.push(ast.handler);
+  else if (ast.handler)
+	handlers = ast.handler;
+
+  let handler_strs = [];
+  for each (let handler in handlers) {
+	let handler_str = "catch (" + decompileAST(handler.param);
+	if (handler.guard)
+      handler_str += " if " + decompileAST(handler.guard);
+	handler_str += ") " + decompileAST(handler.body);
+	handler_strs.push(handler_str);
+  }
+  str += handler_strs.join("");
+  if (ast.finalizer)
+	str += " finally " + decompileAST(ast.finalizer);
+  return str;
+}
+
+function decompileWhileStatement(ast) {
+  return "while (" + decompileAST(ast.test) + ") " + decompileAST(ast.body);
+}
+
+function decompileDoWhileStatement(ast) {
+  return "do " + decompileAST(ast.body) + " while (" + decompileAST(ast.test) + ");";
+}
+
+function decompileForStatement(ast) {
+  let str = "for (";
+  if (ast.init) {
+	if (ast.init.type == "VariableDeclaration")
+      str += decompileAST(ast.init);
+	else
+      str += decompileAST(ast.init) + ";";
+  } else {
+    str += ";";
+  }
+  if (ast.test)
+    str += decompileAST(ast.test);
+  str += ";";
+  if (ast.update)
+    str += decompileAST(ast.update);
+  str += ") ";
+  return str + decompileAST(ast.body);
+}
+
+function decompileForInStatement(ast) {
+  let str = "for";
+  if (ast.each)
+	  str += " each";
+  str += "(";
+  if (ast.left.type == "VariableDeclaration")
+	  str += decompileVariableDeclaration(ast.left, true);
+  else
+	  str += decompileAST(ast.left);
+  str += " in " + decompileExpr(ast.right, ast) + ") ";
+  str += decompileAST(ast.body);
+  return str;
+}
+
+function decompileLetStatement(ast) {
+  let str = "let (";
+  str += [d ? decompileAST(d) : ' ' for each (d in ast.head)].join(', ');
+  str += ") " + decompileAST(ast.body);
+  return str;
+}
+
+function decompileDebuggerStatement(ast) {
+  return "debugger;";
+}
+
+function decompileFunctionDeclaration(ast, init, name_ast) {
+  let str = (init ? init : "function") + " ";
+  if (ast.id)
+    str += ast.id.name;
+  else if (name_ast)
+	str += decompileAST(name_ast);
+  str += "(";
+  str += [decompileAST(param) for each (param in ast.params)].join(', ');
+  str += ") " + decompileAST(ast.body);
+  return str;
+}
+
+function decompileVariableDeclaration(ast, excludeSemi) {
+  let inits = [];
+  for each (let initializer in ast.declarations) {
+    inits.push(decompileAST(initializer));
+  }
+  return ast.kind + " " + inits.join(', ') + (excludeSemi ? "" : ";");
+}
+
+function decompileVariableDeclarator(ast) {
+  if (ast.init)
+    return ast.id.name + " = " + decompileAST(ast.init);
+  return ast.id.name;
+}
+
+/* Expressions */
+let precedence = {
+  "FunctionExpression": 0,
+  "YieldExpression": 1,
+  "SequenceExpression": 2,
+  "AssignmentExpression": 3,
+  "ConditionalExpression": 4,
+  "||": 5,
+  "&&": 6,
+  "|": 7,
+  "^": 8,
+  "&": 9,
+  "==": 10, "!=": 10, "===": 10, "!==": 10,
+  "<=": 11, ">=": 11, "<": 11, ">": 11, "in": 11,
+  "<<": 12, ">>": 12, ">>>": 12,
+  "+": 13, "-": 13,
+  "*": 14, "/": 14, "%": 14,
+  "UnaryExpression": 15,
+  "UpdateExpression": 16,
+  "NewExpression": 17,
+  "CallExpression": 18, "MemberExpression": 18
+  /* Everything else is 19 */
+};
+
+function getPrecedence(expr) {
+  if (expr.type in precedence)
+    return precedence[expr.type];
+  else if (expr.operator && expr.operator in precedence)
+    return precedence[expr.operator];
+  return 19;
+}
+
+function decompileExpr(expr, par) {
+  if (getPrecedence(expr) < getPrecedence(par))
+    return "(" + decompileAST(expr) + ")";
+  else
+    return decompileAST(expr);
+}
+
+function decompileThisExpression(ast) {
+	return "this";
+}
+
+function decompileArrayExpression(ast) {
+  if (ast.elements)
+    return "[" + [el ? decompileAST(el) : "" for each (el in ast.elements)].
+      join(", ") + "]";
+  return "[]";
+}
+
+function decompileObjectExpression(ast) {
+  let props = [];
+  for each (let prop in ast.properties) {
+	if (prop.kind == "init")
+      props.push(decompileAST(prop.key) + ": " + decompileAST(prop.value));
+	else if (prop.kind == "get" || prop.kind == "set")
+	  props.push(decompileFunctionDeclaration(prop.value, prop.kind, prop.key));
+	else
+	  throw "Unknown kind " + prop.kind;
+  }
+  return "{\n" + props.join(",\n") + "}";
+}
+
+function decompileFunctionExpression(ast) {
+  return decompileFunctionDeclaration(ast);
+}
+
+function decompileSequenceExpression(ast) {
+  return "(" + [decompileExpr(e, ast) for each (e in ast.expressions)].join(", ") + ")";
+}
+
+function decompileUnaryExpression(ast) {
+  if (ast.prefix)
+    return ast.operator + " " + decompileExpr(ast.argument, ast);
+  throw "ER, wtf?";
+}
+
+function decompileBinaryExpression(ast) {
+  return decompileExpr(ast.left, ast) + " " + ast.operator +
+    " " + decompileExpr(ast.right, ast);
+}
+
+function decompileAssignmentExpression(ast) {
+  return decompileExpr(ast.left, ast) + " " + ast.operator +
+    " " + decompileExpr(ast.right, ast);
+}
+
+function decompileUpdateExpression(ast) {
+  let before = "", after = ast.operator;
+  if (ast.prefix) {
+	  before = after;
+	  after = "";
+  }
+  return before + decompileExpr(ast.argument, ast) + after;
+}
+
+function decompileLogicalExpression(ast) {
+  return decompileExpr(ast.left, ast) + " " + ast.operator +
+    " " + decompileExpr(ast.right, ast);
+}
+
+function decompileConditionalExpression(ast) {
+  return decompileExpr(ast.test, ast) + " ? " +
+    decompileExpr(ast.consequent, ast) + " : " +
+    decompileExpr(ast.alternate, ast);
+}
+
+function decompileNewExpression(ast) {
+  let str = "new " + decompileAST(ast.callee, ast) + "(";
+  if (ast.arguments)
+	str += [decompileAST(arg) for each (arg in ast.arguments)].join(", ");
+  str += ")";
+  return str;
+}
+
+function decompileCallExpression(ast) {
+  return decompileExpr(ast.callee, ast) + "(" +
+    [decompileAST(param) for each (param in ast.arguments)] + ")";
+}
+
+function decompileMemberExpression(ast) {
+  function isIdentifier(ast2) {
+    let val = decompileAST(ast2);
+    if (val.length == 0) return false;
+    if (!(val[0] == '_' || val[0] == '$' ||
+          (val[0] >= 'a' && val[0] <= 'z') || (val[0] >= 'A' && val[0] <= 'Z')))
+        return false;
+    for (let i = 1; i < val.length; i++) {
+      if (!(val[i] == '_' || val[i] == '$' ||
+          (val[i] >= 'a' && val[i] <= 'z') ||
+          (val[i] >= 'A' && val[i] <= 'Z') ||
+          (val[i] >= '0' && val[i] <= '9')))
+        return false;
+    }
+    return true;
+  }
+  return decompileExpr(ast.object, ast) +
+    (ast.computed ? '[' + decompileAST(ast.property) + ']' :
+     !isIdentifier(ast.property) ?
+       '["' + sanitize(decompileAST(ast.property), '"') + '"]' :
+       '.' + ast.property.name);
+}
+
+function decompileYieldExpression(ast) {
+  return "yield" + (ast.argument ? " " + decompileAST(ast.argument) : "");
+}
+
+function decompileComprehensionExpression(ast, paren) {
+  let str = (paren ? paren.l : "[") + decompileAST(ast.body);
+  for each (let block in ast.blocks) {
+    str += (block.each ? " for each " : " for ") 
+    str += "(" + decompileAST(block.left) + " in ";
+    str += decompileAST(block.right) + ")";
+  }
+  if (ast.filter)
+    str += " if (" + decompileAST(ast.filter) + ")";
+  return str + (paren ? paren.r : "]");
+}
+
+function decompileGeneratorExpression(ast) {
+  return decompileComprehensionExpression(ast, {l: "(", r: ")"});
+}
+
+function decompileGraphExpression(ast) {
+  return "#" + ast.index + "=" + decompileAST(ast.expression);
+}
+
+function decompileGraphIndexExpression(ast) {
+  return "#" + ast.index;
+}
+
+function decompileLetExpression(ast) {
+  return decompileLetStatement(ast);
+}
+
+/* Patterns */
+
+function decompileObjectPattern(ast) {
+  let str = "{";
+  str += [decompileAST(p.key) + ": " + decompileAST(p.value)
+	for each (p in ast.properties)].join(', ');
+  return str + "}";
+}
+
+function decompileArrayPattern(ast) {
+  return "[" +
+	[e ? decompileAST(e) : ' ' for each (e in ast.elements)].join(', ') + "]";
+}
+
+function decompileIdentifier(ast) { return ast.name; }
+
+function sanitize(str, q) {
+  function replace(x) {
+    if (x == q) return '\\' + q;
+    if (x == '\\') return '\\\\';
+    if (x == '\b') return '\\b';
+    if (x == '\f') return '\\f';
+    if (x == '\n') return '\\n';
+    if (x == '\r') return '\\r';
+    if (x == '\t') return '\\t';
+    if (x == '\v') return '\\v';
+    let val = x.charCodeAt(0)
+    if (x < ' ') return '\\x' + (val - val % 16) / 16 + (val % 16);
+    return x;
+  }
+  return [replace(x) for each (x in str)].join('');
+}
+
+function decompileLiteral(ast) {
+  if (typeof ast.value == "string")
+    return '"' + sanitize(ast.value, '"') + '"';
+  if (ast.value === null)
+	  return "null";
+  return ast.value;
+}
+
+/* E4X */
+function decompileXMLDefaultDeclaration(ast) {
+  return "default xml namespace = " + decompileAST(ast.namespace) + ";";
+}
+
+function decompileXMLAnyName(ast) {
+  return "*";
+}
+
+function decompileXMLQualifiedIdentifier(ast) {
+  let str = decompileAST(ast.left) + "::";
+  if (ast.computed)
+	str += "[";
+  str += decompileAST(ast.right);
+  if (ast.computed)
+	str += "]";
+  return str;
+}
+
+function decompileXMLFunctionQualifiedIdentifier(ast) {
+  let str = "function::";
+  if (ast.computed)
+	str += "[";
+  str += decompileAST(ast.right);
+  if (ast.computed)
+	str += "]";
+  return str;
+}
+
+function decompileXMLAttributeSelector(ast) {
+  return "@" + decompileAST(ast.attribute);
+}
+
+function decompileXMLFilterExpression(ast) {
+  return decompileAST(ast.left) + ".(" + decompileAST(ast.right) + ")";
+}
+
+function decompileXMLElement(ast) {
+  return [decompileAST(xml) for each (xml in ast.contents)].join('');
+}
+
+function decompileXMLList(ast) {
+  return "<>" + [decompileAST(xml) for each (xml in ast.contents)].join("") + "</>";
+}
+
+function decompileXMLEscape(ast) {
+  return "{" + decompileAST(ast.expression) + "}";
+}
+
+function decompileXMLText(ast) {
+  return ast.text;
+}
+
+function tagJoin(strings) {
+  let str = strings[0];
+  for (let i = 1; i < strings.length; i++)
+    str += (i % 2 ? ' ' : '=') + strings[i];
+  return str;
+}
+
+function decompileXMLStartTag(ast) {
+  return "<" + tagJoin([decompileAST(xml) for each (xml in ast.contents)]) + ">";
+}
+
+function decompileXMLEndTag(ast) {
+  return "</" + tagJoin([decompileAST(xml) for each (xml in ast.contents)]) + ">";
+}
+
+function decompileXMLPointTag(ast) {
+  return "<" + tagJoin([decompileAST(xml) for each (xml in ast.contents)]) + "/>";
+}
+
+function decompileXMLName(ast) {
+  if (typeof ast.contents == "string")
+	return ast.contents + " ";
+  return [decompileAST(xml) for each (xml in ast.contents)].join('');
+}
+
+function decompileXMLAttribute(ast) {
+  return '"' + ast.value + '"';
+}
+
+function decompileXMLCdata(ast) {
+  return "<![CDATA[" + ast.contents + "]]>";
+}
+
+function decompileXMLComment(ast) {
+  return "<!--" + ast.comment + "-->";
+}
+
+function decompileXMLProcessingInstruction(ast) {
+  return "<?" + ast.target + (ast.contents ? " " + ast.contents : "") + "?>";
+}
+
+function process_js(ast) {
+	_print(decompileAST(ast));
+}

-- 
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