[VM] Delete access to Dart 1 parser.

- delete access to Dart 1 parser
- Skip codegen unit tests as they use the Dart 1 parser

Change-Id: I24f3986fac9c496e231c723c6eaa0704e6a616f5
Reviewed-on: https://dart-review.googlesource.com/77009
Commit-Queue: Siva Annamalai <asiva@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
asiva 2018-09-27 23:08:20 +00:00 committed by commit-bot@chromium.org
parent cfe9202393
commit c9f5c3a79e
7 changed files with 67 additions and 15402 deletions

View file

@ -149,11 +149,8 @@ static RawInstance* CreateParameterMirrorList(const Function& func,
// * Whether a parameters has been declared as final.
// * Any metadata associated with the parameter.
Object& result = Object::Handle();
if (func.kernel_offset() > 0) {
result = kernel::BuildParameterDescriptor(func);
} else {
result = Parser::ParseFunctionParameters(func);
}
ASSERT(func.kernel_offset() > 0);
result = kernel::BuildParameterDescriptor(func);
if (result.IsError()) {
Exceptions::PropagateError(Error::Cast(result));
UNREACHABLE();

View file

@ -349,6 +349,36 @@ cc/SourcePosition_Switch: SkipByDesign
cc/SourcePosition_TryCatchFinally: SkipByDesign
cc/SourcePosition_While: SkipByDesign
cc/SourcePosition_WhileContinueBreak: SkipByDesign
cc/CompileFunctionOnHelperThread: SkipByDesign
cc/CompileFunction: SkipByDesign
cc/InvokeDynamic_CompileError: SkipByDesign
cc/InvokeStatic_CompileError: SkipByDesign
cc/DartEntry: SkipByDesign
cc/FindCodeObject: SkipByDesign
cc/Parser_TopLevel: SkipByDesign
cc/DartDynamicResolve: SkipByDesign
cc/DartStaticResolve: SkipByDesign
cc/AllocateNewObjectCodegen: SkipByDesign
cc/InstanceCallCodegen: SkipByDesign
cc/StaticCallCodegen: SkipByDesign
cc/SimpleReturnCodegen: SkipByDesign
cc/SmiReturnCodegen: SkipByDesign
cc/SimpleStaticCallCodegen: SkipByDesign
cc/StaticCallReturnParameterCodegen: SkipByDesign
cc/StaticCallReturnParameterCodegen: SkipByDesign
cc/StaticCallSmiParamSumCodegen: SkipByDesign
cc/SmiAddCodegen: SkipByDesign
cc/GenericAddCodegen: SkipByDesign
cc/SmiBinaryOpCodegen: SkipByDesign
cc/BoolNotCodegen: SkipByDesign
cc/BoolAndCodegen: SkipByDesign
cc/BinaryOpCodegen: SkipByDesign
cc/SmiUnaryOpCodegen: SkipByDesign
cc/DoubleUnaryOpCodegen: SkipByDesign
cc/ParseClassDefinition: SkipByDesign
cc/CompileScript: SkipByDesign
cc/DartAPI_LoadLibraryPatch_1: SkipByDesign
cc/StackMapCodegen: SkipByDesign
[ $compiler == precompiler || $mode == product ]
cc/CoreSnapshotSize: SkipByDesign # Imports dart:mirrors

View file

@ -958,43 +958,29 @@ class CallSiteInliner : public ValueObject {
InlineExitCollector* exit_collector =
new (Z) InlineExitCollector(caller_graph_, call);
FlowGraph* callee_graph;
if (UseKernelFrontEndFor(parsed_function)) {
Code::EntryKind entry_kind = Code::EntryKind::kNormal;
if (StaticCallInstr* instr = call_data->call->AsStaticCall()) {
entry_kind = instr->entry_kind();
} else if (InstanceCallInstr* instr =
call_data->call->AsInstanceCall()) {
entry_kind = instr->entry_kind();
} else if (PolymorphicInstanceCallInstr* instr =
call_data->call->AsPolymorphicInstanceCall()) {
entry_kind = instr->instance_call()->entry_kind();
} else if (ClosureCallInstr* instr =
call_data->call->AsClosureCall()) {
entry_kind = instr->entry_kind();
}
kernel::FlowGraphBuilder builder(
parsed_function, ic_data_array, /* not building var desc */ NULL,
exit_collector,
/* optimized = */ true, Compiler::kNoOSRDeoptId,
caller_graph_->max_block_id() + 1,
entry_kind == Code::EntryKind::kUnchecked);
{
CSTAT_TIMER_SCOPE(thread(), graphinliner_build_timer);
callee_graph = builder.BuildGraph();
Code::EntryKind entry_kind = Code::EntryKind::kNormal;
if (StaticCallInstr* instr = call_data->call->AsStaticCall()) {
entry_kind = instr->entry_kind();
} else if (InstanceCallInstr* instr =
call_data->call->AsInstanceCall()) {
entry_kind = instr->entry_kind();
} else if (PolymorphicInstanceCallInstr* instr =
call_data->call->AsPolymorphicInstanceCall()) {
entry_kind = instr->instance_call()->entry_kind();
} else if (ClosureCallInstr* instr = call_data->call->AsClosureCall()) {
entry_kind = instr->entry_kind();
}
kernel::FlowGraphBuilder builder(
parsed_function, ic_data_array, /* not building var desc */ NULL,
exit_collector,
/* optimized = */ true, Compiler::kNoOSRDeoptId,
caller_graph_->max_block_id() + 1,
entry_kind == Code::EntryKind::kUnchecked);
{
CSTAT_TIMER_SCOPE(thread(), graphinliner_build_timer);
callee_graph = builder.BuildGraph();
CalleeGraphValidator::Validate(callee_graph);
}
} else {
FlowGraphBuilder builder(*parsed_function, *ic_data_array,
/* not building var desc */ NULL,
exit_collector, Compiler::kNoOSRDeoptId);
builder.SetInitialBlockId(caller_graph_->max_block_id());
{
CSTAT_TIMER_SCOPE(thread(), graphinliner_build_timer);
callee_graph = builder.BuildGraph();
CalleeGraphValidator::Validate(callee_graph);
}
CalleeGraphValidator::Validate(callee_graph);
}
#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) && \
!defined(TARGET_ARCH_IA32)
@ -1368,10 +1354,6 @@ class CallSiteInliner : public ValueObject {
*in_cache = false;
ParsedFunction* parsed_function =
new (Z) ParsedFunction(thread(), function);
if (!UseKernelFrontEndFor(parsed_function)) {
Parser::ParseFunction(parsed_function);
parsed_function->AllocateVariables();
}
return parsed_function;
}

View file

@ -138,18 +138,8 @@ DEFINE_FLAG_HANDLER(PrecompilationModeHandler,
#ifndef DART_PRECOMPILED_RUNTIME
bool UseKernelFrontEndFor(ParsedFunction* parsed_function) {
const Function& function = parsed_function->function();
return (function.kernel_offset() > 0) || function.HasBytecode() ||
(function.kind() == RawFunction::kNoSuchMethodDispatcher) ||
(function.kind() == RawFunction::kInvokeFieldDispatcher);
}
void DartCompilationPipeline::ParseFunction(ParsedFunction* parsed_function) {
if (!UseKernelFrontEndFor(parsed_function)) {
Parser::ParseFunction(parsed_function);
parsed_function->AllocateVariables();
}
// Nothing to do here.
}
FlowGraph* DartCompilationPipeline::BuildFlowGraph(
@ -158,20 +148,12 @@ FlowGraph* DartCompilationPipeline::BuildFlowGraph(
ZoneGrowableArray<const ICData*>* ic_data_array,
intptr_t osr_id,
bool optimized) {
if (UseKernelFrontEndFor(parsed_function)) {
kernel::FlowGraphBuilder builder(parsed_function, ic_data_array,
/* not building var desc */ NULL,
/* not inlining */ NULL, optimized,
osr_id);
FlowGraph* graph = builder.BuildGraph();
ASSERT(graph != NULL);
return graph;
}
FlowGraphBuilder builder(*parsed_function, *ic_data_array,
/* not building var desc */ NULL,
/* not inlining */ NULL, osr_id);
return builder.BuildGraph();
kernel::FlowGraphBuilder builder(parsed_function, ic_data_array,
/* not building var desc */ NULL,
/* not inlining */ NULL, optimized, osr_id);
FlowGraph* graph = builder.BuildGraph();
ASSERT(graph != NULL);
return graph;
}
void DartCompilationPipeline::FinalizeCompilation(FlowGraph* flow_graph) {}
@ -348,27 +330,6 @@ bool Compiler::IsBackgroundCompilation() {
}
RawError* Compiler::Compile(const Library& library, const Script& script) {
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
Thread* const thread = Thread::Current();
StackZone zone(thread);
if (FLAG_trace_compiler) {
const String& script_url = String::Handle(script.url());
// TODO(iposva): Extract script kind.
THR_Print("Compiling %s '%s'\n", "", script_url.ToCString());
}
const String& library_key = String::Handle(library.private_key());
script.Tokenize(library_key);
Parser::ParseCompilationUnit(library, script);
return Error::null();
} else {
Thread* const thread = Thread::Current();
StackZone zone(thread);
Error& error = Error::Handle();
error = thread->sticky_error();
thread->clear_sticky_error();
return error.raw();
}
UNREACHABLE();
return Error::null();
}
@ -491,23 +452,6 @@ RawError* Compiler::CompileClass(const Class& cls) {
AddRelatedClassesToList(parse_list.At(i), &parse_list, &patch_list);
}
// Classes loaded from a kernel should not be parsed.
if (cls.kernel_offset() <= 0) {
// Parse all the classes that have been added above.
for (intptr_t i = (parse_list.length() - 1); i >= 0; i--) {
const Class& parse_class = parse_list.At(i);
ASSERT(!parse_class.IsNull());
Parser::ParseClass(parse_class);
}
// Parse all the patch classes that have been added above.
for (intptr_t i = 0; i < patch_list.length(); i++) {
const Class& parse_class = patch_list.At(i);
ASSERT(!parse_class.IsNull());
Parser::ParseClass(parse_class);
}
}
// Finalize these classes.
for (intptr_t i = (parse_list.length() - 1); i >= 0; i--) {
const Class& parse_class = parse_list.At(i);
@ -543,8 +487,6 @@ RawError* Compiler::CompileClass(const Class& cls) {
thread->clear_sticky_error();
return error.raw();
}
UNREACHABLE();
return Error::null();
}
class CompileParsedFunctionHelper : public ValueObject {
@ -1366,20 +1308,11 @@ void Compiler::ComputeLocalVarDescriptors(const Code& code) {
ZoneGrowableArray<intptr_t>* context_level_array =
new ZoneGrowableArray<intptr_t>();
if (!UseKernelFrontEndFor(parsed_function)) {
Parser::ParseFunction(parsed_function);
parsed_function->AllocateVariables();
FlowGraphBuilder builder(
*parsed_function, *ic_data_array, context_level_array,
/* not inlining */ NULL, Compiler::kNoOSRDeoptId);
builder.BuildGraph();
} else {
parsed_function->EnsureKernelScopes();
kernel::FlowGraphBuilder builder(
parsed_function, ic_data_array, context_level_array,
/* not inlining */ NULL, false, Compiler::kNoOSRDeoptId);
builder.BuildGraph();
}
parsed_function->EnsureKernelScopes();
kernel::FlowGraphBuilder builder(
parsed_function, ic_data_array, context_level_array,
/* not inlining */ NULL, false, Compiler::kNoOSRDeoptId);
builder.BuildGraph();
const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle(
parsed_function->node_sequence()->scope()->GetVarDescriptors(
@ -1522,12 +1455,7 @@ RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
// Create a one-time-use function to evaluate the initializer and invoke
// it immediately.
if (field.kernel_offset() > 0) {
parsed_function = kernel::ParseStaticFieldInitializer(zone, field);
} else {
parsed_function = Parser::ParseStaticFieldInitializer(field);
parsed_function->AllocateVariables();
}
parsed_function = kernel::ParseStaticFieldInitializer(zone, field);
const Function& initializer = parsed_function->function();
if (FLAG_enable_interpreter) {
@ -1959,11 +1887,6 @@ bool BackgroundCompiler::IsDisabled() {
#else // DART_PRECOMPILED_RUNTIME
bool UseKernelFrontEndFor(ParsedFunction* parsed_function) {
UNREACHABLE();
return false;
}
CompilationPipeline* CompilationPipeline::New(Zone* zone,
const Function& function) {
UNREACHABLE();

View file

@ -28,8 +28,6 @@ class RawInstance;
class Script;
class SequenceNode;
bool UseKernelFrontEndFor(ParsedFunction* parsed_function);
class CompilationPipeline : public ZoneAllocated {
public:
static CompilationPipeline* New(Zone* zone, const Function& function);

File diff suppressed because it is too large Load diff

View file

@ -286,13 +286,6 @@ class Parser : public ValueObject {
static void ParseFunction(ParsedFunction* parsed_function);
// Return true if |field| has a function literal initializer.
// When true is returned, |start| and |end| will hold the token
// range of the function literal.
static bool FieldHasFunctionLiteralInitializer(const Field& field,
TokenPosition* start,
TokenPosition* end);
// Parse and evaluate the metadata expressions at token_pos in the
// class namespace of class cls (which can be the implicit toplevel
// class if the metadata is at the top-level).
@ -323,308 +316,6 @@ class Parser : public ValueObject {
private:
friend class EffectGraphVisitor; // For BuildNoSuchMethodArguments.
struct Block;
class TryStack;
class TokenPosScope;
Parser(const Script& script, const Library& library, TokenPosition token_pos);
Parser(const Script& script,
ParsedFunction* function,
TokenPosition token_pos);
~Parser();
// The function for which we will generate code.
const Function& current_function() const;
// The innermost function being parsed.
const Function& innermost_function() const;
// Note that a local function may be parsed multiple times. It is first parsed
// when its outermost enclosing function is being parsed. It is then parsed
// again when an enclosing function calls this local function or calls
// another local function enclosing it. Code for the local function will only
// be generated the last time the local function is parsed, i.e. when it is
// invoked. For example, a local function nested in another local function,
// itself nested in a static function, is parsed 3 times (unless it does not
// end up being invoked).
// Now, current_function() always points to the outermost function being
// compiled (i.e. the function that is being invoked), and is not updated
// while parsing a nested function of that outermost function.
// Therefore, the statements being parsed may or may not belong to the body
// of the current_function(); they may belong to nested functions.
// innermost_function() is the function that is currently being parsed.
// It is either the same as current_function(), or a lexically nested
// function.
// The function level of the current parsing scope reflects the function
// nesting. The function level is zero while parsing the body of the
// current_function(), but is greater than zero while parsing the body of
// local functions nested in current_function().
// FunctionLevel is 0 when parsing code of current_function(), and denotes
// the relative nesting level when parsing a nested function.
int FunctionLevel() const;
// The class being parsed.
const Class& current_class() const;
void set_current_class(const Class& value);
// ParsedFunction accessor.
ParsedFunction* parsed_function() const { return parsed_function_; }
const Script& script() const { return script_; }
void SetScript(const Script& script, TokenPosition token_pos);
const Library& library() const { return library_; }
void set_library(const Library& value) const { library_ = value.raw(); }
// Parsing a library or a regular source script.
bool is_library_source() const {
return (script_.kind() == RawScript::kScriptTag) ||
(script_.kind() == RawScript::kLibraryTag);
}
bool is_part_source() const {
return script_.kind() == RawScript::kSourceTag;
}
// Parsing library patch script.
bool is_patch_source() const {
return script_.kind() == RawScript::kPatchTag;
}
TokenPosition TokenPos() const { return tokens_iterator_.CurrentPosition(); }
TokenPosition PrevTokenPos() const { return prev_token_pos_; }
Token::Kind CurrentToken() {
if (token_kind_ == Token::kILLEGAL) {
ComputeCurrentToken();
}
return token_kind_;
}
void ComputeCurrentToken();
RawLibraryPrefix* ParsePrefix();
Token::Kind LookaheadToken(int num_tokens);
String* CurrentLiteral() const;
RawDouble* CurrentDoubleLiteral() const;
RawInteger* CurrentIntegerLiteral() const;
// Sets parser to given token position in the stream.
void SetPosition(TokenPosition position);
void ConsumeToken() {
// Reset cache and advance the token.
prev_token_pos_ = tokens_iterator_.CurrentPosition();
token_kind_ = Token::kILLEGAL;
tokens_iterator_.Advance();
INC_STAT(thread(), num_tokens_consumed, 1);
}
void ConsumeRightAngleBracket();
void CheckToken(Token::Kind token_expected, const char* msg = NULL);
void ExpectToken(Token::Kind token_expected);
void ExpectSemicolon();
void UnexpectedToken();
String* ExpectUserDefinedTypeIdentifier(const char* msg);
String* ExpectIdentifier(const char* msg);
bool IsAwaitKeyword();
bool IsYieldKeyword();
void SkipIf(Token::Kind);
void SkipToMatching();
void SkipToMatchingParenthesis();
void SkipBlock();
void SkipOneMetadata();
TokenPosition SkipMetadata();
bool IsPatchAnnotation(TokenPosition pos);
bool IsPragmaAnnotation(TokenPosition pos);
void SkipTypeArguments();
void SkipTypeParameters();
void SkipType(bool allow_void);
void SkipTypeOrFunctionType(bool allow_void);
void SkipInitializers();
void SkipExpr();
void SkipNestedExpr();
void SkipConditionalExpr();
void SkipBinaryExpr();
void SkipUnaryExpr();
void SkipPostfixExpr();
void SkipSelectors();
void SkipPrimary();
void SkipCompoundLiteral();
void SkipSymbolLiteral();
void SkipNewOperator();
void SkipActualParameters();
void SkipMapLiteral();
void SkipListLiteral();
void SkipFunctionLiteral();
void SkipStringLiteral();
void SkipQualIdent();
void SkipFunctionPreamble();
AstNode* DartPrint(const char* str);
void CheckConstructorCallTypeArguments(TokenPosition pos,
const Function& constructor,
const TypeArguments& type_arguments);
// Report already formatted error.
static void ReportError(const Error& error);
// Concatenate and report an already formatted error and a new error message.
static void ReportErrors(const Error& prev_error,
const Script& script,
TokenPosition token_pos,
const char* format,
...) PRINTF_ATTRIBUTE(4, 5);
// Report error message at location of current token in current script.
void ReportError(const char* msg, ...) const PRINTF_ATTRIBUTE(2, 3);
void ReportErrorBefore(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
// Report error message at given location in current script.
void ReportError(TokenPosition token_pos, const char* msg, ...) const
PRINTF_ATTRIBUTE(3, 4);
// Report warning message at location of current token in current script.
void ReportWarning(const char* msg, ...) const PRINTF_ATTRIBUTE(2, 3);
// Report warning message at given location in current script.
void ReportWarning(TokenPosition token_pos, const char* msg, ...) const
PRINTF_ATTRIBUTE(3, 4);
void CheckRecursiveInvocation();
const Instance& EvaluateConstExpr(TokenPosition expr_pos, AstNode* expr);
StaticGetterNode* RunStaticFieldInitializer(const Field& field,
TokenPosition field_ref_pos);
RawObject* EvaluateConstConstructorCall(
const Class& type_class,
const TypeArguments& type_arguments,
const Function& constructor,
ArgumentListNode* arguments,
bool obfuscate_symbol_instances = true);
LiteralNode* FoldConstExpr(TokenPosition expr_pos, AstNode* expr);
// Support for parsing of scripts.
void ParseTopLevel();
void ParseEnumDeclaration(const GrowableObjectArray& pending_classes,
const Object& tl_owner,
TokenPosition metadata_pos);
void ParseEnumDefinition(const Class& cls);
void ParseClassDeclaration(const GrowableObjectArray& pending_classes,
const Object& tl_owner,
TokenPosition metadata_pos);
void ParseClassDefinition(const Class& cls);
void ParseMixinAppAlias(const GrowableObjectArray& pending_classes,
const Object& tl_owner,
TokenPosition metadata_pos);
void ParseTypedef(const GrowableObjectArray& pending_classes,
const Object& tl_owner,
TokenPosition metadata_pos);
void ParseTopLevelVariable(TopLevel* top_level,
const Object& owner,
TokenPosition metadata_pos);
void ParseTopLevelFunction(TopLevel* top_level,
const Object& owner,
TokenPosition metadata_pos);
void ParseTopLevelAccessor(TopLevel* top_level,
const Object& owner,
TokenPosition metadata_pos);
RawArray* EvaluateMetadata();
RawFunction::AsyncModifier ParseFunctionModifier();
// Support for parsing libraries.
RawObject* CallLibraryTagHandler(Dart_LibraryTag tag,
TokenPosition token_pos,
const String& url);
void ParseIdentList(GrowableObjectArray* names);
void ParseLibraryDefinition(const Object& tl_owner);
void ParseLibraryName();
void ParseLibraryImportExport(const Object& tl_owner,
TokenPosition metadata_pos);
void ParseLibraryPart();
void ParsePartHeader();
void ParseLibraryNameObsoleteSyntax();
void ParseLibraryImportObsoleteSyntax();
void ParseLibraryIncludeObsoleteSyntax();
void ResolveSignatureTypeParameters(const Function& signature);
void ResolveTypeParameters(AbstractType* type);
RawAbstractType* CanonicalizeType(const AbstractType& type);
RawAbstractType* ParseType(ClassFinalizer::FinalizationKind finalization,
bool allow_deferred_type = false,
bool consume_unresolved_prefix = true);
RawAbstractType* ParseType(ClassFinalizer::FinalizationKind finalization,
bool allow_deferred_type,
bool consume_unresolved_prefix,
LibraryPrefix* prefix);
RawType* ParseFunctionType(const AbstractType& result_type,
ClassFinalizer::FinalizationKind finalization);
RawAbstractType* ParseTypeOrFunctionType(
bool allow_void,
ClassFinalizer::FinalizationKind finalization);
void ParseTypeParameters(bool parameterizing_class);
RawTypeArguments* ParseTypeArguments(
ClassFinalizer::FinalizationKind finalization);
void ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method);
void ParseFieldDefinition(ClassDesc* members, MemberDesc* field);
void CheckMemberNameConflict(ClassDesc* members, MemberDesc* member);
void ParseClassMemberDefinition(ClassDesc* members,
TokenPosition metadata_pos);
void CheckFinalInitializationConflicts(const ClassDesc* class_desc,
const MemberDesc* member);
void ParseParameterType(ParamList* params);
void ParseFormalParameter(bool allow_explicit_default_value,
bool evaluate_metadata,
ParamList* params);
void ParseFormalParameters(bool use_function_type_syntax,
bool allow_explicit_default_values,
bool evaluate_metadata,
ParamList* params);
void ParseFormalParameterList(bool use_function_type_syntax,
bool allow_explicit_default_values,
bool evaluate_metadata,
ParamList* params);
void CheckFieldsInitialized(const Class& cls);
void AddImplicitConstructor(const Class& cls);
void CheckConstructors(ClassDesc* members);
AstNode* ParseExternalInitializedField(const Field& field);
void ParseInitializedInstanceFields(
const Class& cls,
LocalVariable* receiver,
GrowableArray<Field*>* initialized_fields);
AstNode* CheckDuplicateFieldInit(TokenPosition init_pos,
GrowableArray<Field*>* initialized_fields,
AstNode* instance,
Field* field,
AstNode* init_value);
StaticCallNode* GenerateSuperConstructorCall(
const Class& cls,
TokenPosition supercall_pos,
LocalVariable* receiver,
ArgumentListNode* forwarding_args);
StaticCallNode* ParseSuperInitializer(const Class& cls,
LocalVariable* receiver);
AstNode* ParseInitializer(const Class& cls,
LocalVariable* receiver,
GrowableArray<Field*>* initialized_fields);
void ParseConstructorRedirection(const Class& cls, LocalVariable* receiver);
void ParseInitializers(const Class& cls,
LocalVariable* receiver,
GrowableArray<Field*>* initialized_fields);
String& ParseNativeDeclaration();
void ParseInterfaceList(const Class& cls);
RawAbstractType* ParseMixins(const AbstractType& super_type);
static StaticCallNode* BuildInvocationMirrorAllocation(
TokenPosition call_pos,
const String& function_name,
const ArgumentListNode& function_args,
const LocalVariable* temp,
bool is_super_invocation);
// Build arguments for a NoSuchMethodCall. If LocalVariable temp is not NULL,
// the last argument is stored in temp.
static ArgumentListNode* BuildNoSuchMethodArguments(
@ -633,409 +324,6 @@ class Parser : public ValueObject {
const ArgumentListNode& function_args,
const LocalVariable* temp,
bool is_super_invocation);
RawFunction* GetSuperFunction(TokenPosition token_pos,
const String& name,
ArgumentListNode* arguments,
bool resolve_getter,
bool* is_no_such_method);
AstNode* ParseSuperCall(const String& function_name,
const TypeArguments& func_type_args);
AstNode* ParseSuperFieldAccess(const String& field_name,
TokenPosition field_pos);
AstNode* ParseSuperOperator();
AstNode* BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super);
static bool ParseFormalParameters(const Function& func, ParamList* params);
void SetupDefaultsForOptionalParams(const ParamList& params);
ClosureNode* CreateImplicitClosureNode(const Function& func,
TokenPosition token_pos,
AstNode* receiver);
void FinalizeFormalParameterTypes(const ParamList* params);
void AddFormalParamsToFunction(const ParamList* params, const Function& func);
void AddFormalParamsToScope(const ParamList* params, LocalScope* scope);
SequenceNode* ParseConstructor(const Function& func);
SequenceNode* ParseFunc(const Function& func, bool check_semicolon);
void ParseNativeFunctionBlock(const ParamList* params, const Function& func);
SequenceNode* ParseInstanceGetter(const Function& func);
SequenceNode* ParseInstanceSetter(const Function& func);
SequenceNode* ParseStaticFinalGetter(const Function& func);
SequenceNode* ParseStaticInitializer();
SequenceNode* ParseMethodExtractor(const Function& func);
SequenceNode* ParseNoSuchMethodDispatcher(const Function& func);
SequenceNode* ParseInvokeFieldDispatcher(const Function& func);
SequenceNode* ParseImplicitClosure(const Function& func);
void BuildDispatcherScope(const Function& func,
const ArgumentsDescriptor& desc);
void EnsureHasReturnStatement(SequenceNode* seq, TokenPosition return_pos);
void ChainNewBlock(LocalScope* outer_scope);
void OpenBlock();
void OpenLoopBlock();
void OpenFunctionBlock(const Function& func);
void OpenAsyncClosure();
RawFunction* OpenAsyncFunction(TokenPosition formal_param_pos);
RawFunction* OpenSyncGeneratorFunction(TokenPosition func_pos);
SequenceNode* CloseSyncGenFunction(const Function& closure,
SequenceNode* closure_node);
void AddSyncGenClosureParameters(ParamList* params);
void AddAsyncGenClosureParameters(ParamList* params);
// Support for async* functions.
RawFunction* OpenAsyncGeneratorFunction(TokenPosition func_pos);
SequenceNode* CloseAsyncGeneratorFunction(const Function& closure,
SequenceNode* closure_node);
void OpenAsyncGeneratorClosure();
SequenceNode* CloseAsyncGeneratorClosure(SequenceNode* body);
void OpenAsyncTryBlock();
SequenceNode* CloseBlock();
SequenceNode* CloseAsyncFunction(const Function& closure,
SequenceNode* closure_node);
SequenceNode* CloseAsyncClosure(SequenceNode* body,
TokenPosition func_end_pos);
SequenceNode* CloseAsyncTryBlock(SequenceNode* try_block,
TokenPosition func_end_pos);
SequenceNode* CloseAsyncGeneratorTryBlock(SequenceNode* body);
void AddAsyncClosureParameters(ParamList* params);
void AddContinuationVariables();
void AddAsyncClosureVariables();
void AddAsyncGeneratorVariables();
LocalVariable* LookupReceiver(LocalScope* from_scope, bool test_only);
LocalVariable* LookupTypeArgumentsParameter(LocalScope* from_scope,
bool test_only);
void CaptureInstantiator();
void CaptureFunctionTypeArguments();
void CaptureAllInstantiators();
AstNode* LoadReceiver(TokenPosition token_pos);
AstNode* LoadFieldIfUnresolved(AstNode* node);
AstNode* LoadClosure(PrimaryNode* primary);
AstNode* LoadTypeParameter(PrimaryNode* primary);
InstanceGetterNode* CallGetter(TokenPosition token_pos,
AstNode* object,
const String& name);
AstNode* ParseAssertStatement(bool is_const = false);
AstNode* ParseJump(String* label_name);
AstNode* ParseIfStatement(String* label_name);
AstNode* ParseWhileStatement(String* label_name);
AstNode* ParseDoWhileStatement(String* label_name);
AstNode* ParseForStatement(String* label_name);
AstNode* ParseAwaitForStatement(String* label_name);
AstNode* ParseForInStatement(TokenPosition forin_pos, SourceLabel* label);
RawClass* CheckCaseExpressions(const GrowableArray<LiteralNode*>& values);
CaseNode* ParseCaseClause(LocalVariable* switch_expr_value,
GrowableArray<LiteralNode*>* case_expr_values,
SourceLabel* case_label);
AstNode* ParseSwitchStatement(String* label_name);
// try/catch/finally parsing.
void AddCatchParamsToScope(CatchParamDesc* exception_param,
CatchParamDesc* stack_trace_param,
LocalScope* scope);
void SetupExceptionVariables(LocalScope* try_scope,
bool is_async,
LocalVariable** context_var,
LocalVariable** exception_var,
LocalVariable** stack_trace_var,
LocalVariable** saved_exception_var,
LocalVariable** saved_stack_trace_var);
void SaveExceptionAndStackTrace(SequenceNode* statements,
LocalVariable* exception_var,
LocalVariable* stack_trace_var,
LocalVariable* saved_exception_var,
LocalVariable* saved_stack_trace_var);
// Parse all the catch clause of a try.
SequenceNode* ParseCatchClauses(TokenPosition handler_pos,
bool is_async,
LocalVariable* exception_var,
LocalVariable* stack_trace_var,
LocalVariable* rethrow_exception_var,
LocalVariable* rethrow_stack_trace_var,
const GrowableObjectArray& handler_types,
bool* needs_stack_trace);
// Parse or generate a finally clause.
SequenceNode* EnsureFinallyClause(bool parse,
bool is_async,
LocalVariable* exception_var,
LocalVariable* stack_trace_var,
LocalVariable* rethrow_exception_var,
LocalVariable* rethrow_stack_trace_var);
// Push try block onto the stack of try blocks in scope.
void PushTry(Block* try_block);
// Pop the inner most try block from the stack.
TryStack* PopTry();
// Collect saved try context variables if await or yield is in try block.
void CheckAsyncOpInTryBlock(LocalVariable** saved_try_ctx,
LocalVariable** async_saved_try_ctx,
LocalVariable** outer_saved_try_ctx,
LocalVariable** outer_async_saved_try_ctx) const;
// Add specified node to try block list so that it can be patched with
// inlined finally code if needed.
void AddNodeForFinallyInlining(AstNode* node);
void RemoveNodesForFinallyInlining(SourceLabel* label);
// Add the inlined finally clause to the specified node.
void AddFinallyClauseToNode(bool is_async,
AstNode* node,
InlinedFinallyNode* finally_clause);
AstNode* ParseTryStatement(String* label_name);
RawAbstractType* ParseConstFinalVarOrType(
ClassFinalizer::FinalizationKind finalization);
AstNode* ParseVariableDeclaration(const AbstractType& type,
bool is_final,
bool is_const,
SequenceNode** await_preamble);
AstNode* ParseVariableDeclarationList();
AstNode* ParseFunctionStatement(bool is_literal);
AstNode* ParseYieldStatement();
AstNode* ParseStatement();
SequenceNode* ParseNestedStatement(bool parsing_loop_body,
SourceLabel* label);
void ParseStatementSequence();
bool IsIdentifier();
bool IsSymbol(const String& symbol);
bool IsSimpleLiteral(const AbstractType& type, Instance* value);
bool IsFunctionTypeSymbol();
bool IsFunctionTypeAliasName(bool* use_function_type_syntax);
bool TryParseQualIdent();
bool TryParseTypeParameters();
bool TryParseTypeArguments();
bool IsTypeParameters();
bool IsArgumentPart();
bool IsParameterPart();
bool TryParseType(bool allow_void);
bool IsVariableDeclaration();
bool IsFunctionReturnType();
bool IsFunctionDeclaration();
bool IsFunctionLiteral();
bool IsForInStatement();
bool IsTopLevelAccessor();
AstNode* ParseBinaryExpr(int min_preced);
LiteralNode* ParseConstExpr();
static const bool kRequireConst = true;
static const bool kAllowConst = false;
static const bool kConsumeCascades = true;
static const bool kNoCascades = false;
AstNode* ParseAwaitableExpr(bool require_compiletime_const,
bool consume_cascades,
SequenceNode** await_preamble);
AstNode* ParseExpr(bool require_compiletime_const, bool consume_cascades);
AstNode* ParseAwaitableExprList();
AstNode* ParseConditionalExpr();
AstNode* ParseUnaryExpr();
AstNode* ParsePostfixExpr();
AstNode* ParseSelectors(AstNode* primary, bool is_cascade);
AstNode* ParseCascades(AstNode* expr);
AstNode* ParsePrimary();
AstNode* ParseStringLiteral(bool allow_interpolation);
String* ParseImportStringLiteral();
AstNode* ParseCompoundLiteral();
AstNode* ParseSymbolLiteral();
AstNode* ParseListLiteral(TokenPosition type_pos,
bool is_const,
const TypeArguments& type_arguments);
AstNode* ParseMapLiteral(TokenPosition type_pos,
bool is_const,
const TypeArguments& type_arguments);
AstNode* ParseNewOperator(Token::Kind op_kind);
// An implicit argument, if non-null, is prepended to the returned list.
ArgumentListNode* ParseActualParameters(ArgumentListNode* implicit_arguments,
const TypeArguments& func_type_args,
bool require_const);
AstNode* ParseStaticCall(const Class& cls,
const String& method_name,
TokenPosition ident_pos,
const TypeArguments& func_type_args,
const LibraryPrefix* prefix = NULL);
AstNode* ParseInstanceCall(AstNode* receiver,
const String& method_name,
TokenPosition ident_pos,
const TypeArguments& func_type_args,
bool is_conditional);
AstNode* ParseClosureCall(AstNode* closure,
const TypeArguments& func_type_args);
AstNode* GenerateStaticFieldLookup(const Field& field,
TokenPosition ident_pos);
AstNode* GenerateStaticFieldAccess(const Class& cls,
const String& field_name,
TokenPosition ident_pos);
LocalVariable* LookupLocalScope(const String& ident);
void CheckInstanceFieldAccess(TokenPosition field_pos,
const String& field_name);
bool ParsingStaticMember() const;
bool GetFunctionLiteralInitializerRange(const Field& field,
TokenPosition* start,
TokenPosition* end);
const AbstractType* ReceiverType(const Class& cls);
bool IsInstantiatorRequired() const;
bool InGenericFunctionScope() const;
bool ResolveIdentInLocalScope(TokenPosition ident_pos,
const String& ident,
AstNode** node,
intptr_t* function_level);
static const bool kResolveLocally = true;
static const bool kResolveIncludingImports = false;
// Resolve a primary identifier in the library or prefix scope and
// generate the corresponding AstNode.
AstNode* ResolveIdentInCurrentLibraryScope(TokenPosition ident_pos,
const String& ident);
AstNode* ResolveIdentInPrefixScope(TokenPosition ident_pos,
const LibraryPrefix& prefix,
const String& ident);
AstNode* ResolveIdent(TokenPosition ident_pos,
const String& ident,
bool allow_closure_names);
RawString* ResolveImportVar(TokenPosition ident_pos, const String& ident);
AstNode* OptimizeBinaryOpNode(TokenPosition op_pos,
Token::Kind binary_op,
AstNode* lhs,
AstNode* rhs);
AstNode* ExpandAssignableOp(TokenPosition op_pos,
Token::Kind assignment_op,
AstNode* lhs,
AstNode* rhs);
LetNode* PrepareCompoundAssignmentNodes(AstNode** expr);
LocalVariable* CreateTempConstVariable(TokenPosition token_pos,
const char* s);
static SequenceNode* NodeAsSequenceNode(TokenPosition sequence_pos,
AstNode* node,
LocalScope* scope);
SequenceNode* MakeImplicitConstructor(const Function& func);
AstNode* MakeStaticCall(const String& cls_name,
const String& func_name,
ArgumentListNode* arguments);
String& Interpolate(const GrowableArray<AstNode*>& values);
AstNode* ThrowTypeError(TokenPosition type_pos,
const AbstractType& type,
LibraryPrefix* prefix = NULL);
AstNode* ThrowNoSuchMethodError(TokenPosition call_pos,
const Class& cls,
const String& function_name,
ArgumentListNode* function_arguments,
InvocationMirror::Level level,
InvocationMirror::Kind kind,
const Function* func,
const LibraryPrefix* prefix = NULL);
void SetupSavedTryContext(LocalVariable* saved_try_context);
void CheckOperatorArity(const MemberDesc& member);
void EnsureExpressionTemp();
bool IsLegalAssignableSyntax(AstNode* expr, TokenPosition end_pos);
AstNode* CreateAssignmentNode(AstNode* original,
AstNode* rhs,
const String* left_ident,
TokenPosition left_pos,
bool is_compound = false);
ConstructorCallNode* CreateConstructorCallNode(
TokenPosition token_pos,
const TypeArguments& type_arguments,
const Function& constructor,
ArgumentListNode* arguments);
void AddEqualityNullCheck();
AstNode* AddAsyncResultTypeCheck(TokenPosition expr_pos, AstNode* expr);
AstNode* BuildClosureCall(TokenPosition token_pos,
AstNode* closure,
ArgumentListNode* arguments);
RawInstance* TryCanonicalize(const Instance& instance,
TokenPosition token_pos);
void CacheConstantValue(TokenPosition token_pos, const Instance& value);
bool GetCachedConstant(TokenPosition token_pos, Instance* value);
Thread* thread() const { return thread_; }
Isolate* isolate() const { return isolate_; }
Zone* zone() const { return thread_->zone(); }
Thread* thread_; // Cached current thread.
Isolate* isolate_; // Cached current isolate.
// It is Heap::kNew for mutator thread and Heap::kOld for other threads (e.g.
// background compiler).
Heap::Space allocation_space_;
Script& script_;
TokenStream::Iterator tokens_iterator_;
Token::Kind token_kind_; // Cached token kind for current token.
TokenPosition prev_token_pos_;
Block* current_block_;
// is_top_level_ is true if parsing the "top level" of a compilation unit,
// that is class definitions, function type aliases, global functions,
// global variables.
bool is_top_level_;
// await_is_keyword_ is true if we are parsing an async or generator
// function. In this context the identifiers await, async and yield
// are treated as keywords.
bool await_is_keyword_;
// The member currently being parsed during "top level" parsing.
MemberDesc* current_member_;
// Parser mode to allow/disallow function literals. This is used in
// constructor initializer expressions to handle ambiguous grammar.
bool SetAllowFunctionLiterals(bool value);
bool allow_function_literals_;
// The function currently being compiled.
ParsedFunction* parsed_function_;
// The function currently being parsed.
Function& innermost_function_;
// Current literal token.
LiteralToken& literal_token_;
// The class currently being parsed, or the owner class of the
// function currently being parsed. It is used for primary identifier lookups.
Class& current_class_;
// The current library (and thus class dictionary) used to resolve names.
// When parsing a function, this is the library in which the function
// is defined. This can be the library in which the current_class_ is
// defined, or the library of a mixin class where the function originates.
Library& library_;
// Stack of try blocks in scope, this is used to generate inlined finally
// code at all points in the try block where an exit from the block is
// done using 'return', 'break' or 'continue' statements.
TryStack* try_stack_;
// Each try in this function gets its own try index.
int16_t AllocateTryIndex();
int16_t last_used_try_index_;
bool unregister_pending_function_;
LocalScope* async_temp_scope_;
// Indentation of parser trace.
intptr_t trace_indent_;
intptr_t recursion_counter_;
friend class RecursionChecker;
DISALLOW_COPY_AND_ASSIGN(Parser);
};