CHAKRA_API JsParseModuleSource( _In_ JsModuleRecord requestModule, _In_ JsSourceContext sourceContext, _In_ byte* sourceText, _In_ unsigned int sourceLength, _In_ JsParseModuleSourceFlags sourceFlag, _Outptr_result_maybenull_ JsValueRef* exceptionValueRef) { PARAM_NOT_NULL(requestModule); PARAM_NOT_NULL(exceptionValueRef); if (sourceFlag > JsParseModuleSourceFlags_DataIsUTF8) { return JsErrorInvalidArgument; } *exceptionValueRef = JS_INVALID_REFERENCE; HRESULT hr; if (!Js::SourceTextModuleRecord::Is(requestModule)) { return JsErrorInvalidArgument; } Js::SourceTextModuleRecord* moduleRecord = Js::SourceTextModuleRecord::FromHost(requestModule); if (moduleRecord->WasParsed()) { return JsErrorModuleParsed; } Js::ScriptContext* scriptContext = moduleRecord->GetScriptContext(); JsErrorCode errorCode = GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { SourceContextInfo* sourceContextInfo = scriptContext->GetSourceContextInfo(sourceContext, nullptr); if (sourceContextInfo == nullptr) { sourceContextInfo = scriptContext->CreateSourceContextInfo(sourceContext, nullptr, 0, nullptr, nullptr, 0); } SRCINFO si = { /* sourceContextInfo */ sourceContextInfo, /* dlnHost */ 0, /* ulColumnHost */ 0, /* lnMinHost */ 0, /* ichMinHost */ 0, /* ichLimHost */ static_cast<ULONG>(sourceLength), /* ulCharOffset */ 0, /* mod */ 0, /* grfsi */ 0 }; hr = moduleRecord->ParseSource(sourceText, sourceLength, &si, exceptionValueRef, sourceFlag == JsParseModuleSourceFlags_DataIsUTF8 ? true : false); if (FAILED(hr)) { return JsErrorScriptCompile; } return JsNoError; }); return errorCode; }
CHAKRA_API JsInitializeModuleRecord( _In_opt_ JsModuleRecord referencingModule, _In_ JsValueRef normalizedSpecifier, _Outptr_result_maybenull_ JsModuleRecord* moduleRecord) { PARAM_NOT_NULL(moduleRecord); Js::SourceTextModuleRecord* childModuleRecord = nullptr; JsErrorCode errorCode = ContextAPIWrapper_NoRecord<true>([&](Js::ScriptContext *scriptContext) -> JsErrorCode { childModuleRecord = Js::SourceTextModuleRecord::Create(scriptContext); if (referencingModule == nullptr) { childModuleRecord->SetIsRootModule(); } if (normalizedSpecifier != JS_INVALID_REFERENCE) { childModuleRecord->SetSpecifier(normalizedSpecifier); } return JsNoError; }); if (errorCode == JsNoError) { *moduleRecord = childModuleRecord; } else { *moduleRecord = JS_INVALID_REFERENCE; } return errorCode; }
CHAKRA_API JsDiagGetBreakOnException( _In_ JsRuntimeHandle runtimeHandle, _Out_ JsDiagBreakOnExceptionAttributes* exceptionAttributes) { #ifndef ENABLE_SCRIPT_DEBUGGING return JsErrorCategoryUsage; #else return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { VALIDATE_INCOMING_RUNTIME_HANDLE(runtimeHandle); PARAM_NOT_NULL(exceptionAttributes); *exceptionAttributes = JsDiagBreakOnExceptionAttributeNone; JsrtRuntime * runtime = JsrtRuntime::FromHandle(runtimeHandle); JsrtDebugManager* jsrtDebugManager = runtime->GetJsrtDebugManager(); VALIDATE_IS_DEBUGGING(jsrtDebugManager); *exceptionAttributes = jsrtDebugManager->GetBreakOnException(); return JsNoError; }); #endif }
CHAKRA_API JsDiagGetSource( _In_ unsigned int scriptId, _Out_ JsValueRef *source) { #ifndef ENABLE_SCRIPT_DEBUGGING return JsErrorCategoryUsage; #else return ContextAPIWrapper_NoRecord<false>([&](Js::ScriptContext *scriptContext) -> JsErrorCode { PARAM_NOT_NULL(source); *source = JS_INVALID_REFERENCE; JsrtContext *currentContext = JsrtContext::GetCurrent(); JsrtDebugManager* jsrtDebugManager = currentContext->GetRuntime()->GetJsrtDebugManager(); VALIDATE_IS_DEBUGGING(jsrtDebugManager); Js::DynamicObject* sourceObject = jsrtDebugManager->GetSource(scriptContext, scriptId); if (sourceObject != nullptr) { *source = sourceObject; return JsNoError; } return JsErrorInvalidArgument; }); #endif }
CHAKRA_API JsDiagGetScripts( _Out_ JsValueRef *scriptsArray) { #ifndef ENABLE_SCRIPT_DEBUGGING return JsErrorCategoryUsage; #else return ContextAPIWrapper_NoRecord<false>([&](Js::ScriptContext *scriptContext) -> JsErrorCode { PARAM_NOT_NULL(scriptsArray); *scriptsArray = JS_INVALID_REFERENCE; JsrtContext *currentContext = JsrtContext::GetCurrent(); JsrtDebugManager* jsrtDebugManager = currentContext->GetRuntime()->GetJsrtDebugManager(); VALIDATE_IS_DEBUGGING(jsrtDebugManager); Js::JavascriptArray* scripts = jsrtDebugManager->GetScripts(scriptContext); if (scripts != nullptr) { *scriptsArray = scripts; return JsNoError; } return JsErrorDiagUnableToPerformAction; }); #endif }
CHAKRA_API JsDiagSetBreakpoint( _In_ unsigned int scriptId, _In_ unsigned int lineNumber, _In_ unsigned int columnNumber, _Out_ JsValueRef *breakpoint) { #ifndef ENABLE_SCRIPT_DEBUGGING return JsErrorCategoryUsage; #else return ContextAPIWrapper_NoRecord<false>([&](Js::ScriptContext* scriptContext) -> JsErrorCode { PARAM_NOT_NULL(breakpoint); *breakpoint = JS_INVALID_REFERENCE; JsrtContext* currentContext = JsrtContext::GetCurrent(); JsrtRuntime* runtime = currentContext->GetRuntime(); ThreadContextScope scope(runtime->GetThreadContext()); if (!scope.IsValid()) { return JsErrorWrongThread; } VALIDATE_IS_DEBUGGING(runtime->GetJsrtDebugManager()); Js::Utf8SourceInfo* utf8SourceInfo = nullptr; for (Js::ScriptContext* currentScriptContext = runtime->GetThreadContext()->GetScriptContextList(); currentScriptContext != nullptr && utf8SourceInfo == nullptr && !currentScriptContext->IsClosed(); currentScriptContext = currentScriptContext->next) { currentScriptContext->MapScript([&](Js::Utf8SourceInfo* sourceInfo) -> bool { if (sourceInfo->GetSourceInfoId() == scriptId) { utf8SourceInfo = sourceInfo; return true; } return false; }); } if (utf8SourceInfo != nullptr && utf8SourceInfo->HasDebugDocument()) { JsrtDebugManager* jsrtDebugManager = runtime->GetJsrtDebugManager(); Js::DynamicObject* bpObject = jsrtDebugManager->SetBreakPoint(currentContext->GetScriptContext(), utf8SourceInfo, lineNumber, columnNumber); if(bpObject != nullptr) { *breakpoint = bpObject; return JsNoError; } return JsErrorDiagUnableToPerformAction; } return JsErrorDiagObjectNotFound; }); #endif }
CHAKRA_API JsDiagStopDebugging( _In_ JsRuntimeHandle runtimeHandle, _Out_ void** callbackState) { #ifndef ENABLE_SCRIPT_DEBUGGING return JsErrorCategoryUsage; #else return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { VALIDATE_INCOMING_RUNTIME_HANDLE(runtimeHandle); PARAM_NOT_NULL(callbackState); *callbackState = nullptr; JsrtRuntime * runtime = JsrtRuntime::FromHandle(runtimeHandle); ThreadContext * threadContext = runtime->GetThreadContext(); VALIDATE_RUNTIME_STATE_FOR_START_STOP_DEBUGGING(threadContext); JsrtDebugManager* jsrtDebugManager = runtime->GetJsrtDebugManager(); VALIDATE_IS_DEBUGGING(jsrtDebugManager); for (Js::ScriptContext *scriptContext = runtime->GetThreadContext()->GetScriptContextList(); scriptContext != nullptr && !scriptContext->IsClosed(); scriptContext = scriptContext->next) { Assert(scriptContext->IsScriptContextInDebugMode()); HRESULT hr; if (FAILED(hr = scriptContext->OnDebuggerDetached())) { Debugger_AttachDetach_fatal_error(hr); // Inconsistent state, we can't continue from here return JsErrorFatal; } Js::DebugContext* debugContext = scriptContext->GetDebugContext(); Js::ProbeContainer* probeContainer = debugContext->GetProbeContainer(); probeContainer->UninstallInlineBreakpointProbe(nullptr); probeContainer->UninstallDebuggerScriptOptionCallback(); jsrtDebugManager->ClearBreakpointDebugDocumentDictionary(); } *callbackState = jsrtDebugManager->GetAndClearCallbackState(); return JsNoError; }); #endif }
CHAKRA_API JsDiagGetBreakpoints( _Out_ JsValueRef *breakpoints) { #ifndef ENABLE_SCRIPT_DEBUGGING return JsErrorCategoryUsage; #else return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { PARAM_NOT_NULL(breakpoints); *breakpoints = JS_INVALID_REFERENCE; JsrtContext *currentContext = JsrtContext::GetCurrent(); Js::JavascriptArray* bpsArray = currentContext->GetScriptContext()->GetLibrary()->CreateArray(); JsrtRuntime * runtime = currentContext->GetRuntime(); ThreadContextScope scope(runtime->GetThreadContext()); if (!scope.IsValid()) { return JsErrorWrongThread; } JsrtDebugManager* jsrtDebugManager = runtime->GetJsrtDebugManager(); VALIDATE_IS_DEBUGGING(jsrtDebugManager); for (Js::ScriptContext *scriptContext = runtime->GetThreadContext()->GetScriptContextList(); scriptContext != nullptr && !scriptContext->IsClosed(); scriptContext = scriptContext->next) { jsrtDebugManager->GetBreakpoints(&bpsArray, scriptContext); } *breakpoints = bpsArray; return JsNoError; }); #endif }
CHAKRA_API JsDiagStartDebugging( _In_ JsRuntimeHandle runtimeHandle, _In_ JsDiagDebugEventCallback debugEventCallback, _In_opt_ void* callbackState) { #ifndef ENABLE_SCRIPT_DEBUGGING return JsErrorCategoryUsage; #else return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { VALIDATE_INCOMING_RUNTIME_HANDLE(runtimeHandle); PARAM_NOT_NULL(debugEventCallback); JsrtRuntime * runtime = JsrtRuntime::FromHandle(runtimeHandle); ThreadContext * threadContext = runtime->GetThreadContext(); VALIDATE_RUNTIME_STATE_FOR_START_STOP_DEBUGGING(threadContext); if (runtime->GetJsrtDebugManager() != nullptr && runtime->GetJsrtDebugManager()->IsDebugEventCallbackSet()) { return JsErrorDiagAlreadyInDebugMode; } // Create the debug object to save callback function and data runtime->EnsureJsrtDebugManager(); JsrtDebugManager* jsrtDebugManager = runtime->GetJsrtDebugManager(); jsrtDebugManager->SetDebugEventCallback(debugEventCallback, callbackState); if (threadContext->GetDebugManager() != nullptr) { threadContext->GetDebugManager()->SetLocalsDisplayFlags(Js::DebugManager::LocalsDisplayFlags::LocalsDisplayFlags_NoGroupMethods); } for (Js::ScriptContext *scriptContext = runtime->GetThreadContext()->GetScriptContextList(); scriptContext != nullptr && !scriptContext->IsClosed(); scriptContext = scriptContext->next) { Assert(!scriptContext->IsScriptContextInDebugMode()); Js::DebugContext* debugContext = scriptContext->GetDebugContext(); if (debugContext->GetHostDebugContext() == nullptr) { debugContext->SetHostDebugContext(jsrtDebugManager); } HRESULT hr; if (FAILED(hr = scriptContext->OnDebuggerAttached())) { Debugger_AttachDetach_fatal_error(hr); // Inconsistent state, we can't continue from here return JsErrorFatal; } // ScriptContext might get closed in OnDebuggerAttached if (!scriptContext->IsClosed()) { Js::ProbeContainer* probeContainer = debugContext->GetProbeContainer(); probeContainer->InitializeInlineBreakEngine(jsrtDebugManager); probeContainer->InitializeDebuggerScriptOptionCallback(jsrtDebugManager); } } return JsNoError; }); #endif }