function shouldBe(expected, actual, msg = "") { if (msg) msg = " for " + msg; if (actual !== expected) throw new Error("bad value" + msg + ": " + actual + ". Expected " + expected); } function shouldBeAsync(expected, promise, msg) { let actual; var hadError = false; promise.then(function(value) { actual = value; }, function(error) { hadError = true; actual = error; }); drainMicrotasks(); if (hadError) throw actual; shouldBe(expected, actual, msg); } var AsyncFunctionPrototype = async function(){}.__proto__; function sink (p, q) { var g = async function(x) { return x; }; if (p) { if (q) g.inner = 42; return g; } return async function(x) { return x; }; } noInline(sink); for (var i = 0; i < 10000; ++i) { var f = sink(true, true); shouldBe(f.__proto__, AsyncFunctionPrototype); shouldBeAsync(42, f(42)); } // At this point, the function should be compiled down to the FTL // Test the allocation on the implicit inner else branch var f = sink(true, false); shouldBe(f.__proto__, AsyncFunctionPrototype); shouldBeAsync(12, f(12)); // Check that the allocation did not sink beyond the property assignment var f = sink(true, true); shouldBe(f.__proto__, AsyncFunctionPrototype); shouldBe(42, f.inner);