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

Side by Side Diff: runtime/vm/object.cc

Issue 471283002: Runtime support for evaluation of static field initializer expressions (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 2709 matching lines...) Expand 10 before | Expand all | Expand 10 after
2720 orig_list = fields(); 2720 orig_list = fields();
2721 orig_len = orig_list.Length(); 2721 orig_len = orig_list.Length();
2722 patch_list = patch.fields(); 2722 patch_list = patch.fields();
2723 patch_len = patch_list.Length(); 2723 patch_len = patch_list.Length();
2724 2724
2725 Field& field = Field::Handle(); 2725 Field& field = Field::Handle();
2726 Field& orig_field = Field::Handle(); 2726 Field& orig_field = Field::Handle();
2727 new_list = Array::New(patch_len + orig_len); 2727 new_list = Array::New(patch_len + orig_len);
2728 for (intptr_t i = 0; i < patch_len; i++) { 2728 for (intptr_t i = 0; i < patch_len; i++) {
2729 field ^= patch_list.At(i); 2729 field ^= patch_list.At(i);
2730 field.set_owner(*this); 2730 field.set_owner(patch_class);
2731 member_name = field.name(); 2731 member_name = field.name();
2732 // TODO(iposva): Verify non-public fields only. 2732 // TODO(iposva): Verify non-public fields only.
2733 2733
2734 // Verify no duplicate additions. 2734 // Verify no duplicate additions.
2735 orig_field ^= LookupField(member_name); 2735 orig_field ^= LookupField(member_name);
2736 if (!orig_field.IsNull()) { 2736 if (!orig_field.IsNull()) {
2737 *error = LanguageError::NewFormatted( 2737 *error = LanguageError::NewFormatted(
2738 *error, // No previous error. 2738 *error, // No previous error.
2739 Script::Handle(patch.script()), 2739 Script::Handle(patch.script()),
2740 field.token_pos(), 2740 field.token_pos(),
(...skipping 2396 matching lines...) Expand 10 before | Expand all | Expand 10 after
5137 5137
5138 5138
5139 void Function::set_saved_args_desc(const Array& value) const { 5139 void Function::set_saved_args_desc(const Array& value) const {
5140 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || 5140 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher ||
5141 kind() == RawFunction::kInvokeFieldDispatcher); 5141 kind() == RawFunction::kInvokeFieldDispatcher);
5142 ASSERT(raw_ptr()->data_ == Object::null()); 5142 ASSERT(raw_ptr()->data_ == Object::null());
5143 set_data(value); 5143 set_data(value);
5144 } 5144 }
5145 5145
5146 5146
5147 RawField* Function::saved_static_field() const {
5148 ASSERT(kind() == RawFunction::kStaticInitializer);
5149 const Object& obj = Object::Handle(raw_ptr()->data_);
5150 ASSERT(obj.IsField());
5151 return Field::Cast(obj).raw();
5152 }
5153
5154
5155 void Function::set_saved_static_field(const Field& value) const {
5156 ASSERT(kind() == RawFunction::kStaticInitializer);
5157 ASSERT(raw_ptr()->data_ == Object::null());
5158 set_data(value);
5159 }
5160
5161
5162 RawFunction* Function::parent_function() const { 5147 RawFunction* Function::parent_function() const {
5163 if (IsClosureFunction()) { 5148 if (IsClosureFunction()) {
5164 const Object& obj = Object::Handle(raw_ptr()->data_); 5149 const Object& obj = Object::Handle(raw_ptr()->data_);
5165 ASSERT(!obj.IsNull()); 5150 ASSERT(!obj.IsNull());
5166 return ClosureData::Cast(obj).parent_function(); 5151 return ClosureData::Cast(obj).parent_function();
5167 } 5152 }
5168 return Function::null(); 5153 return Function::null();
5169 } 5154 }
5170 5155
5171 5156
5172 void Function::set_parent_function(const Function& value) const { 5157 void Function::set_parent_function(const Function& value) const {
5173 if (IsClosureFunction()) { 5158 if (IsClosureFunction()) {
5174 const Object& obj = Object::Handle(raw_ptr()->data_); 5159 const Object& obj = Object::Handle(raw_ptr()->data_);
5175 ASSERT(!obj.IsNull()); 5160 ASSERT(!obj.IsNull());
5176 ClosureData::Cast(obj).set_parent_function(value); 5161 ClosureData::Cast(obj).set_parent_function(value);
5177 return; 5162 return;
5178 } 5163 }
5179 UNREACHABLE(); 5164 UNREACHABLE();
5180 } 5165 }
5181 5166
5182 5167
5183 RawFunction* Function::implicit_closure_function() const { 5168 RawFunction* Function::implicit_closure_function() const {
5184 if (IsClosureFunction() || 5169 if (IsClosureFunction() ||
5185 IsSignatureFunction() || 5170 IsSignatureFunction() ||
5186 IsStaticInitializerFunction() ||
5187 IsFactory()) { 5171 IsFactory()) {
5188 return Function::null(); 5172 return Function::null();
5189 } 5173 }
5190 const Object& obj = Object::Handle(raw_ptr()->data_); 5174 const Object& obj = Object::Handle(raw_ptr()->data_);
5191 ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction()); 5175 ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction());
5192 return (obj.IsNull() || obj.IsScript()) ? Function::null() 5176 return (obj.IsNull() || obj.IsScript()) ? Function::null()
5193 : Function::Cast(obj).raw(); 5177 : Function::Cast(obj).raw();
5194 } 5178 }
5195 5179
5196 5180
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
5270 break; 5254 break;
5271 case RawFunction::kImplicitGetter: 5255 case RawFunction::kImplicitGetter:
5272 return "kImplicitGetter"; 5256 return "kImplicitGetter";
5273 break; 5257 break;
5274 case RawFunction::kImplicitSetter: 5258 case RawFunction::kImplicitSetter:
5275 return "kImplicitSetter"; 5259 return "kImplicitSetter";
5276 break; 5260 break;
5277 case RawFunction::kImplicitStaticFinalGetter: 5261 case RawFunction::kImplicitStaticFinalGetter:
5278 return "kImplicitStaticFinalGetter"; 5262 return "kImplicitStaticFinalGetter";
5279 break; 5263 break;
5280 case RawFunction::kStaticInitializer:
5281 return "kStaticInitializer";
5282 break;
5283 case RawFunction::kMethodExtractor: 5264 case RawFunction::kMethodExtractor:
5284 return "kMethodExtractor"; 5265 return "kMethodExtractor";
5285 break; 5266 break;
5286 case RawFunction::kNoSuchMethodDispatcher: 5267 case RawFunction::kNoSuchMethodDispatcher:
5287 return "kNoSuchMethodDispatcher"; 5268 return "kNoSuchMethodDispatcher";
5288 break; 5269 break;
5289 case RawFunction::kInvokeFieldDispatcher: 5270 case RawFunction::kInvokeFieldDispatcher:
5290 return "kInvokeFieldDispatcher"; 5271 return "kInvokeFieldDispatcher";
5291 break; 5272 break;
5292 default: 5273 default:
(...skipping 1325 matching lines...) Expand 10 before | Expand all | Expand 10 after
6618 ToFullyQualifiedCString(), 6599 ToFullyQualifiedCString(),
6619 fp, 6600 fp,
6620 SourceFingerprint()); 6601 SourceFingerprint());
6621 return false; 6602 return false;
6622 } 6603 }
6623 } 6604 }
6624 return true; 6605 return true;
6625 } 6606 }
6626 6607
6627 6608
6628 RawFunction* Function::NewStaticInitializer(const Field& field) {
6629 ASSERT(field.is_static());
6630 const String& field_name = String::Handle(field.name());
6631 const String& init_name =
6632 String::Handle(Symbols::New(String::Handle(
6633 String::Concat(Symbols::InitPrefix(), field_name))));
6634 const Function& init_function = Function::ZoneHandle(
6635 Function::New(init_name,
6636 RawFunction::kStaticInitializer,
6637 true, // static
6638 false, // !const
6639 false, // !abstract
6640 false, // !external
6641 false, // !native
6642 Class::Handle(field.owner()),
6643 field.token_pos()));
6644 init_function.set_result_type(AbstractType::Handle(field.type()));
6645 // Static initializer functions are generated by the VM and are therfore
6646 // hidden from the user. Since they are only executed once, we avoid
6647 // optimizing and inlining them. After the field is initialized, the
6648 // optimizing compiler can eliminate the call to the static initializer
6649 // via constant folding.
6650 init_function.set_is_visible(false);
6651 init_function.SetIsOptimizable(false);
6652 init_function.set_is_inlinable(false);
6653 init_function.set_saved_static_field(field);
6654 return init_function.raw();
6655 }
6656
6657
6658 const char* Function::ToCString() const { 6609 const char* Function::ToCString() const {
6659 const char* static_str = is_static() ? " static" : ""; 6610 const char* static_str = is_static() ? " static" : "";
6660 const char* abstract_str = is_abstract() ? " abstract" : ""; 6611 const char* abstract_str = is_abstract() ? " abstract" : "";
6661 const char* kind_str = NULL; 6612 const char* kind_str = NULL;
6662 const char* const_str = is_const() ? " const" : ""; 6613 const char* const_str = is_const() ? " const" : "";
6663 switch (kind()) { 6614 switch (kind()) {
6664 case RawFunction::kRegularFunction: 6615 case RawFunction::kRegularFunction:
6665 case RawFunction::kClosureFunction: 6616 case RawFunction::kClosureFunction:
6666 case RawFunction::kGetterFunction: 6617 case RawFunction::kGetterFunction:
6667 case RawFunction::kSetterFunction: 6618 case RawFunction::kSetterFunction:
6668 kind_str = ""; 6619 kind_str = "";
6669 break; 6620 break;
6670 case RawFunction::kSignatureFunction: 6621 case RawFunction::kSignatureFunction:
6671 kind_str = " signature"; 6622 kind_str = " signature";
6672 break; 6623 break;
6673 case RawFunction::kConstructor: 6624 case RawFunction::kConstructor:
6674 kind_str = is_static() ? " factory" : " constructor"; 6625 kind_str = is_static() ? " factory" : " constructor";
6675 break; 6626 break;
6676 case RawFunction::kImplicitGetter: 6627 case RawFunction::kImplicitGetter:
6677 kind_str = " getter"; 6628 kind_str = " getter";
6678 break; 6629 break;
6679 case RawFunction::kImplicitSetter: 6630 case RawFunction::kImplicitSetter:
6680 kind_str = " setter"; 6631 kind_str = " setter";
6681 break; 6632 break;
6682 case RawFunction::kStaticInitializer:
6683 kind_str = " static-initializer";
6684 break;
6685 case RawFunction::kImplicitStaticFinalGetter: 6633 case RawFunction::kImplicitStaticFinalGetter:
6686 kind_str = " static-final-getter"; 6634 kind_str = " static-final-getter";
6687 break; 6635 break;
6688 case RawFunction::kMethodExtractor: 6636 case RawFunction::kMethodExtractor:
6689 kind_str = " method-extractor"; 6637 kind_str = " method-extractor";
6690 break; 6638 break;
6691 case RawFunction::kNoSuchMethodDispatcher: 6639 case RawFunction::kNoSuchMethodDispatcher:
6692 kind_str = " no-such-method-dispatcher"; 6640 kind_str = " no-such-method-dispatcher";
6693 break; 6641 break;
6694 case RawFunction::kInvokeFieldDispatcher: 6642 case RawFunction::kInvokeFieldDispatcher:
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
7210 } 7158 }
7211 7159
7212 7160
7213 bool Field::IsUninitialized() const { 7161 bool Field::IsUninitialized() const {
7214 const Instance& value = Instance::Handle(raw_ptr()->value_); 7162 const Instance& value = Instance::Handle(raw_ptr()->value_);
7215 ASSERT(value.raw() != Object::transition_sentinel().raw()); 7163 ASSERT(value.raw() != Object::transition_sentinel().raw());
7216 return value.raw() == Object::sentinel().raw(); 7164 return value.raw() == Object::sentinel().raw();
7217 } 7165 }
7218 7166
7219 7167
7168 void Field::EvaluateInitializer() const {
7169 ASSERT(is_static());
7170 if (value() == Object::sentinel().raw()) {
7171 set_value(Object::transition_sentinel());
7172 Object& value = Object::Handle(Compiler::EvaluateStaticInitializer(*this));
7173 if (value.IsError()) {
7174 set_value(Object::null_instance());
7175 Exceptions::PropagateError(Error::Cast(value));
7176 UNREACHABLE();
7177 }
7178 ASSERT(value.IsNull() || value.IsInstance());
7179 set_value(value.IsNull() ? Instance::null_instance()
7180 : Instance::Cast(value));
7181 return;
7182 } else if (value() == Object::transition_sentinel().raw()) {
7183 set_value(Object::null_instance());
7184 const Array& ctor_args = Array::Handle(Array::New(1));
7185 const String& field_name = String::Handle(name());
7186 ctor_args.SetAt(0, field_name);
7187 Exceptions::ThrowByType(Exceptions::kCyclicInitializationError, ctor_args);
7188 UNREACHABLE();
7189 return;
7190 }
7191 UNREACHABLE();
7192 }
7193
7194
7220 static intptr_t GetListLength(const Object& value) { 7195 static intptr_t GetListLength(const Object& value) {
7221 if (value.IsTypedData()) { 7196 if (value.IsTypedData()) {
7222 const TypedData& list = TypedData::Cast(value); 7197 const TypedData& list = TypedData::Cast(value);
7223 return list.Length(); 7198 return list.Length();
7224 } else if (value.IsArray()) { 7199 } else if (value.IsArray()) {
7225 const Array& list = Array::Cast(value); 7200 const Array& list = Array::Cast(value);
7226 return list.Length(); 7201 return list.Length();
7227 } else if (value.IsGrowableObjectArray()) { 7202 } else if (value.IsGrowableObjectArray()) {
7228 // List length is variable. 7203 // List length is variable.
7229 return Field::kNoFixedLength; 7204 return Field::kNoFixedLength;
(...skipping 12186 matching lines...) Expand 10 before | Expand all | Expand 10 after
19416 return tag_label.ToCString(); 19391 return tag_label.ToCString();
19417 } 19392 }
19418 19393
19419 19394
19420 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 19395 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
19421 Instance::PrintJSONImpl(stream, ref); 19396 Instance::PrintJSONImpl(stream, ref);
19422 } 19397 }
19423 19398
19424 19399
19425 } // namespace dart 19400 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698