Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(774)

Unified Diff: runtime/vm/kernel_to_il.cc

Issue 2886873008: [kernel] Streaming ScopeBuilder (Closed)
Patch Set: Addressed (some) comments; rebased. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/kernel_to_il.cc
diff --git a/runtime/vm/kernel_to_il.cc b/runtime/vm/kernel_to_il.cc
index 7635053d71dcc957bb8896bc0b7c96266c7faa66..5b10f05fa41a64ffd304d0ef1c7eb76b1348fe06 100644
--- a/runtime/vm/kernel_to_il.cc
+++ b/runtime/vm/kernel_to_il.cc
@@ -57,225 +57,6 @@ static void DiscoverEnclosingElements(Zone* zone,
}
-ScopeBuilder::ScopeBuilder(ParsedFunction* parsed_function, TreeNode* node)
- : result_(NULL),
- parsed_function_(parsed_function),
- node_(node),
- translation_helper_(Thread::Current()),
- zone_(translation_helper_.zone()),
- type_translator_(&translation_helper_, &active_class_, /*finalize=*/true),
- current_function_scope_(NULL),
- scope_(NULL),
- depth_(0),
- name_index_(0),
- needs_expr_temp_(false) {
- Script& script = Script::Handle(Z, parsed_function->function().script());
- H.SetStringOffsets(TypedData::Handle(Z, script.kernel_string_offsets()));
- H.SetStringData(TypedData::Handle(Z, script.kernel_string_data()));
- H.SetCanonicalNames(TypedData::Handle(Z, script.kernel_canonical_names()));
-}
-
-
-void ScopeBuilder::EnterScope(TreeNode* node, TokenPosition start_position) {
- scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_);
- scope_->set_begin_token_pos(start_position);
- ASSERT(node->kernel_offset() >= 0);
- result_->scopes.Insert(node->kernel_offset(), scope_);
-}
-
-
-void ScopeBuilder::ExitScope(TokenPosition end_position) {
- scope_->set_end_token_pos(end_position);
- scope_ = scope_->parent();
-}
-
-
-LocalVariable* ScopeBuilder::MakeVariable(TokenPosition declaration_pos,
- TokenPosition token_pos,
- const dart::String& name,
- const AbstractType& type) {
- return new (Z) LocalVariable(declaration_pos, token_pos, name, type);
-}
-
-
-void ScopeBuilder::AddParameters(FunctionNode* function, intptr_t pos) {
- List<VariableDeclaration>& positional = function->positional_parameters();
- for (intptr_t i = 0; i < positional.length(); ++i) {
- AddParameter(positional[i], pos++);
- }
- List<VariableDeclaration>& named = function->named_parameters();
- for (intptr_t i = 0; i < named.length(); ++i) {
- AddParameter(named[i], pos++);
- }
-}
-
-
-void ScopeBuilder::AddParameter(VariableDeclaration* declaration,
- intptr_t pos) {
- LocalVariable* variable = MakeVariable(
- declaration->position(), declaration->position(),
- H.DartSymbol(declaration->name()), T.TranslateVariableType(declaration));
- if (declaration->IsFinal()) {
- variable->set_is_final();
- }
- if (variable->name().raw() == Symbols::IteratorParameter().raw()) {
- variable->set_is_forced_stack();
- }
- scope_->InsertParameterAt(pos, variable);
- result_->locals.Insert(declaration->kernel_offset(), variable);
-
- // The default value may contain 'let' bindings for which the constant
- // evaluator needs scope bindings.
- Expression* defaultValue = declaration->initializer();
- if (defaultValue != NULL) {
- defaultValue->AcceptExpressionVisitor(this);
- }
-}
-
-
-void ScopeBuilder::AddExceptionVariable(
- GrowableArray<LocalVariable*>* variables,
- const char* prefix,
- intptr_t nesting_depth) {
- LocalVariable* v = NULL;
-
- // If we are inside a function with yield points then Kernel transformer
- // could have lifted some of the auxiliary exception variables into the
- // context to preserve them across yield points because they might
- // be needed for rethrow.
- // Check if it did and capture such variables instead of introducing
- // new local ones.
- // Note: function that wrap kSyncYielding function does not contain
- // its own try/catches.
- if (current_function_node_->async_marker() == FunctionNode::kSyncYielding) {
- ASSERT(current_function_scope_->parent() != NULL);
- v = current_function_scope_->parent()->LocalLookupVariable(
- GenerateName(prefix, nesting_depth - 1));
- if (v != NULL) {
- scope_->CaptureVariable(v);
- }
- }
-
- // No need to create variables for try/catch-statements inside
- // nested functions.
- if (depth_.function_ > 0) return;
- if (variables->length() >= nesting_depth) return;
-
- // If variable was not lifted by the transformer introduce a new
- // one into the current function scope.
- if (v == NULL) {
- v = MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
- GenerateName(prefix, nesting_depth - 1),
- AbstractType::dynamic_type());
-
- // If transformer did not lift the variable then there is no need
- // to lift it into the context when we encouter a YieldStatement.
- v->set_is_forced_stack();
- current_function_scope_->AddVariable(v);
- }
-
- variables->Add(v);
-}
-
-
-void ScopeBuilder::AddTryVariables() {
- AddExceptionVariable(&result_->catch_context_variables,
- ":saved_try_context_var", depth_.try_);
-}
-
-
-void ScopeBuilder::AddCatchVariables() {
- AddExceptionVariable(&result_->exception_variables, ":exception",
- depth_.catch_);
- AddExceptionVariable(&result_->stack_trace_variables, ":stack_trace",
- depth_.catch_);
-}
-
-
-void ScopeBuilder::AddIteratorVariable() {
- if (depth_.function_ > 0) return;
- if (result_->iterator_variables.length() >= depth_.for_in_) return;
-
- ASSERT(result_->iterator_variables.length() == depth_.for_in_ - 1);
- LocalVariable* iterator =
- MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
- GenerateName(":iterator", depth_.for_in_ - 1),
- AbstractType::dynamic_type());
- current_function_scope_->AddVariable(iterator);
- result_->iterator_variables.Add(iterator);
-}
-
-
-void ScopeBuilder::LookupVariable(VariableDeclaration* declaration) {
- LocalVariable* variable =
- result_->locals.Lookup(declaration->kernel_offset());
- if (variable == NULL) {
- // We have not seen a declaration of the variable, so it must be the
- // case that we are compiling a nested function and the variable is
- // declared in an outer scope. In that case, look it up in the scope by
- // name and add it to the variable map to simplify later lookup.
- ASSERT(current_function_scope_->parent() != NULL);
- const dart::String& name = H.DartSymbol(declaration->name());
- variable = current_function_scope_->parent()->LookupVariable(name, true);
- ASSERT(variable != NULL);
- result_->locals.Insert(declaration->kernel_offset(), variable);
- }
- if (variable->owner()->function_level() < scope_->function_level()) {
- // We call `LocalScope->CaptureVariable(variable)` in two scenarios for two
- // different reasons:
- // Scenario 1:
- // We need to know which variables defined in this function
- // are closed over by nested closures in order to ensure we will
- // create a [Context] object of appropriate size and store captured
- // variables there instead of the stack.
- // Scenario 2:
- // We need to find out which variables defined in enclosing functions
- // are closed over by this function/closure or nested closures. This
- // is necessary in order to build a fat flattened [ContextScope]
- // object.
- scope_->CaptureVariable(variable);
- } else {
- ASSERT(variable->owner()->function_level() == scope_->function_level());
- }
-}
-
-
-void ScopeBuilder::LookupCapturedVariableByName(LocalVariable** variable,
- const dart::String& name) {
- if (*variable == NULL) {
- *variable = scope_->LookupVariable(name, true);
- ASSERT(*variable != NULL);
- scope_->CaptureVariable(*variable);
- }
-}
-
-
-const dart::String& ScopeBuilder::GenerateName(const char* prefix,
- intptr_t suffix) {
- char name[64];
- OS::SNPrint(name, 64, "%s%" Pd "", prefix, suffix);
- return H.DartSymbol(name);
-}
-
-
-void ScopeBuilder::AddVariable(VariableDeclaration* declaration) {
- // In case `declaration->IsConst()` the flow graph building will take care of
- // evaluating the constant and setting it via
- // `declaration->SetConstantValue()`.
- const dart::String& name = (H.StringSize(declaration->name()) == 0)
- ? GenerateName(":var", name_index_++)
- : H.DartSymbol(declaration->name());
- LocalVariable* variable =
- MakeVariable(declaration->position(), declaration->end_position(), name,
- T.TranslateVariableType(declaration));
- if (declaration->IsFinal()) {
- variable->set_is_final();
- }
- scope_->AddVariable(variable);
- result_->locals.Insert(declaration->kernel_offset(), variable);
-}
-
-
static bool IsStaticInitializer(const Function& function, Zone* zone) {
return (function.kind() == RawFunction::kImplicitStaticFinalGetter) &&
dart::String::Handle(zone, function.name())
@@ -283,539 +64,6 @@ static bool IsStaticInitializer(const Function& function, Zone* zone) {
}
-ScopeBuildingResult* ScopeBuilder::BuildScopes() {
- if (result_ != NULL) return result_;
-
- ASSERT(scope_ == NULL && depth_.loop_ == 0 && depth_.function_ == 0);
- result_ = new (Z) ScopeBuildingResult();
-
- ParsedFunction* parsed_function = parsed_function_;
- const Function& function = parsed_function->function();
-
- // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used
- // e.g. for type translation.
- const dart::Class& klass =
- dart::Class::Handle(zone_, parsed_function_->function().Owner());
- Function& outermost_function = Function::Handle(Z);
- TreeNode* outermost_node = NULL;
- Class* kernel_class = NULL;
- DiscoverEnclosingElements(Z, function, &outermost_function, &outermost_node,
- &kernel_class);
- // Use [klass]/[kernel_class] as active class. Type parameters will get
- // resolved via [kernel_class] unless we are nested inside a static factory
- // in which case we will use [member].
- ActiveClassScope active_class_scope(&active_class_, kernel_class, &klass);
- Member* member = ((outermost_node != NULL) && outermost_node->IsMember())
- ? Member::Cast(outermost_node)
- : NULL;
- ActiveMemberScope active_member(&active_class_, member);
-
-
- LocalScope* enclosing_scope = NULL;
- if (function.IsLocalFunction()) {
- enclosing_scope = LocalScope::RestoreOuterScope(
- ContextScope::Handle(Z, function.context_scope()));
- }
- current_function_scope_ = scope_ = new (Z) LocalScope(enclosing_scope, 0, 0);
- scope_->set_begin_token_pos(function.token_pos());
- scope_->set_end_token_pos(function.end_token_pos());
-
- LocalVariable* context_var = parsed_function->current_context_var();
- context_var->set_is_forced_stack();
- scope_->AddVariable(context_var);
-
- parsed_function->SetNodeSequence(
- new SequenceNode(TokenPosition::kNoSource, scope_));
-
- switch (function.kind()) {
- case RawFunction::kClosureFunction:
- case RawFunction::kRegularFunction:
- case RawFunction::kGetterFunction:
- case RawFunction::kSetterFunction:
- case RawFunction::kConstructor: {
- FunctionNode* node;
- if (node_->IsProcedure()) {
- node = Procedure::Cast(node_)->function();
- } else if (node_->IsConstructor()) {
- node = Constructor::Cast(node_)->function();
- } else {
- node = FunctionNode::Cast(node_);
- }
- current_function_node_ = node;
-
- intptr_t pos = 0;
- if (function.IsClosureFunction()) {
- LocalVariable* variable = MakeVariable(
- TokenPosition::kNoSource, TokenPosition::kNoSource,
- Symbols::ClosureParameter(), AbstractType::dynamic_type());
- variable->set_is_forced_stack();
- scope_->InsertParameterAt(pos++, variable);
- } else if (!function.is_static()) {
- // We use [is_static] instead of [IsStaticFunction] because the latter
- // returns `false` for constructors.
- dart::Class& klass = dart::Class::Handle(Z, function.Owner());
- Type& klass_type = H.GetCanonicalType(klass);
- LocalVariable* variable =
- MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
- Symbols::This(), klass_type);
- scope_->InsertParameterAt(pos++, variable);
- result_->this_variable = variable;
-
- // We visit instance field initializers because they might contain
- // [Let] expressions and we need to have a mapping.
- if (node_->IsConstructor()) {
- Class* klass = Class::Cast(Constructor::Cast(node_)->parent());
-
- for (intptr_t i = 0; i < klass->fields().length(); i++) {
- Field* field = klass->fields()[i];
- if (!field->IsStatic() && (field->initializer() != NULL)) {
- EnterScope(field, field->position());
- field->initializer()->AcceptExpressionVisitor(this);
- ExitScope(field->end_position());
- }
- }
- }
- } else if (function.IsFactory()) {
- LocalVariable* variable = MakeVariable(
- TokenPosition::kNoSource, TokenPosition::kNoSource,
- Symbols::TypeArgumentsParameter(), AbstractType::dynamic_type());
- scope_->InsertParameterAt(pos++, variable);
- result_->type_arguments_variable = variable;
- }
- AddParameters(node, pos);
-
- // We generate a syntethic body for implicit closure functions - which
- // will forward the call to the real function.
- // -> see BuildGraphOfImplicitClosureFunction
- if (!function.IsImplicitClosureFunction()) {
- // TODO(jensj): HACK: Push the begin token to after any parameters to
- // avoid crash when breaking on definition line of async method in
- // debugger. It seems that another scope needs to be added
- // in which captures are made, but I can't make that work.
- // This 'solution' doesn't crash, but I cannot see the parameters at
- // that particular breakpoint either.
- // Also push the end token to after the "}" to avoid crashing on
- // stepping past the last line (to the "}" character).
- if (node->body() != NULL && node->body()->position().IsReal()) {
- scope_->set_begin_token_pos(node->body()->position());
- }
- if (scope_->end_token_pos().IsReal()) {
- scope_->set_end_token_pos(scope_->end_token_pos().Next());
- }
- node_->AcceptVisitor(this);
- }
- break;
- }
- case RawFunction::kImplicitGetter:
- case RawFunction::kImplicitStaticFinalGetter:
- case RawFunction::kImplicitSetter: {
- ASSERT(node_->IsField());
- if (IsStaticInitializer(function, Z)) {
- node_->AcceptVisitor(this);
- break;
- }
- bool is_setter = function.IsImplicitSetterFunction();
- bool is_method = !function.IsStaticFunction();
- intptr_t pos = 0;
- if (is_method) {
- dart::Class& klass = dart::Class::Handle(Z, function.Owner());
- Type& klass_type = H.GetCanonicalType(klass);
- LocalVariable* variable =
- MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
- Symbols::This(), klass_type);
- scope_->InsertParameterAt(pos++, variable);
- result_->this_variable = variable;
- }
- if (is_setter) {
- result_->setter_value =
- MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
- Symbols::Value(), AbstractType::dynamic_type());
- scope_->InsertParameterAt(pos++, result_->setter_value);
- }
- break;
- }
- case RawFunction::kMethodExtractor: {
- // Add a receiver parameter. Though it is captured, we emit code to
- // explicitly copy it to a fixed offset in a freshly-allocated context
- // instead of using the generic code for regular functions.
- // Therefore, it isn't necessary to mark it as captured here.
- dart::Class& klass = dart::Class::Handle(Z, function.Owner());
- Type& klass_type = H.GetCanonicalType(klass);
- LocalVariable* variable =
- MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
- Symbols::This(), klass_type);
- scope_->InsertParameterAt(0, variable);
- result_->this_variable = variable;
- break;
- }
- case RawFunction::kNoSuchMethodDispatcher:
- case RawFunction::kInvokeFieldDispatcher:
- for (intptr_t i = 0; i < function.NumParameters(); ++i) {
- LocalVariable* variable = MakeVariable(
- TokenPosition::kNoSource, TokenPosition::kNoSource,
- dart::String::ZoneHandle(Z, function.ParameterNameAt(i)),
- AbstractType::dynamic_type());
- scope_->InsertParameterAt(i, variable);
- }
- break;
- case RawFunction::kSignatureFunction:
- case RawFunction::kIrregexpFunction:
- UNREACHABLE();
- }
- if (needs_expr_temp_) {
- scope_->AddVariable(parsed_function_->EnsureExpressionTemp());
- }
- parsed_function->AllocateVariables();
-
- return result_;
-}
-
-
-void ScopeBuilder::VisitThisExpression(ThisExpression* node) {
- HandleSpecialLoad(&result_->this_variable, Symbols::This());
-}
-
-
-void ScopeBuilder::VisitTypeParameterType(TypeParameterType* node) {
- Function& function = Function::Handle(Z, parsed_function_->function().raw());
- while (function.IsClosureFunction()) {
- function = function.parent_function();
- }
-
- if (function.IsFactory()) {
- // The type argument vector is passed as the very first argument to the
- // factory constructor function.
- HandleSpecialLoad(&result_->type_arguments_variable,
- Symbols::TypeArgumentsParameter());
- } else {
- // The type argument vector is stored on the instance object. We therefore
- // need to capture `this`.
- HandleSpecialLoad(&result_->this_variable, Symbols::This());
- }
-}
-
-
-void ScopeBuilder::VisitVariableGet(VariableGet* node) {
- LookupVariable(node->variable());
-}
-
-
-void ScopeBuilder::VisitVariableSet(VariableSet* node) {
- LookupVariable(node->variable());
- node->VisitChildren(this);
-}
-
-
-void ScopeBuilder::VisitConditionalExpression(ConditionalExpression* node) {
- needs_expr_temp_ = true;
- node->VisitChildren(this);
-}
-
-
-void ScopeBuilder::VisitLogicalExpression(LogicalExpression* node) {
- needs_expr_temp_ = true;
- node->VisitChildren(this);
-}
-
-
-void ScopeBuilder::HandleLocalFunction(TreeNode* parent,
- FunctionNode* function) {
- LocalScope* saved_function_scope = current_function_scope_;
- FunctionNode* saved_function_node = current_function_node_;
- ScopeBuilder::DepthState saved_depth_state = depth_;
- depth_ = DepthState(depth_.function_ + 1);
- EnterScope(parent, function->position());
- current_function_scope_ = scope_;
- current_function_node_ = function;
- if (depth_.function_ == 1) {
- FunctionScope function_scope = {function->kernel_offset(), scope_};
- result_->function_scopes.Add(function_scope);
- }
- AddParameters(function);
- VisitFunctionNode(function);
- ExitScope(function->end_position());
- depth_ = saved_depth_state;
- current_function_scope_ = saved_function_scope;
- current_function_node_ = saved_function_node;
-}
-
-
-void ScopeBuilder::HandleSpecialLoad(LocalVariable** variable,
- const dart::String& symbol) {
- if (current_function_scope_->parent() != NULL) {
- // We are building the scope tree of a closure function and saw [node]. We
- // lazily populate the variable using the parent function scope.
- if (*variable == NULL) {
- *variable =
- current_function_scope_->parent()->LookupVariable(symbol, true);
- ASSERT(*variable != NULL);
- }
- }
-
- if ((current_function_scope_->parent() != NULL) ||
- (scope_->function_level() > 0)) {
- // Every scope we use the [variable] from needs to be notified of the usage
- // in order to ensure that preserving the context scope on that particular
- // use-site also includes the [variable].
- scope_->CaptureVariable(*variable);
- }
-}
-
-
-void ScopeBuilder::VisitFunctionExpression(FunctionExpression* node) {
- HandleLocalFunction(node, node->function());
-}
-
-
-void ScopeBuilder::VisitLet(Let* node) {
- EnterScope(node, node->position());
- node->VisitChildren(this);
- ExitScope(node->end_position());
-}
-
-
-void ScopeBuilder::VisitBlock(Block* node) {
- EnterScope(node, node->position());
- node->VisitChildren(this);
- ExitScope(node->end_position());
-}
-
-
-void ScopeBuilder::VisitVariableDeclaration(VariableDeclaration* node) {
- AddVariable(node);
- node->VisitChildren(this);
-}
-
-
-void ScopeBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) {
- VisitVariableDeclaration(node->variable());
- HandleLocalFunction(node, node->function());
-}
-
-
-void ScopeBuilder::VisitWhileStatement(WhileStatement* node) {
- ++depth_.loop_;
- node->VisitChildren(this);
- --depth_.loop_;
-}
-
-
-void ScopeBuilder::VisitDoStatement(DoStatement* node) {
- ++depth_.loop_;
- node->VisitChildren(this);
- --depth_.loop_;
-}
-
-
-void ScopeBuilder::VisitForStatement(ForStatement* node) {
- EnterScope(node, node->position());
- List<VariableDeclaration>& variables = node->variables();
- for (intptr_t i = 0; i < variables.length(); ++i) {
- VisitVariableDeclaration(variables[i]);
- }
- ++depth_.loop_;
- if (node->condition() != NULL) {
- node->condition()->AcceptExpressionVisitor(this);
- }
- node->body()->AcceptStatementVisitor(this);
- List<Expression>& updates = node->updates();
- for (intptr_t i = 0; i < updates.length(); ++i) {
- updates[i]->AcceptExpressionVisitor(this);
- }
- --depth_.loop_;
- ExitScope(node->end_position());
-}
-
-
-void ScopeBuilder::VisitForInStatement(ForInStatement* node) {
- node->iterable()->AcceptExpressionVisitor(this);
- ++depth_.for_in_;
- AddIteratorVariable();
- ++depth_.loop_;
- EnterScope(node, node->position());
- VisitVariableDeclaration(node->variable());
- node->body()->AcceptStatementVisitor(this);
- ExitScope(node->end_position());
- --depth_.loop_;
- --depth_.for_in_;
-}
-
-
-void ScopeBuilder::AddSwitchVariable() {
- if ((depth_.function_ == 0) && (result_->switch_variable == NULL)) {
- LocalVariable* variable =
- MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
- Symbols::SwitchExpr(), AbstractType::dynamic_type());
- variable->set_is_forced_stack();
- current_function_scope_->AddVariable(variable);
- result_->switch_variable = variable;
- }
-}
-
-
-void ScopeBuilder::VisitSwitchStatement(SwitchStatement* node) {
- AddSwitchVariable();
- node->VisitChildren(this);
-}
-
-
-void ScopeBuilder::VisitReturnStatement(ReturnStatement* node) {
- if ((depth_.function_ == 0) && (depth_.finally_ > 0) &&
- (result_->finally_return_variable == NULL)) {
- const dart::String& name = H.DartSymbol(":try_finally_return_value");
- LocalVariable* variable =
- MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, name,
- AbstractType::dynamic_type());
- current_function_scope_->AddVariable(variable);
- result_->finally_return_variable = variable;
- }
- node->VisitChildren(this);
-}
-
-
-void ScopeBuilder::VisitTryCatch(TryCatch* node) {
- ++depth_.try_;
- AddTryVariables();
- node->body()->AcceptStatementVisitor(this);
- --depth_.try_;
-
- ++depth_.catch_;
- AddCatchVariables();
- List<Catch>& catches = node->catches();
- for (intptr_t i = 0; i < catches.length(); ++i) {
- Catch* ketch = catches[i];
- EnterScope(ketch, ketch->position());
- if (ketch->exception() != NULL) {
- VisitVariableDeclaration(ketch->exception());
- }
- if (ketch->stack_trace() != NULL) {
- VisitVariableDeclaration(ketch->stack_trace());
- }
- ketch->body()->AcceptStatementVisitor(this);
- ExitScope(ketch->end_position());
- }
- --depth_.catch_;
-}
-
-
-void ScopeBuilder::VisitTryFinally(TryFinally* node) {
- ++depth_.try_;
- ++depth_.finally_;
- AddTryVariables();
- node->body()->AcceptStatementVisitor(this);
- --depth_.finally_;
- --depth_.try_;
-
- ++depth_.catch_;
- AddCatchVariables();
- node->finalizer()->AcceptStatementVisitor(this);
- --depth_.catch_;
-}
-
-
-void ScopeBuilder::VisitFunctionNode(FunctionNode* node) {
- List<TypeParameter>& type_parameters = node->type_parameters();
- for (intptr_t i = 0; i < type_parameters.length(); ++i) {
- VisitTypeParameter(type_parameters[i]);
- }
-
- if (FLAG_causal_async_stacks &&
- (node->dart_async_marker() == FunctionNode::kAsync ||
- node->dart_async_marker() == FunctionNode::kAsyncStar)) {
- LocalVariable* asyncStackTraceVar = MakeVariable(
- TokenPosition::kNoSource, TokenPosition::kNoSource,
- Symbols::AsyncStackTraceVar(), AbstractType::dynamic_type());
- scope_->AddVariable(asyncStackTraceVar);
- }
-
- if (node->async_marker() == FunctionNode::kSyncYielding) {
- LocalScope* scope = parsed_function_->node_sequence()->scope();
- intptr_t offset = parsed_function_->function().num_fixed_parameters();
- for (intptr_t i = 0;
- i < parsed_function_->function().NumOptionalPositionalParameters();
- i++) {
- scope->VariableAt(offset + i)->set_is_forced_stack();
- }
- }
-
- // Do not visit the positional and named parameters, because they've
- // already been added to the scope.
- if (node->body() != NULL) {
- node->body()->AcceptStatementVisitor(this);
- }
-
- // Ensure that :await_jump_var, :await_ctx_var, :async_op and
- // :async_stack_trace are captured.
- if (node->async_marker() == FunctionNode::kSyncYielding) {
- {
- LocalVariable* temp = NULL;
- LookupCapturedVariableByName(
- (depth_.function_ == 0) ? &result_->yield_jump_variable : &temp,
- Symbols::AwaitJumpVar());
- }
- {
- LocalVariable* temp = NULL;
- LookupCapturedVariableByName(
- (depth_.function_ == 0) ? &result_->yield_context_variable : &temp,
- Symbols::AwaitContextVar());
- }
- {
- LocalVariable* temp =
- scope_->LookupVariable(Symbols::AsyncOperation(), true);
- if (temp != NULL) {
- scope_->CaptureVariable(temp);
- }
- }
- if (FLAG_causal_async_stacks) {
- LocalVariable* temp =
- scope_->LookupVariable(Symbols::AsyncStackTraceVar(), true);
- if (temp != NULL) {
- scope_->CaptureVariable(temp);
- }
- }
- }
-}
-
-
-void ScopeBuilder::VisitYieldStatement(YieldStatement* node) {
- ASSERT(node->is_native());
- if (depth_.function_ == 0) {
- AddSwitchVariable();
- // Promote all currently visible local variables into the context.
- // TODO(27590) CaptureLocalVariables promotes to many variables into
- // the scope. Mark those variables as stack_local.
- // TODO(27590) we don't need to promote those variables that are
- // not used across yields.
- scope_->CaptureLocalVariables(current_function_scope_);
- }
-}
-
-
-void ScopeBuilder::VisitAssertStatement(AssertStatement* node) {
- if (I->asserts()) {
- RecursiveVisitor::VisitAssertStatement(node);
- }
-}
-
-
-void ScopeBuilder::VisitConstructor(Constructor* node) {
- // Field initializers that come from non-static field declarations are
- // compiled as if they appear in the constructor initializer list. This is
- // important for closure-valued field initializers because the VM expects the
- // corresponding closure functions to appear as if they were nested inside the
- // constructor.
- List<Field>& fields = Class::Cast(node->parent())->fields();
- for (intptr_t i = 0; i < fields.length(); ++i) {
- Field* field = fields[i];
- Expression* initializer = field->initializer();
- if (!field->IsStatic() && (initializer != NULL)) {
- initializer->AcceptExpressionVisitor(this);
- }
- }
- node->VisitChildren(this);
-}
-
-
Fragment& Fragment::operator+=(const Fragment& other) {
if (entry == NULL) {
entry = other.entry;
@@ -3042,7 +2290,7 @@ intptr_t FlowGraphBuilder::CurrentTryIndex() {
LocalVariable* FlowGraphBuilder::LookupVariable(VariableDeclaration* var) {
- LocalVariable* local = scopes_->locals.Lookup(var->kernel_offset());
+ LocalVariable* local = scopes_->locals.Lookup(var->kernel_offset_no_tag());
ASSERT(local != NULL);
return local;
}
@@ -3225,8 +2473,6 @@ FlowGraph* FlowGraphBuilder::BuildGraph() {
FunctionNode* kernel_function = node_->IsProcedure()
? Procedure::Cast(node_)->function()
: FunctionNode::Cast(node_);
- ActiveFunctionScope active_function_scope(&active_class_,
- kernel_function);
return function.IsImplicitClosureFunction()
? BuildGraphOfImplicitClosureFunction(kernel_function,
function)
@@ -3237,12 +2483,10 @@ FlowGraph* FlowGraphBuilder::BuildGraph() {
if (is_factory) {
Procedure* procedure = Procedure::Cast(node_);
FunctionNode* function = procedure->function();
- ActiveFunctionScope active_function_scope(&active_class_, function);
return BuildGraphOfFunction(function, NULL);
} else {
Constructor* constructor = Constructor::Cast(node_);
FunctionNode* function = constructor->function();
- ActiveFunctionScope active_function_scope(&active_class_, function);
return BuildGraphOfFunction(function, constructor);
}
}
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698