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

Unified 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: Address review comments 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index f674cd4b80669a4b9a64444e12601acb5135aed4..6491077caa7e96ed1d7897a6420dcecb2366daba 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -7386,6 +7386,73 @@ void Field::PrintJSONImpl(JSONStream* stream, bool ref) const {
}
}
+// Build a closure object that gets (or sets) the contents of a static
+// field f and cache the closure in a newly created static field
+// named #f (or #f= in case of a setter).
+RawInstance* Field::AccessorClosure(bool make_setter) const {
+ ASSERT(is_static());
+ const Class& field_owner = Class::Handle(owner());
+
+ String& closure_name = String::Handle(this->name());
+ closure_name = Symbols::FromConcat(Symbols::HashMark(), closure_name);
+ if (make_setter) {
+ closure_name = Symbols::FromConcat(Symbols::HashMark(), closure_name);
+ }
+
+ Field& closure_field = Field::Handle();
+ closure_field = field_owner.LookupStaticField(closure_name);
+ if (!closure_field.IsNull()) {
+ ASSERT(closure_field.is_static());
+ const Instance& closure = Instance::Handle(closure_field.value());
+ ASSERT(!closure.IsNull());
+ ASSERT(closure.IsClosure());
+ return closure.raw();
+ }
+
+ // This is the first time a closure for this field is requested.
+ // Create the closure and a new static field in which it is stored.
+ const char* field_name = String::Handle(name()).ToCString();
+ String& expr_src = String::Handle();
+ if (make_setter) {
+ expr_src =
+ String::NewFormatted("(%s_) { return %s = %s_; }",
+ field_name, field_name, field_name);
+ } else {
+ expr_src = String::NewFormatted("() { return %s; }", field_name);
+ }
+ Object& result =
+ Object::Handle(field_owner.Evaluate(expr_src,
+ Object::empty_array(),
+ Object::empty_array()));
+ ASSERT(result.IsInstance());
+ // The caller may expect the closure to be allocated in old space. Copy
+ // the result here, since Object::Clone() is a private method.
+ result = Object::Clone(result, Heap::kOld);
+
+ closure_field = Field::New(closure_name,
+ true, // is_static
+ true, // is_final
+ true, // is_const
+ true, // is_synthetic
+ field_owner,
+ this->token_pos());
+ closure_field.set_value(Instance::Cast(result));
+ closure_field.set_type(Type::Handle(Type::DynamicType()));
+ field_owner.AddField(closure_field);
+
+ return Instance::RawCast(result.raw());
+}
+
+
+RawInstance* Field::GetterClosure() const {
+ return AccessorClosure(false);
+}
+
+
+RawInstance* Field::SetterClosure() const {
+ return AccessorClosure(true);
+}
+
RawArray* Field::dependent_code() const {
return raw_ptr()->dependent_code_;
« 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