/* static */ BOOL ES_DebugBuiltins::getObjectDemographics(ES_Execution_Context *context, unsigned argc, ES_Value_Internal *argv, ES_Value_Internal *return_value) { return_value->SetNull(); if (argc == 1) { if (!argv[0].ToNumber(context) || !argv[0].IsUInt32()) return FALSE; if (ES_Heap *heap = g_ecmaManager->GetHeapById(argv[0].GetNumAsUInt32())) { TempBuffer *buffer = g_ecmaManager->GetHeapDebuggerBuffer(); buffer->Clear(); buffer->Append("{ "); unsigned *live_objects = heap->live_objects; for (unsigned index = 0; index < GCTAG_UNINITIALIZED; ++index) { if (index != 0) buffer->Append(", "); buffer->Append("\""); buffer->Append(g_ecmaClassName[index]); buffer->Append("\": "); buffer->AppendUnsignedLong(live_objects[index]); } buffer->Append(" }"); return_value->SetString(JString::Make(context, buffer->GetStorage(), buffer->Length())); } } return TRUE; }
/* static */ BOOL ES_DebugBuiltins::getHeapInformation(ES_Execution_Context *context, unsigned argc, ES_Value_Internal *argv, ES_Value_Internal *return_value) { Head *active, *inactive, *destroy; g_ecmaManager->GetHeapLists(active, inactive, destroy); TempBuffer *buffer = g_ecmaManager->GetHeapDebuggerBuffer(); buffer->Clear(); buffer->Append("{ \"heaps\": { "); ES_Heap *heads[3] = { static_cast<ES_Heap *>(active->First()), static_cast<ES_Heap *>(inactive->First()), static_cast<ES_Heap *>(destroy->First()) }; for (unsigned head = 0; head < 3; ++head) for (ES_Heap *heap = heads[head]; heap; heap = static_cast<ES_Heap *>(heap->Suc())) { buffer->AppendFormat(UNI_L("\"%u\": { \"bytesLive\": %u, \"bytesLivePeak\": %u, \"bytesLimit\": %u, \"runtimes\": ["), heap->Id(), heap->GetBytesLive(), heap->GetBytesLivePeak(), heap->GetBytesLimit()); ES_Runtime *runtime = heap->GetFirstRuntime(); while (runtime) { #ifndef _STANDALONE ES_Object *global_object = runtime->GetGlobalObject(); if (global_object->IsHostObject() && ES_Runtime::GetHostObject(global_object)->IsA(DOM_TYPE_WINDOW)) { OpString url; DOM_Utils::GetOriginURL(DOM_Utils::GetDOM_Runtime(runtime)).GetAttribute(URL::KUniName, url); for (unsigned index = 0; index < static_cast<unsigned>(url.Length()); ++index) if (url.CStr()[index] == '"') url.Insert(index++, "\\"); buffer->AppendFormat(UNI_L("\"%s\""), url.CStr()); } else #endif // _STANDALONE buffer->Append("\"<unidentified runtime>\""); runtime = g_ecmaManager->GetNextRuntimePerHeap(runtime); if (runtime) buffer->Append(", "); } buffer->Append("] }, "); } buffer->AppendFormat(UNI_L("\"count\": %u }, \"allocators\": ["), active->Cardinal() + inactive->Cardinal() + destroy->Cardinal()); for (ES_PageAllocator *allocator = static_cast<ES_PageAllocator *>(g_ecmaPageAllocatorList->First()); allocator; allocator = static_cast<ES_PageAllocator *>(allocator->Suc())) { buffer->AppendFormat(UNI_L("{ \"chunks\": %u, \"chunkSize\": %u, \"pages\": %u, \"pageSize\": %u, \"heaps\": ["), allocator->CountChunks(), allocator->ChunkSize(), allocator->CountPages(), allocator->PageSize()); for (ES_HeapHandle *heaph = allocator->GetFirstHeapHandle(); heaph; heaph = static_cast<ES_HeapHandle *>(heaph->Suc())) { buffer->AppendUnsignedLong(heaph->heap->Id()); if (heaph->Suc()) buffer->Append(", "); } buffer->Append("] }"); if (allocator->Suc()) buffer->Append(", "); } buffer->Append("], \"cachedPrograms\": ["); for (Link *link = RT_DATA.program_cache->GetCachedPrograms()->First(); link; link = link->Suc()) { ES_ProgramCodeStatic *program = static_cast<ES_ProgramCodeStatic *>(link); buffer->AppendFormat(UNI_L("{ \"url\": \"\", \"length\": %u }"), program->source.GetSource()->length); if (link->Suc()) buffer->Append(", "); } buffer->Append("] }"); return_value->SetString(JString::Make(context, buffer->GetStorage(), buffer->Length())); return TRUE; }
BOOL XPath_Node::HasStringValueL (const uni_char *value) { unsigned value_length; if (!value) value = UNI_L (""), value_length = 0; else value_length = uni_strlen (value); XMLTreeAccessor::Node *iter = treenode, *first = 0; TempBuffer buffer; ANCHOR (TempBuffer, buffer); const uni_char *data = 0; BOOL id, specified; switch (type) { case XP_NODE_ROOT: case XP_NODE_ELEMENT: LEAVE_IF_ERROR (tree->GetCharacterDataContent (data, treenode, &buffer)); return uni_strcmp (value, data) == 0; case XP_NODE_TEXT: while (XPath_Utils::GetNodeType (tree, iter) == XP_NODE_TEXT) { first = iter; if (XMLTreeAccessor::Node *previous = tree->GetPreviousSibling (iter)) iter = previous; else break; } while (first && XPath_Utils::GetNodeType (tree, first) == XP_NODE_TEXT) { LEAVE_IF_ERROR (tree->GetData (data, first, &buffer)); unsigned data_length = uni_strlen (data); if (value_length < data_length || uni_strncmp (value, data, data_length) != 0) return FALSE; value += data_length; value_length -= data_length; buffer.Clear (); first = tree->GetNextSibling (first); } return TRUE; case XP_NODE_ATTRIBUTE: LEAVE_IF_ERROR (tree->GetAttribute (tree->GetAttributes (treenode, FALSE, TRUE), name, data, id, specified, &buffer)); return uni_strcmp (value, data) == 0; case XP_NODE_NAMESPACE: { const uni_char *uri = name.GetUri (); if (uri) return uni_strcmp (value, uri) == 0; else return value_length == 0; } case XP_NODE_PI: case XP_NODE_COMMENT: LEAVE_IF_ERROR (tree->GetData (data, iter, &buffer)); return uni_strcmp (value, data) == 0; } return FALSE; }