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