Index: runtime/vm/object.cc |
=================================================================== |
--- runtime/vm/object.cc (revision 9490) |
+++ runtime/vm/object.cc (working copy) |
@@ -321,6 +321,9 @@ |
// Therefore, it cannot have a heap allocated name (the name is hard coded, |
// see GetSingletonClassIndex) and its array fields cannot be set to the empty |
// array, but remain null. |
+ // |
+ // TODO(turnidge): Once the empty array is allocated in the vm |
+ // isolate, use it here. |
cls = Class::New<Instance>(kDynamicClassId); |
cls.set_is_finalized(); |
cls.set_is_interface(); |
@@ -1925,26 +1928,51 @@ |
} |
-static bool MatchesPrivateName(const String& name, const String& private_name) { |
- intptr_t name_len = name.Length(); |
- intptr_t private_len = private_name.Length(); |
- // The private_name must at least have room for the separator and one key |
- // character. |
- if ((name_len < (private_len + 2)) || (name_len == 0) || (private_len == 0)) { |
+// Check to see if mangled_name is equal to bare_name once the private |
+// key separator is stripped from mangled_name. |
+// |
+// Things are made more complicated by the fact that constructors are |
+// added *after* the private suffix, so "foo@123.named" should match |
+// "foo.named". |
+// |
+// Also, the private suffix can occur more than once in the name, as in: |
+// |
+// _ReceivePortImpl@6be832b._internal@6be832b |
+// |
+bool EqualsIgnoringPrivate(const String& mangled_name, |
+ const String& bare_name) { |
+ intptr_t mangled_len = mangled_name.Length(); |
+ intptr_t bare_len = bare_name.Length(); |
+ if (mangled_len < bare_len) { |
+ // No way they can match. |
return false; |
} |
- // Check for the private key separator. |
- if (name.CharAt(private_len) != Scanner::kPrivateKeySeparator) { |
- return false; |
- } |
+ intptr_t mangled_pos = 0; |
+ intptr_t bare_pos = 0; |
+ while (mangled_pos < mangled_len) { |
+ int32_t mangled_char = mangled_name.CharAt(mangled_pos); |
+ mangled_pos++; |
- for (intptr_t i = 0; i < private_len; i++) { |
- if (name.CharAt(i) != private_name.CharAt(i)) { |
+ if (mangled_char == Scanner::kPrivateKeySeparator) { |
+ // Consume a private key separator. |
+ while (mangled_pos < mangled_len && |
+ mangled_name.CharAt(mangled_pos) != '.') { |
+ mangled_pos++; |
+ } |
+ |
+ // Resume matching characters. |
+ continue; |
+ } |
+ if (bare_pos == bare_len || mangled_char != bare_name.CharAt(bare_pos)) { |
return false; |
} |
+ bare_pos++; |
} |
- return true; |
+ |
+ // The strings match if we have reached the end of both strings. |
+ return (mangled_pos == mangled_len && |
+ bare_pos == bare_len); |
} |
@@ -1957,7 +1985,8 @@ |
for (intptr_t i = 0; i < len; i++) { |
function ^= funcs.At(i); |
function_name ^= function.name(); |
- if (function_name.Equals(name) || MatchesPrivateName(function_name, name)) { |
+ if (function_name.Equals(name) || |
+ EqualsIgnoringPrivate(function_name, name)) { |
return function.raw(); |
} |
} |
@@ -2059,7 +2088,7 @@ |
for (intptr_t i = 0; i < len; i++) { |
field ^= flds.At(i); |
field_name ^= field.name(); |
- if (field_name.Equals(name) || MatchesPrivateName(field_name, name)) { |
+ if (field_name.Equals(name) || EqualsIgnoringPrivate(field_name, name)) { |
return field.raw(); |
} |
} |