Bug 1185106 - Part 13: Support async function in Function.prototype.toString. r=till
authorTooru Fujisawa <arai_a@mac.com>
Mon, 29 Aug 2016 02:06:19 +0900
changeset 320253 6b10479b988db3c3d668611ed75791424503afd2
parent 320252 0df8a2814d0c6a7cb905086ffef6c4236fa4e2cf
child 320254 8fae1fb3e02eef78e34aeafb662cbc54496521e1
push id20754
push usercbook@mozilla.com
push dateMon, 31 Oct 2016 15:58:35 +0000
treeherderfx-team@b1b66b1780c2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1185106
milestone52.0a1
Bug 1185106 - Part 13: Support async function in Function.prototype.toString. r=till MozReview-Commit-ID: 1CwKhHKOLhk
js/src/jsfun.cpp
js/src/tests/ecma_7/AsyncFunctions/toString.js
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -34,16 +34,17 @@
 #include "frontend/TokenStream.h"
 #include "gc/Marking.h"
 #include "gc/Policy.h"
 #include "jit/InlinableNatives.h"
 #include "jit/Ion.h"
 #include "jit/JitFrameIterator.h"
 #include "js/CallNonGenericMethod.h"
 #include "js/Proxy.h"
+#include "vm/AsyncFunction.h"
 #include "vm/Debugger.h"
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
 #include "vm/SelfHosting.h"
 #include "vm/Shape.h"
 #include "vm/SharedImmutableStringsCache.h"
 #include "vm/StringBuffer.h"
 #include "vm/WrapperObject.h"
@@ -981,44 +982,59 @@ js::FunctionToString(JSContext* cx, Hand
     if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx))
         return nullptr;
 
     if (IsAsmJSModule(fun))
         return AsmJSModuleToString(cx, fun, !lambdaParen);
     if (IsAsmJSFunction(fun))
         return AsmJSFunctionToString(cx, fun);
 
+    if (IsWrappedAsyncFunction(cx, fun)) {
+        RootedFunction unwrapped(cx, GetUnwrappedAsyncFunction(fun));
+        return FunctionToString(cx, unwrapped, lambdaParen);
+    }
+
     StringBuffer out(cx);
     RootedScript script(cx);
 
     if (fun->hasScript()) {
         script = fun->nonLazyScript();
         if (script->isGeneratorExp()) {
             if (!out.append("function genexp() {") ||
                 !out.append("\n    [generator expression]\n") ||
                 !out.append("}"))
             {
                 return nullptr;
             }
             return out.finishString();
         }
     }
 
+    if (fun->isAsync()) {
+        if (!out.append("async "))
+            return nullptr;
+    }
+
     bool funIsMethodOrNonArrowLambda = (fun->isLambda() && !fun->isArrow()) || fun->isMethod() ||
                                         fun->isGetter() || fun->isSetter();
 
     // If we're not in pretty mode, put parentheses around lambda functions and methods.
     if (fun->isInterpreted() && !lambdaParen && funIsMethodOrNonArrowLambda &&
         !fun->isSelfHostedBuiltin())
     {
         if (!out.append("("))
             return nullptr;
     }
     if (!fun->isArrow()) {
-        if (!(fun->isStarGenerator() ? out.append("function* ") : out.append("function ")))
+        bool ok;
+        if (fun->isStarGenerator() && !fun->isAsync())
+            ok = out.append("function* ");
+        else
+            ok = out.append("function ");
+        if (!ok)
             return nullptr;
     }
     if (fun->name()) {
         if (!out.append(fun->name()))
             return nullptr;
     }
 
     bool haveSource = fun->isInterpreted() && !fun->isSelfHostedBuiltin();
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/toString.js
@@ -0,0 +1,24 @@
+var BUGNUMBER = 1185106;
+var summary = "async function toString";
+
+print(BUGNUMBER + ": " + summary);
+
+async function f1(a, b, c) { await a; }
+
+assertEq(f1.toString(),
+         "async function f1(a, b, c) { await a; }");
+
+assertEq(async function (a, b, c) { await a; }.toString(),
+         "async function (a, b, c) { await a; }");
+
+assertEq((async (a, b, c) => await a).toString(),
+         "async (a, b, c) => await a");
+
+assertEq((async (a, b, c) => { await a; }).toString(),
+         "async (a, b, c) => { await a; }");
+
+assertEq({ async foo(a, b, c) { await a; } }.foo.toString(),
+         "async function foo(a, b, c) { await a; }");
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);