/* 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; }
/* virtual */ ES_GetState JS_Location::GetName(OpAtom property_name, ES_Value* value, ES_Runtime* origining_runtime) { TempBuffer *buffer = GetEmptyTempBuf(); URL url; if (fakewindow) url = fakewindow->GetURL(); #ifdef SELFTEST else if (!do_navigation) url = current_url; #endif // SELFTEST else if (FramesDocument *frames_doc = GetFramesDocument()) { url = frames_doc->GetURL(); // The anchors (hash) might be better in DocumentManager URL doc_man_url = frames_doc->GetDocManager()->GetCurrentURL(); if (doc_man_url == url) // Doesn't compare anchors url = doc_man_url; } #ifdef DOM_WEBWORKERS_SUPPORT /* No FramesDocument to query, so consult the origin DocumentManager for the Worker */ if (!GetFramesDocument()) { DOM_WebWorkerController *web_workers = GetEnvironment()->GetWorkerController(); if (DOM_WebWorker *ww = web_workers->GetWorkerObject()) url = ww->GetLocationURL(); else if (DocumentManager *doc = web_workers->GetWorkerDocManager()) url = doc->GetCurrentURL(); OP_ASSERT(!url.IsEmpty()); } #endif // DOM_WEBWORKERS_SUPPORT switch (property_name) { case OP_ATOM_href: DOMSetString(value, url.GetAttribute(URL::KUniName_With_Fragment_Escaped).CStr()); return GET_SUCCESS; case OP_ATOM_protocol: if (value) { const char *protocol = url.GetAttribute(URL::KProtocolName).CStr(); if (protocol) { GET_FAILED_IF_ERROR(buffer->Append(protocol)); GET_FAILED_IF_ERROR(buffer->Append(":")); } DOMSetString(value, buffer); } return GET_SUCCESS; case OP_ATOM_host: case OP_ATOM_hostname: if (value) { const uni_char *name = url.GetServerName() ? url.GetServerName()->UniName() : NULL; if (property_name == OP_ATOM_host) { unsigned short port = url.GetServerPort(); if (port) { GET_FAILED_IF_ERROR(buffer->Append(name)); GET_FAILED_IF_ERROR(buffer->Append(":")); GET_FAILED_IF_ERROR(buffer->AppendUnsignedLong(port)); name = buffer->GetStorage(); } } DOMSetString(value, name); } return GET_SUCCESS; case OP_ATOM_port: if (value) { unsigned short port = url.GetServerPort(); if (port) GET_FAILED_IF_ERROR(buffer->AppendUnsignedLong(port)); DOMSetString(value, buffer); } return GET_SUCCESS; case OP_ATOM_pathname: if (value) { const uni_char *path = url.GetAttribute(URL::KUniPath).CStr(); if (path) { GET_FAILED_IF_ERROR(buffer->Append(path)); uni_char *path_tmp = buffer->GetStorage(); /* It isn't obvious from the JS spec and the relevant RFC, but in Javascript the 'pathname' excludes any arguments passed to the page. */ if (uni_char *query_start = uni_strchr(path_tmp, '?')) { path = path_tmp; *query_start = 0; } } DOMSetString(value, path); } return GET_SUCCESS; case OP_ATOM_search: if (value) { const uni_char *name = url.GetAttribute(URL::KUniName).CStr(); if (name) name = uni_strchr(name, '?'); DOMSetString(value, name); } return GET_SUCCESS; case OP_ATOM_hash: if (value) { const uni_char *fragment = url.UniRelName(); // MSIE emits "#" for the empty fragment (as in http://www.opera.com/# ) but no other // browser does that and neither will we. if (fragment && *fragment) { GET_FAILED_IF_ERROR(buffer->Append('#')); GET_FAILED_IF_ERROR(buffer->Append(fragment)); fragment = buffer->GetStorage(); } DOMSetString(value, fragment); } return GET_SUCCESS; } return GET_FAILED; }