text: #ifndef USER_MODE_MULTI_THREAD_SUPPORT_H
  #define USER_MODE_MULTI_THREAD_SUPPORT_H
  
  #include <vector>
  #include <map>
  
  #include "dobby_internal.h"
  
  #include "UserMode/Thread/PlatformThread.h"
  
  // StackFrame base in CallStack
  typedef struct _StackFrame {
      // context between `pre_call` and `post_call`
      std::map<char *, void *> kv_context;
      // origin function ret address
      void *orig_ret;
  } StackFrame;
  
  // (thead) CallStack base in thread
  typedef struct _CallStack {
      std::vector<StackFrame *> stackframes;
  } CallStack;
  
  // ThreadSupport base on vm_core, support mutipl platforms.
  class ThreadSupport {
  public:
      // Push stack frame
      static void PushStackFrame(StackFrame *stackframe) {
          CallStack *callstack = ThreadSupport::CurrentThreadCallStack();
          callstack->stackframes.push_back(stackframe);
      }
  
      // Pop stack frame
      static StackFrame *PopStackFrame() {
          CallStack *callstack = ThreadSupport::CurrentThreadCallStack();
          StackFrame *stackframe = callstack->stackframes.back();
          callstack->stackframes.pop_back();
          return stackframe;
      }
  
      // =====
      static void SetStackFrameContextValue(StackFrame *stackframe, char *key, void *value) {
          std::map<char *, void *> *kv_context = &stackframe->kv_context;
          kv_context->insert(std::pair<char *, void *>(key, value));
      };
  
      static void *GetStackFrameContextValue(StackFrame *stackframe, char *key) {
          std::map<char *, void *> kv_context = stackframe->kv_context;
          std::map<char *, void *>::iterator it;
          it = kv_context.find(key);
          if (it != kv_context.end()) {
              return (void *) it->second;
          }
          return NULL;
      };
  
      static CallStack *CurrentThreadCallStack();
  
  private:
      static zz::OSThread::LocalStorageKey thread_callstack_key_;
  };
  
  #endif
  