| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #pragma once
- namespace Js
- {
- class MutationBreakpoint;
- enum StopType
- {
- STOP_BREAKPOINT,
- STOP_INLINEBREAKPOINT,
- STOP_STEPCOMPLETE,
- STOP_EXCEPTIONTHROW,
- STOP_ASYNCBREAK,
- STOP_MUTATIONBREAKPOINT,
- STOP_DOMMUTATIONBREAKPOINT
- };
- struct ReturnedValue
- {
- ReturnedValue() {}
- ReturnedValue(Js::Var _returnedValue, Js::JavascriptFunction * _calledFunction, bool _isValueOfReturnStatement)
- : returnedValue(_returnedValue), calledFunction(_calledFunction), isValueOfReturnStatement(_isValueOfReturnStatement)
- {
- if (isValueOfReturnStatement)
- {
- Assert(returnedValue == nullptr);
- Assert(calledFunction == nullptr);
- }
- }
- Field(Js::Var) returnedValue;
- Field(Js::JavascriptFunction *) calledFunction;
- Field(bool) isValueOfReturnStatement;
- };
- typedef JsUtil::List<ReturnedValue*> ReturnedValueList;
- class DiagStackFrame;
- typedef JsUtil::Stack<DiagStackFrame*> DiagStack;
- typedef WeakArenaReference<DiagStack> WeakDiagStack;
- struct InterpreterHaltState
- {
- StopType stopType;
- const FunctionBody* executingFunction;
- DiagStackFrame* topFrame;
- DiagStack* framePointers;
- ReferencedArenaAdapter* referencedDiagnosticArena;
- JavascriptExceptionObject* exceptionObject;
- StringBuilder<ArenaAllocator>* stringBuilder;
- MutationBreakpoint* activeMutationBP;
- InterpreterHaltState(StopType _stopType, const FunctionBody* _executingFunction, MutationBreakpoint* _activeMutationBP = nullptr);
- FunctionBody* GetFunction();
- int GetCurrentOffset();
- void SetCurrentOffset(int offset);
- bool IsValid() const;
- };
- struct HaltCallback
- {
- virtual bool CanHalt(InterpreterHaltState* pHaltState) = 0;
- virtual void DispatchHalt(InterpreterHaltState* pHaltState) = 0;
- virtual void CleanupHalt() = 0;
- virtual bool IsInClosedState() { return false; }
- // Mentions the policy if the hitting a breakpoint is allowed (based on the fact whether we are at callback from the breakpoint)
- virtual bool CanAllowBreakpoints() { return false; }
- };
- struct Probe : HaltCallback
- {
- virtual bool Install(Js::ScriptContext* pScriptContext) = 0;
- virtual bool Uninstall(Js::ScriptContext* pScriptContext) = 0;
- };
- enum StepType : BYTE
- {
- STEP_NONE,
- STEP_IN = 0x01,
- STEP_OVER = 0x02,
- STEP_OUT = 0x04,
- STEP_DOCUMENT = 0x08,
- // On entry of a jitted function, need to bailout to handle stepping if in STEP_IN mode,
- // or STEP_OVER (e.g. STEP_OVER at the end of this function, and it is called again by a
- // library caller).
- STEP_BAILOUT = STEP_IN | STEP_OVER,
- };
- struct DebuggerOptionsCallback
- {
- virtual bool IsExceptionReportingEnabled() { return true; }
- virtual bool IsFirstChanceExceptionEnabled() { return false; }
- virtual bool IsNonUserCodeSupportEnabled() { return false; }
- virtual bool IsLibraryStackFrameSupportEnabled() { return false; }
- };
- class StepController
- {
- friend class ProbeManager;
- friend class ProbeContainer;
- StepType stepType;
- int byteOffset;
- RecyclerRootPtr<FunctionBody> body;
- FunctionBody::StatementMap* statementMap;
- int frameCountWhenSet;
- int returnedValueRecordingDepth;
- DWORD_PTR frameAddrWhenSet;
- uint scriptIdWhenSet;
- bool stepCompleteOnInlineBreakpoint;
- ScriptContext *pActivatedContext;
- ReturnedValueList *returnedValueList;
- public:
- StepController();
- ~StepController()
- {
- this->Deactivate();
- }
- bool IsActive();
- void Activate(StepType stepType, InterpreterHaltState* haltState);
- void Deactivate(InterpreterHaltState* haltState = nullptr);
- bool IsStepComplete_AllowingFalsePositives(InterpreterStackFrame * stackFrame);
- bool IsStepComplete(InterpreterHaltState* haltState, HaltCallback *haltCallback, OpCode originalOpcode);
- bool ContinueFromInlineBreakpoint();
- ScriptContext* GetActivatedContext() const
- {
- return this->pActivatedContext;
- }
- const StepType* GetAddressOfStepType() const
- {
- return &stepType;
- }
- void* GetAddressOfScriptIdWhenSet() const
- {
- return (void*)&scriptIdWhenSet;
- }
- void* GetAddressOfFrameAddress() const
- {
- return (void*)&frameAddrWhenSet;
- }
- void SetFrameAddr(DWORD_PTR value)
- {
- this->frameAddrWhenSet = value;
- }
- void AddToReturnedValueContainer(Js::Var returnValue, Js::JavascriptFunction * function, bool isValueOfReturnStatement);
- void AddReturnToReturnedValueContainer();
- void StartRecordingCall();
- void EndRecordingCall(Js::Var returnValue, Js::JavascriptFunction * function);
- ReturnedValueList* GetReturnedValueList() const { return this->returnedValueList; }
- void ResetReturnedValueList();
- void HandleResumeAction(Js::InterpreterHaltState* haltState, BREAKRESUMEACTION resumeAction);
- private:
- uint GetScriptId(_In_ FunctionBody* body);
- };
- // This is separate from the step controller because it is the only case where activation
- // happens while the script is running.
- class AsyncBreakController
- {
- private:
- HaltCallback* haltCallback;
- public:
- AsyncBreakController();
- void Activate(HaltCallback* haltCallback);
- void Deactivate();
- bool IsBreak();
- bool IsAtStoppingLocation(InterpreterHaltState* haltState);
- void DispatchAndReset(InterpreterHaltState* haltState);
- };
- typedef JsUtil::List<Probe*, ArenaAllocator> ProbeList;
- }
|