Bug 1185106 - Part 13: Support async function in Function.prototype.toString. r=till
MozReview-Commit-ID: 1CwKhHKOLhk
--- 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,31 @@
+var BUGNUMBER = 1185106;
+var summary = "async function toString";
+
+print(BUGNUMBER + ": " + summary);
+
+var test = `
+
+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 (asyncFunctionsEnabled())
+ eval(test);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);