Răsfoiți Sursa

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

Kolten Pearson 2 ani în urmă
părinte
comite
6bdc8fd494
5 a modificat fișierele cu 81 adăugiri și 3 ștergeri
  1. 13 0
      c_bindings/main.c
  2. 24 0
      c_bindings/pocketpy_c.cpp
  3. 14 0
      c_bindings/pocketpy_c.h
  4. 11 1
      src/obj.h
  5. 19 2
      src/vm.h

+ 13 - 0
c_bindings/main.c

@@ -1,12 +1,25 @@
 #include "pocketpy_c.h"
 
 
+void test_binding(pkpy_vm vm) {
+    pkpy_push_int(vm, 12);
+}
+
 int main(int argc, char** argv) {
 
     pkpy_vm vm = pkpy_vm_create(true, true);
 
     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);
 
     return 0;

+ 24 - 0
c_bindings/pocketpy_c.cpp

@@ -19,3 +19,27 @@ void pkpy_vm_destroy(pkpy_vm vm_handle) {
     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();
+}
+
+

+ 14 - 0
c_bindings/pocketpy_c.h

@@ -6,6 +6,7 @@ extern "C" {
 #endif
 
 #include <stdbool.h>
+#include <stdint.h>
 
 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_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
 }
 #endif

+ 11 - 1
src/obj.h

@@ -23,6 +23,16 @@ struct NativeFunc {
     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 KwArg {
         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)
 
-}   // namespace pkpy
+}   // namespace pkpy

+ 19 - 2
src/vm.h

@@ -100,7 +100,7 @@ public:
     // for quick access
     Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str;
     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_super, tp_exception, tp_bytes, tp_mappingproxy;
 
@@ -414,6 +414,11 @@ inline PyObject* NativeFunc::operator()(VM* vm, ArgsView args) const{
     return f(vm, args);
 }
 
+inline void StackFunc::operator()(VM* vm) const{
+    return f(vm);
+}
+
+
 inline void CodeObject::optimize(VM* vm){
     // uint32_t base_n = (uint32_t)(names.size() / kLocalsLoadFactor + 0.5);
     // 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(Function, tp_function)
 DEF_NATIVE_2(NativeFunc, tp_native_func)
+DEF_NATIVE_2(StackFunc, tp_stack_func)
 DEF_NATIVE_2(BoundMethod, tp_bound_method)
 DEF_NATIVE_2(Range, tp_range)
 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...]
     }
 
+    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);
 
     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_FLOAT
 
-}   // namespace pkpy
+}   // namespace pkpy