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

Unified Diff: runtime/vm/kernel_to_il.cc

Issue 2477563003: VM: [Kernel] Set types on [LocalVariable] if they were introduced by [VariableDeclaration]s (Closed)
Patch Set: addressed comments Created 4 years, 1 month 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') | no next file » | 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 38900f10b9a2efb5a1c96073f314a77ec985e258..02f54379e86e50ca0231e41aa207ddafc84e2afb 100644
--- a/runtime/vm/kernel_to_il.cc
+++ b/runtime/vm/kernel_to_il.cc
@@ -30,6 +30,33 @@ namespace kernel {
#define I Isolate::Current()
+static void DiscoverEnclosingElements(Zone* zone,
+ const Function& function,
+ Function* outermost_function,
+ TreeNode** outermost_node,
+ Class** klass) {
+ // Find out if there is an enclosing kernel class (which will be used to
+ // resolve type parameters).
+ *outermost_function = function.raw();
+ while (outermost_function->parent_function() != Object::null()) {
+ *outermost_function = outermost_function->parent_function();
+ }
+ *outermost_node =
+ static_cast<TreeNode*>(outermost_function->kernel_function());
+ if (*outermost_node != NULL) {
+ TreeNode* parent = NULL;
+ if ((*outermost_node)->IsProcedure()) {
+ parent = Procedure::Cast(*outermost_node)->parent();
+ } else if ((*outermost_node)->IsConstructor()) {
+ parent = Constructor::Cast(*outermost_node)->parent();
+ } else if ((*outermost_node)->IsField()) {
+ parent = Field::Cast(*outermost_node)->parent();
+ }
+ if (parent != NULL && parent->IsClass()) *klass = Class::Cast(parent);
+ }
+}
+
+
void ScopeBuilder::EnterScope(TreeNode* node) {
scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_);
result_->scopes.Insert(node, scope_);
@@ -39,17 +66,8 @@ void ScopeBuilder::EnterScope(TreeNode* node) {
void ScopeBuilder::ExitScope() { scope_ = scope_->parent(); }
-LocalVariable* ScopeBuilder::MakeVariable(const dart::String& name) {
- return new (Z)
- LocalVariable(TokenPosition::kNoSource,
- TokenPosition::kNoSource,
- name,
- Object::dynamic_type());
-}
-
-
LocalVariable* ScopeBuilder::MakeVariable(const dart::String& name,
- const Type& type) {
+ const AbstractType& type) {
return new (Z) LocalVariable(TokenPosition::kNoSource,
TokenPosition::kNoSource,
name,
@@ -71,7 +89,9 @@ void ScopeBuilder::AddParameters(FunctionNode* function, intptr_t pos) {
void ScopeBuilder::AddParameter(VariableDeclaration* declaration,
intptr_t pos) {
- LocalVariable* variable = MakeVariable(H.DartSymbol(declaration->name()));
+ LocalVariable* variable =
+ MakeVariable(H.DartSymbol(declaration->name()),
+ T.TranslateVariableType(declaration));
if (declaration->IsFinal()) {
variable->set_is_final();
}
@@ -117,7 +137,8 @@ void ScopeBuilder::AddExceptionVariable(
// If variable was not lifted by the transformer introduce a new
// one into the current function scope.
if (v == NULL) {
- v = MakeVariable(GenerateName(prefix, nesting_depth - 1));
+ v = MakeVariable(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.
@@ -149,7 +170,8 @@ void ScopeBuilder::AddIteratorVariable() {
ASSERT(result_->iterator_variables.length() == depth_.for_in_ - 1);
LocalVariable* iterator =
- MakeVariable(GenerateName(":iterator", depth_.for_in_ - 1));
+ MakeVariable(GenerateName(":iterator", depth_.for_in_ - 1),
+ AbstractType::dynamic_type());
current_function_scope_->AddVariable(iterator);
result_->iterator_variables.Add(iterator);
}
@@ -213,7 +235,8 @@ void ScopeBuilder::AddVariable(VariableDeclaration* declaration) {
const dart::String& name = declaration->name()->is_empty()
? GenerateName(":var", name_index_++)
: H.DartSymbol(declaration->name());
- LocalVariable* variable = MakeVariable(name);
+ LocalVariable* variable =
+ MakeVariable(name, T.TranslateVariableType(declaration));
if (declaration->IsFinal()) {
variable->set_is_final();
}
@@ -238,6 +261,25 @@ ScopeBuildingResult* ScopeBuilder::BuildScopes() {
ParsedFunction* parsed_function = parsed_function_;
const dart::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_klass = NULL;
+ DiscoverEnclosingElements(
+ Z, function, &outermost_function, &outermost_node, &kernel_klass);
+ // Use [klass]/[kernel_klass] as active class. Type parameters will get
+ // resolved via [kernel_klass] unless we are nested inside a static factory
+ // in which case we will use [member].
+ ActiveClassScope active_class_scope(&active_class_, kernel_klass, &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(
@@ -271,7 +313,9 @@ ScopeBuildingResult* ScopeBuilder::BuildScopes() {
intptr_t pos = 0;
if (function.IsClosureFunction()) {
- LocalVariable* variable = MakeVariable(Symbols::ClosureParameter());
+ LocalVariable* variable =
+ MakeVariable(Symbols::ClosureParameter(),
+ AbstractType::dynamic_type());
variable->set_is_forced_stack();
scope_->InsertParameterAt(pos++, variable);
} else if (!function.is_static()) {
@@ -299,7 +343,8 @@ ScopeBuildingResult* ScopeBuilder::BuildScopes() {
}
} else if (function.IsFactory()) {
LocalVariable* variable = MakeVariable(
- Symbols::TypeArgumentsParameter(), AbstractType::dynamic_type());
+ Symbols::TypeArgumentsParameter(),
+ AbstractType::dynamic_type());
scope_->InsertParameterAt(pos++, variable);
result_->type_arguments_variable = variable;
}
@@ -332,7 +377,8 @@ ScopeBuildingResult* ScopeBuilder::BuildScopes() {
result_->this_variable = variable;
}
if (is_setter) {
- result_->setter_value = MakeVariable(Symbols::Value());
+ result_->setter_value = MakeVariable(
+ Symbols::Value(), AbstractType::dynamic_type());
scope_->InsertParameterAt(pos++, result_->setter_value);
}
break;
@@ -353,7 +399,8 @@ ScopeBuildingResult* ScopeBuilder::BuildScopes() {
case RawFunction::kInvokeFieldDispatcher:
for (intptr_t i = 0; i < function.NumParameters(); ++i) {
LocalVariable* variable = MakeVariable(
- dart::String::ZoneHandle(Z, function.ParameterNameAt(i)));
+ dart::String::ZoneHandle(Z, function.ParameterNameAt(i)),
+ AbstractType::dynamic_type());
scope_->InsertParameterAt(i, variable);
}
break;
@@ -528,7 +575,9 @@ void ScopeBuilder::VisitForInStatement(ForInStatement* node) {
void ScopeBuilder::AddSwitchVariable() {
if ((depth_.function_ == 0) && (result_->switch_variable == NULL)) {
- LocalVariable* variable = MakeVariable(Symbols::SwitchExpr());
+ LocalVariable* variable = MakeVariable(
+ Symbols::SwitchExpr(),
+ AbstractType::dynamic_type());
variable->set_is_forced_stack();
current_function_scope_->AddVariable(variable);
result_->switch_variable = variable;
@@ -546,7 +595,9 @@ 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(name);
+ LocalVariable* variable = MakeVariable(
+ name,
+ AbstractType::dynamic_type());
current_function_scope_->AddVariable(variable);
result_->finally_return_variable = variable;
}
@@ -2731,34 +2782,18 @@ FlowGraph* FlowGraphBuilder::BuildGraph() {
dart::Class& klass =
dart::Class::Handle(zone_, parsed_function_->function().Owner());
- // Find out if there is an enclosing kernel class (which will be used to
- // resolve type parameters).
+ Function& outermost_function = Function::Handle(Z);
+ TreeNode* outermost_node = NULL;
Class* kernel_klass = NULL;
- dart::Function& topmost = dart::Function::Handle(Z, function.raw());
- while (topmost.parent_function() != Object::null()) {
- topmost = topmost.parent_function();
- }
- TreeNode* topmost_node = static_cast<TreeNode*>(topmost.kernel_function());
- if (topmost_node != NULL) {
- // Going up the closure->parent chain needs to result in a Procedure or
- // Constructor.
- TreeNode* parent = NULL;
- if (topmost_node->IsProcedure()) {
- parent = Procedure::Cast(topmost_node)->parent();
- } else if (topmost_node->IsConstructor()) {
- parent = Constructor::Cast(topmost_node)->parent();
- } else if (topmost_node->IsField()) {
- parent = Field::Cast(topmost_node)->parent();
- }
- if (parent != NULL && parent->IsClass()) kernel_klass = Class::Cast(parent);
- }
+ DiscoverEnclosingElements(
+ Z, function, &outermost_function, &outermost_node, &kernel_klass);
// Mark that we are using [klass]/[kernell_klass] as active class. Resolving
// of type parameters will get resolved via [kernell_klass] unless we are
// nested inside a static factory in which case we will use [member].
ActiveClassScope active_class_scope(&active_class_, kernel_klass, &klass);
- Member* member = topmost_node != NULL && topmost_node->IsMember()
- ? Member::Cast(topmost_node)
+ Member* member = ((outermost_node != NULL) && outermost_node->IsMember())
+ ? Member::Cast(outermost_node)
: NULL;
ActiveMemberScope active_member(&active_class_, member);
@@ -2846,12 +2881,12 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfFunction(FunctionNode* function,
LocalVariable* variable = scope->VariableAt(i);
if (variable->is_captured()) {
// There is no LocalVariable describing the on-stack parameter so
- // create one directly.
+ // create one directly and use the same type.
LocalVariable* parameter =
new (Z) LocalVariable(TokenPosition::kNoSource,
TokenPosition::kNoSource,
Symbols::TempParam(),
- Object::dynamic_type());
+ variable->type());
parameter->set_index(parameter_index);
// Mark the stack variable so it will be ignored by the code for
// try/catch.
@@ -3804,6 +3839,24 @@ AbstractType& DartTypeTranslator::TranslateTypeWithoutFinalization(
}
+const AbstractType& DartTypeTranslator::TranslateVariableType(
+ VariableDeclaration* variable) {
+ AbstractType& abstract_type = TranslateType(variable->type());
+
+ // We return a new `ZoneHandle` here on purpose: The intermediate language
+ // instructions do not make a copy of the handle, so we do it.
+ AbstractType& type = Type::ZoneHandle(Z);
+
+ if (abstract_type.IsMalformed()) {
+ type = AbstractType::dynamic_type().raw();
+ } else {
+ type = result_.raw();
+ }
+
+ return type;
+}
+
+
void DartTypeTranslator::VisitInvalidType(InvalidType* node) {
result_ = ClassFinalizer::NewFinalizedMalformedType(
Error::Handle(Z), // No previous error.
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698