Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: runtime/vm/object.cc

Issue 100603011: Add GrowableObjectArray::ToUserCString(). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11385 matching lines...) Expand 10 before | Expand all | Expand 10 after
11396 const String& type_name = String::Handle(type.UserVisibleName()); 11396 const String& type_name = String::Handle(type.UserVisibleName());
11397 // Calculate the size of the string. 11397 // Calculate the size of the string.
11398 intptr_t len = OS::SNPrint(NULL, 0, kFormat, type_name.ToCString()) + 1; 11398 intptr_t len = OS::SNPrint(NULL, 0, kFormat, type_name.ToCString()) + 1;
11399 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 11399 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
11400 OS::SNPrint(chars, len, kFormat, type_name.ToCString()); 11400 OS::SNPrint(chars, len, kFormat, type_name.ToCString());
11401 return chars; 11401 return chars;
11402 } 11402 }
11403 } 11403 }
11404 11404
11405 11405
11406 const char* Instance::ToUserCString(intptr_t maxLen) const { 11406 const char* Instance::ToUserCString(intptr_t max_len, intptr_t nesting) const {
11407 if (raw() == Object::sentinel().raw()) { 11407 if (raw() == Object::sentinel().raw()) {
11408 return "<not initialized>"; 11408 return "<not initialized>";
11409 } else if (raw() == Object::transition_sentinel().raw()) { 11409 } else if (raw() == Object::transition_sentinel().raw()) {
11410 return "<being initialized>"; 11410 return "<being initialized>";
11411 } else { 11411 } else {
11412 return ToCString(); 11412 return ToCString();
11413 } 11413 }
11414 } 11414 }
11415 11415
11416 11416
(...skipping 2811 matching lines...) Expand 10 before | Expand all | Expand 10 after
14228 } 14228 }
14229 const intptr_t len = Utf8::Length(*this); 14229 const intptr_t len = Utf8::Length(*this);
14230 Zone* zone = Isolate::Current()->current_zone(); 14230 Zone* zone = Isolate::Current()->current_zone();
14231 uint8_t* result = zone->Alloc<uint8_t>(len + 1); 14231 uint8_t* result = zone->Alloc<uint8_t>(len + 1);
14232 ToUTF8(result, len); 14232 ToUTF8(result, len);
14233 result[len] = 0; 14233 result[len] = 0;
14234 return reinterpret_cast<const char*>(result); 14234 return reinterpret_cast<const char*>(result);
14235 } 14235 }
14236 14236
14237 14237
14238 static bool IsAsciiPrintChar(intptr_t codePoint) { 14238 static bool IsAsciiPrintChar(intptr_t code_point) {
14239 return codePoint >= ' ' && codePoint <= '~'; 14239 return code_point >= ' ' && code_point <= '~';
14240 } 14240 }
14241 14241
14242 14242
14243 // Does not null-terminate. 14243 // Does not null-terminate.
14244 intptr_t String::EscapedString(char* buffer, int maxLen) const { 14244 intptr_t String::EscapedString(char* buffer, int max_len) const {
14245 int pos = 0; 14245 int pos = 0;
14246 14246
14247 CodePointIterator cpi(*this); 14247 CodePointIterator cpi(*this);
14248 while (cpi.Next()) { 14248 while (cpi.Next()) {
14249 int32_t codePoint = cpi.Current(); 14249 int32_t code_point = cpi.Current();
14250 if (IsSpecialCharacter(codePoint)) { 14250 if (IsSpecialCharacter(code_point)) {
14251 if (pos + 2 > maxLen) { 14251 if (pos + 2 > max_len) {
14252 return pos; 14252 return pos;
14253 } 14253 }
14254 buffer[pos++] = '\\'; 14254 buffer[pos++] = '\\';
14255 buffer[pos++] = SpecialCharacter(codePoint); 14255 buffer[pos++] = SpecialCharacter(code_point);
14256 } else if (IsAsciiPrintChar(codePoint)) { 14256 } else if (IsAsciiPrintChar(code_point)) {
14257 buffer[pos++] = codePoint; 14257 buffer[pos++] = code_point;
14258 } else { 14258 } else {
14259 if (pos + 6 > maxLen) { 14259 if (pos + 6 > max_len) {
14260 return pos; 14260 return pos;
14261 } 14261 }
14262 pos += OS::SNPrint((buffer + pos), (maxLen - pos), "\\u%04x", codePoint); 14262 pos += OS::SNPrint((buffer + pos), (max_len - pos),
14263 "\\u%04x", code_point);
14263 } 14264 }
14264 if (pos == maxLen) { 14265 if (pos == max_len) {
14265 return pos; 14266 return pos;
14266 } 14267 }
14267 } 14268 }
14268 return pos; 14269 return pos;
14269 } 14270 }
14270 14271
14271 14272
14272 intptr_t String::EscapedStringLen(intptr_t tooLong) const { 14273 intptr_t String::EscapedStringLen(intptr_t too_long) const {
14273 intptr_t len = 0; 14274 intptr_t len = 0;
14274 14275
14275 CodePointIterator cpi(*this); 14276 CodePointIterator cpi(*this);
14276 while (cpi.Next()) { 14277 while (cpi.Next()) {
14277 int32_t codePoint = cpi.Current(); 14278 int32_t code_point = cpi.Current();
14278 if (IsSpecialCharacter(codePoint)) { 14279 if (IsSpecialCharacter(code_point)) {
14279 len += 2; // e.g. "\n" 14280 len += 2; // e.g. "\n"
14280 } else if (IsAsciiPrintChar(codePoint)) { 14281 } else if (IsAsciiPrintChar(code_point)) {
14281 len += 1; 14282 len += 1;
14282 } else { 14283 } else {
14283 len += 6; // e.g. "\u0000". 14284 len += 6; // e.g. "\u0000".
14284 } 14285 }
14285 if (len > tooLong) { 14286 if (len > too_long) {
14286 // No point going further. 14287 // No point going further.
14287 break; 14288 break;
14288 } 14289 }
14289 } 14290 }
14290 return len; 14291 return len;
14291 } 14292 }
14292 14293
14293 14294
14294 const char* String::ToUserCString(intptr_t maxLen) const { 14295 const char* String::ToUserCString(intptr_t max_len, intptr_t nesting) const {
14295 // Compute the needed length for the buffer. 14296 // Compute the needed length for the buffer.
14296 const intptr_t escapedLen = EscapedStringLen(maxLen); 14297 const intptr_t escaped_len = EscapedStringLen(max_len);
14297 intptr_t printLen = escapedLen; 14298 intptr_t print_len = escaped_len;
14298 intptr_t bufferLen = escapedLen + 2; // +2 for quotes. 14299 intptr_t buffer_len = escaped_len + 2; // +2 for quotes.
14299 if (bufferLen > maxLen) { 14300 if (buffer_len > max_len) {
14300 bufferLen = maxLen; // Truncate. 14301 buffer_len = max_len; // Truncate.
14301 printLen = maxLen - 5; // -2 for quotes, -3 for elipsis. 14302 print_len = max_len - 5; // -2 for quotes, -3 for elipsis.
14302 } 14303 }
14303 14304
14304 // Allocate the buffer. 14305 // Allocate the buffer.
14305 Zone* zone = Isolate::Current()->current_zone(); 14306 Zone* zone = Isolate::Current()->current_zone();
14306 char* buffer = zone->Alloc<char>(bufferLen + 1); 14307 char* buffer = zone->Alloc<char>(buffer_len + 1);
14307 14308
14308 // Leading quote. 14309 // Leading quote.
14309 intptr_t pos = 0; 14310 intptr_t pos = 0;
14310 buffer[pos++] = '\"'; 14311 buffer[pos++] = '\"';
14311 14312
14312 // Print escaped string. 14313 // Print escaped string.
14313 pos += EscapedString((buffer + pos), printLen); 14314 pos += EscapedString((buffer + pos), print_len);
14314 14315
14315 // Trailing quote. 14316 // Trailing quote.
14316 buffer[pos++] = '\"'; 14317 buffer[pos++] = '\"';
14317 14318
14318 if (printLen < escapedLen) { 14319 if (print_len < escaped_len) {
14319 buffer[pos++] = '.'; 14320 buffer[pos++] = '.';
14320 buffer[pos++] = '.'; 14321 buffer[pos++] = '.';
14321 buffer[pos++] = '.'; 14322 buffer[pos++] = '.';
14322 } 14323 }
14323 ASSERT(pos <= bufferLen); 14324 ASSERT(pos <= buffer_len);
14324 buffer[pos++] = '\0'; 14325 buffer[pos++] = '\0';
14325 14326
14326 return buffer; 14327 return buffer;
14327 } 14328 }
14328 14329
14329 14330
14330 void String::PrintToJSONStream(JSONStream* stream, bool ref) const { 14331 void String::PrintToJSONStream(JSONStream* stream, bool ref) const {
14331 Instance::PrintToJSONStream(stream, ref); 14332 Instance::PrintToJSONStream(stream, ref);
14332 } 14333 }
14333 14334
(...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after
15376 return "_GrowableList NULL"; 15377 return "_GrowableList NULL";
15377 } 15378 }
15378 const char* format = "Instance(length:%" Pd ") of '_GrowableList'"; 15379 const char* format = "Instance(length:%" Pd ") of '_GrowableList'";
15379 intptr_t len = OS::SNPrint(NULL, 0, format, Length()) + 1; 15380 intptr_t len = OS::SNPrint(NULL, 0, format, Length()) + 1;
15380 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 15381 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
15381 OS::SNPrint(chars, len, format, Length()); 15382 OS::SNPrint(chars, len, format, Length());
15382 return chars; 15383 return chars;
15383 } 15384 }
15384 15385
15385 15386
15387 const char* GrowableObjectArray::ToUserCString(intptr_t max_len,
15388 intptr_t nesting) const {
15389 if (Length() == 0) {
15390 return "[]";
15391 }
15392 if (nesting > 3) {
15393 return "[...]";
15394 }
15395
15396 Isolate* isolate = Isolate::Current();
15397 Zone* zone = isolate->current_zone();
15398 Object& obj = Object::Handle(isolate);
15399 Instance& element = Instance::Handle(isolate);
15400
15401 // Pre-print the suffix that we will use if the string is truncated.
15402 // It is important to know the suffix length when deciding where to
15403 // limit the list.
15404 char trunc_suffix[16];
Cutch 2013/12/13 19:22:46 const intptr_t kTruncSuffixLen = 16;
turnidge 2013/12/13 19:29:58 Done.
15405 intptr_t trunc_suffix_len;
15406 if (nesting == 0) {
15407 trunc_suffix_len = OS::SNPrint(trunc_suffix, 16, "...](length:%" Pd ")",
15408 Length());
15409 } else {
15410 trunc_suffix_len = OS::SNPrint(trunc_suffix, 16, "...]");
15411 }
15412 bool truncate = false;
15413
15414 const int kMaxPrintElements = 128;
15415 const char* strings[kMaxPrintElements];
15416 intptr_t print_len = 1; // +1 for "["
15417
15418 // Figure out how many elements will fit in the string.
15419 int i = 0;
15420 while (i < Length()) {
15421 if (i == kMaxPrintElements) {
15422 if (i < Length()) {
15423 truncate = true;
15424 }
15425 break;
15426 }
15427 obj = At(i);
15428 if (!obj.IsInstance()) {
15429 // Bail.
15430 UNREACHABLE();
15431 return "[<invalid list>]";
15432 }
15433 element ^= obj.raw();
15434
15435 // Choose max child length. This is chosen so that it is small
15436 // enough to maybe fit but not so small that we can't print
15437 // anything.
15438 int child_max_len = max_len - print_len;
15439 if ((i + 1) < Length()) {
15440 child_max_len -= (trunc_suffix_len + 1); // 1 for ","
15441 } else {
15442 child_max_len -= 1; // 1 for "]"
15443 }
15444 if (child_max_len < 8) {
15445 child_max_len = 8;
15446 }
15447
15448 strings[i] = element.ToUserCString(child_max_len, nesting + 1);
15449 print_len += strlen(strings[i]) + 1; // +1 for "," or "]"
15450 i++;
15451 if (print_len > max_len) {
15452 truncate = true;
15453 break;
15454 }
15455 }
15456 if (truncate) {
15457 // Go backwards until there is enough room for the truncation suffix.
15458 while (i >= 0 && (print_len + trunc_suffix_len) > max_len) {
15459 i--;
15460 print_len -= (strlen(strings[i]) + 1); // +1 for ","
15461 }
15462 }
15463
15464 // Finally, allocate and print the string.
15465 int num_to_print = i;
15466 char* buffer = zone->Alloc<char>(print_len + 1); // +1 for "\0"
15467 intptr_t pos = 0;
15468 buffer[pos++] = '[';
15469 for (i = 0; i < num_to_print; i++) {
15470 if ((i + 1) == Length()) {
15471 pos += OS::SNPrint((buffer + pos), (max_len + 1 - pos),
15472 "%s]", strings[i]);
15473 } else {
15474 pos += OS::SNPrint((buffer + pos), (max_len + 1 - pos),
15475 "%s,", strings[i]);
15476 }
15477 }
15478 if (i < Length()) {
15479 pos += OS::SNPrint((buffer + pos), (max_len + 1 - pos), "%s", trunc_suffix);
15480 }
15481 ASSERT(pos <= max_len);
15482 buffer[pos] = '\0';
15483 return buffer;
15484 }
15485
15486
15386 void GrowableObjectArray::PrintToJSONStream(JSONStream* stream, 15487 void GrowableObjectArray::PrintToJSONStream(JSONStream* stream,
15387 bool ref) const { 15488 bool ref) const {
15388 Instance::PrintToJSONStream(stream, ref); 15489 Instance::PrintToJSONStream(stream, ref);
15389 } 15490 }
15390 15491
15391 15492
15392 RawFloat32x4* Float32x4::New(float v0, float v1, float v2, float v3, 15493 RawFloat32x4* Float32x4::New(float v0, float v1, float v2, float v3,
15393 Heap::Space space) { 15494 Heap::Space space) {
15394 ASSERT(Isolate::Current()->object_store()->float32x4_class() != 15495 ASSERT(Isolate::Current()->object_store()->float32x4_class() !=
15395 Class::null()); 15496 Class::null());
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after
16158 return "_MirrorReference"; 16259 return "_MirrorReference";
16159 } 16260 }
16160 16261
16161 16262
16162 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 16263 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
16163 Instance::PrintToJSONStream(stream, ref); 16264 Instance::PrintToJSONStream(stream, ref);
16164 } 16265 }
16165 16266
16166 16267
16167 } // namespace dart 16268 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698