basic stack based api for creating a binding from c to python is functional

This commit is contained in:
Kolten Pearson 2023-04-29 13:33:51 -06:00
parent 9b9a78524e
commit 6bdc8fd494
5 changed files with 81 additions and 3 deletions

View File

@ -1,12 +1,25 @@
#include "pocketpy_c.h" #include "pocketpy_c.h"
void test_binding(pkpy_vm vm) {
pkpy_push_int(vm, 12);
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
pkpy_vm vm = pkpy_vm_create(true, true); pkpy_vm vm = pkpy_vm_create(true, true);
pkpy_vm_exec(vm, "print('hello world!')"); pkpy_vm_exec(vm, "print('hello world!')");
pkpy_push_int(vm, 11);
pkpy_set_global(vm, "eleven");
pkpy_push_cfunction(vm, test_binding);
pkpy_set_global(vm, "binding");
pkpy_vm_exec(vm, "print(eleven)");
pkpy_vm_exec(vm, "print(binding())");
pkpy_vm_destroy(vm); pkpy_vm_destroy(vm);
return 0; return 0;

View File

@ -19,3 +19,27 @@ void pkpy_vm_destroy(pkpy_vm vm_handle) {
delete vm; delete vm;
} }
void pkpy_push_cfunction(pkpy_vm vm_handle, pkpy_cfunction f) {
pkpy::VM* vm = (pkpy::VM*) vm_handle;
vm->s_data.push(pkpy::py_var(vm, pkpy::StackFunc((pkpy::StackFuncC) f)));
}
void pkpy_push_int(pkpy_vm vm_handle, int64_t value) {
pkpy::VM* vm = (pkpy::VM*) vm_handle;
vm->s_data.push(VAR(value));
}
void pkpy_push_float(pkpy_vm vm_handle, double value) {
pkpy::VM* vm = (pkpy::VM*) vm_handle;
vm->s_data.push(VAR(value));
}
void pkpy_set_global(pkpy_vm vm_handle, const char* name) {
pkpy::VM* vm = (pkpy::VM*) vm_handle;
vm->_main->attr().set(name, vm->s_data.top());
vm->s_data.pop();
}

View File

@ -6,6 +6,7 @@ extern "C" {
#endif #endif
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
typedef struct pkpy_vm_handle* pkpy_vm; typedef struct pkpy_vm_handle* pkpy_vm;
@ -13,6 +14,19 @@ pkpy_vm pkpy_vm_create(bool use_stdio, bool enable_os);
void pkpy_vm_exec(pkpy_vm vm_handle, const char* source); void pkpy_vm_exec(pkpy_vm vm_handle, const char* source);
void pkpy_vm_destroy(pkpy_vm vm); void pkpy_vm_destroy(pkpy_vm vm);
////////binding a c function to pocketpy
typedef void (*pkpy_cfunction)(pkpy_vm);
void pkpy_push_cfunction(pkpy_vm, pkpy_cfunction);
void pkpy_push_int(pkpy_vm, int64_t);
void pkpy_push_float(pkpy_vm, double);
void pkpy_set_global(pkpy_vm, const char* name);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -23,6 +23,16 @@ struct NativeFunc {
PyObject* operator()(VM* vm, ArgsView args) const; PyObject* operator()(VM* vm, ArgsView args) const;
}; };
typedef void (*StackFuncC)(VM*);
struct StackFunc {
StackFuncC f;
StackFunc(StackFuncC f) : f(f) {}
void operator()(VM* vm) const;
};
struct FuncDecl { struct FuncDecl {
struct KwArg { struct KwArg {
int key; // index in co->varnames int key; // index in co->varnames
@ -259,4 +269,4 @@ __T _py_cast(VM* vm, PyObject* obj) {
#define CAST(T, x) py_cast<T>(vm, x) #define CAST(T, x) py_cast<T>(vm, x)
#define _CAST(T, x) _py_cast<T>(vm, x) #define _CAST(T, x) _py_cast<T>(vm, x)
} // namespace pkpy } // namespace pkpy

View File

@ -100,7 +100,7 @@ public:
// for quick access // for quick access
Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str; Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str;
Type tp_list, tp_tuple; Type tp_list, tp_tuple;
Type tp_function, tp_native_func, tp_iterator, tp_bound_method; Type tp_function, tp_stack_func, tp_native_func, tp_iterator, tp_bound_method;
Type tp_slice, tp_range, tp_module; Type tp_slice, tp_range, tp_module;
Type tp_super, tp_exception, tp_bytes, tp_mappingproxy; Type tp_super, tp_exception, tp_bytes, tp_mappingproxy;
@ -414,6 +414,11 @@ inline PyObject* NativeFunc::operator()(VM* vm, ArgsView args) const{
return f(vm, args); return f(vm, args);
} }
inline void StackFunc::operator()(VM* vm) const{
return f(vm);
}
inline void CodeObject::optimize(VM* vm){ inline void CodeObject::optimize(VM* vm){
// uint32_t base_n = (uint32_t)(names.size() / kLocalsLoadFactor + 0.5); // uint32_t base_n = (uint32_t)(names.size() / kLocalsLoadFactor + 0.5);
// perfect_locals_capacity = std::max(find_next_capacity(base_n), NameDict::__Capacity); // perfect_locals_capacity = std::max(find_next_capacity(base_n), NameDict::__Capacity);
@ -425,6 +430,7 @@ DEF_NATIVE_2(List, tp_list)
DEF_NATIVE_2(Tuple, tp_tuple) DEF_NATIVE_2(Tuple, tp_tuple)
DEF_NATIVE_2(Function, tp_function) DEF_NATIVE_2(Function, tp_function)
DEF_NATIVE_2(NativeFunc, tp_native_func) DEF_NATIVE_2(NativeFunc, tp_native_func)
DEF_NATIVE_2(StackFunc, tp_stack_func)
DEF_NATIVE_2(BoundMethod, tp_bound_method) DEF_NATIVE_2(BoundMethod, tp_bound_method)
DEF_NATIVE_2(Range, tp_range) DEF_NATIVE_2(Range, tp_range)
DEF_NATIVE_2(Slice, tp_slice) DEF_NATIVE_2(Slice, tp_slice)
@ -927,6 +933,17 @@ inline PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
// [unbound, self, args..., kwargs...] // [unbound, self, args..., kwargs...]
} }
if(is_non_tagged_type(callable, tp_stack_func)) {
const auto& f = OBJ_GET(StackFunc, callable);
if(ARGC != 0) TypeError("stack_func does not track argument counts ");
if(KWARGC != 0) TypeError("stack_func does not accept keyword arguments");
f(this);
PyObject* ret = s_data.top();
s_data.reset(p0);
return ret;
}
ArgsView args(p1 - ARGC - int(method_call), p1); ArgsView args(p1 - ARGC - int(method_call), p1);
if(is_non_tagged_type(callable, tp_native_func)){ if(is_non_tagged_type(callable, tp_native_func)){
@ -1201,4 +1218,4 @@ inline Str obj_type_name(VM *vm, Type type){
#undef PY_VAR_INT #undef PY_VAR_INT
#undef PY_VAR_FLOAT #undef PY_VAR_FLOAT
} // namespace pkpy } // namespace pkpy