mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
181 lines
3.8 KiB
C++
181 lines
3.8 KiB
C++
#include "pocketpy.h"
|
|
#include "pocketpy_c.h"
|
|
|
|
using namespace pkpy;
|
|
|
|
|
|
#define ERRHANDLER_OPEN try { \
|
|
try { \
|
|
if (vm->c_data.top() == nullptr) \
|
|
return false; \
|
|
|
|
#define ERRHANDLER_CLOSE \
|
|
} catch( Exception e ) { \
|
|
vm->c_data.clear(); \
|
|
vm->c_data.push(VAR(e.summary())); \
|
|
vm->c_data.push(NULL); \
|
|
return false; \
|
|
} \
|
|
} catch(...) { \
|
|
std::cerr << "ERROR: a non pocketpy exeception was thrown " \
|
|
<< "this probably means pocketpy itself has a bug!\n"; \
|
|
exit(2); \
|
|
}
|
|
|
|
bool pkpy_clear_error(pkpy_vm vm_handle, const char** message) {
|
|
VM* vm = (VM*) vm_handle;
|
|
|
|
try {
|
|
if (vm->c_data.top() != nullptr)
|
|
return false;
|
|
|
|
vm->c_data.pop();
|
|
Str wrapped_message = CAST(Str&, vm->c_data.top());
|
|
if (message != nullptr)
|
|
*message = wrapped_message.c_str_dup();
|
|
else
|
|
std::cerr << "ERROR: " << wrapped_message << "\n";
|
|
|
|
vm->c_data.pop();
|
|
//at this point the stack is clear
|
|
|
|
return true;
|
|
|
|
} catch(...) {
|
|
std::cerr << "ERROR: a non pocketpy exeception was thrown "
|
|
<< "this probably means pocketpy itself has a bug!\n";
|
|
exit(2);
|
|
}
|
|
}
|
|
|
|
pkpy_vm pkpy_vm_create(bool use_stdio, bool enable_os) {
|
|
VM* vm = new VM(use_stdio, enable_os);
|
|
|
|
return (pkpy_vm) vm;
|
|
}
|
|
|
|
bool pkpy_vm_exec(pkpy_vm vm_handle, const char* source) {
|
|
VM* vm = (VM*) vm_handle;
|
|
ERRHANDLER_OPEN
|
|
|
|
vm->exec(source, "main.py", EXEC_MODE);
|
|
|
|
return true;
|
|
ERRHANDLER_CLOSE
|
|
}
|
|
|
|
void pkpy_vm_destroy(pkpy_vm vm_handle) {
|
|
VM* vm = (VM*) vm_handle;
|
|
delete vm;
|
|
}
|
|
|
|
bool pkpy_push_function(pkpy_vm vm_handle, pkpy_function f) {
|
|
return true;
|
|
}
|
|
|
|
bool pkpy_push_int(pkpy_vm vm_handle, int value) {
|
|
VM* vm = (VM*) vm_handle;
|
|
ERRHANDLER_OPEN
|
|
|
|
vm->c_data.push(VAR(value));
|
|
|
|
return true;
|
|
ERRHANDLER_CLOSE
|
|
}
|
|
|
|
bool pkpy_push_float(pkpy_vm vm_handle, double value) {
|
|
VM* vm = (VM*) vm_handle;
|
|
|
|
ERRHANDLER_OPEN
|
|
vm->c_data.push(VAR(value));
|
|
|
|
return true;
|
|
ERRHANDLER_CLOSE
|
|
}
|
|
|
|
bool pkpy_set_global(pkpy_vm vm_handle, const char* name) {
|
|
VM* vm = (VM*) vm_handle;
|
|
|
|
ERRHANDLER_OPEN
|
|
|
|
vm->_main->attr().set(name, vm->c_data.top());
|
|
|
|
vm->c_data.pop();
|
|
|
|
return true;
|
|
ERRHANDLER_CLOSE
|
|
}
|
|
|
|
bool pkpy_get_global(pkpy_vm vm_handle, const char* name) {
|
|
VM* vm = (VM*) vm_handle;
|
|
|
|
ERRHANDLER_OPEN
|
|
|
|
PyObject* o = vm->_main->attr().try_get(name);
|
|
|
|
vm->c_data.push(o);
|
|
|
|
return true;
|
|
ERRHANDLER_CLOSE
|
|
}
|
|
|
|
static void call_wrapper(VM* vm, int argc, bool method_call) {
|
|
int callable_index = vm->c_data.size() - argc - 1;
|
|
|
|
PyObject* callable = vm->c_data.get(callable_index);
|
|
|
|
vm->s_data.push(callable);
|
|
if (method_call)
|
|
vm->s_data.push(vm->c_data.get(callable_index - 1));
|
|
else
|
|
vm->s_data.push(PY_NULL);
|
|
|
|
for (int i = 0; i < argc; i++)
|
|
vm->s_data.push(vm->c_data.get(callable_index + i + 1));
|
|
|
|
PyObject* o = vm->vectorcall(argc);
|
|
|
|
vm->c_data.shrink(argc + 1 + (int) method_call);
|
|
|
|
//TODO unpack tuple?
|
|
vm->c_data.push(o);
|
|
}
|
|
|
|
bool pkpy_call(pkpy_vm vm_handle, int argc) {
|
|
VM* vm = (VM*) vm_handle;
|
|
ERRHANDLER_OPEN
|
|
call_wrapper(vm, argc, false);
|
|
|
|
return true;
|
|
ERRHANDLER_CLOSE
|
|
}
|
|
|
|
bool pkpy_call_method(pkpy_vm vm_handle, int argc) {
|
|
VM* vm = (VM*) vm_handle;
|
|
ERRHANDLER_OPEN
|
|
call_wrapper(vm, argc, true);
|
|
|
|
return true;
|
|
ERRHANDLER_CLOSE
|
|
}
|
|
|
|
static int lua_to_cstack_index(int index, int size) {
|
|
if (index < 0)
|
|
index = size + index;
|
|
return index;
|
|
}
|
|
|
|
bool pkpy_to_int(pkpy_vm vm_handle, int index, int* ret) {
|
|
VM* vm = (VM*) vm_handle;
|
|
ERRHANDLER_OPEN
|
|
|
|
index = lua_to_cstack_index(index, vm->c_data.size());
|
|
|
|
PyObject* o = vm->c_data.get(index);
|
|
if (ret != nullptr)
|
|
*ret = py_cast<int>(vm, o);
|
|
|
|
return true;
|
|
ERRHANDLER_CLOSE
|
|
}
|