Bug 1454728 - [BinAST] Create recursive bindings for function expressions. (r=Yoric, r=arai)

--HG--
extra : rebase_source : 0ddd2aa262bc18cf69e231182b4767d0756695e3
extra : histedit_source : 7a6d8a49a87f82895d20db61fb3fc9f1d6caae02
This commit is contained in:
Eric Faust 2018-04-30 22:23:03 -07:00
Родитель 225b0afd64
Коммит 7b46edd90a
266 изменённых файлов: 78 добавлений и 68 удалений

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

@ -4536,9 +4536,9 @@ BinASTParser<Tok>::parseInterfaceEagerArrowExpression(const size_t start, const
interface EagerFunctionDeclaration : Node {
bool isAsync;
bool isGenerator;
BindingIdentifier name;
AssertedParameterScope? parameterScope;
AssertedVarScope? bodyScope;
BindingIdentifier name;
FormalParameters params;
FunctionBody body;
}
@ -4567,7 +4567,7 @@ BinASTParser<Tok>::parseInterfaceEagerFunctionDeclaration(const size_t start, co
#if defined(DEBUG)
const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body };
const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::Name, BinField::ParameterScope, BinField::BodyScope, BinField::Params, BinField::Body };
MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
#endif // defined(DEBUG)
@ -4582,12 +4582,17 @@ BinASTParser<Tok>::parseInterfaceEagerFunctionDeclaration(const size_t start, co
BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool());
BINJS_MOZ_TRY_DECL(name, parseBindingIdentifier());
BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
isGenerator ? GeneratorKind::Generator
: GeneratorKind::NotGenerator,
isAsync ? FunctionAsyncKind::AsyncFunction
: FunctionAsyncKind::SyncFunction,
syntax));
syntax, name));
// Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);
@ -4608,11 +4613,6 @@ BinASTParser<Tok>::parseInterfaceEagerFunctionDeclaration(const size_t start, co
BINJS_MOZ_TRY_DECL(name, parseBindingIdentifier());
BINJS_MOZ_TRY_DECL(params, parseFormalParameters());
@ -4632,9 +4632,9 @@ BinASTParser<Tok>::parseInterfaceEagerFunctionDeclaration(const size_t start, co
interface EagerFunctionExpression : Node {
bool isAsync;
bool isGenerator;
BindingIdentifier? name;
AssertedParameterScope? parameterScope;
AssertedVarScope? bodyScope;
BindingIdentifier? name;
FormalParameters params;
FunctionBody body;
}
@ -4663,7 +4663,7 @@ BinASTParser<Tok>::parseInterfaceEagerFunctionExpression(const size_t start, con
#if defined(DEBUG)
const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body };
const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::Name, BinField::ParameterScope, BinField::BodyScope, BinField::Params, BinField::Body };
MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
#endif // defined(DEBUG)
@ -4678,12 +4678,17 @@ BinASTParser<Tok>::parseInterfaceEagerFunctionExpression(const size_t start, con
BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool());
BINJS_MOZ_TRY_DECL(name, parseOptionalBindingIdentifier());
BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
isGenerator ? GeneratorKind::Generator
: GeneratorKind::NotGenerator,
isAsync ? FunctionAsyncKind::AsyncFunction
: FunctionAsyncKind::SyncFunction,
syntax));
syntax, name));
// Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);
@ -4704,11 +4709,6 @@ BinASTParser<Tok>::parseInterfaceEagerFunctionExpression(const size_t start, con
BINJS_MOZ_TRY_DECL(name, parseOptionalBindingIdentifier());
BINJS_MOZ_TRY_DECL(params, parseFormalParameters());
@ -4773,7 +4773,7 @@ BinASTParser<Tok>::parseInterfaceEagerGetter(const size_t start, const BinKind k
BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
GeneratorKind::NotGenerator,
FunctionAsyncKind::SyncFunction,
FunctionSyntaxKind::Getter));
FunctionSyntaxKind::Getter, name));
// Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);
@ -4798,9 +4798,9 @@ BinASTParser<Tok>::parseInterfaceEagerGetter(const size_t start, const BinKind k
interface EagerMethod : Node {
bool isAsync;
bool isGenerator;
PropertyName name;
AssertedParameterScope? parameterScope;
AssertedVarScope? bodyScope;
PropertyName name;
FormalParameters params;
FunctionBody body;
}
@ -4829,7 +4829,7 @@ BinASTParser<Tok>::parseInterfaceEagerMethod(const size_t start, const BinKind k
#if defined(DEBUG)
const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body };
const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::Name, BinField::ParameterScope, BinField::BodyScope, BinField::Params, BinField::Body };
MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
#endif // defined(DEBUG)
@ -4844,12 +4844,17 @@ BinASTParser<Tok>::parseInterfaceEagerMethod(const size_t start, const BinKind k
BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool());
BINJS_MOZ_TRY_DECL(name, parsePropertyName());
BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
isGenerator ? GeneratorKind::Generator
: GeneratorKind::NotGenerator,
isAsync ? FunctionAsyncKind::AsyncFunction
: FunctionAsyncKind::SyncFunction,
syntax));
syntax, name));
// Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);
@ -4870,11 +4875,6 @@ BinASTParser<Tok>::parseInterfaceEagerMethod(const size_t start, const BinKind k
BINJS_MOZ_TRY_DECL(name, parsePropertyName());
BINJS_MOZ_TRY_DECL(params, parseFormalParameters());
@ -4891,9 +4891,9 @@ BinASTParser<Tok>::parseInterfaceEagerMethod(const size_t start, const BinKind k
/*
interface EagerSetter : Node {
PropertyName name;
AssertedParameterScope? parameterScope;
AssertedVarScope? bodyScope;
PropertyName name;
Parameter param;
FunctionBody body;
}
@ -4922,13 +4922,18 @@ BinASTParser<Tok>::parseInterfaceEagerSetter(const size_t start, const BinKind k
#if defined(DEBUG)
const BinField expected_fields[5] = { BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Param, BinField::Body };
const BinField expected_fields[5] = { BinField::Name, BinField::ParameterScope, BinField::BodyScope, BinField::Param, BinField::Body };
MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
#endif // defined(DEBUG)
BINJS_MOZ_TRY_DECL(name, parsePropertyName());
MOZ_TRY(parseOptionalAssertedParameterScope());
@ -4939,18 +4944,13 @@ BinASTParser<Tok>::parseInterfaceEagerSetter(const size_t start, const BinKind k
BINJS_MOZ_TRY_DECL(name, parsePropertyName());
BINJS_MOZ_TRY_DECL(param, parseParameter());
BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
GeneratorKind::NotGenerator,
FunctionAsyncKind::SyncFunction,
FunctionSyntaxKind::Setter));
FunctionSyntaxKind::Setter, name));
// Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);

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

@ -122,23 +122,20 @@ BinASTParser<Tok>::parseAux(const uint8_t* start, const size_t length)
return result; // Magic conversion to Ok.
}
template<typename Tok> JS::Result<FunctionBox*>
BinASTParser<Tok>::buildFunctionBox(GeneratorKind generatorKind,
FunctionAsyncKind functionAsyncKind,
FunctionSyntaxKind syntax)
FunctionSyntaxKind syntax,
ParseNode* name)
{
RootedAtom atom(cx_);
if (name)
atom = name->name();
// Allocate the function before walking down the tree.
RootedFunction fun(cx_);
BINJS_TRY_VAR(fun, NewFunctionWithProto(cx_,
/* native = */ nullptr,
/* nargs placeholder = */ 0,
JSFunction::INTERPRETED_NORMAL,
/* enclosingEnv = */ nullptr,
/* name (placeholder) = */ nullptr,
/* proto = */ nullptr,
gc::AllocKind::FUNCTION,
TenuredObject
));
BINJS_TRY_VAR(fun, AllocNewFunction(cx_, atom, syntax, generatorKind, functionAsyncKind, nullptr));
BINJS_TRY_DECL(funbox, alloc_.new_<FunctionBox>(cx_,
traceListHead_,
fun,
@ -155,17 +152,11 @@ BinASTParser<Tok>::buildFunctionBox(GeneratorKind generatorKind,
template<typename Tok> JS::Result<ParseNode*>
BinASTParser<Tok>::buildFunction(const size_t start, const BinKind kind, ParseNode* name,
ParseNode* params, ParseNode* body, FunctionBox* funbox)
ParseNode* params, ParseNode* body, FunctionBox* funbox)
{
TokenPos pos = tokenizer_->pos(start);
RootedAtom atom((cx_));
if (name)
atom = name->pn_atom;
funbox->function()->setArgCount(params ? uint16_t(params->pn_count) : 0);
funbox->function()->initAtom(atom);
// ParseNode represents the body as concatenated after the params.
params->appendWithoutOrderAssumption(body);
@ -197,6 +188,13 @@ BinASTParser<Tok>::buildFunction(const size_t start, const BinKind kind, ParseNo
funbox->functionScopeBindings().set(*bindings);
if (funbox->function()->isNamedLambda()) {
BINJS_TRY_DECL(recursiveBinding,
NewLexicalScopeData(cx_, parseContext_->namedLambdaScope(), alloc_, parseContext_));
funbox->namedLambdaBindings().set(*recursiveBinding);
}
return result;
}

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

@ -183,8 +183,7 @@ class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEPa
buildFunction(const size_t start, const BinKind kind, ParseNode* name, ParseNode* params,
ParseNode* body, FunctionBox* funbox);
JS::Result<FunctionBox*>
buildFunctionBox(GeneratorKind generatorKind, FunctionAsyncKind functionAsyncKind,
FunctionSyntaxKind syntax);
buildFunctionBox(GeneratorKind generatorKind, FunctionAsyncKind functionAsyncKind, FunctionSyntaxKind syntax, ParseNode* name);
// Parse full scope information to a specific var scope / let scope combination.
MOZ_MUST_USE JS::Result<Ok> parseAndUpdateScope(ParseContext::Scope& varScope,

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

@ -428,9 +428,9 @@ interface EagerMethod : Node {
attribute boolean isAsync;
// True for `GeneratorMethod`, false otherwise.
attribute boolean isGenerator;
attribute PropertyName name;
attribute AssertedParameterScope? parameterScope;
attribute AssertedVarScope? bodyScope;
attribute PropertyName name;
// The `UniqueFormalParameters`.
attribute FormalParameters params;
attribute FunctionBody body;
@ -453,9 +453,9 @@ interface EagerGetter : Node {
// `set PropertyName ( PropertySetParameterList ) { FunctionBody }`
interface EagerSetter : Node {
attribute PropertyName name;
attribute AssertedParameterScope? parameterScope;
attribute AssertedVarScope? bodyScope;
attribute PropertyName name;
// The `PropertySetParameterList`.
attribute Parameter param;
attribute FunctionBody body;
@ -605,9 +605,9 @@ interface ConditionalExpression : Node {
interface EagerFunctionExpression : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute BindingIdentifier? name;
attribute AssertedParameterScope? parameterScope;
attribute AssertedVarScope? bodyScope;
attribute BindingIdentifier? name;
attribute FormalParameters params;
attribute FunctionBody body;
};
@ -857,9 +857,9 @@ interface FunctionBody : Node {
interface EagerFunctionDeclaration : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute BindingIdentifier name;
attribute AssertedParameterScope? parameterScope;
attribute AssertedVarScope? bodyScope;
attribute BindingIdentifier name;
attribute FormalParameters params;
attribute FunctionBody body;
};
@ -905,4 +905,4 @@ interface VariableDeclaration : Node {
interface VariableDeclarator : Node {
attribute Binding binding;
attribute Expression? init;
};
};

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

@ -542,7 +542,7 @@ EagerFunctionExpression:
: GeneratorKind::NotGenerator,
isAsync ? FunctionAsyncKind::AsyncFunction
: FunctionAsyncKind::SyncFunction,
syntax));
syntax, name));
// Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);
@ -564,7 +564,7 @@ EagerGetter:
BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
GeneratorKind::NotGenerator,
FunctionAsyncKind::SyncFunction,
FunctionSyntaxKind::Getter));
FunctionSyntaxKind::Getter, name));
// Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);
@ -594,7 +594,7 @@ EagerSetter:
BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
GeneratorKind::NotGenerator,
FunctionAsyncKind::SyncFunction,
FunctionSyntaxKind::Setter));
FunctionSyntaxKind::Setter, name));
// Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);

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

@ -2828,13 +2828,13 @@ GeneralParser<ParseHandler, CharT>::functionBody(InHandling inHandling,
}
JSFunction*
ParserBase::newFunction(HandleAtom atom, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
HandleObject proto)
AllocNewFunction(JSContext* cx, HandleAtom atom, FunctionSyntaxKind kind, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, HandleObject proto,
bool isSelfHosting /* = false */, bool inFunctionBox /* = false */)
{
MOZ_ASSERT_IF(kind == FunctionSyntaxKind::Statement, atom != nullptr);
RootedFunction fun(context);
RootedFunction fun(cx);
gc::AllocKind allocKind = gc::AllocKind::FUNCTION;
JSFunction::Flags flags;
@ -2875,7 +2875,7 @@ ParserBase::newFunction(HandleAtom atom, FunctionSyntaxKind kind,
default:
MOZ_ASSERT(kind == FunctionSyntaxKind::Statement);
#ifdef DEBUG
if (options().selfHostingMode && !pc->isFunctionBox()) {
if (isSelfHosting && !inFunctionBox) {
isGlobalSelfHostedBuiltin = true;
allocKind = gc::AllocKind::FUNCTION_EXTENDED;
}
@ -2890,11 +2890,11 @@ ParserBase::newFunction(HandleAtom atom, FunctionSyntaxKind kind,
if (asyncKind == FunctionAsyncKind::AsyncFunction)
allocKind = gc::AllocKind::FUNCTION_EXTENDED;
fun = NewFunctionWithProto(context, nullptr, 0, flags, nullptr, atom, proto,
fun = NewFunctionWithProto(cx, nullptr, 0, flags, nullptr, atom, proto,
allocKind, TenuredObject);
if (!fun)
return nullptr;
if (options().selfHostingMode) {
if (isSelfHosting) {
fun->setIsSelfHostedBuiltin();
#ifdef DEBUG
if (isGlobalSelfHostedBuiltin)
@ -2904,6 +2904,15 @@ ParserBase::newFunction(HandleAtom atom, FunctionSyntaxKind kind,
return fun;
}
JSFunction*
ParserBase::newFunction(HandleAtom atom, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
HandleObject proto)
{
return AllocNewFunction(context, atom, kind, generatorKind, asyncKind, proto,
options().selfHostingMode, pc->isFunctionBox());
}
template <class ParseHandler, typename CharT>
bool
GeneralParser<ParseHandler, CharT>::matchOrInsertSemicolon()

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

@ -1599,6 +1599,10 @@ NewVarScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc
mozilla::Maybe<LexicalScope::Data*>
NewLexicalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc);
JSFunction*
AllocNewFunction(JSContext* cx, HandleAtom atom, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
HandleObject proto, bool isSelfHosting = false, bool inFunctionBox = false);
} /* namespace frontend */
} /* namespace js */

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше