summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/modules/python
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sca-cpp/trunk/modules/python/Makefile.am4
-rw-r--r--sca-cpp/trunk/modules/python/driver.hpp8
-rw-r--r--sca-cpp/trunk/modules/python/eval.hpp204
-rw-r--r--sca-cpp/trunk/modules/python/mod-python.cpp27
-rw-r--r--sca-cpp/trunk/modules/python/mod-python.hpp42
-rw-r--r--sca-cpp/trunk/modules/python/python-shell.cpp4
-rw-r--r--sca-cpp/trunk/modules/python/python-test.cpp165
7 files changed, 196 insertions, 258 deletions
diff --git a/sca-cpp/trunk/modules/python/Makefile.am b/sca-cpp/trunk/modules/python/Makefile.am
index 80c3097b48..92548de6d0 100644
--- a/sca-cpp/trunk/modules/python/Makefile.am
+++ b/sca-cpp/trunk/modules/python/Makefile.am
@@ -35,7 +35,7 @@ EXTRA_DIST = domain-test.composite client-test.py server-test.py
mod_LTLIBRARIES = libmod_tuscany_python.la
libmod_tuscany_python_la_SOURCES = mod-python.cpp
-libmod_tuscany_python_la_LDFLAGS = -lxml2 -lcurl -lmozjs -L${PYTHON_LIB} -R${PYTHON_LIB} -lpython${PYTHON_VERSION}
+libmod_tuscany_python_la_LDFLAGS = -lxml2 -lcurl -ljansson -L${PYTHON_LIB} -R${PYTHON_LIB} -lpython${PYTHON_VERSION}
noinst_DATA = libmod_tuscany_python${libsuffix}
libmod_tuscany_python${libsuffix}:
ln -s .libs/libmod_tuscany_python${libsuffix}
@@ -47,7 +47,7 @@ python_shell_SOURCES = python-shell.cpp
python_shell_LDFLAGS = -L${PYTHON_LIB} -R${PYTHON_LIB} -lpython${PYTHON_VERSION}
client_test_SOURCES = client-test.cpp
-client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+client_test_LDFLAGS = -lxml2 -lcurl -ljansson
dist_noinst_SCRIPTS = server-test wiring-test
noinst_PROGRAMS = python-test client-test
diff --git a/sca-cpp/trunk/modules/python/driver.hpp b/sca-cpp/trunk/modules/python/driver.hpp
index a5d554172b..41daed32c3 100644
--- a/sca-cpp/trunk/modules/python/driver.hpp
+++ b/sca-cpp/trunk/modules/python/driver.hpp
@@ -35,9 +35,9 @@
namespace tuscany {
namespace python {
-const value evalDriverLoop(PyObject* script, istream& in, ostream& out, PythonRuntime& py) {
+const value evalDriverLoop(PyObject* const script, istream& in, ostream& out, PythonRuntime& py) {
scheme::promptForInput(scheme::evalInputPrompt, out);
- value input = scheme::readValue(in);
+ const value input = content(scheme::readValue(in));
if (isNil(input))
return input;
const failable<value> output = evalScript(input, script, py);
@@ -46,11 +46,11 @@ const value evalDriverLoop(PyObject* script, istream& in, ostream& out, PythonRu
return evalDriverLoop(script, in, out, py);
}
-const bool evalDriverRun(const char* path, istream& in, ostream& out) {
+const bool evalDriverRun(const char* const path, istream& in, ostream& out) {
PythonRuntime py;
scheme::setupDisplay(out);
ifstream is(path);
- failable<PyObject*> script = readScript(moduleName(path), path, is, py);
+ const failable<PyObject*> script = readScript(moduleName(path), path, is, py);
if (!hasContent(script))
return true;
evalDriverLoop(content(script), in, out, py);
diff --git a/sca-cpp/trunk/modules/python/eval.hpp b/sca-cpp/trunk/modules/python/eval.hpp
index 5c0be7d261..3f9c6c20a2 100644
--- a/sca-cpp/trunk/modules/python/eval.hpp
+++ b/sca-cpp/trunk/modules/python/eval.hpp
@@ -53,8 +53,8 @@ class PythonRuntime;
/**
* Maintain a garbage collected reference to a Python object.
*/
-const bool pyIncRef(PyObject* o);
-const bool pyDecRef(PyObject* o, PythonRuntime* py);
+const bool pyIncRef(PyObject* const o);
+const bool pyDecRef(PyObject* const o, PythonRuntime* const py);
/**
* Write to debug log from Python.
@@ -70,7 +70,7 @@ const value pyDebug(const list<value>& args) {
class PythonRuntime {
public:
- PythonRuntime() {
+ PythonRuntime() : owner(true) {
debug("python::pythonruntime");
// Save current process id
@@ -115,7 +115,7 @@ public:
PySys_SetArgv(0, const_cast<char**>(&arg0));
// Install debug log function
- PyObject* mkPyLambda(const lambda<value(const list<value>&)>& l, PythonRuntime* py);
+ PyObject* mkPyLambda(const lvvlambda& l, PythonRuntime* py);
PyObject* pyd= mkPyLambda(pyDebug, this);
PyObject* sys = PyImport_ImportModule("sys");
PyObject_SetAttrString(sys, "debug", pyd);
@@ -127,10 +127,21 @@ public:
#endif
}
+#ifdef WANT_THREADS
+ PythonRuntime(const PythonRuntime& py) : owner(false), mutex(py.mutex), pidmutex(py.pidmutex), pid(py.pid) {
+ }
+#else
+ PythonRuntime(const PythonRuntime& py) : owner(false), pid(py.pid) {
+ }
+#endif
+
+ PythonRuntime& operator=(const PythonRuntime& py) = delete;
+
~PythonRuntime() {
}
private:
+ const bool owner;
#ifdef WANT_THREADS
pthread_mutex_t mutex;
pthread_mutex_t pidmutex;
@@ -145,9 +156,9 @@ private:
/**
* Return the last python error.
*/
-const string lastErrorTrace(PyObject *trace) {
+const string lastErrorTrace(PyObject* const trace) {
if (trace == NULL)
- return "";
+ return emptyString;
PyTracebackObject* tb = (PyTracebackObject*)trace;
const int limit = 16;
int depth = 0;
@@ -167,16 +178,16 @@ const string lastErrorTrace(PyObject *trace) {
return str(os);
}
-const string lastError(PythonRuntime* py) {
+const string lastError(PythonRuntime* const py) {
if(PyErr_Occurred()) {
PyObject* type = NULL;
PyObject* val = NULL;
PyObject* trace = NULL;
PyErr_Fetch(&type, &val, &trace);
if (type != NULL && val != NULL) {
- PyObject* stype = PyObject_Repr(type);
- PyObject* sval = PyObject_Repr(val);
- string msg = string() + PyString_AsString(stype) + " : " + PyString_AsString(sval) + lastErrorTrace(trace);
+ PyObject* const stype = PyObject_Repr(type);
+ PyObject* const sval = PyObject_Repr(val);
+ const string msg = string() + PyString_AsString(stype) + " : " + PyString_AsString(sval) + lastErrorTrace(trace);
pyDecRef(stype, py);
pyDecRef(sval, py);
PyErr_Restore(type, val, trace);
@@ -187,7 +198,7 @@ const string lastError(PythonRuntime* py) {
PyErr_Clear();
return "Unknown Python error";
}
- return "";
+ return emptyString;
}
/**
@@ -195,7 +206,7 @@ const string lastError(PythonRuntime* py) {
*/
class PythonRuntimeLock {
public:
- PythonRuntimeLock(PythonRuntime* py) : py(py) {
+ PythonRuntimeLock(PythonRuntime* const py) : py(py) {
#ifdef WANT_THREADS
pthread_mutex_lock(&py->mutex);
#endif
@@ -208,7 +219,7 @@ public:
}
private:
- PythonRuntime* py;
+ PythonRuntime* const py;
};
/**
@@ -216,7 +227,7 @@ private:
*/
class PythonThreadIn {
public:
- PythonThreadIn(PythonRuntime* py) : py(py) {
+ PythonThreadIn(PythonRuntime* const py) : py(py) {
// Reinitialize Python thread support after a fork
const unsigned long pid = processId();
@@ -261,7 +272,7 @@ public:
}
private:
- PythonRuntime* py;
+ PythonRuntime* const py;
#ifdef WANT_THREADS
PyGILState_STATE gstate;
#endif
@@ -272,7 +283,7 @@ private:
*/
class PythonThreadOut {
public:
- PythonThreadOut(PythonRuntime* py) : py(py) {
+ PythonThreadOut(PythonRuntime* const py) : py(py) {
#ifdef WANT_THREADS
//debug("python::gil::save");
tstate = PyEval_SaveThread();
@@ -289,7 +300,7 @@ public:
}
private:
- PythonRuntime* py;
+ PythonRuntime* const py;
#ifdef WANT_THREADS
PyThreadState* tstate;
#endif
@@ -300,7 +311,7 @@ private:
*/
class PyGCRef {
public:
- PyGCRef(PyObject* o, PythonRuntime* py) : o(o), py(py) {
+ PyGCRef(PyObject* const o, PythonRuntime* const py) : o(o), py(py) {
}
~PyGCRef() {
@@ -311,21 +322,21 @@ public:
}
private:
- PyObject* o;
- PythonRuntime* py;
+ PyObject* const o;
+ PythonRuntime* const py;
};
/**
* Maintain a garbage collected reference to a Python object.
*/
-const bool pyIncRef(PyObject* o) {
+const bool pyIncRef(PyObject* const o) {
if (o == NULL)
return true;
Py_INCREF(o);
return true;
}
-const bool pyDecRef(unused PyObject* o, unused PythonRuntime* py) {
+const bool pyDecRef(unused PyObject* const o, unused PythonRuntime* const py) {
if (o == NULL)
return true;
//new (gc_new<PyGCRef>()) PyGCRef(o, py);
@@ -336,40 +347,40 @@ const bool pyDecRef(unused PyObject* o, unused PythonRuntime* py) {
/**
* Declare conversion functions.
*/
-PyObject* valueToPyObject(const value& v, PythonRuntime* py);
-const value pyObjectToValue(PyObject *o, PythonRuntime* py);
-PyObject* valuesToPyTuple(const list<value>& v, PythonRuntime* py);
-const list<value> pyTupleToValues(PyObject* o, PythonRuntime* py);
+PyObject* const valueToPyObject(const value& v, PythonRuntime* const py);
+const value pyObjectToValue(PyObject* const o, PythonRuntime* const py);
+PyObject* const valuesToPyTuple(const list<value>& v, PythonRuntime* const py);
+const list<value> pyTupleToValues(PyObject* const o, PythonRuntime* const py);
/**
* Callable python type used to represent a lambda expression.
*/
typedef struct {
PyObject_HEAD
- lambda<value(const list<value>&)>* func;
+ lvvlambda* func;
PythonRuntime* py;
} pyLambda;
-PyObject *mkPyLambda(const lambda<value(const list<value>&)>& l, PythonRuntime* py);
+PyObject* const mkPyLambda(const lvvlambda& l, PythonRuntime* const py);
-void pyLambda_dealloc(PyObject* self) {
+void pyLambda_dealloc(PyObject* const self) {
//debug(self, "python::pylambda_dealloc");
PyObject_Del(self);
}
-const string pyRepr(PyObject* o, PythonRuntime* py) {
- PyObject* r = PyObject_Repr(o);
+const string pyRepr(PyObject* const o, PythonRuntime* const py) {
+ PyObject* const r = PyObject_Repr(o);
const string s = PyString_AsString(r);
pyDecRef(r, py);
return s;
}
-const value pyLambda_callout(const pyLambda* pyl, const list<value>& args, PythonRuntime* py) {
+const value pyLambda_callout(const pyLambda* const pyl, const list<value>& args, PythonRuntime* const py) {
PythonThreadOut pyout(py);
return (*(pyl->func))(args);
}
-PyObject* pyLambda_call(PyObject* self, PyObject* args, unused PyObject* kwds) {
+PyObject* const pyLambda_call(PyObject* const self, PyObject* const args, unused PyObject* const kwds) {
debug("python::call");
const pyLambda* pyl = (const pyLambda*)self;
const value result = pyLambda_callout(pyl, pyTupleToValues(args, pyl->py), pyl->py);
@@ -378,22 +389,7 @@ PyObject* pyLambda_call(PyObject* self, PyObject* args, unused PyObject* kwds) {
return pyr;
}
-struct pyProxy {
- const value name;
- const lambda<value(const list<value>&)> func;
-
- pyProxy(const value& name, const lambda<value(const list<value>&)>& func) : name(name), func(func) {
- }
-
- const value operator()(const list<value>& args) const {
- debug(name, "python::proxy::name");
- const value result = func(cons<value>(name, args));
- debug(result, "python::proxy::result");
- return result;
- }
-};
-
-PyObject* pyLambda_getattr(PyObject *self, PyObject *attrname) {
+PyObject* const pyLambda_getattr(PyObject* const self, PyObject* const attrname) {
const string name = PyString_AsString(attrname);
if (substr(name, 0, 1) == "_")
return PyObject_GenericGetAttr(self, attrname);
@@ -403,9 +399,18 @@ PyObject* pyLambda_getattr(PyObject *self, PyObject *attrname) {
return self;
}
- const pyLambda* pyl = (pyLambda*)self;
+ const pyLambda* const pyl = (const pyLambda* const)self;
debug(name, "python::getattr::name");
- PyObject* pyr = mkPyLambda(pyProxy(name, *(pyl->func)), pyl->py);
+
+ const lvvlambda func = *(pyl->func);
+ const lvvlambda pyProxy = [name, func](const list<value>& args) -> const value {
+ debug(name, "python::proxy::name");
+ const value result = func(cons<value>(name, args));
+ debug(result, "python::proxy::result");
+ return result;
+ };
+
+ PyObject* const pyr = mkPyLambda(pyProxy, pyl->py);
return pyr;
}
@@ -464,10 +469,10 @@ PyObject* pyLambda_getattr(PyObject *self, PyObject *attrname) {
/**
* Create a new python object representing a lambda expression.
*/
-PyObject *mkPyLambda(const lambda<value(const list<value>&)>& l, PythonRuntime* py) {
- pyLambda* pyl = PyObject_New(pyLambda, &pyLambda_type);
+PyObject* const mkPyLambda(const lvvlambda& l, PythonRuntime* const py) {
+ pyLambda* const pyl = PyObject_New(pyLambda, &pyLambda_type);
if (pyl != NULL) {
- pyl->func = new (gc_new<lambda<value(const list<value>&)> >()) lambda<value(const list<value>&)>(l);
+ pyl->func = new (gc_new<lvvlambda >()) lvvlambda(l);
pyl->py = py;
}
//debug(pyl, "python::mkpylambda");
@@ -477,18 +482,18 @@ PyObject *mkPyLambda(const lambda<value(const list<value>&)>& l, PythonRuntime*
/**
* Convert a list of values to a python list.
*/
-PyObject* valuesToPyListHelper(PyObject* l, const list<value>& v, PythonRuntime* py) {
+PyObject* const valuesToPyListHelper(PyObject* const l, const list<value>& v, PythonRuntime* const py) {
if (isNil(v))
return l;
- PyObject* pyv = valueToPyObject(car(v), py);
+ PyObject* const pyv = valueToPyObject(car(v), py);
PyList_Append(l, pyv);
pyDecRef(pyv, py);
return valuesToPyListHelper(l, cdr(v), py);
}
-PyObject* valuesToPyTuple(const list<value>& v, PythonRuntime* py) {
- PyObject* pyl = valuesToPyListHelper(PyList_New(0), v, py);
- PyObject* pyt = PyList_AsTuple(pyl);
+PyObject* const valuesToPyTuple(const list<value>& v, PythonRuntime* const py) {
+ PyObject* const pyl = valuesToPyListHelper(PyList_New(0), v, py);
+ PyObject* const pyt = PyList_AsTuple(pyl);
pyDecRef(pyl, py);
return pyt;
}
@@ -496,14 +501,14 @@ PyObject* valuesToPyTuple(const list<value>& v, PythonRuntime* py) {
/**
* Convert a value to a python object.
*/
-PyObject* valueToPyObject(const value& v, PythonRuntime* py) {
+PyObject* const valueToPyObject(const value& v, PythonRuntime* const py) {
switch (type(v)) {
case value::List:
return valuesToPyTuple(v, py);
case value::Lambda:
return mkPyLambda(v, py);
case value::Symbol:
- return PyString_FromString(c_str(string("'") + v));
+ return PyString_FromString(c_str(string("'") + (string)v));
case value::String: {
const string s = (string)v;
return PyString_FromStringAndSize(c_str(s), length(s));
@@ -511,12 +516,12 @@ PyObject* valueToPyObject(const value& v, PythonRuntime* py) {
case value::Number:
return PyFloat_FromDouble((double)v);
case value::Bool: {
- PyObject* b = (bool)v? Py_True : Py_False;
+ PyObject* const b = (bool)v? Py_True : Py_False;
pyIncRef(b);
return b;
}
default: {
- PyObject* n = Py_None;
+ PyObject* const n = Py_None;
pyIncRef(n);
return n;
}
@@ -526,39 +531,29 @@ PyObject* valueToPyObject(const value& v, PythonRuntime* py) {
/**
* Convert a python tuple to a list of values.
*/
-const list<value> pyTupleToValuesHelper(PyObject* o, const size_t i, const size_t size, PythonRuntime* py) {
+const list<value> pyTupleToValuesHelper(PyObject* const o, const size_t i, const size_t size, PythonRuntime* const py) {
if (i == size)
- return list<value>();
+ return nilListValue;
return cons(pyObjectToValue(PyTuple_GetItem(o, i), py), pyTupleToValuesHelper(o, i + 1, size, py));
}
-const list<value> pyTupleToValues(PyObject* o, PythonRuntime* py) {
+const list<value> pyTupleToValues(PyObject* const o, PythonRuntime* const py) {
return pyTupleToValuesHelper(o, 0, PyTuple_Size(o), py);
}
/**
* Lambda function used to represent a python callable object.
*/
-struct pyCallable {
- PyObject* func;
- PythonRuntime* py;
- bool owner;
-
- pyCallable(PyObject* func, PythonRuntime* py) : func(func), py(py), owner(true) {
+class pyCallable {
+public:
+ pyCallable(PyObject* const func, PythonRuntime* const py) : func(func), py(py), owner(true) {
pyIncRef(func);
}
pyCallable(const pyCallable& c) : func(c.func), py(c.py), owner(false) {
}
- const pyCallable& operator=(const pyCallable& c) {
- if(this == &c)
- return *this;
- func = c.func;
- py = c.py;
- owner = false;
- return *this;
- }
+ pyCallable& operator=(const pyCallable& c) = delete;
~pyCallable() {
if (!owner)
@@ -569,16 +564,16 @@ struct pyCallable {
const value operator()(const list<value>& args) const {
PythonThreadIn pyin(py);
if (debug_islogging()) {
- PyObject* rfunc = PyObject_Repr(func);
+ PyObject* const rfunc = PyObject_Repr(func);
char* s = NULL;
Py_ssize_t l = 0;
PyString_AsStringAndSize(rfunc, &s, &l);
debug(string(s, l), "python::operator()::func");
pyDecRef(rfunc, py);
}
- PyObject* pyargs = valuesToPyTuple(args, py);
+ PyObject* const pyargs = valuesToPyTuple(args, py);
if (debug_islogging()) {
- PyObject* rargs = PyObject_Repr(pyargs);
+ PyObject* const rargs = PyObject_Repr(pyargs);
char* s = NULL;
Py_ssize_t l = 0;
PyString_AsStringAndSize(rargs, &s, &l);
@@ -586,21 +581,26 @@ struct pyCallable {
pyDecRef(rargs, py);
}
- PyObject* result = PyObject_CallObject(func, pyargs);
+ PyObject* const result = PyObject_CallObject(func, pyargs);
pyDecRef(pyargs, py);
const value v = pyObjectToValue(result, py);
pyDecRef(result, py);
return v;
}
+
+private:
+ PyObject* const func;
+ PythonRuntime* const py;
+ const bool owner;
};
/**
* Convert a python object to a value.
*/
-const value pyObjectToValue(PyObject *o, PythonRuntime* py) {
+const value pyObjectToValue(PyObject* const o, PythonRuntime* const py) {
if (o == NULL)
- return value();
+ return nilValue;
if (PyString_Check(o)) {
char* s = NULL;
Py_ssize_t l = 0;
@@ -622,8 +622,8 @@ const value pyObjectToValue(PyObject *o, PythonRuntime* py) {
if (PyObject_TypeCheck(o, &pyLambda_type))
return *(((pyLambda*)o)->func);
if (PyCallable_Check(o))
- return lambda<value(const list<value>&)>(pyCallable(o, py));
- return value();
+ return lvvlambda(pyCallable(o, py));
+ return nilValue;
}
/**
@@ -636,37 +636,37 @@ const string moduleName(const string& path) {
/**
* Evaluate an expression against a script provided as a python object.
*/
-const failable<value> evalScript(const value& expr, PyObject* script, PythonRuntime& py) {
+const failable<value> evalScript(const value& expr, PyObject* const script, PythonRuntime& py) {
PythonThreadIn pyin(&py);
// Get the requested function
- PyObject* func = PyObject_GetAttrString(script, c_str(car<value>(expr)));
+ PyObject* const func = PyObject_GetAttrString(script, c_str(car<value>(expr)));
if (func == NULL) {
// The start, stop, and restart functions are optional
const value fn = car<value>(expr);
if (fn == "start" || fn == "stop") {
PyErr_Clear();
- return value(lambda<value(const list<value>&)>());
+ return value(lvvlambda());
}
- return mkfailure<value>(string("Couldn't find function: ") + car<value>(expr) + " : " + lastError(&py));
+ return mkfailure<value>(string("Couldn't find function: ") + (string)car<value>(expr) + " : " + lastError(&py));
}
if (!PyCallable_Check(func)) {
pyDecRef(func, &py);
- return mkfailure<value>(string("Couldn't find callable function: ") + car<value>(expr));
+ return mkfailure<value>(string("Couldn't find callable function: ") + (string)car<value>(expr));
}
// Convert args to python objects
- PyObject* args = valuesToPyTuple(cdr<value>(expr), &py);
+ PyObject* const args = valuesToPyTuple(cdr<value>(expr), &py);
// Call the function
- PyObject* result = PyObject_CallObject(func, args);
+ PyObject* const result = PyObject_CallObject(func, args);
if (result == NULL) {
const string msg = lastError(&py);
pyDecRef(func, &py);
pyDecRef(args, &py);
- return mkfailure<value>(string("Function call failed: ") + car<value>(expr) + " : " + msg);
+ return mkfailure<value>(string("Function call failed: ") + (string)car<value>(expr) + " : " + msg);
}
pyDecRef(func, &py);
pyDecRef(args, &py);
@@ -684,8 +684,8 @@ const failable<PyObject*> readScript(const string& name, const string& path, ist
PythonThreadIn pyin(&py);
// Lookup already loaded module
- PyObject *mods = PyImport_GetModuleDict();
- PyObject *emod = PyDict_GetItemString(mods, const_cast<char*>(c_str(name)));
+ PyObject* const mods = PyImport_GetModuleDict();
+ PyObject* const emod = PyDict_GetItemString(mods, const_cast<char*>(c_str(name)));
if (emod != NULL)
return emod;
@@ -695,10 +695,10 @@ const failable<PyObject*> readScript(const string& name, const string& path, ist
const list<string> ls = streamList(is);
ostringstream os;
write(ls, os);
- PyObject* code = Py_CompileStringFlags(c_str(str(os)), c_str(path), Py_file_input, NULL);
+ PyObject* const code = Py_CompileStringFlags(c_str(str(os)), c_str(path), Py_file_input, NULL);
if (code == NULL)
return mkfailure<PyObject*>(string("Couldn't compile script: ") + path + " : " + lastError(&py));
- PyObject* mod = PyImport_ExecCodeModuleEx(const_cast<char*>(c_str(name)), code, const_cast<char*>(c_str(path)));
+ PyObject* const mod = PyImport_ExecCodeModuleEx(const_cast<char*>(c_str(name)), code, const_cast<char*>(c_str(path)));
if (mod == NULL) {
const string msg = lastError(&py);
pyDecRef(code, &py);
@@ -708,7 +708,7 @@ const failable<PyObject*> readScript(const string& name, const string& path, ist
pyDecRef(mod, &py);
// Lookup the loaded module
- PyObject *lmod = PyDict_GetItemString(mods, const_cast<char*>(c_str(name)));
+ PyObject* const lmod = PyDict_GetItemString(mods, const_cast<char*>(c_str(name)));
if (lmod != NULL)
return lmod;
@@ -718,7 +718,7 @@ const failable<PyObject*> readScript(const string& name, const string& path, ist
/**
* Release a python script.
*/
-const failable<bool> releaseScript(unused PyObject* script, PythonRuntime& py) {
+const failable<bool> releaseScript(unused PyObject* const script, PythonRuntime& py) {
PythonThreadIn pyin(&py);
// No need to decref the script here, as it's referenced only once from sys.modules
return true;
diff --git a/sca-cpp/trunk/modules/python/mod-python.cpp b/sca-cpp/trunk/modules/python/mod-python.cpp
index 956edf1059..eaaeeb8e3e 100644
--- a/sca-cpp/trunk/modules/python/mod-python.cpp
+++ b/sca-cpp/trunk/modules/python/mod-python.cpp
@@ -40,42 +40,35 @@ namespace modeval {
/**
* Apply a lifecycle start or restart event.
*/
-struct pythonLifecycle {
- python::PythonRuntime& py;
- pythonLifecycle(python::PythonRuntime& py) : py(py) {
- }
- const value operator()(const list<value>& params) const {
- const value func = car(params);
- if (func == "pythonRuntime")
- return (gc_ptr<value>)(value*)&py;
- return lambda<value(const list<value>&)>();
- }
-};
-
const value applyLifecycle(unused const list<value>& params) {
// Create a Python runtime
python::PythonRuntime& py = *(new (gc_new<python::PythonRuntime>()) python::PythonRuntime());
// Return the function to invoke on subsequent events
- return failable<value>(lambda<value(const list<value>&)>(pythonLifecycle(py)));
+ return failable<value>(lvvlambda([&py](const list<value>& params) -> const value {
+ const value func = car(params);
+ if (func == "pythonRuntime")
+ return (gc_ptr<value>)(value*)&py;
+ return lvvlambda();
+ }));
}
/**
* Evaluate a Python component implementation and convert it to an applicable
* lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, const lambda<value(const list<value>&)>& lifecycle) {
+const failable<lvvlambda > evalImplementation(const string& path, const value& impl, const list<value>& px, const lvvlambda& lifecycle) {
const string itype(elementName(impl));
if (contains(itype, ".python")) {
- const value* p = (gc_ptr<value>)lifecycle(mklist<value>("pythonRuntime"));
+ const value* const p = (gc_ptr<value>)lifecycle(mklist<value>("pythonRuntime"));
return modpython::evalImplementation(path, impl, px, *(python::PythonRuntime*)p);
}
if (contains(itype, ".cpp"))
return modcpp::evalImplementation(path, impl, px);
if (contains(itype, ".widget"))
- return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype, -1, false);
- return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
+ return mkfailure<lvvlambda >(string("Unsupported implementation type: ") + itype, -1, false);
+ return mkfailure<lvvlambda >(string("Unsupported implementation type: ") + itype);
}
}
diff --git a/sca-cpp/trunk/modules/python/mod-python.hpp b/sca-cpp/trunk/modules/python/mod-python.hpp
index e6effb985b..00f2e4ab4e 100644
--- a/sca-cpp/trunk/modules/python/mod-python.hpp
+++ b/sca-cpp/trunk/modules/python/mod-python.hpp
@@ -40,38 +40,30 @@ namespace server {
namespace modpython {
/**
- * Apply a Python component implementation function.
- */
-struct applyImplementation {
- PyObject* impl;
- const list<value> px;
- python::PythonRuntime& py;
- applyImplementation(PyObject* impl, const list<value>& px, python::PythonRuntime& py) : impl(impl), px(px), py(py) {
- }
- const value operator()(const list<value>& params) const {
- const value expr = append<value>(params, px);
- debug(expr, "modeval::python::applyImplementation::input");
- const failable<value> res = python::evalScript(expr, impl, py);
- const value val = !hasContent(res)? mklist<value>(value(), reason(res), rcode(res)) : mklist<value>(content(res));
- debug(val, "modeval::python::applyImplementation::result");
- return val;
- }
-};
-
-/**
* Evaluate a Python component implementation and convert it to an applicable
* lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, python::PythonRuntime& py) {
+const failable<lvvlambda > evalImplementation(const string& path, const value& impl, const list<value>& px, python::PythonRuntime& py) {
const string spath(attributeValue("script", impl));
const string fpath(path + spath);
ifstream is(fpath);
if (fail(is))
- return mkfailure<lambda<value(const list<value>&)> >(string("Could not read implementation: ") + fpath);
- const failable<PyObject*> script = python::readScript(python::moduleName(spath), fpath, is, py);
- if (!hasContent(script))
- return mkfailure<lambda<value(const list<value>&)> >(script);
- return lambda<value(const list<value>&)>(applyImplementation(content(script), px, py));
+ return mkfailure<lvvlambda >(string("Could not read implementation: ") + fpath);
+ const failable<PyObject*> fscript = python::readScript(python::moduleName(spath), fpath, is, py);
+ if (!hasContent(fscript))
+ return mkfailure<lvvlambda >(fscript);
+ PyObject* const script = content(fscript);
+
+ const lvvlambda applyImplementation = [script, px, &py](const list<value>& params) -> const value {
+ // Apply a Python component implementation function
+ const value expr = append<value>(params, px);
+ debug(expr, "modeval::python::applyImplementation::input");
+ const failable<value> res = python::evalScript(expr, script, py);
+ const value val = !hasContent(res)? mklist<value>(nilValue, reason(res), rcode(res)) : mklist<value>(content(res));
+ debug(val, "modeval::python::applyImplementation::result");
+ return val;
+ };
+ return applyImplementation;
}
}
diff --git a/sca-cpp/trunk/modules/python/python-shell.cpp b/sca-cpp/trunk/modules/python/python-shell.cpp
index 89b47b8d44..7575ffa077 100644
--- a/sca-cpp/trunk/modules/python/python-shell.cpp
+++ b/sca-cpp/trunk/modules/python/python-shell.cpp
@@ -29,8 +29,8 @@
#include "string.hpp"
#include "driver.hpp"
-int main(const int argc, char** argv) {
- tuscany::gc_scoped_pool pool;
+int main(const int argc, const char** const argv) {
+ const tuscany::gc_scoped_pool pool;
if (argc != 2) {
tuscany::cerr << "Usage: python-shell <script.py>" << tuscany::endl;
return 1;
diff --git a/sca-cpp/trunk/modules/python/python-test.cpp b/sca-cpp/trunk/modules/python/python-test.cpp
index 29a66cc2e7..44a72f8f88 100644
--- a/sca-cpp/trunk/modules/python/python-test.cpp
+++ b/sca-cpp/trunk/modules/python/python-test.cpp
@@ -37,12 +37,12 @@ const string testPythonAdd =
"def add(x, y):\n"
" return x + y\n";
-bool testEvalExpr() {
- gc_scoped_pool pool;
+const bool testEvalExpr() {
+ const gc_scoped_pool pool;
PythonRuntime py;
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script1", "script1.py", is, py);
+ const failable<PyObject*> script = readScript("script1", "script1.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -58,12 +58,12 @@ const string testPythonMap =
"def addmap(x, y):\n"
" return tuple(map(lambda i: i + y, x))\n";
-bool testEvalList() {
- gc_scoped_pool pool;
+const bool testEvalList() {
+ const gc_scoped_pool pool;
PythonRuntime py;
istringstream is(testPythonMap);
- failable<PyObject*> script = readScript("script2", "script2.py", is, py);
+ const failable<PyObject*> script = readScript("script2", "script2.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("addmap", mklist<value>(1, 2, 3), 1);
@@ -94,8 +94,8 @@ const string testCallLambda(
"def testCallLambda(l, x, y):\n"
" return l(x, y)\n");
-bool testEvalLambda() {
- gc_scoped_pool pool;
+const bool testEvalLambda() {
+ const gc_scoped_pool pool;
PythonRuntime py;
const value trl = mklist<value>("testReturnLambda");
@@ -104,7 +104,7 @@ bool testEvalLambda() {
assert(hasContent(trlv));
assert(isLambda(content(trlv)));
- const lambda<value(const list<value>&)> trll(content(trlv));
+ const lvvlambda trll(content(trlv));
assert(trll(mklist<value>(2, 3)) == value(6));
istringstream tclis(testCallLambda);
@@ -114,20 +114,20 @@ bool testEvalLambda() {
assert(content(tclv) == value(6));
istringstream tcelis(testCallLambda);
- const value tcel = mklist<value>("testCallLambda", lambda<value(const list<value>&)>(mult), 3, 4);
+ const value tcel = mklist<value>("testCallLambda", lvvlambda(mult), 3, 4);
const failable<value> tcelv = evalScript(tcel, tcelis, py);
assert(hasContent(tcelv));
assert(content(tcelv) == value(12));
return true;
}
-struct testEvalReadAdd {
- PythonRuntime& py;
- testEvalReadAdd(PythonRuntime& py) : py(py) {
- }
- const bool operator()() const {
+const bool testEvalPerf() {
+ const gc_scoped_pool pool;
+ PythonRuntime py;
+
+ const blambda erl = [&py]() -> const bool {
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script3", "script3.py", is, py);
+ const failable<PyObject*> script = readScript("script3", "script3.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -137,51 +137,36 @@ struct testEvalReadAdd {
releaseScript(content(script), py);
return true;
- }
-};
-
-struct testEvalAdd {
- PyObject* script;
- PythonRuntime& py;
- testEvalAdd(PyObject* script, PythonRuntime& py) : script(script), py(py) {
- }
- const bool operator()() const {
+ };
+ cout << "Python read + eval test " << time(erl, 5, 10000) << " ms" << endl;
+
+ istringstream is(testPythonAdd);
+ const failable<PyObject*> fscript = readScript("script4", "script4.py", is, py);
+ assert(hasContent(fscript));
+
+ PyObject* const script = content(fscript);
+ const blambda el = [script, &py]() -> const bool {
const value exp = mklist<value>("add", 2, 3);
const failable<value> r = evalScript(exp, script, py);
assert(hasContent(r));
assert(content(r) == value(5));
return true;
- }
-};
-
-bool testEvalPerf() {
- gc_scoped_pool pool;
- PythonRuntime py;
-
- const lambda<bool()> erl = lambda<bool()>(testEvalReadAdd(py));
- cout << "Python read + eval test " << time(erl, 5, 10000) << " ms" << endl;
-
- istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script4", "script4.py", is, py);
- assert(hasContent(script));
-
- const lambda<bool()> el = lambda<bool()>(testEvalAdd(content(script), py));
+ };
cout << "Python eval test " << time(el, 5, 10000) << " ms" << endl;
- releaseScript(content(script), py);
+ releaseScript(script, py);
return true;
}
#ifdef WANT_THREADS
-struct testReadEvalAddLoop {
- PythonRuntime& py;
- testReadEvalAddLoop(PythonRuntime& py) : py(py) {
- }
- const bool operator()() const {
+const list<future<bool> > submitReadEvals(worker& w, const int max, const int i, PythonRuntime& py) {
+ if (i == max)
+ return list<future<bool> >();
+ const blambda func = [&py]() -> const bool {
for (int i = 0; i < 100; i++) {
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script6", "script6.py", is, py);
+ const failable<PyObject*> script = readScript("script6", "script6.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -192,15 +177,14 @@ struct testReadEvalAddLoop {
releaseScript(content(script), py);
}
return true;
- }
-};
-
-struct testEvalAddLoop {
- PyObject* script;
- PythonRuntime& py;
- testEvalAddLoop(PyObject* script, PythonRuntime& py) : script(script), py(py) {
- }
- const bool operator()() const {
+ };
+ return cons(submit(w, func), submitReadEvals(w, max, i + 1, py));
+}
+
+const list<future<bool> > submitEvals(worker& w, const int max, const int i, PyObject* const script, PythonRuntime& py) {
+ if (i == max)
+ return list<future<bool> >();
+ const blambda func = [script, &py]() -> const bool {
for (int i = 0; i < 100; i++) {
const value exp = mklist<value>("add", 2, 3);
const failable<value> r = evalScript(exp, script, py);
@@ -208,75 +192,44 @@ struct testEvalAddLoop {
assert(content(r) == value(5));
}
return true;
- }
-};
-
-const list<future<bool> > submitReadEvals(worker& w, const int max, const int i, PythonRuntime& py) {
- if (i == max)
- return list<future<bool> >();
- const lambda<bool()> func = lambda<bool()>(testReadEvalAddLoop(py));
- return cons(submit(w, func), submitReadEvals(w, max, i + 1, py));
-}
-
-const list<future<bool> > submitEvals(worker& w, const int max, const int i, PyObject* script, PythonRuntime& py) {
- if (i == max)
- return list<future<bool> >();
- const lambda<bool()> func = lambda<bool()>(testEvalAddLoop(script, py));
+ };
return cons(submit(w, func), submitEvals(w, max, i + 1, script, py));
}
-bool checkEvalResults(const list<future<bool> > r) {
+const bool checkEvalResults(const list<future<bool> > r) {
if (isNil(r))
return true;
assert(car(r) == true);
return checkEvalResults(cdr(r));
}
-struct testReadEvalThreads {
- worker& w;
- const int max;
- PythonRuntime& py;
- testReadEvalThreads(worker& w, const int max, PythonRuntime& py) : w(w), max(max), py(py) {
- }
- const bool operator()() const {
- const list<future<bool> > r(submitReadEvals(w, max, 0, py));
- checkEvalResults(r);
- return true;
- }
-};
-
-struct testEvalThreads {
- worker& w;
- const int max;
- PyObject* script;
- PythonRuntime& py;
- testEvalThreads(worker& w, const int max, PyObject* script, PythonRuntime& py) : w(w), max(max), script(script), py(py) {
- }
- const bool operator()() const {
- const list<future<bool> > r(submitEvals(w, max, 0, script, py));
- checkEvalResults(r);
- return true;
- }
-};
-
-bool testThreads() {
- gc_scoped_pool pool;
+const bool testThreads() {
+ const gc_scoped_pool pool;
PythonRuntime py;
const int max = 100;
worker w(max);
- const lambda<bool()> elr = lambda<bool()>(testReadEvalThreads(w, max, py));
+ const blambda elr = [&w, max, &py]() -> const bool {
+ const list<future<bool> > r(submitReadEvals(w, max, 0, py));
+ checkEvalResults(r);
+ return true;
+ };
cout << "Python eval + read thread test " << time(elr, 1, 1) / 10000.0 << " ms" << endl;
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script7", "script7.py", is, py);
- assert(hasContent(script));
+ const failable<PyObject*> fscript = readScript("script7", "script7.py", is, py);
+ assert(hasContent(fscript));
- const lambda<bool()> el = lambda<bool()>(testEvalThreads(w, max, content(script), py));
+ PyObject* const script = content(fscript);
+ const blambda el = [&w, max, script, &py]() -> const bool {
+ const list<future<bool> > r(submitEvals(w, max, 0, script, py));
+ checkEvalResults(r);
+ return true;
+ };
cout << "Python eval thread test " << time(el, 1, 1) / 10000.0 << " ms" << endl;
- releaseScript(content(script), py);
+ releaseScript(script, py);
return true;
}
@@ -286,7 +239,7 @@ bool testThreads() {
}
int main() {
- tuscany::gc_scoped_pool p;
+ const tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::python::testEvalExpr();