Bug 1530745 - Part 3: Add a helper to retrieve the prototype for a specific function type. r=arai

Depends on D22667

Differential Revision: https://phabricator.services.mozilla.com/D22668

--HG--
extra : moz-landing-system : lando
This commit is contained in:
André Bargull 2019-03-08 12:36:14 +00:00
Родитель 6cfbd3c507
Коммит d6d62140a2
4 изменённых файлов: 55 добавлений и 83 удалений

Просмотреть файл

@ -2557,23 +2557,8 @@ GeneralParser<ParseHandler, Unit>::functionDefinition(
}
RootedObject proto(cx_);
if (asyncKind == FunctionAsyncKind::AsyncFunction &&
generatorKind == GeneratorKind::Generator) {
proto = GlobalObject::getOrCreateAsyncGenerator(cx_, cx_->global());
if (!proto) {
return null();
}
} else if (asyncKind == FunctionAsyncKind::AsyncFunction) {
proto = GlobalObject::getOrCreateAsyncFunctionPrototype(cx_, cx_->global());
if (!proto) {
return null();
}
} else if (generatorKind == GeneratorKind::Generator) {
proto =
GlobalObject::getOrCreateGeneratorFunctionPrototype(cx_, cx_->global());
if (!proto) {
return null();
}
if (!GetFunctionPrototype(cx_, generatorKind, asyncKind, &proto)) {
return null();
}
RootedFunction fun(
cx_, newFunction(funName, kind, generatorKind, asyncKind, proto));

Просмотреть файл

@ -605,23 +605,17 @@ XDRResult js::XDRInterpretedFunction(XDRState<mode>* xdr,
MOZ_TRY(xdr->codeUint32(&flagsword));
if (mode == XDR_DECODE) {
GeneratorKind generatorKind = (firstword & IsGenerator)
? GeneratorKind::Generator
: GeneratorKind::NotGenerator;
FunctionAsyncKind asyncKind = (firstword & IsAsync)
? FunctionAsyncKind::AsyncFunction
: FunctionAsyncKind::SyncFunction;
RootedObject proto(cx);
if ((firstword & IsAsync) && (firstword & IsGenerator)) {
proto = GlobalObject::getOrCreateAsyncGenerator(cx, cx->global());
if (!proto) {
return xdr->fail(JS::TranscodeResult_Throw);
}
} else if (firstword & IsAsync) {
proto = GlobalObject::getOrCreateAsyncFunctionPrototype(cx, cx->global());
if (!proto) {
return xdr->fail(JS::TranscodeResult_Throw);
}
} else if (firstword & IsGenerator) {
proto =
GlobalObject::getOrCreateGeneratorFunctionPrototype(cx, cx->global());
if (!proto) {
return xdr->fail(JS::TranscodeResult_Throw);
}
if (!GetFunctionPrototype(cx, generatorKind, asyncKind, &proto)) {
return xdr->fail(JS::TranscodeResult_Throw);
}
gc::AllocKind allocKind = gc::AllocKind::FUNCTION;
@ -1910,22 +1904,8 @@ static bool CreateDynamicFunction(JSContext* cx, const CallArgs& args,
// Initialize the function with the default prototype:
// Leave as nullptr to get the default from clasp for normal functions.
RootedObject defaultProto(cx);
if (isAsync && isGenerator) {
defaultProto = GlobalObject::getOrCreateAsyncGenerator(cx, cx->global());
if (!defaultProto) {
return false;
}
} else if (isAsync) {
defaultProto = GlobalObject::getOrCreateAsyncFunctionPrototype(cx, global);
if (!defaultProto) {
return false;
}
} else if (isGenerator) {
defaultProto =
GlobalObject::getOrCreateGeneratorFunctionPrototype(cx, global);
if (!defaultProto) {
return false;
}
if (!GetFunctionPrototype(cx, generatorKind, asyncKind, &defaultProto)) {
return false;
}
// Step 30-37 (reordered).
@ -2149,6 +2129,28 @@ JSFunction* js::NewFunctionWithProto(
return fun;
}
bool js::GetFunctionPrototype(JSContext* cx, js::GeneratorKind generatorKind,
js::FunctionAsyncKind asyncKind,
js::MutableHandleObject proto) {
if (generatorKind == js::GeneratorKind::NotGenerator) {
if (asyncKind == js::FunctionAsyncKind::SyncFunction) {
proto.set(nullptr);
return true;
}
proto.set(
GlobalObject::getOrCreateAsyncFunctionPrototype(cx, cx->global()));
} else {
if (asyncKind == js::FunctionAsyncKind::SyncFunction) {
proto.set(GlobalObject::getOrCreateGeneratorFunctionPrototype(
cx, cx->global()));
} else {
proto.set(GlobalObject::getOrCreateAsyncGenerator(cx, cx->global()));
}
}
return !!proto;
}
bool js::CanReuseScriptForClone(JS::Realm* realm, HandleFunction fun,
HandleObject newParent) {
MOZ_ASSERT(fun->isInterpreted());
@ -2183,23 +2185,9 @@ static inline JSFunction* NewFunctionClone(JSContext* cx, HandleFunction fun,
HandleObject proto) {
RootedObject cloneProto(cx, proto);
if (!proto) {
if (fun->isAsync() && fun->isGenerator()) {
cloneProto = GlobalObject::getOrCreateAsyncGenerator(cx, cx->global());
if (!cloneProto) {
return nullptr;
}
} else if (fun->isAsync()) {
cloneProto =
GlobalObject::getOrCreateAsyncFunctionPrototype(cx, cx->global());
if (!cloneProto) {
return nullptr;
}
} else if (fun->isGenerator()) {
cloneProto =
GlobalObject::getOrCreateGeneratorFunctionPrototype(cx, cx->global());
if (!cloneProto) {
return nullptr;
}
if (!GetFunctionPrototype(cx, fun->generatorKind(), fun->asyncKind(),
&cloneProto)) {
return nullptr;
}
}

Просмотреть файл

@ -894,6 +894,19 @@ extern JSFunction* NewScriptedFunction(
HandleObject proto = nullptr,
gc::AllocKind allocKind = gc::AllocKind::FUNCTION,
NewObjectKind newKind = GenericObject, HandleObject enclosingEnv = nullptr);
// Determine which [[Prototype]] to use when creating a new function using the
// requested generator and async kind.
//
// This sets `proto` to `nullptr` for non-generator, synchronous functions to
// mean "the builtin %FunctionPrototype% in the current realm", the common case.
//
// We could set it to `cx->global()->getOrCreateFunctionPrototype()`, but
// nullptr gets a fast path in e.g. js::NewObjectWithClassProtoCommon.
extern bool GetFunctionPrototype(JSContext* cx, js::GeneratorKind generatorKind,
js::FunctionAsyncKind asyncKind,
js::MutableHandleObject proto);
extern JSAtom* IdToFunctionName(
JSContext* cx, HandleId id,
FunctionPrefixKind prefixKind = FunctionPrefixKind::None);

Просмотреть файл

@ -3988,23 +3988,9 @@ static JSObject* CloneInnerInterpretedFunction(
Handle<ScriptSourceObject*> sourceObject) {
/* NB: Keep this in sync with XDRInterpretedFunction. */
RootedObject cloneProto(cx);
if (srcFun->isAsync() && srcFun->isGenerator()) {
cloneProto = GlobalObject::getOrCreateAsyncGenerator(cx, cx->global());
if (!cloneProto) {
return nullptr;
}
} else if (srcFun->isAsync()) {
cloneProto =
GlobalObject::getOrCreateAsyncFunctionPrototype(cx, cx->global());
if (!cloneProto) {
return nullptr;
}
} else if (srcFun->isGenerator()) {
cloneProto =
GlobalObject::getOrCreateGeneratorFunctionPrototype(cx, cx->global());
if (!cloneProto) {
return nullptr;
}
if (!GetFunctionPrototype(cx, srcFun->generatorKind(), srcFun->asyncKind(),
&cloneProto)) {
return nullptr;
}
gc::AllocKind allocKind = srcFun->getAllocKind();