00001
00008 #include <string>
00009 #include <vector>
00010
00011
00012
00013
00014
00015
00016
00017
00018 extern "C" {
00019 #include "EXTERN.h"
00020 #include "perl.h"
00021 #include "XSUB.h"
00022 #include "ppport.h"
00023 #include <cstdarg>
00024 };
00025
00026 namespace pl {
00027 class Str;
00028 class UInt;
00029 class Int;
00030 class Double;
00031 class Pointer;
00032 class Reference;
00033 class Hash;
00034 class Array;
00035 class Package;
00036 class Code;
00037 class Ctx;
00038 class Scalar;
00039
00041 class IO {
00042 public:
00044 static PerlIO* stderr() {
00045 return PerlIO_stderr();
00046 }
00048 static PerlIO* stdout() {
00049 return PerlIO_stdout();
00050 }
00052 static void printf(const char *format, ...) {
00053 va_list args;
00054 va_start(args, format);
00055 PerlIO_vprintf(IO::stdout(), format, args);
00056 va_end(args);
00057 }
00059 static void printf(PerlIO* io, const char *format, ...) {
00060 va_list args;
00061 va_start(args, format);
00062 PerlIO_vprintf(io, format, args);
00063 va_end(args);
00064 }
00065 };
00066
00070 class Carp {
00071 public:
00072 static void croak(const char * format, ...) {
00073 va_list args;
00074 va_start(args, format);
00075 Perl_vcroak(aTHX_ format, &args);
00076 va_end(args);
00077 }
00078 static void warn(const char * format, ...) {
00079 va_list args;
00080 va_start(args, format);
00081 Perl_vwarn(aTHX_ format, &args);
00082 va_end(args);
00083 }
00084 };
00085
00089 std::vector<Ctx*> ctxstack;
00090 class CurCtx {
00091 public:
00092 static Ctx * get() {
00093 if (ctxstack.size() > 0) {
00094 return ctxstack[ctxstack.size()-1];
00095 } else {
00096 Carp::croak("Devel::BindPP: missing context");
00097 throw;
00098 }
00099 }
00100 };
00101
00105 class Value {
00106 friend class Ctx;
00107 friend class Reference;
00108 friend class Array;
00109 friend class Perl;
00110 friend class Hash;
00111 friend class Package;
00112 friend class Code;
00113
00114 public:
00119 void dump() {
00120 sv_dump(this->val);
00121 }
00126 void refcnt_inc() {
00127 SvREFCNT_inc_simple_void(this->val);
00128 }
00133 void refcnt_dec() {
00134 SvREFCNT_dec(this->val);
00135 }
00139 int refcnt() {
00140 return SvREFCNT(this->val);
00141 }
00142 bool is_true() {
00143 return SvTRUE(this->val);
00144 }
00148 Reference* reference();
00149 ~Value() {
00150 }
00151 protected:
00152 SV* val;
00153 Value() { }
00154 Value(SV* _v) {
00155 this->val = _v;
00156 }
00157 };
00158
00162 class Scalar : public Value {
00163 friend class Ctx;
00164 friend class Reference;
00165 friend class Array;
00166 friend class Perl;
00167 friend class Hash;
00168 friend class Package;
00169 friend class Code;
00170
00171 public:
00176 Scalar * mortal() {
00177 sv_2mortal(this->val);
00178 return this;
00179 }
00183 Str* as_str();
00187 Int* as_int();
00191 UInt* as_uint();
00195 Double* as_double();
00199 Pointer* as_pointer();
00203 Reference* as_ref();
00204 Scalar * clone () {
00205 return Scalar::create(newSVsv(this->val));
00206 }
00207
00208 template <class T>
00209 static Scalar *to_perl(T s) {
00210 return Scalar::create(to_sv(s));
00211 }
00212 protected:
00213 Scalar(SV* _v) : Value(_v) { }
00214 static Scalar * create(SV* _v);
00215 static SV *to_sv(const char* s) {
00216 return (newSVpv(s, strlen(s)));
00217 }
00218 static SV *to_sv(unsigned int v) {
00219 return (newSVuv(v));
00220 }
00221 static SV *to_sv(int v) {
00222 return (newSViv(v));
00223 }
00224 static SV *to_sv(I32 v) {
00225 return (newSViv(v));
00226 }
00227 static SV *to_sv(double v) {
00228 return (newSVnv(v));
00229 }
00230 static SV *to_sv(Scalar * v) {
00231 if (v && v->val) {
00232 return (v->val);
00233 } else {
00234 return (&PL_sv_undef);
00235 }
00236 }
00237 static SV *to_sv(std::string& v) {
00238 return (newSVpv(v.c_str(), v.length()));
00239 }
00240 static SV *to_sv(bool b) {
00241 return (b ? &PL_sv_yes : &PL_sv_no);
00242 }
00243 };
00244
00248 class Boolean : public Scalar {
00249 public:
00250 Boolean(bool b) : Scalar(b ? &PL_sv_yes : &PL_sv_no) { }
00255 static Boolean* yes();
00260 static Boolean* no();
00261 };
00265 class Int : public Scalar {
00266 friend class Scalar;
00267 public:
00271 int to_c() {
00272 return SvIV(this->val);
00273 }
00274 protected:
00275 Int(SV* _s) : Scalar(_s) { }
00276 };
00280 class UInt : public Scalar {
00281 friend class Scalar;
00282 public:
00283 UInt(unsigned int _i) : Scalar(newSVuv(_i)) { }
00287 unsigned int to_c() {
00288 return SvUV(this->val);
00289 }
00290 protected:
00291 UInt(SV* _s) : Scalar(_s) { }
00292 };
00296 class Double : public Scalar {
00297 friend class Scalar;
00298 public:
00299 Double(double _i) : Scalar(newSVnv(_i)) { }
00303 double to_c() {
00304 return SvNV(this->val);
00305 }
00306 protected:
00307 Double(SV* _s) : Scalar(_s) { }
00308 };
00312 class Str : public Scalar {
00313 friend class Scalar;
00314 public:
00315 Str(std::string & _s) : Scalar(newSVpv(_s.c_str(), _s.length())) { }
00316 Str(const char* _s) : Scalar(newSVpv(_s, strlen(_s))) { }
00317 Str(const char* _s, int _n) : Scalar(newSVpv(_s, _n)) { }
00321 const char* to_c() {
00322 return SvPV_nolen(this->val);
00323 }
00327 void concat(const char* s, I32 len) {
00328 sv_catpvn(this->val, s, len);
00329 }
00330 void concat(const char* s) {
00331 sv_catpv(this->val, s);
00332 }
00333 void concat(Str* s) {
00334 sv_catsv(this->val, s->val);
00335 }
00337 int length() {
00338 return sv_len(this->val);
00339 }
00340 protected:
00341 Str(SV* _s) : Scalar(_s) { }
00342 };
00343
00347 class Reference : public Scalar {
00348 friend class Scalar;
00349 friend class Hash;
00350 friend class Array;
00351 public:
00355 static Reference * new_inc(Value* thing);
00357 void bless(const char *pkg) {
00358 HV * stash = gv_stashpv(pkg, TRUE);
00359 sv_bless(this->val, stash);
00360 }
00362 Hash * as_hash();
00364 Array * as_array();
00366 Scalar * as_scalar();
00368 Code* as_code();
00372 bool is_object() {
00373 return sv_isobject(this->val);
00374 }
00375 protected:
00376 Reference(SV*v) : Scalar(v) { }
00377 };
00378
00382 class Hash : public Value {
00383 friend class Reference;
00384 public:
00385 Hash() : Value((SV*)newHV()) { }
00387 Reference * fetch(const char *key);
00389 bool exists(const char*key) {
00390 return this->exists(key, strlen(key));
00391 }
00393 bool exists(const char*key, I32 klen) {
00394 return hv_exists((HV*)this->val, key, klen);
00395 }
00397 Reference* del(const char*key) {
00398 return this->del(key, strlen(key));
00399 }
00401 Reference* del(const char*key, I32 klen);
00402
00404 template <class T>
00405 void store(const char*key, T value) {
00406 this->store(key, strlen(key), value);
00407 }
00409 template <class T>
00410 void store(const char*key, I32 klen, T value);
00412 Scalar* scalar();
00414 void undef();
00416 void clear();
00417 protected:
00418 Hash(HV* _h) : Value((SV*)_h) { }
00419 };
00420
00424 class Array : public Value {
00425 friend class Reference;
00426 public:
00427 Array() : Value((SV*)newAV()) { }
00429 void push(Scalar* s) {
00430 s->refcnt_inc();
00431 av_push((AV*)this->val, s->val);
00432 }
00433 template <class T>
00434 void push(T v) {
00435 SV * s = Scalar::to_sv(v);
00436 SvREFCNT_inc_simple_void(s);
00437 av_push((AV*)this->val, s);
00438 }
00443 void unshift(Int &i) {
00444 this->unshift(i.to_c());
00445 }
00446 void unshift(I32 i) {
00447 av_unshift((AV*)this->val, i);
00448 }
00450 Scalar * pop();
00452 Scalar * shift();
00454 Reference * fetch(I32 key);
00455
00457 I32 len() {
00458 return av_len((AV*)this->val);
00459 }
00461 U32 size() {
00462 return this->len() + 1;
00463 }
00464
00466 template <class T>
00467 Scalar * store(I32 key, T v);
00469 void clear() {
00470 av_clear((AV*)this->val);
00471 }
00473 void undef() {
00474 av_undef((AV*)this->val);
00475 }
00477 void extend(I32 n) {
00478 av_extend((AV*)this->val, n);
00479 }
00480 protected:
00481 Array(AV* _a) : Value((SV*)_a) { }
00482 };
00483
00487 class Ctx {
00488 public:
00489 Ctx();
00490 Ctx(int arg_cnt);
00491 ~Ctx();
00493 I32 arg_len() {
00494 return (I32)(PL_stack_sp - mark);
00495 }
00497 Scalar* arg(int n) {
00498 Scalar*s = new Scalar(fetch_stack(n));
00499 this->register_allocated(s);
00500 return s;
00501 }
00503 template <class T>
00504 void ret(T n) {
00505 SV * s = Scalar::to_sv(n);
00506 this->ret(0, s);
00507 }
00508 template <class T>
00509 void ret(int n, T v) {
00510 return this->ret(n, Scalar::to_sv(v));
00511 }
00513 bool wantarray() {
00514 return GIMME_V & G_ARRAY ? true : false;
00515 }
00517 void ret(Array* ary) {
00518 unsigned int size = ary->size();
00519 if (size != 0) {
00520 SV** sp = PL_stack_sp;
00521 if ((unsigned int)(PL_stack_max - sp) < size) {
00522 sp = stack_grow(sp, sp, size);
00523 }
00524
00525 for (unsigned int i=0; i < size; ++i) {
00526 Scalar * s = ary->fetch(i);
00527 PL_stack_base[ax++] = s->val;
00528 }
00529 ax--;
00530 } else {
00531 this->return_undef();
00532 }
00533 }
00535 void return_true() {
00536 this->ret(0, &PL_sv_yes);
00537 }
00539 void return_undef() {
00540 this->ret(0, &PL_sv_undef);
00541 }
00547 void register_allocated(Value* v) {
00548 allocated.push_back(v);
00549 }
00550 protected:
00555 SV* fetch_stack(int n) {
00556 return PL_stack_base[this->ax + n];
00557 }
00558 void ret(int n, SV* s) {
00559 PL_stack_base[ax + n] = s;
00560 }
00561 void initialize();
00562 I32 ax;
00563 SV ** mark;
00564 std::vector<Value*> allocated;
00565 };
00566 Ctx::Ctx() {
00567 this->initialize();
00568 }
00569 Ctx::Ctx(int arg_cnt) {
00570 this->initialize();
00571
00572 int got = arg_len();
00573 if (arg_cnt != got) {
00574 Carp::croak("This method requires %d arguments, but %d", arg_cnt, got);
00575 }
00576 }
00577 void Ctx::initialize() {
00578
00579 this->ax = *PL_markstack_ptr + 1;
00580 --PL_markstack_ptr;
00581 this->mark = PL_stack_base + this->ax - 1;
00582
00583 ctxstack.push_back(this);
00584 }
00585 Ctx::~Ctx() {
00586 std::vector<Value*>::iterator iter;
00587 for (iter = allocated.begin(); iter != allocated.end(); iter++) {
00588 delete *iter;
00589 }
00590
00591 PL_stack_sp = PL_stack_base + ax;
00592
00593 ctxstack.pop_back();
00594 }
00595
00596 Reference * Reference::new_inc(Value* thing) {
00597 SV * v = newRV_inc(thing->val);
00598 Reference * ref = new Reference(v);
00599 CurCtx::get()->register_allocated(ref);
00600 return ref;
00601 }
00602
00603 Reference * Hash::fetch(const char* key) {
00604
00605 SV ** v = hv_fetch((HV*)this->val, key, strlen(key), 0);
00606 if (v) {
00607 Reference * ref = new Reference(*v);
00608 CurCtx::get()->register_allocated(ref);
00609 return ref;
00610 } else {
00611 return NULL;
00612 }
00613 }
00614 Reference * Array::fetch(I32 key) {
00615 SV ** v = av_fetch((AV*)this->val, key, 0);
00616 if (v) {
00617 Reference * ref = new Reference(*v);
00618 CurCtx::get()->register_allocated(ref);
00619 return ref;
00620 } else {
00621 return NULL;
00622 }
00623 }
00624 Scalar * Array::pop() {
00625 SV* v = av_pop((AV*)this->val);
00626 return Scalar::create(v);
00627 }
00628 Scalar * Array::shift() {
00629 SV* v = av_shift((AV*)this->val);
00630 return Scalar::create(v);
00631 }
00632 template <class T>
00633 Scalar * Array::store(I32 key, T arg) {
00634 SV * _v = Scalar::to_sv(arg);
00635 SvREFCNT_inc_simple_void(_v);
00636 SV** v = av_store((AV*)this->val, key, _v);
00637 if (v) {
00638 Reference * ref = new Reference(*v);
00639 CurCtx::get()->register_allocated(ref);
00640 return ref;
00641 } else {
00642 return NULL;
00643 }
00644 }
00645
00649 class Package {
00650 public:
00651 Package(std::string _pkg, const char *_file) {
00652 this->pkg = _pkg;
00653 this->file = _file;
00654 stash = gv_stashpvn(pkg.c_str(), pkg.length(), TRUE);
00655 }
00660 void add_method(const char*name, XSUBADDR_t func) {
00661 char * buf = const_cast<char*>( (pkg + "::" + name).c_str() );
00662 newXS(buf, func, const_cast<char*>(this->file));
00663 }
00668 void add_constant(const char *name, Value * val) {
00669 this->add_constant(name, val->val);
00670 }
00671
00672 template <class T>
00673 void add_constant(const char *name, T val) {
00674 SV * s = Scalar::to_sv(val);
00675 this->add_constant(name, s);
00676 }
00677 protected:
00678 void add_constant(const char *name, SV* val) {
00679 newCONSTSUB(stash, const_cast<char*>(name), val);
00680 }
00681 private:
00682 std::string pkg;
00683 HV * stash;
00684 const char * file;
00685 };
00686
00690 class BootstrapCtx : public Ctx {
00691 public:
00692 BootstrapCtx() : Ctx() {
00693 xs_version_bootcheck();
00694 }
00695 ~BootstrapCtx() {
00696 PL_stack_base[this->ax] = &PL_sv_yes;
00697 PL_stack_sp = PL_stack_base + this->ax;
00698 }
00699 protected:
00700
00701 void xs_version_bootcheck() {
00702 SV *_sv;
00703 const char *vn = NULL, *module = SvPV_nolen_const(ST(0));
00704 if (this->arg_len() >= 2) {
00705
00706 _sv = PL_stack_base[ax+1];
00707 } else {
00708
00709 _sv = get_sv(Perl_form(aTHX_ "%s::%s", module,
00710 vn = "XS_VERSION"), FALSE);
00711 if (!_sv || !SvOK(_sv))
00712 _sv = get_sv(Perl_form(aTHX_ "%s::%s", module,
00713 vn = "VERSION"), FALSE);
00714 }
00715 if (_sv && (!SvOK(_sv) || strNE(XS_VERSION, SvPV_nolen(_sv)))) {
00716 Perl_croak(aTHX_ "%s object version %s does not match %s%s%s%s %"SVf,
00717 module, XS_VERSION,
00718 vn ? "$" : "", vn ? module : "", vn ? "::" : "",
00719 vn ? vn : "bootstrap parameter", _sv
00720 );
00721 }
00722 }
00723 };
00724
00728 class Code : public Scalar {
00729 public:
00730 Code(SV * _s) : Scalar(_s) { }
00732 void call(Array * args, Array* retval) {
00733 SV **sp = PL_stack_sp;
00734
00735 push_scope();
00736 save_int((int*)&PL_tmps_floor);
00737 PL_tmps_floor = PL_tmps_ix;
00738
00739 if (++PL_markstack_ptr == PL_markstack_max) {
00740 markstack_grow();
00741 }
00742 *PL_markstack_ptr = (I32)((sp) - PL_stack_base);
00743
00744 for (int i =0; i < args->len()+1; i++) {
00745 if (PL_stack_max - sp < 1) {
00746
00747 sp = stack_grow(sp, sp, 1);
00748 }
00749 *++sp = args->pop()->val;
00750 }
00751 PL_stack_sp = sp;
00752
00753 int count = call_sv(this->val, G_ARRAY);
00754
00755 sp = PL_stack_sp;
00756
00757 for (int i=0; i<count; i++) {
00758 Scalar * s = Scalar::create(newSVsv(*sp--));
00759 retval->store(i, s);
00760 }
00761
00762 PL_stack_sp = sp;
00763 if (PL_tmps_ix > PL_tmps_floor) {
00764 free_tmps();
00765 }
00766 pop_scope();
00767 }
00769 void call(Array * args, Scalar** retval) {
00770 SV **sp = PL_stack_sp;
00771
00772 push_scope();
00773 save_int((int*)&PL_tmps_floor);
00774 PL_tmps_floor = PL_tmps_ix;
00775
00776 if (++PL_markstack_ptr == PL_markstack_max) {
00777 markstack_grow();
00778 }
00779 *PL_markstack_ptr = (I32)((sp) - PL_stack_base);
00780
00781 for (int i =0; i < args->len()+1; i++) {
00782 if (PL_stack_max - sp < 1) {
00783
00784 sp = stack_grow(sp, sp, 1);
00785 }
00786 *++sp = args->pop()->val;
00787 }
00788 PL_stack_sp = sp;
00789
00790 int count = call_sv(this->val, G_SCALAR);
00791
00792 sp = PL_stack_sp;
00793
00794 if (count != 0) {
00795 *retval = Scalar::create(newSVsv(*sp--));
00796 }
00797
00798 PL_stack_sp = sp;
00799 if (PL_tmps_ix > PL_tmps_floor) {
00800 free_tmps();
00801 }
00802 pop_scope();
00803 }
00804 };
00805
00809 class Pointer : public Scalar {
00810 public:
00811 Pointer(SV* s) : Scalar(s) { }
00813 Pointer(void* _ptr, const char* klass) : Scalar(sv_newmortal()) {
00814 if (_ptr == NULL) {
00815 sv_setsv(this->val, &PL_sv_undef);
00816 } else {
00817 sv_setref_pv(this->val, klass, _ptr);
00818 }
00819 }
00820
00824 template <class T>
00825 T extract() {
00826 return INT2PTR(T, SvROK(this->val) ? SvIV(SvRV(this->val)) : SvIV(this->val));
00827 }
00828 };
00829
00834 class FileTest {
00835 public:
00840 static bool is_regular_file(const char * fname) {
00841 Stat_t buf;
00842 int ret = PerlLIO_stat(fname, &buf);
00843 if (ret == 0 && S_ISREG(buf.st_mode)) {
00844 return true;
00845 } else {
00846 return false;
00847 }
00848 }
00853 static bool is_dir(const char * fname) {
00854 Stat_t buf;
00855 int ret = PerlLIO_stat(fname, &buf);
00856 if (ret == 0 && S_ISDIR(buf.st_mode)) {
00857 return true;
00858 } else {
00859 return false;
00860 }
00861 }
00862 };
00863
00864 Reference * Value::reference() {
00865 return Reference::new_inc(this);
00866 }
00867
00868 Str* Scalar::as_str() {
00869 if (SvPOK(this->val)) {
00870 Str * s = new Str(this->val);
00871 CurCtx::get()->register_allocated(s);
00872 return s;
00873 } else {
00874 Perl_croak(aTHX_ "%s: %s is not a string",
00875 "Devel::BindPP",
00876 "sv");
00877 }
00878 }
00879 Pointer* Scalar::as_pointer() {
00880 if (SvROK(this->val)) {
00881 Pointer * s = new Pointer(this->val);
00882 CurCtx::get()->register_allocated(s);
00883 return s;
00884 } else {
00885 Perl_croak(aTHX_ "%s: %s is not a pointer",
00886 "Devel::BindPP",
00887 "sv");
00888 }
00889 }
00890 Int* Scalar::as_int() {
00891 if (SvIOKp(this->val)) {
00892 Int * s = new Int(this->val);
00893 CurCtx::get()->register_allocated(s);
00894 return s;
00895 } else {
00896 Perl_croak(aTHX_ "%s: %s is not a int",
00897 "Devel::BindPP",
00898 "sv");
00899 }
00900 }
00901 UInt* Scalar::as_uint() {
00902 if (SvIOK(this->val)) {
00903 UInt * s = new UInt(this->val);
00904 CurCtx::get()->register_allocated(s);
00905 return s;
00906 } else {
00907 Perl_croak(aTHX_ "%s: %s is not a uint",
00908 "Devel::BindPP",
00909 "sv");
00910 }
00911 }
00912 Double* Scalar::as_double() {
00913 if (SvNOK(this->val)) {
00914 Double * s = new Double(this->val);
00915 CurCtx::get()->register_allocated(s);
00916 return s;
00917 } else {
00918 Perl_croak(aTHX_ "%s: %s is not a double",
00919 "Devel::BindPP",
00920 "sv");
00921 }
00922 }
00923 Reference* Scalar::as_ref() {
00924 if (SvROK(this->val)) {
00925 Reference * obj = new Reference(this->val);
00926 CurCtx::get()->register_allocated(obj);
00927 return obj;
00928 } else {
00929 Perl_croak(aTHX_ "%s: %s is not a reference",
00930 "Devel::BindPP",
00931 "sv");
00932 }
00933 }
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943 Hash * Reference::as_hash() {
00944 if (SvROK(this->val) && SvTYPE(SvRV(this->val))==SVt_PVHV) {
00945 HV* h = (HV*)SvRV(this->val);
00946 Hash * hobj = new Hash(h);
00947 CurCtx::get()->register_allocated(hobj);
00948 return hobj;
00949 } else {
00950 Perl_croak(aTHX_ "%s: %s is not a hash reference",
00951 "Devel::BindPP",
00952 "hv");
00953 }
00954 }
00955 Array * Reference::as_array() {
00956 SV* v = this->val;
00957 if (SvROK(v) && SvTYPE(SvRV(v))==SVt_PVAV) {
00958 AV* a = (AV*)SvRV(v);
00959 Array * obj = new Array(a);
00960 CurCtx::get()->register_allocated(obj);
00961 return obj;
00962 } else {
00963 Perl_croak(aTHX_ "%s: %s is not a array reference",
00964 "Devel::BindPP",
00965 "av");
00966 }
00967 }
00968 Scalar * Reference::as_scalar() {
00969 SV* v = this->val;
00970 if (v && SvROK(v)) {
00971 SV* a = (SV*)SvRV(v);
00972 Scalar * obj = new Scalar(a);
00973 CurCtx::get()->register_allocated(obj);
00974 return obj;
00975 } else {
00976 Perl_croak(aTHX_ "%s: %s is not a array reference",
00977 "Devel::BindPP",
00978 "sv");
00979 }
00980 }
00981 Code * Reference::as_code() {
00982 SV* v = this->val;
00983 if (v && SvROK(v)) {
00984 SV* a = (SV*)SvRV(v);
00985 Code * obj = new Code(a);
00986 CurCtx::get()->register_allocated(obj);
00987 return obj;
00988 } else {
00989 Perl_croak(aTHX_ "%s: %s is not a array reference",
00990 "Devel::BindPP",
00991 "sv");
00992 }
00993 }
00994
00995 Reference* Hash::del(const char*key, I32 klen) {
00996 Reference * ref = new Reference(hv_delete((HV*)this->val, key, klen, 0));
00997 CurCtx::get()->register_allocated(ref);
00998 return ref;
00999 }
01000 template <class T>
01001 void Hash::store(const char*key, I32 klen, T value) {
01002 SV * v = Scalar::to_sv(value);
01003 SvREFCNT_inc_simple_void(v);
01004 hv_store((HV*)this->val, key, klen, v, 0);
01005 }
01006 Scalar* Hash::scalar() {
01007 Scalar*s = new Scalar(hv_scalar((HV*)this->val));
01008 CurCtx::get()->register_allocated(s);
01009 return s;
01010 }
01011 void Hash::undef() {
01012 hv_undef((HV*)this->val);
01013 }
01014 void Hash::clear() {
01015 hv_clear((HV*)this->val);
01016 }
01017 Boolean* Boolean::yes() {
01018 Boolean* s = new Boolean(true);
01019 CurCtx::get()->register_allocated(s);
01020 return s;
01021 }
01022 Boolean* Boolean::no() {
01023 Boolean* s = new Boolean(false);
01024 CurCtx::get()->register_allocated(s);
01025 return s;
01026 }
01027
01028 Scalar* Scalar::create(SV* s) {
01029 Scalar * v = new Scalar(s);
01030 CurCtx::get()->register_allocated(v);
01031 return v;
01032 }
01033 };