diff --git a/include/pocketpy/interpreter/vm.h b/include/pocketpy/interpreter/vm.h index 0e2ecc72..678ce84f 100644 --- a/include/pocketpy/interpreter/vm.h +++ b/include/pocketpy/interpreter/vm.h @@ -99,6 +99,7 @@ int pk_arrayeq(py_TValue* lhs, int lhs_length, py_TValue* rhs, int rhs_length); /// The result is stored in `self->last_retval`. /// The stack remains unchanged. bool pk_stack_binaryop(pk_VM* self, py_Name op, py_Name rop); +void pk_print_stack(pk_VM* self, Frame* frame, Bytecode byte); // type registration void pk_object__register(); diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 1f5951cc..6671ae4a 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -83,55 +83,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { __NEXT_STEP: byte = *frame->ip; -#if 1 - c11_sbuf buf; - c11_sbuf__ctor(&buf); - for(py_Ref p = self->stack.begin; p != SP(); p++) { - switch(p->type) { - case 0: c11_sbuf__write_cstr(&buf, "nil"); break; - case tp_int: c11_sbuf__write_i64(&buf, p->_i64); break; - case tp_float: c11_sbuf__write_f64(&buf, p->_f64, -1); break; - case tp_bool: c11_sbuf__write_cstr(&buf, p->_bool ? "True" : "False"); break; - case tp_none_type: c11_sbuf__write_cstr(&buf, "None"); break; - case tp_list: { - pk_sprintf(&buf, "list(%d)", py_list__len(p)); - break; - } - case tp_tuple: { - pk_sprintf(&buf, "tuple(%d)", py_tuple__len(p)); - break; - } - case tp_function: { - Function* ud = py_touserdata(p); - c11_sbuf__write_cstr(&buf, ud->decl->code.name->data); - c11_sbuf__write_cstr(&buf, "()"); - break; - } - case tp_type: { - pk_sprintf(&buf, "", py_totype(p)); - break; - } - case tp_str: { - int size; - const char* data = py_tostrn(p, &size); - pk_sprintf(&buf, "%q", (c11_sv){data, size}); - break; - } - default: { - pk_sprintf(&buf, "(%t)", p->type); - break; - } - } - if(p != TOP()) c11_sbuf__write_cstr(&buf, ", "); - } - c11_string* stack_str = c11_sbuf__submit(&buf); - printf("L%-3d: %-25s %-6d [%s]\n", - Frame__lineno(frame), - pk_opname(byte.op), - byte.arg, - stack_str->data); - c11_string__delete(stack_str); -#endif + pk_print_stack(self, frame, byte); switch((Opcode)byte.op) { case OP_NO_OP: DISPATCH(); diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 31e4635b..739db762 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -334,6 +334,8 @@ bool __prepare_py_call(py_TValue* buffer, } pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bool opcall) { + pk_print_stack(self, self->top_frame, (Bytecode){}); + py_Ref p1 = self->stack.sp - kwargc * 2; py_Ref p0 = p1 - argc - 2; // [callable, , args..., kwargs...] @@ -458,7 +460,6 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo *self->stack.sp++ = *p0; // push cls memcpy(self->stack.sp, argv, span * sizeof(py_TValue)); self->stack.sp += span; - // [new_f, cls, args..., kwargs...] pk_FrameResult res = pk_VM__vectorcall(self, argc, kwargc, false); if(res == RES_ERROR) return RES_ERROR; @@ -522,3 +523,56 @@ void pk_ManagedHeap__mark(pk_ManagedHeap* self) { // vm->__stack_gc_mark(vm->s_data.begin(), vm->s_data.end()); // if(self->_gc_marker_ex) self->_gc_marker_ex((pkpy_VM*)vm); } + +void pk_print_stack(pk_VM* self, Frame* frame, Bytecode byte) { + return; + py_TValue* sp = self->stack.sp; + c11_sbuf buf; + c11_sbuf__ctor(&buf); + for(py_Ref p = self->stack.begin; p != sp; p++) { + switch(p->type) { + case 0: c11_sbuf__write_cstr(&buf, "nil"); break; + case tp_int: c11_sbuf__write_i64(&buf, p->_i64); break; + case tp_float: c11_sbuf__write_f64(&buf, p->_f64, -1); break; + case tp_bool: c11_sbuf__write_cstr(&buf, p->_bool ? "True" : "False"); break; + case tp_none_type: c11_sbuf__write_cstr(&buf, "None"); break; + case tp_list: { + pk_sprintf(&buf, "list(%d)", py_list__len(p)); + break; + } + case tp_tuple: { + pk_sprintf(&buf, "tuple(%d)", py_tuple__len(p)); + break; + } + case tp_function: { + Function* ud = py_touserdata(p); + c11_sbuf__write_cstr(&buf, ud->decl->code.name->data); + c11_sbuf__write_cstr(&buf, "()"); + break; + } + case tp_type: { + pk_sprintf(&buf, "", py_totype(p)); + break; + } + case tp_str: { + int size; + const char* data = py_tostrn(p, &size); + pk_sprintf(&buf, "%q", (c11_sv){data, size}); + break; + } + default: { + pk_sprintf(&buf, "(%t)", p->type); + break; + } + } + if(p != &sp[-1]) c11_sbuf__write_cstr(&buf, ", "); + } + c11_string* stack_str = c11_sbuf__submit(&buf); + + printf("L%-3d: %-25s %-6d [%s]\n", + Frame__lineno(frame), + pk_opname(byte.op), + byte.arg, + stack_str->data); + c11_string__delete(stack_str); +} \ No newline at end of file diff --git a/src/public/error.c b/src/public/error.c index 68c5e333..46ce091b 100644 --- a/src/public/error.c +++ b/src/public/error.c @@ -35,9 +35,9 @@ bool py_exception(const char* name, const char* fmt, ...) { py_Ref message = py_pushtmp(); py_newstrn(message, res->data, res->size); c11_string__delete(res); + bool ok = py_tpcall(tp_exception, 1, message); py_pop(); - bool ok = py_tpcall(tp_exception, 1, message); if(!ok) abort(); vm->last_exception = *py_retval(); diff --git a/src/public/py_list.c b/src/public/py_list.c index 71546025..7255d396 100644 --- a/src/public/py_list.c +++ b/src/public/py_list.c @@ -110,10 +110,11 @@ static bool _py_list__new__(int argc, py_Ref argv) { } return true; } + + if(!py_iter(py_arg(1))) return false; py_Ref iter = py_pushtmp(); py_Ref list = py_pushtmp(); - if(!py_iter(py_arg(1))) return false; *iter = *py_retval(); py_newlist(list); while(true) {