Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/capi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ license.workspace = true
crate-type = ["cdylib", "rlib"]

[dependencies]
rustpython-vm = { workspace = true, features = ["threading"] }
rustpython-vm = { workspace = true, features = ["threading", "compiler"] }
rustpython-stdlib = {workspace = true, features = ["threading"] }

[dev-dependencies]
Expand Down
84 changes: 84 additions & 0 deletions crates/capi/src/ceval.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use crate::pystate::with_vm;
use core::ffi::{CStr, c_char, c_int};
use core::ptr::NonNull;
use rustpython_vm::builtins::{PyCode, PyDict};
use rustpython_vm::compiler::Mode;
use rustpython_vm::function::ArgMapping;
use rustpython_vm::scope::Scope;
use rustpython_vm::{AsObject, PyObject, TryFromObject};

#[unsafe(no_mangle)]
pub unsafe extern "C" fn Py_CompileString(
code: *const c_char,
filename: *const c_char,
start: c_int,
) -> *mut PyObject {
with_vm(|vm| {
let code = unsafe { CStr::from_ptr(code) }.to_str().map_err(|_| {
vm.new_system_error("Py_CompileString called with non UTF-8 code string")
})?;
let filename = unsafe { CStr::from_ptr(filename) }
.to_str()
.map_err(|_| vm.new_system_error("Py_CompileString called with non UTF-8 filename"))?;
Comment thread
coderabbitai[bot] marked this conversation as resolved.

let mode = match start {
256 => Mode::Single,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's these numbers? do they have proper name or symbol?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added constants for these values.

257 => Mode::Exec,
258 => Mode::Eval,
_ => {
return Err(
vm.new_system_error("Invalid start argument passed to Py_CompileString")
);
}
};

vm.compile(code, mode, filename.to_owned())
.map_err(|err| vm.new_syntax_error(&err, Some(code)))
})
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn PyEval_EvalCode(
co: *mut PyObject,
globals: *mut PyObject,
locals: *mut PyObject,
) -> *mut PyObject {
with_vm(|vm| {
let code = unsafe { &*co }.try_downcast_ref::<PyCode>(vm)?;
let globals = unsafe { &*globals }.try_downcast_ref::<PyDict>(vm)?;
let locals = NonNull::new(locals)
.map(|ptr| ArgMapping::try_from_object(vm, unsafe { ptr.as_ref() }.to_owned()))
.transpose()?;

let scope = Scope::with_builtins(locals, globals.to_owned(), vm);

vm.run_code_obj(code.to_owned(), scope)
})
}

#[unsafe(no_mangle)]
pub extern "C" fn PyEval_GetBuiltins() -> *mut PyObject {
with_vm(|vm| vm.builtins.as_object().as_raw())
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}

#[cfg(false)]
mod tests {
use pyo3::exceptions::PyException;
use pyo3::prelude::*;

#[test]
fn test_code_eval() {
Python::attach(|py| {
let result = py.eval(c"1 + 1", None, None).unwrap();
assert_eq!(result.extract::<u32>().unwrap(), 2);
})
}

#[test]
fn test_code_run_exception() {
Python::attach(|py| {
let err = py.run(c"raise Exception()", None, None).unwrap_err();
assert!(err.is_instance_of::<PyException>(py));
})
}
}
1 change: 1 addition & 0 deletions crates/capi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern crate alloc;

pub mod abstract_;
pub mod bytesobject;
pub mod ceval;
pub mod import;
pub mod longobject;
pub mod object;
Expand Down
Loading