summaryrefslogtreecommitdiffstats
path: root/js/src/jsfun.cpp
diff options
context:
space:
mode:
authorjanekptacijarabaci <janekptacijarabaci@seznam.cz>2018-03-16 09:04:55 +0100
committerjanekptacijarabaci <janekptacijarabaci@seznam.cz>2018-03-16 09:04:55 +0100
commit28d4e4a5fa5ba7a22d3497769fbb5a9d11db7a9e (patch)
tree3565ccfc38a6ea0f86c1bfbe5751dee60be602b7 /js/src/jsfun.cpp
parent11bdaa144d8a38ecd897dde278cb1db9b8313961 (diff)
downloadUXP-28d4e4a5fa5ba7a22d3497769fbb5a9d11db7a9e.tar
UXP-28d4e4a5fa5ba7a22d3497769fbb5a9d11db7a9e.tar.gz
UXP-28d4e4a5fa5ba7a22d3497769fbb5a9d11db7a9e.tar.lz
UXP-28d4e4a5fa5ba7a22d3497769fbb5a9d11db7a9e.tar.xz
UXP-28d4e4a5fa5ba7a22d3497769fbb5a9d11db7a9e.zip
Bug 1318017: Call GetPrototypeFromConstructor for generator/async function and Intl constructors
[Depends on] Bug 755821: Function() should use the parser's argument parsing code
Diffstat (limited to 'js/src/jsfun.cpp')
-rw-r--r--js/src/jsfun.cpp50
1 files changed, 39 insertions, 11 deletions
diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp
index c952441ad..9be02b217 100644
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1682,11 +1682,9 @@ const JSFunctionSpec js::function_methods[] = {
};
static bool
-FunctionConstructor(JSContext* cx, unsigned argc, Value* vp, GeneratorKind generatorKind,
+FunctionConstructor(JSContext* cx, const CallArgs& args, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind)
{
- CallArgs args = CallArgsFromVp(argc, vp);
-
/* Block this call if security callbacks forbid it. */
Rooted<GlobalObject*> global(cx, &args.callee().global());
if (!GlobalObject::isRuntimeCodeGenEnabled(cx, global)) {
@@ -1803,16 +1801,23 @@ FunctionConstructor(JSContext* cx, unsigned argc, Value* vp, GeneratorKind gener
* and so would a call to f from another top-level's script or function.
*/
RootedAtom anonymousAtom(cx, cx->names().anonymous);
+
+ // ES2017, draft rev 0f10dba4ad18de92d47d421f378233a2eae8f077
+ // 19.2.1.1.1 Runtime Semantics: CreateDynamicFunction, step 24.
RootedObject proto(cx);
- if (isStarGenerator) {
+ if (!isAsync) {
+ if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
+ return false;
+ }
+
+ // 19.2.1.1.1, step 4.d, use %Generator% as the fallback prototype.
+ // Also use %Generator% for the unwrapped function of async functions.
+ if (!proto && isStarGenerator) {
// Unwrapped function of async function should use GeneratorFunction,
// while wrapped function isn't generator.
proto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, global);
if (!proto)
return false;
- } else {
- if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
- return false;
}
RootedObject globalLexical(cx, &global->lexicalEnvironment());
@@ -1921,24 +1926,47 @@ FunctionConstructor(JSContext* cx, unsigned argc, Value* vp, GeneratorKind gener
bool
js::Function(JSContext* cx, unsigned argc, Value* vp)
{
- return FunctionConstructor(cx, argc, vp, NotGenerator, SyncFunction);
+ CallArgs args = CallArgsFromVp(argc, vp);
+ return FunctionConstructor(cx, args, NotGenerator, SyncFunction);
}
bool
js::Generator(JSContext* cx, unsigned argc, Value* vp)
{
- return FunctionConstructor(cx, argc, vp, StarGenerator, SyncFunction);
+ CallArgs args = CallArgsFromVp(argc, vp);
+ return FunctionConstructor(cx, args, StarGenerator, SyncFunction);
}
bool
js::AsyncFunctionConstructor(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
- if (!FunctionConstructor(cx, argc, vp, StarGenerator, AsyncFunction))
+
+ // Save the callee before its reset in FunctionConstructor().
+ RootedObject newTarget(cx);
+ if (args.isConstructing())
+ newTarget = &args.newTarget().toObject();
+ else
+ newTarget = &args.callee();
+
+ if (!FunctionConstructor(cx, args, StarGenerator, AsyncFunction))
return false;
+ // ES2017, draft rev 0f10dba4ad18de92d47d421f378233a2eae8f077
+ // 19.2.1.1.1 Runtime Semantics: CreateDynamicFunction, step 24.
+ RootedObject proto(cx);
+ if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
+ return false;
+
+ // 19.2.1.1.1, step 4.d, use %AsyncFunctionPrototype% as the fallback.
+ if (!proto) {
+ proto = GlobalObject::getOrCreateAsyncFunctionPrototype(cx, cx->global());
+ if (!proto)
+ return false;
+ }
+
RootedFunction unwrapped(cx, &args.rval().toObject().as<JSFunction>());
- RootedObject wrapped(cx, WrapAsyncFunction(cx, unwrapped));
+ RootedObject wrapped(cx, WrapAsyncFunctionWithProto(cx, unwrapped, proto));
if (!wrapped)
return false;