| OLD | NEW |
| 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 155 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 156 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 156 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 157 RawClass* Object::unhandled_exception_class_ = | 157 RawClass* Object::unhandled_exception_class_ = |
| 158 reinterpret_cast<RawClass*>(RAW_NULL); | 158 reinterpret_cast<RawClass*>(RAW_NULL); |
| 159 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 159 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 160 | 160 |
| 161 | 161 |
| 162 const double MegamorphicCache::kLoadFactor = 0.75; | 162 const double MegamorphicCache::kLoadFactor = 0.75; |
| 163 | 163 |
| 164 | 164 |
| 165 static void AppendSubString(Zone* zone, |
| 166 GrowableArray<const char*>* segments, |
| 167 const char* name, |
| 168 intptr_t start_pos, intptr_t len) { |
| 169 char* segment = zone->Alloc<char>(len + 1); // '\0'-terminated. |
| 170 memmove(segment, name + start_pos, len); |
| 171 segment[len] = '\0'; |
| 172 segments->Add(segment); |
| 173 } |
| 174 |
| 175 |
| 176 static const char* MergeSubStrings(Zone* zone, |
| 177 const GrowableArray<const char*>& segments, |
| 178 intptr_t alloc_len) { |
| 179 char* result = zone->Alloc<char>(alloc_len + 1); // '\0'-terminated |
| 180 intptr_t pos = 0; |
| 181 for (intptr_t k = 0; k < segments.length(); k++) { |
| 182 const char* piece = segments[k]; |
| 183 const intptr_t piece_len = strlen(segments[k]); |
| 184 memmove(result + pos, piece, piece_len); |
| 185 pos += piece_len; |
| 186 ASSERT(pos <= alloc_len); |
| 187 } |
| 188 result[pos] = '\0'; |
| 189 return result; |
| 190 } |
| 191 |
| 192 |
| 165 // Takes a vm internal name and makes it suitable for external user. | 193 // Takes a vm internal name and makes it suitable for external user. |
| 166 // | 194 // |
| 167 // Examples: | 195 // Examples: |
| 168 // | 196 // |
| 169 // Internal getter and setter prefixes are changed: | 197 // Internal getter and setter prefixes are changed: |
| 170 // | 198 // |
| 171 // get:foo -> foo | 199 // get:foo -> foo |
| 172 // set:foo -> foo= | 200 // set:foo -> foo= |
| 173 // | 201 // |
| 174 // Private name mangling is removed, possibly multiple times: | 202 // Private name mangling is removed, possibly multiple times: |
| 175 // | 203 // |
| 176 // _ReceivePortImpl@6be832b -> _ReceivePortImpl | 204 // _ReceivePortImpl@709387912 -> _ReceivePortImpl |
| 177 // _ReceivePortImpl@6be832b._internal@6be832b -> _ReceivePortImpl._internal | 205 // _ReceivePortImpl@709387912._internal@709387912 -> |
| 178 // _C@0x2b4ab9cc&_E@0x2b4ab9cc&_F@0x2b4ab9cc -> _C&_E&_F | 206 // _ReceivePortImpl._internal |
| 207 // _C@6328321&_E@6328321&_F@6328321 -> _C&_E&_F |
| 179 // | 208 // |
| 180 // The trailing . on the default constructor name is dropped: | 209 // The trailing . on the default constructor name is dropped: |
| 181 // | 210 // |
| 182 // List. -> List | 211 // List. -> List |
| 183 // | 212 // |
| 184 // And so forth: | 213 // And so forth: |
| 185 // | 214 // |
| 186 // get:foo@6be832b -> foo | 215 // get:foo@6328321 -> foo |
| 187 // _MyClass@6b3832b. -> _MyClass | 216 // _MyClass@6328321. -> _MyClass |
| 188 // _MyClass@6b3832b.named -> _MyClass.named | 217 // _MyClass@6328321.named -> _MyClass.named |
| 189 // | 218 // |
| 190 RawString* String::IdentifierPrettyName(const String& name) { | 219 RawString* String::IdentifierPrettyName(const String& name) { |
| 220 Zone* zone = Thread::Current()->zone(); |
| 191 if (name.Equals(Symbols::TopLevel())) { | 221 if (name.Equals(Symbols::TopLevel())) { |
| 192 // Name of invisible top-level class. | 222 // Name of invisible top-level class. |
| 193 return Symbols::Empty().raw(); | 223 return Symbols::Empty().raw(); |
| 194 } | 224 } |
| 195 | 225 |
| 226 const char* cname = name.ToCString(); |
| 227 ASSERT(strlen(cname) == static_cast<size_t>(name.Length())); |
| 228 const intptr_t name_len = name.Length(); |
| 196 // First remove all private name mangling. | 229 // First remove all private name mangling. |
| 197 String& unmangled_name = String::Handle(Symbols::Empty().raw()); | |
| 198 String& segment = String::Handle(); | |
| 199 intptr_t start_pos = 0; | 230 intptr_t start_pos = 0; |
| 200 for (intptr_t i = 0; i < name.Length(); i++) { | 231 GrowableArray<const char*> unmangled_segments; |
| 201 if (name.CharAt(i) == '@' && | 232 intptr_t sum_segment_len = 0; |
| 202 (i+1) < name.Length() && | 233 for (intptr_t i = 0; i < name_len; i++) { |
| 203 (name.CharAt(i+1) >= '0') && | 234 if ((cname[i] == '@') && ((i + 1) < name_len) && |
| 204 (name.CharAt(i+1) <= '9')) { | 235 (cname[i + 1] >= '0') && (cname[i + 1] <= '9')) { |
| 205 // Append the current segment to the unmangled name. | 236 // Append the current segment to the unmangled name. |
| 206 segment = String::SubString(name, start_pos, (i - start_pos)); | 237 const intptr_t segment_len = i - start_pos; |
| 207 unmangled_name = String::Concat(unmangled_name, segment); | 238 sum_segment_len += segment_len; |
| 208 | 239 AppendSubString(zone, &unmangled_segments, cname, start_pos, segment_len); |
| 209 // Advance until past the name mangling. The private keys are only | 240 // Advance until past the name mangling. The private keys are only |
| 210 // numbers so we skip until the first non-number. | 241 // numbers so we skip until the first non-number. |
| 211 i++; // Skip the '@'. | 242 i++; // Skip the '@'. |
| 212 while ((i < name.Length()) && | 243 while ((i < name.Length()) && |
| 213 (name.CharAt(i) >= '0') && | 244 (name.CharAt(i) >= '0') && |
| 214 (name.CharAt(i) <= '9')) { | 245 (name.CharAt(i) <= '9')) { |
| 215 i++; | 246 i++; |
| 216 } | 247 } |
| 217 start_pos = i; | 248 start_pos = i; |
| 218 i--; // Account for for-loop increment. | 249 i--; // Account for for-loop increment. |
| 219 } | 250 } |
| 220 } | 251 } |
| 252 |
| 253 const char* unmangled_name = NULL; |
| 221 if (start_pos == 0) { | 254 if (start_pos == 0) { |
| 222 // No name unmangling needed, reuse the name that was passed in. | 255 // No name unmangling needed, reuse the name that was passed in. |
| 223 unmangled_name = name.raw(); | 256 unmangled_name = cname; |
| 257 sum_segment_len = name_len; |
| 224 } else if (name.Length() != start_pos) { | 258 } else if (name.Length() != start_pos) { |
| 225 // Append the last segment. | 259 // Append the last segment. |
| 226 segment = String::SubString(name, start_pos, (name.Length() - start_pos)); | 260 const intptr_t segment_len = name.Length() - start_pos; |
| 227 unmangled_name = String::Concat(unmangled_name, segment); | 261 sum_segment_len += segment_len; |
| 262 AppendSubString(zone, &unmangled_segments, cname, start_pos, segment_len); |
| 263 } |
| 264 if (unmangled_name == NULL) { |
| 265 // Merge unmangled_segments. |
| 266 unmangled_name = MergeSubStrings(zone, unmangled_segments, sum_segment_len); |
| 228 } | 267 } |
| 229 | 268 |
| 230 intptr_t len = unmangled_name.Length(); | 269 intptr_t len = sum_segment_len; |
| 231 intptr_t start = 0; | 270 intptr_t start = 0; |
| 232 intptr_t dot_pos = -1; // Position of '.' in the name, if any. | 271 intptr_t dot_pos = -1; // Position of '.' in the name, if any. |
| 233 bool is_setter = false; | 272 bool is_setter = false; |
| 234 for (intptr_t i = start; i < len; i++) { | 273 for (intptr_t i = start; i < len; i++) { |
| 235 if (unmangled_name.CharAt(i) == ':') { | 274 if (unmangled_name[i] == ':') { |
| 236 if (start != 0) { | 275 if (start != 0) { |
| 237 // Reset and break. | 276 // Reset and break. |
| 238 start = 0; | 277 start = 0; |
| 239 dot_pos = -1; | 278 dot_pos = -1; |
| 240 break; | 279 break; |
| 241 } | 280 } |
| 242 ASSERT(start == 0); // Only one : is possible in getters or setters. | 281 ASSERT(start == 0); // Only one : is possible in getters or setters. |
| 243 if (unmangled_name.CharAt(0) == 's') { | 282 if (unmangled_name[0] == 's') { |
| 244 is_setter = true; | 283 is_setter = true; |
| 245 } | 284 } |
| 246 start = i + 1; | 285 start = i + 1; |
| 247 } else if (unmangled_name.CharAt(i) == '.') { | 286 } else if (unmangled_name[i] == '.') { |
| 248 if (dot_pos != -1) { | 287 if (dot_pos != -1) { |
| 249 // Reset and break. | 288 // Reset and break. |
| 250 start = 0; | 289 start = 0; |
| 251 dot_pos = -1; | 290 dot_pos = -1; |
| 252 break; | 291 break; |
| 253 } | 292 } |
| 254 ASSERT(dot_pos == -1); // Only one dot is supported. | 293 ASSERT(dot_pos == -1); // Only one dot is supported. |
| 255 dot_pos = i; | 294 dot_pos = i; |
| 256 } | 295 } |
| 257 } | 296 } |
| 258 | 297 |
| 259 if ((start == 0) && (dot_pos == -1)) { | 298 if ((start == 0) && (dot_pos == -1)) { |
| 260 // This unmangled_name is fine as it is. | 299 // This unmangled_name is fine as it is. |
| 261 return unmangled_name.raw(); | 300 return Symbols::New(unmangled_name, sum_segment_len); |
| 262 } | 301 } |
| 263 | 302 |
| 264 // Drop the trailing dot if needed. | 303 // Drop the trailing dot if needed. |
| 265 intptr_t end = ((dot_pos + 1) == len) ? dot_pos : len; | 304 intptr_t end = ((dot_pos + 1) == len) ? dot_pos : len; |
| 266 | 305 |
| 267 const String& result = | 306 unmangled_segments.Clear(); |
| 268 String::Handle(String::SubString(unmangled_name, start, (end - start))); | 307 intptr_t final_len = end - start; |
| 269 | 308 AppendSubString(zone, &unmangled_segments, unmangled_name, start, final_len); |
| 270 if (is_setter) { | 309 if (is_setter) { |
| 271 // Setters need to end with '='. | 310 const char* equals = Symbols::Equals().ToCString(); |
| 272 return String::Concat(result, Symbols::Equals()); | 311 const intptr_t equals_len = strlen(equals); |
| 312 AppendSubString(zone, &unmangled_segments, equals, 0, equals_len); |
| 313 final_len += equals_len; |
| 273 } | 314 } |
| 274 | 315 |
| 275 return result.raw(); | 316 unmangled_name = MergeSubStrings(zone, unmangled_segments, final_len); |
| 317 |
| 318 return Symbols::New(unmangled_name); |
| 276 } | 319 } |
| 277 | 320 |
| 278 | 321 |
| 279 RawString* String::IdentifierPrettyNameRetainPrivate(const String& name) { | 322 RawString* String::IdentifierPrettyNameRetainPrivate(const String& name) { |
| 280 intptr_t len = name.Length(); | 323 intptr_t len = name.Length(); |
| 281 intptr_t start = 0; | 324 intptr_t start = 0; |
| 282 intptr_t at_pos = -1; // Position of '@' in the name, if any. | 325 intptr_t at_pos = -1; // Position of '@' in the name, if any. |
| 283 bool is_setter = false; | 326 bool is_setter = false; |
| 284 | 327 |
| 285 for (intptr_t i = start; i < len; i++) { | 328 for (intptr_t i = start; i < len; i++) { |
| (...skipping 21122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21408 return tag_label.ToCString(); | 21451 return tag_label.ToCString(); |
| 21409 } | 21452 } |
| 21410 | 21453 |
| 21411 | 21454 |
| 21412 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 21455 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 21413 Instance::PrintJSONImpl(stream, ref); | 21456 Instance::PrintJSONImpl(stream, ref); |
| 21414 } | 21457 } |
| 21415 | 21458 |
| 21416 | 21459 |
| 21417 } // namespace dart | 21460 } // namespace dart |
| OLD | NEW |