/*
 * Interface file for calling Cyclone code from C code in GeekOS.
 * Copyright (c) 2004, Michael Hicks <mwh@cs.umd.edu>
 * $Revision: 1.1.1.1 $
 * 
 * This is free software.  You are permitted to use,
 * redistribute, and modify it as specified in the file "COPYING".
 */

#ifndef __CYCLONE_H__
#define __CYCLONE_H__

#include "runtime_tls.h"
//#include <cyc_setjmp.h>

/*struct _RuntimeStack {
  int tag; 
  struct _RuntimeStack *next;
   void (*cleanup)(struct _RuntimeStack *frame);
};

/ Exceptions 
 struct _handler_cons {
  struct _RuntimeStack s;
  jmp_buf handler;
  };*/

extern char *_set_top_handler();
extern char *_set_catchall_handler(struct _handler_cons *h);

     
/* To call a Cyclone function.  This macro does two things: 

   1) Places a "top-level" exception handler around this call to catch
   any stray exceptions.  The result of the macro is NULL if no
   exception is thrown, or the exception name if it was.
   2) Places Cyc_ prefix around the call.

   For cyc_call, the result is stored in the provided variable res.
*/
#define cyc_call(res,e)				\
({ tls_record_t tlr;                            \
   tls_slot_t tls; tls.pid=0; tls.record=&tlr;  \
   register_thread_cyc_runtime(&tls);           \
   struct _handler_cons h;			\
   char *exn = _set_catchall_handler(&h);	\
   if (!exn) res = Cyc_ ## e;			\
   unregister_thread_cyc_runtime();             \
})

#define void_cyc_call(e)			\
({ tls_record_t tlr;                            \
   tls_slot_t tls; tls.pid=0; tls.record=&tlr;  \
   register_thread_cyc_runtime(&tls);           \
   struct _handler_cons h;			\
   char *exn = _set_catchall_handler(&h);	\
   if (!exn) Cyc_ ## e;				\
   unregister_thread_cyc_runtime();             \
})

#endif
