00001
00002
00003 #include "cppscript"
00004 #include "dynamic/extensions.hpp"
00005 #include "tls.hpp"
00006 #include "thread.hpp"
00007
00008 #include <cstdlib>
00009 #include <memory>
00010
00011
00012 namespace
00013 {
00015
00019 class ref_counted : cg::not_copyable, cg::not_assignable
00020 {
00021 public:
00023 virtual ~ref_counted() { }
00024
00026 void add_ref()
00027 {
00028 ++m_count;
00029 }
00030
00032 void release()
00033 {
00034 if( -- m_count == 0 ) delete this;
00035 }
00036
00037 private:
00038 api::atomic_counter m_count;
00039 };
00040
00041
00043
00047 template<typename Ref>
00048 class ref_counted_impl
00049 {
00050 public:
00051 ref_counted_impl(Ref * r) : m_ref(r)
00052 {
00053 r->add_ref();
00054 }
00055
00056 ~ref_counted_impl()
00057 {
00058 m_ref->release();
00059 }
00060
00061 ref_counted_impl(const ref_counted_impl & r) : m_ref(r.m_ref)
00062 {
00063 m_ref->add_ref();
00064 }
00065
00066 ref_counted_impl & operator=(const ref_counted_impl & r)
00067 {
00068 r.m_ref->add_ref();
00069 m_ref->release();
00070 m_ref = r.m_ref();
00071 }
00072
00074 Ref * get() const { return m_ref; }
00075
00076 private:
00077 Ref * m_ref;
00078 };
00079 }
00080
00082
00104 class dynamic::apartment : public ref_counted
00105 {
00106
00107 kingsley_heap m_heap;
00108 std::auto_ptr<gc::garbage_collector> m_gc;
00109
00110 public:
00111 apartment() : m_gc(gc::create_gc())
00112 {
00113 }
00114
00116 void * malloc(std::size_t bytes)
00117 {
00118 return m_heap.malloc(bytes);
00119 }
00120
00122 void free( void * p )
00123 {
00124 m_heap.free(p);
00125 }
00126
00128 void defrag()
00129 {
00130 m_heap.defrag();
00131 }
00132
00134 gc::garbage_collector & gc() const
00135 {
00136 return *m_gc;
00137 }
00138
00140
00141 static apartment * current()
00142 {
00143 apartment * a = cg::tls<apartment*>::get();
00144 if(!cg::tls<apartment*>::get())
00145 {
00146 static internal::use_new_apartment static_apartment;
00147 a = cg::tls<apartment*>::get();
00148
00149
00150
00151
00152 }
00153
00154 return a;
00155 }
00156
00158
00159 void enter()
00160 {
00161 current()->unlock();
00162 lock();
00163 cg::tls<apartment*>::set(this);
00164 }
00165
00166 private:
00167 api::mutex m_mutex;
00168
00169 public:
00171
00172 void lock()
00173 {
00174 m_mutex.lock();
00175 }
00176
00178 void unlock()
00179 {
00180 m_mutex.unlock();
00181 }
00182 };
00183
00184
00185 namespace
00186 {
00188
00190 class proxy_stub_impl : public ref_counted
00191 {
00192 public:
00193 proxy_stub_impl(const var & v, apartment * from) : m_value(v), m_apartment(from)
00194 {
00195 }
00196
00198 apartment * apt() const
00199 {
00200 return m_apartment.get();
00201 }
00202
00204 var_impl & impl() const
00205 {
00206 return m_value.impl();
00207 }
00208
00209 private:
00210 var m_value;
00211 ref_counted_impl<apartment> m_apartment;
00212 };
00213 }
00214
00215 namespace dynamic
00216 {
00217 namespace types
00218 {
00220
00221 class proxy_impl : public var_impl
00222 {
00223 class enter_apartment
00224 {
00225 public:
00226 enter_apartment(apartment * new_apartment) : m_previous(apartment::current())
00227 {
00228 new_apartment->enter();
00229 }
00230
00231 ~enter_apartment()
00232 {
00233 m_previous->enter();
00234 }
00235
00236 apartment * from_apt()
00237 {
00238 return m_previous;
00239 }
00240
00241 private:
00242 apartment * m_previous;
00243 };
00244
00245 ref_counted_impl<proxy_stub_impl> m_stub;
00246
00247 public:
00248 proxy_impl(proxy_stub_impl * stub) : m_stub(stub)
00249 {
00250 }
00251
00252 var proxy()
00253 {
00254 return var(*this, var::assign_impl());
00255 }
00256
00257 void copy_to(void * p) const
00258 {
00259 new(p) proxy_impl(*this);
00260 }
00261
00262 apartment * to_apt()
00263 {
00264 return m_stub.get()->apt();
00265 }
00266
00267 var_impl & impl()
00268 {
00269 return m_stub.get()->impl();
00270 }
00271
00272 var_cmp_index comparison_index()
00273 {
00274 return cmp_proxy;
00275 }
00276
00277 var_cmp_result compare2(const var & v)
00278 {
00279 proxy_impl * other = dynamic_cast<proxy_impl*>(&v.impl());
00280
00281 if(other)
00282 {
00283 std::ptrdiff_t d = m_stub.get() - other->m_stub.get();
00284 return d<0 ? cmp_lt : d>0 ? cmp_gt: cmp_equal;
00285 }
00286
00287 return cmp_not_equal;
00288 }
00289
00290 var as_root()
00291 {
00292 return var(*this, var::assign_impl());
00293 }
00294
00295 var as_nonroot()
00296 {
00297 return var(*this, var::assign_impl());
00298 }
00299
00300 var clone()
00301 {
00302 enter_apartment a(to_apt());
00303
00304 try
00305 {
00306 return impl().clone().proxy();
00307 }
00308 catch(var & ex)
00309 {
00310 throw ex.proxy();
00311 }
00312 }
00313
00314 int as_int()
00315 {
00316 enter_apartment a(to_apt());
00317 try
00318 {
00319 return impl().as_int();
00320 }
00321 catch(var & ex)
00322 {
00323 throw ex.proxy();
00324 }
00325 }
00326
00327 bool as_bool()
00328 {
00329 enter_apartment a(to_apt());
00330 try
00331 {
00332 return impl().as_bool();
00333 }
00334 catch(var & ex)
00335 {
00336 throw ex.proxy();
00337 }
00338 }
00339
00340 double as_double()
00341 {
00342 enter_apartment a(to_apt());
00343 try
00344 {
00345 return impl().as_double();
00346 }
00347 catch(var & ex)
00348 {
00349 throw ex.proxy();
00350 }
00351 }
00352
00353 int max_args()
00354 {
00355 enter_apartment a(to_apt());
00356 try
00357 {
00358 return impl().max_args();
00359 }
00360 catch(var & ex)
00361 {
00362 throw ex.proxy();
00363 }
00364 }
00365
00366
00367 void output(ostream & os)
00368 {
00369 enter_apartment a(to_apt());
00370 try
00371 {
00372 return impl().output(os);
00373 }
00374 catch(var & ex)
00375 {
00376 throw ex.proxy();
00377 }
00378 }
00379
00380 void output(wostream & os)
00381 {
00382 enter_apartment a(to_apt());
00383 try
00384 {
00385 return impl().output(os);
00386 }
00387 catch(var & ex)
00388 {
00389 throw ex.proxy();
00390 }
00391 }
00392
00393
00394 std::string class_name()
00395 {
00396 enter_apartment a(to_apt());
00397 try
00398 {
00399 return impl().class_name();
00400 }
00401 catch(var & ex)
00402 {
00403 throw ex.proxy();
00404 }
00405 }
00406
00407 var call()
00408 {
00409 enter_apartment a(to_apt());
00410 try
00411 {
00412 return impl().call().proxy();
00413 }
00414 catch(var & ex)
00415 {
00416 throw ex.proxy();
00417 }
00418 }
00419
00420 var member_call(const char *m)
00421 {
00422 enter_apartment a(to_apt());
00423 try
00424 {
00425 return impl().member_call(m).proxy();
00426 }
00427 catch(var & ex)
00428 {
00429 throw ex.proxy();
00430 }
00431 }
00432
00433 var call(const var & a0)
00434 {
00435 var a0_proxy = a0.proxy();
00436 enter_apartment a(to_apt());
00437 try
00438 {
00439 return impl().call(a0_proxy).proxy();
00440 }
00441 catch(var & ex)
00442 {
00443 throw ex.proxy();
00444 }
00445 }
00446
00447 var member_call(const char *m, const var & a0)
00448 {
00449 var a0_proxy = a0.proxy();
00450 enter_apartment a(to_apt());
00451 try
00452 {
00453 return impl().member_call(m, a0_proxy).proxy();
00454 }
00455 catch(var & ex)
00456 {
00457 throw ex.proxy();
00458 }
00459 }
00460
00461 var call(const var & a0, const var & a1)
00462 {
00463 var a0_proxy = a0.proxy();
00464 var a1_proxy = a1.proxy();
00465 enter_apartment a(to_apt());
00466 try
00467 {
00468 return impl().call(a0_proxy,a1_proxy).proxy();
00469 }
00470 catch(var & ex)
00471 {
00472 throw ex.proxy();
00473 }
00474 }
00475
00476 var member_call(const char *m, const var & a0, const var & a1)
00477 {
00478 var a0_proxy = a0.proxy();
00479 var a1_proxy = a1.proxy();
00480 enter_apartment a(to_apt());
00481 try
00482 {
00483 return impl().member_call(m,a0_proxy,a1_proxy).proxy();
00484 }
00485 catch(var & ex)
00486 {
00487 throw ex.proxy();
00488 }
00489 }
00490
00491 var call(const var & a0, const var & a1, const var & a2)
00492 {
00493 var a0_proxy = a0.proxy();
00494 var a1_proxy = a1.proxy();
00495 var a2_proxy = a2.proxy();
00496 enter_apartment a(to_apt());
00497 try
00498 {
00499 return impl().call(a0_proxy,a1_proxy,a2_proxy).proxy();
00500 }
00501 catch(var & ex)
00502 {
00503 throw ex.proxy();
00504 }
00505 }
00506
00507 var member_call(const char *m, const var & a0, const var & a1, const var & a2)
00508 {
00509 var a0_proxy = a0.proxy();
00510 var a1_proxy = a1.proxy();
00511 var a2_proxy = a2.proxy();
00512 enter_apartment a(to_apt());
00513 try
00514 {
00515 return impl().member_call(m, a0_proxy,a1_proxy,a2_proxy).proxy();
00516 }
00517 catch(var & ex)
00518 {
00519 throw ex.proxy();
00520 }
00521 }
00522
00523 var call(const var & a0, const var & a1, const var & a2, const var & a3)
00524 {
00525 var a0_proxy = a0.proxy();
00526 var a1_proxy = a1.proxy();
00527 var a2_proxy = a2.proxy();
00528 var a3_proxy = a3.proxy();
00529 enter_apartment a(to_apt());
00530 try
00531 {
00532 return impl().call(a0_proxy,a1_proxy,a2_proxy,a3_proxy).proxy();
00533 }
00534 catch(var & ex)
00535 {
00536 throw ex.proxy();
00537 }
00538 }
00539
00540 var member_call(const char * m, const var & a0, const var & a1, const var & a2, const var & a3)
00541 {
00542 var a0_proxy = a0.proxy();
00543 var a1_proxy = a1.proxy();
00544 var a2_proxy = a2.proxy();
00545 var a3_proxy = a3.proxy();
00546 enter_apartment a(to_apt());
00547 try
00548 {
00549 return impl().member_call(m, a0_proxy,a1_proxy,a2_proxy,a3_proxy).proxy();
00550 }
00551 catch(var & ex)
00552 {
00553 throw ex.proxy();
00554 }
00555 }
00556
00557 var call(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4)
00558 {
00559 var a0_proxy = a0.proxy();
00560 var a1_proxy = a1.proxy();
00561 var a2_proxy = a2.proxy();
00562 var a3_proxy = a3.proxy();
00563 var a4_proxy = a4.proxy();
00564 enter_apartment a(to_apt());
00565 try
00566 {
00567 return impl().call(a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy).proxy();
00568 }
00569 catch(var & ex)
00570 {
00571 throw ex.proxy();
00572 }
00573 }
00574
00575 var member_call(const char * m, const var & a0, const var & a1, const var & a2, const var & a3, const var & a4)
00576 {
00577 var a0_proxy = a0.proxy();
00578 var a1_proxy = a1.proxy();
00579 var a2_proxy = a2.proxy();
00580 var a3_proxy = a3.proxy();
00581 var a4_proxy = a4.proxy();
00582 enter_apartment a(to_apt());
00583 try
00584 {
00585 return impl().member_call(m,a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy).proxy();
00586 }
00587 catch(var & ex)
00588 {
00589 throw ex.proxy();
00590 }
00591 }
00592
00593 var call(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5)
00594 {
00595 var a0_proxy = a0.proxy();
00596 var a1_proxy = a1.proxy();
00597 var a2_proxy = a2.proxy();
00598 var a3_proxy = a3.proxy();
00599 var a4_proxy = a4.proxy();
00600 var a5_proxy = a5.proxy();
00601 enter_apartment a(to_apt());
00602 try
00603 {
00604 return impl().call(a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy,a5_proxy).proxy();
00605 }
00606 catch(var & ex)
00607 {
00608 throw ex.proxy();
00609 }
00610 }
00611
00612 var member_call(const char * m, const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5)
00613 {
00614 var a0_proxy = a0.proxy();
00615 var a1_proxy = a1.proxy();
00616 var a2_proxy = a2.proxy();
00617 var a3_proxy = a3.proxy();
00618 var a4_proxy = a4.proxy();
00619 var a5_proxy = a5.proxy();
00620 enter_apartment a(to_apt());
00621 try
00622 {
00623 return impl().member_call(m,a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy,a5_proxy).proxy();
00624 }
00625 catch(var & ex)
00626 {
00627 throw ex.proxy();
00628 }
00629 }
00630
00631 var call(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6)
00632 {
00633 var a0_proxy = a0.proxy();
00634 var a1_proxy = a1.proxy();
00635 var a2_proxy = a2.proxy();
00636 var a3_proxy = a3.proxy();
00637 var a4_proxy = a4.proxy();
00638 var a5_proxy = a5.proxy();
00639 var a6_proxy = a6.proxy();
00640 enter_apartment a(to_apt());
00641 try
00642 {
00643 return impl().call(a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy,a5_proxy,a6_proxy).proxy();
00644 }
00645 catch(var & ex)
00646 {
00647 throw ex.proxy();
00648 }
00649 }
00650
00651 var member_call(const char * m, const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6)
00652 {
00653 var a0_proxy = a0.proxy();
00654 var a1_proxy = a1.proxy();
00655 var a2_proxy = a2.proxy();
00656 var a3_proxy = a3.proxy();
00657 var a4_proxy = a4.proxy();
00658 var a5_proxy = a5.proxy();
00659 var a6_proxy = a6.proxy();
00660 enter_apartment a(to_apt());
00661 try
00662 {
00663 return impl().member_call(m,a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy,a5_proxy,a6_proxy).proxy();
00664 }
00665 catch(var & ex)
00666 {
00667 throw ex.proxy();
00668 }
00669 }
00670
00671 var call(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6, const var & a7)
00672 {
00673 var a0_proxy = a0.proxy();
00674 var a1_proxy = a1.proxy();
00675 var a2_proxy = a2.proxy();
00676 var a3_proxy = a3.proxy();
00677 var a4_proxy = a4.proxy();
00678 var a5_proxy = a5.proxy();
00679 var a6_proxy = a6.proxy();
00680 var a7_proxy = a7.proxy();
00681 enter_apartment a(to_apt());
00682 try
00683 {
00684 return impl().call(a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy,a5_proxy,a6_proxy,a7_proxy).proxy();
00685 }
00686 catch(var & ex)
00687 {
00688 throw ex.proxy();
00689 }
00690 }
00691
00692 var member_call(const char * m, const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6, const var & a7)
00693 {
00694 var a0_proxy = a0.proxy();
00695 var a1_proxy = a1.proxy();
00696 var a2_proxy = a2.proxy();
00697 var a3_proxy = a3.proxy();
00698 var a4_proxy = a4.proxy();
00699 var a5_proxy = a5.proxy();
00700 var a6_proxy = a6.proxy();
00701 var a7_proxy = a7.proxy();
00702 enter_apartment a(to_apt());
00703 try
00704 {
00705 return impl().member_call(m,a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy,a5_proxy,a6_proxy,a7_proxy).proxy();
00706 }
00707 catch(var & ex)
00708 {
00709 throw ex.proxy();
00710 }
00711 }
00712
00713 var call(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6, const var & a7, const var & a8)
00714 {
00715 var a0_proxy = a0.proxy();
00716 var a1_proxy = a1.proxy();
00717 var a2_proxy = a2.proxy();
00718 var a3_proxy = a3.proxy();
00719 var a4_proxy = a4.proxy();
00720 var a5_proxy = a5.proxy();
00721 var a6_proxy = a6.proxy();
00722 var a7_proxy = a7.proxy();
00723 var a8_proxy = a8.proxy();
00724 enter_apartment a(to_apt());
00725 try
00726 {
00727 return impl().call(a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy,a5_proxy,a6_proxy,a7_proxy,a8_proxy).proxy();
00728 }
00729 catch(var & ex)
00730 {
00731 throw ex.proxy();
00732 }
00733 }
00734
00735 var member_call(const char * m, const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6, const var & a7, const var & a8)
00736 {
00737 var a0_proxy = a0.proxy();
00738 var a1_proxy = a1.proxy();
00739 var a2_proxy = a2.proxy();
00740 var a3_proxy = a3.proxy();
00741 var a4_proxy = a4.proxy();
00742 var a5_proxy = a5.proxy();
00743 var a6_proxy = a6.proxy();
00744 var a7_proxy = a7.proxy();
00745 var a8_proxy = a8.proxy();
00746 enter_apartment a(to_apt());
00747 try
00748 {
00749 return impl().member_call(m, a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy,a5_proxy,a6_proxy,a7_proxy,a8_proxy).proxy();
00750 }
00751 catch(var & ex)
00752 {
00753 throw ex.proxy();
00754 }
00755 }
00756
00757 var call(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6, const var & a7, const var & a8, const var & a9)
00758 {
00759 var a0_proxy = a0.proxy();
00760 var a1_proxy = a1.proxy();
00761 var a2_proxy = a2.proxy();
00762 var a3_proxy = a3.proxy();
00763 var a4_proxy = a4.proxy();
00764 var a5_proxy = a5.proxy();
00765 var a6_proxy = a6.proxy();
00766 var a7_proxy = a7.proxy();
00767 var a8_proxy = a8.proxy();
00768 var a9_proxy = a9.proxy();
00769 enter_apartment a(to_apt());
00770 try
00771 {
00772 return impl().call(a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy,a5_proxy,a6_proxy,a7_proxy,a8_proxy,a9_proxy).proxy();
00773 }
00774 catch(var & ex)
00775 {
00776 throw ex.proxy();
00777 }
00778 }
00779
00780 var member_call(const char * m, const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6, const var & a7, const var & a8, const var & a9)
00781 {
00782 var a0_proxy = a0.proxy();
00783 var a1_proxy = a1.proxy();
00784 var a2_proxy = a2.proxy();
00785 var a3_proxy = a3.proxy();
00786 var a4_proxy = a4.proxy();
00787 var a5_proxy = a5.proxy();
00788 var a6_proxy = a6.proxy();
00789 var a7_proxy = a7.proxy();
00790 var a8_proxy = a8.proxy();
00791 var a9_proxy = a9.proxy();
00792 enter_apartment a(to_apt());
00793 try
00794 {
00795 return impl().member_call(m,a0_proxy,a1_proxy,a2_proxy,a3_proxy,a4_proxy,a5_proxy,a6_proxy,a7_proxy,a8_proxy,a9_proxy).proxy();
00796 }
00797 catch(var & ex)
00798 {
00799 throw ex.proxy();
00800 }
00801 }
00802
00803 int size()
00804 {
00805 enter_apartment a(to_apt());
00806 try
00807 {
00808 return impl().size();
00809 }
00810 catch(var & ex)
00811 {
00812 throw ex.proxy();
00813 }
00814 }
00815
00816 std::size_t capacity()
00817 {
00818 enter_apartment a(to_apt());
00819 try
00820 {
00821 return impl().capacity();
00822 }
00823 catch(var & ex)
00824 {
00825 throw ex.proxy();
00826 }
00827 }
00828
00829 void get_range(std::size_t size, std::pair<std::size_t, std::size_t> & out)
00830 {
00831 enter_apartment a(to_apt());
00832 try
00833 {
00834 return impl().get_range(size, out);
00835 }
00836 catch(var & ex)
00837 {
00838 throw ex.proxy();
00839 }
00840 }
00841
00842 void resize(std::size_t n)
00843 {
00844 enter_apartment a(to_apt());
00845 try
00846 {
00847 impl().resize(n);
00848 }
00849 catch(var & ex)
00850 {
00851 throw ex.proxy();
00852 }
00853 }
00854
00855 bool empty()
00856 {
00857 enter_apartment a(to_apt());
00858 try
00859 {
00860 return impl().empty();
00861 }
00862 catch(var & ex)
00863 {
00864 throw ex.proxy();
00865 }
00866 }
00867
00868 void clear()
00869 {
00870 enter_apartment a(to_apt());
00871 try
00872 {
00873 impl().clear();
00874 }
00875 catch(var & ex)
00876 {
00877 throw ex.proxy();
00878 }
00879 }
00880
00881 var front()
00882 {
00883 enter_apartment a(to_apt());
00884 try
00885 {
00886 return impl().front().proxy();
00887 }
00888 catch(var & ex)
00889 {
00890 throw ex.proxy();
00891 }
00892 }
00893
00894 var back()
00895 {
00896 enter_apartment a(to_apt());
00897 try
00898 {
00899 return impl().back().proxy();
00900 }
00901 catch(var & ex)
00902 {
00903 throw ex.proxy();
00904 }
00905 }
00906
00907 var key()
00908 {
00909 enter_apartment a(to_apt());
00910 try
00911 {
00912 return impl().key().proxy();
00913 }
00914 catch(var & ex)
00915 {
00916 throw ex.proxy();
00917 }
00918 }
00919
00920 var value()
00921 {
00922 enter_apartment a(to_apt());
00923 try
00924 {
00925 return impl().value().proxy();
00926 }
00927 catch(var & ex)
00928 {
00929 throw ex.proxy();
00930 }
00931 }
00932
00933 var deref()
00934 {
00935 enter_apartment a(to_apt());
00936 try
00937 {
00938 return impl().deref().proxy();
00939 }
00940 catch(var & ex)
00941 {
00942 throw ex.proxy();
00943 }
00944 }
00945
00946 var begin()
00947 {
00948 enter_apartment a(to_apt());
00949 try
00950 {
00951 return impl().begin().proxy();
00952 }
00953 catch(var & ex)
00954 {
00955 throw ex.proxy();
00956 }
00957 }
00958
00959 var end()
00960 {
00961 enter_apartment a(to_apt());
00962 try
00963 {
00964 return impl().end().proxy();
00965 }
00966 catch(var & ex)
00967 {
00968 throw ex.proxy();
00969 }
00970 }
00971
00972 var rbegin()
00973 {
00974 enter_apartment a(to_apt());
00975 try
00976 {
00977 return impl().rbegin().proxy();
00978 }
00979 catch(var & ex)
00980 {
00981 throw ex.proxy();
00982 }
00983 }
00984
00985 var rend()
00986 {
00987 enter_apartment a(to_apt());
00988 try
00989 {
00990 return impl().rend().proxy();
00991 }
00992 catch(var & ex)
00993 {
00994 throw ex.proxy();
00995 }
00996 }
00997
00998 void op_inc()
00999 {
01000 enter_apartment a(to_apt());
01001 try
01002 {
01003 impl().op_inc();
01004 }
01005 catch(var & ex)
01006 {
01007 throw ex.proxy();
01008 }
01009 }
01010
01011 void op_dec()
01012 {
01013 enter_apartment a(to_apt());
01014 try
01015 {
01016 impl().op_dec();
01017 }
01018 catch(var & ex)
01019 {
01020 throw ex.proxy();
01021 }
01022 }
01023
01024 var enumerator()
01025 {
01026 enter_apartment a(to_apt());
01027 try
01028 {
01029 return impl().enumerator().proxy();
01030 }
01031 catch(var & ex)
01032 {
01033 throw ex.proxy();
01034 }
01035 }
01036
01037 var reverse_enumerator()
01038 {
01039 enter_apartment a(to_apt());
01040 try
01041 {
01042 return impl().reverse_enumerator().proxy();
01043 }
01044 catch(var & ex)
01045 {
01046 throw ex.proxy();
01047 }
01048 }
01049
01050 var keys()
01051 {
01052 enter_apartment a(to_apt());
01053 try
01054 {
01055 return impl().keys().proxy();
01056 }
01057 catch(var & ex)
01058 {
01059 throw ex.proxy();
01060 }
01061 }
01062
01063 var values()
01064 {
01065 enter_apartment a(to_apt());
01066 try
01067 {
01068 return impl().values().proxy();
01069 }
01070 catch(var & ex)
01071 {
01072 throw ex.proxy();
01073 }
01074 }
01075
01076 var get_member(const var & i)
01077 {
01078 var i_proxy = i.proxy();
01079 enter_apartment a(to_apt());
01080 try
01081 {
01082 return impl().get_member(i_proxy).proxy();
01083 }
01084 catch(var & ex)
01085 {
01086 throw ex.proxy();
01087 }
01088 }
01089
01090 var get_member(int i)
01091 {
01092 enter_apartment a(to_apt());
01093 try
01094 {
01095 return impl().get_member(i).proxy();
01096 }
01097 catch(var & ex)
01098 {
01099 throw ex.proxy();
01100 }
01101 }
01102
01103 var get_member(const char* i)
01104 {
01105 enter_apartment a(to_apt());
01106 try
01107 {
01108 return impl().get_member(i).proxy();
01109 }
01110 catch(var & ex)
01111 {
01112 throw ex.proxy();
01113 }
01114 }
01115
01116 void set_member(const var & a, const var & b)
01117 {
01118 var a_proxy = a.proxy();
01119 var b_proxy = b.proxy();
01120 enter_apartment ea(to_apt());
01121 try
01122 {
01123 impl().set_member(a_proxy,b_proxy);
01124 }
01125 catch(var & ex)
01126 {
01127 throw ex.proxy();
01128 }
01129 }
01130
01131 void set_member(int a, const var & b)
01132 {
01133 var b_proxy = b.proxy();
01134 enter_apartment ea(to_apt());
01135 try
01136 {
01137 impl().set_member(a,b_proxy);
01138 }
01139 catch(var & ex)
01140 {
01141 throw ex.proxy();
01142 }
01143 }
01144
01145 void set_member(const char *a, const var & b)
01146 {
01147 var b_proxy = b.proxy();
01148 enter_apartment ea(to_apt());
01149 try
01150 {
01151 impl().set_member(a,b_proxy);
01152 }
01153 catch(var & ex)
01154 {
01155 throw ex.proxy();
01156 }
01157 }
01158
01159 void push_back(const var & v)
01160 {
01161 var v_proxy = v.proxy();
01162 enter_apartment ea(to_apt());
01163 try
01164 {
01165 impl().push_back(v_proxy);
01166 }
01167 catch(var & ex)
01168 {
01169 throw ex.proxy();
01170 }
01171 }
01172
01173 void push_front(const var & v)
01174 {
01175 var v_proxy = v.proxy();
01176 enter_apartment ea(to_apt());
01177 try
01178 {
01179 impl().push_front(v_proxy);
01180 }
01181 catch(var & ex)
01182 {
01183 throw ex.proxy();
01184 }
01185 }
01186
01187 var pop_back()
01188 {
01189 enter_apartment ea(to_apt());
01190 try
01191 {
01192 return impl().pop_back().proxy();
01193 }
01194 catch(var & ex)
01195 {
01196 throw ex.proxy();
01197 }
01198 }
01199
01200 var pop_front()
01201 {
01202 enter_apartment ea(to_apt());
01203 try
01204 {
01205 return impl().pop_front().proxy();
01206 }
01207 catch(var & ex)
01208 {
01209 throw ex.proxy();
01210 }
01211 }
01212
01213 bool contains(const var & s)
01214 {
01215 var s_proxy = s.proxy();
01216 enter_apartment ea(to_apt());
01217 try
01218 {
01219 return impl().contains(s_proxy);
01220 }
01221 catch(var & ex)
01222 {
01223 throw ex.proxy();
01224 }
01225 }
01226
01227 var op_add(const var & v)
01228 {
01229 var v_proxy = v.proxy();
01230 enter_apartment a(to_apt());
01231 try
01232 {
01233 return impl().op_add(v_proxy).proxy();
01234 }
01235 catch(var & ex)
01236 {
01237 throw ex.proxy();
01238 }
01239 }
01240
01241 var op_sub(const var & v)
01242 {
01243 var v_proxy = v.proxy();
01244 enter_apartment a(to_apt());
01245 try
01246 {
01247 return impl().op_sub(v_proxy).proxy();
01248 }
01249 catch(var & ex)
01250 {
01251 throw ex.proxy();
01252 }
01253 }
01254
01255 var op_mul(const var & v)
01256 {
01257 var v_proxy = v.proxy();
01258 enter_apartment a(to_apt());
01259 try
01260 {
01261 return impl().op_mul(v_proxy).proxy();
01262 }
01263 catch(var & ex)
01264 {
01265 throw ex.proxy();
01266 }
01267 }
01268
01269 var op_div(const var & v)
01270 {
01271 var v_proxy = v.proxy();
01272 enter_apartment a(to_apt());
01273 try
01274 {
01275 return impl().op_div(v_proxy).proxy();
01276 }
01277 catch(var & ex)
01278 {
01279 throw ex.proxy();
01280 }
01281 }
01282
01283 var op_mod(const var & v)
01284 {
01285 var v_proxy = v.proxy();
01286 enter_apartment a(to_apt());
01287 try
01288 {
01289 return impl().op_mod(v_proxy).proxy();
01290 }
01291 catch(var & ex)
01292 {
01293 throw ex.proxy();
01294 }
01295 }
01296
01297 var op_pos()
01298 {
01299 enter_apartment a(to_apt());
01300 try
01301 {
01302 return impl().op_pos().proxy();
01303 }
01304 catch(var & ex)
01305 {
01306 throw ex.proxy();
01307 }
01308 }
01309
01310 var op_neg()
01311 {
01312 enter_apartment a(to_apt());
01313 try
01314 {
01315 return impl().op_neg().proxy();
01316 }
01317 catch(var & ex)
01318 {
01319 throw ex.proxy();
01320 }
01321 }
01322
01323 var op_inv()
01324 {
01325 enter_apartment a(to_apt());
01326 try
01327 {
01328 return impl().op_inv().proxy();
01329 }
01330 catch(var & ex)
01331 {
01332 throw ex.proxy();
01333 }
01334 }
01335
01336 var op_lshift(const var & n)
01337 {
01338 var n_proxy = n.proxy();
01339 enter_apartment a(to_apt());
01340 try
01341 {
01342 return impl().op_lshift(n_proxy).proxy();
01343 }
01344 catch(var & ex)
01345 {
01346 throw ex.proxy();
01347 }
01348 }
01349
01350 var op_rshift(const var & n)
01351 {
01352 var n_proxy = n.proxy();
01353 enter_apartment a(to_apt());
01354 try
01355 {
01356 return impl().op_rshift(n_proxy).proxy();
01357 }
01358 catch(var & ex)
01359 {
01360 throw ex.proxy();
01361 }
01362 }
01363
01364 var op_and(const var & n)
01365 {
01366 var n_proxy = n.proxy();
01367 enter_apartment a(to_apt());
01368 try
01369 {
01370 return impl().op_and(n_proxy).proxy();
01371 }
01372 catch(var & ex)
01373 {
01374 throw ex.proxy();
01375 }
01376 }
01377
01378 var op_or(const var & n)
01379 {
01380 var n_proxy = n.proxy();
01381 enter_apartment a(to_apt());
01382 try
01383 {
01384 return impl().op_or(n_proxy).proxy();
01385 }
01386 catch(var & ex)
01387 {
01388 throw ex.proxy();
01389 }
01390 }
01391
01392 var op_xor(const var & n)
01393 {
01394 var n_proxy = n.proxy();
01395 enter_apartment a(to_apt());
01396 try
01397 {
01398 return impl().op_xor(n_proxy).proxy();
01399 }
01400 catch(var & ex)
01401 {
01402 throw ex.proxy();
01403 }
01404 }
01405
01406 void assign_add(const var & n)
01407 {
01408 var n_proxy = n.proxy();
01409 enter_apartment a(to_apt());
01410 try
01411 {
01412 impl().assign_add(n_proxy);
01413 }
01414 catch(var & ex)
01415 {
01416 throw ex.proxy();
01417 }
01418 }
01419
01420 void assign_sub(const var & n)
01421 {
01422 var n_proxy = n.proxy();
01423 enter_apartment a(to_apt());
01424 try
01425 {
01426 impl().assign_sub(n_proxy);
01427 }
01428 catch(var & ex)
01429 {
01430 throw ex.proxy();
01431 }
01432 }
01433
01434 void assign_mul(const var & n)
01435 {
01436 var n_proxy = n.proxy();
01437 enter_apartment a(to_apt());
01438 try
01439 {
01440 impl().assign_mul(n_proxy);
01441 }
01442 catch(var & ex)
01443 {
01444 throw ex.proxy();
01445 }
01446 }
01447
01448 void assign_div(const var & n)
01449 {
01450 var n_proxy = n.proxy();
01451 enter_apartment a(to_apt());
01452 try
01453 {
01454 impl().assign_div(n_proxy);
01455 }
01456 catch(var & ex)
01457 {
01458 throw ex.proxy();
01459 }
01460 }
01461
01462 void assign_mod(const var & n)
01463 {
01464 var n_proxy = n.proxy();
01465 enter_apartment a(to_apt());
01466 try
01467 {
01468 impl().assign_mod(n_proxy);
01469 }
01470 catch(var & ex)
01471 {
01472 throw ex.proxy();
01473 }
01474 }
01475
01476 void assign_lshift(const var & n)
01477 {
01478 var n_proxy = n.proxy();
01479 enter_apartment a(to_apt());
01480 try
01481 {
01482 impl().assign_lshift(n_proxy);
01483 }
01484 catch(var & ex)
01485 {
01486 throw ex.proxy();
01487 }
01488 }
01489
01490 void assign_rshift(const var & n)
01491 {
01492 var n_proxy = n.proxy();
01493 enter_apartment a(to_apt());
01494 try
01495 {
01496 impl().assign_rshift(n_proxy);
01497 }
01498 catch(var & ex)
01499 {
01500 throw ex.proxy();
01501 }
01502 }
01503
01504 void assign_and(const var & n)
01505 {
01506 var n_proxy = n.proxy();
01507 enter_apartment a(to_apt());
01508 try
01509 {
01510 impl().assign_and(n_proxy);
01511 }
01512 catch(var & ex)
01513 {
01514 throw ex.proxy();
01515 }
01516 }
01517
01518 void assign_or(const var & n)
01519 {
01520 var n_proxy = n.proxy();
01521 enter_apartment a(to_apt());
01522 try
01523 {
01524 impl().assign_or(n_proxy);
01525 }
01526 catch(var & ex)
01527 {
01528 throw ex.proxy();
01529 }
01530 }
01531
01532 void assign_xor(const var & n)
01533 {
01534 var n_proxy = n.proxy();
01535 enter_apartment a(to_apt());
01536 try
01537 {
01538 impl().assign_xor(n_proxy);
01539 }
01540 catch(var & ex)
01541 {
01542 throw ex.proxy();
01543 }
01544 }
01545
01546 void erase(const var & n)
01547 {
01548 var n_proxy = n.proxy();
01549 enter_apartment a(to_apt());
01550 try
01551 {
01552 impl().erase(n_proxy);
01553 }
01554 catch(var & ex)
01555 {
01556 throw ex.proxy();
01557 }
01558 }
01559
01560 void insert(const var & n)
01561 {
01562 var n_proxy = n.proxy();
01563 enter_apartment a(to_apt());
01564 try
01565 {
01566 impl().insert(n_proxy);
01567 }
01568 catch(var & ex)
01569 {
01570 throw ex.proxy();
01571 }
01572 }
01573
01574 void insert(const var & m, const var & n)
01575 {
01576 var m_proxy = m.proxy();
01577 var n_proxy = n.proxy();
01578 enter_apartment a(to_apt());
01579 try
01580 {
01581 impl().insert(m_proxy,n_proxy);
01582 }
01583 catch(var & ex)
01584 {
01585 throw ex.proxy();
01586 }
01587 }
01588
01589 var member_inc(const char * n)
01590 {
01591 enter_apartment a(to_apt());
01592 try
01593 {
01594 return impl().member_inc(n).proxy();
01595 }
01596 catch(var & ex)
01597 {
01598 throw ex.proxy();
01599 }
01600 }
01601
01602 var member_dec(const char * n)
01603 {
01604 enter_apartment a(to_apt());
01605 try
01606 {
01607 return impl().member_dec(n).proxy();
01608 }
01609 catch(var & ex)
01610 {
01611 throw ex.proxy();
01612 }
01613 }
01614
01615 var member_add(const char * n, const var & m)
01616 {
01617 var m_proxy = m.proxy();
01618 enter_apartment a(to_apt());
01619 try
01620 {
01621 return impl().member_add(n,m_proxy).proxy();
01622 }
01623 catch(var & ex)
01624 {
01625 throw ex.proxy();
01626 }
01627 }
01628
01629 var member_sub(const char * n, const var & m)
01630 {
01631 var m_proxy = m.proxy();
01632 enter_apartment a(to_apt());
01633 try
01634 {
01635 return impl().member_sub(n,m_proxy).proxy();
01636 }
01637 catch(var & ex)
01638 {
01639 throw ex.proxy();
01640 }
01641 }
01642 };
01643 }
01644 }
01645
01646
01647 var dynamic::internal::proxy(const var & v)
01648 {
01649 return proxy(v, apartment::current());
01650 }
01651
01652
01653 var dynamic::internal::proxy(const var & v, apartment * from)
01654 {
01655 return var(types::proxy_impl(new proxy_stub_impl(v, from)), var::assign_impl());
01656 }
01657
01658
01659
01660 #define DEBUG_MALLOC 1
01661
01662
01663 void * dynamic::internal::apartment_malloc(std::size_t bytes)
01664 {
01665 #if DEBUG_MALLOC
01666 return ::malloc(bytes);
01667 #else
01668 return apartment::current()->malloc( bytes );
01669 #endif
01670 }
01671
01672
01673 void dynamic::internal::apartment_free(void *p)
01674 {
01675 #if DEBUG_MALLOC
01676 ::free(p);
01677 #else
01678 apartment::current()->free(p);
01679 #endif
01680 }
01681
01682
01683 void dynamic::internal::apartment_defrag()
01684 {
01685 apartment::current()->defrag();
01686 }
01687
01688
01689 internal::leave_apartment::leave_apartment()
01690 {
01691 apartment::current()->unlock();
01692 }
01693
01694
01695 internal::leave_apartment::~leave_apartment()
01696 {
01697 apartment::current()->lock();
01698 }
01699
01700
01701 var dynamic::shared(const var & cmd)
01702 {
01703 return internal::proxy(cmd, new apartment())();
01704 }
01705
01706
01707 var dynamic::global(const var & cmd)
01708 {
01709 static apartment * appt = new apartment();
01710 static var p = proxy(var(), appt);
01711 return proxy(cmd, appt)();
01712 }
01713
01714
01715 internal::use_new_apartment::use_new_apartment() : m_previous(cg::tls<apartment*>::get())
01716 {
01717 if(m_previous) m_previous->unlock();
01718 apartment * a = new apartment();
01719 a->add_ref();
01720 a->lock();
01721 cg::tls<apartment*>::set( a );
01722 }
01723
01724
01725 internal::use_new_apartment::~use_new_apartment()
01726 {
01727 apartment * current = cg::tls<apartment*>::get();
01728 current->unlock();
01729 current->release();
01730 if(m_previous) m_previous->lock();
01731 cg::tls<apartment*>::set(m_previous);
01732 }
01733
01734
01735 dynamic::gc::garbage_collector & dynamic::gc::global_gc()
01736 {
01737 return apartment::current()->gc();
01738 }