зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1059908 - Merge FunctionType and FunctionSyntaxKind. r=efaust
This commit is contained in:
Родитель
8444c671f4
Коммит
d554d80442
|
@ -7604,9 +7604,7 @@ ParseFunction(ModuleCompiler& m, ParseNode** fnOut)
|
|||
if (!funpc.init(tokenStream))
|
||||
return false;
|
||||
|
||||
if (!m.parser().functionArgsAndBodyGeneric(InAllowed, YieldIsName, fn, fun, Normal,
|
||||
Statement))
|
||||
{
|
||||
if (!m.parser().functionArgsAndBodyGeneric(InAllowed, YieldIsName, fn, fun, Statement)) {
|
||||
if (tokenStream.hadError() || directives == newDirectives)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -282,7 +282,9 @@ frontend::CompileScript(ExclusiveContext* cx, LifoAlloc* alloc, HandleObject sco
|
|||
return nullptr;
|
||||
|
||||
bool savedCallerFun = evalCaller && evalCaller->functionOrCallerFunction();
|
||||
bool allowSuperProperty = savedCallerFun && evalCaller->functionOrCallerFunction()->isMethod();
|
||||
bool allowSuperProperty = savedCallerFun && (evalCaller->functionOrCallerFunction()->isMethod() ||
|
||||
evalCaller->functionOrCallerFunction()->isGetter() ||
|
||||
evalCaller->functionOrCallerFunction()->isSetter());
|
||||
|
||||
Directives directives(options.strictOption);
|
||||
GlobalSharedContext globalsc(cx, directives, options.extraWarningsOption, allowSuperProperty);
|
||||
|
|
|
@ -1693,7 +1693,16 @@ enum ParseReportKind
|
|||
ParseStrictError
|
||||
};
|
||||
|
||||
enum FunctionSyntaxKind { Expression, Statement, Arrow, Method };
|
||||
enum FunctionSyntaxKind
|
||||
{
|
||||
Expression,
|
||||
Statement,
|
||||
Arrow,
|
||||
Method,
|
||||
ClassConstructor,
|
||||
Getter,
|
||||
Setter
|
||||
};
|
||||
|
||||
static inline ParseNode*
|
||||
FunctionArgsList(ParseNode* fn, unsigned* numFormals)
|
||||
|
|
|
@ -1215,6 +1215,7 @@ Parser<ParseHandler>::newFunction(HandleAtom atom, FunctionSyntaxKind kind, Hand
|
|||
|
||||
RootedFunction fun(context);
|
||||
|
||||
gc::AllocKind allocKind = gc::AllocKind::FUNCTION;
|
||||
JSFunction::Flags flags;
|
||||
switch (kind) {
|
||||
case Expression:
|
||||
|
@ -1222,18 +1223,27 @@ Parser<ParseHandler>::newFunction(HandleAtom atom, FunctionSyntaxKind kind, Hand
|
|||
break;
|
||||
case Arrow:
|
||||
flags = JSFunction::INTERPRETED_LAMBDA_ARROW;
|
||||
allocKind = gc::AllocKind::FUNCTION_EXTENDED;
|
||||
break;
|
||||
case Method:
|
||||
flags = JSFunction::INTERPRETED_METHOD;
|
||||
allocKind = gc::AllocKind::FUNCTION_EXTENDED;
|
||||
break;
|
||||
case ClassConstructor:
|
||||
flags = JSFunction::INTERPRETED_CLASS_CONSTRUCTOR;
|
||||
allocKind = gc::AllocKind::FUNCTION_EXTENDED;
|
||||
break;
|
||||
case Getter:
|
||||
flags = JSFunction::INTERPRETED_GETTER;
|
||||
break;
|
||||
case Setter:
|
||||
flags = JSFunction::INTERPRETED_SETTER;
|
||||
break;
|
||||
default:
|
||||
flags = JSFunction::INTERPRETED;
|
||||
break;
|
||||
}
|
||||
|
||||
gc::AllocKind allocKind = gc::AllocKind::FUNCTION;
|
||||
if (kind == Arrow || kind == Method)
|
||||
allocKind = gc::AllocKind::FUNCTION_EXTENDED;
|
||||
fun = NewFunctionWithProto(context, nullptr, 0, flags, NullPtr(), atom, proto,
|
||||
allocKind, TenuredObject);
|
||||
if (!fun)
|
||||
|
@ -1556,7 +1566,7 @@ Parser<ParseHandler>::bindDestructuringArg(BindData<ParseHandler>* data,
|
|||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind,
|
||||
FunctionType type, Node* listp, Node funcpn, bool* hasRest)
|
||||
Node* listp, Node funcpn, bool* hasRest)
|
||||
{
|
||||
FunctionBox* funbox = pc->sc->asFunctionBox();
|
||||
|
||||
|
@ -1604,9 +1614,9 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||
bool hasDefaults = false;
|
||||
Node duplicatedArg = null();
|
||||
Node list = null();
|
||||
bool disallowDuplicateArgs = kind == Arrow || kind == Method;
|
||||
bool disallowDuplicateArgs = kind == Arrow || kind == Method || kind == ClassConstructor;
|
||||
|
||||
if (type == Getter) {
|
||||
if (kind == Getter) {
|
||||
report(ParseError, false, null(), JSMSG_ACCESSOR_WRONG_ARGS, "getter", "no", "s");
|
||||
return false;
|
||||
}
|
||||
|
@ -1689,7 +1699,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||
|
||||
case TOK_TRIPLEDOT:
|
||||
{
|
||||
if (type == Setter) {
|
||||
if (kind == Setter) {
|
||||
report(ParseError, false, null(),
|
||||
JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
|
||||
return false;
|
||||
|
@ -1766,7 +1776,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||
return false;
|
||||
}
|
||||
|
||||
if (parenFreeArrow || type == Setter)
|
||||
if (parenFreeArrow || kind == Setter)
|
||||
break;
|
||||
|
||||
bool matched;
|
||||
|
@ -1781,7 +1791,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||
if (!tokenStream.getToken(&tt))
|
||||
return false;
|
||||
if (tt != TOK_RP) {
|
||||
if (type == Setter) {
|
||||
if (kind == Setter) {
|
||||
report(ParseError, false, null(),
|
||||
JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
|
||||
return false;
|
||||
|
@ -1794,7 +1804,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||
|
||||
if (!hasDefaults)
|
||||
funbox->length = pc->numArgs() - *hasRest;
|
||||
} else if (type == Setter) {
|
||||
} else if (kind == Setter) {
|
||||
report(ParseError, false, null(), JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
|
||||
return false;
|
||||
}
|
||||
|
@ -2149,9 +2159,8 @@ Parser<ParseHandler>::templateLiteral(YieldHandling yieldHandling)
|
|||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::functionDef(InHandling inHandling, YieldHandling yieldHandling,
|
||||
HandlePropertyName funName, FunctionType type,
|
||||
FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
InvokedPrediction invoked)
|
||||
HandlePropertyName funName, FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind, InvokedPrediction invoked)
|
||||
{
|
||||
MOZ_ASSERT_IF(kind == Statement, funName);
|
||||
|
||||
|
@ -2195,7 +2204,7 @@ Parser<ParseHandler>::functionDef(InHandling inHandling, YieldHandling yieldHand
|
|||
tokenStream.tell(&start);
|
||||
|
||||
while (true) {
|
||||
if (functionArgsAndBody(inHandling, pn, fun, type, kind, generatorKind, directives,
|
||||
if (functionArgsAndBody(inHandling, pn, fun, kind, generatorKind, directives,
|
||||
&newDirectives))
|
||||
{
|
||||
break;
|
||||
|
@ -2303,8 +2312,8 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox* funbo
|
|||
template <>
|
||||
bool
|
||||
Parser<FullParseHandler>::functionArgsAndBody(InHandling inHandling, ParseNode* pn,
|
||||
HandleFunction fun, FunctionType type,
|
||||
FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
HandleFunction fun, FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind,
|
||||
Directives inheritedDirectives,
|
||||
Directives* newDirectives)
|
||||
{
|
||||
|
@ -2344,8 +2353,7 @@ Parser<FullParseHandler>::functionArgsAndBody(InHandling inHandling, ParseNode*
|
|||
return false;
|
||||
|
||||
if (!parser->functionArgsAndBodyGeneric(inHandling, yieldHandling,
|
||||
SyntaxParseHandler::NodeGeneric, fun, type,
|
||||
kind))
|
||||
SyntaxParseHandler::NodeGeneric, fun, kind))
|
||||
{
|
||||
if (parser->hadAbortedSyntaxParse()) {
|
||||
// Try again with a full parse.
|
||||
|
@ -2383,7 +2391,7 @@ Parser<FullParseHandler>::functionArgsAndBody(InHandling inHandling, ParseNode*
|
|||
if (!funpc.init(tokenStream))
|
||||
return false;
|
||||
|
||||
if (!functionArgsAndBodyGeneric(inHandling, yieldHandling, pn, fun, type, kind))
|
||||
if (!functionArgsAndBodyGeneric(inHandling, yieldHandling, pn, fun, kind))
|
||||
return false;
|
||||
|
||||
if (!leaveFunction(pn, outerpc, kind))
|
||||
|
@ -2404,7 +2412,7 @@ Parser<FullParseHandler>::functionArgsAndBody(InHandling inHandling, ParseNode*
|
|||
template <>
|
||||
bool
|
||||
Parser<SyntaxParseHandler>::functionArgsAndBody(InHandling inHandling, Node pn, HandleFunction fun,
|
||||
FunctionType type, FunctionSyntaxKind kind,
|
||||
FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind,
|
||||
Directives inheritedDirectives,
|
||||
Directives* newDirectives)
|
||||
|
@ -2424,7 +2432,7 @@ Parser<SyntaxParseHandler>::functionArgsAndBody(InHandling inHandling, Node pn,
|
|||
return false;
|
||||
|
||||
YieldHandling yieldHandling = generatorKind != NotGenerator ? YieldIsKeyword : YieldIsName;
|
||||
if (!functionArgsAndBodyGeneric(inHandling, yieldHandling, pn, fun, type, kind))
|
||||
if (!functionArgsAndBodyGeneric(inHandling, yieldHandling, pn, fun, kind))
|
||||
return false;
|
||||
|
||||
if (!leaveFunction(pn, outerpc, kind))
|
||||
|
@ -2486,8 +2494,16 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, unsigned st
|
|||
return null();
|
||||
|
||||
YieldHandling yieldHandling = generatorKind != NotGenerator ? YieldIsKeyword : YieldIsName;
|
||||
FunctionSyntaxKind syntaxKind = fun->isMethod() ? Method : Statement;
|
||||
if (!functionArgsAndBodyGeneric(InAllowed, yieldHandling, pn, fun, Normal, syntaxKind)) {
|
||||
FunctionSyntaxKind syntaxKind = Statement;
|
||||
if (fun->isClassConstructor())
|
||||
syntaxKind = ClassConstructor;
|
||||
else if (fun->isMethod())
|
||||
syntaxKind = Method;
|
||||
else if (fun->isGetter())
|
||||
syntaxKind = Getter;
|
||||
else if (fun->isSetter())
|
||||
syntaxKind = Setter;
|
||||
if (!functionArgsAndBodyGeneric(InAllowed, yieldHandling, pn, fun, syntaxKind)) {
|
||||
MOZ_ASSERT(directives == newDirectives);
|
||||
return null();
|
||||
}
|
||||
|
@ -2515,8 +2531,7 @@ template <typename ParseHandler>
|
|||
bool
|
||||
Parser<ParseHandler>::functionArgsAndBodyGeneric(InHandling inHandling,
|
||||
YieldHandling yieldHandling, Node pn,
|
||||
HandleFunction fun, FunctionType type,
|
||||
FunctionSyntaxKind kind)
|
||||
HandleFunction fun, FunctionSyntaxKind kind)
|
||||
{
|
||||
// Given a properly initialized parse context, try to parse an actual
|
||||
// function without concern for conversion to strict mode, use of lazy
|
||||
|
@ -2524,7 +2539,7 @@ Parser<ParseHandler>::functionArgsAndBodyGeneric(InHandling inHandling,
|
|||
|
||||
Node prelude = null();
|
||||
bool hasRest;
|
||||
if (!functionArguments(yieldHandling, kind, type, &prelude, pn, &hasRest))
|
||||
if (!functionArguments(yieldHandling, kind, &prelude, pn, &hasRest))
|
||||
return false;
|
||||
|
||||
FunctionBox* funbox = pc->sc->asFunctionBox();
|
||||
|
@ -2574,8 +2589,11 @@ Parser<ParseHandler>::functionArgsAndBodyGeneric(InHandling inHandling,
|
|||
if (!body)
|
||||
return false;
|
||||
|
||||
if (kind != Method && fun->name() && !checkStrictBinding(fun->name(), pn))
|
||||
if ((kind != Method && kind != ClassConstructor) && fun->name() &&
|
||||
!checkStrictBinding(fun->name(), pn))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bodyType == StatementListBody) {
|
||||
bool matched;
|
||||
|
@ -2648,7 +2666,7 @@ Parser<ParseHandler>::functionStmt(YieldHandling yieldHandling)
|
|||
!report(ParseStrictError, pc->sc->strict(), null(), JSMSG_STRICT_FUNCTION_STATEMENT))
|
||||
return null();
|
||||
|
||||
return functionDef(InAllowed, yieldHandling, name, Normal, Statement, generatorKind);
|
||||
return functionDef(InAllowed, yieldHandling, name, Statement, generatorKind);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
|
@ -2680,7 +2698,7 @@ Parser<ParseHandler>::functionExpr(InvokedPrediction invoked)
|
|||
}
|
||||
|
||||
YieldHandling yieldHandling = generatorKind != NotGenerator ? YieldIsKeyword : YieldIsName;
|
||||
return functionDef(InAllowed, yieldHandling, name, Normal, Expression, generatorKind, invoked);
|
||||
return functionDef(InAllowed, yieldHandling, name, Expression, generatorKind, invoked);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -6575,7 +6593,7 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
|
|||
if (!tokenStream.peekToken(&ignored))
|
||||
return null();
|
||||
|
||||
return functionDef(inHandling, yieldHandling, NullPtr(), Normal, Arrow, NotGenerator);
|
||||
return functionDef(inHandling, yieldHandling, NullPtr(), Arrow, NotGenerator);
|
||||
}
|
||||
|
||||
default:
|
||||
|
@ -7806,7 +7824,7 @@ Parser<ParseHandler>::checkAndMarkSuperScope()
|
|||
sc->asFunctionBox()->setNeedsHomeObject();
|
||||
return true;
|
||||
} else if (sc->isFunctionBox() && !sc->asFunctionBox()->function()->isArrow()) {
|
||||
// super is not legal is normal functions.
|
||||
// super is not legal in normal functions.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -8297,6 +8315,7 @@ Parser<ParseHandler>::propertyList(YieldHandling yieldHandling, PropListType typ
|
|||
|
||||
JSOp op = JSOP_INITPROP;
|
||||
Node propname;
|
||||
bool isConstructor = false;
|
||||
switch (ltok) {
|
||||
case TOK_NUMBER:
|
||||
atom = DoubleToAtom(context, tokenStream.currentToken().number());
|
||||
|
@ -8423,6 +8442,7 @@ Parser<ParseHandler>::propertyList(YieldHandling yieldHandling, PropListType typ
|
|||
return null();
|
||||
}
|
||||
seenConstructor = true;
|
||||
isConstructor = true;
|
||||
} else if (isStatic && atom == context->names().prototype) {
|
||||
report(ParseError, false, propname, JSMSG_BAD_METHOD_DEF);
|
||||
return null();
|
||||
|
@ -8498,7 +8518,8 @@ Parser<ParseHandler>::propertyList(YieldHandling yieldHandling, PropListType typ
|
|||
return null();
|
||||
} else if (tt == TOK_LP) {
|
||||
tokenStream.ungetToken();
|
||||
if (!methodDefinition(yieldHandling, type, propList, propname, Normal,
|
||||
if (!methodDefinition(yieldHandling, type, propList, propname,
|
||||
isConstructor ? ClassConstructor : Method,
|
||||
isGenerator ? StarGenerator : NotGenerator, isStatic, op))
|
||||
{
|
||||
return null();
|
||||
|
@ -8542,17 +8563,18 @@ Parser<ParseHandler>::propertyList(YieldHandling yieldHandling, PropListType typ
|
|||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::methodDefinition(YieldHandling yieldHandling, PropListType listType,
|
||||
Node propList, Node propname, FunctionType type,
|
||||
Node propList, Node propname, FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind, bool isStatic, JSOp op)
|
||||
{
|
||||
MOZ_ASSERT(kind == Method || kind == ClassConstructor || kind == Getter || kind == Setter);
|
||||
/* NB: Getter function in { get x(){} } is unnamed. */
|
||||
RootedPropertyName funName(context);
|
||||
if (type == Normal && tokenStream.isCurrentTokenType(TOK_NAME))
|
||||
if ((kind == Method || kind == ClassConstructor) && tokenStream.isCurrentTokenType(TOK_NAME))
|
||||
funName = tokenStream.currentName();
|
||||
else
|
||||
funName = nullptr;
|
||||
|
||||
Node fn = functionDef(InAllowed, yieldHandling, funName, type, Method, generatorKind);
|
||||
Node fn = functionDef(InAllowed, yieldHandling, funName, kind, generatorKind);
|
||||
if (!fn)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -328,7 +328,6 @@ class CompExprTransplanter;
|
|||
|
||||
enum LetContext { LetExpression, LetStatement };
|
||||
enum VarContext { HoistVars, DontHoistVars };
|
||||
enum FunctionType { Getter, Setter, Normal };
|
||||
enum PropListType { ObjectLiteral, ClassBody };
|
||||
|
||||
// Specify a value for an ES6 grammar parametrization. We have no enum for
|
||||
|
@ -504,8 +503,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
|||
FunctionBodyType type);
|
||||
|
||||
bool functionArgsAndBodyGeneric(InHandling inHandling, YieldHandling yieldHandling, Node pn,
|
||||
HandleFunction fun, FunctionType type,
|
||||
FunctionSyntaxKind kind);
|
||||
HandleFunction fun, FunctionSyntaxKind kind);
|
||||
|
||||
// Determine whether |yield| is a valid name in the current context, or
|
||||
// whether it's prohibited due to strictness, JS version, or occurrence
|
||||
|
@ -594,19 +592,19 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
|||
bool checkAndMarkSuperScope();
|
||||
|
||||
bool methodDefinition(YieldHandling yieldHandling, PropListType listType, Node propList,
|
||||
Node propname, FunctionType type, GeneratorKind generatorKind,
|
||||
Node propname, FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
bool isStatic, JSOp Op);
|
||||
|
||||
/*
|
||||
* Additional JS parsers.
|
||||
*/
|
||||
bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind, FunctionType type,
|
||||
Node* list, Node funcpn, bool* hasRest);
|
||||
bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind, Node* list,
|
||||
Node funcpn, bool* hasRest);
|
||||
|
||||
Node functionDef(InHandling inHandling, YieldHandling uieldHandling, HandlePropertyName name,
|
||||
FunctionType type, FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
bool functionArgsAndBody(InHandling inHandling, Node pn, HandleFunction fun, FunctionType type,
|
||||
bool functionArgsAndBody(InHandling inHandling, Node pn, HandleFunction fun,
|
||||
FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
Directives inheritedDirectives, Directives* newDirectives);
|
||||
|
||||
|
|
|
@ -306,7 +306,7 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
void setArgumentsHasLocalBinding() { funCxFlags.argumentsHasLocalBinding = true; }
|
||||
void setDefinitelyNeedsArgsObj() { MOZ_ASSERT(funCxFlags.argumentsHasLocalBinding);
|
||||
funCxFlags.definitelyNeedsArgsObj = true; }
|
||||
void setNeedsHomeObject() { MOZ_ASSERT(function()->isMethod());
|
||||
void setNeedsHomeObject() { MOZ_ASSERT(allowSuperProperty());
|
||||
funCxFlags.needsHomeObject = true; }
|
||||
|
||||
bool hasDefaults() const {
|
||||
|
@ -339,7 +339,7 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
}
|
||||
|
||||
bool allowSuperProperty() const {
|
||||
return function()->isMethod();
|
||||
return function()->isMethod() || function()->isGetter() || function()->isSetter();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -981,7 +981,8 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool bodyOnly, bool lamb
|
|||
}
|
||||
}
|
||||
|
||||
bool funIsMethodOrNonArrowLambda = (fun->isLambda() && !fun->isArrow()) || fun->isMethod();
|
||||
bool funIsMethodOrNonArrowLambda = (fun->isLambda() && !fun->isArrow()) || fun->isMethod() ||
|
||||
fun->isGetter() || fun->isSetter();
|
||||
if (!bodyOnly) {
|
||||
// If we're not in pretty mode, put parentheses around lambda functions and methods.
|
||||
if (fun->isInterpreted() && !lambdaParen && funIsMethodOrNonArrowLambda) {
|
||||
|
|
|
@ -32,7 +32,10 @@ class JSFunction : public js::NativeObject
|
|||
NormalFunction = 0,
|
||||
Arrow, /* ES6 '(args) => body' syntax */
|
||||
Method, /* ES6 MethodDefinition */
|
||||
AsmJS /* function is an asm.js module or exported function */
|
||||
Getter,
|
||||
Setter,
|
||||
AsmJS, /* function is an asm.js module or exported function */
|
||||
FunctionKindLimit
|
||||
};
|
||||
|
||||
enum Flags {
|
||||
|
@ -57,16 +60,22 @@ class JSFunction : public js::NativeObject
|
|||
RESOLVED_NAME = 0x1000, /* f.name has been resolved (see fun_resolve). */
|
||||
|
||||
FUNCTION_KIND_SHIFT = 13,
|
||||
FUNCTION_KIND_MASK = 0x3 << FUNCTION_KIND_SHIFT,
|
||||
FUNCTION_KIND_MASK = 0x7 << FUNCTION_KIND_SHIFT,
|
||||
|
||||
ASMJS_KIND = AsmJS << FUNCTION_KIND_SHIFT,
|
||||
ARROW_KIND = Arrow << FUNCTION_KIND_SHIFT,
|
||||
METHOD_KIND = Method << FUNCTION_KIND_SHIFT,
|
||||
GETTER_KIND = Getter << FUNCTION_KIND_SHIFT,
|
||||
SETTER_KIND = Setter << FUNCTION_KIND_SHIFT,
|
||||
|
||||
/* Derived Flags values for convenience: */
|
||||
NATIVE_FUN = 0,
|
||||
ASMJS_CTOR = ASMJS_KIND | NATIVE_CTOR,
|
||||
ASMJS_LAMBDA_CTOR = ASMJS_KIND | NATIVE_CTOR | LAMBDA,
|
||||
INTERPRETED_METHOD = INTERPRETED | (Method << FUNCTION_KIND_SHIFT),
|
||||
INTERPRETED_METHOD = INTERPRETED | METHOD_KIND,
|
||||
INTERPRETED_CLASS_CONSTRUCTOR = INTERPRETED | METHOD_KIND,
|
||||
INTERPRETED_GETTER = INTERPRETED | GETTER_KIND,
|
||||
INTERPRETED_SETTER = INTERPRETED | SETTER_KIND,
|
||||
INTERPRETED_LAMBDA = INTERPRETED | LAMBDA,
|
||||
INTERPRETED_LAMBDA_ARROW = INTERPRETED | LAMBDA | ARROW_KIND,
|
||||
STABLE_ACROSS_CLONES = NATIVE_CTOR | IS_FUN_PROTO | EXPR_BODY | HAS_GUESSED_ATOM |
|
||||
|
@ -76,6 +85,8 @@ class JSFunction : public js::NativeObject
|
|||
|
||||
static_assert((INTERPRETED | INTERPRETED_LAZY) == js::JS_FUNCTION_INTERPRETED_BITS,
|
||||
"jsfriendapi.h's JSFunction::INTERPRETED-alike is wrong");
|
||||
static_assert(((FunctionKindLimit - 1) << FUNCTION_KIND_SHIFT) <= FUNCTION_KIND_MASK,
|
||||
"FunctionKind doesn't fit into flags_");
|
||||
|
||||
private:
|
||||
uint16_t nargs_; /* number of formal arguments
|
||||
|
@ -152,8 +163,16 @@ class JSFunction : public js::NativeObject
|
|||
|
||||
// Arrow functions store their lexical |this| in the first extended slot.
|
||||
bool isArrow() const { return kind() == Arrow; }
|
||||
// Every class-constructor is also a method.
|
||||
bool isMethod() const { return kind() == Method; }
|
||||
|
||||
bool isGetter() const { return kind() == Getter; }
|
||||
bool isSetter() const { return kind() == Setter; }
|
||||
|
||||
bool isClassConstructor() const {
|
||||
return kind() == Method && isInterpretedConstructor();
|
||||
}
|
||||
|
||||
bool hasResolvedLength() const { return flags() & RESOLVED_LENGTH; }
|
||||
bool hasResolvedName() const { return flags() & RESOLVED_NAME; }
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче