From e08bc60c38f91ee9d9585c2d4ad564c6b9a1622f Mon Sep 17 00:00:00 2001 From: ksen Date: Thu, 6 Feb 2014 08:27:27 -0800 Subject: [PATCH] fixed issue #43 --- src/js/instrument/esnstrument.js | 38 +++++++++++++++++++++++++++++++- tests/unit/shadow-arguments.js | 23 ++++++++++++++----- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/js/instrument/esnstrument.js b/src/js/instrument/esnstrument.js index fc00ece1..08ddc333 100644 --- a/src/js/instrument/esnstrument.js +++ b/src/js/instrument/esnstrument.js @@ -1173,6 +1173,13 @@ } }; + Scope.prototype.hasOwnVar = function (name) { + var s = this; + if (s && HOP(s.vars, name)) + return s.vars[name]; + return null; + }; + Scope.prototype.hasVar = function (name) { var s = this; while (s !== null) { @@ -1210,6 +1217,10 @@ var currentScope = null; + // rename arguments to J$_arguments + var fromName = 'arguments'; + var toName = astUtil.JALANGI_VAR+"_arguments"; + function handleFun(node) { var oldScope = currentScope; currentScope = new Scope(currentScope); @@ -1217,6 +1228,9 @@ if (node.type === 'FunctionDeclaration') { oldScope.addVar(node.id.name, "defun", node.loc); MAP(node.params, function (param) { + if (param.name === fromName) { // rename arguments to J$_arguments + param.name = toName; + } currentScope.addVar(param.name, "arg"); }); } else if (node.type === 'FunctionExpression') { @@ -1224,6 +1238,9 @@ currentScope.addVar(node.id.name, "lambda"); } MAP(node.params, function (param) { + if (param.name === fromName) { // rename arguments to J$_arguments + param.name = toName; + } currentScope.addVar(param.name, "arg"); }); } @@ -1253,7 +1270,26 @@ var visitorPost = { 'Program':popScope, 'FunctionDeclaration':popScope, - 'FunctionExpression':popScope + 'FunctionExpression':popScope, + 'Identifier':function (node, context) { // rename arguments to J$_arguments + if (context === astUtil.CONTEXT.RHS && node.name === fromName && currentScope.hasOwnVar(toName)) { + node.name = toName; + } + return node; + }, + "UpdateExpression":function (node) { // rename arguments to J$_arguments + if (node.argument.type === 'Identifier' && node.argument.name === fromName && currentScope.hasOwnVar(toName)) { + node.argument.name = toName; + } + return node; + }, + "AssignmentExpression":function (node) { // rename arguments to J$_arguments + if (node.left.type === 'Identifier' && node.left.name === fromName && currentScope.hasOwnVar(toName)) { + node.left.name = toName; + } + return node; + } + }; astUtil.transformAst(ast, visitorPost, visitorPre); } diff --git a/tests/unit/shadow-arguments.js b/tests/unit/shadow-arguments.js index a5df213c..8b881663 100644 --- a/tests/unit/shadow-arguments.js +++ b/tests/unit/shadow-arguments.js @@ -1,6 +1,17 @@ - var a = function a(b, arguments) { - }; -var D = function () { - a.call(null, false, null); -}; -new D(); +function a(b, arguments) { + var x = arguments; + arguments++; + arguments += 4; + arguments = arguments + 4; + arguments[0] = 2; + arguments.callee = 'x'; + f(arguments); +} + +function f(x) {} + +function b() { + var x = arguments; + var y = arguments.callee; + var z = arguments[0]; +}