| 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();
|
| }
|
| }
|
|
|