366 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			366 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef HX_DEBUG_H
 | 
						|
#define HX_DEBUG_H
 | 
						|
 | 
						|
#include <hxcpp.h>
 | 
						|
 | 
						|
// Some functions used by AdvancedDebug.cpp
 | 
						|
// Returns the thread number of the calling thread
 | 
						|
HXCPP_EXTERN_CLASS_ATTRIBUTES
 | 
						|
int __hxcpp_GetCurrentThreadNumber();
 | 
						|
 | 
						|
namespace hx
 | 
						|
{
 | 
						|
 | 
						|
#ifdef HXCPP_DEBUGGER
 | 
						|
 | 
						|
template<typename T> struct StackVariableWrapper
 | 
						|
{
 | 
						|
   typedef T wrapper;
 | 
						|
};
 | 
						|
template<> struct StackVariableWrapper<size_t>
 | 
						|
{
 | 
						|
   #ifdef HXCPP_M64
 | 
						|
   typedef cpp::Int64 wrapper;
 | 
						|
   #else
 | 
						|
   typedef int wrapper;
 | 
						|
   #endif
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
template<typename T> struct StackVariableWrapper<T *>
 | 
						|
{
 | 
						|
   typedef cpp::Pointer<T> wrapper;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
class StackVariable
 | 
						|
{
 | 
						|
public:
 | 
						|
 | 
						|
    const char *mHaxeName;
 | 
						|
    bool mIsArg;
 | 
						|
    StackVariable *mNext;
 | 
						|
 | 
						|
    template<typename T>
 | 
						|
    StackVariable(StackVariable *&inHead, bool inIsArg,
 | 
						|
                  const char *inHaxeName, T *inCppVar)
 | 
						|
        : mHaxeName(inHaxeName), mIsArg(inIsArg), mHead(inHead),
 | 
						|
          mCppVar((void *) inCppVar)
 | 
						|
    {
 | 
						|
        mGetOrSetFunction = GetOrSetFunction<T>;
 | 
						|
        mNext = mHead;
 | 
						|
        mHead = this;
 | 
						|
    }
 | 
						|
 | 
						|
    StackVariable(StackVariable *&inHead, bool inIsArg,
 | 
						|
                  const char *inHaxeName, hx::Object **inCppVar)
 | 
						|
        : mHaxeName(inHaxeName), mIsArg(inIsArg), mHead(inHead),
 | 
						|
          mCppVar((void *) inCppVar)
 | 
						|
    {
 | 
						|
        mGetOrSetFunction = GetOrSetFunctionHxObject;
 | 
						|
        mNext = mHead;
 | 
						|
        mHead = this;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    // For StackThis
 | 
						|
    template<typename T>
 | 
						|
    StackVariable(StackVariable *&inHead, T *inCppVar)
 | 
						|
        : mHaxeName("this"), mIsArg(true), mHead(inHead),
 | 
						|
          mCppVar((void *) inCppVar)
 | 
						|
    {
 | 
						|
        mNext = mHead;
 | 
						|
        mHead = this;
 | 
						|
    }
 | 
						|
 | 
						|
    ~StackVariable()
 | 
						|
    {
 | 
						|
        // Stack variables are always deleted in the reverse order that they
 | 
						|
        // are created, so a simple pop_front is sufficient; no need to hunt
 | 
						|
        // for and remove the variable, it's always in the front ...
 | 
						|
        mHead = mNext;
 | 
						|
    }
 | 
						|
 | 
						|
    operator Dynamic()
 | 
						|
    {
 | 
						|
        return mGetOrSetFunction(true, mCppVar, 0);
 | 
						|
    }
 | 
						|
 | 
						|
    StackVariable &operator =(Dynamic &other)
 | 
						|
    {
 | 
						|
        (void) mGetOrSetFunction(false, mCppVar, &other);
 | 
						|
 | 
						|
        return *this;
 | 
						|
    }
 | 
						|
 | 
						|
protected:
 | 
						|
 | 
						|
	typedef Dynamic (*GetOrSetFunctionType)(bool, void *, Dynamic *);
 | 
						|
 | 
						|
    GetOrSetFunctionType mGetOrSetFunction;
 | 
						|
 | 
						|
private:
 | 
						|
 | 
						|
    template<typename T>
 | 
						|
    static Dynamic GetOrSetFunction(bool get, void *ptr, Dynamic *dynamic)
 | 
						|
    {
 | 
						|
       typedef typename StackVariableWrapper<T>::wrapper Wrap;
 | 
						|
 | 
						|
        if (get) {
 | 
						|
            return Wrap(* (T *) ptr);
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            * (T *) ptr = Wrap(*dynamic);
 | 
						|
            return null();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    static Dynamic GetOrSetFunctionHxObject(bool get, void *ptr, Dynamic *dynamic)
 | 
						|
    {
 | 
						|
        if (get) {
 | 
						|
            return * (hx::Object **) ptr;
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            * (hx::Object **)ptr = dynamic->mPtr;
 | 
						|
            return null();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    StackVariable *&mHead;
 | 
						|
 | 
						|
    void *mCppVar;
 | 
						|
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
class StackThis : public StackVariable
 | 
						|
{
 | 
						|
public:
 | 
						|
 | 
						|
    template<typename T>
 | 
						|
    StackThis(StackVariable *&inHead, T *inThis)
 | 
						|
        : StackVariable(inHead, inThis)
 | 
						|
    {
 | 
						|
        mGetOrSetFunction = GetFunction<T>;
 | 
						|
    }
 | 
						|
 | 
						|
    template<typename T>
 | 
						|
    StackThis(StackVariable *&inHead, hx::ObjectPtr<T> &inThis)
 | 
						|
        : StackVariable(inHead, &inThis.mPtr)
 | 
						|
    {
 | 
						|
        mGetOrSetFunction = GetObjectPtr<T>;
 | 
						|
    }
 | 
						|
 | 
						|
    template<typename T>
 | 
						|
    static Dynamic GetObjectPtr(bool get, void *ptr, Dynamic *val)
 | 
						|
    {
 | 
						|
        if (get) {
 | 
						|
            return *(hx::Object **) ptr;
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            return null();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    template<typename T>
 | 
						|
    static Dynamic GetFunction(bool get, void *ptr, Dynamic *val)
 | 
						|
    {
 | 
						|
        if (get) {
 | 
						|
            return (T *) ptr;
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            return null();
 | 
						|
        }
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
class StackCatchable
 | 
						|
{
 | 
						|
public:
 | 
						|
 | 
						|
    StackCatchable *mNext;
 | 
						|
 | 
						|
    template<typename T>
 | 
						|
    StackCatchable(StackFrame &frame, T * /* dummy required by template*/)
 | 
						|
        : mFrame(frame)
 | 
						|
{
 | 
						|
        mNext = frame.catchables;
 | 
						|
        frame.catchables = this;
 | 
						|
        mTestFunction = TestFunction<T>;
 | 
						|
    }
 | 
						|
 | 
						|
    ~StackCatchable()
 | 
						|
{
 | 
						|
        mFrame.catchables = mNext;
 | 
						|
    }
 | 
						|
 | 
						|
    bool Catches(Dynamic e) const
 | 
						|
   {
 | 
						|
        return mTestFunction(e);
 | 
						|
   }
 | 
						|
 | 
						|
private:
 | 
						|
 | 
						|
   template<typename T>
 | 
						|
    static bool TestFunction(Dynamic e)
 | 
						|
   {
 | 
						|
        return e.IsClass<T>();
 | 
						|
   }
 | 
						|
 | 
						|
    StackFrame &mFrame;
 | 
						|
    bool (*mTestFunction)(Dynamic e);
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#endif // HXCPP_DEBUGGER
 | 
						|
 | 
						|
} // end namespace hx
 | 
						|
 | 
						|
 | 
						|
 | 
						|
void __hxcpp_dbg_getScriptableFiles( Array< ::String> ioPaths );
 | 
						|
void __hxcpp_dbg_getScriptableFilesFullPath( Array< ::String> ioPaths );
 | 
						|
void __hxcpp_dbg_getScriptableClasses( Array< ::String> ioClasses );
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#ifdef HXCPP_DEBUGGER
 | 
						|
 | 
						|
 | 
						|
namespace hx
 | 
						|
{
 | 
						|
 | 
						|
// These must match the values present in cpp.vm.Debugger
 | 
						|
 | 
						|
enum ThreadEvent
 | 
						|
{
 | 
						|
    THREAD_CREATED = 1,
 | 
						|
    THREAD_TERMINATED = 2,
 | 
						|
    THREAD_STARTED = 3,
 | 
						|
    THREAD_STOPPED = 4
 | 
						|
};
 | 
						|
 | 
						|
enum StepType
 | 
						|
{
 | 
						|
    STEP_NONE = 0, // Not present or needed in cpp.vm.Debugger
 | 
						|
    STEP_INTO = 1,
 | 
						|
    STEP_OVER = 2,
 | 
						|
    STEP_OUT = 3
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
}  // end namespace hx
 | 
						|
 | 
						|
 | 
						|
// The following functions are called directly, and only, by the haxe standard
 | 
						|
// library's cpp.vm.Debugger.hx class
 | 
						|
void __hxcpp_dbg_setEventNotificationHandler(Dynamic handler);
 | 
						|
void __hxcpp_dbg_enableCurrentThreadDebugging(bool enable);
 | 
						|
int __hxcpp_dbg_getCurrentThreadNumber();
 | 
						|
Array< ::String> __hxcpp_dbg_getFiles();
 | 
						|
Array< ::String> __hxcpp_dbg_getFilesFullPath();
 | 
						|
Array< ::String> __hxcpp_dbg_getClasses();
 | 
						|
Array<Dynamic> __hxcpp_dbg_getThreadInfos();
 | 
						|
Dynamic __hxcpp_dbg_getThreadInfo(int threadNumber, bool unsafe);
 | 
						|
int __hxcpp_dbg_addFileLineBreakpoint(String fileName, int lineNumber);
 | 
						|
int __hxcpp_dbg_addClassFunctionBreakpoint(String className,
 | 
						|
                                            String functionName);
 | 
						|
void __hxcpp_dbg_deleteAllBreakpoints();
 | 
						|
void __hxcpp_dbg_deleteBreakpoint(int number);
 | 
						|
void __hxcpp_dbg_breakNow(bool wait);
 | 
						|
void __hxcpp_dbg_continueThreads(int threadNumber, int count);
 | 
						|
void __hxcpp_dbg_stepThread(int threadNumber, int stepType, int stepCount);
 | 
						|
Array<Dynamic> __hxcpp_dbg_getStackVariables(int threadNumber,
 | 
						|
                                             int stackFrameNumber,
 | 
						|
                                             bool unsafe,
 | 
						|
                                             Dynamic markThreadNotStopped);
 | 
						|
Dynamic __hxcpp_dbg_getStackVariableValue(int threadNumber,
 | 
						|
                                          int stackFrameNumber,
 | 
						|
                                          String name,
 | 
						|
                                          bool unsafe,
 | 
						|
                                          Dynamic markNonexistent,
 | 
						|
                                          Dynamic markThreadNotStopped);
 | 
						|
 | 
						|
Dynamic __hxcpp_dbg_setStackVariableValue(int threadNumber,
 | 
						|
                                          int stackFrameNumber,
 | 
						|
                                          String name, Dynamic value,
 | 
						|
                                          bool unsafe,
 | 
						|
                                          Dynamic markNonexistent,
 | 
						|
                                          Dynamic markThreadNotStopped);
 | 
						|
void __hxcpp_dbg_setNewParameterFunction(Dynamic function);
 | 
						|
void __hxcpp_dbg_setNewStackFrameFunction(Dynamic function);
 | 
						|
void __hxcpp_dbg_setNewThreadInfoFunction(Dynamic function);
 | 
						|
void __hxcpp_dbg_setAddParameterToStackFrameFunction(Dynamic function);
 | 
						|
void __hxcpp_dbg_setAddStackFrameToThreadInfoFunction(Dynamic function);
 | 
						|
 | 
						|
bool __hxcpp_dbg_fix_critical_error(String inErr);
 | 
						|
 | 
						|
// The following functions are called by Thread.cpp to notify of thread
 | 
						|
// created and terminated
 | 
						|
void __hxcpp_dbg_threadCreatedOrTerminated(int threadNumber, bool created);
 | 
						|
 | 
						|
// The following is called by the stack macros, but only if
 | 
						|
// HXCPP_DEBUGGER is set
 | 
						|
HXCPP_EXTERN_CLASS_ATTRIBUTES
 | 
						|
Dynamic __hxcpp_dbg_checkedThrow(Dynamic toThrow);
 | 
						|
HXCPP_EXTERN_CLASS_ATTRIBUTES
 | 
						|
Dynamic __hxcpp_dbg_checkedRethrow(Dynamic toThrow);
 | 
						|
 | 
						|
#else // !HXCPP_DEBUGGER
 | 
						|
 | 
						|
// If no debugger, provide empty implementations of the debugging functions
 | 
						|
 | 
						|
inline void __hxcpp_dbg_setEventNotificationHandler(Dynamic)
 | 
						|
    { hx::Throw("Debugging is not enabled for this program; try\n"
 | 
						|
                "rebuilding it with the -D HXCPP_DEBUGGER option"); }
 | 
						|
inline void __hxcpp_dbg_enableCurrentThreadDebugging(bool) { }
 | 
						|
inline int __hxcpp_dbg_getCurrentThreadNumber() { return -1; }
 | 
						|
inline Array< ::String> __hxcpp_dbg_getFiles()
 | 
						|
    { return Array_obj< String>::__new(); }
 | 
						|
inline Array< ::String> __hxcpp_dbg_getFilesFullPath()
 | 
						|
    { return Array_obj< String>::__new(); }
 | 
						|
inline Array< ::String> __hxcpp_dbg_getClasses()
 | 
						|
    { return Array_obj< String>::__new(); }
 | 
						|
inline Array<Dynamic> __hxcpp_dbg_getThreadInfos()
 | 
						|
    { return Array_obj< ::Dynamic>::__new(); }
 | 
						|
inline Dynamic __hxcpp_dbg_getThreadInfo(int, bool) { return null(); }
 | 
						|
inline int __hxcpp_dbg_addFileLineBreakpoint(String, int) { return -1; }
 | 
						|
inline int __hxcpp_dbg_addClassFunctionBreakpoint(String, String)
 | 
						|
    { return -1; }
 | 
						|
inline void __hxcpp_dbg_deleteAllBreakpoints() { }
 | 
						|
inline void __hxcpp_dbg_deleteBreakpoint(int) { }
 | 
						|
inline void __hxcpp_dbg_breakNow(bool) { }
 | 
						|
inline void __hxcpp_dbg_continueThreads(int, int) { }
 | 
						|
inline void __hxcpp_dbg_stepThread(int, int, int) { }
 | 
						|
inline Array<Dynamic> __hxcpp_dbg_getStackVariables(int, int, bool, Dynamic)
 | 
						|
    { return Array_obj< String>::__new(); }
 | 
						|
inline Dynamic __hxcpp_dbg_getStackVariableValue(int, int, String, bool,
 | 
						|
                                                 Dynamic, Dynamic)
 | 
						|
    { return null(); }
 | 
						|
inline Dynamic __hxcpp_dbg_setStackVariableValue(int, int, String, Dynamic,
 | 
						|
                                                 bool, Dynamic, Dynamic)
 | 
						|
    { return null(); }
 | 
						|
inline void __hxcpp_dbg_setNewParameterFunction(Dynamic) { }
 | 
						|
inline void __hxcpp_dbg_setNewStackFrameFunction(Dynamic) { }
 | 
						|
inline void __hxcpp_dbg_setNewThreadInfoFunction(Dynamic) { }
 | 
						|
inline void __hxcpp_dbg_setAddParameterToStackFrameFunction(Dynamic) { }
 | 
						|
inline void __hxcpp_dbg_setAddStackFrameToThreadInfoFunction(Dynamic) { }
 | 
						|
 | 
						|
// The following functions are called by Thread.cpp to notify of thread
 | 
						|
// created and terminated
 | 
						|
inline void __hxcpp_dbg_threadCreatedOrTerminated(int, bool) { }
 | 
						|
 | 
						|
inline Dynamic __hxcpp_dbg_checkedThrow(Dynamic toThrow) { return hx::Throw(toThrow); }
 | 
						|
inline Dynamic __hxcpp_dbg_checkedRethrow(Dynamic toThrow) { return hx::Rethrow(toThrow); }
 | 
						|
 | 
						|
#endif // HXCPP_DEBUGGER
 | 
						|
 | 
						|
 | 
						|
#endif // HX_DEBUG_H
 |