Commits

Anonymous committed 845ec47

add PerlMethodObject

  • Participants
  • Parent commits d861d92

Comments (0)

Files changed (6)

 def pyclass_name(name):
     return name.replace("::", "_")
 
+
 class Perl(Interpreter):
     
 

File src/_interp.c

 PyDoc_STRVAR(perl_eval_doc, "");
 
 PyObject *
-call_perlcall(Perl_Object *self, SV *ref, char *methodname, I32 gimme, PyObject *args)
+call_perlcall(Perl_Object *self, SV *ref, char *method_name, I32 gimme, PyObject *args)
 {
     PyObject *res, *name;
     int i, retcnt, arglen, errsv;
     SAVETMPS;
     PUSHMARK(SP);
 
-    if(methodname){
+    if(method_name){
         //PyObject *fo = PyTuple_GET_ITEM(args, 0);
         if(!ref){
             //ctor classname
     }
 
     PUTBACK; 
-    if(methodname){
+    if(method_name){
 	    //char *methodname = PyString_AS_STRING(name);
         //printf("call method :%s\n", methodname);
-        retcnt = call_method(methodname, gimme|G_EVAL);
+        retcnt = call_method(method_name, gimme|G_EVAL);
     }else{
         name  = PyTuple_GetItem(args, 0);
         SV *sv = py2sv(self, name);
     return call_perlcall(self, 0, PyString_AS_STRING(name), G_SCALAR, args); 
 }
 
+static PyObject *
+perl_callctor(Perl_Object *self, PyObject *args)
+{
+    dPCTX;
+    PyObject *res;
+    PyObject *name;
+    PyObject *module;
+    //TODO len check
+    name  = PyTuple_GetItem(args, 0);
+    module  = PyTuple_GetItem(args, 1);
+    
+    //SV *sv = py2sv(self, name);
+    res = call_perlcall(self, 0, PyString_AS_STRING(name), G_SCALAR, args); 
+    set_perlmethods((PySvRV_Object *)res, PyString_AS_STRING(module));
+    return res;
+}
+
 PyDoc_STRVAR(perl_callm_doc, "");
 
 PyObject * 
 PyDoc_STRVAR(perl_require_doc, "");
 
 static PyObject *
-perl_get_methodsnames(Perl_Object *self, PyObject *args)
+perl_getmethodnames(Perl_Object *self, PyObject *args)
 {
     char *module;
+    if (!PyArg_ParseTuple(args, "s:Perl.get_methodnames", &module))
+	    return NULL;
+    return get_methodnames(self, module);
+}
+
+PyObject * 
+get_methodnames(Perl_Object *self, char *module)
+{
     HV *stash;
     HE *entry;
     PyObject *res;
 
     dPCTX;
-    if (!PyArg_ParseTuple(args, "s:Perl.get_methodnames", &module))
-	    return NULL;
     
     res = PyList_New(0);
     stash = gv_stashpv(module, FALSE);
     {"eval", (PyCFunction)perl_eval, METH_VARARGS, perl_eval_doc},
     {"call", (PyCFunction)perl_call, METH_VARARGS, perl_call_doc},
     {"call_method", (PyCFunction)perl_callm, METH_VARARGS, perl_callm_doc},
+    {"call_ctor", (PyCFunction)perl_callctor, METH_VARARGS, perl_callm_doc},
     {"require", (PyCFunction)perl_require, METH_VARARGS, perl_require_doc},
-    {"get_methodnames", (PyCFunction)perl_get_methodsnames, METH_VARARGS, perl_get_methodsnames_doc},
+    {"get_methodnames", (PyCFunction)perl_getmethodnames, METH_VARARGS, perl_get_methodsnames_doc},
     {NULL, NULL},
 
 };
 
 static PyTypeObject Perl_Type = {
-	PyVarObject_HEAD_INIT(&PyType_Type, 0)
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_perl.Interpreter",					/* tp_name */
 	sizeof(Perl_Object),				/* tp_basicsize */
 	0,						/* tp_itemsize */
 	if (PyType_Ready(&Perl_Type) < 0)
 		return;
 
+
 	Py_INCREF(&Perl_Type);
 	PyModule_AddObject(m, "Interpreter", (PyObject *) &Perl_Type);
     
-    RefType_Ready(&PySvRV_Type);
 
 }

File src/_interp.h

 PyObject *
 call_perlcall(Perl_Object *self, SV *ref, char *methodname, I32 gimme, PyObject *args);
 
+
+PyObject *
+get_methodnames(Perl_Object *self, char *module);
+
 #include "_interp.h"
 #include "svrv.h"
 
-int
-add_perlmethod(PySvRV_Object *self, PyObject *list);
+//int
+//add_perlmethod(PySvRV_Object *self, PyObject *list);
 
-//PyTypeObject PySvRV_Type;
-static PyObject*
+/*
+static pyobject*
 svrv_getattr(PySvRV_Object *self, char *name)
 {   
     PyObject *val;
 	
     return val;
 }
+*/
 
 
 PyObject * 
 newSvRV_Object(Perl_Object *obj, SV *sv)
 {
     PySvRV_Object *self;
+    PyObject *dict;
 
     PerlInterpreter *my_perl;
     my_perl = obj->perl;
     
     if (self == NULL)
 	   return NULL;
-    if(add_perlmethod(self, NULL) < 0){
-        Py_DECREF(self);
-        return NULL;
-    }
     self->sv = SvREFCNT_inc(sv);
     self->interp = obj;
     Py_INCREF(self->interp);
+    dict = PyDict_New();
+    self->ref_dict = dict;
     return (PyObject *)self;
 }
 
+static PyObject * 
+svrv_getattr(PySvRV_Object *self, PyObject *name)
+{   
+    PyObject *val;
+	register char *sname = PyString_AsString(name);
+    //printf("getattr : %s\n", name);
+    if (strcmp(sname, "__dict__") == 0) {
+	    Py_INCREF(self->ref_dict);
+        val = self->ref_dict;
+    }
+	
+    return val;
+}
+
 static void
 svrv_dealloc(PySvRV_Object *self)
 {
     Py_DECREF(self->interp);
 }
 
-static PyObject*
-call_perlmethod(PySvRV_Object *self, PyObject *args)
+
+static PyObject *
+newPerlMethod(PySvRV_Object *svrv, char *method)
+{
+    PerlMethod_Object *self;
+    self = PyObject_NEW(PerlMethod_Object, &PerlMethod_Type);
+    
+    if (self == NULL)
+	   return NULL;
+
+    Py_INCREF(svrv);
+    self->ref = svrv;
+    self->method = method;
+    return (PyObject *)self;
+}
+
+static PyObject * 
+perlmethod_call(PerlMethod_Object *self, PyObject *args, PyObject *kw)
 {
     PyObject *res;
+    PySvRV_Object *svrv;
+    svrv = self->ref;
+    res = call_perlcall(svrv->interp, (SV*)svrv->sv, (char*)self->method, G_SCALAR, args);
+    return res;
+}
 
-    res = call_perlcall(self->interp, (SV*)self->sv, (char*)self->method, G_SCALAR, args);
-    return res;    
+static void
+perlmethod_dealloc(PerlMethod_Object *self)
+{
+    
+    PyObject_DEL(self);
+    Py_DECREF(self->ref);
 }
 
 int
-add_perlmethod(PySvRV_Object *self, PyObject *list)
+add_perlmethods(PySvRV_Object *self, PyObject *list)
 {
     PyObject *dict;
-    dict = self->ob_type->tp_dict;
+    Py_ssize_t i;
+    dict = self->ref_dict;
     if(dict){
-        /*
-        PyMethodDef def = {"test", (PyCFunction)call_perlmethod, METH_VARARGS, NULL};
-        PyObject *descr = PyDescr_NewMethod(self->ob_type, &def);
+        i = PyList_GET_SIZE(list);
+        while(--i >= 0){
+            PyObject *n = PyList_GET_ITEM(list, i);
+            char *method_name = PyString_AS_STRING(n);
+            PerlMethod_Object *perlmethod;
+            
+            perlmethod = newPerlMethod(self, method_name);
+            if(perlmethod == NULL)
+                return -1;
 
-	    PyDict_SetItemString(dict, "hoge", PyString_FromString("hoge"));
-	    if (PyDict_SetItemString(dict, "test", descr) < 0)
-            printf("miss\n");
-	        return -1;
-        */
+            if(PyDict_SetItemString(dict, method_name, (PyObject *)perlmethod) < 0)
+                return -1;
+            
+        }
+        // PerlMethod_Object meth = new
+	    //PyDict_SetItemString(dict, "hoge", PyString_FromString("hoge"));
+        //PyMethodDef method = {"aaaa", (PyCFunction)test_meth, METH_VARARGS, NULL};
+        //self->m = method;
+    	//PyMethodDescrObject *descr;
+        //descr = PyDescr_NewMethod(self->ob_type, &(self->m));
+        //descr = PyDescr_NewMethod(self->ob_type, &method);
+
+        //if (PyDict_SetItemString(dict, "test", (PyObject *)descr) < 0){
+        //    printf("miss\n");
+	    //    return -1;
+        //}
+        //Py_DECREF(descr);
+    }
+    return 1;
+}
+
+int
+set_perlmethods(PySvRV_Object *self, char *module)
+{
+    SV *sv;
+    PyObject *list;
+    sv = self->sv;
+    if(SvOBJECT(SvRV(sv))){
+        //printf("is object %s\n", module);
+        list = get_methodnames(self->interp, module);
+        return add_perlmethods(self, list);
     }
     return 1;
 }
 
 PyTypeObject PySvRV_Type = {
-	//PyVarObject_HEAD_INIT(&PyBaseObject_Type, 0)
 	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"ref",					/* tp_name */
 	sizeof(PySvRV_Object),				/* tp_basicsize */
 	0,						/* tp_itemsize */
 	(destructor)svrv_dealloc,			/* tp_dealloc */
 	0,						/* tp_print */
-	0,/*(getattrfunc)svrv_getattr,*/						/* tp_getattr */
+	0,                      /* tp_getattr */
 	0,						/* tp_setattr */
 	0,						/* tp_compare */
 	0,						/* tp_repr */
 	0,						/* tp_hash */
 	0,              				/* tp_call */
 	0,						/* tp_str */
-	PyObject_GenericGetAttr,			/* tp_getattro */
+	(getattrofunc)svrv_getattr,			/* tp_getattro */
 	0,						/* tp_setattro */
 	0,						/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,				/* tp_flags */
+	Py_TPFLAGS_DEFAULT ,				/* tp_flags */
 	0,					/* tp_doc */
 	0,						/* tp_traverse */
 	0,						/* tp_clear */
 	0,						/* tp_free */
 };
 
-void 
+PyTypeObject PerlMethod_Type = {
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
+	"perl method",					/* tp_name */
+	sizeof(PerlMethod_Object),				/* tp_basicsize */
+	0,						/* tp_itemsize */
+	(destructor)perlmethod_dealloc,			/* tp_dealloc */
+	0,						/* tp_print */
+	0,                      /* tp_getattr */
+	0,						/* tp_setattr */
+	0,						/* tp_compare */
+	0,						/* tp_repr */
+	0,						/* tp_as_number */
+	0,						/* tp_as_sequence */
+	0,						/* tp_as_mapping */
+	0,						/* tp_hash */
+	perlmethod_call,              		/* tp_call */
+	0,						/* tp_str */
+	0,			/* tp_getattro */
+	0,						/* tp_setattro */
+	0,						/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT ,				/* tp_flags */
+	0,					/* tp_doc */
+	0,						/* tp_traverse */
+	0,						/* tp_clear */
+	0,						/* tp_richcompare */
+	0,						/* tp_weaklistoffset */
+	0,						/* tp_iter */
+	0,						/* tp_iternext */
+    0,  				/* tp_methods */
+	0,						/* tp_members */
+	0, 				/* tp_getset */
+	0,						/* tp_base */
+	0,						/* tp_dict */
+	0,						/* tp_descr_get */
+	0,						/* tp_descr_set */
+	0,						/* tp_dictoffset */
+	0,						/* tp_init */
+	0,						/* tp_alloc */
+	0,					/* tp_new */
+	0,						/* tp_free */
+};
+
+/*
+int  
 RefType_Ready(PyTypeObject *type){
-    PyType_Ready(type);
+	//Py_TYPE(&PySvRV_Type) = &PyType_Type;
+    if(PyType_Ready(type) < 0)
+        return -1;
     type->tp_init = 0;
     type->tp_alloc = 0;
     type->tp_new = 0;
     type->tp_free = 0;
+    return 1;
 }
+*/
 
-
     PyObject_HEAD
     SV *sv;
     Perl_Object *interp;
+    PyObject *ref_dict;
     char *method;
 } PySvRV_Object;
 
+typedef struct {
+    PyObject_HEAD
+    PySvRV_Object *ref;
+    char *method;
+} PerlMethod_Object;
 
 extern PyTypeObject PySvRV_Type;
+extern PyTypeObject PerlMethod_Type;
 
 
 #define PySvRV_Check(v)  ((v)->ob_type == &PySvRV_Type)
 
 PyObject *newSvRV_Object(Perl_Object *obj, SV *sv);
 
-void RefType_Ready(PyTypeObject *type);
+//int RefType_Ready(PyTypeObject *type);
 

File tests/test_perl.py

 import util 
-
 from perlpy import Perl
 
 def test_perl():
 def test_new():
     p = Perl()
     p.require("LWP::UserAgent")
-    ua1 = p.call_method("new", "LWP::UserAgent")
+    ua1 = p.call_ctor("new", "LWP::UserAgent")
+    ua2 = p.call_ctor("new", "LWP::UserAgent")
+    ua3 = p.call_ctor("new", "LWP::UserAgent")
     assert ua1 != None
-    #print ua1.test
-    #print ua1.hoge
+    print ua1.__dict__
     #print dir(ua1)
     #print type(ua1)
     #print locals()
 if __name__ == '__main__':
     #test_evalcall()
     test_new()
+
     #test_get_methodnames()