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

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
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2763 matching lines...) Expand 10 before | Expand all | Expand 10 after
2774 orig_list = fields(); 2774 orig_list = fields();
2775 orig_len = orig_list.Length(); 2775 orig_len = orig_list.Length();
2776 patch_list = patch.fields(); 2776 patch_list = patch.fields();
2777 patch_len = patch_list.Length(); 2777 patch_len = patch_list.Length();
2778 2778
2779 Field& field = Field::Handle(); 2779 Field& field = Field::Handle();
2780 Field& orig_field = Field::Handle(); 2780 Field& orig_field = Field::Handle();
2781 new_list = Array::New(patch_len + orig_len); 2781 new_list = Array::New(patch_len + orig_len);
2782 for (intptr_t i = 0; i < patch_len; i++) { 2782 for (intptr_t i = 0; i < patch_len; i++) {
2783 field ^= patch_list.At(i); 2783 field ^= patch_list.At(i);
2784 field.set_owner(*this); 2784 field.set_owner(patch_class);
2785 member_name = field.name(); 2785 member_name = field.name();
2786 // TODO(iposva): Verify non-public fields only. 2786 // TODO(iposva): Verify non-public fields only.
2787 2787
2788 // Verify no duplicate additions. 2788 // Verify no duplicate additions.
2789 orig_field ^= LookupField(member_name); 2789 orig_field ^= LookupField(member_name);
2790 if (!orig_field.IsNull()) { 2790 if (!orig_field.IsNull()) {
2791 *error = LanguageError::NewFormatted( 2791 *error = LanguageError::NewFormatted(
2792 *error, // No previous error. 2792 *error, // No previous error.
2793 Script::Handle(patch.script()), 2793 Script::Handle(patch.script()),
2794 field.token_pos(), 2794 field.token_pos(),
(...skipping 2405 matching lines...) Expand 10 before | Expand all | Expand 10 after
5200 5200
5201 5201
5202 void Function::set_saved_args_desc(const Array& value) const { 5202 void Function::set_saved_args_desc(const Array& value) const {
5203 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || 5203 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher ||
5204 kind() == RawFunction::kInvokeFieldDispatcher); 5204 kind() == RawFunction::kInvokeFieldDispatcher);
5205 ASSERT(raw_ptr()->data_ == Object::null()); 5205 ASSERT(raw_ptr()->data_ == Object::null());
5206 set_data(value); 5206 set_data(value);
5207 } 5207 }
5208 5208
5209 5209
5210 RawField* Function::saved_static_field() const {
5211 ASSERT(kind() == RawFunction::kStaticInitializer);
5212 const Object& obj = Object::Handle(raw_ptr()->data_);
5213 ASSERT(obj.IsField());
5214 return Field::Cast(obj).raw();
5215 }
5216
5217
5218 void Function::set_saved_static_field(const Field& value) const {
5219 ASSERT(kind() == RawFunction::kStaticInitializer);
5220 ASSERT(raw_ptr()->data_ == Object::null());
5221 set_data(value);
5222 }
5223
5224
5225 RawFunction* Function::parent_function() const { 5210 RawFunction* Function::parent_function() const {
5226 if (IsClosureFunction()) { 5211 if (IsClosureFunction()) {
5227 const Object& obj = Object::Handle(raw_ptr()->data_); 5212 const Object& obj = Object::Handle(raw_ptr()->data_);
5228 ASSERT(!obj.IsNull()); 5213 ASSERT(!obj.IsNull());
5229 return ClosureData::Cast(obj).parent_function(); 5214 return ClosureData::Cast(obj).parent_function();
5230 } 5215 }
5231 return Function::null(); 5216 return Function::null();
5232 } 5217 }
5233 5218
5234 5219
5235 void Function::set_parent_function(const Function& value) const { 5220 void Function::set_parent_function(const Function& value) const {
5236 if (IsClosureFunction()) { 5221 if (IsClosureFunction()) {
5237 const Object& obj = Object::Handle(raw_ptr()->data_); 5222 const Object& obj = Object::Handle(raw_ptr()->data_);
5238 ASSERT(!obj.IsNull()); 5223 ASSERT(!obj.IsNull());
5239 ClosureData::Cast(obj).set_parent_function(value); 5224 ClosureData::Cast(obj).set_parent_function(value);
5240 return; 5225 return;
5241 } 5226 }
5242 UNREACHABLE(); 5227 UNREACHABLE();
5243 } 5228 }
5244 5229
5245 5230
5246 RawFunction* Function::implicit_closure_function() const { 5231 RawFunction* Function::implicit_closure_function() const {
5247 if (IsClosureFunction() || 5232 if (IsClosureFunction() ||
5248 IsSignatureFunction() || 5233 IsSignatureFunction() ||
5249 IsStaticInitializerFunction() ||
5250 IsFactory()) { 5234 IsFactory()) {
5251 return Function::null(); 5235 return Function::null();
5252 } 5236 }
5253 const Object& obj = Object::Handle(raw_ptr()->data_); 5237 const Object& obj = Object::Handle(raw_ptr()->data_);
5254 ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction()); 5238 ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction());
5255 return (obj.IsNull() || obj.IsScript()) ? Function::null() 5239 return (obj.IsNull() || obj.IsScript()) ? Function::null()
5256 : Function::Cast(obj).raw(); 5240 : Function::Cast(obj).raw();
5257 } 5241 }
5258 5242
5259 5243
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
5333 break; 5317 break;
5334 case RawFunction::kImplicitGetter: 5318 case RawFunction::kImplicitGetter:
5335 return "kImplicitGetter"; 5319 return "kImplicitGetter";
5336 break; 5320 break;
5337 case RawFunction::kImplicitSetter: 5321 case RawFunction::kImplicitSetter:
5338 return "kImplicitSetter"; 5322 return "kImplicitSetter";
5339 break; 5323 break;
5340 case RawFunction::kImplicitStaticFinalGetter: 5324 case RawFunction::kImplicitStaticFinalGetter:
5341 return "kImplicitStaticFinalGetter"; 5325 return "kImplicitStaticFinalGetter";
5342 break; 5326 break;
5343 case RawFunction::kStaticInitializer:
5344 return "kStaticInitializer";
5345 break;
5346 case RawFunction::kMethodExtractor: 5327 case RawFunction::kMethodExtractor:
5347 return "kMethodExtractor"; 5328 return "kMethodExtractor";
5348 break; 5329 break;
5349 case RawFunction::kNoSuchMethodDispatcher: 5330 case RawFunction::kNoSuchMethodDispatcher:
5350 return "kNoSuchMethodDispatcher"; 5331 return "kNoSuchMethodDispatcher";
5351 break; 5332 break;
5352 case RawFunction::kInvokeFieldDispatcher: 5333 case RawFunction::kInvokeFieldDispatcher:
5353 return "kInvokeFieldDispatcher"; 5334 return "kInvokeFieldDispatcher";
5354 break; 5335 break;
5355 default: 5336 default:
(...skipping 1325 matching lines...) Expand 10 before | Expand all | Expand 10 after
6681 ToFullyQualifiedCString(), 6662 ToFullyQualifiedCString(),
6682 fp, 6663 fp,
6683 SourceFingerprint()); 6664 SourceFingerprint());
6684 return false; 6665 return false;
6685 } 6666 }
6686 } 6667 }
6687 return true; 6668 return true;
6688 } 6669 }
6689 6670
6690 6671
6691 RawFunction* Function::NewStaticInitializer(const Field& field) {
6692 ASSERT(field.is_static());
6693 const String& field_name = String::Handle(field.name());
6694 const String& init_name =
6695 String::Handle(Symbols::New(String::Handle(
6696 String::Concat(Symbols::InitPrefix(), field_name))));
6697 const Function& init_function = Function::ZoneHandle(
6698 Function::New(init_name,
6699 RawFunction::kStaticInitializer,
6700 true, // static
6701 false, // !const
6702 false, // !abstract
6703 false, // !external
6704 false, // !native
6705 Class::Handle(field.owner()),
6706 field.token_pos()));
6707 init_function.set_result_type(AbstractType::Handle(field.type()));
6708 // Static initializer functions are generated by the VM and are therfore
6709 // hidden from the user. Since they are only executed once, we avoid
6710 // optimizing and inlining them. After the field is initialized, the
6711 // optimizing compiler can eliminate the call to the static initializer
6712 // via constant folding.
6713 init_function.set_is_visible(false);
6714 init_function.SetIsOptimizable(false);
6715 init_function.set_is_inlinable(false);
6716 init_function.set_saved_static_field(field);
6717 return init_function.raw();
6718 }
6719
6720
6721 const char* Function::ToCString() const { 6672 const char* Function::ToCString() const {
6722 const char* static_str = is_static() ? " static" : ""; 6673 const char* static_str = is_static() ? " static" : "";
6723 const char* abstract_str = is_abstract() ? " abstract" : ""; 6674 const char* abstract_str = is_abstract() ? " abstract" : "";
6724 const char* kind_str = NULL; 6675 const char* kind_str = NULL;
6725 const char* const_str = is_const() ? " const" : ""; 6676 const char* const_str = is_const() ? " const" : "";
6726 switch (kind()) { 6677 switch (kind()) {
6727 case RawFunction::kRegularFunction: 6678 case RawFunction::kRegularFunction:
6728 case RawFunction::kClosureFunction: 6679 case RawFunction::kClosureFunction:
6729 case RawFunction::kGetterFunction: 6680 case RawFunction::kGetterFunction:
6730 case RawFunction::kSetterFunction: 6681 case RawFunction::kSetterFunction:
6731 kind_str = ""; 6682 kind_str = "";
6732 break; 6683 break;
6733 case RawFunction::kSignatureFunction: 6684 case RawFunction::kSignatureFunction:
6734 kind_str = " signature"; 6685 kind_str = " signature";
6735 break; 6686 break;
6736 case RawFunction::kConstructor: 6687 case RawFunction::kConstructor:
6737 kind_str = is_static() ? " factory" : " constructor"; 6688 kind_str = is_static() ? " factory" : " constructor";
6738 break; 6689 break;
6739 case RawFunction::kImplicitGetter: 6690 case RawFunction::kImplicitGetter:
6740 kind_str = " getter"; 6691 kind_str = " getter";
6741 break; 6692 break;
6742 case RawFunction::kImplicitSetter: 6693 case RawFunction::kImplicitSetter:
6743 kind_str = " setter"; 6694 kind_str = " setter";
6744 break; 6695 break;
6745 case RawFunction::kStaticInitializer:
6746 kind_str = " static-initializer";
6747 break;
6748 case RawFunction::kImplicitStaticFinalGetter: 6696 case RawFunction::kImplicitStaticFinalGetter:
6749 kind_str = " static-final-getter"; 6697 kind_str = " static-final-getter";
6750 break; 6698 break;
6751 case RawFunction::kMethodExtractor: 6699 case RawFunction::kMethodExtractor:
6752 kind_str = " method-extractor"; 6700 kind_str = " method-extractor";
6753 break; 6701 break;
6754 case RawFunction::kNoSuchMethodDispatcher: 6702 case RawFunction::kNoSuchMethodDispatcher:
6755 kind_str = " no-such-method-dispatcher"; 6703 kind_str = " no-such-method-dispatcher";
6756 break; 6704 break;
6757 case RawFunction::kInvokeFieldDispatcher: 6705 case RawFunction::kInvokeFieldDispatcher:
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
7273 } 7221 }
7274 7222
7275 7223
7276 bool Field::IsUninitialized() const { 7224 bool Field::IsUninitialized() const {
7277 const Instance& value = Instance::Handle(raw_ptr()->value_); 7225 const Instance& value = Instance::Handle(raw_ptr()->value_);
7278 ASSERT(value.raw() != Object::transition_sentinel().raw()); 7226 ASSERT(value.raw() != Object::transition_sentinel().raw());
7279 return value.raw() == Object::sentinel().raw(); 7227 return value.raw() == Object::sentinel().raw();
7280 } 7228 }
7281 7229
7282 7230
7231 void Field::EvaluateInitializer() const {
7232 ASSERT(is_static());
7233 if (value() == Object::sentinel().raw()) {
7234 set_value(Object::transition_sentinel());
7235 Object& value = Object::Handle(Compiler::EvaluateStaticInitializer(*this));
7236 if (value.IsError()) {
7237 set_value(Object::null_instance());
7238 Exceptions::PropagateError(Error::Cast(value));
7239 UNREACHABLE();
7240 }
7241 ASSERT(value.IsNull() || value.IsInstance());
7242 set_value(value.IsNull() ? Instance::null_instance()
7243 : Instance::Cast(value));
7244 return;
7245 } else if (value() == Object::transition_sentinel().raw()) {
7246 set_value(Object::null_instance());
7247 const Array& ctor_args = Array::Handle(Array::New(1));
7248 const String& field_name = String::Handle(name());
7249 ctor_args.SetAt(0, field_name);
7250 Exceptions::ThrowByType(Exceptions::kCyclicInitializationError, ctor_args);
7251 UNREACHABLE();
7252 return;
7253 }
7254 UNREACHABLE();
7255 }
7256
7257
7283 static intptr_t GetListLength(const Object& value) { 7258 static intptr_t GetListLength(const Object& value) {
7284 if (value.IsTypedData()) { 7259 if (value.IsTypedData()) {
7285 const TypedData& list = TypedData::Cast(value); 7260 const TypedData& list = TypedData::Cast(value);
7286 return list.Length(); 7261 return list.Length();
7287 } else if (value.IsArray()) { 7262 } else if (value.IsArray()) {
7288 const Array& list = Array::Cast(value); 7263 const Array& list = Array::Cast(value);
7289 return list.Length(); 7264 return list.Length();
7290 } else if (value.IsGrowableObjectArray()) { 7265 } else if (value.IsGrowableObjectArray()) {
7291 // List length is variable. 7266 // List length is variable.
7292 return Field::kNoFixedLength; 7267 return Field::kNoFixedLength;
(...skipping 12190 matching lines...) Expand 10 before | Expand all | Expand 10 after
19483 return tag_label.ToCString(); 19458 return tag_label.ToCString();
19484 } 19459 }
19485 19460
19486 19461
19487 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 19462 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
19488 Instance::PrintJSONImpl(stream, ref); 19463 Instance::PrintJSONImpl(stream, ref);
19489 } 19464 }
19490 19465
19491 19466
19492 } // namespace dart 19467 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698