{"id":16574654,"url":"https://github.com/hoodmane/clang-python-fpcast-plugin","last_synced_at":"2025-10-09T08:41:26.148Z","repository":{"id":84689951,"uuid":"430238112","full_name":"hoodmane/clang-python-fpcast-plugin","owner":"hoodmane","description":"A clang plugin to fix up common function pointer casts in Python C code","archived":false,"fork":false,"pushed_at":"2021-11-21T08:09:53.000Z","size":23,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-16T05:12:09.849Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hoodmane.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-21T00:18:15.000Z","updated_at":"2021-11-21T08:09:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"d8c82e9f-c5fe-4f44-b99f-47e1caf60458","html_url":"https://github.com/hoodmane/clang-python-fpcast-plugin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoodmane%2Fclang-python-fpcast-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoodmane%2Fclang-python-fpcast-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoodmane%2Fclang-python-fpcast-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoodmane%2Fclang-python-fpcast-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hoodmane","download_url":"https://codeload.github.com/hoodmane/clang-python-fpcast-plugin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242067720,"owners_count":20066750,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T21:45:10.254Z","updated_at":"2025-10-09T08:41:21.097Z","avatar_url":"https://github.com/hoodmane.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Clang Python Wasm Plugin\nA clang plugin to fix up common function pointer casts in Python C code. Thanks\nto [clang-tutor](https://github.com/banach-space/clang-tutor) for helping me to\nunderstand. Both the code itself and especially the CMakeLists files are heavily\ncopied from them.\n\n## Work in progress\n\nStill need to figure out how to use this in Pyodide build process\n(see [the fpcast removal PR](https://github.com/pyodide/pyodide/pull/1677)).\n\n## Why?\n\nThere are two types of function pointer casting that are common in Python code\nthat we want to detect and patch.\n```C\nPyObject*\nsome_method(PyObject* self){\n    // method body\n}\n\n// ... later\nPyMethodDef {\n    .ml_name = \"myfunc2\",\n    .ml_flags = METH_NOARGS,\n    .ml_meth = (PyCFunction)myfunc\n}\n```\nThe problem: `some_method` is a `METH_NOARGS` method. These should have\nsignature `PyObject* some_method(PyObject* self, PyObject* always_null)`. The\nactual call occurs here:\nhttps://github.com/python/cpython/blob/main/Objects/methodobject.c#L489 and\nlooks like `PyObject *result = meth(PyCFunction_GET_SELF(func), NULL);` In x86,\nit's okay to cast `some_method` to a function of two arguments and call it with\na second argument. The second argument will be ignored and everything works\nfine. In wasm, this causes an \"indirect call signature mismatch\" trap. We need to patch\n`some_method` to take a second argument.\n\nThe second common problem is with getters and setters:\n```C\nPyObject*\narrayflags_updateifcopy_get(PyObject *self){\n    return NULL;\n}\n\nint\narrayflags_updateifcopy_set(PyObject *self, PyObject *val){\n    return 0;\n}\n\nPyGetSetDef blah = {\n    \"updateifcopy\",                      // char* name;\n    (getter)arrayflags_updateifcopy_get, // getter get;\n    (setter)arrayflags_updateifcopy_set, // setter set;\n    NULL,  // char* doc\n    NULL   // void* closure\n};\n```\nThe type signature for `getter` is\n`PyObject* func(PyObject *self, void *closure)`.\nThe type signature for `setter` is\n`PyObject* func(PyObject *self, PyObject *value, void *closure)`.\n\nThe last field of `PyGetSetDef` is a \"closure\" which is always passed as a last\nargument to the getter and setter. In many examples, this closure argument goes\nunused, and so people leave it out entirely. Again, we get function signature\nmismatch traps at runtime.\n\n\n## Installing clang 13 / llvm 13\nWe first need to install clang 13. I think it's desirable to avoid building it,\nthough that is of course possible. There are instructions here:\nhttps://apt.llvm.org/\n\nI think the specific invocation that worked for me was:\n```sh\nwget https://apt.llvm.org/llvm.sh\nchmod +x llvm.sh\nsudo ./llvm.sh 13\napt-get install libclang-13-dev\n```\n\n## Building\n\nI build this as follows:\n```sh\nmkdir build\ncmake -DClang_INSTALL_DIR=/usr/lib/llvm-13/ ..\nmake\n```\n\n## Running\nOnce you've built the plugin, from the root directory you can run it as:\n```sh\nclang -cc1 -load build/lib/libMyPlugin.so -plugin LAC test/test.c\n```\nIf you get an error like\n`error: unable to load plugin 'lib/libMyPlugin.so': 'lib/libMyPlugin.so: undefined symbol`,\nyou are probably using the wrong version of clang.\nTry `clang --version` and make sure it's version 13.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoodmane%2Fclang-python-fpcast-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoodmane%2Fclang-python-fpcast-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoodmane%2Fclang-python-fpcast-plugin/lists"}