mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
...
This commit is contained in:
parent
9d633c6eb3
commit
d5711da2ad
@ -66,6 +66,32 @@ int test_multiple_return(pkpy_vm* vm) {
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_minus(pkpy_vm* vm) {
|
||||||
|
int a, b;
|
||||||
|
pkpy_to_int(vm, 0, &a);
|
||||||
|
pkpy_to_int(vm, 1, &b);
|
||||||
|
pkpy_push_int(vm, a - b);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_fib(pkpy_vm* vm) {
|
||||||
|
int n;
|
||||||
|
pkpy_to_int(vm, 0, &n);
|
||||||
|
if (n == 1) {
|
||||||
|
pkpy_push_int(vm, n);
|
||||||
|
} else {
|
||||||
|
pkpy_getglobal(vm, pkpy_name("test_fib"));
|
||||||
|
pkpy_push_null(vm);
|
||||||
|
pkpy_push_int(vm, n-1);
|
||||||
|
pkpy_vectorcall(vm, 1);
|
||||||
|
int r_int;
|
||||||
|
pkpy_to_int(vm, -1, &r_int);
|
||||||
|
pkpy_pop_top(vm);
|
||||||
|
pkpy_push_int(vm, r_int + n);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int test_default_argument(pkpy_vm* vm){
|
int test_default_argument(pkpy_vm* vm){
|
||||||
int x;
|
int x;
|
||||||
pkpy_to_int(vm, -1, &x);
|
pkpy_to_int(vm, -1, &x);
|
||||||
@ -311,6 +337,19 @@ int main(int argc, char** argv) {
|
|||||||
check(pkpy_pop_top(vm));
|
check(pkpy_pop_top(vm));
|
||||||
check(pkpy_stack_size(vm) == 0);
|
check(pkpy_stack_size(vm) == 0);
|
||||||
|
|
||||||
|
PRINT_TITLE("test bindings 2");
|
||||||
|
check(pkpy_push_function(vm, "test_minus(a, b)", test_minus));
|
||||||
|
check(pkpy_setglobal(vm, pkpy_name("test_minus")));
|
||||||
|
check(pkpy_exec(vm, "print(test_minus(5, 3))"));
|
||||||
|
check(pkpy_exec(vm, "for i in range(5): print(test_minus(5, i))"));
|
||||||
|
check(pkpy_stack_size(vm) == 0);
|
||||||
|
|
||||||
|
PRINT_TITLE("test bindings fib");
|
||||||
|
check(pkpy_push_function(vm, "test_fib(n: int) -> int", test_fib));
|
||||||
|
check(pkpy_setglobal(vm, pkpy_name("test_fib")));
|
||||||
|
check(pkpy_exec(vm, "print(test_fib(10))"));
|
||||||
|
check(pkpy_stack_size(vm) == 0);
|
||||||
|
|
||||||
PRINT_TITLE("test error propagate");
|
PRINT_TITLE("test error propagate");
|
||||||
check(pkpy_push_function(vm, "test_error_propagate()", test_error_propagate));
|
check(pkpy_push_function(vm, "test_error_propagate()", test_error_propagate));
|
||||||
check(pkpy_setglobal(vm, pkpy_name("test_error_propagate")));
|
check(pkpy_setglobal(vm, pkpy_name("test_error_propagate")));
|
||||||
|
@ -59,6 +59,17 @@ TypeError: expected 2 positional arguments, got 0 (x)
|
|||||||
====== test bindings ======
|
====== test bindings ======
|
||||||
12
|
12
|
||||||
|
|
||||||
|
====== test bindings 2 ======
|
||||||
|
2
|
||||||
|
5
|
||||||
|
4
|
||||||
|
3
|
||||||
|
2
|
||||||
|
1
|
||||||
|
|
||||||
|
====== test bindings fib ======
|
||||||
|
55
|
||||||
|
|
||||||
====== test error propagate ======
|
====== test error propagate ======
|
||||||
successfully errored with this message:
|
successfully errored with this message:
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
@ -81,6 +92,10 @@ successfully errored with this message:
|
|||||||
TypeError: expected 'int', got 'float'
|
TypeError: expected 'int', got 'float'
|
||||||
|
|
||||||
====== test complicated errors ======
|
====== test complicated errors ======
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "main.py", line 1
|
||||||
|
test_error_propagate()
|
||||||
|
NameError: catch me
|
||||||
successfully errored with this message:
|
successfully errored with this message:
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
_: test direct error mechanism
|
_: test direct error mechanism
|
||||||
|
@ -119,6 +119,7 @@ public:
|
|||||||
|
|
||||||
struct{
|
struct{
|
||||||
PyObject* error;
|
PyObject* error;
|
||||||
|
stack<ArgsView> s_view;
|
||||||
} _c;
|
} _c;
|
||||||
|
|
||||||
PyObject* None;
|
PyObject* None;
|
||||||
|
@ -21,23 +21,24 @@ static int count_extra_elements(VM* vm, int n){
|
|||||||
if(vm->callstack.empty()){
|
if(vm->callstack.empty()){
|
||||||
return vm->s_data.size();
|
return vm->s_data.size();
|
||||||
}
|
}
|
||||||
PyObject** base = vm->top_frame()->_locals.end();
|
PK_ASSERT(!vm->_c.s_view.empty());
|
||||||
return vm->s_data._sp - base;
|
return vm->s_data._sp - vm->_c.s_view.top().end();
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject* stack_item(VM* vm, int index){
|
static PyObject* stack_item(VM* vm, int index){
|
||||||
PyObject** begin;
|
PyObject** begin;
|
||||||
PyObject** end;
|
PyObject** end = vm->s_data.end();
|
||||||
if(vm->callstack.empty()){
|
if(vm->callstack.empty()){
|
||||||
begin = vm->s_data.begin();
|
begin = vm->s_data.begin();
|
||||||
end = vm->s_data.end();
|
|
||||||
}else{
|
}else{
|
||||||
Frame* frame = vm->top_frame().get();
|
PK_ASSERT(!vm->_c.s_view.empty());
|
||||||
begin = frame->_locals.begin();
|
begin = vm->_c.s_view.top().begin();
|
||||||
end = frame->_locals.end();
|
}
|
||||||
|
int size = end - begin;
|
||||||
|
if(index < 0) index += size;
|
||||||
|
if(index < 0 || index >= size){
|
||||||
|
throw std::runtime_error("stack_item() => index out of range");
|
||||||
}
|
}
|
||||||
// may raise
|
|
||||||
index = vm->normalized_index(index, end-begin);
|
|
||||||
return begin[index];
|
return begin[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +127,8 @@ int pkpy_stack_size(pkpy_vm* vm_handle){
|
|||||||
if(vm->callstack.empty()){
|
if(vm->callstack.empty()){
|
||||||
return vm->s_data.size();
|
return vm->s_data.size();
|
||||||
}
|
}
|
||||||
return vm->top_frame()->stack_size();
|
PK_ASSERT(!vm->_c.s_view.empty());
|
||||||
|
return vm->s_data._sp - vm->_c.s_view.top().begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
// int
|
// int
|
||||||
@ -299,11 +301,31 @@ bool pkpy_push_null(pkpy_vm* vm_handle) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TempViewPopper{
|
||||||
|
VM* vm;
|
||||||
|
bool used;
|
||||||
|
|
||||||
|
TempViewPopper(VM* vm): vm(vm), used(false) {}
|
||||||
|
|
||||||
|
void restore() noexcept{
|
||||||
|
if(used) return;
|
||||||
|
vm->_c.s_view.pop();
|
||||||
|
used = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~TempViewPopper(){ restore(); }
|
||||||
|
};
|
||||||
|
|
||||||
// function
|
// function
|
||||||
static PyObject* c_function_wrapper(VM* vm, ArgsView args) {
|
static PyObject* c_function_wrapper(VM* vm, ArgsView args) {
|
||||||
LuaStyleFuncC f = lambda_get_userdata<LuaStyleFuncC>(args.begin());
|
LuaStyleFuncC f = lambda_get_userdata<LuaStyleFuncC>(args.begin());
|
||||||
PyObject** curr_sp = vm->s_data._sp;
|
PyObject** curr_sp = vm->s_data._sp;
|
||||||
int retc = f(vm);
|
|
||||||
|
vm->_c.s_view.push(args);
|
||||||
|
TempViewPopper _tvp(vm);
|
||||||
|
int retc = f(vm); // may raise, _tvp will handle this via RAII
|
||||||
|
_tvp.restore();
|
||||||
|
|
||||||
// propagate_if_errored
|
// propagate_if_errored
|
||||||
if (vm->_c.error != nullptr){
|
if (vm->_c.error != nullptr){
|
||||||
Exception e = _py_cast<Exception&>(vm, vm->_c.error);
|
Exception e = _py_cast<Exception&>(vm, vm->_c.error);
|
||||||
@ -472,11 +494,14 @@ bool pkpy_clear_error(pkpy_vm* vm_handle, char** message) {
|
|||||||
if (message != nullptr)
|
if (message != nullptr)
|
||||||
*message = e.summary().c_str_dup();
|
*message = e.summary().c_str_dup();
|
||||||
else
|
else
|
||||||
std::cerr << e.summary() << std::endl;
|
std::cout << e.summary() << std::endl;
|
||||||
vm->_c.error = nullptr;
|
vm->_c.error = nullptr;
|
||||||
// clear the whole stack??
|
if(vm->callstack.empty()){
|
||||||
vm->callstack.clear();
|
|
||||||
vm->s_data.clear();
|
vm->s_data.clear();
|
||||||
|
}else{
|
||||||
|
PK_ASSERT(!vm->_c.s_view.empty());
|
||||||
|
vm->s_data.reset(vm->_c.s_view.top().end());
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user