OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 #include "vm/debugger.h" |
| 6 #include "vm/disassembler.h" |
| 7 #include "vm/object.h" |
| 8 #include "vm/object_store.h" |
| 9 #include "vm/stub_code.h" |
| 10 #include "vm/symbols.h" |
| 11 |
| 12 namespace dart { |
| 13 |
| 14 #ifndef PRODUCT |
| 15 |
| 16 static void AddNameProperties(JSONObject* jsobj, |
| 17 const String& name, |
| 18 const String& vm_name) { |
| 19 jsobj->AddProperty("name", name.ToCString()); |
| 20 if (!name.Equals(vm_name)) { |
| 21 jsobj->AddProperty("_vmName", vm_name.ToCString()); |
| 22 } |
| 23 } |
| 24 |
| 25 |
| 26 void Object::AddCommonObjectProperties(JSONObject* jsobj, |
| 27 const char* protocol_type, |
| 28 bool ref) const { |
| 29 const char* vm_type = JSONType(); |
| 30 bool same_type = (strcmp(protocol_type, vm_type) == 0); |
| 31 if (ref) { |
| 32 jsobj->AddPropertyF("type", "@%s", protocol_type); |
| 33 } else { |
| 34 jsobj->AddProperty("type", protocol_type); |
| 35 } |
| 36 if (!same_type) { |
| 37 jsobj->AddProperty("_vmType", vm_type); |
| 38 } |
| 39 if (!ref || IsInstance() || IsNull()) { |
| 40 // TODO(turnidge): Provide the type arguments here too? |
| 41 const Class& cls = Class::Handle(this->clazz()); |
| 42 jsobj->AddProperty("class", cls); |
| 43 } |
| 44 if (!ref) { |
| 45 if (raw()->IsHeapObject()) { |
| 46 jsobj->AddProperty("size", raw()->Size()); |
| 47 } else { |
| 48 jsobj->AddProperty("size", (intptr_t)0); |
| 49 } |
| 50 } |
| 51 } |
| 52 |
| 53 |
| 54 void Object::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 55 JSONObject jsobj(stream); |
| 56 AddCommonObjectProperties(&jsobj, "Object", ref); |
| 57 jsobj.AddServiceId(*this); |
| 58 if (ref) { |
| 59 return; |
| 60 } |
| 61 } |
| 62 |
| 63 |
| 64 void Object::PrintJSON(JSONStream* stream, bool ref) const { |
| 65 if (IsNull()) { |
| 66 JSONObject jsobj(stream); |
| 67 AddCommonObjectProperties(&jsobj, "Instance", ref); |
| 68 jsobj.AddProperty("kind", "Null"); |
| 69 jsobj.AddFixedServiceId("objects/null"); |
| 70 jsobj.AddProperty("valueAsString", "null"); |
| 71 } else { |
| 72 PrintJSONImpl(stream, ref); |
| 73 } |
| 74 } |
| 75 |
| 76 |
| 77 void Class::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 78 Isolate* isolate = Isolate::Current(); |
| 79 JSONObject jsobj(stream); |
| 80 if ((raw() == Class::null()) || (id() == kFreeListElement)) { |
| 81 // TODO(turnidge): This is weird and needs to be changed. |
| 82 jsobj.AddProperty("type", "null"); |
| 83 return; |
| 84 } |
| 85 AddCommonObjectProperties(&jsobj, "Class", ref); |
| 86 jsobj.AddFixedServiceId("classes/%" Pd "", id()); |
| 87 const String& user_name = String::Handle(PrettyName()); |
| 88 const String& vm_name = String::Handle(Name()); |
| 89 AddNameProperties(&jsobj, user_name, vm_name); |
| 90 if (ref) { |
| 91 return; |
| 92 } |
| 93 |
| 94 const Error& err = Error::Handle(EnsureIsFinalized(Thread::Current())); |
| 95 if (!err.IsNull()) { |
| 96 jsobj.AddProperty("error", err); |
| 97 } |
| 98 jsobj.AddProperty("abstract", is_abstract()); |
| 99 jsobj.AddProperty("const", is_const()); |
| 100 jsobj.AddProperty("_finalized", is_finalized()); |
| 101 jsobj.AddProperty("_implemented", is_implemented()); |
| 102 jsobj.AddProperty("_patch", is_patch()); |
| 103 jsobj.AddProperty("_traceAllocations", TraceAllocation(isolate)); |
| 104 const Class& superClass = Class::Handle(SuperClass()); |
| 105 if (!superClass.IsNull()) { |
| 106 jsobj.AddProperty("super", superClass); |
| 107 } |
| 108 jsobj.AddProperty("library", Object::Handle(library())); |
| 109 const Script& script = Script::Handle(this->script()); |
| 110 if (!script.IsNull()) { |
| 111 jsobj.AddLocation(script, token_pos(), ComputeEndTokenPos()); |
| 112 } |
| 113 { |
| 114 JSONArray interfaces_array(&jsobj, "interfaces"); |
| 115 const Array& interface_array = Array::Handle(interfaces()); |
| 116 Type& interface_type = Type::Handle(); |
| 117 if (!interface_array.IsNull()) { |
| 118 for (intptr_t i = 0; i < interface_array.Length(); ++i) { |
| 119 interface_type ^= interface_array.At(i); |
| 120 interfaces_array.AddValue(interface_type); |
| 121 } |
| 122 } |
| 123 } |
| 124 { |
| 125 JSONArray fields_array(&jsobj, "fields"); |
| 126 const Array& field_array = Array::Handle(fields()); |
| 127 Field& field = Field::Handle(); |
| 128 if (!field_array.IsNull()) { |
| 129 for (intptr_t i = 0; i < field_array.Length(); ++i) { |
| 130 field ^= field_array.At(i); |
| 131 fields_array.AddValue(field); |
| 132 } |
| 133 } |
| 134 } |
| 135 { |
| 136 JSONArray functions_array(&jsobj, "functions"); |
| 137 const Array& function_array = Array::Handle(functions()); |
| 138 Function& function = Function::Handle(); |
| 139 if (!function_array.IsNull()) { |
| 140 for (intptr_t i = 0; i < function_array.Length(); i++) { |
| 141 function ^= function_array.At(i); |
| 142 functions_array.AddValue(function); |
| 143 } |
| 144 } |
| 145 } |
| 146 { |
| 147 JSONArray subclasses_array(&jsobj, "subclasses"); |
| 148 const GrowableObjectArray& subclasses = |
| 149 GrowableObjectArray::Handle(direct_subclasses()); |
| 150 if (!subclasses.IsNull()) { |
| 151 Class& subclass = Class::Handle(); |
| 152 for (intptr_t i = 0; i < subclasses.Length(); ++i) { |
| 153 // TODO(turnidge): Use the Type directly once regis has added |
| 154 // types to the vmservice. |
| 155 subclass ^= subclasses.At(i); |
| 156 subclasses_array.AddValue(subclass); |
| 157 } |
| 158 } |
| 159 } |
| 160 { |
| 161 ClassTable* class_table = Isolate::Current()->class_table(); |
| 162 const ClassHeapStats* stats = class_table->StatsWithUpdatedSize(id()); |
| 163 if (stats != NULL) { |
| 164 JSONObject allocation_stats(&jsobj, "_allocationStats"); |
| 165 stats->PrintToJSONObject(*this, &allocation_stats); |
| 166 } |
| 167 } |
| 168 } |
| 169 |
| 170 |
| 171 void UnresolvedClass::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 172 Object::PrintJSONImpl(stream, ref); |
| 173 } |
| 174 |
| 175 |
| 176 void TypeArguments::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 177 JSONObject jsobj(stream); |
| 178 // The index in the canonical_type_arguments table cannot be used as part of |
| 179 // the object id (as in typearguments/id), because the indices are not |
| 180 // preserved when the table grows and the entries get rehashed. Use the ring. |
| 181 Isolate* isolate = Isolate::Current(); |
| 182 ObjectStore* object_store = isolate->object_store(); |
| 183 const Array& table = Array::Handle(object_store->canonical_type_arguments()); |
| 184 ASSERT(table.Length() > 0); |
| 185 AddCommonObjectProperties(&jsobj, "TypeArguments", ref); |
| 186 jsobj.AddServiceId(*this); |
| 187 const String& user_name = String::Handle(PrettyName()); |
| 188 const String& vm_name = String::Handle(Name()); |
| 189 AddNameProperties(&jsobj, user_name, vm_name); |
| 190 if (ref) { |
| 191 return; |
| 192 } |
| 193 { |
| 194 JSONArray jsarr(&jsobj, "types"); |
| 195 AbstractType& type_arg = AbstractType::Handle(); |
| 196 for (intptr_t i = 0; i < Length(); i++) { |
| 197 type_arg = TypeAt(i); |
| 198 jsarr.AddValue(type_arg); |
| 199 } |
| 200 } |
| 201 if (!IsInstantiated()) { |
| 202 JSONArray jsarr(&jsobj, "_instantiations"); |
| 203 Array& prior_instantiations = Array::Handle(instantiations()); |
| 204 ASSERT(prior_instantiations.Length() > 0); // Always at least a sentinel. |
| 205 TypeArguments& type_args = TypeArguments::Handle(); |
| 206 intptr_t i = 0; |
| 207 while (true) { |
| 208 if (prior_instantiations.At(i) == Smi::New(StubCode::kNoInstantiator)) { |
| 209 break; |
| 210 } |
| 211 JSONObject instantiation(&jsarr); |
| 212 type_args ^= prior_instantiations.At(i); |
| 213 instantiation.AddProperty("instantiator", type_args, true); |
| 214 type_args ^= prior_instantiations.At(i + 1); |
| 215 instantiation.AddProperty("instantiated", type_args, true); |
| 216 i += 2; |
| 217 } |
| 218 } |
| 219 } |
| 220 |
| 221 |
| 222 void PatchClass::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 223 Object::PrintJSONImpl(stream, ref); |
| 224 } |
| 225 |
| 226 |
| 227 static void AddFunctionServiceId(const JSONObject& jsobj, |
| 228 const Function& f, |
| 229 const Class& cls) { |
| 230 // Special kinds of functions use indices in their respective lists. |
| 231 intptr_t id = -1; |
| 232 const char* selector = NULL; |
| 233 if (f.IsNonImplicitClosureFunction()) { |
| 234 id = Isolate::Current()->FindClosureIndex(f); |
| 235 selector = "closures"; |
| 236 } else if (f.IsImplicitClosureFunction()) { |
| 237 id = cls.FindImplicitClosureFunctionIndex(f); |
| 238 selector = "implicit_closures"; |
| 239 } else if (f.IsNoSuchMethodDispatcher() || f.IsInvokeFieldDispatcher()) { |
| 240 id = cls.FindInvocationDispatcherFunctionIndex(f); |
| 241 selector = "dispatchers"; |
| 242 } |
| 243 if (id != -1) { |
| 244 ASSERT(selector != NULL); |
| 245 jsobj.AddFixedServiceId("classes/%" Pd "/%s/%" Pd "", |
| 246 cls.id(), selector, id); |
| 247 return; |
| 248 } |
| 249 // Regular functions known to their owner use their name (percent-encoded). |
| 250 String& name = String::Handle(f.name()); |
| 251 if (cls.LookupFunction(name) == f.raw()) { |
| 252 name = String::EncodeIRI(name); |
| 253 jsobj.AddFixedServiceId("classes/%" Pd "/functions/%s", |
| 254 cls.id(), name.ToCString()); |
| 255 return; |
| 256 } |
| 257 // Oddball functions (not known to their owner) fall back to use the object |
| 258 // id ring. Current known examples are signature functions of closures |
| 259 // and stubs like 'megamorphic_miss'. |
| 260 jsobj.AddServiceId(f); |
| 261 } |
| 262 |
| 263 |
| 264 void Function::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 265 Class& cls = Class::Handle(Owner()); |
| 266 ASSERT(!cls.IsNull()); |
| 267 Error& err = Error::Handle(); |
| 268 err ^= cls.EnsureIsFinalized(Thread::Current()); |
| 269 ASSERT(err.IsNull()); |
| 270 JSONObject jsobj(stream); |
| 271 AddCommonObjectProperties(&jsobj, "Function", ref); |
| 272 AddFunctionServiceId(jsobj, *this, cls); |
| 273 const String& user_name = String::Handle(PrettyName()); |
| 274 const String& vm_name = String::Handle(name()); |
| 275 AddNameProperties(&jsobj, user_name, vm_name); |
| 276 const Function& parent = Function::Handle(parent_function()); |
| 277 if (!parent.IsNull()) { |
| 278 jsobj.AddProperty("owner", parent); |
| 279 } else if (cls.IsTopLevel()) { |
| 280 const Library& library = Library::Handle(cls.library()); |
| 281 jsobj.AddProperty("owner", library); |
| 282 } else { |
| 283 jsobj.AddProperty("owner", cls); |
| 284 } |
| 285 |
| 286 const char* kind_string = Function::KindToCString(kind()); |
| 287 jsobj.AddProperty("_kind", kind_string); |
| 288 jsobj.AddProperty("static", is_static()); |
| 289 jsobj.AddProperty("const", is_const()); |
| 290 jsobj.AddProperty("_intrinsic", is_intrinsic()); |
| 291 jsobj.AddProperty("_native", is_native()); |
| 292 if (ref) { |
| 293 return; |
| 294 } |
| 295 Code& code = Code::Handle(CurrentCode()); |
| 296 if (!code.IsNull()) { |
| 297 jsobj.AddProperty("code", code); |
| 298 } |
| 299 Array& ics = Array::Handle(ic_data_array()); |
| 300 if (!ics.IsNull()) { |
| 301 jsobj.AddProperty("_icDataArray", ics); |
| 302 } |
| 303 jsobj.AddProperty("_optimizable", is_optimizable()); |
| 304 jsobj.AddProperty("_inlinable", is_inlinable()); |
| 305 jsobj.AddProperty("_recognized", IsRecognized()); |
| 306 code = unoptimized_code(); |
| 307 if (!code.IsNull()) { |
| 308 jsobj.AddProperty("_unoptimizedCode", code); |
| 309 } |
| 310 jsobj.AddProperty("_usageCounter", usage_counter()); |
| 311 jsobj.AddProperty("_optimizedCallSiteCount", optimized_call_site_count()); |
| 312 jsobj.AddProperty("_deoptimizations", |
| 313 static_cast<intptr_t>(deoptimization_counter())); |
| 314 if ((kind() == RawFunction::kImplicitGetter) || |
| 315 (kind() == RawFunction::kImplicitSetter) || |
| 316 (kind() == RawFunction::kImplicitStaticFinalGetter)) { |
| 317 const Field& field = Field::Handle(LookupImplicitGetterSetterField()); |
| 318 if (!field.IsNull()) { |
| 319 jsobj.AddProperty("_field", field); |
| 320 } |
| 321 } |
| 322 |
| 323 const Script& script = Script::Handle(this->script()); |
| 324 if (!script.IsNull()) { |
| 325 jsobj.AddLocation(script, token_pos(), end_token_pos()); |
| 326 } |
| 327 } |
| 328 |
| 329 |
| 330 void RedirectionData::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 331 Object::PrintJSONImpl(stream, ref); |
| 332 } |
| 333 |
| 334 |
| 335 void Field::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 336 JSONObject jsobj(stream); |
| 337 Class& cls = Class::Handle(owner()); |
| 338 String& field_name = String::Handle(name()); |
| 339 field_name = String::EncodeIRI(field_name); |
| 340 AddCommonObjectProperties(&jsobj, "Field", ref); |
| 341 jsobj.AddFixedServiceId("classes/%" Pd "/fields/%s", |
| 342 cls.id(), field_name.ToCString()); |
| 343 |
| 344 const String& user_name = String::Handle(PrettyName()); |
| 345 const String& vm_name = String::Handle(name()); |
| 346 AddNameProperties(&jsobj, user_name, vm_name); |
| 347 if (cls.IsTopLevel()) { |
| 348 const Library& library = Library::Handle(cls.library()); |
| 349 jsobj.AddProperty("owner", library); |
| 350 } else { |
| 351 jsobj.AddProperty("owner", cls); |
| 352 } |
| 353 |
| 354 AbstractType& declared_type = AbstractType::Handle(type()); |
| 355 jsobj.AddProperty("declaredType", declared_type); |
| 356 jsobj.AddProperty("static", is_static()); |
| 357 jsobj.AddProperty("final", is_final()); |
| 358 jsobj.AddProperty("const", is_const()); |
| 359 if (ref) { |
| 360 return; |
| 361 } |
| 362 if (is_static()) { |
| 363 const Instance& valueObj = Instance::Handle(StaticValue()); |
| 364 jsobj.AddProperty("staticValue", valueObj); |
| 365 } |
| 366 |
| 367 jsobj.AddProperty("_guardNullable", is_nullable()); |
| 368 if (guarded_cid() == kIllegalCid) { |
| 369 jsobj.AddProperty("_guardClass", "unknown"); |
| 370 } else if (guarded_cid() == kDynamicCid) { |
| 371 jsobj.AddProperty("_guardClass", "dynamic"); |
| 372 } else { |
| 373 ClassTable* table = Isolate::Current()->class_table(); |
| 374 ASSERT(table->IsValidIndex(guarded_cid())); |
| 375 cls ^= table->At(guarded_cid()); |
| 376 jsobj.AddProperty("_guardClass", cls); |
| 377 } |
| 378 if (guarded_list_length() == kUnknownFixedLength) { |
| 379 jsobj.AddProperty("_guardLength", "unknown"); |
| 380 } else if (guarded_list_length() == kNoFixedLength) { |
| 381 jsobj.AddProperty("_guardLength", "variable"); |
| 382 } else { |
| 383 jsobj.AddProperty("_guardLength", guarded_list_length()); |
| 384 } |
| 385 const Class& origin_cls = Class::Handle(origin()); |
| 386 const Script& script = Script::Handle(origin_cls.script()); |
| 387 if (!script.IsNull()) { |
| 388 jsobj.AddLocation(script, token_pos()); |
| 389 } |
| 390 } |
| 391 |
| 392 |
| 393 void LiteralToken::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 394 Object::PrintJSONImpl(stream, ref); |
| 395 } |
| 396 |
| 397 |
| 398 void TokenStream::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 399 JSONObject jsobj(stream); |
| 400 AddCommonObjectProperties(&jsobj, "Object", ref); |
| 401 // TODO(johnmccutchan): Generate a stable id. TokenStreams hang off |
| 402 // a Script object but do not have a back reference to generate a stable id. |
| 403 jsobj.AddServiceId(*this); |
| 404 if (ref) { |
| 405 return; |
| 406 } |
| 407 const String& private_key = String::Handle(PrivateKey()); |
| 408 jsobj.AddProperty("privateKey", private_key); |
| 409 // TODO(johnmccutchan): Add support for printing LiteralTokens and add |
| 410 // them to members array. |
| 411 JSONArray members(&jsobj, "members"); |
| 412 } |
| 413 |
| 414 |
| 415 // See also Dart_ScriptGetTokenInfo. |
| 416 void Script::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 417 JSONObject jsobj(stream); |
| 418 AddCommonObjectProperties(&jsobj, "Script", ref); |
| 419 const String& uri = String::Handle(url()); |
| 420 ASSERT(!uri.IsNull()); |
| 421 const String& encoded_uri = String::Handle(String::EncodeIRI(uri)); |
| 422 ASSERT(!encoded_uri.IsNull()); |
| 423 const Library& lib = Library::Handle(FindLibrary()); |
| 424 if (kind() == RawScript::kEvaluateTag) { |
| 425 jsobj.AddServiceId(*this); |
| 426 } else { |
| 427 ASSERT(!lib.IsNull()); |
| 428 jsobj.AddFixedServiceId("libraries/%" Pd "/scripts/%s", |
| 429 lib.index(), encoded_uri.ToCString()); |
| 430 } |
| 431 jsobj.AddPropertyStr("uri", uri); |
| 432 jsobj.AddProperty("_kind", GetKindAsCString()); |
| 433 if (ref) { |
| 434 return; |
| 435 } |
| 436 if (!lib.IsNull()) { |
| 437 jsobj.AddProperty("library", lib); |
| 438 } |
| 439 const String& source = String::Handle(Source()); |
| 440 jsobj.AddProperty("lineOffset", line_offset()); |
| 441 jsobj.AddProperty("columnOffset", col_offset()); |
| 442 if (!source.IsNull()) { |
| 443 jsobj.AddPropertyStr("source", source); |
| 444 } |
| 445 |
| 446 // Print the line number table |
| 447 if (!source.IsNull()) { |
| 448 JSONArray tokenPosTable(&jsobj, "tokenPosTable"); |
| 449 |
| 450 const GrowableObjectArray& lineNumberArray = |
| 451 GrowableObjectArray::Handle(GenerateLineNumberArray()); |
| 452 Object& value = Object::Handle(); |
| 453 intptr_t pos = 0; |
| 454 |
| 455 // Skip leading null. |
| 456 ASSERT(lineNumberArray.Length() > 0); |
| 457 value = lineNumberArray.At(pos); |
| 458 ASSERT(value.IsNull()); |
| 459 pos++; |
| 460 |
| 461 while (pos < lineNumberArray.Length()) { |
| 462 JSONArray lineInfo(&tokenPosTable); |
| 463 while (pos < lineNumberArray.Length()) { |
| 464 value = lineNumberArray.At(pos); |
| 465 pos++; |
| 466 if (value.IsNull()) { |
| 467 break; |
| 468 } |
| 469 const Smi& smi = Smi::Cast(value); |
| 470 lineInfo.AddValue(smi.Value()); |
| 471 } |
| 472 } |
| 473 } |
| 474 } |
| 475 |
| 476 |
| 477 void Library::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 478 intptr_t id = index(); |
| 479 ASSERT(id >= 0); |
| 480 JSONObject jsobj(stream); |
| 481 AddCommonObjectProperties(&jsobj, "Library", ref); |
| 482 jsobj.AddFixedServiceId("libraries/%" Pd "", id); |
| 483 const String& vm_name = String::Handle(name()); |
| 484 const String& user_name = |
| 485 String::Handle(String::IdentifierPrettyName(vm_name)); |
| 486 AddNameProperties(&jsobj, user_name, vm_name); |
| 487 const String& library_url = String::Handle(url()); |
| 488 jsobj.AddPropertyStr("uri", library_url); |
| 489 if (ref) { |
| 490 return; |
| 491 } |
| 492 jsobj.AddProperty("debuggable", IsDebuggable()); |
| 493 { |
| 494 JSONArray jsarr(&jsobj, "classes"); |
| 495 ClassDictionaryIterator class_iter(*this); |
| 496 Class& klass = Class::Handle(); |
| 497 while (class_iter.HasNext()) { |
| 498 klass = class_iter.GetNextClass(); |
| 499 if (!klass.IsMixinApplication()) { |
| 500 jsarr.AddValue(klass); |
| 501 } |
| 502 } |
| 503 } |
| 504 { |
| 505 JSONArray jsarr(&jsobj, "dependencies"); |
| 506 |
| 507 Array& ports = Array::Handle(); |
| 508 Namespace& ns = Namespace::Handle(); |
| 509 Library& target = Library::Handle(); |
| 510 |
| 511 // Unprefixed imports. |
| 512 ports = imports(); |
| 513 for (intptr_t i = 0; i < ports.Length(); i++) { |
| 514 ns ^= ports.At(i); |
| 515 if (ns.IsNull()) continue; |
| 516 |
| 517 JSONObject jsdep(&jsarr); |
| 518 jsdep.AddProperty("isDeferred", false); |
| 519 jsdep.AddProperty("isExport", false); |
| 520 jsdep.AddProperty("isImport", true); |
| 521 target = ns.library(); |
| 522 jsdep.AddProperty("target", target); |
| 523 } |
| 524 |
| 525 // Exports. |
| 526 ports = exports(); |
| 527 for (intptr_t i = 0; i < ports.Length(); i++) { |
| 528 ns ^= ports.At(i); |
| 529 if (ns.IsNull()) continue; |
| 530 |
| 531 JSONObject jsdep(&jsarr); |
| 532 jsdep.AddProperty("isDeferred", false); |
| 533 jsdep.AddProperty("isExport", true); |
| 534 jsdep.AddProperty("isImport", false); |
| 535 target = ns.library(); |
| 536 jsdep.AddProperty("target", target); |
| 537 } |
| 538 |
| 539 // Prefixed imports. |
| 540 DictionaryIterator entries(*this); |
| 541 Object& entry = Object::Handle(); |
| 542 LibraryPrefix& prefix = LibraryPrefix::Handle(); |
| 543 String& prefixName = String::Handle(); |
| 544 while (entries.HasNext()) { |
| 545 entry = entries.GetNext(); |
| 546 if (entry.IsLibraryPrefix()) { |
| 547 prefix ^= entry.raw(); |
| 548 ports = prefix.imports(); |
| 549 for (intptr_t i = 0; i < ports.Length(); i++) { |
| 550 ns ^= ports.At(i); |
| 551 if (ns.IsNull()) continue; |
| 552 |
| 553 JSONObject jsdep(&jsarr); |
| 554 jsdep.AddProperty("isDeferred", prefix.is_deferred_load()); |
| 555 jsdep.AddProperty("isExport", false); |
| 556 jsdep.AddProperty("isImport", true); |
| 557 prefixName = prefix.name(); |
| 558 ASSERT(!prefixName.IsNull()); |
| 559 jsdep.AddProperty("prefix", prefixName.ToCString()); |
| 560 target = ns.library(); |
| 561 jsdep.AddProperty("target", target); |
| 562 } |
| 563 } |
| 564 } |
| 565 } |
| 566 { |
| 567 JSONArray jsarr(&jsobj, "variables"); |
| 568 DictionaryIterator entries(*this); |
| 569 Object& entry = Object::Handle(); |
| 570 while (entries.HasNext()) { |
| 571 entry = entries.GetNext(); |
| 572 if (entry.IsField()) { |
| 573 jsarr.AddValue(entry); |
| 574 } |
| 575 } |
| 576 } |
| 577 { |
| 578 JSONArray jsarr(&jsobj, "functions"); |
| 579 DictionaryIterator entries(*this); |
| 580 Object& entry = Object::Handle(); |
| 581 while (entries.HasNext()) { |
| 582 entry = entries.GetNext(); |
| 583 if (entry.IsFunction()) { |
| 584 const Function& func = Function::Cast(entry); |
| 585 if (func.kind() == RawFunction::kRegularFunction || |
| 586 func.kind() == RawFunction::kGetterFunction || |
| 587 func.kind() == RawFunction::kSetterFunction) { |
| 588 jsarr.AddValue(func); |
| 589 } |
| 590 } |
| 591 } |
| 592 } |
| 593 { |
| 594 JSONArray jsarr(&jsobj, "scripts"); |
| 595 Array& scripts = Array::Handle(LoadedScripts()); |
| 596 Script& script = Script::Handle(); |
| 597 for (intptr_t i = 0; i < scripts.Length(); i++) { |
| 598 script ^= scripts.At(i); |
| 599 jsarr.AddValue(script); |
| 600 } |
| 601 } |
| 602 } |
| 603 |
| 604 |
| 605 void LibraryPrefix::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 606 Object::PrintJSONImpl(stream, ref); |
| 607 } |
| 608 |
| 609 |
| 610 void Namespace::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 611 Object::PrintJSONImpl(stream, ref); |
| 612 } |
| 613 |
| 614 |
| 615 void Instructions::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 616 JSONObject jsobj(stream); |
| 617 AddCommonObjectProperties(&jsobj, "Object", ref); |
| 618 jsobj.AddServiceId(*this); |
| 619 if (ref) { |
| 620 return; |
| 621 } |
| 622 } |
| 623 |
| 624 |
| 625 void ObjectPool::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 626 JSONObject jsobj(stream); |
| 627 AddCommonObjectProperties(&jsobj, "Object", ref); |
| 628 jsobj.AddServiceId(*this); |
| 629 jsobj.AddProperty("length", Length()); |
| 630 if (ref) { |
| 631 return; |
| 632 } |
| 633 |
| 634 { |
| 635 JSONArray jsarr(&jsobj, "_entries"); |
| 636 uword imm; |
| 637 Object& obj = Object::Handle(); |
| 638 for (intptr_t i = 0; i < Length(); i++) { |
| 639 JSONObject jsentry(stream); |
| 640 jsentry.AddProperty("offset", OffsetFromIndex(i)); |
| 641 switch (InfoAt(i)) { |
| 642 case ObjectPool::kTaggedObject: |
| 643 obj = ObjectAt(i); |
| 644 jsentry.AddProperty("kind", "Object"); |
| 645 jsentry.AddProperty("value", obj); |
| 646 break; |
| 647 case ObjectPool::kImmediate: |
| 648 imm = RawValueAt(i); |
| 649 jsentry.AddProperty("kind", "Immediate"); |
| 650 jsentry.AddProperty64("value", imm); |
| 651 break; |
| 652 case ObjectPool::kNativeEntry: |
| 653 imm = RawValueAt(i); |
| 654 jsentry.AddProperty("kind", "NativeEntry"); |
| 655 jsentry.AddProperty64("value", imm); |
| 656 break; |
| 657 default: |
| 658 UNREACHABLE(); |
| 659 } |
| 660 } |
| 661 } |
| 662 } |
| 663 |
| 664 |
| 665 void PcDescriptors::PrintToJSONObject(JSONObject* jsobj, bool ref) const { |
| 666 AddCommonObjectProperties(jsobj, "Object", ref); |
| 667 // TODO(johnmccutchan): Generate a stable id. PcDescriptors hang off a Code |
| 668 // object but do not have a back reference to generate an ID. |
| 669 jsobj->AddServiceId(*this); |
| 670 if (ref) { |
| 671 return; |
| 672 } |
| 673 JSONArray members(jsobj, "members"); |
| 674 Iterator iter(*this, RawPcDescriptors::kAnyKind); |
| 675 while (iter.MoveNext()) { |
| 676 JSONObject descriptor(&members); |
| 677 descriptor.AddPropertyF("pcOffset", "%" Px "", iter.PcOffset()); |
| 678 descriptor.AddProperty("kind", KindAsStr(iter.Kind())); |
| 679 descriptor.AddProperty("deoptId", iter.DeoptId()); |
| 680 // TODO(turnidge): Use AddLocation instead. |
| 681 descriptor.AddProperty("tokenPos", iter.TokenPos()); |
| 682 descriptor.AddProperty("tryIndex", iter.TryIndex()); |
| 683 } |
| 684 } |
| 685 |
| 686 |
| 687 void PcDescriptors::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 688 JSONObject jsobj(stream); |
| 689 PrintToJSONObject(&jsobj, ref); |
| 690 } |
| 691 |
| 692 |
| 693 void CodeSourceMap::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 694 Object::PrintJSONImpl(stream, ref); |
| 695 } |
| 696 |
| 697 |
| 698 void Stackmap::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 699 Object::PrintJSONImpl(stream, ref); |
| 700 } |
| 701 |
| 702 |
| 703 void LocalVarDescriptors::PrintJSONImpl(JSONStream* stream, |
| 704 bool ref) const { |
| 705 JSONObject jsobj(stream); |
| 706 AddCommonObjectProperties(&jsobj, "Object", ref); |
| 707 // TODO(johnmccutchan): Generate a stable id. LocalVarDescriptors hang off |
| 708 // a Code object but do not have a back reference to generate an ID. |
| 709 jsobj.AddServiceId(*this); |
| 710 if (ref) { |
| 711 return; |
| 712 } |
| 713 JSONArray members(&jsobj, "members"); |
| 714 String& var_name = String::Handle(); |
| 715 for (intptr_t i = 0; i < Length(); i++) { |
| 716 RawLocalVarDescriptors::VarInfo info; |
| 717 var_name = GetName(i); |
| 718 GetInfo(i, &info); |
| 719 JSONObject var(&members); |
| 720 var.AddProperty("name", var_name.ToCString()); |
| 721 var.AddProperty("index", static_cast<intptr_t>(info.index())); |
| 722 var.AddProperty("beginPos", info.begin_pos); |
| 723 var.AddProperty("endPos", info.end_pos); |
| 724 var.AddProperty("scopeId", static_cast<intptr_t>(info.scope_id)); |
| 725 var.AddProperty("kind", KindToCString(info.kind())); |
| 726 } |
| 727 } |
| 728 |
| 729 |
| 730 void ExceptionHandlers::PrintJSONImpl(JSONStream* stream, |
| 731 bool ref) const { |
| 732 Object::PrintJSONImpl(stream, ref); |
| 733 } |
| 734 |
| 735 |
| 736 void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 737 JSONObject jsobj(stream); |
| 738 AddCommonObjectProperties(&jsobj, "Object", ref); |
| 739 jsobj.AddServiceId(*this); |
| 740 jsobj.AddProperty("_owner", Object::Handle(Owner())); |
| 741 jsobj.AddProperty("_selector", String::Handle(target_name()).ToCString()); |
| 742 if (ref) { |
| 743 return; |
| 744 } |
| 745 jsobj.AddProperty("_argumentsDescriptor", |
| 746 Object::Handle(arguments_descriptor())); |
| 747 jsobj.AddProperty("_entries", Object::Handle(ic_data())); |
| 748 } |
| 749 |
| 750 |
| 751 void ICData::PrintToJSONArray(const JSONArray& jsarray, |
| 752 TokenPosition token_pos, |
| 753 bool is_static_call) const { |
| 754 Isolate* isolate = Isolate::Current(); |
| 755 Class& cls = Class::Handle(); |
| 756 Function& func = Function::Handle(); |
| 757 |
| 758 JSONObject jsobj(&jsarray); |
| 759 jsobj.AddProperty("name", String::Handle(target_name()).ToCString()); |
| 760 jsobj.AddProperty("tokenPos", token_pos); |
| 761 // TODO(rmacnak): Figure out how to stringify DeoptReasons(). |
| 762 // jsobj.AddProperty("deoptReasons", ...); |
| 763 |
| 764 JSONArray cache_entries(&jsobj, "cacheEntries"); |
| 765 for (intptr_t i = 0; i < NumberOfChecks(); i++) { |
| 766 func = GetTargetAt(i); |
| 767 if (is_static_call) { |
| 768 cls ^= func.Owner(); |
| 769 } else { |
| 770 intptr_t cid = GetReceiverClassIdAt(i); |
| 771 cls ^= isolate->class_table()->At(cid); |
| 772 } |
| 773 intptr_t count = GetCountAt(i); |
| 774 JSONObject cache_entry(&cache_entries); |
| 775 if (cls.IsTopLevel()) { |
| 776 cache_entry.AddProperty("receiverContainer", |
| 777 Library::Handle(cls.library())); |
| 778 } else { |
| 779 cache_entry.AddProperty("receiverContainer", cls); |
| 780 } |
| 781 cache_entry.AddProperty("count", count); |
| 782 cache_entry.AddProperty("target", func); |
| 783 } |
| 784 } |
| 785 |
| 786 |
| 787 void ICData::PrintToJSONArrayNew(const JSONArray& jsarray, |
| 788 TokenPosition token_pos, |
| 789 bool is_static_call) const { |
| 790 Isolate* isolate = Isolate::Current(); |
| 791 Class& cls = Class::Handle(); |
| 792 Function& func = Function::Handle(); |
| 793 |
| 794 JSONObject jsobj(&jsarray); |
| 795 jsobj.AddProperty("name", String::Handle(target_name()).ToCString()); |
| 796 jsobj.AddProperty("tokenPos", token_pos.value()); |
| 797 // TODO(rmacnak): Figure out how to stringify DeoptReasons(). |
| 798 // jsobj.AddProperty("deoptReasons", ...); |
| 799 |
| 800 JSONArray cache_entries(&jsobj, "cacheEntries"); |
| 801 for (intptr_t i = 0; i < NumberOfChecks(); i++) { |
| 802 JSONObject cache_entry(&cache_entries); |
| 803 func = GetTargetAt(i); |
| 804 intptr_t count = GetCountAt(i); |
| 805 if (!is_static_call) { |
| 806 intptr_t cid = GetReceiverClassIdAt(i); |
| 807 cls ^= isolate->class_table()->At(cid); |
| 808 cache_entry.AddProperty("receiver", cls); |
| 809 } |
| 810 cache_entry.AddProperty("target", func); |
| 811 cache_entry.AddProperty("count", count); |
| 812 } |
| 813 } |
| 814 |
| 815 |
| 816 void Code::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 817 JSONObject jsobj(stream); |
| 818 AddCommonObjectProperties(&jsobj, "Code", ref); |
| 819 jsobj.AddFixedServiceId("code/%" Px64"-%" Px "", |
| 820 compile_timestamp(), |
| 821 EntryPoint()); |
| 822 const String& user_name = String::Handle(PrettyName()); |
| 823 const String& vm_name = String::Handle(Name()); |
| 824 AddNameProperties(&jsobj, user_name, vm_name); |
| 825 const bool is_stub = IsStubCode() || IsAllocationStubCode(); |
| 826 if (is_stub) { |
| 827 jsobj.AddProperty("kind", "Stub"); |
| 828 } else { |
| 829 jsobj.AddProperty("kind", "Dart"); |
| 830 } |
| 831 jsobj.AddProperty("_optimized", is_optimized()); |
| 832 const Object& obj = Object::Handle(owner()); |
| 833 if (obj.IsFunction()) { |
| 834 const Function& func = Function::Cast(obj); |
| 835 jsobj.AddProperty("_intrinsic", func.is_intrinsic()); |
| 836 jsobj.AddProperty("_native", func.is_native()); |
| 837 } else { |
| 838 jsobj.AddProperty("_intrinsic", false); |
| 839 jsobj.AddProperty("_native", false); |
| 840 } |
| 841 if (ref) { |
| 842 return; |
| 843 } |
| 844 if (obj.IsFunction()) { |
| 845 jsobj.AddProperty("function", obj); |
| 846 } else { |
| 847 // Generate a fake function reference. |
| 848 JSONObject func(&jsobj, "function"); |
| 849 func.AddProperty("type", "@Function"); |
| 850 func.AddProperty("_kind", "Stub"); |
| 851 func.AddProperty("name", user_name.ToCString()); |
| 852 AddNameProperties(&func, user_name, vm_name); |
| 853 } |
| 854 jsobj.AddPropertyF("_startAddress", "%" Px "", EntryPoint()); |
| 855 jsobj.AddPropertyF("_endAddress", "%" Px "", EntryPoint() + Size()); |
| 856 jsobj.AddProperty("_alive", is_alive()); |
| 857 const ObjectPool& object_pool = ObjectPool::Handle(GetObjectPool()); |
| 858 jsobj.AddProperty("_objectPool", object_pool); |
| 859 { |
| 860 JSONArray jsarr(&jsobj, "_disassembly"); |
| 861 if (is_alive()) { |
| 862 // Only disassemble alive code objects. |
| 863 DisassembleToJSONStream formatter(jsarr); |
| 864 Disassemble(&formatter); |
| 865 } |
| 866 } |
| 867 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
| 868 if (!descriptors.IsNull()) { |
| 869 JSONObject desc(&jsobj, "_descriptors"); |
| 870 descriptors.PrintToJSONObject(&desc, false); |
| 871 } |
| 872 const Array& inlined_function_table = Array::Handle(GetInlinedIdToFunction()); |
| 873 if (!inlined_function_table.IsNull() && |
| 874 (inlined_function_table.Length() > 0)) { |
| 875 JSONArray inlined_functions(&jsobj, "_inlinedFunctions"); |
| 876 Function& function = Function::Handle(); |
| 877 for (intptr_t i = 0; i < inlined_function_table.Length(); i++) { |
| 878 function ^= inlined_function_table.At(i); |
| 879 ASSERT(!function.IsNull()); |
| 880 inlined_functions.AddValue(function); |
| 881 } |
| 882 } |
| 883 const Array& intervals = Array::Handle(GetInlinedIntervals()); |
| 884 if (!intervals.IsNull() && (intervals.Length() > 0)) { |
| 885 Smi& start = Smi::Handle(); |
| 886 Smi& end = Smi::Handle(); |
| 887 Smi& temp_smi = Smi::Handle(); |
| 888 JSONArray inline_intervals(&jsobj, "_inlinedIntervals"); |
| 889 for (intptr_t i = 0; i < intervals.Length() - Code::kInlIntNumEntries; |
| 890 i += Code::kInlIntNumEntries) { |
| 891 start ^= intervals.At(i + Code::kInlIntStart); |
| 892 if (start.IsNull()) { |
| 893 continue; |
| 894 } |
| 895 end ^= intervals.At(i + Code::kInlIntNumEntries + Code::kInlIntStart); |
| 896 |
| 897 // Format: [start, end, inline functions...] |
| 898 JSONArray inline_interval(&inline_intervals); |
| 899 inline_interval.AddValue(start.Value()); |
| 900 inline_interval.AddValue(end.Value()); |
| 901 |
| 902 temp_smi ^= intervals.At(i + Code::kInlIntInliningId); |
| 903 intptr_t inlining_id = temp_smi.Value(); |
| 904 ASSERT(inlining_id >= 0); |
| 905 intptr_t caller_id = GetCallerId(inlining_id); |
| 906 while (inlining_id >= 0) { |
| 907 inline_interval.AddValue(inlining_id); |
| 908 inlining_id = caller_id; |
| 909 caller_id = GetCallerId(inlining_id); |
| 910 } |
| 911 } |
| 912 } |
| 913 } |
| 914 |
| 915 |
| 916 void Context::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 917 JSONObject jsobj(stream); |
| 918 // TODO(turnidge): Should the user level type for Context be Context |
| 919 // or Object? |
| 920 AddCommonObjectProperties(&jsobj, "Context", ref); |
| 921 jsobj.AddServiceId(*this); |
| 922 |
| 923 jsobj.AddProperty("length", num_variables()); |
| 924 |
| 925 if (ref) { |
| 926 return; |
| 927 } |
| 928 |
| 929 const Context& parent_context = Context::Handle(parent()); |
| 930 if (!parent_context.IsNull()) { |
| 931 jsobj.AddProperty("parent", parent_context); |
| 932 } |
| 933 |
| 934 JSONArray jsarr(&jsobj, "variables"); |
| 935 Object& var = Object::Handle(); |
| 936 for (intptr_t index = 0; index < num_variables(); index++) { |
| 937 var = At(index); |
| 938 JSONObject jselement(&jsarr); |
| 939 jselement.AddProperty("value", var); |
| 940 } |
| 941 } |
| 942 |
| 943 |
| 944 void ContextScope::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 945 Object::PrintJSONImpl(stream, ref); |
| 946 } |
| 947 |
| 948 |
| 949 void MegamorphicCache::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 950 JSONObject jsobj(stream); |
| 951 AddCommonObjectProperties(&jsobj, "Object", ref); |
| 952 jsobj.AddServiceId(*this); |
| 953 jsobj.AddProperty("_selector", String::Handle(target_name()).ToCString()); |
| 954 if (ref) { |
| 955 return; |
| 956 } |
| 957 jsobj.AddProperty("_buckets", Object::Handle(buckets())); |
| 958 jsobj.AddProperty("_mask", mask()); |
| 959 jsobj.AddProperty("_argumentsDescriptor", |
| 960 Object::Handle(arguments_descriptor())); |
| 961 } |
| 962 |
| 963 |
| 964 void SubtypeTestCache::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 965 Object::PrintJSONImpl(stream, ref); |
| 966 } |
| 967 |
| 968 |
| 969 void Error::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 970 UNREACHABLE(); |
| 971 } |
| 972 |
| 973 |
| 974 void ApiError::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 975 JSONObject jsobj(stream); |
| 976 AddCommonObjectProperties(&jsobj, "Error", ref); |
| 977 jsobj.AddProperty("kind", "InternalError"); |
| 978 jsobj.AddServiceId(*this); |
| 979 jsobj.AddProperty("message", ToErrorCString()); |
| 980 } |
| 981 |
| 982 |
| 983 void LanguageError::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 984 JSONObject jsobj(stream); |
| 985 AddCommonObjectProperties(&jsobj, "Error", ref); |
| 986 jsobj.AddProperty("kind", "LanguageError"); |
| 987 jsobj.AddServiceId(*this); |
| 988 jsobj.AddProperty("message", ToErrorCString()); |
| 989 } |
| 990 |
| 991 |
| 992 void UnhandledException::PrintJSONImpl(JSONStream* stream, |
| 993 bool ref) const { |
| 994 JSONObject jsobj(stream); |
| 995 AddCommonObjectProperties(&jsobj, "Error", ref); |
| 996 jsobj.AddProperty("kind", "UnhandledException"); |
| 997 jsobj.AddServiceId(*this); |
| 998 jsobj.AddProperty("message", ToErrorCString()); |
| 999 if (ref) { |
| 1000 return; |
| 1001 } |
| 1002 Instance& instance = Instance::Handle(); |
| 1003 instance = exception(); |
| 1004 jsobj.AddProperty("exception", instance); |
| 1005 instance = stacktrace(); |
| 1006 jsobj.AddProperty("stacktrace", instance); |
| 1007 } |
| 1008 |
| 1009 |
| 1010 void UnwindError::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1011 JSONObject jsobj(stream); |
| 1012 AddCommonObjectProperties(&jsobj, "Error", ref); |
| 1013 jsobj.AddProperty("kind", "TerminationError"); |
| 1014 jsobj.AddServiceId(*this); |
| 1015 jsobj.AddProperty("message", ToErrorCString()); |
| 1016 jsobj.AddProperty("_is_user_initiated", is_user_initiated()); |
| 1017 jsobj.AddProperty("_is_vm_restart", is_vm_restart()); |
| 1018 } |
| 1019 |
| 1020 |
| 1021 void Instance::PrintSharedInstanceJSON(JSONObject* jsobj, |
| 1022 bool ref) const { |
| 1023 AddCommonObjectProperties(jsobj, "Instance", ref); |
| 1024 if (ref) { |
| 1025 return; |
| 1026 } |
| 1027 |
| 1028 // Walk the superclass chain, adding all instance fields. |
| 1029 Class& cls = Class::Handle(this->clazz()); |
| 1030 { |
| 1031 Instance& fieldValue = Instance::Handle(); |
| 1032 JSONArray jsarr(jsobj, "fields"); |
| 1033 while (!cls.IsNull()) { |
| 1034 const Array& field_array = Array::Handle(cls.fields()); |
| 1035 Field& field = Field::Handle(); |
| 1036 if (!field_array.IsNull()) { |
| 1037 for (intptr_t i = 0; i < field_array.Length(); i++) { |
| 1038 field ^= field_array.At(i); |
| 1039 if (!field.is_static()) { |
| 1040 fieldValue ^= GetField(field); |
| 1041 JSONObject jsfield(&jsarr); |
| 1042 jsfield.AddProperty("type", "BoundField"); |
| 1043 jsfield.AddProperty("decl", field); |
| 1044 jsfield.AddProperty("value", fieldValue); |
| 1045 } |
| 1046 } |
| 1047 } |
| 1048 cls = cls.SuperClass(); |
| 1049 } |
| 1050 } |
| 1051 |
| 1052 if (NumNativeFields() > 0) { |
| 1053 JSONArray jsarr(jsobj, "_nativeFields"); |
| 1054 for (intptr_t i = 0; i < NumNativeFields(); i++) { |
| 1055 intptr_t value = GetNativeField(i); |
| 1056 JSONObject jsfield(&jsarr); |
| 1057 jsfield.AddProperty("index", i); |
| 1058 jsfield.AddProperty("value", value); |
| 1059 } |
| 1060 } |
| 1061 } |
| 1062 |
| 1063 |
| 1064 void Instance::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1065 JSONObject jsobj(stream); |
| 1066 |
| 1067 // Handle certain special instance values. |
| 1068 if (raw() == Object::sentinel().raw()) { |
| 1069 jsobj.AddProperty("type", "Sentinel"); |
| 1070 jsobj.AddProperty("kind", "NotInitialized"); |
| 1071 jsobj.AddProperty("valueAsString", "<not initialized>"); |
| 1072 return; |
| 1073 } else if (raw() == Object::transition_sentinel().raw()) { |
| 1074 jsobj.AddProperty("type", "Sentinel"); |
| 1075 jsobj.AddProperty("kind", "BeingInitialized"); |
| 1076 jsobj.AddProperty("valueAsString", "<being initialized>"); |
| 1077 return; |
| 1078 } |
| 1079 |
| 1080 PrintSharedInstanceJSON(&jsobj, ref); |
| 1081 if (IsClosure()) { |
| 1082 jsobj.AddProperty("kind", "Closure"); |
| 1083 } else { |
| 1084 jsobj.AddProperty("kind", "PlainInstance"); |
| 1085 } |
| 1086 jsobj.AddServiceId(*this); |
| 1087 if (IsClosure()) { |
| 1088 jsobj.AddProperty("closureFunction", |
| 1089 Function::Handle(Closure::Cast(*this).function())); |
| 1090 jsobj.AddProperty("closureContext", |
| 1091 Context::Handle(Closure::Cast(*this).context())); |
| 1092 } |
| 1093 if (ref) { |
| 1094 return; |
| 1095 } |
| 1096 if (IsClosure()) { |
| 1097 Debugger* debugger = Isolate::Current()->debugger(); |
| 1098 Breakpoint* bpt = debugger->BreakpointAtActivation(*this); |
| 1099 if (bpt != NULL) { |
| 1100 jsobj.AddProperty("_activationBreakpoint", bpt); |
| 1101 } |
| 1102 } |
| 1103 } |
| 1104 |
| 1105 |
| 1106 void AbstractType::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1107 UNREACHABLE(); |
| 1108 } |
| 1109 |
| 1110 |
| 1111 void Type::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1112 JSONObject jsobj(stream); |
| 1113 PrintSharedInstanceJSON(&jsobj, ref); |
| 1114 jsobj.AddProperty("kind", "Type"); |
| 1115 if (IsCanonical()) { |
| 1116 const Class& type_cls = Class::Handle(type_class()); |
| 1117 intptr_t id = type_cls.FindCanonicalTypeIndex(*this); |
| 1118 ASSERT(id >= 0); |
| 1119 intptr_t cid = type_cls.id(); |
| 1120 jsobj.AddFixedServiceId("classes/%" Pd "/types/%" Pd "", cid, id); |
| 1121 jsobj.AddProperty("typeClass", type_cls); |
| 1122 } else { |
| 1123 jsobj.AddServiceId(*this); |
| 1124 } |
| 1125 const String& user_name = String::Handle(PrettyName()); |
| 1126 const String& vm_name = String::Handle(Name()); |
| 1127 AddNameProperties(&jsobj, user_name, vm_name); |
| 1128 if (ref) { |
| 1129 return; |
| 1130 } |
| 1131 const TypeArguments& typeArgs = TypeArguments::Handle(arguments()); |
| 1132 if (!typeArgs.IsNull()) { |
| 1133 jsobj.AddProperty("typeArguments", typeArgs); |
| 1134 } |
| 1135 } |
| 1136 |
| 1137 |
| 1138 void FunctionType::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1139 JSONObject jsobj(stream); |
| 1140 PrintSharedInstanceJSON(&jsobj, ref); |
| 1141 jsobj.AddProperty("kind", "FunctionType"); |
| 1142 if (IsCanonical()) { |
| 1143 const Class& scope_cls = Class::Handle(scope_class()); |
| 1144 intptr_t id = scope_cls.FindCanonicalTypeIndex(*this); |
| 1145 ASSERT(id >= 0); |
| 1146 intptr_t cid = scope_cls.id(); |
| 1147 jsobj.AddFixedServiceId("classes/%" Pd "/types/%" Pd "", cid, id); |
| 1148 jsobj.AddProperty("scopeClass", scope_cls); |
| 1149 } else { |
| 1150 jsobj.AddServiceId(*this); |
| 1151 } |
| 1152 const String& user_name = String::Handle(PrettyName()); |
| 1153 const String& vm_name = String::Handle(Name()); |
| 1154 AddNameProperties(&jsobj, user_name, vm_name); |
| 1155 if (ref) { |
| 1156 return; |
| 1157 } |
| 1158 const TypeArguments& typeArgs = TypeArguments::Handle(arguments()); |
| 1159 if (!typeArgs.IsNull()) { |
| 1160 jsobj.AddProperty("typeArguments", typeArgs); |
| 1161 } |
| 1162 } |
| 1163 |
| 1164 |
| 1165 void TypeRef::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1166 JSONObject jsobj(stream); |
| 1167 PrintSharedInstanceJSON(&jsobj, ref); |
| 1168 jsobj.AddProperty("kind", "TypeRef"); |
| 1169 jsobj.AddServiceId(*this); |
| 1170 const String& user_name = String::Handle(PrettyName()); |
| 1171 const String& vm_name = String::Handle(Name()); |
| 1172 AddNameProperties(&jsobj, user_name, vm_name); |
| 1173 if (ref) { |
| 1174 return; |
| 1175 } |
| 1176 jsobj.AddProperty("targetType", AbstractType::Handle(type())); |
| 1177 } |
| 1178 |
| 1179 |
| 1180 void TypeParameter::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1181 JSONObject jsobj(stream); |
| 1182 PrintSharedInstanceJSON(&jsobj, ref); |
| 1183 jsobj.AddProperty("kind", "TypeParameter"); |
| 1184 jsobj.AddServiceId(*this); |
| 1185 const String& user_name = String::Handle(PrettyName()); |
| 1186 const String& vm_name = String::Handle(Name()); |
| 1187 AddNameProperties(&jsobj, user_name, vm_name); |
| 1188 const Class& param_cls = Class::Handle(parameterized_class()); |
| 1189 jsobj.AddProperty("parameterizedClass", param_cls); |
| 1190 if (ref) { |
| 1191 return; |
| 1192 } |
| 1193 jsobj.AddProperty("parameterIndex", index()); |
| 1194 const AbstractType& upper_bound = AbstractType::Handle(bound()); |
| 1195 jsobj.AddProperty("bound", upper_bound); |
| 1196 } |
| 1197 |
| 1198 |
| 1199 void BoundedType::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1200 JSONObject jsobj(stream); |
| 1201 PrintSharedInstanceJSON(&jsobj, ref); |
| 1202 jsobj.AddProperty("kind", "BoundedType"); |
| 1203 jsobj.AddServiceId(*this); |
| 1204 const String& user_name = String::Handle(PrettyName()); |
| 1205 const String& vm_name = String::Handle(Name()); |
| 1206 AddNameProperties(&jsobj, user_name, vm_name); |
| 1207 if (ref) { |
| 1208 return; |
| 1209 } |
| 1210 jsobj.AddProperty("targetType", AbstractType::Handle(type())); |
| 1211 jsobj.AddProperty("bound", AbstractType::Handle(bound())); |
| 1212 } |
| 1213 |
| 1214 |
| 1215 void MixinAppType::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1216 UNREACHABLE(); |
| 1217 } |
| 1218 |
| 1219 |
| 1220 void Number::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1221 UNREACHABLE(); |
| 1222 } |
| 1223 |
| 1224 |
| 1225 void Integer::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1226 JSONObject jsobj(stream); |
| 1227 PrintSharedInstanceJSON(&jsobj, ref); |
| 1228 jsobj.AddProperty("kind", "Int"); |
| 1229 jsobj.AddServiceId(*this); |
| 1230 jsobj.AddProperty("valueAsString", ToCString()); |
| 1231 } |
| 1232 |
| 1233 |
| 1234 void Smi::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1235 JSONObject jsobj(stream); |
| 1236 PrintSharedInstanceJSON(&jsobj, ref); |
| 1237 jsobj.AddProperty("kind", "Int"); |
| 1238 jsobj.AddFixedServiceId("objects/int-%" Pd "", Value()); |
| 1239 jsobj.AddPropertyF("valueAsString", "%" Pd "", Value()); |
| 1240 } |
| 1241 |
| 1242 |
| 1243 void Mint::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1244 Integer::PrintJSONImpl(stream, ref); |
| 1245 } |
| 1246 |
| 1247 |
| 1248 void Double::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1249 JSONObject jsobj(stream); |
| 1250 PrintSharedInstanceJSON(&jsobj, ref); |
| 1251 jsobj.AddProperty("kind", "Double"); |
| 1252 jsobj.AddServiceId(*this); |
| 1253 jsobj.AddProperty("valueAsString", ToCString()); |
| 1254 } |
| 1255 |
| 1256 |
| 1257 void Bigint::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1258 Integer::PrintJSONImpl(stream, ref); |
| 1259 } |
| 1260 |
| 1261 |
| 1262 void String::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1263 JSONObject jsobj(stream); |
| 1264 if (raw() == Symbols::OptimizedOut().raw()) { |
| 1265 // TODO(turnidge): This is a hack. The user could have this |
| 1266 // special string in their program. Fixing this involves updating |
| 1267 // the debugging api a bit. |
| 1268 jsobj.AddProperty("type", "Sentinel"); |
| 1269 jsobj.AddProperty("kind", "OptimizedOut"); |
| 1270 jsobj.AddProperty("valueAsString", "<optimized out>"); |
| 1271 return; |
| 1272 } |
| 1273 PrintSharedInstanceJSON(&jsobj, ref); |
| 1274 jsobj.AddProperty("kind", "String"); |
| 1275 jsobj.AddServiceId(*this); |
| 1276 jsobj.AddProperty("length", Length()); |
| 1277 if (ref) { |
| 1278 // String refs always truncate to a fixed count; |
| 1279 const intptr_t kFixedCount = 128; |
| 1280 if (jsobj.AddPropertyStr("valueAsString", *this, 0, kFixedCount)) { |
| 1281 jsobj.AddProperty("count", kFixedCount); |
| 1282 jsobj.AddProperty("valueAsStringIsTruncated", true); |
| 1283 } |
| 1284 return; |
| 1285 } |
| 1286 |
| 1287 intptr_t offset; |
| 1288 intptr_t count; |
| 1289 stream->ComputeOffsetAndCount(Length(), &offset, &count); |
| 1290 if (offset > 0) { |
| 1291 jsobj.AddProperty("offset", offset); |
| 1292 } |
| 1293 if (count < Length()) { |
| 1294 jsobj.AddProperty("count", count); |
| 1295 } |
| 1296 jsobj.AddPropertyStr("valueAsString", *this, offset, count); |
| 1297 } |
| 1298 |
| 1299 |
| 1300 void Bool::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1301 const char* str = ToCString(); |
| 1302 JSONObject jsobj(stream); |
| 1303 PrintSharedInstanceJSON(&jsobj, ref); |
| 1304 jsobj.AddProperty("kind", "Bool"); |
| 1305 jsobj.AddFixedServiceId("objects/bool-%s", str); |
| 1306 jsobj.AddPropertyF("valueAsString", "%s", str); |
| 1307 } |
| 1308 |
| 1309 |
| 1310 void Array::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1311 JSONObject jsobj(stream); |
| 1312 PrintSharedInstanceJSON(&jsobj, ref); |
| 1313 jsobj.AddProperty("kind", "List"); |
| 1314 jsobj.AddServiceId(*this); |
| 1315 jsobj.AddProperty("length", Length()); |
| 1316 if (ref) { |
| 1317 return; |
| 1318 } |
| 1319 intptr_t offset; |
| 1320 intptr_t count; |
| 1321 stream->ComputeOffsetAndCount(Length(), &offset, &count); |
| 1322 if (offset > 0) { |
| 1323 jsobj.AddProperty("offset", offset); |
| 1324 } |
| 1325 if (count < Length()) { |
| 1326 jsobj.AddProperty("count", count); |
| 1327 } |
| 1328 intptr_t limit = offset + count; |
| 1329 ASSERT(limit <= Length()); |
| 1330 { |
| 1331 JSONArray jsarr(&jsobj, "elements"); |
| 1332 Object& element = Object::Handle(); |
| 1333 for (intptr_t index = offset; index < limit; index++) { |
| 1334 element = At(index); |
| 1335 jsarr.AddValue(element); |
| 1336 } |
| 1337 } |
| 1338 } |
| 1339 |
| 1340 |
| 1341 void GrowableObjectArray::PrintJSONImpl(JSONStream* stream, |
| 1342 bool ref) const { |
| 1343 JSONObject jsobj(stream); |
| 1344 PrintSharedInstanceJSON(&jsobj, ref); |
| 1345 jsobj.AddProperty("kind", "List"); |
| 1346 jsobj.AddServiceId(*this); |
| 1347 jsobj.AddProperty("length", Length()); |
| 1348 if (ref) { |
| 1349 return; |
| 1350 } |
| 1351 intptr_t offset; |
| 1352 intptr_t count; |
| 1353 stream->ComputeOffsetAndCount(Length(), &offset, &count); |
| 1354 if (offset > 0) { |
| 1355 jsobj.AddProperty("offset", offset); |
| 1356 } |
| 1357 if (count < Length()) { |
| 1358 jsobj.AddProperty("count", count); |
| 1359 } |
| 1360 intptr_t limit = offset + count; |
| 1361 ASSERT(limit <= Length()); |
| 1362 { |
| 1363 JSONArray jsarr(&jsobj, "elements"); |
| 1364 Object& element = Object::Handle(); |
| 1365 for (intptr_t index = offset; index < limit; index++) { |
| 1366 element = At(index); |
| 1367 jsarr.AddValue(element); |
| 1368 } |
| 1369 } |
| 1370 } |
| 1371 |
| 1372 |
| 1373 void LinkedHashMap::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1374 JSONObject jsobj(stream); |
| 1375 PrintSharedInstanceJSON(&jsobj, ref); |
| 1376 jsobj.AddProperty("kind", "Map"); |
| 1377 jsobj.AddServiceId(*this); |
| 1378 jsobj.AddProperty("length", Length()); |
| 1379 if (ref) { |
| 1380 return; |
| 1381 } |
| 1382 intptr_t offset; |
| 1383 intptr_t count; |
| 1384 stream->ComputeOffsetAndCount(Length(), &offset, &count); |
| 1385 if (offset > 0) { |
| 1386 jsobj.AddProperty("offset", offset); |
| 1387 } |
| 1388 if (count < Length()) { |
| 1389 jsobj.AddProperty("count", count); |
| 1390 } |
| 1391 intptr_t limit = offset + count; |
| 1392 ASSERT(limit <= Length()); |
| 1393 { |
| 1394 JSONArray jsarr(&jsobj, "associations"); |
| 1395 Object& object = Object::Handle(); |
| 1396 LinkedHashMap::Iterator iterator(*this); |
| 1397 int i = 0; |
| 1398 while (iterator.MoveNext() && i < limit) { |
| 1399 if (i >= offset) { |
| 1400 JSONObject jsassoc(&jsarr); |
| 1401 object = iterator.CurrentKey(); |
| 1402 jsassoc.AddProperty("key", object); |
| 1403 object = iterator.CurrentValue(); |
| 1404 jsassoc.AddProperty("value", object); |
| 1405 } |
| 1406 i++; |
| 1407 } |
| 1408 } |
| 1409 } |
| 1410 |
| 1411 |
| 1412 void Float32x4::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1413 JSONObject jsobj(stream); |
| 1414 PrintSharedInstanceJSON(&jsobj, ref); |
| 1415 jsobj.AddProperty("kind", "Float32x4"); |
| 1416 jsobj.AddServiceId(*this); |
| 1417 jsobj.AddProperty("valueAsString", ToCString()); |
| 1418 } |
| 1419 |
| 1420 |
| 1421 void Int32x4::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1422 JSONObject jsobj(stream); |
| 1423 PrintSharedInstanceJSON(&jsobj, ref); |
| 1424 jsobj.AddProperty("kind", "Int32x4"); |
| 1425 jsobj.AddServiceId(*this); |
| 1426 jsobj.AddProperty("valueAsString", ToCString()); |
| 1427 } |
| 1428 |
| 1429 |
| 1430 void Float64x2::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1431 JSONObject jsobj(stream); |
| 1432 PrintSharedInstanceJSON(&jsobj, ref); |
| 1433 jsobj.AddProperty("kind", "Float64x2"); |
| 1434 jsobj.AddServiceId(*this); |
| 1435 jsobj.AddProperty("valueAsString", ToCString()); |
| 1436 } |
| 1437 |
| 1438 |
| 1439 void TypedData::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1440 JSONObject jsobj(stream); |
| 1441 PrintSharedInstanceJSON(&jsobj, ref); |
| 1442 const Class& cls = Class::Handle(clazz()); |
| 1443 const String& kind = String::Handle(cls.UserVisibleName()); |
| 1444 jsobj.AddProperty("kind", kind.ToCString()); |
| 1445 jsobj.AddServiceId(*this); |
| 1446 jsobj.AddProperty("length", Length()); |
| 1447 if (ref) { |
| 1448 return; |
| 1449 } |
| 1450 intptr_t offset; |
| 1451 intptr_t count; |
| 1452 stream->ComputeOffsetAndCount(Length(), &offset, &count); |
| 1453 if (offset > 0) { |
| 1454 jsobj.AddProperty("offset", offset); |
| 1455 } |
| 1456 if (count < Length()) { |
| 1457 jsobj.AddProperty("count", count); |
| 1458 } |
| 1459 if (count == 0) { |
| 1460 jsobj.AddProperty("bytes", ""); |
| 1461 } else { |
| 1462 NoSafepointScope no_safepoint; |
| 1463 jsobj.AddPropertyBase64("bytes", |
| 1464 reinterpret_cast<const uint8_t*>( |
| 1465 DataAddr(offset * ElementSizeInBytes())), |
| 1466 count * ElementSizeInBytes()); |
| 1467 } |
| 1468 } |
| 1469 |
| 1470 |
| 1471 void ExternalTypedData::PrintJSONImpl(JSONStream* stream, |
| 1472 bool ref) const { |
| 1473 JSONObject jsobj(stream); |
| 1474 PrintSharedInstanceJSON(&jsobj, ref); |
| 1475 const Class& cls = Class::Handle(clazz()); |
| 1476 const String& kind = String::Handle(cls.UserVisibleName()); |
| 1477 jsobj.AddProperty("kind", kind.ToCString()); |
| 1478 jsobj.AddServiceId(*this); |
| 1479 jsobj.AddProperty("length", Length()); |
| 1480 if (ref) { |
| 1481 return; |
| 1482 } |
| 1483 intptr_t offset; |
| 1484 intptr_t count; |
| 1485 stream->ComputeOffsetAndCount(Length(), &offset, &count); |
| 1486 if (offset > 0) { |
| 1487 jsobj.AddProperty("offset", offset); |
| 1488 } |
| 1489 if (count < Length()) { |
| 1490 jsobj.AddProperty("count", count); |
| 1491 } |
| 1492 if (count == 0) { |
| 1493 jsobj.AddProperty("bytes", ""); |
| 1494 } else { |
| 1495 NoSafepointScope no_safepoint; |
| 1496 jsobj.AddPropertyBase64("bytes", |
| 1497 reinterpret_cast<const uint8_t*>( |
| 1498 DataAddr(offset * ElementSizeInBytes())), |
| 1499 count * ElementSizeInBytes()); |
| 1500 } |
| 1501 } |
| 1502 |
| 1503 |
| 1504 void Capability::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1505 Instance::PrintJSONImpl(stream, ref); |
| 1506 } |
| 1507 |
| 1508 |
| 1509 void ReceivePort::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1510 Instance::PrintJSONImpl(stream, ref); |
| 1511 } |
| 1512 |
| 1513 |
| 1514 void SendPort::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1515 Instance::PrintJSONImpl(stream, ref); |
| 1516 } |
| 1517 |
| 1518 |
| 1519 void ClosureData::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1520 Object::PrintJSONImpl(stream, ref); |
| 1521 } |
| 1522 |
| 1523 |
| 1524 void Closure::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1525 Instance::PrintJSONImpl(stream, ref); |
| 1526 } |
| 1527 |
| 1528 |
| 1529 void Stacktrace::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1530 JSONObject jsobj(stream); |
| 1531 PrintSharedInstanceJSON(&jsobj, ref); |
| 1532 jsobj.AddProperty("kind", "StackTrace"); |
| 1533 jsobj.AddServiceId(*this); |
| 1534 intptr_t idx = 0; |
| 1535 jsobj.AddProperty("valueAsString", ToCStringInternal(&idx)); |
| 1536 } |
| 1537 |
| 1538 |
| 1539 void JSRegExp::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1540 JSONObject jsobj(stream); |
| 1541 PrintSharedInstanceJSON(&jsobj, ref); |
| 1542 jsobj.AddProperty("kind", "RegExp"); |
| 1543 jsobj.AddServiceId(*this); |
| 1544 |
| 1545 jsobj.AddProperty("pattern", String::Handle(pattern())); |
| 1546 |
| 1547 if (ref) { |
| 1548 return; |
| 1549 } |
| 1550 |
| 1551 jsobj.AddProperty("isCaseSensitive", !is_ignore_case()); |
| 1552 jsobj.AddProperty("isMultiLine", is_multi_line()); |
| 1553 |
| 1554 Function& func = Function::Handle(); |
| 1555 func = function(kOneByteStringCid); |
| 1556 jsobj.AddProperty("_oneByteFunction", func); |
| 1557 func = function(kTwoByteStringCid); |
| 1558 jsobj.AddProperty("_twoByteFunction", func); |
| 1559 func = function(kExternalOneByteStringCid); |
| 1560 jsobj.AddProperty("_externalOneByteFunction", func); |
| 1561 func = function(kExternalTwoByteStringCid); |
| 1562 jsobj.AddProperty("_externalTwoByteFunction", func); |
| 1563 } |
| 1564 |
| 1565 |
| 1566 void WeakProperty::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1567 JSONObject jsobj(stream); |
| 1568 PrintSharedInstanceJSON(&jsobj, ref); |
| 1569 jsobj.AddProperty("kind", "WeakProperty"); |
| 1570 jsobj.AddServiceId(*this); |
| 1571 if (ref) { |
| 1572 return; |
| 1573 } |
| 1574 |
| 1575 const Object& key_handle = Object::Handle(key()); |
| 1576 jsobj.AddProperty("propertyKey", key_handle); |
| 1577 const Object& value_handle = Object::Handle(value()); |
| 1578 jsobj.AddProperty("propertyValue", value_handle); |
| 1579 } |
| 1580 |
| 1581 |
| 1582 void MirrorReference::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1583 JSONObject jsobj(stream); |
| 1584 PrintSharedInstanceJSON(&jsobj, ref); |
| 1585 jsobj.AddProperty("kind", "MirrorReference"); |
| 1586 jsobj.AddServiceId(*this); |
| 1587 |
| 1588 if (ref) { |
| 1589 return; |
| 1590 } |
| 1591 |
| 1592 const Object& referent_handle = Object::Handle(referent()); |
| 1593 jsobj.AddProperty("mirrorReferent", referent_handle); |
| 1594 } |
| 1595 |
| 1596 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 1597 Instance::PrintJSONImpl(stream, ref); |
| 1598 } |
| 1599 |
| 1600 #endif |
| 1601 |
| 1602 } // namespace dart |
OLD | NEW |