#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