00001 #line 475 "./lpsrc/flx_rtl.pak"
00002 #ifndef __FLX_RTL_H__
00003 #define __FLX_RTL_H__
00004 #include "flx_rtl_config.hpp"
00005 #include "flx_meta.hpp"
00006 #include "flx_gc.hpp"
00007 #include <string>
00008 #include <functional>
00009
00010 #if FLX_PTF_STATIC_STRUCT
00011 #define PTF ptf.
00012 #elif FLX_PTF_STATIC_POINTER
00013 #define PTF ptf->
00014 #else
00015 #define PTF ptf->
00016 #endif
00017
00018
00019 #if FLX_PTF_STATIC_STRUCT
00020 #define FLX_FMEM_DECL
00021 #define FLX_FPAR_DECL_ONLY
00022 #define FLX_FPAR_DECL
00023 #define FLX_APAR_DECL_ONLY
00024 #define FLX_APAR_DECL
00025 #define FLX_DCL_THREAD_FRAME extern thread_frame_t ptf;
00026 #elif FLX_PTF_STATIC_POINTER
00027 #define FLX_FMEM_DECL
00028 #define FLX_FPAR_DECL_ONLY
00029 #define FLX_FPAR_DECL
00030 #define FLX_APAR_DECL_ONLY
00031 #define FLX_APAR_DECL
00032 #define FLX_DCL_THREAD_FRAME extern thread_frame_t *ptf;
00033 #else
00034 #define FLX_FMEM_DECL thread_frame_t *ptf;
00035 #define FLX_FPAR_DECL_ONLY thread_frame_t *_ptf
00036 #define FLX_FPAR_DECL thread_frame_t *_ptf,
00037 #define FLX_APAR_DECL_ONLY thread_frame_t *ptf
00038 #define FLX_APAR_DECL thread_frame_t *ptf,
00039 #define FLX_DCL_THREAD_FRAME
00040 #endif
00041
00042 #if FLX_CGOTO
00043 #define FLX_PC_DECL void *pc;
00044 #else
00045 #define FLX_PC_DECL int pc;
00046 #endif
00047
00048
00049 namespace flx { namespace rtl {
00050
00051
00052
00053
00054
00055 struct RTL_EXTERN con_t;
00056 struct RTL_EXTERN thread_t;
00057
00058 struct RTL_EXTERN _uctor_;
00059 struct RTL_EXTERN schannel_t;
00060 struct RTL_EXTERN slist_t;
00061 struct RTL_EXTERN _root_ptr_t;
00062
00063 struct RTL_EXTERN unit {};
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 RTL_EXTERN extern flx::gc::generic::gc_shape_t _fthread_ptr_map;
00074 RTL_EXTERN extern flx::gc::generic::gc_shape_t schannel_ptr_map;
00075 RTL_EXTERN extern flx::gc::generic::gc_shape_t _ref_ptr_map;
00076 RTL_EXTERN extern flx::gc::generic::gc_shape_t _uctor_ptr_map;
00077 RTL_EXTERN extern flx::gc::generic::gc_shape_t _int_ptr_map;
00078 RTL_EXTERN extern flx::gc::generic::gc_shape_t unit_ptr_map;
00079 RTL_EXTERN extern flx::gc::generic::gc_shape_t slist_ptr_map;
00080 RTL_EXTERN extern flx::gc::generic::gc_shape_t _root_ptr_ptr_map;
00081
00082
00083
00084
00085
00086 struct RTL_EXTERN flx_exception_t;
00087 struct RTL_EXTERN flx_exec_failure_t;
00088 struct RTL_EXTERN flx_range_srcref_t;
00089 struct RTL_EXTERN flx_match_failure_t;
00090 struct RTL_EXTERN flx_assert_failure_t;
00091 struct RTL_EXTERN flx_assert2_failure_t;
00092 struct RTL_EXTERN flx_switch_failure_t;
00093
00094
00095
00096
00097 struct RTL_EXTERN con_t
00098 {
00099 FLX_PC_DECL
00100 _uctor_ *p_svc;
00101
00102 con_t();
00103 virtual con_t *resume()=0;
00104 virtual ~con_t();
00105 con_t * _caller;
00106 };
00107
00108
00109
00110
00111
00112
00113 struct RTL_EXTERN slist_t {
00114 gc::generic::collector_t *gc;
00115 struct slist_node_t *head;
00116
00117 slist_t (gc::generic::collector_t *);
00118 slist_t (slist_t const &);
00119
00120 void push(void *data);
00121 void *pop();
00122 bool isempty()const;
00123 };
00124
00125
00126
00127
00128
00129 struct RTL_EXTERN fthread_t
00130 {
00131 con_t *cc;
00132
00133 fthread_t();
00134 fthread_t(con_t*);
00135 _uctor_ *run();
00136 void kill();
00137 _uctor_ *get_svc()const;
00138 private:
00139 fthread_t(fthread_t const&);
00140 void operator=(fthread_t const&);
00141 };
00142
00143
00144
00145
00146
00147 struct RTL_EXTERN schannel_t
00148 {
00149 slist_t *waiting_to_read;
00150 slist_t *waiting_to_write;
00151 schannel_t(gc::generic::collector_t*);
00152 void push_reader(fthread_t *);
00153 fthread_t *pop_reader();
00154 void push_writer(fthread_t *);
00155 fthread_t *pop_writer();
00156 private:
00157 schannel_t(schannel_t const&);
00158 void operator= (schannel_t const&);
00159 };
00160
00161
00162
00163
00164
00165
00166 struct RTL_EXTERN _uctor_
00167 {
00168 int variant;
00169 void *data;
00170 _uctor_() : variant(-1), data(0) {}
00171 _uctor_(int i, void *d) : variant(i), data(d) {}
00172 _uctor_(int *a, _uctor_ x) : variant(a[x.variant]), data(x.data) {}
00173 };
00174
00175
00176
00177
00178
00179
00180
00181 struct RTL_EXTERN _root_ptr_t
00182 {
00183 _root_ptr_t();
00184 _root_ptr_t(void *x);
00185 _root_ptr_t(_root_ptr_t const&);
00186 void operator=(_root_ptr_t const&);
00187 ~_root_ptr_t();
00188
00189 _root_ptr_t *next;
00190 _root_ptr_t *prev;
00191 void *data;
00192
00193 private:
00194 void insert_after (_root_ptr_t*);
00195 void erase();
00196 };
00197
00198
00199 template<class T>
00200 struct root_ptr_t : _root_ptr_t {
00201 root_ptr_t(){}
00202 root_ptr_t(root_ptr_t<T> const&){}
00203 root_ptr_t<T>& operator=(root_ptr_t<T> const &a){
00204 return reinterpret_cast<root_ptr_t<T>&>(_root_ptr_t::operator=(a));
00205 }
00206 ~root_ptr_t(){}
00207
00208 root_ptr_t(T const *a) : _root_ptr_t (const_cast<T*>(a)) {}
00209
00210 T *operator->() { return (T*)data; }
00211 T const *operator->() const { return (T const*)data; }
00212 T &operator*() { return *(T*)data; }
00213 T const &operator*() const { return *(T const*)data; }
00214 };
00215
00216 template<class T>
00217 bool operator == (root_ptr_t<T> a, root_ptr_t<T> b)
00218 {
00219 return a-> data == b->data;
00220 }
00221
00222 template<class T>
00223 bool operator != (root_ptr_t<T> a, root_ptr_t<T> b)
00224 {
00225 return a-> data != b->data;
00226 }
00227
00228 template<class T>
00229 bool operator < (root_ptr_t<T> const &a, root_ptr_t<T> const &b)
00230 {
00231
00232 return std::less<void const*>()(a-> data, b->data);
00233 }
00234
00235 template<class T>
00236 bool operator <= (root_ptr_t<T> const &a, root_ptr_t<T> const &b)
00237 {
00238
00239 return std::less_equal<void const*>()(a-> data, b->data);
00240 }
00241
00242 template<class T>
00243 bool operator > (root_ptr_t<T> const &a, root_ptr_t<T> const &b)
00244 {
00245
00246 return std::greater<void const*>()(a-> data, b->data);
00247 }
00248
00249 template<class T>
00250 bool operator >= (root_ptr_t<T> const &a, root_ptr_t<T> const &b)
00251 {
00252
00253 return std::greater_equal<void const*>()(a-> data, b->data);
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263 struct RTL_EXTERN flx_exception_t {
00264 virtual ~flx_exception_t()=0;
00265 };
00266
00267
00268
00269
00270
00271
00272 struct RTL_EXTERN flx_exec_failure_t : flx_exception_t {
00273 std::string filename;
00274 std::string operation;
00275 std::string what;
00276 flx_exec_failure_t(std::string f, std::string o, std::string w);
00277 virtual ~flx_exec_failure_t();
00278 };
00279
00280
00281
00282
00283
00284 struct RTL_EXTERN flx_range_srcref_t {
00285 char *filename;
00286 int startline;
00287 int startcol;
00288 int endline;
00289 int endcol;
00290 flx_range_srcref_t(char *f,int sl, int sc, int el, int ec);
00291 flx_range_srcref_t();
00292 };
00293
00294
00295
00296
00297
00298
00299 struct RTL_EXTERN flx_halt_t : flx_exception_t {
00300 std::string reason;
00301 flx_range_srcref_t flx_loc;
00302 char *cxx_srcfile;
00303 int cxx_srcline;
00304 flx_halt_t(flx_range_srcref_t ff, char *cf, int cl, std::string reason);
00305 virtual ~flx_halt_t();
00306 };
00307
00308
00309
00310
00311
00312
00313
00314 struct RTL_EXTERN flx_match_failure_t : flx_exception_t {
00315 flx_range_srcref_t flx_loc;
00316 char *cxx_srcfile;
00317 int cxx_srcline;
00318 flx_match_failure_t(flx_range_srcref_t ff, char *cf, int cl);
00319 virtual ~flx_match_failure_t();
00320 };
00321
00322
00323
00324
00325
00326
00327 struct RTL_EXTERN flx_assert_failure_t : flx_exception_t {
00328 flx_range_srcref_t flx_loc;
00329 char *cxx_srcfile;
00330 int cxx_srcline;
00331 flx_assert_failure_t(flx_range_srcref_t ff, char *cf, int cl);
00332 virtual ~flx_assert_failure_t();
00333 };
00334
00335 struct RTL_EXTERN flx_assert2_failure_t : flx_exception_t {
00336 flx_range_srcref_t flx_loc;
00337 flx_range_srcref_t flx_loc2;
00338 char *cxx_srcfile;
00339 int cxx_srcline;
00340 flx_assert2_failure_t(flx_range_srcref_t ff, flx_range_srcref_t ff2, char *cf, int cl);
00341 virtual ~flx_assert2_failure_t();
00342 };
00343
00344
00345
00346
00347
00348
00349 struct RTL_EXTERN flx_range_failure_t : flx_exception_t {
00350 flx_range_srcref_t flx_loc;
00351 char *cxx_srcfile;
00352 int cxx_srcline;
00353 flx_range_failure_t(flx_range_srcref_t ff, char *cf, int cl);
00354 virtual ~flx_range_failure_t();
00355 };
00356
00357 RTL_EXTERN long range_check (long l, long x, long h, flx_range_srcref_t sref, char *cf, int cl);
00358
00359
00360
00361
00362
00363
00364 struct RTL_EXTERN flx_switch_failure_t : flx_exception_t {
00365 virtual ~flx_switch_failure_t();
00366 };
00367
00368
00369
00370
00371
00372
00373
00374 enum svc_t
00375 {
00376 svc_yield = 0,
00377 svc_get_fthread=1,
00378 svc_read=2,
00379 svc_general=3,
00380 svc_reserved=4,
00381 svc_spawn_pthread=5,
00382 svc_spawn_detached=6,
00383 svc_sread=7,
00384 svc_swrite=8,
00385 svc_kill=9,
00386 svc_collect=10,
00387 svc_end
00388 };
00389
00390 struct readreq_t {
00391 schannel_t *chan;
00392 void *variable;
00393 };
00394
00395 }}
00396
00397 #define FLX_EXEC_FAILURE(f,op,what) \
00398 throw flx::rtl::flx_exec_failure_t (f,op,what)
00399
00400 #define FLX_HALT(f,sl,sc,el,ec,s) \
00401 throw flx::rtl::flx_halt_t (flx_range_srcref_t(f,sl,sc,el,ec),__FILE__,__LINE__,s)
00402
00403 #define FLX_MATCH_FAILURE(f,sl,sc,el,ec) \
00404 throw flx::rtl::flx_match_failure_t (flx_range_srcref_t(f,sl,sc,el,ec),__FILE__,__LINE__)
00405
00406 #define FLX_ASSERT_FAILURE(f,sl,sc,el,ec) \
00407 throw flx::rtl::flx_assert_failure_t (flx_range_srcref_t(f,sl,sc,el,ec),__FILE__,__LINE__)
00408
00409 #define FLX_ASSERT2_FAILURE(f,sl,sc,el,ec,f2,sl2,sc2,el2,ec2) \
00410 throw flx::rtl::flx_assert2_failure_t (\
00411 flx_range_srcref_t(f,sl,sc,el,ec),\
00412 flx_range_srcref_t(f2,sl2,sc2,el2,sc2),\
00413 __FILE__,__LINE__)
00414
00415 #define FLX_RANGE_FAILURE(f,sl,sc,el,ec) \
00416 throw flx::rtl::flx_range_failure_t (flx_range_srcref_t(f,sl,sc,el,ec),__FILE__,__LINE__)
00417
00418
00419 #define INIT_PC pc=0;
00420
00421
00422 #if FLX_CGOTO
00423 #define FLX_START_SWITCH if(pc)goto *pc;
00424 #define FLX_SET_PC(x) pc=&&case_##x;
00425 #define FLX_CASE_LABEL(x) case_##x:;
00426 #define FLX_DECLARE_LABEL(n,i,x) \
00427 extern void f##i##_##n##_##x(void) __asm__("l"#i"_"#n"_"#x);
00428 #define FLX_LABEL(n,i,x) x:\
00429 __asm__(".global l"#i"_"#n"_"#x);\
00430 __asm__("l"#i"_"#n"_"#x":");\
00431 __asm__(""::"g"(&&x));
00432 #define FLX_FARTARGET(n,i,x) (void*)&f##i##_##n##_##x
00433 #define FLX_END_SWITCH
00434 #else
00435 #define FLX_START_SWITCH switch(pc){case 0:;
00436 #define FLX_SET_PC(x) pc=x;
00437 #define FLX_CASE_LABEL(x) case x:;
00438 #define FLX_DECLARE_LABEL(n,i,x)
00439 #define FLX_LABEL(n,i,x) case n: x:;
00440 #define FLX_FARTARGET(n,i,x) n
00441 #define FLX_END_SWITCH default: throw flx_switch_failure_t(); }
00442 #endif
00443
00444 #define FLX_RETURN \
00445 { \
00446 con_t *tmp = _caller; \
00447 _caller = 0; \
00448 return tmp; \
00449 }
00450
00451 #define FLX_NEWP(x) new(*PTF gc,x##_ptr_map)x
00452
00453 #define FLX_FINALISER(x) \
00454 static void x##_finaliser(collector_t *, void *p){\
00455 ((x*)p)->~x();\
00456 }
00457
00458 #if FLX_USE_REGPARM3 && FLX_HAVE_GNU_X86
00459 #define FLX_REGPARM __attribute__((regparm(3)))
00460 #else
00461 #define FLX_REGPARM
00462 #endif
00463
00464 #if FLX_PTF_STATIC_STRUCT
00465 #define FLX_FMEM_INIT_ONLY
00466 #define FLX_FMEM_INIT :
00467 #define FLX_FPAR_PASS_ONLY
00468 #define FLX_FPAR_PASS
00469 #define FLX_APAR_PASS_ONLY
00470 #define FLX_APAR_PASS
00471 #define _PTF _ptf.
00472 #define _PTFV
00473 #define FLX_PASS_PTF 0
00474 #define FLX_EAT_PTF(x)
00475 #define FLX_DEF_THREAD_FRAME thread_frame_t ptf;
00476 #elif FLX_PTF_STATIC_POINTER
00477 #define FLX_FMEM_INIT_ONLY
00478 #define FLX_FMEM_INIT :
00479 #define FLX_FPAR_PASS_ONLY
00480 #define FLX_FPAR_PASS
00481 #define FLX_APAR_PASS_ONLY
00482 #define FLX_APAR_PASS
00483 #define _PTF _ptf->
00484 #define _PTFV
00485 #define FLX_PASS_PTF 0
00486 #define FLX_EAT
00487 #define FLX_DEF_THREAD_FRAME thread_frame_t *ptf=0;
00488 #else
00489 #define FLX_FMEM_INIT_ONLY : ptf(_ptf)
00490 #define FLX_FMEM_INIT : ptf(_ptf),
00491 #define FLX_FPAR_PASS_ONLY ptf
00492 #define FLX_FPAR_PASS ptf,
00493 #define FLX_APAR_PASS_ONLY _ptf
00494 #define FLX_APAR_PASS _ptf,
00495 #define _PTF _ptf->
00496 #define _PTFV _ptf
00497 #define FLX_PASS_PTF 1
00498 #define FLX_EAT_PTF(x) x
00499 #define FLX_DEF_THREAD_FRAME
00500 #endif
00501
00502 #if FLX_PTF_STATIC_STRUCT
00503 #define FLX_FRAME_WRAPPERS(mname) \
00504 extern "C" thread_frame_t *create_thread_frame(\
00505 collector_t *gc\
00506 ) {\
00507 ptf.gc = gc;\
00508 return &ptf;\
00509 }
00510 #elif FLX_PTF_STATIC_POINTER
00511 #define FLX_FRAME_WRAPPERS(mname) \
00512 extern "C" thread_frame_t *create_thread_frame(\
00513 collector_t *gc\
00514 ) {\
00515 mname::thread_frame_t *p = new(*gc,mname::thread_frame_t_ptr_map) mname::thread_frame_t(gc);\
00516 ptf = p;\
00517 return p;\
00518 }
00519 #else
00520 #define FLX_FRAME_WRAPPERS(mname) \
00521 extern "C" FLX_EXPORT mname::thread_frame_t *create_thread_frame(\
00522 collector_t *gc\
00523 ) {\
00524 mname::thread_frame_t *p = new(*gc,mname::thread_frame_t_ptr_map) mname::thread_frame_t(gc);\
00525 return p;\
00526 }
00527 #endif
00528
00529 #if FLX_PTF_STATIC_STRUCT
00530 #define FLX_START_WRAPPER(mname,x)\
00531 extern "C" con_t *flx_start(\
00532 mname::thread_frame_t *ptf,\
00533 int argc,\
00534 char **argv,\
00535 FILE *stdin_,\
00536 FILE *stdout_,\
00537 FILE *stderr_\
00538 ) {\
00539 ptf->argc = argc;\
00540 ptf->argv = argv;\
00541 ptf->flx_stdin = stdin_;\
00542 ptf->flx_stdout = stdout_;\
00543 ptf->flx_stderr = stderr_;\
00544 return (new(*ptf->gc,mname::x##_ptr_map) \
00545 mname::x()) ->call(0);\
00546 }
00547 #elif FLX_PTF_STATIC_POINTER
00548 #define FLX_START_WRAPPER(mname,x)\
00549 extern "C" con_t *flx_start(\
00550 mname::thread_frame_t *ptf,\
00551 int argc,\
00552 char **argv,\
00553 FILE *stdin_,\
00554 FILE *stdout_,\
00555 FILE *stderr_\
00556 ) {\
00557 ptf->argc = argc;\
00558 ptf->argv = argv;\
00559 ptf->flx_stdin = stdin_;\
00560 ptf->flx_stdout = stdout_;\
00561 ptf->flx_stderr = stderr_;\
00562 return (new(*ptf->gc,mname::x##_ptr_map) \
00563 mname::x()) ->call(0);\
00564 }
00565 #else
00566 #define FLX_START_WRAPPER(mname,x)\
00567 extern "C" FLX_EXPORT con_t *flx_start(\
00568 mname::thread_frame_t *ptf,\
00569 int argc,\
00570 char **argv,\
00571 FILE *stdin_,\
00572 FILE *stdout_,\
00573 FILE *stderr_\
00574 ) {\
00575 ptf->argc = argc;\
00576 ptf->argv = argv;\
00577 ptf->flx_stdin = stdin_;\
00578 ptf->flx_stdout = stdout_;\
00579 ptf->flx_stderr = stderr_;\
00580 return (new(*ptf->gc,mname::x##_ptr_map) \
00581 mname::x(ptf)) ->call(0);\
00582 }
00583 #endif
00584
00585 #if FLX_PTF_STATIC_STRUCT
00586 #define FLX_STACK_START_WRAPPER(mname,x)\
00587 extern "C" con_t *flx_start(\
00588 mname::thread_frame_t *ptf,\
00589 int argc,\
00590 char **argv,\
00591 FILE *stdin_,\
00592 FILE *stdout_,\
00593 FILE *stderr_\
00594 ) {\
00595 ptf->argc = argc;\
00596 ptf->argv = argv;\
00597 ptf->flx_stdin = stdin_;\
00598 ptf->flx_stdout = stdout_;\
00599 ptf->flx_stderr = stderr_;\
00600 mname::x().stack_call();\
00601 return 0;\
00602 }
00603 #elif FLX_PTF_STATIC_POINTER
00604 #define FLX_STACK_START_WRAPPER(mname,x)\
00605 extern "C" con_t *flx_start(\
00606 mname::thread_frame_t *ptf,\
00607 int argc,\
00608 char **argv,\
00609 FILE *stdin_,\
00610 FILE *stdout_,\
00611 FILE *stderr_\
00612 ) {\
00613 ptf->argc = argc;\
00614 ptf->argv = argv;\
00615 ptf->flx_stdin = stdin_;\
00616 ptf->flx_stdout = stdout_;\
00617 ptf->flx_stderr = stderr_;\
00618 mname::x().stack_call();\
00619 return 0;\
00620 }
00621 #else
00622 #define FLX_STACK_START_WRAPPER(mname,x)\
00623 extern "C" FLX_EXPORT con_t *flx_start(\
00624 mname::thread_frame_t *ptf,\
00625 int argc,\
00626 char **argv,\
00627 FILE *stdin_,\
00628 FILE *stdout_,\
00629 FILE *stderr_\
00630 ) {\
00631 ptf->argc = argc;\
00632 ptf->argv = argv;\
00633 ptf->flx_stdin = stdin_;\
00634 ptf->flx_stdout = stdout_;\
00635 ptf->flx_stderr = stderr_;\
00636 mname::x(ptf).stack_call();\
00637 return 0;\
00638 }
00639 #endif
00640
00641 #if FLX_PTF_STATIC_STRUCT
00642 #define FLX_C_START_WRAPPER(mname,x)\
00643 extern "C" con_t *flx_start(\
00644 mname::thread_frame_t *ptf,\
00645 int argc,\
00646 char **argv,\
00647 FILE *stdin_,\
00648 FILE *stdout_,\
00649 FILE *stderr_\
00650 ) {\
00651 ptf->argc = argc;\
00652 ptf->argv = argv;\
00653 ptf->flx_stdin = stdin_;\
00654 ptf->flx_stdout = stdout_;\
00655 ptf->flx_stderr = stderr_;\
00656 mname::x();\
00657 return 0;\
00658 }
00659 #elif FLX_PTF_STATIC_POINTER
00660 #define FLX_C_START_WRAPPER(mname,x)\
00661 extern "C" con_t *flx_start(\
00662 mname::thread_frame_t *ptf,\
00663 int argc,\
00664 char **argv,\
00665 FILE *stdin_,\
00666 FILE *stdout_,\
00667 FILE *stderr_\
00668 ) {\
00669 ptf->argc = argc;\
00670 ptf->argv = argv;\
00671 ptf->flx_stdin = stdin_;\
00672 ptf->flx_stdout = stdout_;\
00673 ptf->flx_stderr = stderr_;\
00674 mname::x();\
00675 return 0;\
00676 }
00677 #else
00678 #define FLX_C_START_WRAPPER(mname,x)\
00679 extern "C" FLX_EXPORT con_t *flx_start(\
00680 mname::thread_frame_t *ptf,\
00681 int argc,\
00682 char **argv,\
00683 FILE *stdin_,\
00684 FILE *stdout_,\
00685 FILE *stderr_\
00686 ) {\
00687 ptf->argc = argc;\
00688 ptf->argv = argv;\
00689 ptf->flx_stdin = stdin_;\
00690 ptf->flx_stdout = stdout_;\
00691 ptf->flx_stderr = stderr_;\
00692 mname::x(ptf);\
00693 return 0;\
00694 }
00695 #endif
00696
00697 #endif