mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20: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;
|
||||
}
|
||||
|
||||
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 x;
|
||||
pkpy_to_int(vm, -1, &x);
|
||||
@ -311,6 +337,19 @@ int main(int argc, char** argv) {
|
||||
check(pkpy_pop_top(vm));
|
||||
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");
|
||||
check(pkpy_push_function(vm, "test_error_propagate()", 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 ======
|
||||
12
|
||||
|
||||
====== test bindings 2 ======
|
||||
2
|
||||
5
|
||||
4
|
||||
3
|
||||
2
|
||||
1
|
||||
|
||||
====== test bindings fib ======
|
||||
55
|
||||
|
||||
====== test error propagate ======
|
||||
successfully errored with this message:
|
||||
Traceback (most recent call last):
|
||||
@ -81,6 +92,10 @@ successfully errored with this message:
|
||||
TypeError: expected 'int', got 'float'
|
||||
|
||||
====== test complicated errors ======
|
||||
Traceback (most recent call last):
|
||||
File "main.py", line 1
|
||||
test_error_propagate()
|
||||
NameError: catch me
|
||||
successfully errored with this message:
|
||||
Traceback (most recent call last):
|
||||
_: test direct error mechanism
|
||||
|
@ -119,6 +119,7 @@ public:
|
||||
|
||||
struct{
|
||||
PyObject* error;
|
||||
stack<ArgsView> s_view;
|
||||
} _c;
|
||||
|
||||
PyObject* None;
|
||||
|
@ -21,23 +21,24 @@ static int count_extra_elements(VM* vm, int n){
|
||||
if(vm->callstack.empty()){
|
||||
return vm->s_data.size();
|
||||
}
|
||||
PyObject** base = vm->top_frame()->_locals.end();
|
||||
return vm->s_data._sp - base;
|
||||
PK_ASSERT(!vm->_c.s_view.empty());
|
||||
return vm->s_data._sp - vm->_c.s_view.top().end();
|
||||
}
|
||||
|
||||
static PyObject* stack_item(VM* vm, int index){
|
||||
PyObject** begin;
|
||||
PyObject** end;
|
||||
PyObject** end = vm->s_data.end();
|
||||
if(vm->callstack.empty()){
|
||||
begin = vm->s_data.begin();
|
||||
end = vm->s_data.end();
|
||||
}else{
|
||||
Frame* frame = vm->top_frame().get();
|
||||
begin = frame->_locals.begin();
|
||||
end = frame->_locals.end();
|
||||
PK_ASSERT(!vm->_c.s_view.empty());
|
||||
begin = vm->_c.s_view.top().begin();
|
||||
}
|
||||
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];
|
||||
}
|
||||
|
||||
@ -126,7 +127,8 @@ int pkpy_stack_size(pkpy_vm* vm_handle){
|
||||
if(vm->callstack.empty()){
|
||||
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
|
||||
@ -299,11 +301,31 @@ bool pkpy_push_null(pkpy_vm* vm_handle) {
|
||||
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
|
||||
static PyObject* c_function_wrapper(VM* vm, ArgsView args) {
|
||||
LuaStyleFuncC f = lambda_get_userdata<LuaStyleFuncC>(args.begin());
|
||||
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
|
||||
if (vm->_c.error != nullptr){
|
||||
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)
|
||||
*message = e.summary().c_str_dup();
|
||||
else
|
||||
std::cerr << e.summary() << std::endl;
|
||||
std::cout << e.summary() << std::endl;
|
||||
vm->_c.error = nullptr;
|
||||
// clear the whole stack??
|
||||
vm->callstack.clear();
|
||||
if(vm->callstack.empty()){
|
||||
vm->s_data.clear();
|
||||
}else{
|
||||
PK_ASSERT(!vm->_c.s_view.empty());
|
||||
vm->s_data.reset(vm->_c.s_view.top().end());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user