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 prefices are removed: | |
siva
2012/08/07 21:41:37
prefixes
turnidge
2012/08/07 23:32:09
Done.
| |
110 // | |
111 // get:foo -> foo | |
112 // set:foo -> foo | |
siva
2012/08/07 21:41:37
I am wondering get:foo should become 'get foo' and
turnidge
2012/08/07 23:32:09
Discussed offline. For now this lets me share the
| |
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 | |
135 for (int i = 0; i < name.Length(); i++) { | |
136 if (name.CharAt(i) == ':') { | |
137 ASSERT(start == 0); | |
138 start = i + 1; | |
139 } else if (name.CharAt(i) == '@') { | |
140 ASSERT(at_pos == len); | |
141 at_pos = i; | |
142 } else if (name.CharAt(i) == '.') { | |
143 dot_pos = i; | |
144 break; | |
145 } | |
146 } | |
147 intptr_t limit = (at_pos < dot_pos ? at_pos : dot_pos); | |
148 if (start == 0 && limit == len) { | |
149 // This name is fine as it is. | |
150 return name.raw(); | |
151 } | |
152 | |
153 String& result = String::Handle(); | |
154 result = String::SubString(name, start, (limit - start)); | |
siva
2012/08/07 21:41:37
const String& result = String::Handle(String::Sub.
turnidge
2012/08/07 23:32:09
Done.
| |
155 | |
156 // Look for a second '@' now to correctly handle names like | |
157 // "_ReceivePortImpl@6be832b._internal@6be832b". | |
158 at_pos = len; | |
159 for (int i = dot_pos; i < name.Length(); i++) { | |
160 if (name.CharAt(i) == '@') { | |
161 ASSERT(at_pos == len); | |
162 at_pos = i; | |
163 } | |
164 } | |
165 | |
166 intptr_t suffix_len = at_pos - dot_pos; | |
167 if (suffix_len <= 1) { | |
168 // The constructor name is of length 0 or 1. That means that | |
169 // either this isn't a constructor or that this is an unnamed | |
170 // constructor. In either case, we're done. | |
171 return result.raw(); | |
172 } | |
173 | |
174 const String& suffix = | |
175 String::Handle(String::SubString(name, dot_pos, suffix_len)); | |
176 return String::Concat(result, suffix); | |
177 } | |
178 | |
179 | |
104 int Object::GetSingletonClassIndex(const RawClass* raw_class) { | 180 int Object::GetSingletonClassIndex(const RawClass* raw_class) { |
105 ASSERT(raw_class->IsHeapObject()); | 181 ASSERT(raw_class->IsHeapObject()); |
106 if (raw_class == class_class()) { | 182 if (raw_class == class_class()) { |
107 return kClassClass; | 183 return kClassClass; |
108 } else if (raw_class == null_class()) { | 184 } else if (raw_class == null_class()) { |
109 return kNullClass; | 185 return kNullClass; |
110 } else if (raw_class == dynamic_class()) { | 186 } else if (raw_class == dynamic_class()) { |
111 return kDynamicClass; | 187 return kDynamicClass; |
112 } else if (raw_class == void_class()) { | 188 } else if (raw_class == void_class()) { |
113 return kVoidClass; | 189 return kVoidClass; |
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1124 case kUint64Array: | 1200 case kUint64Array: |
1125 case kExternalUint64Array: | 1201 case kExternalUint64Array: |
1126 return Symbols::New("Uint64List"); | 1202 return Symbols::New("Uint64List"); |
1127 case kFloat32Array: | 1203 case kFloat32Array: |
1128 case kExternalFloat32Array: | 1204 case kExternalFloat32Array: |
1129 return Symbols::New("Float32List"); | 1205 return Symbols::New("Float32List"); |
1130 case kFloat64Array: | 1206 case kFloat64Array: |
1131 case kExternalFloat64Array: | 1207 case kExternalFloat64Array: |
1132 return Symbols::New("Float64List"); | 1208 return Symbols::New("Float64List"); |
1133 default: | 1209 default: |
1134 return Name(); | 1210 const String& name = String::Handle(Name()); |
1211 return IdentifierPrettyName(name); | |
1135 } | 1212 } |
1136 UNREACHABLE(); | 1213 UNREACHABLE(); |
1137 } | 1214 } |
1138 | 1215 |
1139 | 1216 |
1140 RawType* Class::SignatureType() const { | 1217 RawType* Class::SignatureType() const { |
1141 ASSERT(IsSignatureClass()); | 1218 ASSERT(IsSignatureClass()); |
1142 const Function& function = Function::Handle(signature_function()); | 1219 const Function& function = Function::Handle(signature_function()); |
1143 ASSERT(!function.IsNull()); | 1220 ASSERT(!function.IsNull()); |
1144 if (function.signature_class() != raw()) { | 1221 if (function.signature_class() != raw()) { |
(...skipping 3214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4359 } | 4436 } |
4360 return true; | 4437 return true; |
4361 } | 4438 } |
4362 | 4439 |
4363 | 4440 |
4364 bool Function::HasOptimizedCode() const { | 4441 bool Function::HasOptimizedCode() const { |
4365 return HasCode() && Code::Handle(raw_ptr()->code_).is_optimized(); | 4442 return HasCode() && Code::Handle(raw_ptr()->code_).is_optimized(); |
4366 } | 4443 } |
4367 | 4444 |
4368 | 4445 |
4446 RawString* Function::UserVisibleName() const { | |
4447 String& tmp = String::Handle(); | |
4448 tmp = name(); | |
4449 tmp = IdentifierPrettyName(tmp); | |
4450 if (kind() == RawFunction::kSetterFunction) { | |
4451 const String& suffix = String::Handle(Symbols::Equals()); | |
4452 tmp = String::Concat(tmp, suffix); | |
siva
2012/08/07 21:41:37
See comment above regarding setter/gettter, does i
turnidge
2012/08/07 23:32:09
See above.
| |
4453 } | |
4454 return tmp.raw(); | |
4455 } | |
4456 | |
4457 | |
4458 RawString* Function::QualifiedUserVisibleName() const { | |
4459 String& tmp = String::Handle(); | |
4460 String& suffix = String::Handle(); | |
4461 const Class& cls = Class::Handle(owner()); | |
4462 | |
4463 if (IsClosureFunction()) { | |
4464 if (IsLocalFunction()) { | |
4465 const Function& parent = Function::Handle(parent_function()); | |
4466 tmp = parent.QualifiedUserVisibleName(); | |
4467 } else { | |
4468 return UserVisibleName(); | |
4469 } | |
4470 } else { | |
4471 if (cls.IsTopLevel()) { | |
4472 return UserVisibleName(); | |
4473 } else { | |
4474 tmp = cls.UserVisibleName(); | |
4475 } | |
4476 } | |
4477 suffix = Symbols::Dot(); | |
4478 tmp = String::Concat(tmp, suffix); | |
4479 suffix = UserVisibleName(); | |
4480 return String::Concat(tmp, suffix); | |
4481 } | |
4482 | |
4483 | |
4369 const char* Function::ToCString() const { | 4484 const char* Function::ToCString() const { |
4370 const char* static_str = is_static() ? " static" : ""; | 4485 const char* static_str = is_static() ? " static" : ""; |
4371 const char* abstract_str = is_abstract() ? " abstract" : ""; | 4486 const char* abstract_str = is_abstract() ? " abstract" : ""; |
4372 const char* kind_str = NULL; | 4487 const char* kind_str = NULL; |
4373 const char* const_str = is_const() ? " const" : ""; | 4488 const char* const_str = is_const() ? " const" : ""; |
4374 switch (kind()) { | 4489 switch (kind()) { |
4375 case RawFunction::kRegularFunction: | 4490 case RawFunction::kRegularFunction: |
4376 case RawFunction::kClosureFunction: | 4491 case RawFunction::kClosureFunction: |
4377 case RawFunction::kGetterFunction: | 4492 case RawFunction::kGetterFunction: |
4378 case RawFunction::kSetterFunction: | 4493 case RawFunction::kSetterFunction: |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4512 } | 4627 } |
4513 result.set_is_final(is_final); | 4628 result.set_is_final(is_final); |
4514 result.set_is_const(is_const); | 4629 result.set_is_const(is_const); |
4515 result.set_owner(owner); | 4630 result.set_owner(owner); |
4516 result.set_token_pos(token_pos); | 4631 result.set_token_pos(token_pos); |
4517 result.set_has_initializer(false); | 4632 result.set_has_initializer(false); |
4518 return result.raw(); | 4633 return result.raw(); |
4519 } | 4634 } |
4520 | 4635 |
4521 | 4636 |
4637 RawString* Field::UserVisibleName() const { | |
4638 const String& str = String::Handle(name()); | |
4639 return IdentifierPrettyName(str); | |
4640 } | |
4641 | |
4642 | |
4522 const char* Field::ToCString() const { | 4643 const char* Field::ToCString() const { |
4523 const char* kF0 = is_static() ? " static" : ""; | 4644 const char* kF0 = is_static() ? " static" : ""; |
4524 const char* kF1 = is_final() ? " final" : ""; | 4645 const char* kF1 = is_final() ? " final" : ""; |
4525 const char* kF2 = is_const() ? " const" : ""; | 4646 const char* kF2 = is_const() ? " const" : ""; |
4526 const char* kFormat = "Field <%s.%s>:%s%s%s"; | 4647 const char* kFormat = "Field <%s.%s>:%s%s%s"; |
4527 const char* field_name = String::Handle(name()).ToCString(); | 4648 const char* field_name = String::Handle(name()).ToCString(); |
4528 const Class& cls = Class::Handle(owner()); | 4649 const Class& cls = Class::Handle(owner()); |
4529 const char* cls_name = String::Handle(cls.Name()).ToCString(); | 4650 const char* cls_name = String::Handle(cls.Name()).ToCString(); |
4530 intptr_t len = | 4651 intptr_t len = |
4531 OS::SNPrint(NULL, 0, kFormat, cls_name, field_name, kF0, kF1, kF2) + 1; | 4652 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... | |
10881 obj = func_list.At(j); | 11002 obj = func_list.At(j); |
10882 function_array.SetAt(i, obj); | 11003 function_array.SetAt(i, obj); |
10883 obj = code_list.At(j); | 11004 obj = code_list.At(j); |
10884 code_array.SetAt(i, obj); | 11005 code_array.SetAt(i, obj); |
10885 obj = pc_offset_list.At(j); | 11006 obj = pc_offset_list.At(j); |
10886 pc_offset_array.SetAt(i, obj); | 11007 pc_offset_array.SetAt(i, obj); |
10887 } | 11008 } |
10888 } | 11009 } |
10889 | 11010 |
10890 | 11011 |
10891 const char* Stacktrace::ToCStringInternal(bool verbose) const { | 11012 const char* Stacktrace::ToCString() const { |
10892 Function& function = Function::Handle(); | 11013 Function& function = Function::Handle(); |
10893 Code& code = Code::Handle(); | 11014 Code& code = Code::Handle(); |
10894 Class& function_class = Class::Handle(); | 11015 Class& owner = Class::Handle(); |
10895 Script& script = Script::Handle(); | 11016 Script& script = Script::Handle(); |
10896 String& function_name = String::Handle(); | 11017 String& function_name = String::Handle(); |
10897 String& class_name = String::Handle(); | |
10898 String& url = String::Handle(); | 11018 String& url = String::Handle(); |
10899 | 11019 |
10900 // Iterate through the stack frames and create C string description | 11020 // Iterate through the stack frames and create C string description |
10901 // for each frame. | 11021 // for each frame. |
10902 intptr_t total_len = 0; | 11022 intptr_t total_len = 0; |
10903 const char* kFormat = verbose ? | 11023 const char* kFormat = " at %s (%s:%d:%d)\n"; |
siva
2012/08/07 21:41:37
Looking at the sample output you have attached I a
turnidge
2012/08/07 23:32:09
Replaced "at" with a frame number.
On 2012/08/07
| |
10904 " %d. Function: '%s%s%s' url: '%s' line:%d col:%d code-entry: 0x%x\n" : | |
10905 " %d. Function: '%s%s%s' url: '%s' line:%d col:%d\n"; | |
10906 GrowableArray<char*> frame_strings; | 11024 GrowableArray<char*> frame_strings; |
10907 for (intptr_t i = 0; i < Length(); i++) { | 11025 for (intptr_t i = 0; i < Length(); i++) { |
10908 function = FunctionAtFrame(i); | 11026 function = FunctionAtFrame(i); |
10909 code = CodeAtFrame(i); | 11027 code = CodeAtFrame(i); |
10910 uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i)); | 11028 uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i)); |
10911 intptr_t token_pos = code.GetTokenIndexOfPC(pc); | 11029 intptr_t token_pos = code.GetTokenIndexOfPC(pc); |
10912 function_class = function.owner(); | 11030 owner = function.owner(); |
10913 script = function_class.script(); | 11031 script = owner.script(); |
10914 function_name = function.name(); | 11032 function_name = function.QualifiedUserVisibleName(); |
10915 class_name = function_class.Name(); | |
10916 url = script.url(); | 11033 url = script.url(); |
10917 intptr_t line = -1; | 11034 intptr_t line = -1; |
10918 intptr_t column = -1; | 11035 intptr_t column = -1; |
10919 if (token_pos >= 0) { | 11036 if (token_pos >= 0) { |
10920 script.GetTokenLocation(token_pos, &line, &column); | 11037 script.GetTokenLocation(token_pos, &line, &column); |
10921 } | 11038 } |
10922 intptr_t len = OS::SNPrint(NULL, 0, kFormat, | 11039 intptr_t len = OS::SNPrint(NULL, 0, kFormat, |
10923 i, | |
10924 class_name.ToCString(), | |
10925 function_class.IsTopLevel() ? "" : ".", | |
10926 function_name.ToCString(), | 11040 function_name.ToCString(), |
10927 url.ToCString(), | 11041 url.ToCString(), |
10928 line, column, | 11042 line, column); |
10929 code.EntryPoint()); | |
10930 total_len += len; | 11043 total_len += len; |
10931 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 11044 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
10932 OS::SNPrint(chars, (len + 1), kFormat, | 11045 OS::SNPrint(chars, (len + 1), kFormat, |
10933 i, | |
10934 class_name.ToCString(), | |
10935 function_class.IsTopLevel() ? "" : ".", | |
10936 function_name.ToCString(), | 11046 function_name.ToCString(), |
10937 url.ToCString(), | 11047 url.ToCString(), |
10938 line, column, | 11048 line, column); |
10939 code.EntryPoint()); | |
10940 frame_strings.Add(chars); | 11049 frame_strings.Add(chars); |
10941 } | 11050 } |
10942 | 11051 |
10943 // Now concatentate the frame descriptions into a single C string. | 11052 // Now concatentate the frame descriptions into a single C string. |
10944 char* chars = Isolate::Current()->current_zone()->Alloc<char>(total_len + 1); | 11053 char* chars = Isolate::Current()->current_zone()->Alloc<char>(total_len + 1); |
10945 intptr_t index = 0; | 11054 intptr_t index = 0; |
10946 for (intptr_t i = 0; i < frame_strings.length(); i++) { | 11055 for (intptr_t i = 0; i < frame_strings.length(); i++) { |
10947 index += OS::SNPrint((chars + index), | 11056 index += OS::SNPrint((chars + index), |
10948 (total_len + 1 - index), | 11057 (total_len + 1 - index), |
10949 "%s", | 11058 "%s", |
10950 frame_strings[i]); | 11059 frame_strings[i]); |
10951 } | 11060 } |
10952 return chars; | 11061 return chars; |
10953 } | 11062 } |
10954 | 11063 |
10955 | 11064 |
10956 const char* Stacktrace::ToCString() const { | |
10957 return ToCStringInternal(false); | |
10958 } | |
10959 | |
10960 | |
10961 void JSRegExp::set_pattern(const String& pattern) const { | 11065 void JSRegExp::set_pattern(const String& pattern) const { |
10962 StorePointer(&raw_ptr()->pattern_, pattern.raw()); | 11066 StorePointer(&raw_ptr()->pattern_, pattern.raw()); |
10963 } | 11067 } |
10964 | 11068 |
10965 | 11069 |
10966 void JSRegExp::set_num_bracket_expressions(intptr_t value) const { | 11070 void JSRegExp::set_num_bracket_expressions(intptr_t value) const { |
10967 raw_ptr()->num_bracket_expressions_ = Smi::New(value); | 11071 raw_ptr()->num_bracket_expressions_ = Smi::New(value); |
10968 } | 11072 } |
10969 | 11073 |
10970 | 11074 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11049 const char* JSRegExp::ToCString() const { | 11153 const char* JSRegExp::ToCString() const { |
11050 const String& str = String::Handle(pattern()); | 11154 const String& str = String::Handle(pattern()); |
11051 const char* format = "JSRegExp: pattern=%s flags=%s"; | 11155 const char* format = "JSRegExp: pattern=%s flags=%s"; |
11052 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 11156 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
11053 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 11157 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
11054 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 11158 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
11055 return chars; | 11159 return chars; |
11056 } | 11160 } |
11057 | 11161 |
11058 } // namespace dart | 11162 } // namespace dart |
OLD | NEW |