Revision: 582
http://rpy.svn.sourceforge.net/rpy/?rev=582&view=rev
Author: lgautier
Date: 2008-07-21 16:05:10 +0000 (Mon, 21 Jul 2008)
Log Message:
-----------
- Fixed missing R_PreserveObject for vectors (cause them to sometimes vanish
at garbage collection)
- split control of debugging output into several definitions RPY_DEBUG_*
- one new method for Sexp_Type: named (wraps R's C-level NAMED)
- two new experimental methods for EnvironmentSexp_Type (frame and enclos)
Modified Paths:
--------------
branches/rpy_nextgen/rpy/rinterface/rinterface.c
Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.c
===================================================================
--- branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-07-21 15:59:21 UTC
(rev 581)
+++ branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-07-21 16:05:10 UTC
(rev 582)
@@ -123,10 +123,10 @@
static unsigned int embeddedR_status = 0;
static PyObject *embeddedR_isInitialized;
-inline void embeddedR_setlock() {
+inline void embeddedR_setlock(void) {
embeddedR_status = embeddedR_status | RPY_R_BUSY;
}
-inline void embeddedR_freelock() {
+inline void embeddedR_freelock(void) {
embeddedR_status = embeddedR_status ^ RPY_R_BUSY;
}
@@ -361,19 +361,22 @@
{
RPY_DECREF(self);
#ifdef RPY_VERBOSE
- printf("Python:%p / R:%p -- sexp count is %i\n",
+ printf("Python:%p / R:%p -- sexp count is %i...",
self, RPY_SEXP(self), RPY_COUNT(self));
#endif
if ((RPY_COUNT(self) == 0) && RPY_SEXP(self)) {
#ifdef RPY_VERBOSE
- printf("freeing SEXP resources...\n");
+ printf("freeing SEXP resources...");
#endif
if (RPY_SEXP(self) != R_NilValue) {
- R_ReleaseObject(RPY_SEXP(self));
+#ifdef RPY_DEBUG_PRESERVE
+ printf(" Sexp_clear: R_ReleaseObject( %p )\n", RPY_SEXP(self));
+#endif
+ R_ReleaseObject(RPY_SEXP(self));
}
- free(self->sObj);
+ PyMem_Free(self->sObj);
////self->ob_type->tp_free((PyObject*)self);
#ifdef RPY_VERBOSE
printf("done.\n");
@@ -412,7 +415,8 @@
static PyObject*
Sexp_typeof(PyObject *self)
{
- SEXP sexp = RPY_SEXP(((PySexpObject*)self));
+ PySexpObject *pso = (PySexpObject*)self;
+ SEXP sexp = RPY_SEXP(pso);
if (! sexp) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
return NULL;;
@@ -450,9 +454,24 @@
PyDoc_STRVAR(Sexp_do_slot_doc,
"\n\
Returns the attribute/slot for an R object.\n\
-The name of the slot as a string is the only parameter for\
+The name of the slot (a string) is the only parameter for\
the method.\n");
+static PyObject*
+Sexp_named(PyObject *self)
+{
+ SEXP sexp = RPY_SEXP(((PySexpObject*)self));
+ if (! sexp) {
+ PyErr_Format(PyExc_ValueError, "NULL SEXP.");
+ return NULL;;
+ }
+ unsigned int res = NAMED(sexp);
+ return PyInt_FromLong((long)res);
+}
+PyDoc_STRVAR(Sexp_named_doc,
+"Return the integer code for the R object reference-pseudo counting.\n\
+This method corresponds to the macro NAMED.\n\
+See the R-extensions manual for further details.");
static PyMethodDef Sexp_methods[] = {
@@ -460,6 +479,8 @@
Sexp_typeof_doc},
{"do_slot", (PyCFunction)Sexp_do_slot, METH_O,
Sexp_do_slot_doc},
+ {"named", (PyCFunction)Sexp_named, METH_NOARGS,
+ Sexp_named_doc},
{NULL, NULL} /* sentinel */
};
@@ -486,7 +507,7 @@
if (! self)
PyErr_NoMemory();
- self->sObj = (SexpObject *)calloc(1, sizeof(SexpObject));
+ self->sObj = (SexpObject *)PyMem_Malloc(1 * sizeof(SexpObject));
if (! self->sObj) {
Py_DECREF(self);
PyErr_NoMemory();
@@ -560,7 +581,7 @@
printf("done.\n");
#endif
-
+ //SET_NAMED(RPY_SEXP((PySexpObject *)self), (unsigned int)2);
return 0;
}
@@ -626,6 +647,7 @@
/* Evaluate a SEXP. It must be constructed by hand. It raises a Python
exception if an error ocurred in the evaluation */
SEXP do_eval_expr(SEXP expr_R, SEXP env_R) {
+
SEXP res_R = NULL;
int error = 0;
PyOS_sighandler_t old_int;
@@ -727,6 +749,7 @@
goto fail;
}
tmp_R = RPY_SEXP((PySexpObject *)tmp_obj);
+ //tmp_R = Rf_duplicate(tmp_R);
if (! tmp_R) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
Py_DECREF(tmp_obj);
@@ -769,6 +792,8 @@
}
Py_DECREF(tmp_obj);
tmp_R = RPY_SEXP((PySexpObject *)argValue);
+ //SET_NAMED(tmp_R, 2);
+ //tmp_R = Rf_duplicate(tmp_R);
if (! tmp_R) {
PyErr_Format(PyExc_ValueError, "NULL SEXP.");
Py_DECREF(tmp_obj);
@@ -779,6 +804,7 @@
argNameString = PyString_AsString(argName);
SET_TAG(c_R, install(argNameString));
//printf("PyMem_Free...");
+ //FIXME: probably memory leak with argument names.
//PyMem_Free(argNameString);
c_R = CDR(c_R);
}
@@ -1219,6 +1245,10 @@
//(RPy has something)... or leave it to extensions ?
RPY_SEXP((PySexpObject *)self) = newSEXP(object, sexptype);
+ #ifdef RPY_DEBUG_OBJECTINIT
+ printf(" SEXP vector is %p.\n", RPY_SEXP((PySexpObject *)self));
+ #endif
+ //SET_NAMED(RPY_SEXP((PySexpObject *)self), 2);
} else {
PyErr_Format(PyExc_ValueError, "Invalid sexpvector.");
return -1;
@@ -1285,9 +1315,37 @@
"The optional parameter `wantFun` indicates whether functions
should be\n"
"returned or not.");
+static PyObject*
+EnvironmentSexp_frame(PyObject *self)
+{
+ SEXP res_R = NULL;
+ PySexpObject *res;
+ res_R = FRAME(RPY_SEXP((PySexpObject *)self));
+ res = newPySexpObject(res_R);
+ return (PyObject *)res;
+}
+PyDoc_STRVAR(EnvironmentSexp_frame_doc,
+ "Return the frame the environment is in.");
+
+static PyObject*
+EnvironmentSexp_enclos(PyObject *self)
+{
+ SEXP res_R = NULL;
+ PySexpObject *res;
+ res_R = ENCLOS(RPY_SEXP((PySexpObject *)self));
+ res = newPySexpObject(res_R);
+ return (PyObject *)res;
+}
+PyDoc_STRVAR(EnvironmentSexp_enclos_doc,
+ "Return the enclosure the environment is in.");
+
static PyMethodDef EnvironmentSexp_methods[] = {
{"get", (PyCFunction)EnvironmentSexp_findVar, METH_VARARGS | METH_KEYWORDS,
EnvironmentSexp_findVar_doc},
+ {"frame", (PyCFunction)EnvironmentSexp_frame, METH_NOARGS,
+ EnvironmentSexp_frame_doc},
+ {"enclos", (PyCFunction)EnvironmentSexp_frame, METH_NOARGS,
+ EnvironmentSexp_enclos_doc},
{NULL, NULL} /* sentinel */
};
@@ -1567,12 +1625,19 @@
if (TYPEOF(sexp) == PROMSXP) {
env_R = PRENV(sexp);
sexp_ok = eval(sexp, env_R);
+#ifdef RPY_DEBUG_PROMISE
+ printf(" evaluating promise %p into %p.\n", sexp, sexp_ok);
+#endif
}
else {
sexp_ok = sexp;
}
- if (sexp_ok)
+ if (sexp_ok) {
R_PreserveObject(sexp_ok);
+#ifdef RPY_DEBUG_PRESERVE
+ printf(" R_PreserveObject( %p ).\n", sexp_ok);
+#endif
+ }
switch (TYPEOF(sexp_ok)) {
case CLOSXP:
@@ -1600,6 +1665,9 @@
break;
}
if (!object) {
+#ifdef RPY_DEBUG_PRESERVE
+ printf(" R_ReleaseObject( %p )\n", sexp_ok);
+#endif
R_ReleaseObject(sexp_ok);
PyErr_NoMemory();
return NULL;
@@ -1724,10 +1792,15 @@
PyErr_Format(PyExc_ValueError, "Cannot handle type %d", rType);
sexp = NULL;
}
+
+ R_PreserveObject(sexp);
+#ifdef RPY_DEBUG_PRESERVE
+ printf(" R_PreserveObject( %p ).\n", sexp);
+#endif
UNPROTECT(1);
#ifdef RPY_VERBOSE
printf(" new SEXP for Python:%p is %p.\n", object, sexp);
-#endif
+#endif
return sexp;
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
rpy-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rpy-list