From a06e6ac6ba68214171e995a7cc1ffe205a070d8b Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 27 Jul 2026 03:18:48 +0800 Subject: [PATCH] fix bugs --- src/compiler/lexer.c | 13 ++++-- src/interpreter/vm.c | 97 ++++++++++++++++++++++++-------------------- 2 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 34a8343d..bab4c4de 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -189,8 +189,8 @@ static Error* LexerError(Lexer* self, const char* fmt, ...) { err->src = self->src; PK_INCREF(self->src); err->lineno = self->current_line; - const char* end = self->src->source->data + self->src->source->size; - if(self->curr_char <= end && *self->curr_char == '\n') { err->lineno--; } + const char* p_end = self->src->source->data + self->src->source->size; + if(self->curr_char <= p_end && *self->curr_char == '\n') { err->lineno--; } va_list args; va_start(args, fmt); vsnprintf(err->msg, sizeof(err->msg), fmt, args); @@ -282,9 +282,16 @@ static Error* _eat_string(Lexer* self, c11_sbuf* buff, char quote, enum StringTy case 'b': c11_sbuf__write_char(buff, '\b'); break; case 'f': c11_sbuf__write_char(buff, '\f'); break; case 'v': c11_sbuf__write_char(buff, '\v'); break; - // Special case for the often used \0 while we don't have full support for octal literals. + // Special case for the often used \0 while we don't have full support for octal + // literals. case '0': c11_sbuf__write_char(buff, '\0'); break; case 'x': { + // check there are at least 2 chars can read + const char* p_end = self->src->source->data + self->src->source->size; + if(p_end - self->curr_char < 2) { + return LexerError(self, "invalid hex escape"); + } + char hex[3] = {eatchar(self), eatchar(self), '\0'}; int code; if(sscanf(hex, "%x", &code) != 1 || code > 0xFF) { diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 1db9ef6d..47578ded 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -713,53 +713,62 @@ void ManagedHeap__mark(ManagedHeap* self) { } } - void* ud = PyObject__userdata(obj); - switch(obj->type) { - case tp_list: { - List* self = ud; - for(int i = 0; i < self->length; i++) { - py_TValue* val = c11__at(py_TValue, self, i); - pk__mark_value(val); + if(obj->type > tp_object) { + // NOTE: `defaultdict` -> `dict` -> `object` + // NOTE: native types must extend from `object`. + py_TypeInfo* ti = pk_typeinfo(obj->type); + while(ti->base != tp_object) { + ti = ti->base_ti; + } + + void* ud = PyObject__userdata(obj); + switch(ti->index) { + case tp_list: { + List* self = ud; + for(int i = 0; i < self->length; i++) { + py_TValue* val = c11__at(py_TValue, self, i); + pk__mark_value(val); + } + break; } - break; - } - case tp_dict: { - Dict* self = ud; - for(int i = 0; i < self->entries.length; i++) { - DictEntry* entry = c11__at(DictEntry, &self->entries, i); - if(py_isnil(&entry->key)) continue; - pk__mark_value(&entry->key); - pk__mark_value(&entry->val); + case tp_dict: { + Dict* self = ud; + for(int i = 0; i < self->entries.length; i++) { + DictEntry* entry = c11__at(DictEntry, &self->entries, i); + if(py_isnil(&entry->key)) continue; + pk__mark_value(&entry->key); + pk__mark_value(&entry->val); + } + break; } - break; - } - case tp_generator: { - Generator* self = ud; - if(self->frame) Frame__gc_mark(self->frame, p_stack); - break; - } - case tp_function: { - function__gc_mark(ud, p_stack); - break; - } - case tp_BaseException: { - BaseException* self = ud; - pk__mark_value(&self->args); - pk__mark_value(&self->inner_exc); - c11__foreach(BaseExceptionFrame, &self->stacktrace, frame) { - pk__mark_value(&frame->locals); - pk__mark_value(&frame->globals); + case tp_generator: { + Generator* self = ud; + if(self->frame) Frame__gc_mark(self->frame, p_stack); + break; + } + case tp_function: { + function__gc_mark(ud, p_stack); + break; + } + case tp_BaseException: { + BaseException* self = ud; + pk__mark_value(&self->args); + pk__mark_value(&self->inner_exc); + c11__foreach(BaseExceptionFrame, &self->stacktrace, frame) { + pk__mark_value(&frame->locals); + pk__mark_value(&frame->globals); + } + break; + } + case tp_code: { + CodeObject* self = ud; + CodeObject__gc_mark(self, p_stack); + break; + } + case tp_chunked_array2d: { + c11_chunked_array2d__mark(ud, p_stack); + break; } - break; - } - case tp_code: { - CodeObject* self = ud; - CodeObject__gc_mark(self, p_stack); - break; - } - case tp_chunked_array2d: { - c11_chunked_array2d__mark(ud, p_stack); - break; } } }