Bug 800407 - Remove incorrect assertion that Function constructor defined functions cannot have inherited strict mode. r=benjamin code=Nikhil Marathe
authorBenjamin Peterson <benjamin@python.org>
Mon, 15 Oct 2012 16:12:41 -0400
changeset 110456 28f11e31359b1f2492f76f38c836bfce9cdd2bd2
parent 110455 c4b7708e04f4f04c849faad9d1c90d1a7f360bd2
child 110457 66c3714ea45fdd00b1688ba1ba7f84ba8594a6e4
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersbenjamin
bugs800407
milestone19.0a1
Bug 800407 - Remove incorrect assertion that Function constructor defined functions cannot have inherited strict mode. r=benjamin code=Nikhil Marathe
js/src/jsfun.cpp
js/src/tests/ecma_5/extensions/strict-function-toSource.js
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -657,19 +657,16 @@ js::FunctionToString(JSContext *cx, Hand
         JS_ASSERT_IF(!funCon, src->length() > 0 && chars[0] == '(');
 
         // If a function inherits strict mode by having scopes above it that
         // have "use strict", we insert "use strict" into the body of the
         // function. This ensures that if the result of toString is evaled, the
         // resulting function will have the same semantics.
         bool addUseStrict = script->strictModeCode && !script->explicitUseStrict;
 
-        // Functions created with the constructor can't have inherited strict
-        // mode.
-        JS_ASSERT(!funCon || !addUseStrict);
         bool buildBody = funCon && !bodyOnly;
         if (buildBody) {
             // This function was created with the Function constructor. We don't
             // have source for the arguments, so we have to generate that. Part
             // of bug 755821 should be cobbling the arguments passed into the
             // Function constructor into the source string.
             if (!out.append("("))
                 return NULL;
@@ -687,20 +684,27 @@ js::FunctionToString(JSContext *cx, Hand
                 }
             }
             if (!out.append(") {\n"))
                 return NULL;
         }
         if ((bodyOnly && !funCon) || addUseStrict) {
             // We need to get at the body either because we're only supposed to
             // return the body or we need to insert "use strict" into the body.
-            JS_ASSERT(!buildBody);
-            size_t bodyStart = 0, bodyEnd = 0;
-            if (!FindBody(cx, fun, chars, src->length(), &bodyStart, &bodyEnd))
-                return NULL;
+            size_t bodyStart = 0, bodyEnd;
+
+            // If the function is defined in the Function constructor, we
+            // already have a body.
+            if (!funCon) {
+                JS_ASSERT(!buildBody);
+                if (!FindBody(cx, fun, chars, src->length(), &bodyStart, &bodyEnd))
+                    return NULL;
+            } else {
+                bodyEnd = src->length();
+            }
 
             if (addUseStrict) {
                 // Output source up to beginning of body.
                 if (!out.append(chars, bodyStart))
                     return NULL;
                 if (exprBody) {
                     // We can't insert a statement into a function with an
                     // expression body. Do what the decompiler did, and insert a
@@ -710,17 +714,17 @@ js::FunctionToString(JSContext *cx, Hand
                 } else {
                     if (!out.append("\n\"use strict\";\n"))
                         return NULL;
                 }
             }
 
             // Output just the body (for bodyOnly) or the body and possibly
             // closing braces (for addUseStrict).
-            size_t dependentEnd = (bodyOnly) ? bodyEnd : src->length();
+            size_t dependentEnd = bodyOnly ? bodyEnd : src->length();
             if (!out.append(chars + bodyStart, dependentEnd - bodyStart))
                 return NULL;
         } else {
             if (!out.append(src))
                 return NULL;
         }
         if (buildBody) {
             if (!out.append("\n}"))
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/strict-function-toSource.js
@@ -0,0 +1,15 @@
+/*
+ * Bug 800407 - Functions defined with Function construcor
+ * do have strict mode when JSOPTION_STRICT_MODE is on.
+ */
+
+options("strict_mode");
+function testRunOptionStrictMode(str, arg, result) {
+    var strict_inner = new Function('return typeof this == "undefined";');
+    return strict_inner;
+}
+assertEq(eval(uneval(testRunOptionStrictMode()))(), true);
+
+assertEq(decompileBody(new Function('x', 'return x*2;')).contains('\n"use strict"'), true)
+
+reportCompare(true, true);