Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix: instrumentation breaks `new(require('foo'))(args)` #19

Open
wants to merge 1 commit into from

1 participant

@andreyvit

Fix a missing parenthesis when generating code for a new() statement applied to an expression, like the example:

new(require('foo'))(args)

which used to generate

new require('foo')(args)

resulting in the returned function being called without 'new'.

I have no idea why on earth TOK_LP calls instrument_function_call; it seems to treat all parethesized expressions as function calls, but I didn't feel like investigating that.

@andreyvit andreyvit Fix: instrumentation breaks "new(require('foo'))(args)"
Fix a missing parenthesis when generating code for a new() statement
applied to an expression, like the example:

    new(require('foo'))(args)

which used to generate

    new require('foo')(args)

resulting in the returned function being called without 'new'.

I have no idea why on earth TOK_LP calls instrument_function_call; it
seems to treat all parethesized expressions as function calls, but I
didn't feel like investigating that.
c7801a9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 22, 2012
  1. @andreyvit

    Fix: instrumentation breaks "new(require('foo'))(args)"

    andreyvit authored
    Fix a missing parenthesis when generating code for a new() statement
    applied to an expression, like the example:
    
        new(require('foo'))(args)
    
    which used to generate
    
        new require('foo')(args)
    
    resulting in the returned function being called without 'new'.
    
    I have no idea why on earth TOK_LP calls instrument_function_call; it
    seems to treat all parethesized expressions as function calls, but I
    didn't feel like investigating that.
This page is out of date. Refresh to see the latest.
View
13 instrument-js.cpp
@@ -438,7 +438,7 @@ static void instrument_function(JSParseNode * node, Stream * f, int indent, enum
Stream_write_char(f, '}');
}
-static void instrument_function_call(JSParseNode * node, Stream * f) {
+static void instrument_function_call(JSParseNode * node, Stream * f, bool parenthesize_for_new) {
JSParseNode * function_node = node->pn_head;
if (function_node->pn_type == TOK_FUNCTION) {
JSObject * object = function_node->pn_funpob->object;
@@ -455,7 +455,14 @@ static void instrument_function_call(JSParseNode * node, Stream * f) {
return;
}
}
+ bool parenthesize_callee = parenthesize_for_new && (function_node->pn_type == TOK_LP); // e.g. new (require('foo'))()
+ if (parenthesize_callee) {
+ Stream_write_char(f, '(');
+ }
output_expression(function_node, f, false);
+ if (parenthesize_callee) {
+ Stream_write_char(f, ')');
+ }
Stream_write_char(f, '(');
for (struct JSParseNode * p = function_node->pn_next; p != NULL; p = p->pn_next) {
if (p != node->pn_head->pn_next) {
@@ -636,7 +643,7 @@ static void output_expression(JSParseNode * node, Stream * f, bool parenthesize_
break;
case TOK_NEW:
Stream_write_string(f, "new ");
- instrument_function_call(node, f);
+ instrument_function_call(node, f, true);
break;
case TOK_DELETE:
Stream_write_string(f, "delete ");
@@ -693,7 +700,7 @@ static void output_expression(JSParseNode * node, Stream * f, bool parenthesize_
Stream_write_char(f, ']');
break;
case TOK_LP:
- instrument_function_call(node, f);
+ instrument_function_call(node, f, false);
break;
case TOK_RB:
Stream_write_char(f, '[');
View
25 tests/javascript.expected/javascript-new-indirect.js
@@ -0,0 +1,25 @@
+/* automatically generated by JSCoverage - do not edit */
+if (typeof _$jscoverage === 'undefined') _$jscoverage = {};
+if (! _$jscoverage['javascript-new-indirect.js']) {
+ _$jscoverage['javascript-new-indirect.js'] = [];
+ _$jscoverage['javascript-new-indirect.js'][1] = 0;
+ _$jscoverage['javascript-new-indirect.js'][2] = 0;
+ _$jscoverage['javascript-new-indirect.js'][3] = 0;
+ _$jscoverage['javascript-new-indirect.js'][4] = 0;
+ _$jscoverage['javascript-new-indirect.js'][5] = 0;
+}
+_$jscoverage['javascript-new-indirect.js'][1]++;
+function X() {
+}
+_$jscoverage['javascript-new-indirect.js'][2]++;
+function y() {
+ _$jscoverage['javascript-new-indirect.js'][2]++;
+ return X;
+}
+_$jscoverage['javascript-new-indirect.js'][3]++;
+x = new (y())();
+_$jscoverage['javascript-new-indirect.js'][4]++;
+x = new (y())(1);
+_$jscoverage['javascript-new-indirect.js'][5]++;
+x = new (y())(1, 2);
+_$jscoverage['javascript-new-indirect.js'].source = ["function X() {}","function y() { return X; }","x = new (y())();","x = new (y())(1);","x = new (y())(1, 2);"];
View
5 tests/javascript/javascript-new-indirect.js
@@ -0,0 +1,5 @@
+function X() {}
+function y() { return X; }
+x = new (y())();
+x = new (y())(1);
+x = new (y())(1, 2);
Something went wrong with that request. Please try again.