cffi1_module.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #include "parse_c_type.c"
  2. #include "realize_c_type.c"
  3. #define CFFI_VERSION_MIN 0x2601
  4. #define CFFI_VERSION_CHAR16CHAR32 0x2801
  5. #define CFFI_VERSION_MAX 0x28FF
  6. typedef struct FFIObject_s FFIObject;
  7. typedef struct LibObject_s LibObject;
  8. static PyTypeObject FFI_Type; /* forward */
  9. static PyTypeObject Lib_Type; /* forward */
  10. #include "ffi_obj.c"
  11. #include "cglob.c"
  12. #include "lib_obj.c"
  13. #include "cdlopen.c"
  14. #include "commontypes.c"
  15. #include "call_python.c"
  16. static int init_ffi_lib(PyObject *m)
  17. {
  18. PyObject *x;
  19. int i, res;
  20. static char init_done = 0;
  21. if (!init_done) {
  22. if (init_global_types_dict(FFI_Type.tp_dict) < 0)
  23. return -1;
  24. FFIError = PyErr_NewException("ffi.error", NULL, NULL);
  25. if (FFIError == NULL)
  26. return -1;
  27. if (PyDict_SetItemString(FFI_Type.tp_dict, "error", FFIError) < 0)
  28. return -1;
  29. if (PyDict_SetItemString(FFI_Type.tp_dict, "CType",
  30. (PyObject *)&CTypeDescr_Type) < 0)
  31. return -1;
  32. if (PyDict_SetItemString(FFI_Type.tp_dict, "CData",
  33. (PyObject *)&CData_Type) < 0)
  34. return -1;
  35. if (PyDict_SetItemString(FFI_Type.tp_dict, "buffer",
  36. (PyObject *)&MiniBuffer_Type) < 0)
  37. return -1;
  38. for (i = 0; all_dlopen_flags[i].name != NULL; i++) {
  39. x = PyInt_FromLong(all_dlopen_flags[i].value);
  40. if (x == NULL)
  41. return -1;
  42. res = PyDict_SetItemString(FFI_Type.tp_dict,
  43. all_dlopen_flags[i].name, x);
  44. Py_DECREF(x);
  45. if (res < 0)
  46. return -1;
  47. }
  48. init_done = 1;
  49. }
  50. return 0;
  51. }
  52. static int make_included_tuples(char *module_name,
  53. const char *const *ctx_includes,
  54. PyObject **included_ffis,
  55. PyObject **included_libs)
  56. {
  57. Py_ssize_t num = 0;
  58. const char *const *p_include;
  59. if (ctx_includes == NULL)
  60. return 0;
  61. for (p_include = ctx_includes; *p_include; p_include++) {
  62. num++;
  63. }
  64. *included_ffis = PyTuple_New(num);
  65. *included_libs = PyTuple_New(num);
  66. if (*included_ffis == NULL || *included_libs == NULL)
  67. goto error;
  68. num = 0;
  69. for (p_include = ctx_includes; *p_include; p_include++) {
  70. PyObject *included_ffi, *included_lib;
  71. PyObject *m = PyImport_ImportModule(*p_include);
  72. if (m == NULL)
  73. goto import_error;
  74. included_ffi = PyObject_GetAttrString(m, "ffi");
  75. PyTuple_SET_ITEM(*included_ffis, num, included_ffi);
  76. included_lib = (included_ffi == NULL) ? NULL :
  77. PyObject_GetAttrString(m, "lib");
  78. PyTuple_SET_ITEM(*included_libs, num, included_lib);
  79. Py_DECREF(m);
  80. if (included_lib == NULL)
  81. goto import_error;
  82. if (!FFIObject_Check(included_ffi) ||
  83. !LibObject_Check(included_lib))
  84. goto import_error;
  85. num++;
  86. }
  87. return 0;
  88. import_error:
  89. PyErr_Format(PyExc_ImportError,
  90. "while loading %.200s: failed to import ffi, lib from %.200s",
  91. module_name, *p_include);
  92. error:
  93. Py_XDECREF(*included_ffis); *included_ffis = NULL;
  94. Py_XDECREF(*included_libs); *included_libs = NULL;
  95. return -1;
  96. }
  97. static PyObject *_my_Py_InitModule(char *module_name)
  98. {
  99. #if PY_MAJOR_VERSION >= 3
  100. struct PyModuleDef *module_def, local_module_def = {
  101. PyModuleDef_HEAD_INIT,
  102. module_name,
  103. NULL,
  104. -1,
  105. NULL, NULL, NULL, NULL, NULL
  106. };
  107. /* note: the 'module_def' is allocated dynamically and leaks,
  108. but anyway the C extension module can never be unloaded */
  109. module_def = PyMem_Malloc(sizeof(struct PyModuleDef));
  110. if (module_def == NULL)
  111. return PyErr_NoMemory();
  112. *module_def = local_module_def;
  113. return PyModule_Create(module_def);
  114. #else
  115. return Py_InitModule(module_name, NULL);
  116. #endif
  117. }
  118. static PyObject *b_init_cffi_1_0_external_module(PyObject *self, PyObject *arg)
  119. {
  120. PyObject *m, *modules_dict;
  121. FFIObject *ffi;
  122. LibObject *lib;
  123. Py_ssize_t version, num_exports;
  124. char *module_name, *exports, *module_name_with_lib;
  125. void **raw;
  126. const struct _cffi_type_context_s *ctx;
  127. raw = (void **)PyLong_AsVoidPtr(arg);
  128. if (raw == NULL)
  129. return NULL;
  130. module_name = (char *)raw[0];
  131. version = (Py_ssize_t)raw[1];
  132. exports = (char *)raw[2];
  133. ctx = (const struct _cffi_type_context_s *)raw[3];
  134. if (version < CFFI_VERSION_MIN || version > CFFI_VERSION_MAX) {
  135. if (!PyErr_Occurred())
  136. PyErr_Format(PyExc_ImportError,
  137. "cffi extension module '%s' uses an unknown version tag %p. "
  138. "This module might need a more recent version of cffi "
  139. "than the one currently installed, which is %s",
  140. module_name, (void *)version, CFFI_VERSION);
  141. return NULL;
  142. }
  143. /* initialize the exports array */
  144. num_exports = 25;
  145. if (ctx->flags & 1) /* set to mean that 'extern "Python"' is used */
  146. num_exports = 26;
  147. if (version >= CFFI_VERSION_CHAR16CHAR32)
  148. num_exports = 28;
  149. memcpy(exports, (char *)cffi_exports, num_exports * sizeof(void *));
  150. /* make the module object */
  151. m = _my_Py_InitModule(module_name);
  152. if (m == NULL)
  153. return NULL;
  154. /* build the FFI and Lib object inside this new module */
  155. ffi = ffi_internal_new(&FFI_Type, ctx);
  156. Py_XINCREF(ffi); /* make the ffi object really immortal */
  157. if (ffi == NULL || PyModule_AddObject(m, "ffi", (PyObject *)ffi) < 0)
  158. return NULL;
  159. lib = lib_internal_new(ffi, module_name, NULL, 0);
  160. if (lib == NULL || PyModule_AddObject(m, "lib", (PyObject *)lib) < 0)
  161. return NULL;
  162. if (make_included_tuples(module_name, ctx->includes,
  163. &ffi->types_builder.included_ffis,
  164. &lib->l_types_builder->included_libs) < 0)
  165. return NULL;
  166. /* add manually 'module_name.lib' in sys.modules:
  167. see test_import_from_lib */
  168. modules_dict = PySys_GetObject("modules");
  169. if (!modules_dict)
  170. return NULL;
  171. module_name_with_lib = alloca(strlen(module_name) + 5);
  172. strcpy(module_name_with_lib, module_name);
  173. strcat(module_name_with_lib, ".lib");
  174. if (PyDict_SetItemString(modules_dict, module_name_with_lib,
  175. (PyObject *)lib) < 0)
  176. return NULL;
  177. #if PY_MAJOR_VERSION >= 3
  178. /* add manually 'module_name' in sys.modules: it seems that
  179. Py_InitModule() is not enough to do that */
  180. if (PyDict_SetItemString(modules_dict, module_name, m) < 0)
  181. return NULL;
  182. #endif
  183. return m;
  184. }