PageRenderTime 69ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/bundles/pyml/pyml-current/pyml_stubs.c

http://github.com/coccinelle/coccinelle
C | 1372 lines | 1206 code | 120 blank | 46 comment | 176 complexity | f8b0bcc2179767017ea0d88039fbf649 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, LGPL-3.0, CC-BY-SA-4.0
  1. #define _GNU_SOURCE
  2. #include <caml/mlvalues.h>
  3. #include <caml/memory.h>
  4. #include <caml/fail.h>
  5. #include <caml/callback.h>
  6. #include <caml/custom.h>
  7. #include <caml/alloc.h>
  8. #include <sys/param.h>
  9. #include <string.h>
  10. #include <stdbool.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <errno.h>
  15. #include "pyml_stubs.h"
  16. static FILE *(*Python__Py_fopen)(const char *pathname, const char *mode);
  17. static void *xmalloc(size_t size)
  18. {
  19. void *p = malloc(size);
  20. if (!p) {
  21. failwith("Virtual memory exhausted\n");
  22. }
  23. return p;
  24. }
  25. #ifdef _WIN32
  26. #include <windows.h>
  27. typedef HINSTANCE library_t;
  28. static library_t
  29. open_library(const char *filename)
  30. {
  31. return LoadLibrary(filename);
  32. }
  33. void
  34. close_library(library_t library)
  35. {
  36. if (!FreeLibrary(library)) {
  37. fprintf(stderr, "close_library.\n");
  38. exit(EXIT_FAILURE);
  39. }
  40. }
  41. static library_t
  42. get_default_library(void)
  43. {
  44. return GetModuleHandle(0);
  45. }
  46. static void *
  47. find_symbol(library_t library, const char *name)
  48. {
  49. return GetProcAddress(library, name);
  50. }
  51. int
  52. unsetenv(const char *name)
  53. {
  54. size_t len = strlen(name);
  55. char string[len + 2];
  56. snprintf(string, len + 2, "%s=", name);
  57. return _putenv(string);
  58. }
  59. extern int win_CRT_fd_of_filedescr(value handle);
  60. static FILE *
  61. file_of_file_descr(value file_descr, const char *mode)
  62. {
  63. CAMLparam1(file_descr);
  64. int fd = win_CRT_fd_of_filedescr(file_descr);
  65. FILE *result = _fdopen(dup(fd), mode);
  66. CAMLreturnT(FILE *, result);
  67. }
  68. #else
  69. #include <dlfcn.h>
  70. typedef void *library_t;
  71. static library_t
  72. open_library(const char *filename)
  73. {
  74. return dlopen(filename, RTLD_LAZY | RTLD_GLOBAL);
  75. }
  76. void
  77. close_library(library_t filename)
  78. {
  79. if (dlclose(filename)) {
  80. fprintf(stderr, "close_library: %s.\n", dlerror());
  81. exit(EXIT_FAILURE);
  82. }
  83. }
  84. static library_t
  85. get_default_library(void)
  86. {
  87. return RTLD_DEFAULT;
  88. }
  89. static void *
  90. find_symbol(library_t library, const char *name)
  91. {
  92. return dlsym(library, name);
  93. }
  94. static FILE *
  95. file_of_file_descr(value file_descr, const char *mode)
  96. {
  97. CAMLparam1(file_descr);
  98. int fd = Int_val(file_descr);
  99. FILE *result = fdopen(dup(fd), mode);
  100. CAMLreturnT(FILE *, result);
  101. }
  102. #endif
  103. /* The following definitions are extracted and simplified from
  104. #include <Python.h>
  105. */
  106. typedef struct {
  107. int cf_flags;
  108. } PyCompilerFlags;
  109. #define Py_TPFLAGS_INT_SUBCLASS (1L<<23)
  110. #define Py_TPFLAGS_LONG_SUBCLASS (1UL << 24)
  111. #define Py_TPFLAGS_LIST_SUBCLASS (1UL << 25)
  112. #define Py_TPFLAGS_TUPLE_SUBCLASS (1UL << 26)
  113. #define Py_TPFLAGS_BYTES_SUBCLASS (1UL << 27)
  114. #define Py_TPFLAGS_UNICODE_SUBCLASS (1UL << 28)
  115. #define Py_TPFLAGS_DICT_SUBCLASS (1UL << 29)
  116. #define Py_TPFLAGS_BASE_EXC_SUBCLASS (1UL << 30)
  117. #define Py_TPFLAGS_TYPE_SUBCLASS (1UL << 31)
  118. #define Py_LT 0
  119. #define Py_LE 1
  120. #define Py_EQ 2
  121. #define Py_NE 3
  122. #define Py_GT 4
  123. #define Py_GE 5
  124. typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
  125. typedef struct PyMethodDef {
  126. const char *ml_name;
  127. PyCFunction ml_meth;
  128. int ml_flags;
  129. const char *ml_doc;
  130. } PyMethodDef;
  131. typedef void (*PyCapsule_Destructor)(PyObject *);
  132. static void *Python27__PyObject_NextNotImplemented;
  133. /* Global variables for the library */
  134. /* version_major != 0 iff the library is initialized */
  135. static int version_major;
  136. static int version_minor;
  137. static library_t library;
  138. /* Functions that are special enough to deserved to be wrapped specifically */
  139. /* Wrapped by pywrap_closure */
  140. static PyObject *(*Python_PyCFunction_NewEx)
  141. (PyMethodDef *, PyObject *, PyObject *);
  142. /* Wrapped by closure and capsule */
  143. static void *(*Python27_PyCapsule_New)
  144. (void *, const char *, PyCapsule_Destructor);
  145. static void *(*Python27_PyCapsule_GetPointer)(PyObject *, const char *);
  146. static int (*Python27_PyCapsule_IsValid)(PyObject *, char *);
  147. static void *(*Python2_PyCObject_FromVoidPtr)(void *, void (*)(void *));
  148. static void *(*Python2_PyCObject_AsVoidPtr)(PyObject *);
  149. /* Hack for multi-arguments */
  150. static PyObject *(*Python_PyObject_CallFunctionObjArgs)(PyObject *, ...);
  151. static PyObject *(*Python_PyObject_CallMethodObjArgs)(
  152. PyObject *, PyObject *, ...);
  153. /* Wrapped by PyErr_Fetch_wrapper */
  154. static void (*Python_PyErr_Fetch)(PyObject **, PyObject **, PyObject **);
  155. static void (*Python_PyErr_NormalizeException)
  156. (PyObject **, PyObject **, PyObject **);
  157. /* Resolved differently between Python 2 and Python 3 */
  158. static PyObject *Python__Py_FalseStruct;
  159. /* Buffer and size */
  160. static int (*Python_PyString_AsStringAndSize)
  161. (PyObject *, char **, Py_ssize_t *);
  162. static int (*Python_PyObject_AsCharBuffer)
  163. (PyObject *, const char **, Py_ssize_t *);
  164. static int (*Python_PyObject_AsReadBuffer)
  165. (PyObject *, const void **, Py_ssize_t *);
  166. static int (*Python_PyObject_AsWriteBuffer)
  167. (PyObject *, void **, Py_ssize_t *);
  168. /* Length argument */
  169. static PyObject *(*Python_PyLong_FromString)(char *, char **, int);
  170. /* Internal use only */
  171. static void (*Python_PyMem_Free)(void *);
  172. static enum UCS { UCS_NONE, UCS2, UCS4 } ucs;
  173. /* Single instance of () */
  174. static PyObject *tuple_empty;
  175. #include "pyml.h"
  176. static void *getcustom( value v )
  177. {
  178. return *((void **)Data_custom_val(v));
  179. }
  180. static void pydecref( value v )
  181. {
  182. if (getcustom(v)) {
  183. Py_DECREF((PyObject *)getcustom(v));
  184. }
  185. }
  186. static int
  187. rich_compare_bool_nofail
  188. (PyObject *o1, PyObject *o2, int opid)
  189. {
  190. int result = Python_PyObject_RichCompareBool(o1, o2, opid);
  191. if (result == -1) {
  192. Python_PyErr_Clear();
  193. result = 0;
  194. }
  195. return result;
  196. }
  197. static int
  198. pycompare(value v1, value v2)
  199. {
  200. int result;
  201. PyObject *o1 = getcustom(v1);
  202. PyObject *o2 = getcustom(v2);
  203. if (o1 && !o2)
  204. result = -1;
  205. else if (o2 && !o1)
  206. result = 1;
  207. else if (!o1 && !o2)
  208. result = 0;
  209. else if (version_major < 3)
  210. Python2_PyObject_Cmp(o1, o2, &result);
  211. else if (rich_compare_bool_nofail(o1, o2, Py_EQ))
  212. result = 0;
  213. else if (rich_compare_bool_nofail(o1, o2, Py_LT))
  214. result = -1;
  215. else if (rich_compare_bool_nofail(o1, o2, Py_GT))
  216. result = 1;
  217. else
  218. result = -1;
  219. return result;
  220. }
  221. static intnat
  222. pyhash( value v )
  223. {
  224. if (getcustom(v)) {
  225. intnat result = Python_PyObject_Hash((PyObject *)getcustom(v));
  226. if (result == -1) {
  227. Python_PyErr_Clear();
  228. }
  229. return result;
  230. }
  231. else {
  232. return 0;
  233. }
  234. }
  235. static uintnat
  236. pydeserialize(void *dst)
  237. {
  238. return 0L;
  239. }
  240. struct custom_operations pyops =
  241. {
  242. "PythonObject",
  243. pydecref,
  244. pycompare,
  245. pyhash,
  246. custom_serialize_default,
  247. pydeserialize
  248. };
  249. enum code {
  250. CODE_NULL,
  251. CODE_NONE,
  252. CODE_TRUE,
  253. CODE_FALSE,
  254. CODE_TUPLE_EMPTY
  255. };
  256. static void *
  257. resolve(const char *symbol)
  258. {
  259. void *result = find_symbol(library, symbol);
  260. if (!result) {
  261. char *fmt = "Cannot resolve %s.\n";
  262. ssize_t size = snprintf(NULL, 0, fmt, symbol);
  263. char *msg = xmalloc(size + 1);
  264. snprintf(msg, size + 1, fmt, symbol);
  265. failwith(msg);
  266. }
  267. return result;
  268. }
  269. static void *
  270. resolve_optional(const char *symbol)
  271. {
  272. return find_symbol(library, symbol);
  273. }
  274. value
  275. pyml_wrap(PyObject *object, bool steal)
  276. {
  277. CAMLparam0();
  278. CAMLlocal1(v);
  279. if (!object) {
  280. CAMLreturn(Val_int(CODE_NULL));
  281. }
  282. if (object == Python__Py_NoneStruct) {
  283. CAMLreturn(Val_int(CODE_NONE));
  284. }
  285. if (object == Python__Py_TrueStruct) {
  286. CAMLreturn(Val_int(CODE_TRUE));
  287. }
  288. if (object == Python__Py_FalseStruct) {
  289. CAMLreturn(Val_int(CODE_FALSE));
  290. }
  291. unsigned long flags =
  292. ((struct _typeobject *) pyobjectdescr(pyobjectdescr(object)->ob_type))
  293. ->tp_flags;
  294. if (flags & Py_TPFLAGS_TUPLE_SUBCLASS
  295. && Python_PySequence_Length(object) == 0) {
  296. CAMLreturn(Val_int(CODE_TUPLE_EMPTY));
  297. }
  298. if (!steal) {
  299. Py_INCREF(object);
  300. }
  301. v = caml_alloc_custom(&pyops, sizeof(PyObject *), 100, 30000000);
  302. *((PyObject **)Data_custom_val(v)) = object;
  303. CAMLreturn(v);
  304. }
  305. PyObject *
  306. pyml_unwrap(value v)
  307. {
  308. if (Is_long(v))
  309. switch (Int_val(v)) {
  310. case CODE_NULL:
  311. return NULL;
  312. case CODE_NONE:
  313. return Python__Py_NoneStruct;
  314. case CODE_TRUE:
  315. return Python__Py_TrueStruct;
  316. case CODE_FALSE:
  317. return Python__Py_FalseStruct;
  318. case CODE_TUPLE_EMPTY:
  319. return tuple_empty;
  320. }
  321. return *((PyObject **)Data_custom_val(v));
  322. }
  323. /*
  324. static value
  325. pyml_wrap_compilerflags(PyCompilerFlags *flags)
  326. {
  327. CAMLparam0();
  328. CAMLlocal2(ref, some);
  329. if (!flags) {
  330. CAMLreturn(Val_int(0));
  331. }
  332. else {
  333. ref = caml_alloc(0, 1);
  334. Store_field(ref, 0, Val_int(flags->cf_flags));
  335. some = caml_alloc(0, 1);
  336. Store_field(some, 0, ref);
  337. CAMLreturn(some);
  338. }
  339. }
  340. */
  341. static PyCompilerFlags *
  342. pyml_unwrap_compilerflags(value v)
  343. {
  344. CAMLparam1(v);
  345. if (Is_block(v)) {
  346. PyCompilerFlags *flags = malloc(sizeof(PyCompilerFlags));
  347. flags->cf_flags = Int_val(Field(Field(v, 0), 0));
  348. CAMLreturnT(PyCompilerFlags *, flags);
  349. }
  350. else {
  351. CAMLreturnT(PyCompilerFlags *, NULL);
  352. }
  353. }
  354. /*
  355. static value
  356. pyml_wrap_intref(int v)
  357. {
  358. CAMLparam0();
  359. CAMLlocal1(ref);
  360. ref = caml_alloc(0, 1);
  361. Store_field(ref, 0, Val_int(v));
  362. CAMLreturn(ref);
  363. }
  364. */
  365. static int
  366. pyml_unwrap_intref(value v)
  367. {
  368. CAMLparam1(v);
  369. CAMLreturnT(int, Int_val(Field(v, 0)));
  370. }
  371. static void *
  372. unwrap_capsule(PyObject *obj, const char *type)
  373. {
  374. if (Python27_PyCapsule_GetPointer) {
  375. return Python27_PyCapsule_GetPointer(obj, type);
  376. }
  377. else {
  378. return Python2_PyCObject_AsVoidPtr(obj);
  379. }
  380. }
  381. static PyObject *
  382. wrap_capsule(void *ptr, char *type, void (*destr)(PyObject *))
  383. {
  384. if (Python27_PyCapsule_New) {
  385. return Python27_PyCapsule_New(ptr, type, destr);
  386. }
  387. else {
  388. return Python2_PyCObject_FromVoidPtr(ptr, (void(*)(void *))destr);
  389. }
  390. }
  391. static PyObject *
  392. pycall_callback(PyObject *obj, PyObject *args)
  393. {
  394. CAMLparam0();
  395. CAMLlocal3(ml_out, ml_func, ml_args);
  396. PyObject *out;
  397. void *p = unwrap_capsule(obj, "ocaml-closure");
  398. if (!p) {
  399. Py_INCREF(Python__Py_NoneStruct);
  400. return Python__Py_NoneStruct;
  401. }
  402. ml_func = *(value *) p;
  403. ml_args = pyml_wrap(args, false);
  404. ml_out = caml_callback(ml_func, ml_args);
  405. out = pyml_unwrap(ml_out);
  406. Py_XINCREF(out);
  407. CAMLreturnT(PyObject *, out);
  408. }
  409. static PyObject *
  410. pycall_callback_with_keywords(PyObject *obj, PyObject *args, PyObject *keywords)
  411. {
  412. CAMLparam0();
  413. CAMLlocal4(ml_out, ml_func, ml_args, ml_keywords);
  414. PyObject *out;
  415. void *p = unwrap_capsule(obj, "ocaml-closure");
  416. if (!p) {
  417. Py_INCREF(Python__Py_NoneStruct);
  418. return Python__Py_NoneStruct;
  419. }
  420. ml_func = *(value *) p;
  421. ml_args = pyml_wrap(args, false);
  422. ml_keywords = pyml_wrap(keywords, false);
  423. ml_out = caml_callback2(ml_func, ml_args, ml_keywords);
  424. out = pyml_unwrap(ml_out);
  425. Py_XINCREF(out);
  426. CAMLreturnT(PyObject *, out);
  427. }
  428. static void
  429. caml_destructor(PyObject *v, const char *capsule_name)
  430. {
  431. value *valptr = (value *) unwrap_capsule(v, capsule_name);
  432. caml_remove_global_root(valptr);
  433. free(valptr);
  434. }
  435. static void
  436. camldestr_closure(PyObject *v)
  437. {
  438. caml_destructor(v, "ocaml-closure");
  439. }
  440. static PyObject *
  441. camlwrap_closure(value val, void *aux_str, int size)
  442. {
  443. value *v = (value *) malloc(sizeof(value) + size);
  444. *v = val;
  445. memcpy((void *)v + sizeof(value), aux_str, size);
  446. caml_register_global_root(v);
  447. return wrap_capsule(v, "ocaml-closure", camldestr_closure);
  448. }
  449. static void
  450. camldestr_capsule(PyObject *v)
  451. {
  452. caml_destructor(v, "ocaml-capsule");
  453. }
  454. static PyObject *
  455. camlwrap_capsule(value val, void *aux_str, int size)
  456. {
  457. value *v = (value *) malloc(sizeof(value) + size);
  458. *v = val;
  459. memcpy((void *)v + sizeof(value), aux_str, size);
  460. caml_register_global_root(v);
  461. return wrap_capsule(v, "ocaml-capsule", camldestr_capsule);
  462. }
  463. static void *
  464. caml_aux(PyObject *obj)
  465. {
  466. value *v = (value *) unwrap_capsule(obj, "ocaml-closure");
  467. return (void *) v + sizeof(value);
  468. }
  469. void
  470. pyml_assert_initialized()
  471. {
  472. if (!version_major) {
  473. failwith("Run 'Py.initialize ()' first");
  474. }
  475. }
  476. void
  477. pyml_assert_python2()
  478. {
  479. if (version_major != 2) {
  480. pyml_assert_initialized();
  481. failwith("Python 2 needed");
  482. }
  483. }
  484. void
  485. pyml_assert_ucs2()
  486. {
  487. if (ucs != UCS2) {
  488. pyml_assert_initialized();
  489. failwith("Python with UCS2 needed");
  490. }
  491. }
  492. void
  493. pyml_assert_ucs4()
  494. {
  495. if (ucs != UCS4) {
  496. pyml_assert_initialized();
  497. failwith("Python with UCS4 needed");
  498. }
  499. }
  500. void
  501. pyml_assert_python3()
  502. {
  503. if (version_major != 3) {
  504. pyml_assert_initialized();
  505. failwith("Python 3 needed");
  506. }
  507. }
  508. void
  509. pyml_check_symbol_available(void *symbol, char *symbol_name)
  510. {
  511. if (!symbol) {
  512. char *fmt = "Symbol unavailable with this version of Python: %s.\n";
  513. ssize_t size = snprintf(NULL, 0, fmt, symbol_name);
  514. if (size < 0) {
  515. failwith("Symbol unavailable with this version of Python.\n");
  516. return;
  517. }
  518. char *msg = xmalloc(size + 1);
  519. size = snprintf(msg, size + 1, fmt, symbol_name);
  520. if (size < 0) {
  521. failwith("Symbol unavailable with this version of Python.\n");
  522. return;
  523. }
  524. failwith(msg);
  525. }
  526. }
  527. void *
  528. deref_not_null(void *pointer)
  529. {
  530. if (pointer) {
  531. return *(void **) pointer;
  532. }
  533. else {
  534. return NULL;
  535. }
  536. }
  537. CAMLprim value
  538. pyml_wrap_closure(value docstring, value closure)
  539. {
  540. CAMLparam2(docstring, closure);
  541. pyml_assert_initialized();
  542. PyMethodDef ml;
  543. PyObject *obj;
  544. PyMethodDef *ml_def;
  545. ml.ml_name = "anonymous_closure";
  546. if (Tag_val(closure) == 0) {
  547. ml.ml_flags = 1;
  548. ml.ml_meth = pycall_callback;
  549. }
  550. else {
  551. ml.ml_flags = 3;
  552. ml.ml_meth = (PyCFunction) pycall_callback_with_keywords;
  553. }
  554. ml.ml_doc = String_val(docstring);
  555. obj = camlwrap_closure(Field(closure, 0), &ml, sizeof(ml));
  556. ml_def = (PyMethodDef *) caml_aux(obj);
  557. PyObject *f = Python_PyCFunction_NewEx(ml_def, obj, NULL);
  558. CAMLreturn(pyml_wrap(f, true));
  559. }
  560. int debug_build;
  561. CAMLprim value
  562. py_load_library(value filename_ocaml, value debug_build_ocaml)
  563. {
  564. CAMLparam2(filename_ocaml, debug_build_ocaml);
  565. if (Is_block(filename_ocaml)) {
  566. char *filename = String_val(Field(filename_ocaml, 0));
  567. library = open_library(filename);
  568. if (!library) {
  569. failwith("Library not found");
  570. }
  571. }
  572. else {
  573. library = get_default_library();
  574. }
  575. Python_Py_GetVersion = find_symbol(library, "Py_GetVersion");
  576. if (!Python_Py_GetVersion) {
  577. failwith("No Python symbol");
  578. }
  579. const char *version = Python_Py_GetVersion();
  580. version_major = version[0] - '0';
  581. version_minor = version[2] - '0';
  582. Python_PyCFunction_NewEx = resolve("PyCFunction_NewEx");
  583. if ((version_major == 2 && version_minor >= 7) || version_major >= 3) {
  584. Python27_PyCapsule_New = resolve("PyCapsule_New");
  585. Python27_PyCapsule_GetPointer = resolve("PyCapsule_GetPointer");
  586. Python27_PyCapsule_IsValid = resolve("PyCapsule_IsValid");
  587. Python27__PyObject_NextNotImplemented =
  588. resolve("_PyObject_NextNotImplemented");
  589. }
  590. Python_PyObject_CallFunctionObjArgs =
  591. resolve("PyObject_CallFunctionObjArgs");
  592. Python_PyObject_CallMethodObjArgs =
  593. resolve("PyObject_CallMethodObjArgs");
  594. Python_PyErr_Fetch = resolve("PyErr_Fetch");
  595. Python_PyErr_NormalizeException = resolve("PyErr_NormalizeException");
  596. Python_PyObject_AsCharBuffer = resolve("PyObject_AsCharBuffer");
  597. Python_PyObject_AsReadBuffer = resolve("PyObject_AsReadBuffer");
  598. Python_PyObject_AsWriteBuffer = resolve("PyObject_AsWriteBuffer");
  599. if (version_major >= 3) {
  600. Python__Py_FalseStruct = resolve("_Py_FalseStruct");
  601. Python_PyString_AsStringAndSize = resolve("PyBytes_AsStringAndSize");
  602. }
  603. else {
  604. Python__Py_FalseStruct = resolve("_Py_ZeroStruct");
  605. Python_PyString_AsStringAndSize = resolve("PyString_AsStringAndSize");
  606. }
  607. Python_PyLong_FromString = resolve("PyLong_FromString");
  608. Python_PyMem_Free = resolve("PyMem_Free");
  609. if (version_major >= 3) {
  610. Python__Py_fopen = resolve("_Py_fopen");
  611. }
  612. else {
  613. Python2_PyCObject_FromVoidPtr = resolve("PyCObject_FromVoidPtr");
  614. Python2_PyCObject_AsVoidPtr = resolve("PyCObject_AsVoidPtr");
  615. }
  616. if (find_symbol(library, "PyUnicodeUCS2_AsEncodedString")) {
  617. ucs = UCS2;
  618. }
  619. else if (find_symbol(library, "PyUnicodeUCS4_AsEncodedString")) {
  620. ucs = UCS4;
  621. }
  622. else {
  623. ucs = UCS_NONE;
  624. }
  625. #include "pyml_dlsyms.inc"
  626. Python_Py_Initialize();
  627. if (Is_block(debug_build_ocaml)) {
  628. debug_build = Int_val(Field(debug_build_ocaml, 0));
  629. }
  630. else {
  631. PyObject *sysconfig = Python_PyImport_ImportModule("sysconfig");
  632. PyObject *get_config_var =
  633. Python_PyObject_GetAttrString(sysconfig, "get_config_var");
  634. PyObject *args;
  635. PyObject *py_debug;
  636. PyObject *debug_build_py;
  637. char *py_debug_str = "Py_DEBUG";
  638. if (version_major >= 3) {
  639. py_debug = Python3_PyUnicode_FromStringAndSize(py_debug_str, 8);
  640. }
  641. else {
  642. py_debug = Python2_PyString_FromStringAndSize(py_debug_str, 8);
  643. }
  644. if (!py_debug) {
  645. failwith("py_debug");
  646. }
  647. args = Python_PyTuple_New(1);
  648. if (!args) {
  649. failwith("PyTuple_New");
  650. }
  651. if (Python_PyTuple_SetItem(args, 0, py_debug)) {
  652. failwith("PyTuple_SetItem");
  653. }
  654. debug_build_py =
  655. Python_PyEval_CallObjectWithKeywords(get_config_var, args, NULL);
  656. if (!debug_build_py) {
  657. failwith("PyEval_CallObjectWithKeywords");
  658. }
  659. if (version_major >= 3) {
  660. debug_build = Python_PyLong_AsLong(debug_build_py);
  661. }
  662. else {
  663. debug_build = Python2_PyInt_AsLong(debug_build_py);
  664. }
  665. if (debug_build == -1) {
  666. failwith("AsLong");
  667. }
  668. }
  669. tuple_empty = Python_PyTuple_New(0);
  670. CAMLreturn(Val_unit);
  671. }
  672. struct PyObjectDebug {
  673. PyObject *_ob_next; \
  674. PyObject *_ob_prev;
  675. PyObjectDescr descr;
  676. };
  677. PyObjectDescr *pyobjectdescr(PyObject *obj) {
  678. if (debug_build) {
  679. return &((struct PyObjectDebug *) obj)->descr;
  680. }
  681. else {
  682. return (PyObjectDescr *) obj;
  683. }
  684. }
  685. CAMLprim value
  686. py_is_debug_build()
  687. {
  688. CAMLparam0();
  689. CAMLreturn(Val_int(debug_build));
  690. }
  691. CAMLprim value
  692. py_finalize_library(value unit)
  693. {
  694. CAMLparam1(unit);
  695. pyml_assert_initialized();
  696. Py_DECREF(tuple_empty);
  697. if (library != get_default_library()) {
  698. close_library(library);
  699. }
  700. version_major = 0;
  701. ucs = UCS_NONE;
  702. CAMLreturn(Val_unit);
  703. }
  704. CAMLprim value
  705. py_unsetenv(value name_ocaml)
  706. {
  707. CAMLparam1(name_ocaml);
  708. char *name = String_val(name_ocaml);
  709. if (unsetenv(name) == -1) {
  710. failwith(strerror(errno));
  711. }
  712. CAMLreturn(Val_unit);
  713. }
  714. CAMLprim value
  715. py_get_UCS(value unit)
  716. {
  717. CAMLparam1(unit);
  718. pyml_assert_initialized();
  719. CAMLreturn(Val_int(ucs));
  720. }
  721. CAMLprim value
  722. PyNull_wrapper(value unit)
  723. {
  724. CAMLparam1(unit);
  725. CAMLreturn(Val_int(CODE_NULL));
  726. }
  727. CAMLprim value
  728. PyNone_wrapper(value unit)
  729. {
  730. CAMLparam1(unit);
  731. CAMLreturn(Val_int(CODE_NONE));
  732. }
  733. CAMLprim value
  734. PyTrue_wrapper(value unit)
  735. {
  736. CAMLparam1(unit);
  737. CAMLreturn(Val_int(CODE_TRUE));
  738. }
  739. CAMLprim value
  740. PyFalse_wrapper(value unit)
  741. {
  742. CAMLparam1(unit);
  743. CAMLreturn(Val_int(CODE_FALSE));
  744. }
  745. CAMLprim value
  746. PyTuple_Empty_wrapper(value unit)
  747. {
  748. CAMLparam1(unit);
  749. CAMLreturn(Val_int(CODE_TUPLE_EMPTY));
  750. }
  751. enum pytype_labels {
  752. PyUnknown,
  753. Bool,
  754. Bytes,
  755. Callable,
  756. Capsule,
  757. Closure,
  758. Dict,
  759. Float,
  760. List,
  761. Int,
  762. Long,
  763. Module,
  764. NoneType,
  765. Null,
  766. Tuple,
  767. Type,
  768. Unicode,
  769. Iter
  770. };
  771. CAMLprim value
  772. pytype(value object_ocaml)
  773. {
  774. CAMLparam1(object_ocaml);
  775. pyml_assert_initialized();
  776. PyObject *object = pyml_unwrap(object_ocaml);
  777. if (!object) {
  778. CAMLreturn(Val_int(Null));
  779. }
  780. PyObject *ob_type = pyobjectdescr(object)->ob_type;
  781. struct _typeobject *typeobj = (struct _typeobject *) pyobjectdescr(ob_type);
  782. unsigned long flags = typeobj->tp_flags;
  783. int result;
  784. if (ob_type == Python_PyBool_Type) {
  785. result = Bool;
  786. }
  787. else if (flags & Py_TPFLAGS_BYTES_SUBCLASS) {
  788. result = Bytes;
  789. }
  790. else if (Python_PyCallable_Check(object)) {
  791. result = Callable;
  792. }
  793. else if (Python27_PyCapsule_IsValid
  794. && Python27_PyCapsule_IsValid(object, "ocaml-capsule")) {
  795. result = Capsule;
  796. }
  797. else if (Python27_PyCapsule_IsValid
  798. && Python27_PyCapsule_IsValid(object, "ocaml-closure")) {
  799. result = Closure;
  800. }
  801. else if (flags & Py_TPFLAGS_DICT_SUBCLASS) {
  802. result = Dict;
  803. }
  804. else if (ob_type == Python_PyFloat_Type ||
  805. Python_PyType_IsSubtype(ob_type, Python_PyFloat_Type)) {
  806. result = Float;
  807. }
  808. else if (flags & Py_TPFLAGS_LIST_SUBCLASS) {
  809. result = List;
  810. }
  811. else if (flags & Py_TPFLAGS_INT_SUBCLASS) {
  812. result = Int;
  813. }
  814. else if (flags & Py_TPFLAGS_LONG_SUBCLASS) {
  815. result = Long;
  816. }
  817. else if (ob_type == Python_PyModule_Type ||
  818. Python_PyType_IsSubtype(ob_type, Python_PyModule_Type)) {
  819. result = Module;
  820. }
  821. else if (object == Python__Py_NoneStruct) {
  822. result = NoneType;
  823. }
  824. else if (flags & Py_TPFLAGS_TUPLE_SUBCLASS) {
  825. result = Tuple;
  826. }
  827. else if (flags & Py_TPFLAGS_TYPE_SUBCLASS) {
  828. result = Type;
  829. }
  830. else if (flags & Py_TPFLAGS_UNICODE_SUBCLASS) {
  831. result = Unicode;
  832. }
  833. else if (typeobj->tp_iternext != NULL &&
  834. typeobj->tp_iternext != &Python27__PyObject_NextNotImplemented) {
  835. result = Iter;
  836. }
  837. else {
  838. result = PyUnknown;
  839. }
  840. CAMLreturn(Val_int(result));
  841. }
  842. CAMLprim value
  843. PyObject_CallFunctionObjArgs_wrapper(
  844. value callable_ocaml, value arguments_ocaml)
  845. {
  846. CAMLparam2(callable_ocaml, arguments_ocaml);
  847. pyml_assert_initialized();
  848. PyObject *callable = pyml_unwrap(callable_ocaml);
  849. PyObject *result;
  850. mlsize_t argument_count = Wosize_val(arguments_ocaml);
  851. switch (argument_count) {
  852. case 0:
  853. result = Python_PyObject_CallFunctionObjArgs(callable, NULL);
  854. break;
  855. case 1:
  856. result = Python_PyObject_CallFunctionObjArgs
  857. (callable,
  858. pyml_unwrap(Field(arguments_ocaml, 0)),
  859. NULL);
  860. break;
  861. case 2:
  862. result = Python_PyObject_CallFunctionObjArgs
  863. (callable,
  864. pyml_unwrap(Field(arguments_ocaml, 0)),
  865. pyml_unwrap(Field(arguments_ocaml, 1)),
  866. NULL);
  867. break;
  868. case 3:
  869. result = Python_PyObject_CallFunctionObjArgs
  870. (callable,
  871. pyml_unwrap(Field(arguments_ocaml, 0)),
  872. pyml_unwrap(Field(arguments_ocaml, 1)),
  873. pyml_unwrap(Field(arguments_ocaml, 2)),
  874. NULL);
  875. break;
  876. case 4:
  877. result = Python_PyObject_CallFunctionObjArgs
  878. (callable,
  879. pyml_unwrap(Field(arguments_ocaml, 0)),
  880. pyml_unwrap(Field(arguments_ocaml, 1)),
  881. pyml_unwrap(Field(arguments_ocaml, 2)),
  882. pyml_unwrap(Field(arguments_ocaml, 3)),
  883. NULL);
  884. break;
  885. case 5:
  886. result = Python_PyObject_CallFunctionObjArgs
  887. (callable,
  888. pyml_unwrap(Field(arguments_ocaml, 0)),
  889. pyml_unwrap(Field(arguments_ocaml, 1)),
  890. pyml_unwrap(Field(arguments_ocaml, 2)),
  891. pyml_unwrap(Field(arguments_ocaml, 3)),
  892. pyml_unwrap(Field(arguments_ocaml, 4)),
  893. NULL);
  894. break;
  895. default:
  896. fprintf(stderr,
  897. "PyObject_CallFunctionObjArgs_wrapper not implemented for more "
  898. "than 5 arguments\n");
  899. exit(EXIT_FAILURE);
  900. }
  901. CAMLreturn(pyml_wrap(result, true));
  902. }
  903. CAMLprim value
  904. PyObject_CallMethodObjArgs_wrapper(
  905. value object_ocaml, value name_ocaml, value arguments_ocaml)
  906. {
  907. CAMLparam3(object_ocaml, name_ocaml, arguments_ocaml);
  908. pyml_assert_initialized();
  909. PyObject *object = pyml_unwrap(object_ocaml);
  910. PyObject *name = pyml_unwrap(name_ocaml);
  911. PyObject *result;
  912. mlsize_t argument_count = Wosize_val(arguments_ocaml);
  913. switch (argument_count) {
  914. case 0:
  915. result = Python_PyObject_CallMethodObjArgs(object, name);
  916. break;
  917. case 1:
  918. result = Python_PyObject_CallMethodObjArgs
  919. (object, name,
  920. pyml_unwrap(Field(arguments_ocaml, 0)),
  921. NULL);
  922. break;
  923. case 2:
  924. result = Python_PyObject_CallMethodObjArgs
  925. (object, name,
  926. pyml_unwrap(Field(arguments_ocaml, 0)),
  927. pyml_unwrap(Field(arguments_ocaml, 1)),
  928. NULL);
  929. break;
  930. case 3:
  931. result = Python_PyObject_CallMethodObjArgs
  932. (object, name,
  933. pyml_unwrap(Field(arguments_ocaml, 0)),
  934. pyml_unwrap(Field(arguments_ocaml, 1)),
  935. pyml_unwrap(Field(arguments_ocaml, 2)),
  936. NULL);
  937. break;
  938. case 4:
  939. result = Python_PyObject_CallMethodObjArgs
  940. (object, name,
  941. pyml_unwrap(Field(arguments_ocaml, 0)),
  942. pyml_unwrap(Field(arguments_ocaml, 1)),
  943. pyml_unwrap(Field(arguments_ocaml, 2)),
  944. pyml_unwrap(Field(arguments_ocaml, 3)),
  945. NULL);
  946. break;
  947. case 5:
  948. result = Python_PyObject_CallMethodObjArgs
  949. (object, name,
  950. pyml_unwrap(Field(arguments_ocaml, 0)),
  951. pyml_unwrap(Field(arguments_ocaml, 1)),
  952. pyml_unwrap(Field(arguments_ocaml, 2)),
  953. pyml_unwrap(Field(arguments_ocaml, 3)),
  954. pyml_unwrap(Field(arguments_ocaml, 4)),
  955. NULL);
  956. break;
  957. default:
  958. fprintf(stderr,
  959. "PyObject_CallMethodObjArgs_wrapper not implemented for more "
  960. "than 5 arguments\n");
  961. exit(EXIT_FAILURE);
  962. }
  963. CAMLreturn(pyml_wrap(result, true));
  964. }
  965. CAMLprim value
  966. pyml_wrap_value(value v)
  967. {
  968. CAMLparam1(v);
  969. pyml_assert_initialized();
  970. PyObject *result = camlwrap_capsule(v, NULL, 0);
  971. CAMLreturn(pyml_wrap(result, true));
  972. }
  973. CAMLprim value
  974. pyml_unwrap_value(value x_ocaml)
  975. {
  976. CAMLparam1(x_ocaml);
  977. CAMLlocal1(v);
  978. pyml_assert_initialized();
  979. PyObject *x = pyml_unwrap(x_ocaml);
  980. void *p = unwrap_capsule(x, "ocaml-capsule");
  981. if (!p) {
  982. fprintf(stderr, "pyml_unwrap_value: type mismatch");
  983. exit(EXIT_FAILURE);
  984. }
  985. v = *(value *) p;
  986. CAMLreturn(v);
  987. }
  988. CAMLprim value
  989. PyErr_Fetch_wrapper(value unit)
  990. {
  991. CAMLparam1(unit);
  992. CAMLlocal1(result);
  993. pyml_assert_initialized();
  994. PyObject *excType, *excValue, *excTraceback;
  995. Python_PyErr_Fetch(&excType, &excValue, &excTraceback);
  996. Python_PyErr_NormalizeException(&excType, &excValue, &excTraceback);
  997. result = caml_alloc_tuple(3);
  998. Store_field(result, 0, pyml_wrap(excType, false));
  999. Store_field(result, 1, pyml_wrap(excValue, false));
  1000. Store_field(result, 2, pyml_wrap(excTraceback, false));
  1001. CAMLreturn(result);
  1002. }
  1003. CAMLprim value
  1004. pyml_wrap_string_option(char *s)
  1005. {
  1006. CAMLparam0();
  1007. CAMLlocal1(result);
  1008. if (!s) {
  1009. CAMLreturn(Val_int(0));
  1010. }
  1011. result = caml_alloc_tuple(1);
  1012. Store_field(result, 0, caml_copy_string(s));
  1013. CAMLreturn(result);
  1014. }
  1015. CAMLprim value
  1016. pyrefcount(value pyobj)
  1017. {
  1018. CAMLparam1(pyobj);
  1019. PyObject *obj = pyml_unwrap(pyobj);
  1020. CAMLreturn(Val_int(pyobjectdescr(obj)->ob_refcnt));
  1021. }
  1022. static value
  1023. pyml_wrap_wide_string(wchar_t *ws)
  1024. {
  1025. CAMLparam0();
  1026. CAMLlocal1(result);
  1027. size_t n = wcstombs(NULL, ws, 0);
  1028. if (n == (size_t) -1) {
  1029. fprintf(stderr, "pyml_wrap_wide_string failure.\n");
  1030. exit(EXIT_FAILURE);
  1031. }
  1032. char *s = xmalloc((n + 1) * sizeof (char));
  1033. wcstombs(s, ws, n);
  1034. result = caml_copy_string(s);
  1035. free(s);
  1036. CAMLreturn(result);
  1037. }
  1038. static wchar_t *
  1039. pyml_unwrap_wide_string(value string_ocaml)
  1040. {
  1041. CAMLparam1(string_ocaml);
  1042. char *s = String_val(string_ocaml);
  1043. size_t n = mbstowcs(NULL, s, 0);
  1044. if (n == (size_t) -1) {
  1045. fprintf(stderr, "pyml_unwrap_wide_string failure.\n");
  1046. exit(EXIT_FAILURE);
  1047. }
  1048. wchar_t *ws = xmalloc((n + 1) * sizeof (wchar_t));
  1049. mbstowcs(ws, s, n);
  1050. CAMLreturnT(wchar_t *, ws);
  1051. }
  1052. static int16_t *
  1053. pyml_unwrap_ucs2(value array_ocaml)
  1054. {
  1055. CAMLparam1(array_ocaml);
  1056. mlsize_t len = Wosize_val(array_ocaml);
  1057. int16_t *result = xmalloc(len * sizeof(int16_t));
  1058. size_t i;
  1059. for (i = 0; i < len; i++) {
  1060. result[i] = Field(array_ocaml, i);
  1061. }
  1062. CAMLreturnT(int16_t *, result);
  1063. }
  1064. static int32_t *
  1065. pyml_unwrap_ucs4(value array_ocaml)
  1066. {
  1067. CAMLparam1(array_ocaml);
  1068. mlsize_t len = Wosize_val(array_ocaml);
  1069. int32_t *result = xmalloc(len * sizeof(int32_t));
  1070. size_t i;
  1071. for (i = 0; i < len; i++) {
  1072. result[i] = Field(array_ocaml, i);
  1073. }
  1074. CAMLreturnT(int32_t *, result);
  1075. }
  1076. static value
  1077. pyml_wrap_ucs2_option(int16_t *buffer)
  1078. {
  1079. CAMLparam0();
  1080. CAMLlocal2(result, array);
  1081. mlsize_t len;
  1082. if (buffer == NULL) {
  1083. CAMLreturn(Val_int(0));
  1084. }
  1085. len = 0;
  1086. while (buffer[len]) {
  1087. len++;
  1088. }
  1089. array = caml_alloc_tuple(len);
  1090. size_t i;
  1091. for (i = 0; i < len; i++) {
  1092. Store_field(array, i, buffer[i]);
  1093. }
  1094. result = caml_alloc_tuple(1);
  1095. Store_field(result, 0, array);
  1096. CAMLreturn(result);
  1097. }
  1098. static value
  1099. pyml_wrap_ucs4_option_and_free(int32_t *buffer, bool free)
  1100. {
  1101. CAMLparam0();
  1102. CAMLlocal2(result, array);
  1103. mlsize_t len;
  1104. if (buffer == NULL) {
  1105. CAMLreturn(Val_int(0));
  1106. }
  1107. len = 0;
  1108. while (buffer[len]) {
  1109. len++;
  1110. }
  1111. array = caml_alloc_tuple(len);
  1112. size_t i;
  1113. for (i = 0; i < len; i++) {
  1114. Store_field(array, i, buffer[i]);
  1115. }
  1116. result = caml_alloc_tuple(1);
  1117. Store_field(result, 0, array);
  1118. if (free) {
  1119. Python_PyMem_Free(buffer);
  1120. }
  1121. CAMLreturn(result);
  1122. }
  1123. #define StringAndSize_wrapper(func, byte_type) \
  1124. CAMLprim value \
  1125. func##_wrapper(value arg_ocaml) \
  1126. { \
  1127. CAMLparam1(arg_ocaml); \
  1128. CAMLlocal2(result, string); \
  1129. PyObject *arg = pyml_unwrap(arg_ocaml); \
  1130. byte_type *buffer; \
  1131. Py_ssize_t length; \
  1132. int return_value; \
  1133. return_value = Python_##func(arg, &buffer, &length); \
  1134. if (return_value == -1) { \
  1135. CAMLreturn(Val_int(0)); \
  1136. } \
  1137. string = caml_alloc_string(length); \
  1138. memcpy(String_val(string), buffer, length); \
  1139. result = caml_alloc_tuple(1); \
  1140. Store_field(result, 0, string); \
  1141. CAMLreturn(result); \
  1142. }
  1143. StringAndSize_wrapper(PyString_AsStringAndSize, char);
  1144. StringAndSize_wrapper(PyObject_AsCharBuffer, const char);
  1145. StringAndSize_wrapper(PyObject_AsReadBuffer, const void);
  1146. StringAndSize_wrapper(PyObject_AsWriteBuffer, void);
  1147. static FILE *
  1148. open_file(value file, const char *mode)
  1149. {
  1150. CAMLparam1(file);
  1151. FILE *result;
  1152. if (Tag_val(file) == 0) {
  1153. char *filename = String_val(Field(file, 0));
  1154. if (version_major >= 3) {
  1155. result = Python__Py_fopen(filename, mode);
  1156. }
  1157. else {
  1158. result = fopen(filename, mode);
  1159. }
  1160. }
  1161. else {
  1162. result = file_of_file_descr(Field(file, 0), mode);
  1163. }
  1164. CAMLreturnT(FILE *, result);
  1165. }
  1166. static void
  1167. close_file(value file, FILE *file_struct)
  1168. {
  1169. CAMLparam1(file);
  1170. if (Tag_val(file) == 0) {
  1171. if (version_major >= 3) {
  1172. /* No _Py_fclose :( */
  1173. }
  1174. else {
  1175. fclose(file_struct);
  1176. }
  1177. }
  1178. else if (Tag_val(file) == 1) {
  1179. fclose(file_struct);
  1180. }
  1181. CAMLreturn0;
  1182. }
  1183. /* Numpy */
  1184. void **
  1185. pyml_get_pyarray_api(PyObject *c_api)
  1186. {
  1187. if (version_major >= 3) {
  1188. return (void **)Python27_PyCapsule_GetPointer(c_api, NULL);
  1189. }
  1190. else {
  1191. return (void **)Python2_PyCObject_AsVoidPtr(c_api);
  1192. }
  1193. }
  1194. CAMLprim value
  1195. get_pyarray_type(value numpy_api_ocaml)
  1196. {
  1197. CAMLparam1(numpy_api_ocaml);
  1198. PyObject *c_api = pyml_unwrap(numpy_api_ocaml);
  1199. void **PyArray_API = pyml_get_pyarray_api(c_api);
  1200. PyObject *result = PyArray_API[2];
  1201. CAMLreturn(pyml_wrap(result, true));
  1202. }
  1203. CAMLprim value
  1204. pyarray_of_floatarray_wrapper(
  1205. value numpy_api_ocaml, value array_type_ocaml, value array_ocaml)
  1206. {
  1207. CAMLparam3(numpy_api_ocaml, array_type_ocaml, array_ocaml);
  1208. pyml_assert_initialized();
  1209. PyObject *c_api = pyml_unwrap(numpy_api_ocaml);
  1210. void **PyArray_API = pyml_get_pyarray_api(c_api);
  1211. PyObject *(*PyArray_New)
  1212. (PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int,
  1213. PyObject *) = PyArray_API[93];
  1214. npy_intp length = Wosize_val(array_ocaml);
  1215. void *data = (double *) array_ocaml;
  1216. PyTypeObject (*PyArray_SubType) =
  1217. (PyTypeObject *) pyml_unwrap(array_type_ocaml);
  1218. PyObject *result = PyArray_New(
  1219. PyArray_SubType, 1, &length, NPY_DOUBLE, NULL, data, 0,
  1220. NPY_ARRAY_CARRAY, NULL);
  1221. CAMLreturn(pyml_wrap(result, true));
  1222. }
  1223. CAMLprim value
  1224. PyLong_FromString_wrapper(value str_ocaml, value base_ocaml)
  1225. {
  1226. CAMLparam2(str_ocaml, base_ocaml);
  1227. CAMLlocal1(result);
  1228. pyml_assert_initialized();
  1229. char *str = String_val(str_ocaml);
  1230. char *pend;
  1231. int base = Int_val(base_ocaml);
  1232. PyObject *l = Python_PyLong_FromString(str, &pend, base);
  1233. ssize_t len = pend - str;
  1234. result = caml_alloc_tuple(2);
  1235. Store_field(result, 0, pyml_wrap(l, true));
  1236. Store_field(result, 1, Val_int(len));
  1237. CAMLreturn(result);
  1238. }
  1239. CAMLprim value
  1240. Python27_PyCapsule_IsValid_wrapper(value arg0_ocaml, value arg1_ocaml)
  1241. {
  1242. CAMLparam2(arg0_ocaml, arg1_ocaml);
  1243. pyml_assert_initialized();
  1244. if (!Python27_PyCapsule_IsValid) {
  1245. failwith("PyCapsule_IsValid is only available in Python >2.7");
  1246. }
  1247. PyObject *arg0 = pyml_unwrap(arg0_ocaml);
  1248. char *arg1 = String_val(arg1_ocaml);
  1249. int result = Python27_PyCapsule_IsValid(arg0, arg1);
  1250. CAMLreturn(Val_int(result));
  1251. }
  1252. #include "pyml_wrappers.inc"