Beispiel #1
0
CHAKRA_API JsDiagRemoveBreakpoint(
    _In_ unsigned int breakpointId)
{
#ifndef ENABLE_SCRIPT_DEBUGGING
    return JsErrorCategoryUsage;
#else
    return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode {

        JsrtContext *currentContext = JsrtContext::GetCurrent();

        JsrtRuntime* runtime = currentContext->GetRuntime();

        ThreadContextScope scope(runtime->GetThreadContext());

        if (!scope.IsValid())
        {
            return JsErrorWrongThread;
        }

        JsrtDebugManager* jsrtDebugManager = runtime->GetJsrtDebugManager();

        VALIDATE_IS_DEBUGGING(jsrtDebugManager);

        if (!jsrtDebugManager->RemoveBreakpoint(breakpointId))
        {
            return JsErrorInvalidArgument;
        }

        return JsNoError;
    });
#endif
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
/* static */
bool JsrtContext::TrySetCurrent(JsrtContext * context)
{
    Assert(s_tlsSlot != TLS_OUT_OF_INDEXES);

    ThreadContext * threadContext;

    //We are not pinning the context after SetCurrentContext, so if the context is not pinned
    //it might be reclaimed half way during execution. In jsrtshell the runtime was optimized out
    //at time of JsrtContext::Run by the compiler.
    //The change is to pin the context at setconcurrentcontext, and unpin the previous one. In
    //JsDisposeRuntime we'll reject if current context is active, so that will make sure all
    //contexts are unpinned at time of JsDisposeRuntime.
    if (context != nullptr)
    {
        threadContext = context->GetScriptContext()->GetThreadContext();

        if (!ThreadContextTLSEntry::TrySetThreadContext(threadContext))
        {
            return false;
        }
        threadContext->GetRecycler()->RootAddRef((LPVOID)context);
    }
    else
    {
        if (!ThreadContextTLSEntry::ClearThreadContext(true))
        {
            return false;
        }
    }

    JsrtContext* originalContext = (JsrtContext*) TlsGetValue(s_tlsSlot);
    if (originalContext != nullptr)
    {
        originalContext->GetScriptContext()->GetRecycler()->RootRelease((LPVOID) originalContext);
    }

    TlsSetValue(s_tlsSlot, context);
    return true;
}
Beispiel #7
0
CHAKRA_API JsDiagSetStepType(
    _In_ JsDiagStepType stepType)
{
#ifndef ENABLE_SCRIPT_DEBUGGING
    return JsErrorCategoryUsage;
#else
    return ContextAPIWrapper_NoRecord<true>([&](Js::ScriptContext * scriptContext) -> JsErrorCode {

        JsrtContext *currentContext = JsrtContext::GetCurrent();
        JsrtRuntime* runtime = currentContext->GetRuntime();

        VALIDATE_RUNTIME_IS_AT_BREAK(runtime);

        JsrtDebugManager* jsrtDebugManager = runtime->GetJsrtDebugManager();

        VALIDATE_IS_DEBUGGING(jsrtDebugManager);

        if (stepType == JsDiagStepTypeStepIn)
        {
            jsrtDebugManager->SetResumeType(BREAKRESUMEACTION_STEP_INTO);
        }
        else if (stepType == JsDiagStepTypeStepOut)
        {
           jsrtDebugManager->SetResumeType(BREAKRESUMEACTION_STEP_OUT);
        }
        else if (stepType == JsDiagStepTypeStepOver)
        {
            jsrtDebugManager->SetResumeType(BREAKRESUMEACTION_STEP_OVER);
        }
        else if (stepType == JsDiagStepTypeStepBack)
        {
#if ENABLE_TTD
            ThreadContext* threadContext = runtime->GetThreadContext();
            if(!threadContext->IsRuntimeInTTDMode())
            {
                //Don't want to fail hard when user accidentally clicks this so pring message and step forward 
                fprintf(stderr, "Must be in replay mode to use reverse-step - launch with \"--replay-debug\" flag in Node.");
                jsrtDebugManager->SetResumeType(BREAKRESUMEACTION_STEP_OVER);
            }
            else
            {
                threadContext->TTDExecutionInfo->SetPendingTTDStepBackMove();

                //don't worry about BP suppression because we are just going to throw after we return
                jsrtDebugManager->SetResumeType(BREAKRESUMEACTION_CONTINUE);
            }
#else
            return JsErrorInvalidArgument;
#endif
        }
        else if (stepType == JsDiagStepTypeReverseContinue)
        {
#if ENABLE_TTD
            ThreadContext* threadContext = runtime->GetThreadContext();
            if(!threadContext->IsRuntimeInTTDMode())
            {
                //Don't want to fail hard when user accidentally clicks this so pring message and step forward 
                fprintf(stderr, "Must be in replay mode to use reverse-continue - launch with \"--replay-debug\" flag in Node.");
                jsrtDebugManager->SetResumeType(BREAKRESUMEACTION_CONTINUE);
            }
            else
            {
                threadContext->TTDExecutionInfo->SetPendingTTDReverseContinueMove(JsTTDMoveMode::JsTTDMoveScanIntervalForContinue);

                //don't worry about BP suppression because we are just going to throw after we return
                jsrtDebugManager->SetResumeType(BREAKRESUMEACTION_CONTINUE);
            }
#else
            return JsErrorInvalidArgument;
#endif
        }
        else if (stepType == JsDiagStepTypeContinue)
        {
            jsrtDebugManager->SetResumeType(BREAKRESUMEACTION_CONTINUE);
        }

        return JsNoError;
    });
#endif
}