#ifndef AEE_STATIC_H
#define AEE_STATIC_H /* #ifndef AEE_STATIC_H */

/*======================================================
FILE:  AEE_static.h

SERVICES:  BREW helper functions for static
           applications and modules.

GENERAL DESCRIPTION:
   Static linkage variant of AEE.h.

        Copyright © 2003 QUALCOMM Incorporated.
               All Rights Reserved.
            QUALCOMM Proprietary/GTDR
=====================================================*/

#if !defined(AEE_STATIC)
#error AEE_static.h is for inclusion by static apps and modules: those compiled with the BREW library directly, or as part of an OEM build.  If you are statically linking with BREW, please define AEE_STATIC in your Makefile.
#endif 

#if !defined(AEE_STATIC_H__INC__BY__AEE_H)
#error AEE_static.h is not for intended for direct inclusion.  Please remove any include directives that reference AEE_static.h directly and change them to include AEE.h.
#endif

#include "AEEBridle.h"

/* ==========================================================================
  ||
  || Static linkers get these
  ||
  ========================================================================== */

//
// Prevent supervisor mode from calling through a user mode vtable.
//
// There is a performance and size penalty for this (since the vtable
// determination is run-time instead of compile-time), so only do this
// during development.
//

#if defined(AEE_SIMULATOR) || defined(FEATURE_BREW_DEV)

// Allow access if vtable address is safe; else cause an abort
#define BRIDLE_PVTBL(p,iname,pvt) (!BRIDLE_UNSAFE_PFN(pvt) ? \
                                   (pvt) : \
                                   (iname##Vtbl*)BRIDLE_CHECK_WRITEACCESS(BRIDLE_FROM_UNPRIV, 0, 4))

// SET is safe, so redefine these to not use GET, which will shortly become r-value only
#undef  INIT_VTBL
#define INIT_VTBL(p,iname,vt)    (((iname*)p)->pvt = (VTBL(iname)*)&vt)
#undef  AEEINITVTBL
#define AEEINITVTBL(p,iname,vt)  (*((AEEVTBL(iname) **)p) = (AEEVTBL(iname)*)&vt)

// GET is unsafe, so do some bridle runtime checks
#undef  GET_PVTBL
#define GET_PVTBL(p,iname)    BRIDLE_PVTBL(p,iname,((iname*)p)->pvt)
#undef  AEEGETPVTBL
#define AEEGETPVTBL(p,iname)  BRIDLE_PVTBL(p,iname,*((AEEVTBL(iname)**)p))

#endif // defined(AEE_SIMULATOR) || defined(FEATURE_BREW_DEV)

//
// Switch to user before supervisor mode calls a user mode cancel function.
//
#undef  CALLBACK_Cancel

static __inline void CALLBACK_Cancel(AEECallback *pcb)
{
   //We need this stack variable so we operate on the copy of the
   //cancel function in the off chance that 2 or more tasks
   //are cancelling at the same time.
   
   PFNCBCANCEL pfnCancel = (pcb)->pfnCancel;
   
   if (0 != pfnCancel) 
   { 
      if (BRIDLE_UNSAFE_PFN(pfnCancel)) 
      {
         BRIDLE_USER_VOID_1(pfnCancel, pcb);
      }
      else 
      {
         pfnCancel(pcb);
      }
   }
}

/* ==========================================================================
  ||
  || end Static
  ||
  ========================================================================== */


#endif /* #ifndef AEE_STATIC_H */
