Docs GODI Archive
Projects Blog Link DB

Search GODI:


More options
File include/flx_rtl.hpp GODI Package apps-felix
 
   flx_rtl.hpp  
#line 184 "lpsrc/flx_rtl.ipk"
#ifndef FLX_RTL
#define FLX_RTL
#include "flx_rtl_config.hpp"
#include "flx_meta.hpp"
#ifndef FLX_GC
#include "flx_gc.hpp"
#endif
#include <string>

#if defined(FLX_PTF_STATIC_STRUCT)
#define PTF ptf.
#elif defined(FLX_PTF_STATIC_POINTER)
#define PTF ptf->
#else
#define PTF ptf->
#endif

// for declarations in header file
#if defined(FLX_PTF_STATIC_STRUCT)
#define FLX_FMEM_DECL
#define FLX_FPAR_DECL_ONLY
#define FLX_FPAR_DECL
#define FLX_APAR_DECL_ONLY
#define FLX_APAR_DECL
#define FLX_DCL_THREAD_FRAME extern thread_frame_t ptf;
#elif defined(FLX_PTF_STATIC_POINTER)
#define FLX_FMEM_DECL
#define FLX_FPAR_DECL_ONLY
#define FLX_FPAR_DECL
#define FLX_APAR_DECL_ONLY
#define FLX_APAR_DECL
#define FLX_DCL_THREAD_FRAME extern thread_frame_t *ptf;
#else
#define FLX_FMEM_DECL thread_frame_t *ptf;
#define FLX_FPAR_DECL_ONLY thread_frame_t *_ptf
#define FLX_FPAR_DECL thread_frame_t *_ptf,
#define FLX_APAR_DECL_ONLY thread_frame_t *ptf
#define FLX_APAR_DECL thread_frame_t *ptf,
#define FLX_DCL_THREAD_FRAME
#endif

namespace flx { namespace rtl {

// ********************************************************
// Felix system classes
// ********************************************************

struct FLX_RTL_EXTERN con_t;     // continuation
struct FLX_RTL_EXTERN fthread_t; // f-thread
struct FLX_RTL_EXTERN _ref_;     // pointer/reference
struct FLX_RTL_EXTERN _uctor_;   // union constructor
struct FLX_RTL_EXTERN unit {};   // unit
  // INLINE DEFINITION, PROBLEMATIC!!

// ********************************************************
// Shape (RTTI) objects for system classes
// con_t is only an abstract base, so has no fixed shape
// shapes for instance types generated by Felix compiler
// we provide a shape for C 'int' type as well
// ********************************************************

extern FLX_RTL_EXTERN flx::gc::generic::gc_shape_t _fthread_ptr_map;
extern FLX_RTL_EXTERN flx::gc::generic::gc_shape_t _ref_ptr_map;
extern FLX_RTL_EXTERN flx::gc::generic::gc_shape_t _uctor_ptr_map;
extern FLX_RTL_EXTERN flx::gc::generic::gc_shape_t _int_ptr_map;
extern FLX_RTL_EXTERN flx::gc::generic::gc_shape_t unit_ptr_map;

// ********************************************************
// Standard C++ Exceptions
// ********************************************************

struct FLX_RTL_EXTERN flx_exec_failure_t;
struct FLX_RTL_EXTERN flx_range_srcref_t;
struct FLX_RTL_EXTERN flx_match_failure_t;
struct FLX_RTL_EXTERN flx_assert_failure_t;
struct FLX_RTL_EXTERN flx_switch_failure_t;

// ********************************************************
// SERVICE REQUEST CODE
// THESE VALUES MUST SYNCH WITH THE STANDARD LIBRARY
// ********************************************************

enum svc_t               // what the dispatch should do
{                        // when the resume callback returns
  svc_yield = 0,
  svc_get_fthread=1,
  svc_read=2,
  svc_general=3,         // temporary hack by RF
  svc_end
};

// ********************************************************
// CONTINUATION
// ********************************************************

struct FLX_RTL_EXTERN con_t // abstract base for mutable continuations
{
#ifdef FLX_CGOTO
  void *pc;                 // interior program counter
#else
   int pc;
#endif

  _uctor_ *p_svc;           // pointer to service request

  con_t();
  virtual con_t *resume()=0;
  virtual ~con_t();
  con_t * _caller;          // callers continuation
};

// ********************************************************
// FTHREAD -- Felix threads
// ********************************************************

struct FLX_RTL_EXTERN fthread_t // fthread abstraction
{
  fthread_t();                  // dead thread, suitable for assignment
  fthread_t(con_t*);            // make thread from a continuation
  con_t *cc;                    // current continuation
  virtual _uctor_ *run();       // run until dead or driver service request
  _uctor_ *get_svc()const;      // get current service request of waiting thread
  virtual ~fthread_t();         // kill the thread -- continuation cc unaffected
};

// ********************************************************
// REFERENCE -- Felix pointer type
// note: non-polymorphic, so ctor can be inline
// ********************************************************

struct FLX_RTL_EXTERN _ref_
{
  void *frame;
  void *data;

  _ref_(){}
  _ref_(void *f, void *d): frame(f), data(d) {}
  ~_ref_()
  {
    frame=0;
  }

  _ref_(_ref_ const& r) : frame(r.frame), data(r.data)
  {
  }
  void operator = (_ref_ const& r);
};


// ********************************************************
// VARIANTS -- Felix union type
// note: non-polymorphic, so ctor can be inline
// ********************************************************

struct FLX_RTL_EXTERN _uctor_
{
  int variant;
  void *data;
  _uctor_() : variant(-1), data(0) {}
  _uctor_(int i, void *d) : variant(i), data(d) {}
};


// ********************************************************
// EXCEPTION: EXEC protocol failure
// Thrown when trying to run a dead procedure
// ********************************************************

struct FLX_RTL_EXTERN flx_exec_failure_t {
  std::string filename;
  std::string operation;
  std::string what;
  flx_exec_failure_t(std::string f, std::string o, std::string w);
  virtual ~flx_exec_failure_t();
};

// ********************************************************
// SOURCE REFERENCE: to track places in user source code
// ********************************************************

struct FLX_RTL_EXTERN flx_range_srcref_t {
  char *filename;
  int startline;
  int startcol;
  int endline;
  int endcol;
  flx_range_srcref_t(char *f,int sl, int sc, int el, int ec);
};

// ********************************************************
// EXCEPTION: MATCH failure
// Thrown when no match cases match the argument of a match,
// regmatch, or reglex
// ********************************************************

struct FLX_RTL_EXTERN flx_match_failure_t {
  flx_range_srcref_t flx_loc;
  char *cxx_srcfile;    // in C++ file
  int cxx_srcline;      // __LINE__ macro
  flx_match_failure_t(flx_range_srcref_t ff, char *cf, int cl);
  virtual ~flx_match_failure_t();
};

// ********************************************************
// EXCEPTION: ASSERT failure
// Thrown when user assertion fails
// ********************************************************

struct FLX_RTL_EXTERN flx_assert_failure_t {
  flx_range_srcref_t flx_loc;
  char *cxx_srcfile;    // in C++ file
  int cxx_srcline;      // __LINE__ macro
  flx_assert_failure_t(flx_range_srcref_t ff, char *cf, int cl);
  virtual ~flx_assert_failure_t();
};

// ********************************************************
// EXCEPTION: SWITCH failure -- this is a system failure!
// ********************************************************

struct FLX_RTL_EXTERN flx_switch_failure_t {
  virtual ~flx_switch_failure_t();
};


}} // namespaces

#define FLX_MATCH_FAILURE(f,sl,sc,el,ec) \
  throw flx::rtl::flx_match_failure_t (flx_range_srcref_t(f,sl,sc,el,ec),__FILE__,__LINE__)

#define FLX_ASSERT_FAILURE(f,sl,sc,el,ec) \
  throw flx::rtl::flx_assert_failure_t (flx_range_srcref_t(f,sl,sc,el,ec),__FILE__,__LINE__)

// for generated code in body file
#define INIT_PC pc=0;

#ifdef FLX_CGOTO
  #define FLX_START_SWITCH if(pc)goto *pc;
  #define FLX_SET_PC(x) pc=&&case_##x;
  #define FLX_CASE_LABEL(x) case_##x:;
  #define FLX_DECLARE_LABEL(n,i,x) \
    extern void f##i##_##n##_##x(void) __asm__("l"#i"_"#n"_"#x);
  #define FLX_LABEL(n,i,x) x:\
    __asm__(".global l"#i"_"#n"_"#x);\
    __asm__("l"#i"_"#n"_"#x":");\
    __asm__(""::"g"(&&x));
  #define FLX_FARTARGET(n,i,x) (void*)&f##i##_##n##_##x
  #define FLX_END_SWITCH
#else
  #define FLX_START_SWITCH switch(pc){case 0:;
  #define FLX_SET_PC(x) pc=x;
  #define FLX_CASE_LABEL(x) case x:;
  #define FLX_DECLARE_LABEL(n,i,x)
  #define FLX_LABEL(n,i,x) case n: x:;
  #define FLX_FARTARGET(n,i,x) n
  #define FLX_END_SWITCH default: throw flx_switch_failure_t(); }
#endif

#define FLX_RETURN \
{ \
  con_t *tmp = _caller; \
  _caller = 0; \
  return tmp; \
}

#define FLX_NEWP(x) new(*PTF gc,x##_ptr_map)x

#define FLX_FINALISER(x) \
static void x##_finaliser(collector_t *, void *p){\
  ((x*)p)->~x();\
}

#if defined(FLX_USE_REGPARM3) && defined(HAVE_GXX_X86)
#define FLX_REGPARM __attribute__((regparm(3)))
#else
#define FLX_REGPARM
#endif

#if defined(FLX_PTF_STATIC_STRUCT)
#define FLX_FMEM_INIT_ONLY
#define FLX_FMEM_INIT :
#define FLX_FPAR_PASS_ONLY
#define FLX_FPAR_PASS
#define _PTF _ptf.
#define _PTFV
#define FLX_PASS_PTF 0
#define FLX_EAT_PTF(x)
#define FLX_DEF_THREAD_FRAME thread_frame_t ptf;
#elif defined(FLX_PTF_STATIC_POINTER)
#define FLX_FMEM_INIT_ONLY
#define FLX_FMEM_INIT :
#define FLX_FPAR_PASS_ONLY
#define FLX_FPAR_PASS
#define _PTF _ptf->
#define _PTFV
#define FLX_PASS_PTF 0
#define FLX_EAT_PTF(x)
#define FLX_DEF_THREAD_FRAME thread_frame_t *ptf=0;
#else
#define FLX_FMEM_INIT_ONLY : ptf(_ptf)
#define FLX_FMEM_INIT : ptf(_ptf),
#define FLX_FPAR_PASS_ONLY ptf
#define FLX_FPAR_PASS ptf,
#define _PTF _ptf->
#define _PTFV _ptf
#define FLX_PASS_PTF 1
#define FLX_EAT_PTF(x) x
#define FLX_DEF_THREAD_FRAME
#endif

#if defined(FLX_PTF_STATIC_STRUCT)
#define FLX_FRAME_WRAPPERS \
extern "C" thread_frame_t *create_thread_frame(\
  collector_t *gc\
) {\
  ptf.gc = gc;\
  return &ptf;\
}
#elif defined(FLX_PTF_STATIC_POINTER)
#define FLX_FRAME_WRAPPERS \
extern "C" thread_frame_t *create_thread_frame(\
  collector_t *gc\
) {\
  thread_frame_t *p = new(*gc,thread_frame_t_ptr_map) thread_frame_t(gc);\
  ptf = p;\
  return p;\
}
#else
#define FLX_FRAME_WRAPPERS \
extern "C" FLX_EXPORT thread_frame_t *create_thread_frame(\
  collector_t *gc\
) {\
  thread_frame_t *p = new(*gc,thread_frame_t_ptr_map) thread_frame_t(gc);\
  return p;\
}
#endif

#if defined(FLX_PTF_STATIC_STRUCT)
#define FLX_START_WRAPPER(x)\
extern "C" con_t *flx_start(\
  thread_frame_t *ptf,\
  int argc,\
  char **argv,\
  FILE *stdin_,\
  FILE *stdout_,\
  FILE *stderr_\
) {\
  ptf->argc = argc;\
  ptf->argv = argv;\
  ptf->flx_stdin = stdin_;\
  ptf->flx_stdout = stdout_;\
  ptf->flx_stderr = stderr_;\
  return (new(*ptf->gc,x##_ptr_map) \
    x()) ->call(0);\
}
#elif defined(FLX_PTF_STATIC_POINTER)
#define FLX_START_WRAPPER(x)\
extern "C" con_t *flx_start(\
  thread_frame_t *ptf,\
  int argc,\
  char **argv,\
  FILE *stdin_,\
  FILE *stdout_,\
  FILE *stderr_\
) {\
  ptf->argc = argc;\
  ptf->argv = argv;\
  ptf->flx_stdin = stdin_;\
  ptf->flx_stdout = stdout_;\
  ptf->flx_stderr = stderr_;\
  return (new(*ptf->gc,x##_ptr_map) \
    x()) ->call(0);\
}
#else
#define FLX_START_WRAPPER(x)\
extern "C" FLX_EXPORT con_t *flx_start(\
  thread_frame_t *ptf,\
  int argc,\
  char **argv,\
  FILE *stdin_,\
  FILE *stdout_,\
  FILE *stderr_\
) {\
  ptf->argc = argc;\
  ptf->argv = argv;\
  ptf->flx_stdin = stdin_;\
  ptf->flx_stdout = stdout_;\
  ptf->flx_stderr = stderr_;\
  return (new(*ptf->gc,x##_ptr_map) \
    x(ptf)) ->call(0);\
}
#endif

#endif


This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml