зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
6cfbd3c507
Коммит
d6d62140a2
|
@ -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();
|
||||
|
|
Загрузка…
Ссылка в новой задаче