cglob.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. typedef void *(*gs_fetch_addr_fn)(void);
  2. typedef struct {
  3. PyObject_HEAD
  4. PyObject *gs_name;
  5. CTypeDescrObject *gs_type;
  6. char *gs_data;
  7. gs_fetch_addr_fn gs_fetch_addr;
  8. } GlobSupportObject;
  9. static void glob_support_dealloc(GlobSupportObject *gs)
  10. {
  11. Py_DECREF(gs->gs_name);
  12. Py_DECREF(gs->gs_type);
  13. PyObject_Del(gs);
  14. }
  15. static PyTypeObject GlobSupport_Type = {
  16. PyVarObject_HEAD_INIT(NULL, 0)
  17. "_cffi_backend.__FFIGlobSupport",
  18. sizeof(GlobSupportObject),
  19. 0,
  20. (destructor)glob_support_dealloc, /* tp_dealloc */
  21. 0, /* tp_print */
  22. 0, /* tp_getattr */
  23. 0, /* tp_setattr */
  24. 0, /* tp_compare */
  25. 0, /* tp_repr */
  26. 0, /* tp_as_number */
  27. 0, /* tp_as_sequence */
  28. 0, /* tp_as_mapping */
  29. 0, /* tp_hash */
  30. 0, /* tp_call */
  31. 0, /* tp_str */
  32. PyObject_GenericGetAttr, /* tp_getattro */
  33. 0, /* tp_setattro */
  34. 0, /* tp_as_buffer */
  35. Py_TPFLAGS_DEFAULT, /* tp_flags */
  36. };
  37. #define GlobSupport_Check(ob) (Py_TYPE(ob) == &GlobSupport_Type)
  38. static PyObject *make_global_var(PyObject *name, CTypeDescrObject *type,
  39. char *addr, gs_fetch_addr_fn fetch_addr)
  40. {
  41. GlobSupportObject *gs = PyObject_New(GlobSupportObject, &GlobSupport_Type);
  42. if (gs == NULL)
  43. return NULL;
  44. Py_INCREF(name);
  45. Py_INCREF(type);
  46. gs->gs_name = name;
  47. gs->gs_type = type;
  48. gs->gs_data = addr;
  49. gs->gs_fetch_addr = fetch_addr;
  50. return (PyObject *)gs;
  51. }
  52. static void *fetch_global_var_addr(GlobSupportObject *gs)
  53. {
  54. void *data;
  55. if (gs->gs_data != NULL) {
  56. data = gs->gs_data;
  57. }
  58. else {
  59. Py_BEGIN_ALLOW_THREADS
  60. restore_errno();
  61. data = gs->gs_fetch_addr();
  62. save_errno();
  63. Py_END_ALLOW_THREADS
  64. }
  65. if (data == NULL) {
  66. PyErr_Format(FFIError, "global variable '%s' is at address NULL",
  67. PyText_AS_UTF8(gs->gs_name));
  68. return NULL;
  69. }
  70. return data;
  71. }
  72. static PyObject *read_global_var(GlobSupportObject *gs)
  73. {
  74. void *data = fetch_global_var_addr(gs);
  75. if (data == NULL)
  76. return NULL;
  77. return convert_to_object(data, gs->gs_type);
  78. }
  79. static int write_global_var(GlobSupportObject *gs, PyObject *obj)
  80. {
  81. void *data = fetch_global_var_addr(gs);
  82. if (data == NULL)
  83. return -1;
  84. return convert_from_object(data, gs->gs_type, obj);
  85. }
  86. static PyObject *cg_addressof_global_var(GlobSupportObject *gs)
  87. {
  88. void *data;
  89. PyObject *x, *ptrtype = new_pointer_type(gs->gs_type);
  90. if (ptrtype == NULL)
  91. return NULL;
  92. data = fetch_global_var_addr(gs);
  93. if (data != NULL)
  94. x = new_simple_cdata(data, (CTypeDescrObject *)ptrtype);
  95. else
  96. x = NULL;
  97. Py_DECREF(ptrtype);
  98. return x;
  99. }