| 554 | } |
| 555 | |
| 556 | std::string gjs_debug_object(JSObject* const obj) { |
| 557 | if (!obj) |
| 558 | return "<null object>"; |
| 559 | |
| 560 | std::ostringstream out; |
| 561 | |
| 562 | if (js::IsFunctionObject(obj)) { |
| 563 | JSFunction* fun = JS_GetObjectFunction(obj); |
| 564 | JSString* display_name = JS_GetMaybePartialFunctionDisplayId(fun); |
| 565 | if (display_name && JS_GetStringLength(display_name)) |
| 566 | out << "<function " << gjs_debug_string(display_name); |
| 567 | else |
| 568 | out << "<anonymous function"; |
| 569 | out << " at " << fun << '>'; |
| 570 | return out.str(); |
| 571 | } |
| 572 | |
| 573 | // This is OK because the promise methods can't cause a garbage collection |
| 574 | JS::HandleObject handle = JS::HandleObject::fromMarkedLocation(&obj); |
| 575 | if (JS::IsPromiseObject(handle)) { |
| 576 | out << '<'; |
| 577 | JS::PromiseState state = JS::GetPromiseState(handle); |
| 578 | if (state == JS::PromiseState::Pending) |
| 579 | out << "pending "; |
| 580 | out << "promise " << JS::GetPromiseID(handle) << " at " << obj; |
| 581 | if (state != JS::PromiseState::Pending) { |
| 582 | out << ' '; |
| 583 | out << (state == JS::PromiseState::Rejected ? "rejected" |
| 584 | : "resolved"); |
| 585 | out << " with " << gjs_debug_value(JS::GetPromiseResult(handle)); |
| 586 | } |
| 587 | out << '>'; |
| 588 | return out.str(); |
| 589 | } |
| 590 | |
| 591 | const JSClass* clasp = JS::GetClass(obj); |
| 592 | out << "<object " << clasp->name << " at " << obj << '>'; |
| 593 | return out.str(); |
| 594 | } |
| 595 | |
| 596 | std::string gjs_debug_callable(JSObject* callable) { |
| 597 | if (JSFunction* fn = JS_GetObjectFunction(callable)) { |
no test coverage detected