void InspectorRuntimeAgent::parse(ErrorString*, const String& expression, Inspector::TypeBuilder::Runtime::SyntaxErrorType::Enum* result, Inspector::TypeBuilder::OptOutput<String>* message, RefPtr<Inspector::TypeBuilder::Runtime::ErrorRange>& range) { VM& vm = globalVM(); JSLockHolder lock(vm); ParserError error; checkSyntax(vm, JSC::makeSource(expression), error); switch (error.m_syntaxErrorType) { case ParserError::SyntaxErrorNone: *result = Inspector::TypeBuilder::Runtime::SyntaxErrorType::None; break; case ParserError::SyntaxErrorIrrecoverable: *result = Inspector::TypeBuilder::Runtime::SyntaxErrorType::Irrecoverable; break; case ParserError::SyntaxErrorUnterminatedLiteral: *result = Inspector::TypeBuilder::Runtime::SyntaxErrorType::UnterminatedLiteral; break; case ParserError::SyntaxErrorRecoverable: *result = Inspector::TypeBuilder::Runtime::SyntaxErrorType::Recoverable; break; } if (error.m_syntaxErrorType != ParserError::SyntaxErrorNone) { *message = error.m_message; range = buildErrorRangeObject(error.m_token.m_location); } }
void InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets(ErrorString& errorString, const Inspector::InspectorArray& locations, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::TypeDescription>>& typeDescriptions) { static const bool verbose = false; VM& vm = globalVM(); typeDescriptions = Inspector::Protocol::Array<Inspector::Protocol::Runtime::TypeDescription>::create(); if (!vm.typeProfiler()) { errorString = ASCIILiteral("The VM does not currently have Type Information."); return; } double start = currentTimeMS(); vm.typeProfilerLog()->processLogEntries(ASCIILiteral("User Query")); for (size_t i = 0; i < locations.length(); i++) { RefPtr<Inspector::InspectorValue> value = locations.get(i); RefPtr<InspectorObject> location; if (!value->asObject(location)) { errorString = ASCIILiteral("Array of TypeLocation objects has an object that does not have type of TypeLocation."); return; } int descriptor; String sourceIDAsString; int divot; location->getInteger(ASCIILiteral("typeInformationDescriptor"), descriptor); location->getString(ASCIILiteral("sourceID"), sourceIDAsString); location->getInteger(ASCIILiteral("divot"), divot); bool okay; TypeLocation* typeLocation = vm.typeProfiler()->findLocation(divot, sourceIDAsString.toIntPtrStrict(&okay), static_cast<TypeProfilerSearchDescriptor>(descriptor), vm); ASSERT(okay); RefPtr<TypeSet> typeSet; if (typeLocation) { if (typeLocation->m_globalTypeSet && typeLocation->m_globalVariableID != TypeProfilerNoGlobalIDExists) typeSet = typeLocation->m_globalTypeSet; else typeSet = typeLocation->m_instructionTypeSet; } bool isValid = typeLocation && typeSet && !typeSet->isEmpty(); auto description = Inspector::Protocol::Runtime::TypeDescription::create() .setIsValid(isValid) .release(); if (isValid) { description->setLeastCommonAncestor(typeSet->leastCommonAncestor()); description->setStructures(typeSet->allStructureRepresentations()); description->setTypeSet(typeSet->inspectorTypeSet()); description->setIsTruncated(typeSet->isOverflown()); } typeDescriptions->addItem(WTF::move(description)); } double end = currentTimeMS(); if (verbose) dataLogF("Inspector::getRuntimeTypesForVariablesAtOffsets took %lfms\n", end - start); }
void InspectorRuntimeAgent::setTypeProfilerEnabledState(bool shouldEnableTypeProfiling) { if (m_isTypeProfilingEnabled == shouldEnableTypeProfiling) return; m_isTypeProfilingEnabled = shouldEnableTypeProfiling; VM& vm = globalVM(); // If JavaScript is running, it's not safe to recompile, since we'll end // up throwing away code that is live on the stack. if (vm.entryScope) { vm.entryScope->setEntryScopeDidPopListener(this, [=] (VM& vm, JSGlobalObject*) { recompileAllJSFunctionsForTypeProfiling(vm, shouldEnableTypeProfiling); } ); } else recompileAllJSFunctionsForTypeProfiling(vm, shouldEnableTypeProfiling); }
void InspectorRuntimeAgent::getBasicBlocks(ErrorString& errorString, const String& sourceIDAsString, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::BasicBlock>>& basicBlocks) { VM& vm = globalVM(); if (!vm.controlFlowProfiler()) { errorString = ASCIILiteral("The VM does not currently have a Control Flow Profiler."); return; } bool okay; intptr_t sourceID = sourceIDAsString.toIntPtrStrict(&okay); ASSERT(okay); const Vector<BasicBlockRange>& basicBlockRanges = vm.controlFlowProfiler()->getBasicBlocksForSourceID(sourceID, vm); basicBlocks = Inspector::Protocol::Array<Inspector::Protocol::Runtime::BasicBlock>::create(); for (const BasicBlockRange& block : basicBlockRanges) { Ref<Inspector::Protocol::Runtime::BasicBlock> location = Inspector::Protocol::Runtime::BasicBlock::create() .setStartOffset(block.m_startOffset) .setEndOffset(block.m_endOffset) .setHasExecuted(block.m_hasExecuted) .release(); basicBlocks->addItem(WTF::move(location)); } }
void InspectorRuntimeAgent::getRuntimeTypeForVariableAtOffset(ErrorString*, const String& in_variableName, const String& in_id, int in_divot, String* out_types) { VM& vm = globalVM(); String types(vm.getTypesForVariableAtOffset(in_divot, in_variableName, in_id)); *out_types = types; }