blitz_ex.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "blitz.h"
  2. #define EX_GROW 10
  3. typedef struct BBExEnv{
  4. char _cpu_state[256]; //worse case - bit ugly, but better than an #ifdef
  5. }BBExEnv;
  6. typedef struct BBExStack{
  7. BBExEnv *ex_base,*ex_sp,*ex_end;
  8. }BBExStack;
  9. #ifdef _WIN32
  10. #include <windows.h>
  11. static DWORD exKey(){
  12. static int done;
  13. static DWORD key;
  14. if( !done ){
  15. key=TlsAlloc();
  16. done=1;
  17. }
  18. return key;
  19. }
  20. BBExStack *getExStack(){
  21. return (BBExStack*)TlsGetValue( exKey() );
  22. }
  23. void setExStack( BBExStack *st ){
  24. TlsSetValue( exKey(),st );
  25. }
  26. #else
  27. #include <pthread.h>
  28. static pthread_key_t exKey(){
  29. static int done;
  30. static pthread_key_t key;
  31. if( !done ){
  32. pthread_key_create( &key,0 );
  33. done=1;
  34. }
  35. return key;
  36. }
  37. BBExStack *getExStack(){
  38. return (BBExStack*)pthread_getspecific( exKey() );
  39. }
  40. void setExStack( BBExStack *st ){
  41. pthread_setspecific( exKey(),st );
  42. }
  43. #endif
  44. static BBExStack *exStack(){
  45. BBExStack *st=getExStack();
  46. if( !st ){
  47. st=(BBExStack*)bbMemAlloc( sizeof( BBExStack ) );
  48. memset( st,0,sizeof( BBExStack ) );
  49. setExStack( st );
  50. }
  51. return st;
  52. }
  53. static void freeExStack( BBExStack *st ){
  54. bbMemFree( st->ex_base );
  55. bbMemFree( st );
  56. setExStack( 0 );
  57. }
  58. void *bbExEnter(){
  59. BBExStack *st=exStack();
  60. if( st->ex_sp==st->ex_end ){
  61. int len=st->ex_sp-st->ex_base,new_len=len+EX_GROW;
  62. st->ex_base=(BBExEnv*)bbMemExtend( st->ex_base,len*sizeof(BBExEnv),new_len*sizeof(BBExEnv) );
  63. st->ex_end=st->ex_base+new_len;
  64. st->ex_sp=st->ex_base+len;
  65. }
  66. return (st->ex_sp++)->_cpu_state;
  67. }
  68. void bbExThrow( BBObject *p ){
  69. BBExStack *st=getExStack();
  70. if( !st ) bbOnDebugUnhandledEx( p );
  71. if( --st->ex_sp==st->ex_base ){
  72. static char buf[256];
  73. memcpy( buf,st->ex_sp->_cpu_state,256 );
  74. freeExStack( st );
  75. _bbExThrow( buf,p );
  76. }else{
  77. _bbExThrow( st->ex_sp->_cpu_state,p );
  78. }
  79. }
  80. void bbExLeave(){
  81. BBExStack *st=getExStack();
  82. //invariant...leaving a Try!
  83. //assert( st && st->ex_sp!=st->ex_base );
  84. if( --st->ex_sp==st->ex_base ){
  85. freeExStack( st );
  86. }
  87. }
  88. void bbExThrowCString( const char *p ){
  89. bbExThrow( (BBObject*)bbStringFromCString( p ) );
  90. }