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/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 94 RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
95 RawClass* Object::subtypetestcache_class_ = | 95 RawClass* Object::subtypetestcache_class_ = |
96 reinterpret_cast<RawClass*>(RAW_NULL); | 96 reinterpret_cast<RawClass*>(RAW_NULL); |
97 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 97 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
98 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 98 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
99 RawClass* Object::unhandled_exception_class_ = | 99 RawClass* Object::unhandled_exception_class_ = |
100 reinterpret_cast<RawClass*>(RAW_NULL); | 100 reinterpret_cast<RawClass*>(RAW_NULL); |
101 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 101 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
102 #undef RAW_NULL | 102 #undef RAW_NULL |
103 | 103 |
| 104 |
| 105 // Takes a vm internal name and makes it suitable for external user. |
| 106 // |
| 107 // Examples: |
| 108 // |
| 109 // Internal getter and setter prefixes are changed: |
| 110 // |
| 111 // get:foo -> foo |
| 112 // set:foo -> foo= |
| 113 // |
| 114 // Private name mangling is removed, possibly twice: |
| 115 // |
| 116 // _ReceivePortImpl@6be832b -> _ReceivePortImpl |
| 117 // _ReceivePortImpl@6be832b._internal@6be832b -> +ReceivePortImpl._internal |
| 118 // |
| 119 // The trailing . on the default constructor name is dropped: |
| 120 // |
| 121 // List. -> List |
| 122 // |
| 123 // And so forth: |
| 124 // |
| 125 // get:foo@6be832b -> foo |
| 126 // _MyClass@6b3832b. -> _MyClass |
| 127 // _MyClass@6b3832b.named -> _MyClass.named |
| 128 // |
| 129 static RawString* IdentifierPrettyName(const String& name) { |
| 130 intptr_t len = name.Length(); |
| 131 intptr_t start = 0; |
| 132 intptr_t at_pos = len; // Position of '@' in the name. |
| 133 intptr_t dot_pos = len; // Position of '.' in the name. |
| 134 bool is_setter = false; |
| 135 |
| 136 for (int i = 0; i < name.Length(); i++) { |
| 137 if (name.CharAt(i) == ':') { |
| 138 ASSERT(start == 0); |
| 139 if (name.CharAt(0) == 's') { |
| 140 is_setter = true; |
| 141 } |
| 142 start = i + 1; |
| 143 } else if (name.CharAt(i) == '@') { |
| 144 ASSERT(at_pos == len); |
| 145 at_pos = i; |
| 146 } else if (name.CharAt(i) == '.') { |
| 147 dot_pos = i; |
| 148 break; |
| 149 } |
| 150 } |
| 151 intptr_t limit = (at_pos < dot_pos ? at_pos : dot_pos); |
| 152 if (start == 0 && limit == len) { |
| 153 // This name is fine as it is. |
| 154 return name.raw(); |
| 155 } |
| 156 |
| 157 const String& result = |
| 158 String::Handle(String::SubString(name, start, (limit - start))); |
| 159 |
| 160 // Look for a second '@' now to correctly handle names like |
| 161 // "_ReceivePortImpl@6be832b._internal@6be832b". |
| 162 at_pos = len; |
| 163 for (int i = dot_pos; i < name.Length(); i++) { |
| 164 if (name.CharAt(i) == '@') { |
| 165 ASSERT(at_pos == len); |
| 166 at_pos = i; |
| 167 } |
| 168 } |
| 169 |
| 170 intptr_t suffix_len = at_pos - dot_pos; |
| 171 if (suffix_len > 1) { |
| 172 // This is a named constructor. Add the name back to the string. |
| 173 const String& suffix = |
| 174 String::Handle(String::SubString(name, dot_pos, suffix_len)); |
| 175 return String::Concat(result, suffix); |
| 176 } |
| 177 |
| 178 if (is_setter) { |
| 179 // Setters need to end with '='. |
| 180 const String& suffix = String::Handle(Symbols::Equals()); |
| 181 return String::Concat(result, suffix); |
| 182 } |
| 183 |
| 184 return result.raw(); |
| 185 } |
| 186 |
| 187 |
104 int Object::GetSingletonClassIndex(const RawClass* raw_class) { | 188 int Object::GetSingletonClassIndex(const RawClass* raw_class) { |
105 ASSERT(raw_class->IsHeapObject()); | 189 ASSERT(raw_class->IsHeapObject()); |
106 if (raw_class == class_class()) { | 190 if (raw_class == class_class()) { |
107 return kClassClass; | 191 return kClassClass; |
108 } else if (raw_class == null_class()) { | 192 } else if (raw_class == null_class()) { |
109 return kNullClass; | 193 return kNullClass; |
110 } else if (raw_class == dynamic_class()) { | 194 } else if (raw_class == dynamic_class()) { |
111 return kDynamicClass; | 195 return kDynamicClass; |
112 } else if (raw_class == void_class()) { | 196 } else if (raw_class == void_class()) { |
113 return kVoidClass; | 197 return kVoidClass; |
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 case kUint64Array: | 1208 case kUint64Array: |
1125 case kExternalUint64Array: | 1209 case kExternalUint64Array: |
1126 return Symbols::New("Uint64List"); | 1210 return Symbols::New("Uint64List"); |
1127 case kFloat32Array: | 1211 case kFloat32Array: |
1128 case kExternalFloat32Array: | 1212 case kExternalFloat32Array: |
1129 return Symbols::New("Float32List"); | 1213 return Symbols::New("Float32List"); |
1130 case kFloat64Array: | 1214 case kFloat64Array: |
1131 case kExternalFloat64Array: | 1215 case kExternalFloat64Array: |
1132 return Symbols::New("Float64List"); | 1216 return Symbols::New("Float64List"); |
1133 default: | 1217 default: |
1134 return Name(); | 1218 const String& name = String::Handle(Name()); |
| 1219 return IdentifierPrettyName(name); |
1135 } | 1220 } |
1136 UNREACHABLE(); | 1221 UNREACHABLE(); |
1137 } | 1222 } |
1138 | 1223 |
1139 | 1224 |
1140 RawType* Class::SignatureType() const { | 1225 RawType* Class::SignatureType() const { |
1141 ASSERT(IsSignatureClass()); | 1226 ASSERT(IsSignatureClass()); |
1142 const Function& function = Function::Handle(signature_function()); | 1227 const Function& function = Function::Handle(signature_function()); |
1143 ASSERT(!function.IsNull()); | 1228 ASSERT(!function.IsNull()); |
1144 if (function.signature_class() != raw()) { | 1229 if (function.signature_class() != raw()) { |
(...skipping 3220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4365 } | 4450 } |
4366 return true; | 4451 return true; |
4367 } | 4452 } |
4368 | 4453 |
4369 | 4454 |
4370 bool Function::HasOptimizedCode() const { | 4455 bool Function::HasOptimizedCode() const { |
4371 return HasCode() && Code::Handle(raw_ptr()->code_).is_optimized(); | 4456 return HasCode() && Code::Handle(raw_ptr()->code_).is_optimized(); |
4372 } | 4457 } |
4373 | 4458 |
4374 | 4459 |
| 4460 RawString* Function::UserVisibleName() const { |
| 4461 const String& str = String::Handle(name()); |
| 4462 return IdentifierPrettyName(str); |
| 4463 } |
| 4464 |
| 4465 |
| 4466 RawString* Function::QualifiedUserVisibleName() const { |
| 4467 String& tmp = String::Handle(); |
| 4468 String& suffix = String::Handle(); |
| 4469 const Class& cls = Class::Handle(owner()); |
| 4470 |
| 4471 if (IsClosureFunction()) { |
| 4472 if (IsLocalFunction()) { |
| 4473 const Function& parent = Function::Handle(parent_function()); |
| 4474 tmp = parent.QualifiedUserVisibleName(); |
| 4475 } else { |
| 4476 return UserVisibleName(); |
| 4477 } |
| 4478 } else { |
| 4479 if (cls.IsTopLevel()) { |
| 4480 return UserVisibleName(); |
| 4481 } else { |
| 4482 tmp = cls.UserVisibleName(); |
| 4483 } |
| 4484 } |
| 4485 suffix = Symbols::Dot(); |
| 4486 tmp = String::Concat(tmp, suffix); |
| 4487 suffix = UserVisibleName(); |
| 4488 return String::Concat(tmp, suffix); |
| 4489 } |
| 4490 |
| 4491 |
4375 const char* Function::ToCString() const { | 4492 const char* Function::ToCString() const { |
4376 const char* static_str = is_static() ? " static" : ""; | 4493 const char* static_str = is_static() ? " static" : ""; |
4377 const char* abstract_str = is_abstract() ? " abstract" : ""; | 4494 const char* abstract_str = is_abstract() ? " abstract" : ""; |
4378 const char* kind_str = NULL; | 4495 const char* kind_str = NULL; |
4379 const char* const_str = is_const() ? " const" : ""; | 4496 const char* const_str = is_const() ? " const" : ""; |
4380 switch (kind()) { | 4497 switch (kind()) { |
4381 case RawFunction::kRegularFunction: | 4498 case RawFunction::kRegularFunction: |
4382 case RawFunction::kClosureFunction: | 4499 case RawFunction::kClosureFunction: |
4383 case RawFunction::kGetterFunction: | 4500 case RawFunction::kGetterFunction: |
4384 case RawFunction::kSetterFunction: | 4501 case RawFunction::kSetterFunction: |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4518 } | 4635 } |
4519 result.set_is_final(is_final); | 4636 result.set_is_final(is_final); |
4520 result.set_is_const(is_const); | 4637 result.set_is_const(is_const); |
4521 result.set_owner(owner); | 4638 result.set_owner(owner); |
4522 result.set_token_pos(token_pos); | 4639 result.set_token_pos(token_pos); |
4523 result.set_has_initializer(false); | 4640 result.set_has_initializer(false); |
4524 return result.raw(); | 4641 return result.raw(); |
4525 } | 4642 } |
4526 | 4643 |
4527 | 4644 |
| 4645 RawString* Field::UserVisibleName() const { |
| 4646 const String& str = String::Handle(name()); |
| 4647 return IdentifierPrettyName(str); |
| 4648 } |
| 4649 |
| 4650 |
4528 const char* Field::ToCString() const { | 4651 const char* Field::ToCString() const { |
4529 const char* kF0 = is_static() ? " static" : ""; | 4652 const char* kF0 = is_static() ? " static" : ""; |
4530 const char* kF1 = is_final() ? " final" : ""; | 4653 const char* kF1 = is_final() ? " final" : ""; |
4531 const char* kF2 = is_const() ? " const" : ""; | 4654 const char* kF2 = is_const() ? " const" : ""; |
4532 const char* kFormat = "Field <%s.%s>:%s%s%s"; | 4655 const char* kFormat = "Field <%s.%s>:%s%s%s"; |
4533 const char* field_name = String::Handle(name()).ToCString(); | 4656 const char* field_name = String::Handle(name()).ToCString(); |
4534 const Class& cls = Class::Handle(owner()); | 4657 const Class& cls = Class::Handle(owner()); |
4535 const char* cls_name = String::Handle(cls.Name()).ToCString(); | 4658 const char* cls_name = String::Handle(cls.Name()).ToCString(); |
4536 intptr_t len = | 4659 intptr_t len = |
4537 OS::SNPrint(NULL, 0, kFormat, cls_name, field_name, kF0, kF1, kF2) + 1; | 4660 OS::SNPrint(NULL, 0, kFormat, cls_name, field_name, kF0, kF1, kF2) + 1; |
(...skipping 6349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10887 obj = func_list.At(j); | 11010 obj = func_list.At(j); |
10888 function_array.SetAt(i, obj); | 11011 function_array.SetAt(i, obj); |
10889 obj = code_list.At(j); | 11012 obj = code_list.At(j); |
10890 code_array.SetAt(i, obj); | 11013 code_array.SetAt(i, obj); |
10891 obj = pc_offset_list.At(j); | 11014 obj = pc_offset_list.At(j); |
10892 pc_offset_array.SetAt(i, obj); | 11015 pc_offset_array.SetAt(i, obj); |
10893 } | 11016 } |
10894 } | 11017 } |
10895 | 11018 |
10896 | 11019 |
10897 const char* Stacktrace::ToCStringInternal(bool verbose) const { | 11020 const char* Stacktrace::ToCString() const { |
10898 Function& function = Function::Handle(); | 11021 Function& function = Function::Handle(); |
10899 Code& code = Code::Handle(); | 11022 Code& code = Code::Handle(); |
10900 Class& function_class = Class::Handle(); | 11023 Class& owner = Class::Handle(); |
10901 Script& script = Script::Handle(); | 11024 Script& script = Script::Handle(); |
10902 String& function_name = String::Handle(); | 11025 String& function_name = String::Handle(); |
10903 String& class_name = String::Handle(); | |
10904 String& url = String::Handle(); | 11026 String& url = String::Handle(); |
10905 | 11027 |
10906 // Iterate through the stack frames and create C string description | 11028 // Iterate through the stack frames and create C string description |
10907 // for each frame. | 11029 // for each frame. |
10908 intptr_t total_len = 0; | 11030 intptr_t total_len = 0; |
10909 const char* kFormat = verbose ? | 11031 const char* kFormat = "#%-6d %s (%s:%d:%d)\n"; |
10910 " %d. Function: '%s%s%s' url: '%s' line:%d col:%d code-entry: 0x%x\n" : | |
10911 " %d. Function: '%s%s%s' url: '%s' line:%d col:%d\n"; | |
10912 GrowableArray<char*> frame_strings; | 11032 GrowableArray<char*> frame_strings; |
10913 for (intptr_t i = 0; i < Length(); i++) { | 11033 for (intptr_t i = 0; i < Length(); i++) { |
10914 function = FunctionAtFrame(i); | 11034 function = FunctionAtFrame(i); |
10915 code = CodeAtFrame(i); | 11035 code = CodeAtFrame(i); |
10916 uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i)); | 11036 uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i)); |
10917 intptr_t token_pos = code.GetTokenIndexOfPC(pc); | 11037 intptr_t token_pos = code.GetTokenIndexOfPC(pc); |
10918 function_class = function.owner(); | 11038 owner = function.owner(); |
10919 script = function_class.script(); | 11039 script = owner.script(); |
10920 function_name = function.name(); | 11040 function_name = function.QualifiedUserVisibleName(); |
10921 class_name = function_class.Name(); | |
10922 url = script.url(); | 11041 url = script.url(); |
10923 intptr_t line = -1; | 11042 intptr_t line = -1; |
10924 intptr_t column = -1; | 11043 intptr_t column = -1; |
10925 if (token_pos >= 0) { | 11044 if (token_pos >= 0) { |
10926 script.GetTokenLocation(token_pos, &line, &column); | 11045 script.GetTokenLocation(token_pos, &line, &column); |
10927 } | 11046 } |
10928 intptr_t len = OS::SNPrint(NULL, 0, kFormat, | 11047 intptr_t len = OS::SNPrint(NULL, 0, kFormat, |
10929 i, | 11048 i, |
10930 class_name.ToCString(), | |
10931 function_class.IsTopLevel() ? "" : ".", | |
10932 function_name.ToCString(), | 11049 function_name.ToCString(), |
10933 url.ToCString(), | 11050 url.ToCString(), |
10934 line, column, | 11051 line, column); |
10935 code.EntryPoint()); | |
10936 total_len += len; | 11052 total_len += len; |
10937 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 11053 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
10938 OS::SNPrint(chars, (len + 1), kFormat, | 11054 OS::SNPrint(chars, (len + 1), kFormat, |
10939 i, | 11055 i, |
10940 class_name.ToCString(), | |
10941 function_class.IsTopLevel() ? "" : ".", | |
10942 function_name.ToCString(), | 11056 function_name.ToCString(), |
10943 url.ToCString(), | 11057 url.ToCString(), |
10944 line, column, | 11058 line, column); |
10945 code.EntryPoint()); | |
10946 frame_strings.Add(chars); | 11059 frame_strings.Add(chars); |
10947 } | 11060 } |
10948 | 11061 |
10949 // Now concatentate the frame descriptions into a single C string. | 11062 // Now concatentate the frame descriptions into a single C string. |
10950 char* chars = Isolate::Current()->current_zone()->Alloc<char>(total_len + 1); | 11063 char* chars = Isolate::Current()->current_zone()->Alloc<char>(total_len + 1); |
10951 intptr_t index = 0; | 11064 intptr_t index = 0; |
10952 for (intptr_t i = 0; i < frame_strings.length(); i++) { | 11065 for (intptr_t i = 0; i < frame_strings.length(); i++) { |
10953 index += OS::SNPrint((chars + index), | 11066 index += OS::SNPrint((chars + index), |
10954 (total_len + 1 - index), | 11067 (total_len + 1 - index), |
10955 "%s", | 11068 "%s", |
10956 frame_strings[i]); | 11069 frame_strings[i]); |
10957 } | 11070 } |
10958 return chars; | 11071 return chars; |
10959 } | 11072 } |
10960 | 11073 |
10961 | 11074 |
10962 const char* Stacktrace::ToCString() const { | |
10963 return ToCStringInternal(false); | |
10964 } | |
10965 | |
10966 | |
10967 void JSRegExp::set_pattern(const String& pattern) const { | 11075 void JSRegExp::set_pattern(const String& pattern) const { |
10968 StorePointer(&raw_ptr()->pattern_, pattern.raw()); | 11076 StorePointer(&raw_ptr()->pattern_, pattern.raw()); |
10969 } | 11077 } |
10970 | 11078 |
10971 | 11079 |
10972 void JSRegExp::set_num_bracket_expressions(intptr_t value) const { | 11080 void JSRegExp::set_num_bracket_expressions(intptr_t value) const { |
10973 raw_ptr()->num_bracket_expressions_ = Smi::New(value); | 11081 raw_ptr()->num_bracket_expressions_ = Smi::New(value); |
10974 } | 11082 } |
10975 | 11083 |
10976 | 11084 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11055 const char* JSRegExp::ToCString() const { | 11163 const char* JSRegExp::ToCString() const { |
11056 const String& str = String::Handle(pattern()); | 11164 const String& str = String::Handle(pattern()); |
11057 const char* format = "JSRegExp: pattern=%s flags=%s"; | 11165 const char* format = "JSRegExp: pattern=%s flags=%s"; |
11058 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 11166 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
11059 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 11167 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
11060 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 11168 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
11061 return chars; | 11169 return chars; |
11062 } | 11170 } |
11063 | 11171 |
11064 } // namespace dart | 11172 } // namespace dart |
OLD | NEW |