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 110324 28f11e31359b1f2492f76f38c836bfce9cdd2bd2
parent 110323 c4b7708e04f4f04c849faad9d1c90d1a7f360bd2
child 110325 66c3714ea45fdd00b1688ba1ba7f84ba8594a6e4
push id23680
push useremorley@mozilla.com
push dateTue, 16 Oct 2012 08:09:24 +0000
treeherdermozilla-central@8f145599e4bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbenjamin
bugs800407
milestone19.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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);