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

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

Issue 1234883005: Implement tear-off closure operator # (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Reuse previously created closures Created 5 years, 5 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
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 7369 matching lines...) Expand 10 before | Expand all | Expand 10 after
7380 jsobj.AddProperty("_guardLength", guarded_list_length()); 7380 jsobj.AddProperty("_guardLength", guarded_list_length());
7381 } 7381 }
7382 const Class& origin_cls = Class::Handle(origin()); 7382 const Class& origin_cls = Class::Handle(origin());
7383 const Script& script = Script::Handle(origin_cls.script()); 7383 const Script& script = Script::Handle(origin_cls.script());
7384 if (!script.IsNull()) { 7384 if (!script.IsNull()) {
7385 jsobj.AddLocation(script, token_pos()); 7385 jsobj.AddLocation(script, token_pos());
7386 } 7386 }
7387 } 7387 }
7388 7388
7389 7389
7390 // Build a closure object that gets the contents of a static field f
7391 // and cache the closure in a newly created static field named #f.
7392 RawInstance* Field::GetterClosure() const {
7393 ASSERT(is_static());
7394 const Class& field_owner = Class::Handle(owner());
7395
7396 String& closure_name = String::Handle();
Florian Schneider 2015/07/22 08:25:53 String& closure_name = String::Handle(this->name()
hausner 2015/07/22 18:41:09 vertigo prevented :)
7397 closure_name = this->name();
7398 closure_name = Symbols::FromConcat(Symbols::HashMark(), closure_name);
7399
7400 Field& closure_field = Field::Handle();
7401 closure_field = field_owner.LookupStaticField(closure_name);
7402 if (!closure_field.IsNull()) {
7403 ASSERT(closure_field.is_static());
7404 const Instance& closure = Instance::Handle(closure_field.value());
7405 ASSERT(!closure.IsNull());
7406 ASSERT(closure.IsClosure());
7407 return closure.raw();
7408 }
7409
7410 // This is the first time a getter closure for this field is requested.
7411 // Create the closure and a new static field in which the closure is
7412 // stored.
7413 const char* field_name = String::Handle(name()).ToCString();
7414 String& expr_src = String::Handle(
7415 String::NewFormatted("() { return %s; }", field_name));
7416 Object& result =
7417 Object::Handle(field_owner.Evaluate(expr_src,
7418 Object::empty_array(),
7419 Object::empty_array()));
7420 ASSERT(result.IsInstance());
7421 // The caller may expect the closure to be allocated in old space. Copy
7422 // the result here, since Object::Clone() is a private method.
7423 result = Object::Clone(result, Heap::kOld);
7424
7425 closure_field = Field::New(closure_name,
7426 true, // is_static
7427 true, // is_final
7428 true, // is_const
7429 true, // is_synthetic
7430 field_owner,
7431 this->token_pos());
7432 closure_field.set_value(Instance::Cast(result));
7433 closure_field.set_type(Type::Handle(Type::DynamicType()));
7434 field_owner.AddField(closure_field);
7435
7436 return Instance::RawCast(result.raw());
7437 }
7438
7439
7440 // Build a closure object that sets the contents of a static field f
7441 // and cache the closure in a newly created static field named #f=.
7442 RawInstance* Field::SetterClosure() const {
7443 ASSERT(is_static());
7444 const Class& field_owner = Class::Handle(owner());
7445
7446 String& closure_name = String::Handle();
Florian Schneider 2015/07/22 08:25:53 String& closure_name = String::Handle(this->name()
hausner 2015/07/22 18:41:09 Done.
7447 closure_name = this->name();
7448 closure_name = String::Concat(closure_name, Symbols::Equals());
7449 closure_name = Symbols::FromConcat(Symbols::HashMark(), closure_name);
7450
7451 Field& closure_field = Field::Handle();
7452 closure_field = field_owner.LookupStaticField(closure_name);
7453 if (!closure_field.IsNull()) {
7454 ASSERT(closure_field.is_static());
7455 const Instance& closure = Instance::Handle(closure_field.value());
7456 ASSERT(!closure.IsNull());
7457 ASSERT(closure.IsClosure());
7458 return closure.raw();
7459 }
7460
7461 // This is the first time a getter closure for this field is requested.
Florian Schneider 2015/07/22 08:25:53 Update comment for setter closure.
hausner 2015/07/22 18:41:09 Done.
7462 // Create the closure and a new static field in which the closure is
7463 // stored.
7464 const String& field_name = String::Handle(name());
7465 String& expr_src = String::Handle();
7466 if (field_owner.IsTopLevel()) {
Florian Schneider 2015/07/22 08:25:54 Why is the top-level case needed here, and not for
hausner 2015/07/22 18:41:09 The class name is added to avoid name conflicts wh
7467 expr_src = String::NewFormatted("(value) { return %s = value; }",
7468 field_name.ToCString());
7469 } else {
7470 const String& owner_name = String::Handle(field_owner.Name());
7471 expr_src = String::NewFormatted("(value) { return %s.%s = value; }",
7472 owner_name.ToCString(),
7473 field_name.ToCString());
7474 }
7475 Object& result =
7476 Object::Handle(field_owner.Evaluate(expr_src,
7477 Object::empty_array(),
7478 Object::empty_array()));
7479 ASSERT(result.IsInstance());
7480 // The caller may expect the closure to be allocated in old space. Copy
7481 // the result here, since Object::Clone() is a private method.
7482 result = Object::Clone(result, Heap::kOld);
7483
7484 closure_field = Field::New(closure_name,
7485 true, // is_static
7486 true, // is_final
7487 true, // is_const
7488 true, // is_synthetic
7489 field_owner,
7490 this->token_pos());
7491 closure_field.set_value(Instance::Cast(result));
7492 closure_field.set_type(Type::Handle(Type::DynamicType()));
7493 field_owner.AddField(closure_field);
Florian Schneider 2015/07/22 08:25:54 Maybe factor the creation of the field into a file
hausner 2015/07/22 18:41:09 Factoring out 4 lines of code that would require 3
7494
7495 return Instance::RawCast(result.raw());
7496 }
7497
7498
7390 RawArray* Field::dependent_code() const { 7499 RawArray* Field::dependent_code() const {
7391 return raw_ptr()->dependent_code_; 7500 return raw_ptr()->dependent_code_;
7392 } 7501 }
7393 7502
7394 7503
7395 void Field::set_dependent_code(const Array& array) const { 7504 void Field::set_dependent_code(const Array& array) const {
7396 StorePointer(&raw_ptr()->dependent_code_, array.raw()); 7505 StorePointer(&raw_ptr()->dependent_code_, array.raw());
7397 } 7506 }
7398 7507
7399 7508
(...skipping 13810 matching lines...) Expand 10 before | Expand all | Expand 10 after
21210 return tag_label.ToCString(); 21319 return tag_label.ToCString();
21211 } 21320 }
21212 21321
21213 21322
21214 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 21323 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
21215 Instance::PrintJSONImpl(stream, ref); 21324 Instance::PrintJSONImpl(stream, ref);
21216 } 21325 }
21217 21326
21218 21327
21219 } // namespace dart 21328 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.h » ('j') | runtime/vm/parser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698