-
Notifications
You must be signed in to change notification settings - Fork 165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BindPython ABI #2796
BindPython ABI #2796
Changes from 12 commits
272889a
51e3975
67853c7
94fa4b6
f256e43
57b0e80
ff32b75
42565b5
31f1225
62ae095
24f52fa
3d1b50e
a3bca79
3cf7b22
432b184
dd6a76b
8278e43
644a453
e750a04
9ea5cdc
839f6b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#ifndef LIBASR_PASS_PYTHON_BIND_H | ||
#define LIBASR_PASS_PYTHON_BIND_H | ||
|
||
#include <libasr/asr.h> | ||
#include <libasr/utils.h> | ||
|
||
namespace LCompilers { | ||
|
||
void pass_python_bind(Allocator &al, ASR::TranslationUnit_t &unit, | ||
const PassOptions &pass_options); | ||
|
||
} // namespace LCompilers | ||
|
||
#endif // LIBASR_PASS_PYTHON_BIND_H |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -4248,6 +4248,7 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> { | |||
bool is_interface = false; | ||||
std::string interface_name = ""; | ||||
bool is_derived_type = false; | ||||
bool contains_bindpython = false; | ||||
std::vector<std::string> current_procedure_args; | ||||
ASR::abiType current_procedure_abi_type = ASR::abiType::Source; | ||||
std::map<SymbolTable*, ASR::accessType> assgn; | ||||
|
@@ -4428,6 +4429,55 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> { | |||
//Implemented in BodyVisitor | ||||
} | ||||
|
||||
void import_cpython(const AST::FunctionDef_t &x, SymbolTable *parent_scope) { | ||||
std::vector<std::string> pybind_funcs = { | ||||
"Py_Initialize", | ||||
"Py_IsInitialized", | ||||
"PyRun_SimpleString", | ||||
"Py_DecodeLocale", | ||||
"PySys_SetArgv", | ||||
"Py_FinalizeEx", | ||||
"PyUnicode_FromString", | ||||
"PyUnicode_AsUTF8AndSize", | ||||
"PyImport_Import", | ||||
"Py_DecRef", | ||||
"Py_IncRef", | ||||
"PyObject_GetAttrString", | ||||
"PyTuple_New", | ||||
"PyTuple_SetItem", | ||||
"PyObject_CallObject", | ||||
"PyLong_AsLongLong", | ||||
"PyLong_AsUnsignedLongLong", | ||||
"PyLong_FromLongLong", | ||||
"PyLong_FromUnsignedLongLong", | ||||
"PyFloat_FromDouble", | ||||
"PyFloat_AsDouble", | ||||
"PyBool_FromLong", | ||||
"PyObject_IsTrue", | ||||
}; | ||||
Str s; | ||||
AST::alias_t *module_symbols = | ||||
al.allocate<AST::alias_t>(pybind_funcs.size()); | ||||
|
||||
for (size_t i = 0; i < pybind_funcs.size(); i++) { | ||||
s.from_str(al, pybind_funcs.at(i)); | ||||
(module_symbols + i)->loc = x.base.base.loc; | ||||
(module_symbols + i)->m_name = s.c_str(al); | ||||
(module_symbols + i)->m_asname = nullptr; | ||||
} | ||||
|
||||
AST::ImportFrom_t *imports = | ||||
(AST::ImportFrom_t*)AST::make_ImportFrom_t( | ||||
al, x.base.base.loc, | ||||
(char*)"cpython_bindings", module_symbols, | ||||
pybind_funcs.size(), 0); | ||||
|
||||
SymbolTable *function_scope = current_scope; | ||||
current_scope = parent_scope; | ||||
visit_ImportFrom(*imports); | ||||
current_scope = function_scope; | ||||
} | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are these needed in AST->ASR? Ideally the initial ASR has nothing to do with Python C/API. Then the ASR->ASR pass translates There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly, even I was confused in my last meet with Vipul. Looking into the changes, I think I understand what he is doing here. He has a new runtime module
When he visits the @Vipul-Cariappa Initially this approach sounded interesting to me, but now after going through the changes, it seems like we should instead write the ASR code for these directly in the lpython/src/libasr/codegen/asr_to_wasm.cpp Line 206 in 9374feb
runtime/cpython_bindings.py file.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok. I will update the code to generate the required function declarations in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, exactly. |
||||
|
||||
void visit_FunctionDef(const AST::FunctionDef_t &x) { | ||||
dependencies.clear(al); | ||||
SymbolTable *parent_scope = current_scope; | ||||
|
@@ -4489,6 +4539,13 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> { | |||
current_procedure_abi_type = ASR::abiType::BindPython; | ||||
current_procedure_interface = true; | ||||
module_file = extract_keyword_val_from_decorator(call_d, "module"); | ||||
|
||||
if (!contains_bindpython) { | ||||
|
||||
import_cpython(x, parent_scope); | ||||
} | ||||
contains_bindpython = true; | ||||
|
||||
} else { | ||||
throw SemanticError("Unsupported Decorator type", | ||||
x.base.base.loc); | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
from lpython import ccall, Pointer, i32, i64, u64, f64, empty_c_void_p, CPtr, pointer | ||
|
||
@ccall(header="Python.h") | ||
def Py_Initialize(): | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def Py_IsInitialized() -> i32: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyRun_SimpleString(s: str) -> i32: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def Py_DecodeLocale(s: str, p: CPtr) -> CPtr: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PySys_SetArgv(n: i32, args: Pointer[CPtr]): | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def Py_FinalizeEx() -> i32: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyUnicode_FromString(s: str) -> CPtr: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyUnicode_AsUTF8AndSize(s: CPtr, l: CPtr) -> str: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyImport_Import(name: CPtr) -> CPtr: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def Py_DecRef(name: CPtr): | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def Py_IncRef(name: CPtr): | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyObject_GetAttrString(m: CPtr, s: str) -> CPtr: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyTuple_New(n: i32) -> CPtr: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyTuple_SetItem(t: CPtr, p: i32, o: CPtr) -> i32: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyObject_CallObject(a: CPtr, b: CPtr) -> CPtr: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyLong_AsLongLong(a: CPtr) -> i64: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyLong_AsUnsignedLongLong(a: CPtr) -> u64: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyLong_FromLongLong(a: i64) -> CPtr: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyLong_FromUnsignedLongLong(a: u64) -> CPtr: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyFloat_FromDouble(a: f64) -> CPtr: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyFloat_AsDouble(a: CPtr) -> f64: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyBool_FromLong(a: i32) -> CPtr: | ||
pass | ||
|
||
@ccall(header="Python.h") | ||
def PyObject_IsTrue(a: CPtr) -> i32: | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have
--backend=c
which means the backend isc
. Anotherc_backend
could seem confusing. I think we should call it something likec_skip_bindpy_pass
.We should also enable this flag in
emit_c_to_file()
.