diff options
Diffstat (limited to 'PerlQt/smokeperl.cpp')
-rw-r--r-- | PerlQt/smokeperl.cpp | 426 |
1 files changed, 0 insertions, 426 deletions
diff --git a/PerlQt/smokeperl.cpp b/PerlQt/smokeperl.cpp deleted file mode 100644 index 1998c85..0000000 --- a/PerlQt/smokeperl.cpp +++ /dev/null @@ -1,426 +0,0 @@ -#include "smokeperl.h" - -class SmokePerlTQt : public SmokePerl { -public: - SmokePerlTQt(); - virtual ~SmokePerlTQt(); - - void registerSmoke(const char *name, Smoke *smoke); - Smoke *getSmoke(const char *name); - - void registerHandlers(TypeHandler *h); - - SmokeObject newObject(void *p, const SmokeClass &c); - SmokeObject wrapObject(void *p, const SmokeClass &c); - SmokeObject getObject(void *p); - SmokeObject getObject(SV *sv); - -private: - HV *_registered_smoke; - HV *_registered_handlers; - HV *_remembered_pointers; - - void rememberPointer(SmokeObject &o, const SmokeClass &c, bool remember, void *lastptr = 0); - void rememberPointer(SmokeObject &o); - void forgetPointer(SmokeObject &o); - SmokeObject createObject(void *p, const SmokeClass &c); - - const char *getSmokeName(Smoke *smoke) { - static const char none[] = ""; - HE *he; - - hv_iterinit(_registered_smoke); - while(he = hv_iternext(_registered_smoke)) { - SV *sv = hv_iterval(_registered_smoke, he); - if((Smoke*)SvIV(sv) == smoke) { - I32 toss; - return hv_iterkey(he, &toss); - } - } - return none; - } - - HV *package(const SmokeClass &c) { - // for now, we cheat on the class names by assuming they're all TQt:: - if(!strcmp(c.className(), "TQt")) - return gv_stashpv(c.className(), TRUE); - - SV *name = newSVpv("TQt::", 0); - sv_catpv(name, c.className() + 1); - HV *stash = gv_stashpv(SvPV_nolen(name), TRUE); - SvREFCNT_dec(name); - - return stash; - } -}; - - -Marshall::HandlerFn getMarshallFn(const SmokeType &type); - -class VirtualMethodReturnValue : public Marshall { - Smoke *_smoke; - Smoke::Index _method; - Smoke::Stack _stack; - SmokeType _st; - SV *_retval; -public: - const Smoke::Method &method() { return _smoke->methods[_method]; } - SmokeType type() { return _st; } - Marshall::Action action() { return Marshall::FromSV; } - Smoke::StackItem &item() { return _stack[0]; } - SV *var() { return _retval; } - void unsupported() { - croak("Cannot handle '%s' as return-type of virtual method %s::%s", - type().name(), - _smoke->className(method().classId), - _smoke->methodNames[method().name]); - } - Smoke *smoke() { return _smoke; } - void next() {} - bool cleanup() { return false; } - VirtualMethodReturnValue(Smoke *smoke, Smoke::Index meth, Smoke::Stack stack, SV *retval) : - _smoke(smoke), _method(meth), _stack(stack), _retval(retval) { - _st.set(_smoke, method().ret); - Marshall::HandlerFn fn = getMarshallFn(type()); - (*fn)(this); - } -}; - -extern SV *sv_this; -extern void *_current_object; -extern Smoke::Index _current_object_class; -extern int object_count; -extern bool temporary_virtual_function_success; -extern struct mgvtbl vtbl_smoke; - -class VirtualMethodCall : public Marshall { - Smoke *_smoke; - Smoke::Index _method; - Smoke::Stack _stack; - GV *_gv; - int _cur; - Smoke::Index *_args; - SV **_sp; - bool _called; - SV *_savethis; - -public: - SmokeType type() { return SmokeType(_smoke, _args[_cur]); } - Marshall::Action action() { return Marshall::ToSV; } - Smoke::StackItem &item() { return _stack[_cur + 1]; } - SV *var() { return _sp[_cur]; } - const Smoke::Method &method() { return _smoke->methods[_method]; } - void unsupported() { - croak("Cannot handle '%s' as argument of virtual method %s::%s", - type().name(), - _smoke->className(method().classId), - _smoke->methodNames[method().name]); - } - Smoke *smoke() { return _smoke; } - void callMethod() { - dSP; - if(_called) return; - _called = true; - SP = _sp + method().numArgs - 1; - PUTBACK; - int count = call_sv((SV*)_gv, G_SCALAR); - SPAGAIN; - VirtualMethodReturnValue r(_smoke, _method, _stack, POPs); - PUTBACK; - FREETMPS; - LEAVE; - } - void next() { - int oldcur = _cur; - _cur++; - while(!_called && _cur < method().numArgs) { - Marshall::HandlerFn fn = getMarshallFn(type()); - _sp[_cur] = sv_newmortal(); - (*fn)(this); - _cur++; - } - callMethod(); - _cur = oldcur; - } - bool cleanup() { return false; } // is this right? - VirtualMethodCall(Smoke *smoke, Smoke::Index meth, Smoke::Stack stack, SV *obj, GV *gv) : - _smoke(smoke), _method(meth), _stack(stack), _gv(gv), _cur(-1), _sp(0), _called(false) { - dSP; - ENTER; - SAVETMPS; - PUSHMARK(SP); - EXTEND(SP, method().numArgs); - _savethis = sv_this; - sv_this = newSVsv(obj); - _sp = SP + 1; - for(int i = 0; i < method().numArgs; i++) - _sp[i] = sv_newmortal(); - _args = _smoke->argumentList + method().args; - } - ~VirtualMethodCall() { - SvREFCNT_dec(sv_this); - sv_this = _savethis; - } -}; - -class MethodReturnValue : public Marshall { - Smoke *_smoke; - Smoke::Index _method; - SV *_retval; - Smoke::Stack _stack; -public: - MethodReturnValue(Smoke *smoke, Smoke::Index method, Smoke::Stack stack, SV *retval) : - _smoke(smoke), _method(method), _retval(retval), _stack(stack) { - Marshall::HandlerFn fn = getMarshallFn(type()); - (*fn)(this); - } - const Smoke::Method &method() { return _smoke->methods[_method]; } - SmokeType type() { return SmokeType(_smoke, method().ret); } - Marshall::Action action() { return Marshall::ToSV; } - Smoke::StackItem &item() { return _stack[0]; } - SV *var() { return _retval; } - void unsupported() { - croak("Cannot handle '%s' as return-type of %s::%s", - type().name(), - _smoke->className(method().classId), - _smoke->methodNames[method().name]); - } - Smoke *smoke() { return _smoke; } - void next() {} - bool cleanup() { return false; } -}; - -class MethodCall : public Marshall { - int _cur; - Smoke *_smoke; - Smoke::Stack _stack; - Smoke::Index _method; - Smoke::Index *_args; - SV **_sp; - int _items; - SV *_retval; - bool _called; -public: - MethodCall(Smoke *smoke, Smoke::Index method, SV **sp, int items) : - _smoke(smoke), _method(method), _sp(sp), _items(items), _cur(-1), _called(false) { - _args = _smoke->argumentList + _smoke->methods[_method].args; - _items = _smoke->methods[_method].numArgs; - _stack = new Smoke::StackItem[items + 1]; - _retval = newSV(0); - } - ~MethodCall() { - delete[] _stack; - SvREFCNT_dec(_retval); - } - SmokeType type() { return SmokeType(_smoke, _args[_cur]); } - Marshall::Action action() { return Marshall::FromSV; } - Smoke::StackItem &item() { return _stack[_cur + 1]; } - SV *var() { - if(_cur < 0) return _retval; - SvGETMAGIC(*(_sp + _cur)); - return *(_sp + _cur); - } - inline const Smoke::Method &method() { return _smoke->methods[_method]; } - void unsupported() { - croak("Cannot handle '%s' as argument to %s::%s", - type().name(), - _smoke->className(method().classId), - _smoke->methodNames[method().name]); - } - Smoke *smoke() { return _smoke; } - inline void callMethod() { - if(_called) return; - _called = true; - Smoke::ClassFn fn = _smoke->classes[method().classId].classFn; - void *ptr = _smoke->cast( - _current_object, - _current_object_class, - method().classId - ); - _items = -1; - (*fn)(method().method, ptr, _stack); - MethodReturnValue r(_smoke, _method, _stack, _retval); - } - void next() { - int oldcur = _cur; - _cur++; - - while(!_called && _cur < _items) { - Marshall::HandlerFn fn = getMarshallFn(type()); - (*fn)(this); - _cur++; - } - - callMethod(); - _cur = oldcur; - } - bool cleanup() { return true; } -}; - -class SmokeBindingTQt : public SmokeBinding { - SmokePerlTQt *_smokeperl; -public: - SmokeBindingTQt(Smoke *s, SmokePerlTQt *smokeperl) : - SmokeBinding(s), _smokeperl(smokeperl) {} - void deleted(Smoke::Index classId, void *ptr) { - if(do_debug) printf("%p->~%s()\n", ptr, smoke->className(classId)); - object_count--; - if(do_debug) printf("Remaining objects: %d\n", object_count); - SV *obj = getPointerObject(ptr); - smokeperl_object *o = sv_obj_info(obj); - if(!o || !o->ptr) { - return; - } - unmapPointer(o, o->classId, 0); - o->ptr = 0; - } - bool callMethod(Smoke::Index method, void *ptr, Smoke::Stack args, bool isAbstract) { - SV *obj = getPointerObject(ptr); - smokeperl_object *o = sv_obj_info(obj); - if(do_debug) printf("virtual %p->%s::%s() called\n", ptr, - smoke->classes[smoke->methods[method].classId].className, - smoke->methodNames[smoke->methods[method].name] - ); - - if(!o) { - if(!PL_dirty) // if not in global destruction - warn("Cannot find object for virtual method"); - return false; - } - HV *stash = SvSTASH(SvRV(obj)); - if(*HvNAME(stash) == ' ') - stash = gv_stashpv(HvNAME(stash) + 1, TRUE); - const char *methodName = smoke->methodNames[smoke->methods[method].name]; - GV *gv = gv_fetchmethod_autoload(stash, methodName, 0); - if(!gv) return false; - - VirtualMethodCall c(smoke, method, args, obj, gv); - // exception variable, just temporary - temporary_virtual_function_success = true; - c.next(); - bool ret = temporary_virtual_function_success; - temporary_virtual_function_success = true; - return ret; - } - char *className(Smoke::Index classId) { - const char *className = smoke->className(classId); - char *buf = new char[strlen(className) + 6]; - strcpy(buf, " TQt::"); - strcat(buf, className + 1); - return buf; - } -}; - -SmokePerlTQt::SmokePerlTQt() { - _registered_smoke = newHV(); - _registered_handlers = newHV(); - _remembered_pointers = newHV(); -} - -SmokePerlTQt::~SmokePerlTQt() { - SvREFCNT_dec((SV*)_registered_smoke); - SvREFCNT_dec((SV*)_registered_handlers); - SvREFCNT_dec((SV*)_remembered_pointers); -} - -void SmokePerlTQt::registerSmoke(const char *name, Smoke *smoke) { - hv_store(_registered_smoke, name, strlen(name), newSViv((IV)smoke), 0); - - // This will also need to handle the per-class initialization - smoke->binding = new SmokeBindingTQt(smoke, this); -} - -Smoke *SmokePerlTQt::getSmoke(const char *name) { - SV **svp = hv_fetch(_registered_smoke, name, strlen(name), 0); - if(svp && SvOK(*svp)) - return (Smoke*)SvIV(*svp); - return 0; -} - -void SmokePerlTQt::registerHandlers(TypeHandler *h) { - while(h->name) { - hv_store(_registered_handlers, h->name, strlen(h->name), newSViv((IV)h->fn), 0); - h++; - } -} - -SmokeObject SmokePerlTQt::createObject(void *p, const SmokeClass &c) { - HV *hv = newHV(); - SV *obj = newRV_noinc((SV*)hv); - - Smoke_MAGIC m(p, c); - sv_magic((SV*)hv, (SV*)newAV(), '~', (char*)&m, sizeof(m)); - MAGIC *mg = mg_find((SV*)hv, '~'); - mg->mg_virtual = &vtbl_smoke; - - sv_bless(obj, package(c)); - - SmokeObject o(obj, (Smoke_MAGIC*)mg->mg_ptr); - SvREFCNT_dec(obj); - - if(c.hasVirtual()) - rememberPointer(o); - - return o; -} - -SmokeObject SmokePerlTQt::newObject(void *p, const SmokeClass &c) { - SmokeObject o = createObject(p, c); - - if(c.isVirtual()) - rememberPointer(o); - o.setAllocated(true); - - return o; -} - -SmokeObject SmokePerlTQt::wrapObject(void *p, const SmokeClass &c) { - SmokeObject o = createObject(p, c); - return o; -} - -void SmokePerlTQt::rememberPointer(SmokeObject &o, const SmokeClass &c, bool remember, void *lastptr) { - void *ptr = o.cast(c); - if(ptr != lastptr) { - SV *keysv = newSViv((IV)o.ptr()); - STRLEN klen; - char *key = SvPV(keysv, klen); - - if(remember) - hv_store(_remembered_pointers, key, klen, - sv_rvweaken(newSVsv(o.var())), 0); - else - hv_delete(_remembered_pointers, key, klen, G_DISCARD); - - SvREFCNT_dec(keysv); - } - for(Smoke::Index *i = c.smoke()->inheritanceList + c.c().parents; - *i; - i++) - rememberPointer(o, SmokeClass(c.smoke(), *i), remember, ptr); -} - -void SmokePerlTQt::rememberPointer(SmokeObject &o) { - rememberPointer(o, o.c(), true); -} - -void SmokePerlTQt::forgetPointer(SmokeObject &o) { - rememberPointer(o, o.c(), false); -} - -SmokeObject SmokePerlTQt::getObject(SV *sv) { - MAGIC *mg = mg_find(SvRV(sv), '~'); - Smoke_MAGIC *m = (Smoke_MAGIC*)mg->mg_ptr; - return SmokeObject(sv, m); -} - -SmokeObject SmokePerlTQt::getObject(void *p) { - SV *keysv = newSViv((IV)p); - STRLEN klen; - char *key = SvPV(keysv, klen); - SV **svp = hv_fetch(_remembered_pointers, key, klen, 0); - if(svp && SvROK(*svp)) - return getObject(sv_2mortal(newRV(SvRV(*svp)))); // paranoid copy of a weak ref - return SmokeObject(&PL_sv_undef, 0); -} - |