/numba/_dynfunc.c

https://github.com/agamdua/numba · C · 72 lines · 57 code · 14 blank · 1 comment · 4 complexity · 3dc7c38e8b473fa8afd040f12fd2a636 MD5 · raw file

  1. #include "_pymodule.h"
  2. #include <string.h>
  3. static
  4. PyObject*
  5. make_function(PyObject *self, PyObject *args)
  6. {
  7. PyObject *module, *fname, *fdoc, *fnaddrobj;
  8. void *fnaddr;
  9. PyMethodDef *desc;
  10. char *doc, *name;
  11. char *mlname, *mldoc;
  12. size_t szdoc, szname;
  13. if (!PyArg_ParseTuple(args, "OOOO", &module, &fname, &fdoc, &fnaddrobj)) {
  14. return NULL;
  15. }
  16. fnaddr = PyLong_AsVoidPtr(fnaddrobj);
  17. doc = PyString_AsString(fdoc);
  18. name = PyString_AsString(fname);
  19. szdoc = strlen(doc) + 1;
  20. szname = strlen(name) + 1;
  21. mlname = malloc(szname);
  22. mldoc = malloc(szdoc);
  23. strcpy(mlname, name);
  24. strcpy(mldoc, doc);
  25. /* FIXME Need to figure out a way to free the mallocs */
  26. desc = malloc(sizeof(PyMethodDef));
  27. desc->ml_name = mlname;
  28. desc->ml_meth = (void*)fnaddr;
  29. desc->ml_flags = METH_VARARGS | METH_KEYWORDS;
  30. desc->ml_doc = mldoc;
  31. return PyCFunction_NewEx(desc, NULL, module);
  32. }
  33. static
  34. PyObject*
  35. set_arbitrary_addr(PyObject* self, PyObject* args){
  36. PyObject *obj, *targetobj;
  37. void **target;
  38. if (!PyArg_ParseTuple(args, "OO", &targetobj, &obj)) {
  39. return NULL;
  40. }
  41. target = PyLong_AsVoidPtr(targetobj);
  42. *target = obj;
  43. Py_RETURN_NONE;
  44. }
  45. static PyMethodDef ext_methods[] = {
  46. #define declmethod(func) { #func , ( PyCFunction )func , METH_VARARGS , NULL }
  47. declmethod(make_function),
  48. declmethod(set_arbitrary_addr),
  49. { NULL },
  50. #undef declmethod
  51. };
  52. MOD_INIT(_dynfunc) {
  53. PyObject *m;
  54. MOD_DEF(m, "_dynfunc", "No docs", ext_methods)
  55. if (m == NULL)
  56. return MOD_ERROR_VAL;
  57. return MOD_SUCCESS_VAL(m);
  58. }