mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 07:18:39 +09:00
Bug 1320388: Move JSFunction::HAS_REST to JSScript and LazyScript
Issue #78 [Depends on] Bug 883377: Implement ES6 function "name" property semantics
This commit is contained in:
parent
d3ffa46e36
commit
e7ee7caf1e
16 changed files with 52 additions and 37 deletions
|
|
@ -3423,7 +3423,7 @@ ASTSerializer::function(ParseNode* pn, ASTType type, MutableHandleValue dst)
|
|||
NodeVector defaults(cx);
|
||||
|
||||
RootedValue body(cx), rest(cx);
|
||||
if (func->hasRest())
|
||||
if (pn->pn_funbox->hasRest())
|
||||
rest.setUndefined();
|
||||
else
|
||||
rest.setNull();
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ const Class js::ScalarTypeDescr::class_ = {
|
|||
|
||||
const JSFunctionSpec js::ScalarTypeDescr::typeObjectMethods[] = {
|
||||
JS_SELF_HOSTED_FN("toSource", "DescrToSource", 0, 0),
|
||||
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, JSFUN_HAS_REST),
|
||||
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
|
||||
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1053,7 +1053,7 @@ BytecodeEmitter::EmitterScope::enterFunction(BytecodeEmitter* bce, FunctionBox*
|
|||
if (p) {
|
||||
MOZ_ASSERT(bi.kind() == BindingKind::FormalParameter);
|
||||
MOZ_ASSERT(!funbox->hasDestructuringArgs);
|
||||
MOZ_ASSERT(!funbox->function()->hasRest());
|
||||
MOZ_ASSERT(!funbox->hasRest());
|
||||
p->value() = loc;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -8017,7 +8017,7 @@ BytecodeEmitter::isRestParameter(ParseNode* pn, bool* result)
|
|||
|
||||
FunctionBox* funbox = sc->asFunctionBox();
|
||||
RootedFunction fun(cx, funbox->function());
|
||||
if (!fun->hasRest()) {
|
||||
if (!funbox->hasRest()) {
|
||||
*result = false;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -8960,7 +8960,7 @@ BytecodeEmitter::emitFunctionFormalParameters(ParseNode* pn)
|
|||
EmitterScope* funScope = innermostEmitterScope;
|
||||
|
||||
bool hasParameterExprs = funbox->hasParameterExprs;
|
||||
bool hasRest = funbox->function()->hasRest();
|
||||
bool hasRest = funbox->hasRest();
|
||||
|
||||
uint16_t argSlot = 0;
|
||||
for (ParseNode* arg = pn->pn_head; arg != funBody; arg = arg->pn_next, argSlot++) {
|
||||
|
|
|
|||
|
|
@ -465,6 +465,7 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, LifoAlloc& alloc, ObjectBox* trac
|
|||
usesApply(false),
|
||||
usesThis(false),
|
||||
usesReturn(false),
|
||||
hasRest_(false),
|
||||
funCxFlags()
|
||||
{
|
||||
// Functions created at parse time may be set singleton after parsing and
|
||||
|
|
@ -477,7 +478,6 @@ void
|
|||
FunctionBox::initFromLazyFunction()
|
||||
{
|
||||
JSFunction* fun = function();
|
||||
length = fun->nargs() - fun->hasRest();
|
||||
if (fun->lazyScript()->isDerivedClassConstructor())
|
||||
setDerivedClassConstructor();
|
||||
if (fun->lazyScript()->needsHomeObject())
|
||||
|
|
@ -492,8 +492,6 @@ FunctionBox::initStandaloneFunction(Scope* enclosingScope)
|
|||
// Standalone functions are Function or Generator constructors and are
|
||||
// always scoped to the global.
|
||||
MOZ_ASSERT(enclosingScope->is<GlobalScope>());
|
||||
JSFunction* fun = function();
|
||||
length = fun->nargs() - fun->hasRest();
|
||||
enclosingScope_ = enclosingScope;
|
||||
allowNewTarget_ = true;
|
||||
thisBinding_ = ThisBinding::Function;
|
||||
|
|
@ -2214,6 +2212,8 @@ Parser<SyntaxParseHandler>::finishFunction()
|
|||
lazy->setStrict();
|
||||
lazy->setGeneratorKind(funbox->generatorKind());
|
||||
lazy->setAsyncKind(funbox->asyncKind());
|
||||
if (funbox->hasRest())
|
||||
lazy->setHasRest();
|
||||
if (funbox->isLikelyConstructorWrapper())
|
||||
lazy->setLikelyConstructorWrapper();
|
||||
if (funbox->isDerivedClassConstructor())
|
||||
|
|
@ -2757,7 +2757,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||
}
|
||||
|
||||
hasRest = true;
|
||||
funbox->function()->setHasRest();
|
||||
funbox->setHasRest();
|
||||
|
||||
if (!tokenStream.getToken(&tt))
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -471,6 +471,7 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
bool usesApply:1; /* contains an f.apply() call */
|
||||
bool usesThis:1; /* contains 'this' */
|
||||
bool usesReturn:1; /* contains a 'return' statement */
|
||||
bool hasRest_:1; /* has rest parameter */
|
||||
|
||||
FunctionContextFlags funCxFlags;
|
||||
|
||||
|
|
@ -539,6 +540,11 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
bool isAsync() const { return asyncKind() == AsyncFunction; }
|
||||
bool isArrow() const { return function()->isArrow(); }
|
||||
|
||||
bool hasRest() const { return hasRest_; }
|
||||
void setHasRest() {
|
||||
hasRest_ = true;
|
||||
}
|
||||
|
||||
void setGeneratorKind(GeneratorKind kind) {
|
||||
// A generator kind can be set at initialization, or when "yield" is
|
||||
// first seen. In both cases the transition can only happen from
|
||||
|
|
@ -567,7 +573,7 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
void setHasInnerFunctions() { funCxFlags.hasInnerFunctions = true; }
|
||||
|
||||
bool hasSimpleParameterList() const {
|
||||
return !function()->hasRest() && !hasParameterExprs && !hasDestructuringArgs;
|
||||
return !hasRest() && !hasParameterExprs && !hasDestructuringArgs;
|
||||
}
|
||||
|
||||
bool hasMappedArgsObj() const {
|
||||
|
|
|
|||
|
|
@ -3435,10 +3435,7 @@ JS::NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id)
|
|||
{
|
||||
return nullptr;
|
||||
}
|
||||
JSFunction* fun = &funVal.toObject().as<JSFunction>();
|
||||
if (fs->flags & JSFUN_HAS_REST)
|
||||
fun->setHasRest();
|
||||
return fun;
|
||||
return &funVal.toObject().as<JSFunction>();
|
||||
}
|
||||
|
||||
RootedAtom atom(cx, IdToFunctionName(cx, id));
|
||||
|
|
|
|||
|
|
@ -875,11 +875,7 @@ class MOZ_STACK_CLASS SourceBufferHolder final
|
|||
|
||||
#define JSFUN_CONSTRUCTOR 0x400 /* native that can be called as a ctor */
|
||||
|
||||
// 0x800 /* Unused */
|
||||
|
||||
#define JSFUN_HAS_REST 0x1000 /* function has ...rest parameter. */
|
||||
|
||||
#define JSFUN_FLAGS_MASK 0x1e00 /* | of all the JSFUN_* flags */
|
||||
#define JSFUN_FLAGS_MASK 0x600 /* | of all the JSFUN_* flags */
|
||||
|
||||
/*
|
||||
* If set, will allow redefining a non-configurable property, but only on a
|
||||
|
|
|
|||
|
|
@ -1329,8 +1329,7 @@ JSFunction::getLength(JSContext* cx, uint16_t* length)
|
|||
if (self->isInterpretedLazy() && !self->getOrCreateScript(cx))
|
||||
return false;
|
||||
|
||||
*length = self->hasScript() ? self->nonLazyScript()->funLength()
|
||||
: (self->nargs() - self->hasRest());
|
||||
*length = self->isNative() ? self->nargs() : self->nonLazyScript()->funLength();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1620,7 +1619,7 @@ const JSFunctionSpec js::function_methods[] = {
|
|||
JS_FN(js_apply_str, fun_apply, 2,0),
|
||||
JS_FN(js_call_str, fun_call, 1,0),
|
||||
JS_FN("isGenerator", fun_isGenerator,0,0),
|
||||
JS_SELF_HOSTED_FN("bind", "FunctionBind", 2, JSFUN_HAS_REST),
|
||||
JS_SELF_HOSTED_FN("bind", "FunctionBind", 2, 0),
|
||||
JS_SYM_FN(hasInstance, fun_symbolHasInstance, 1, JSPROP_READONLY | JSPROP_PERMANENT),
|
||||
JS_FS_END
|
||||
};
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class JSFunction : public js::NativeObject
|
|||
function-statement) */
|
||||
SELF_HOSTED = 0x0080, /* function is self-hosted builtin and must not be
|
||||
decompilable nor constructible. */
|
||||
HAS_REST = 0x0100, /* function has a rest (...) parameter */
|
||||
INTERPRETED_LAZY = 0x0200, /* function is interpreted but doesn't have a script yet */
|
||||
RESOLVED_LENGTH = 0x0400, /* f.length has been resolved (see fun_resolve). */
|
||||
RESOLVED_NAME = 0x0800, /* f.name has been resolved (see fun_resolve). */
|
||||
|
|
@ -95,7 +94,7 @@ class JSFunction : public js::NativeObject
|
|||
NO_XDR_FLAGS = RESOLVED_LENGTH | RESOLVED_NAME,
|
||||
|
||||
STABLE_ACROSS_CLONES = CONSTRUCTOR | EXPR_BODY | HAS_GUESSED_ATOM | LAMBDA |
|
||||
SELF_HOSTED | HAS_REST | FUNCTION_KIND_MASK
|
||||
SELF_HOSTED | FUNCTION_KIND_MASK
|
||||
};
|
||||
|
||||
static_assert((INTERPRETED | INTERPRETED_LAZY) == js::JS_FUNCTION_INTERPRETED_BITS,
|
||||
|
|
@ -183,7 +182,6 @@ class JSFunction : public js::NativeObject
|
|||
bool hasGuessedAtom() const { return flags() & HAS_GUESSED_ATOM; }
|
||||
bool isLambda() const { return flags() & LAMBDA; }
|
||||
bool isBoundFunction() const { return flags() & BOUND_FUN; }
|
||||
bool hasRest() const { return flags() & HAS_REST; }
|
||||
bool isInterpretedLazy() const { return flags() & INTERPRETED_LAZY; }
|
||||
bool hasScript() const { return flags() & INTERPRETED; }
|
||||
|
||||
|
|
@ -264,11 +262,6 @@ class JSFunction : public js::NativeObject
|
|||
this->nargs_ = nargs;
|
||||
}
|
||||
|
||||
// Can be called multiple times by the parser.
|
||||
void setHasRest() {
|
||||
flags_ |= HAS_REST;
|
||||
}
|
||||
|
||||
void setIsBoundFunction() {
|
||||
MOZ_ASSERT(!isBoundFunction());
|
||||
flags_ |= BOUND_FUN;
|
||||
|
|
|
|||
|
|
@ -316,6 +316,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
|
|||
IsLegacyGenerator,
|
||||
IsStarGenerator,
|
||||
IsAsync,
|
||||
HasRest,
|
||||
OwnSource,
|
||||
ExplicitUseStrict,
|
||||
SelfHosted,
|
||||
|
|
@ -431,6 +432,8 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
|
|||
scriptBits |= (1 << IsStarGenerator);
|
||||
if (script->asyncKind() == AsyncFunction)
|
||||
scriptBits |= (1 << IsAsync);
|
||||
if (script->hasRest())
|
||||
scriptBits |= (1 << HasRest);
|
||||
if (script->hasSingletons())
|
||||
scriptBits |= (1 << HasSingleton);
|
||||
if (script->treatAsRunOnce())
|
||||
|
|
@ -582,6 +585,8 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
|
|||
|
||||
if (scriptBits & (1 << IsAsync))
|
||||
script->setAsyncKind(AsyncFunction);
|
||||
if (scriptBits & (1 << HasRest))
|
||||
script->setHasRest();
|
||||
}
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(jsbytecode) == 1);
|
||||
|
|
@ -2637,6 +2642,8 @@ JSScript::initFromFunctionBox(ExclusiveContext* cx, HandleScript script,
|
|||
script->isGeneratorExp_ = funbox->isGenexpLambda;
|
||||
script->setGeneratorKind(funbox->generatorKind());
|
||||
script->setAsyncKind(funbox->asyncKind());
|
||||
if (funbox->hasRest())
|
||||
script->setHasRest();
|
||||
|
||||
PositionalFormalParameterIter fi(script);
|
||||
while (fi && !fi.closedOver())
|
||||
|
|
@ -3295,6 +3302,7 @@ js::detail::CopyScript(JSContext* cx, HandleScript src, HandleScript dst,
|
|||
dst->needsHomeObject_ = src->needsHomeObject();
|
||||
dst->isDefaultClassConstructor_ = src->isDefaultClassConstructor();
|
||||
dst->isAsync_ = src->asyncKind() == AsyncFunction;
|
||||
dst->hasRest_ = src->hasRest_;
|
||||
|
||||
if (nconsts != 0) {
|
||||
GCPtrValue* vector = Rebase<GCPtrValue>(dst, src, src->consts()->vector);
|
||||
|
|
@ -4028,6 +4036,7 @@ LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
|
|||
p.shouldDeclareArguments = false;
|
||||
p.hasThisBinding = false;
|
||||
p.isAsync = false;
|
||||
p.hasRest = false;
|
||||
p.numClosedOverBindings = closedOverBindings.length();
|
||||
p.numInnerFunctions = innerFunctions.length();
|
||||
p.generatorKindBits = GeneratorKindAsBits(NotGenerator);
|
||||
|
|
@ -4169,7 +4178,7 @@ JSScript::hasLoops()
|
|||
bool
|
||||
JSScript::mayReadFrameArgsDirectly()
|
||||
{
|
||||
return argumentsHasVarBinding() || (function() && function()->hasRest());
|
||||
return argumentsHasVarBinding() || hasRest();
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
|
|||
|
|
@ -1012,6 +1012,8 @@ class JSScript : public js::gc::TenuredCell
|
|||
|
||||
bool isAsync_:1;
|
||||
|
||||
bool hasRest_:1;
|
||||
|
||||
// Add padding so JSScript is gc::Cell aligned. Make padding protected
|
||||
// instead of private to suppress -Wunused-private-field compiler warnings.
|
||||
protected:
|
||||
|
|
@ -1308,6 +1310,13 @@ class JSScript : public js::gc::TenuredCell
|
|||
isAsync_ = kind == js::AsyncFunction;
|
||||
}
|
||||
|
||||
bool hasRest() const {
|
||||
return hasRest_;
|
||||
}
|
||||
void setHasRest() {
|
||||
hasRest_ = true;
|
||||
}
|
||||
|
||||
void setNeedsHomeObject() {
|
||||
needsHomeObject_ = true;
|
||||
}
|
||||
|
|
@ -1940,6 +1949,7 @@ class LazyScript : public gc::TenuredCell
|
|||
uint32_t treatAsRunOnce : 1;
|
||||
uint32_t isDerivedClassConstructor : 1;
|
||||
uint32_t needsHomeObject : 1;
|
||||
uint32_t hasRest : 1;
|
||||
};
|
||||
|
||||
union {
|
||||
|
|
@ -2068,6 +2078,13 @@ class LazyScript : public gc::TenuredCell
|
|||
p_.isAsync = kind == AsyncFunction;
|
||||
}
|
||||
|
||||
bool hasRest() const {
|
||||
return p_.hasRest;
|
||||
}
|
||||
void setHasRest() {
|
||||
p_.hasRest = true;
|
||||
}
|
||||
|
||||
bool strict() const {
|
||||
return p_.strict;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2894,7 +2894,7 @@ static const JSFunctionSpec string_static_methods[] = {
|
|||
JS_INLINABLE_FN("fromCharCode", js::str_fromCharCode, 1, 0, StringFromCharCode),
|
||||
JS_INLINABLE_FN("fromCodePoint", js::str_fromCodePoint, 1, 0, StringFromCodePoint),
|
||||
|
||||
JS_SELF_HOSTED_FN("raw", "String_static_raw", 2,JSFUN_HAS_REST),
|
||||
JS_SELF_HOSTED_FN("raw", "String_static_raw", 2,0),
|
||||
JS_SELF_HOSTED_FN("substring", "String_static_substring", 3,0),
|
||||
JS_SELF_HOSTED_FN("substr", "String_static_substr", 3,0),
|
||||
JS_SELF_HOSTED_FN("slice", "String_static_slice", 3,0),
|
||||
|
|
|
|||
|
|
@ -282,8 +282,6 @@ MakeDefaultConstructor(JSContext* cx, JSOp op, JSAtom* atom, HandleObject proto)
|
|||
|
||||
ctor->setIsConstructor();
|
||||
ctor->setIsClassConstructor();
|
||||
if (derived)
|
||||
ctor->setHasRest();
|
||||
|
||||
MOZ_ASSERT(ctor->infallibleIsDefaultClassConstructor(cx));
|
||||
|
||||
|
|
|
|||
|
|
@ -3022,7 +3022,7 @@ JSRuntime::cloneSelfHostedFunctionScript(JSContext* cx, HandlePropertyName name,
|
|||
MOZ_ASSERT(!targetFun->isInterpretedLazy());
|
||||
|
||||
MOZ_ASSERT(sourceFun->nargs() == targetFun->nargs());
|
||||
MOZ_ASSERT(sourceFun->hasRest() == targetFun->hasRest());
|
||||
MOZ_ASSERT(sourceScript->hasRest() == targetFun->nonLazyScript()->hasRest());
|
||||
|
||||
// The target function might have been relazified after its flags changed.
|
||||
targetFun->setFlags(targetFun->flags() | sourceFun->flags());
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ InterpreterFrame::isNonGlobalEvalFrame() const
|
|||
JSObject*
|
||||
InterpreterFrame::createRestParameter(JSContext* cx)
|
||||
{
|
||||
MOZ_ASSERT(callee().hasRest());
|
||||
MOZ_ASSERT(script()->hasRest());
|
||||
unsigned nformal = callee().nargs() - 1, nactual = numActualArgs();
|
||||
unsigned nrest = (nactual > nformal) ? nactual - nformal : 0;
|
||||
Value* restvp = argv() + nformal;
|
||||
|
|
|
|||
|
|
@ -3249,7 +3249,7 @@ static bool
|
|||
CheckFunctionHead(ModuleValidator& m, ParseNode* fn)
|
||||
{
|
||||
JSFunction* fun = FunctionObject(fn);
|
||||
if (fun->hasRest())
|
||||
if (fn->pn_funbox->hasRest())
|
||||
return m.fail(fn, "rest args not allowed");
|
||||
if (fun->isExprBody())
|
||||
return m.fail(fn, "expression closures not allowed");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue