753 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			753 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#ifndef HX_STACK_CONTEXT_H
							 | 
						||
| 
								 | 
							
								#define HX_STACK_CONTEXT_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "QuickVec.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef HXCPP_SINGLE_THREADED_APP
							 | 
						||
| 
								 | 
							
								  #define HX_CTX_GET ::hx::gMainThreadContext
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								  #define HX_CTX_GET ((::hx::StackContext *)::hx::tlsStackContext)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Set:
							 | 
						||
| 
								 | 
							
								// HXCPP_STACK_LINE if stack line numbers need to be tracked
							 | 
						||
| 
								 | 
							
								// HXCPP_STACK_TRACE if stack frames need to be tracked
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Keep track of lines - more accurate stack traces for exceptions, also
							 | 
						||
| 
								 | 
							
								// needed for the debugger
							 | 
						||
| 
								 | 
							
								#if (defined(HXCPP_DEBUG) || defined(HXCPP_DEBUGGER)) && !defined(HXCPP_STACK_LINE)
							 | 
						||
| 
								 | 
							
								#define HXCPP_STACK_LINE
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Do we need to keep a stack trace - for basic exception handelling, also needed for the debugger
							 | 
						||
| 
								 | 
							
								// At a minimum, you can track the functions calls and nothing else
							 | 
						||
| 
								 | 
							
								#if (defined(HXCPP_STACK_LINE) || defined(HXCPP_TELEMETRY) || defined(HXCPP_PROFILER) || defined(HXCPP_DEBUG)) && !defined(HXCPP_STACK_TRACE)
							 | 
						||
| 
								 | 
							
								   #define HXCPP_STACK_TRACE
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(HXCPP_STACK_TRACE) && defined(HXCPP_SCRIPTABLE)
							 | 
						||
| 
								 | 
							
								#define HXCPP_STACK_SCRIPTABLE
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								// HXCPP_DEBUG_HASH == HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								// HXCPP_STACK_VARS == HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// HX_STACKFRAME(pos)    - tracks position according to define.  May be optimized away.
							 | 
						||
| 
								 | 
							
								// HX_GC_STACKFRAME(pos) - tracks position according to define, but is never optimized away
							 | 
						||
| 
								 | 
							
								// HX_JUST_GC_STACKFRAME - never tracks position, never optimized away
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Setup the _hx_stackframe variable
							 | 
						||
| 
								 | 
							
								#ifdef HXCPP_STACK_TRACE
							 | 
						||
| 
								 | 
							
								   // Setup the 'HX_DEFINE_STACK_FRAME' 'HX_LOCAL_STACK_FRAME' macro.
							 | 
						||
| 
								 | 
							
								   // This will be empty, just track functions(release), track functions and lines(debug) or track everything (debugger)
							 | 
						||
| 
								 | 
							
								   #define HX_DECLARE_STACK_FRAME(name) extern ::hx::StackPosition name;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_STACK_LINE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      #ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								         #define HX_DEFINE_STACK_FRAME(varName, className, functionName, classFunctionHash, fullName,fileName,     \
							 | 
						||
| 
								 | 
							
								                             lineNumber, fileHash ) \
							 | 
						||
| 
								 | 
							
								          ::hx::StackPosition varName(className, functionName, fullName, fileName, lineNumber, \
							 | 
						||
| 
								 | 
							
								                                            classFunctionHash, fileHash);
							 | 
						||
| 
								 | 
							
								      #else
							 | 
						||
| 
								 | 
							
								         #define HX_DEFINE_STACK_FRAME(varName, className, functionName, classFunctionHash, fullName,fileName,     \
							 | 
						||
| 
								 | 
							
								                          lineNumber, fileHash ) \
							 | 
						||
| 
								 | 
							
								          ::hx::StackPosition varName(className, functionName, fullName, fileName, lineNumber);
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								   #else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      #define HX_DEFINE_STACK_FRAME(varName, className, functionName, classFunctionHash, fullName,fileName,     \
							 | 
						||
| 
								 | 
							
								                          lineNumber, fileHash ) \
							 | 
						||
| 
								 | 
							
								      ::hx::StackPosition varName(className, functionName, fullName, fileName);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #define HX_LOCAL_STACK_FRAME(a,b,c,d,e,f,g,h) static HX_DEFINE_STACK_FRAME(a,b,c,d,e,f,g,h)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // Haxe < 330 does not create position pointers, and we must use a local one.
							 | 
						||
| 
								 | 
							
								   // This code will hst the 'HX_STACK_FRAME' macro
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_FRAME(className, functionName, classFunctionHash, fullName,fileName, lineNumber, fileHash ) \
							 | 
						||
| 
								 | 
							
								      HX_DEFINE_STACK_FRAME(__stackPosition, className, functionName, classFunctionHash, fullName,fileName, lineNumber, fileHash ) \
							 | 
						||
| 
								 | 
							
								      ::hx::StackFrame _hx_stackframe(&__stackPosition);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // Newer code will use the HX_STACKFRAME macro
							 | 
						||
| 
								 | 
							
								   #define HX_STACKFRAME(pos) ::hx::StackFrame _hx_stackframe(pos);
							 | 
						||
| 
								 | 
							
								   #define HX_GC_STACKFRAME(pos) ::hx::StackFrame _hx_stackframe(pos);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // Must record the stack state at the catch
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_BEGIN_CATCH __hxcpp_stack_begin_catch();
							 | 
						||
| 
								 | 
							
								   #define HX_JUST_GC_STACKFRAME ::hx::JustGcStackFrame _hx_stackframe;
							 | 
						||
| 
								 | 
							
								   #define HX_CTX _hx_stackframe.ctx
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								   // No need to track frame
							 | 
						||
| 
								 | 
							
								   #define HX_DECLARE_STACK_FRAME(name)
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_BEGIN_CATCH
							 | 
						||
| 
								 | 
							
								   #define HX_DEFINE_STACK_FRAME(__stackPosition, className, functionName, classFunctionHash, fullName,fileName, lineNumber, fileHash )
							 | 
						||
| 
								 | 
							
								   #define HX_LOCAL_STACK_FRAME(a,b,c,d,e,f,g,h)
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_FRAME(className, functionName, classFunctionHash, fullName,fileName, lineNumber, fileHash )
							 | 
						||
| 
								 | 
							
								   #define HX_STACKFRAME(pos)
							 | 
						||
| 
								 | 
							
								   #define HX_JUST_GC_STACKFRAME ::hx::StackContext *_hx_ctx = HX_CTX_GET;
							 | 
						||
| 
								 | 
							
								   #define HX_GC_STACKFRAME(pos) HX_JUST_GC_STACKFRAME
							 | 
						||
| 
								 | 
							
								   #define HX_CTX _hx_ctx
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define HX_GC_CTX HX_CTX
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Setup debugger catchable and variable macros...
							 | 
						||
| 
								 | 
							
								#ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // Emitted at the beginning of every instance fuction.  ptr is "this".
							 | 
						||
| 
								 | 
							
								   // Only if stack variables are to be tracked
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_THIS(ptr) ::hx::StackThis __stackthis(_hx_stackframe.variables, ptr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // Emitted at the beginning of every function that takes arguments.
							 | 
						||
| 
								 | 
							
								   // name is the name of the argument.
							 | 
						||
| 
								 | 
							
								   // For the lifetime of this object, the argument will be in the [arguments]
							 | 
						||
| 
								 | 
							
								   // list of the stack frame in which the arg was declared
							 | 
						||
| 
								 | 
							
								   // Only if stack variables are to be tracked
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_ARG(cpp_var, haxe_name) \
							 | 
						||
| 
								 | 
							
								       ::hx::StackVariable __stackargument_##cpp_var(_hx_stackframe.variables, true, haxe_name, &cpp_var);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // Emitted whenever a Haxe value is pushed on the stack.  cpp_var is the local
							 | 
						||
| 
								 | 
							
								   // cpp variable, haxe_name is the name that was used in haxe for it
							 | 
						||
| 
								 | 
							
								   // Only if stack variables are to be tracked
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_VAR(cpp_var, haxe_name)                                \
							 | 
						||
| 
								 | 
							
								       ::hx::StackVariable __stackvariable_##cpp_var(_hx_stackframe.variables, false, haxe_name, &cpp_var);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_CATCHABLE(T, n)                                        \
							 | 
						||
| 
								 | 
							
								       hx::StackCatchable __stackcatchable_##n                             \
							 | 
						||
| 
								 | 
							
								           (_hx_stackframe, reinterpret_cast<T *>(&_hx_stackframe));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // If HXCPP_DEBUGGER is enabled, then a throw is checked to see if it
							 | 
						||
| 
								 | 
							
								   // can be caught and if not, the debugger is entered.  Otherwise, the
							 | 
						||
| 
								 | 
							
								   // throw proceeds as normal.
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_DO_THROW(e) __hxcpp_dbg_checkedThrow(e)
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_DO_RETHROW(e) __hxcpp_dbg_checkedRethrow(e)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #define HX_VAR(type,name) type name; HX_STACK_VAR(name, #name)
							 | 
						||
| 
								 | 
							
								   #define HX_VARI(type,name) type name; HX_STACK_VAR(name, #name) name
							 | 
						||
| 
								 | 
							
								   #define HX_VAR_NAME(type,name,dbgName) type name; HX_STACK_VAR(name, dbgName)
							 | 
						||
| 
								 | 
							
								   #define HX_VARI_NAME(type,name,dbgName) type name; HX_STACK_VAR(name, dbgName) name
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else // Non-debugger versions.  Just stub-out.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_THIS(ptr)
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_ARG(cpp_var, haxe_name)
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_VAR(cpp_var, haxe_name)
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_CATCHABLE(T, n)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #define HX_VAR(type,name) type name
							 | 
						||
| 
								 | 
							
								   #define HX_VARI(type,name) type name
							 | 
						||
| 
								 | 
							
								   #define HX_VAR_NAME(type,name,dbgName) type name
							 | 
						||
| 
								 | 
							
								   #define HX_VARI_NAME(type,name,dbgName) type name
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // Just throw - move to hx::Throw function?
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_DO_THROW(e) ::hx::Throw(e)
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_DO_RETHROW(e) ::hx::Rethrow(e)
							 | 
						||
| 
								 | 
							
								#endif // HXCPP_STACK_VARS
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Emitted after every Haxe line.  number is the original Haxe line number.
							 | 
						||
| 
								 | 
							
								// Only if stack lines are to be tracked
							 | 
						||
| 
								 | 
							
								#ifdef HXCPP_STACK_LINE
							 | 
						||
| 
								 | 
							
								   // If the debugger is enabled, must check for a breakpoint at every line.
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								      #define HX_STACK_LINE(number)                                           \
							 | 
						||
| 
								 | 
							
								          _hx_stackframe.lineNumber = number;                                   \
							 | 
						||
| 
								 | 
							
								          /* This is incorrect - a read memory barrier is needed here. */     \
							 | 
						||
| 
								 | 
							
								          /* For now, just live with the exceedingly rare cases where */      \
							 | 
						||
| 
								 | 
							
								          /* breakpoints are missed */                                        \
							 | 
						||
| 
								 | 
							
								          if (::hx::gShouldCallHandleBreakpoints) {                             \
							 | 
						||
| 
								 | 
							
								              __hxcpp_on_line_changed(_hx_stackframe.ctx);                    \
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								      #define HX_STACK_LINE_QUICK(number) _hx_stackframe.lineNumber = number;
							 | 
						||
| 
								 | 
							
								   #else
							 | 
						||
| 
								 | 
							
								      // Just set it
							 | 
						||
| 
								 | 
							
								      #define HX_STACK_LINE(number) _hx_stackframe.lineNumber = number;
							 | 
						||
| 
								 | 
							
								      #define HX_STACK_LINE_QUICK(number) _hx_stackframe.lineNumber = number;
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_LINE(number)
							 | 
						||
| 
								 | 
							
								   #define HX_STACK_LINE_QUICK(number)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// For tidier generated code
							 | 
						||
| 
								 | 
							
								#define HXLINE(number) HX_STACK_LINE(number)
							 | 
						||
| 
								 | 
							
								#define HXDLIN(number)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// To support older versions of the haxe compiler that emit HX_STACK_PUSH
							 | 
						||
| 
								 | 
							
								// instead of HX_STACK_FRAME.  If the old haxe compiler is used with this
							 | 
						||
| 
								 | 
							
								// new debugger implementation, className.functionName breakpoints will
							 | 
						||
| 
								 | 
							
								// not work, and stack reporting will be a little weird.  If you want to
							 | 
						||
| 
								 | 
							
								// use debugging, you really should upgrade to a newer haxe compiler.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#undef HX_STACK_PUSH
							 | 
						||
| 
								 | 
							
								#define HX_STACK_PUSH(fullName, fileName, lineNumber)                  \
							 | 
						||
| 
								 | 
							
								    HX_STACK_FRAME("", fullName, 0, fullName, fileName, lineNumber, 0)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(HXCPP_STACK_TRACE) || defined(HXCPP_TELEMETRY)
							 | 
						||
| 
								 | 
							
								   #define HXCPP_STACK_IDS
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace hx
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class StackFrame;
							 | 
						||
| 
								 | 
							
								struct StackContext;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Profiler;
							 | 
						||
| 
								 | 
							
								void profDestroy(Profiler *);
							 | 
						||
| 
								 | 
							
								void profAttach(Profiler *, StackContext *);
							 | 
						||
| 
								 | 
							
								void profDetach(Profiler *, StackContext *);
							 | 
						||
| 
								 | 
							
								void profSample(Profiler *, StackContext *inContext);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Telemetry;
							 | 
						||
| 
								 | 
							
								Telemetry *tlmCreate(StackContext *);
							 | 
						||
| 
								 | 
							
								void tlmDestroy(Telemetry *);
							 | 
						||
| 
								 | 
							
								void tlmAttach(Telemetry *, StackContext *);
							 | 
						||
| 
								 | 
							
								void tlmDetach(Telemetry *);
							 | 
						||
| 
								 | 
							
								void tlmSampleEnter(Telemetry *, StackFrame *inFrame);
							 | 
						||
| 
								 | 
							
								void tlmSampleExit(Telemetry *);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class DebuggerContext;
							 | 
						||
| 
								 | 
							
								DebuggerContext *dbgCtxCreate(StackContext *);
							 | 
						||
| 
								 | 
							
								void dbgCtxDestroy(DebuggerContext *);
							 | 
						||
| 
								 | 
							
								void dbgCtxAttach(DebuggerContext *, StackContext *);
							 | 
						||
| 
								 | 
							
								void dbgCtxDetach(DebuggerContext *);
							 | 
						||
| 
								 | 
							
								void dbgCtxEnable(DebuggerContext *, bool inEnable);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct scriptCallable;
							 | 
						||
| 
								 | 
							
								class StackVariable;
							 | 
						||
| 
								 | 
							
								class StackCatchable;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename T> struct Hash;
							 | 
						||
| 
								 | 
							
								struct TWeakStringSet;
							 | 
						||
| 
								 | 
							
								typedef Hash<TWeakStringSet> WeakStringSet;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								extern const char* EXTERN_CLASS_NAME;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								extern volatile bool gShouldCallHandleBreakpoints;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// These must match the values present in cpp.vm.Debugger
							 | 
						||
| 
								 | 
							
								enum DebugStatus
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DBG_STATUS_INVALID = 0, // Not present or needed in cpp.vm.Debugger
							 | 
						||
| 
								 | 
							
								    DBG_STATUS_RUNNING = 1,
							 | 
						||
| 
								 | 
							
								    DBG_STATUS_STOPPED_BREAK_IMMEDIATE = 2,
							 | 
						||
| 
								 | 
							
								    DBG_STATUS_STOPPED_BREAKPOINT = 3,
							 | 
						||
| 
								 | 
							
								    DBG_STATUS_STOPPED_UNCAUGHT_EXCEPTION = 4,
							 | 
						||
| 
								 | 
							
								    DBG_STATUS_STOPPED_CRITICAL_ERROR = 5
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								enum ExecutionTrace
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   exeTraceOff = 0,
							 | 
						||
| 
								 | 
							
								   exeTraceFuncs = 1,
							 | 
						||
| 
								 | 
							
								   exeTraceLines = 2,
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								extern ExecutionTrace sExecutionTrace;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class StackPosition
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    // These are constant during the lifetime of the stack frame
							 | 
						||
| 
								 | 
							
								    const char *className;
							 | 
						||
| 
								 | 
							
								    const char *functionName;
							 | 
						||
| 
								 | 
							
								    const char *fullName; // this is className.functionName - used for profiler
							 | 
						||
| 
								 | 
							
								    const char *fileName;
							 | 
						||
| 
								 | 
							
								    int firstLineNumber;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    #if defined(HXCPP_STACK_SCRIPTABLE)
							 | 
						||
| 
								 | 
							
								    // Information about the current cppia function
							 | 
						||
| 
								 | 
							
								    struct ScriptCallable *scriptCallable;
							 | 
						||
| 
								 | 
							
								    #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // These are only used if HXCPP_DEBUGGER is defined
							 | 
						||
| 
								 | 
							
								    #ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								    int fileHash;
							 | 
						||
| 
								 | 
							
								    int classFuncHash;
							 | 
						||
| 
								 | 
							
								    #else
							 | 
						||
| 
								 | 
							
								    enum { fileHash = 0, classFuncHash=0 };
							 | 
						||
| 
								 | 
							
								    #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    inline StackPosition() { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // The constructor automatically adds the StackFrame to the list of
							 | 
						||
| 
								 | 
							
								    // stack frames for the current thread
							 | 
						||
| 
								 | 
							
								    inline StackPosition(const char *inClassName, const char *inFunctionName,
							 | 
						||
| 
								 | 
							
								                         const char *inFullName, const char *inFileName
							 | 
						||
| 
								 | 
							
								                         #ifdef HXCPP_STACK_LINE
							 | 
						||
| 
								 | 
							
								                         , int inLineNumber
							 | 
						||
| 
								 | 
							
								                         #endif
							 | 
						||
| 
								 | 
							
								                         #ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								                         ,int inClassFunctionHash, int inFileHash
							 | 
						||
| 
								 | 
							
								                         #endif
							 | 
						||
| 
								 | 
							
								                  )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								       : className(inClassName), functionName(inFunctionName)
							 | 
						||
| 
								 | 
							
								         ,fullName(inFullName), fileName(inFileName)
							 | 
						||
| 
								 | 
							
								         #ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								         ,classFuncHash(inClassFunctionHash)
							 | 
						||
| 
								 | 
							
								         ,fileHash(inFileHash)
							 | 
						||
| 
								 | 
							
								         #endif
							 | 
						||
| 
								 | 
							
								         #ifdef HXCPP_STACK_LINE
							 | 
						||
| 
								 | 
							
								         ,firstLineNumber(inLineNumber)
							 | 
						||
| 
								 | 
							
								         #endif
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								       #if defined(HXCPP_STACK_SCRIPTABLE)
							 | 
						||
| 
								 | 
							
								       // Information about the current cppia function
							 | 
						||
| 
								 | 
							
								       scriptCallable = 0;
							 | 
						||
| 
								 | 
							
								       #endif
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef HXCPP_STACK_TRACE
							 | 
						||
| 
								 | 
							
								struct ExceptionStackFrame
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_STACK_LINE
							 | 
						||
| 
								 | 
							
								   int line;
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #if HXCPP_API_LEVEL > 330
							 | 
						||
| 
								 | 
							
								   const hx::StackPosition *position;
							 | 
						||
| 
								 | 
							
								   #else
							 | 
						||
| 
								 | 
							
								   const char *className;
							 | 
						||
| 
								 | 
							
								   const char *functionName;
							 | 
						||
| 
								 | 
							
								   const char *fileName;
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   ExceptionStackFrame(const StackFrame &inFrame);
							 | 
						||
| 
								 | 
							
								   ::String format(bool inForDisplay);
							 | 
						||
| 
								 | 
							
								   ::String toDisplay();
							 | 
						||
| 
								 | 
							
								   ::String toString();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef HXCPP_SCRIPTABLE
							 | 
						||
| 
								 | 
							
								enum
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   bcrBreak    = 0x01,
							 | 
						||
| 
								 | 
							
								   bcrContinue = 0x02,
							 | 
						||
| 
								 | 
							
								   bcrReturn   = 0x04,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   bcrLoop     = (bcrBreak | bcrContinue),
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct MarkChunk
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   enum { SIZE = 62 };
							 | 
						||
| 
								 | 
							
								   enum { OBJ_ARRAY_JOB = -1 };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   inline MarkChunk() : count(0), next(0) { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   int        count;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   union
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      hx::Object *stack[SIZE];
							 | 
						||
| 
								 | 
							
								      struct
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         hx::Object **arrayBase;
							 | 
						||
| 
								 | 
							
								         int        arrayElements;
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								   };
							 | 
						||
| 
								 | 
							
								   MarkChunk  *next;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   inline void push(Object *inObj)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      stack[count++] = inObj;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   inline hx::Object *pop()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      if (count)
							 | 
						||
| 
								 | 
							
								         return stack[--count];
							 | 
						||
| 
								 | 
							
								      return 0;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   MarkChunk *swapForNew();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct StackContext : public hx::ImmixAllocator
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_STACK_IDS
							 | 
						||
| 
								 | 
							
								      int  mThreadId;
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_STACK_TRACE
							 | 
						||
| 
								 | 
							
								      hx::QuickVec<StackFrame *> mStackFrames;
							 | 
						||
| 
								 | 
							
								      hx::QuickVec<hx::ExceptionStackFrame> mExceptionStack;
							 | 
						||
| 
								 | 
							
								      // Updated only when a thrown exception unwinds the stack
							 | 
						||
| 
								 | 
							
								      bool mIsUnwindingException;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      #ifdef HXCPP_STACK_SCRIPTABLE
							 | 
						||
| 
								 | 
							
								         // TODO - combine CppaCtx and StackContext
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      #ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								         DebuggerContext  *mDebugger;
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      #ifdef HXCPP_PROFILER
							 | 
						||
| 
								 | 
							
								         // Profiling support
							 | 
						||
| 
								 | 
							
								         Profiler *mProfiler;
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_TELEMETRY
							 | 
						||
| 
								 | 
							
								      // Telemetry support
							 | 
						||
| 
								 | 
							
								      Telemetry *mTelemetry;
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_COMBINE_STRINGS
							 | 
						||
| 
								 | 
							
								   WeakStringSet *stringSet;
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_GC_GENERATIONAL
							 | 
						||
| 
								 | 
							
								   MarkChunk *mOldReferrers;
							 | 
						||
| 
								 | 
							
								   inline void pushReferrer(hx::Object *inObj)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      // If collector is running on non-generational mode, mOldReferrers will be null
							 | 
						||
| 
								 | 
							
								      if (mOldReferrers)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         mOldReferrers->push(inObj);
							 | 
						||
| 
								 | 
							
								         if (mOldReferrers->count==MarkChunk::SIZE)
							 | 
						||
| 
								 | 
							
								            mOldReferrers = mOldReferrers->swapForNew();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_CATCH_SEGV
							 | 
						||
| 
								 | 
							
								      #ifdef _MSC_VER
							 | 
						||
| 
								 | 
							
								      _se_translator_function mOldSignalFunc;
							 | 
						||
| 
								 | 
							
								      #else
							 | 
						||
| 
								 | 
							
								      void (*mOldSignalFunc)(int);
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   StackContext();
							 | 
						||
| 
								 | 
							
								   ~StackContext();
							 | 
						||
| 
								 | 
							
								   void onThreadAttach();
							 | 
						||
| 
								 | 
							
								   void onThreadDetach();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_STACK_TRACE // {
							 | 
						||
| 
								 | 
							
								   void tracePosition();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // Note that the stack frames are manipulated without holding any locks.
							 | 
						||
| 
								 | 
							
								   // This is because the manipulation of stack frames can only be done by
							 | 
						||
| 
								 | 
							
								   // the thread that "owns" that stack frame.  The only other contention on
							 | 
						||
| 
								 | 
							
								   // the call stack is from calls to GetThreadInfo() and GetThreadInfos(),
							 | 
						||
| 
								 | 
							
								   // and these should only be called when the thread for which the call
							 | 
						||
| 
								 | 
							
								   // stack is being acquired is stopped in a breakpoint anyway, thus there
							 | 
						||
| 
								 | 
							
								   // can be no contention on the contents of the CallStack in that case
							 | 
						||
| 
								 | 
							
								   // either.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   inline void pushFrame(StackFrame *inFrame)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      #ifdef HXCPP_PROFILER
							 | 
						||
| 
								 | 
							
								      if (mProfiler)
							 | 
						||
| 
								 | 
							
								         profSample(mProfiler,this);
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      #ifdef HXCPP_TELEMETRY
							 | 
						||
| 
								 | 
							
								      if (mTelemetry)
							 | 
						||
| 
								 | 
							
								         tlmSampleEnter(mTelemetry,inFrame);
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      mIsUnwindingException = false;
							 | 
						||
| 
								 | 
							
								      mStackFrames.push(inFrame);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      #ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								      if (sExecutionTrace!=exeTraceOff)
							 | 
						||
| 
								 | 
							
								         tracePosition();
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   inline void popFrame(StackFrame *inFrame)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      #ifdef HXCPP_TELEMETRY
							 | 
						||
| 
								 | 
							
								      if (mTelemetry)
							 | 
						||
| 
								 | 
							
								         tlmSampleExit(mTelemetry);
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (mIsUnwindingException)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         // Use default operator=
							 | 
						||
| 
								 | 
							
								         mExceptionStack.push( *inFrame );
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      mStackFrames.pop_back();
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   void getCurrentCallStackAsStrings(Array<String> result, bool skipLast);
							 | 
						||
| 
								 | 
							
								   void getCurrentExceptionStackAsStrings(Array<String> result);
							 | 
						||
| 
								 | 
							
								   StackFrame *getCurrentStackFrame() { return mStackFrames.back(); }
							 | 
						||
| 
								 | 
							
								   StackFrame *getStackFrame(int inIndex) { return mStackFrames[inIndex]; }
							 | 
						||
| 
								 | 
							
								   int getDepth() const { return mStackFrames.size(); }
							 | 
						||
| 
								 | 
							
								   inline const char *getFullNameAtDepth(int depth) const;
							 | 
						||
| 
								 | 
							
								   void  dumpExceptionStack();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // Called when a throw occurs
							 | 
						||
| 
								 | 
							
								   void setLastException();
							 | 
						||
| 
								 | 
							
								   void pushLastException();
							 | 
						||
| 
								 | 
							
								    // Called when a catch block begins to be executed.  hxcpp wants to track
							 | 
						||
| 
								 | 
							
								    // the stack back through the catches so that it can be dumped if
							 | 
						||
| 
								 | 
							
								    // uncaught.  If inAll is true, the entire stack is captured immediately.
							 | 
						||
| 
								 | 
							
								    // If inAll is false, only the last stack frame is captured.
							 | 
						||
| 
								 | 
							
								    void beginCatch(bool inAll);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #endif // } HXCPP_STACK_TRACE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								   void enableCurrentThreadDebugging(bool inEnable)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      dbgCtxEnable(mDebugger,inEnable);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   static inline StackContext *getCurrent()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      return HX_CTX_GET;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_STACK_IDS
							 | 
						||
| 
								 | 
							
								   static void getAllStackIds( QuickVec<int> &outIds );
							 | 
						||
| 
								 | 
							
								   static StackContext *getStackForId(int id);
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_SCRIPTABLE
							 | 
						||
| 
								 | 
							
								   unsigned char *stack;
							 | 
						||
| 
								 | 
							
								   unsigned char *pointer;
							 | 
						||
| 
								 | 
							
								   unsigned char *frame;
							 | 
						||
| 
								 | 
							
								   class Object  *exception;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   unsigned int breakContReturn;
							 | 
						||
| 
								 | 
							
								   int  byteMarkId;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template<typename T>
							 | 
						||
| 
								 | 
							
								   void push(T inValue)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      *(T *)pointer = inValue;
							 | 
						||
| 
								 | 
							
								      pointer += sizeof(T);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   unsigned char *stackAlloc(int inSize)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      unsigned char *p = pointer;
							 | 
						||
| 
								 | 
							
								      pointer += inSize;
							 | 
						||
| 
								 | 
							
								      return p;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   void stackFree(int inSize)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      pointer -= inSize;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   int getFrameSize() const { return pointer-frame; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   int runInt(void *vtable);
							 | 
						||
| 
								 | 
							
								   Float runFloat(void *vtable);
							 | 
						||
| 
								 | 
							
								   String runString(void *vtable);
							 | 
						||
| 
								 | 
							
								   void runVoid(void *vtable);
							 | 
						||
| 
								 | 
							
								   Dynamic runObject(void *vtable);
							 | 
						||
| 
								 | 
							
								   hx::Object *runObjectPtr(void *vtable);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   void push(bool &inValue) { *(int *)pointer = inValue; pointer += sizeof(int); }
							 | 
						||
| 
								 | 
							
								   inline void pushBool(bool b) { *(int *)pointer = b; pointer += sizeof(int); }
							 | 
						||
| 
								 | 
							
								   inline void pushInt(int i) { *(int *)pointer = i; pointer += sizeof(int); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   inline void pushFloat(Float f);
							 | 
						||
| 
								 | 
							
								   inline void pushString(const String &s);
							 | 
						||
| 
								 | 
							
								   inline void pushObject(Dynamic d);
							 | 
						||
| 
								 | 
							
								   inline void returnFloat(Float f);
							 | 
						||
| 
								 | 
							
								   inline void returnString(const String &s);
							 | 
						||
| 
								 | 
							
								   inline void returnObject(Dynamic d);
							 | 
						||
| 
								 | 
							
								   inline hx::Object *getThis(bool inCheckPtr=true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   inline void returnBool(bool b) { *(int *)frame = b; }
							 | 
						||
| 
								 | 
							
								   inline void returnInt(int i) { *(int *)frame = i; }
							 | 
						||
| 
								 | 
							
								   inline bool getBool(int inPos=0) { return *(bool *)(frame+inPos); }
							 | 
						||
| 
								 | 
							
								   inline int getInt(int inPos=0) { return *(int *)(frame+inPos); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   inline Float getFloat(int inPos=0);
							 | 
						||
| 
								 | 
							
								   inline String getString(int inPos=0);
							 | 
						||
| 
								 | 
							
								   inline Dynamic getObject(int inPos=0);
							 | 
						||
| 
								 | 
							
								   inline hx::Object *getObjectPtr(int inPos=0) { return *(hx::Object **)(frame+inPos); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   void breakFlag() { breakContReturn |= bcrBreak; }
							 | 
						||
| 
								 | 
							
								   void continueFlag() { breakContReturn |= bcrContinue; }
							 | 
						||
| 
								 | 
							
								   void returnFlag() { breakContReturn |= bcrReturn; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef StackContext CppiaCtx;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class StackFrame
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								   StackContext        *ctx;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #ifdef HXCPP_STACK_TRACE // {
							 | 
						||
| 
								 | 
							
								   const StackPosition *position;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      #ifdef HXCPP_STACK_LINE
							 | 
						||
| 
								 | 
							
								         // Current line number, changes during the lifetime of the stack frame.
							 | 
						||
| 
								 | 
							
								         // Only updated if HXCPP_STACK_LINE is defined.
							 | 
						||
| 
								 | 
							
								         int lineNumber;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         #ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								         // Function arguments and local variables in reverse order of their
							 | 
						||
| 
								 | 
							
								         // declaration.  If a variable name is in here twice, the first version is
							 | 
						||
| 
								 | 
							
								         // the most recently scoped one and should be used.  Only updated if
							 | 
						||
| 
								 | 
							
								         // HXCPP_DEBUGGER is defined.
							 | 
						||
| 
								 | 
							
								         StackVariable *variables;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         // The list of types that can be currently caught in the stack frame.
							 | 
						||
| 
								 | 
							
								         StackCatchable *catchables;
							 | 
						||
| 
								 | 
							
								         #endif
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								       // The constructor automatically adds the StackFrame to the list of
							 | 
						||
| 
								 | 
							
								       // stack frames for the current thread
							 | 
						||
| 
								 | 
							
								       inline StackFrame(const StackPosition *inPosition
							 | 
						||
| 
								 | 
							
								              ) : position(inPosition)
							 | 
						||
| 
								 | 
							
								       {
							 | 
						||
| 
								 | 
							
								          #ifdef HXCPP_STACK_LINE
							 | 
						||
| 
								 | 
							
								             lineNumber = inPosition->firstLineNumber;
							 | 
						||
| 
								 | 
							
								             #ifdef HXCPP_DEBUGGER
							 | 
						||
| 
								 | 
							
								             variables = 0;
							 | 
						||
| 
								 | 
							
								             catchables = 0;
							 | 
						||
| 
								 | 
							
								             #endif
							 | 
						||
| 
								 | 
							
								          #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          ctx =  HX_CTX_GET;
							 | 
						||
| 
								 | 
							
								          ctx->pushFrame(this);
							 | 
						||
| 
								 | 
							
								       }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								       // The destructor automatically removes the StackFrame from the list of
							 | 
						||
| 
								 | 
							
								       // stack frames for the current thread
							 | 
						||
| 
								 | 
							
								       ~StackFrame()
							 | 
						||
| 
								 | 
							
								       {
							 | 
						||
| 
								 | 
							
								          ctx->popFrame(this);
							 | 
						||
| 
								 | 
							
								       }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								       ::String toString();
							 | 
						||
| 
								 | 
							
								       ::String toDisplay();
							 | 
						||
| 
								 | 
							
								   #else // }  !HXCPP_STACK_TRACE {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								       // Release version only has ctx
							 | 
						||
| 
								 | 
							
								       inline StackFrame()
							 | 
						||
| 
								 | 
							
								       {
							 | 
						||
| 
								 | 
							
								          ctx =  HX_CTX_GET;
							 | 
						||
| 
								 | 
							
								       }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #endif // }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef HXCPP_STACK_TRACE
							 | 
						||
| 
								 | 
							
								const char *StackContext::getFullNameAtDepth(int depth) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   return mStackFrames[depth]->position->fullName;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class JustGcStackFrame
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								   StackContext        *ctx;
							 | 
						||
| 
								 | 
							
								   inline JustGcStackFrame() : ctx(HX_CTX_GET) { }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // end namespace hx
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Some functions used by AdvancedDebug.cpp
							 | 
						||
| 
								 | 
							
								// Returns the thread number of the calling thread
							 | 
						||
| 
								 | 
							
								HXCPP_EXTERN_CLASS_ATTRIBUTES
							 | 
						||
| 
								 | 
							
								int __hxcpp_GetCurrentThreadNumber();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Called by the main function when an uncaught exception occurs to dump
							 | 
						||
| 
								 | 
							
								// the stack leading to the exception
							 | 
						||
| 
								 | 
							
								HXCPP_EXTERN_CLASS_ATTRIBUTES
							 | 
						||
| 
								 | 
							
								void __hx_dump_stack();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// The macro HX_STACK_BEGIN_CATCH, which is emitted at the beginning of every
							 | 
						||
| 
								 | 
							
								// catch block, calls this in debug mode to let the debugging system know that
							 | 
						||
| 
								 | 
							
								// a catch block has been entered
							 | 
						||
| 
								 | 
							
								HXCPP_EXTERN_CLASS_ATTRIBUTES
							 | 
						||
| 
								 | 
							
								void __hxcpp_stack_begin_catch();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Last chance to throw an exception for null-pointer access
							 | 
						||
| 
								 | 
							
								HXCPP_EXTERN_CLASS_ATTRIBUTES
							 | 
						||
| 
								 | 
							
								void __hxcpp_set_critical_error_handler(Dynamic inHandler);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HXCPP_EXTERN_CLASS_ATTRIBUTES
							 | 
						||
| 
								 | 
							
								void __hxcpp_execution_trace(int inLevel);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Used by debug breakpoints and execution trace
							 | 
						||
| 
								 | 
							
								HXCPP_EXTERN_CLASS_ATTRIBUTES
							 | 
						||
| 
								 | 
							
								void __hxcpp_set_stack_frame_line(int);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HXCPP_EXTERN_CLASS_ATTRIBUTES
							 | 
						||
| 
								 | 
							
								void __hxcpp_on_line_changed(hx::StackContext *);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HXCPP_EXTERN_CLASS_ATTRIBUTES
							 | 
						||
| 
								 | 
							
								void __hxcpp_set_debugger_info(const char **inAllClasses, const char **inFullPaths);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void __hxcpp_dbg_getScriptableVariables(hx::StackFrame *stackFrame, ::Array< ::Dynamic> outNames);
							 | 
						||
| 
								 | 
							
								bool __hxcpp_dbg_getScriptableValue(hx::StackFrame *stackFrame, String inName, ::Dynamic &outValue);
							 | 
						||
| 
								 | 
							
								bool __hxcpp_dbg_setScriptableValue(hx::StackFrame *StackFrame, String inName, ::Dynamic inValue);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // HX_STACK_CTX_H
							 |