diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ba9c4e42..e86027ad 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,6 +2,7 @@ name: build on: push: + branches: [ main ] paths-ignore: - 'docs/**' - 'web/**' diff --git a/.github/workflows/pybind11.yml b/.github/workflows/pybind11.yml index fec3b95f..3ae18cd6 100644 --- a/.github/workflows/pybind11.yml +++ b/.github/workflows/pybind11.yml @@ -2,6 +2,7 @@ name: PKBIND Build and Test on: push: + branches: [ main ] paths-ignore: - "docs/**" - "web/**" diff --git a/include/pocketpy/common/namedict.h b/include/pocketpy/common/namedict.h new file mode 100644 index 00000000..623b5be3 --- /dev/null +++ b/include/pocketpy/common/namedict.h @@ -0,0 +1,5 @@ +#pragma once + +typedef struct NameDict { + +} NameDict; \ No newline at end of file diff --git a/include/pocketpy/common/smallmap.h b/include/pocketpy/common/smallmap.h index ad95857b..6e2a63ca 100644 --- a/include/pocketpy/common/smallmap.h +++ b/include/pocketpy/common/smallmap.h @@ -5,7 +5,7 @@ #include #define SMALLMAP_T__HEADER -#define K uint16_t +#define K py_Name #define V int #define NAME c11_smallmap_n2i #include "pocketpy/xmacros/smallmap.h" @@ -14,7 +14,7 @@ #define SMALLMAP_T__HEADER #define K c11_sv -#define V uint16_t +#define V py_Name #define NAME c11_smallmap_s2n #define less(a, b) (c11_sv__cmp((a), (b)) < 0) #define equal(a, b) (c11_sv__cmp((a), (b)) == 0) diff --git a/include/pocketpy/interpreter/name.h b/include/pocketpy/interpreter/name.h index b1f08520..9a3a0a07 100644 --- a/include/pocketpy/interpreter/name.h +++ b/include/pocketpy/interpreter/name.h @@ -4,15 +4,18 @@ #include "pocketpy/common/smallmap.h" typedef struct { - char* data; // null-terminated data int size; // size of the data excluding the null-terminator py_TValue obj; // cached `str` object (lazy initialized) -} RInternedEntry; + char data[]; // null-terminated data +} InternedEntry; typedef struct { c11_smallmap_s2n interned; - c11_vector /* T=RInternedEntry */ r_interned; } InternedNames; void InternedNames__ctor(InternedNames* self); void InternedNames__dtor(InternedNames* self); + +#define MAGIC_METHOD(x) extern py_Name x; +#include "pocketpy/xmacros/magics.h" +#undef MAGIC_METHOD \ No newline at end of file diff --git a/include/pocketpy/objects/codeobject.h b/include/pocketpy/objects/codeobject.h index 47f8233b..74800e5e 100644 --- a/include/pocketpy/objects/codeobject.h +++ b/include/pocketpy/objects/codeobject.h @@ -75,9 +75,11 @@ typedef struct CodeObject { c11_vector /*T=py_TValue*/ consts; // constants c11_vector /*T=py_Name*/ varnames; // local variables - int nlocals; // cached varnames.size() + c11_vector /*T=py_Name*/ names; + int nlocals; c11_smallmap_n2i varnames_inv; + c11_smallmap_n2i names_inv; c11_vector /*T=CodeBlock*/ blocks; c11_vector /*T=FuncDecl_*/ func_decls; @@ -89,6 +91,7 @@ typedef struct CodeObject { void CodeObject__ctor(CodeObject* self, SourceData_ src, c11_sv name); void CodeObject__dtor(CodeObject* self); int CodeObject__add_varname(CodeObject* self, py_Name name); +int CodeObject__add_name(CodeObject* self, py_Name name); void CodeObject__gc_mark(const CodeObject* self, c11_vector* p_stack); typedef struct FuncDeclKwArg { diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 547af499..a8eb86b6 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -13,12 +13,12 @@ extern "C" { #endif /************* Public Types *************/ - +/// A helper struct for `py_Name`. +typedef struct py_OpaqueName py_OpaqueName; +/// A pointer that represents a python identifier. For fast name resolution. +typedef py_OpaqueName* py_Name; /// A opaque type that represents a python object. You cannot access its members directly. typedef struct py_TValue py_TValue; -/// An integer that represents a python identifier. This is to achieve string pooling and fast name -/// resolution. -typedef uint16_t py_Name; /// An integer that represents a python type. `0` is invalid. typedef int16_t py_Type; /// A 64-bit integer type. Corresponds to `int` in python. @@ -710,14 +710,6 @@ PK_API int py_replinput(char* buf, int max_size); /// %t: py_Type /// %n: py_Name -enum py_MagicName { - py_MagicName__NULL, // 0 is reserved - -#define MAGIC_METHOD(x) x, -#include "pocketpy/xmacros/magics.h" -#undef MAGIC_METHOD -}; - enum py_PredefinedType { tp_nil = 0, tp_object = 1, diff --git a/src/common/smallmap.c b/src/common/smallmap.c index 3a265158..0857ffa2 100644 --- a/src/common/smallmap.c +++ b/src/common/smallmap.c @@ -1,7 +1,7 @@ #include "pocketpy/common/smallmap.h" #define SMALLMAP_T__SOURCE -#define K uint16_t +#define K py_Name #define V int #define NAME c11_smallmap_n2i #include "pocketpy/xmacros/smallmap.h" @@ -10,7 +10,7 @@ #define SMALLMAP_T__SOURCE #define K c11_sv -#define V uint16_t +#define V py_Name #define NAME c11_smallmap_s2n #define less(a, b) (c11_sv__cmp((a), (b)) < 0) #define equal(a, b) (c11_sv__cmp((a), (b)) == 0) diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 29c93e60..5e7e4c83 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -61,9 +61,9 @@ typedef struct Ctx { int level; int curr_iblock; bool is_compiling_class; - c11_vector /*T=Expr* */ s_expr; + c11_vector /*T=Expr_p*/ s_expr; c11_smallmap_n2i global_names; - c11_smallmap_s2n co_consts_string_dedup_map; + c11_smallmap_s2n co_consts_string_dedup_map; // this stores 0-based index instead of pointer } Ctx; typedef struct Expr Expr; @@ -75,11 +75,12 @@ static int Ctx__enter_block(Ctx* self, CodeBlockType type); static void Ctx__exit_block(Ctx* self); static int Ctx__emit_(Ctx* self, Opcode opcode, uint16_t arg, int line); static int Ctx__emit_virtual(Ctx* self, Opcode opcode, uint16_t arg, int line, bool virtual); -static void Ctx__revert_last_emit_(Ctx* self); +// static void Ctx__revert_last_emit_(Ctx* self); static int Ctx__emit_int(Ctx* self, int64_t value, int line); static void Ctx__patch_jump(Ctx* self, int index); static void Ctx__emit_jump(Ctx* self, int target, int line); static int Ctx__add_varname(Ctx* self, py_Name name); +static int Ctx__add_name(Ctx* self, py_Name name); static int Ctx__add_const(Ctx* self, py_Ref); static int Ctx__add_const_string(Ctx* self, c11_sv); static void Ctx__emit_store_name(Ctx* self, NameScope scope, py_Name name, int line); @@ -117,7 +118,7 @@ void NameExpr__emit_(Expr* self_, Ctx* ctx) { } } } - Ctx__emit_(ctx, op, self->name, self->line); + Ctx__emit_(ctx, op, Ctx__add_name(ctx, self->name), self->line); } } @@ -129,7 +130,7 @@ bool NameExpr__emit_del(Expr* self_, Ctx* ctx) { break; case NAME_GLOBAL: { Opcode op = ctx->co->src->is_dynamic ? OP_DELETE_NAME : OP_DELETE_GLOBAL; - Ctx__emit_(ctx, op, self->name, self->line); + Ctx__emit_(ctx, op, Ctx__add_name(ctx, self->name), self->line); break; } default: c11__unreachable(); @@ -140,7 +141,7 @@ bool NameExpr__emit_del(Expr* self_, Ctx* ctx) { bool NameExpr__emit_store(Expr* self_, Ctx* ctx) { NameExpr* self = (NameExpr*)self_; if(ctx->is_compiling_class) { - Ctx__emit_(ctx, OP_STORE_CLASS_ATTR, self->name, self->line); + Ctx__emit_(ctx, OP_STORE_CLASS_ATTR, Ctx__add_name(ctx, self->name), self->line); return true; } Ctx__emit_store_name(ctx, self->scope, self->name, self->line); @@ -710,7 +711,7 @@ static void BinaryExpr__dtor(Expr* self_) { vtdelete(self->rhs); } -static py_Name cmp_token2name(TokenIndex token) { +static uint16_t cmp_token2name(TokenIndex token) { switch(token) { case TK_LT: return __lt__; case TK_LE: return __le__; @@ -945,20 +946,20 @@ void AttribExpr__dtor(Expr* self_) { void AttribExpr__emit_(Expr* self_, Ctx* ctx) { AttribExpr* self = (AttribExpr*)self_; vtemit_(self->child, ctx); - Ctx__emit_(ctx, OP_LOAD_ATTR, self->name, self->line); + Ctx__emit_(ctx, OP_LOAD_ATTR, Ctx__add_name(ctx, self->name), self->line); } bool AttribExpr__emit_del(Expr* self_, Ctx* ctx) { AttribExpr* self = (AttribExpr*)self_; vtemit_(self->child, ctx); - Ctx__emit_(ctx, OP_DELETE_ATTR, self->name, self->line); + Ctx__emit_(ctx, OP_DELETE_ATTR, Ctx__add_name(ctx, self->name), self->line); return true; } bool AttribExpr__emit_store(Expr* self_, Ctx* ctx) { AttribExpr* self = (AttribExpr*)self_; vtemit_(self->child, ctx); - Ctx__emit_(ctx, OP_STORE_ATTR, self->name, self->line); + Ctx__emit_(ctx, OP_STORE_ATTR, Ctx__add_name(ctx, self->name), self->line); return true; } @@ -966,14 +967,14 @@ void AttribExpr__emit_inplace(Expr* self_, Ctx* ctx) { AttribExpr* self = (AttribExpr*)self_; vtemit_(self->child, ctx); Ctx__emit_(ctx, OP_DUP_TOP, BC_NOARG, self->line); - Ctx__emit_(ctx, OP_LOAD_ATTR, self->name, self->line); + Ctx__emit_(ctx, OP_LOAD_ATTR, Ctx__add_name(ctx, self->name), self->line); } bool AttribExpr__emit_istore(Expr* self_, Ctx* ctx) { // [a, val] -> [val, a] AttribExpr* self = (AttribExpr*)self_; Ctx__emit_(ctx, OP_ROT_TWO, BC_NOARG, self->line); - Ctx__emit_(ctx, OP_STORE_ATTR, self->name, self->line); + Ctx__emit_(ctx, OP_STORE_ATTR, Ctx__add_name(ctx, self->name), self->line); return true; } @@ -1031,7 +1032,7 @@ void CallExpr__emit_(Expr* self_, Ctx* ctx) { if(self->callable->vt->is_attrib) { AttribExpr* p = (AttribExpr*)self->callable; vtemit_(p->child, ctx); - Ctx__emit_(ctx, OP_LOAD_METHOD, p->name, p->line); + Ctx__emit_(ctx, OP_LOAD_METHOD, Ctx__add_name(ctx, p->name), p->line); } else { vtemit_(self->callable, ctx); Ctx__emit_(ctx, OP_LOAD_NULL, BC_NOARG, BC_KEEPLINE); @@ -1046,7 +1047,7 @@ void CallExpr__emit_(Expr* self_, Ctx* ctx) { c11__foreach(Expr*, &self->args, e) { vtemit_(*e, ctx); } c11__foreach(CallExprKwArg, &self->kwargs, e) { - Ctx__emit_int(ctx, e->key, self->line); + Ctx__emit_int(ctx, (uintptr_t)e->key, self->line); vtemit_(e->val, ctx); } int KWARGC = self->kwargs.length; @@ -1166,10 +1167,10 @@ static int Ctx__emit_(Ctx* self, Opcode opcode, uint16_t arg, int line) { return Ctx__emit_virtual(self, opcode, arg, line, false); } -static void Ctx__revert_last_emit_(Ctx* self) { - c11_vector__pop(&self->co->codes); - c11_vector__pop(&self->co->codes_ex); -} +// static void Ctx__revert_last_emit_(Ctx* self) { +// c11_vector__pop(&self->co->codes); +// c11_vector__pop(&self->co->codes_ex); +// } static int Ctx__emit_int(Ctx* self, int64_t value, int line) { if(INT16_MIN <= value && value <= INT16_MAX) { @@ -1199,6 +1200,10 @@ static int Ctx__add_varname(Ctx* self, py_Name name) { return CodeObject__add_varname(self->co, name); } +static int Ctx__add_name(Ctx* self, py_Name name) { + return CodeObject__add_name(self->co, name); +} + static int Ctx__add_const_string(Ctx* self, c11_sv key) { if(key.size > 100) { py_Ref tmp = c11_vector__emplace(&self->co->consts); @@ -1206,7 +1211,7 @@ static int Ctx__add_const_string(Ctx* self, c11_sv key) { int index = self->co->consts.length - 1; return index; } - uint16_t* val = c11_smallmap_s2n__try_get(&self->co_consts_string_dedup_map, key); + uintptr_t* val = c11_smallmap_s2n__try_get(&self->co_consts_string_dedup_map, key); if(val) { return *val; } else { @@ -1235,7 +1240,7 @@ static void Ctx__emit_store_name(Ctx* self, NameScope scope, py_Name name, int l case NAME_LOCAL: Ctx__emit_(self, OP_STORE_FAST, Ctx__add_varname(self, name), line); break; case NAME_GLOBAL: { Opcode op = self->co->src->is_dynamic ? OP_STORE_NAME : OP_STORE_GLOBAL; - Ctx__emit_(self, op, name, line); + Ctx__emit_(self, op, Ctx__add_name(self, name), line); } break; default: c11__unreachable(); } @@ -2409,7 +2414,7 @@ static Error* compile_class(Compiler* self, int decorators) { ctx()->is_compiling_class = false; Ctx__s_emit_decorators(ctx(), decorators); - Ctx__emit_(ctx(), OP_END_CLASS, name, BC_KEEPLINE); + Ctx__emit_(ctx(), OP_END_CLASS, Ctx__add_name(ctx(), name), BC_KEEPLINE); return NULL; } @@ -2517,7 +2522,7 @@ __EAT_DOTS_END: Ctx__emit_(ctx(), OP_DUP_TOP, BC_NOARG, BC_KEEPLINE); consume(TK_ID); c11_sv name = Token__sv(prev()); - Ctx__emit_(ctx(), OP_LOAD_ATTR, py_namev(name), prev()->line); + Ctx__emit_(ctx(), OP_LOAD_ATTR, Ctx__add_name(ctx(), py_namev(name)), prev()->line); if(match(TK_AS)) { consume(TK_ID); name = Token__sv(prev()); @@ -2783,7 +2788,7 @@ static Error* compile_stmt(Compiler* self) { NameExpr* ne = (NameExpr*)Ctx__s_top(ctx()); int index = Ctx__add_const_string(ctx(), type_hint); Ctx__emit_(ctx(), OP_LOAD_CONST, index, BC_KEEPLINE); - Ctx__emit_(ctx(), OP_ADD_CLASS_ANNOTATION, ne->name, BC_KEEPLINE); + Ctx__emit_(ctx(), OP_ADD_CLASS_ANNOTATION, Ctx__add_name(ctx(), ne->name), BC_KEEPLINE); } } } diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index dd4bc08f..b47e2834 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -211,13 +211,13 @@ FrameResult VM__run_top_frame(VM* self) { PUSH(val); DISPATCH(); } - py_Name name = c11__getitem(uint16_t, &frame->co->varnames, byte.arg); + py_Name name = c11__getitem(py_Name, &frame->co->varnames, byte.arg); UnboundLocalError(name); goto __ERROR; } case OP_LOAD_NAME: { assert(frame->is_locals_special); - py_Name name = byte.arg; + py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg); // locals switch(frame->locals->type) { case tp_locals: { @@ -261,7 +261,7 @@ FrameResult VM__run_top_frame(VM* self) { goto __ERROR; } case OP_LOAD_NONLOCAL: { - py_Name name = byte.arg; + py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg); py_Ref tmp = Frame__getclosure(frame, name); if(tmp != NULL) { PUSH(tmp); @@ -283,7 +283,7 @@ FrameResult VM__run_top_frame(VM* self) { goto __ERROR; } case OP_LOAD_GLOBAL: { - py_Name name = byte.arg; + py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg); int res = Frame__getglobal(frame, name); if(res == 1) { PUSH(&self->last_retval); @@ -308,7 +308,7 @@ FrameResult VM__run_top_frame(VM* self) { } case OP_LOAD_CLASS_GLOBAL: { assert(self->curr_class); - py_Name name = byte.arg; + py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg); py_Ref tmp = py_getdict(self->curr_class, name); if(tmp) { PUSH(tmp); @@ -368,7 +368,7 @@ FrameResult VM__run_top_frame(VM* self) { } case OP_STORE_NAME: { assert(frame->is_locals_special); - py_Name name = byte.arg; + py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg); switch(frame->locals->type) { case tp_locals: { py_Frame* noproxy = frame->locals->_ptr; @@ -435,7 +435,7 @@ FrameResult VM__run_top_frame(VM* self) { } case OP_DELETE_NAME: { assert(frame->is_locals_special); - py_Name name = byte.arg; + py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg); switch(frame->locals->type) { case tp_locals: { py_Frame* noproxy = frame->locals->_ptr; @@ -464,7 +464,7 @@ FrameResult VM__run_top_frame(VM* self) { } } case OP_DELETE_GLOBAL: { - py_Name name = byte.arg; + py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg); int res = Frame__delglobal(frame, name); if(res == 1) DISPATCH(); if(res == -1) goto __ERROR; @@ -473,7 +473,8 @@ FrameResult VM__run_top_frame(VM* self) { } case OP_DELETE_ATTR: { - if(!py_delattr(TOP(), byte.arg)) goto __ERROR; + py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg); + if(!py_delattr(TOP(), name)) goto __ERROR; DISPATCH(); } @@ -999,7 +1000,7 @@ FrameResult VM__run_top_frame(VM* self) { /////////// case OP_BEGIN_CLASS: { // [base] - py_Name name = byte.arg; + py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg); py_Type base; if(py_isnone(TOP())) { base = tp_object; @@ -1027,7 +1028,7 @@ FrameResult VM__run_top_frame(VM* self) { } case OP_END_CLASS: { // [cls or decorated] - py_Name name = byte.arg; + py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg); if(!Frame__setglobal(frame, name, TOP())) goto __ERROR; if(py_istype(TOP(), tp_type)) { @@ -1052,7 +1053,7 @@ FrameResult VM__run_top_frame(VM* self) { } case OP_STORE_CLASS_ATTR: { assert(self->curr_class); - py_Name name = byte.arg; + py_Name name = c11__getitem(py_Name, &frame->co->names, byte.arg); // TOP() can be a function, classmethod or custom decorator py_Ref actual_func = TOP(); if(actual_func->type == tp_classmethod) { diff --git a/src/interpreter/name.c b/src/interpreter/name.c index 71966ee1..f358a6df 100644 --- a/src/interpreter/name.c +++ b/src/interpreter/name.c @@ -1,23 +1,25 @@ #include "pocketpy/interpreter/name.h" #include "pocketpy/interpreter/vm.h" +#define MAGIC_METHOD(x) py_Name x; +#include "pocketpy/xmacros/magics.h" +#undef MAGIC_METHOD + void InternedNames__ctor(InternedNames* self) { c11_smallmap_s2n__ctor(&self->interned); - c11_vector__ctor(&self->r_interned, sizeof(RInternedEntry)); // initialize all magic names -#define MAGIC_METHOD(x) \ - if(x != py_name(#x)) abort(); +#define MAGIC_METHOD(x) x = py_name(#x); #include "pocketpy/xmacros/magics.h" #undef MAGIC_METHOD } void InternedNames__dtor(InternedNames* self) { - for(int i = 0; i < self->r_interned.length; i++) { - PK_FREE(c11__getitem(RInternedEntry, &self->r_interned, i).data); + for(int i = 0; i < self->interned.length; i++) { + c11_smallmap_s2n_KV* kv = c11__at(c11_smallmap_s2n_KV, &self->interned, i); + PK_FREE((void*)kv->value); } c11_smallmap_s2n__dtor(&self->interned); - c11_vector__dtor(&self->r_interned); } py_Name py_name(const char* name) { @@ -29,47 +31,37 @@ py_Name py_name(const char* name) { py_Name py_namev(c11_sv name) { InternedNames* self = &pk_current_vm->names; - uint16_t index = c11_smallmap_s2n__get(&self->interned, name, 0); + py_Name index = c11_smallmap_s2n__get(&self->interned, name, 0); if(index != 0) return index; // generate new index - if(self->interned.length > 65530) c11__abort("py_Name index overflow"); - // NOTE: we must allocate the string in the heap so iterators are not invalidated - char* p = PK_MALLOC(name.size + 1); - memcpy(p, name.data, name.size); - p[name.size] = '\0'; - RInternedEntry* entry = c11_vector__emplace(&self->r_interned); - entry->data = p; - entry->size = name.size; - memset(&entry->obj, 0, sizeof(py_TValue)); - index = self->r_interned.length; // 1-based + InternedEntry* p = PK_MALLOC(sizeof(InternedEntry) + name.size + 1); + p->size = name.size; + memcpy(p->data, name.data, name.size); + p->data[name.size] = '\0'; + memset(&p->obj, 0, sizeof(py_TValue)); + index = (py_Name)p; // save to _interned - c11_smallmap_s2n__set(&self->interned, (c11_sv){p, name.size}, index); - assert(self->interned.length == self->r_interned.length); + c11_smallmap_s2n__set(&self->interned, (c11_sv){p->data, name.size}, index); return index; } const char* py_name2str(py_Name index) { - InternedNames* self = &pk_current_vm->names; - assert(index > 0 && index <= self->interned.length); - return c11__getitem(RInternedEntry, &self->r_interned, index - 1).data; + InternedEntry* p = (InternedEntry*)index; + return p->data; } c11_sv py_name2sv(py_Name index) { - InternedNames* self = &pk_current_vm->names; - assert(index > 0 && index <= self->interned.length); - RInternedEntry entry = c11__getitem(RInternedEntry, &self->r_interned, index - 1); - return (c11_sv){entry.data, entry.size}; + InternedEntry* p = (InternedEntry*)index; + return (c11_sv){p->data, p->size}; } py_GlobalRef py_name2ref(py_Name index) { - InternedNames* self = &pk_current_vm->names; - assert(index > 0 && index <= self->interned.length); - RInternedEntry* entry = c11__at(RInternedEntry, &self->r_interned, index - 1); - if(entry->obj.type == tp_nil) { + InternedEntry* p = (InternedEntry*)index; + if(p->obj.type == tp_nil) { c11_sv sv; - sv.data = entry->data; - sv.size = entry->size; - py_newstrv(&entry->obj, sv); + sv.data = p->data; + sv.size = p->size; + py_newstrv(&p->obj, sv); } - return &entry->obj; + return &p->obj; } diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index d9986d8a..627b9b76 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -442,7 +442,7 @@ static bool if(decl->starred_kwarg != -1) py_newdict(&buffer[decl->starred_kwarg]); for(int j = 0; j < kwargc; j++) { - py_Name key = py_toint(&p1[2 * j]); + py_Name key = (py_Name)py_toint(&p1[2 * j]); int index = c11_smallmap_n2i__get(&decl->kw_to_index, key, -1); // if key is an explicit key, set as local variable if(index >= 0) { @@ -681,8 +681,9 @@ void ManagedHeap__mark(ManagedHeap* self) { pk__mark_value(&vm->reg[i]); } // mark interned names - for(int i = 0; i < vm->names.r_interned.length; i++) { - RInternedEntry* entry = c11__at(RInternedEntry, &vm->names.r_interned, i); + for(int i = 0; i < vm->names.interned.length; i++) { + c11_smallmap_s2n_KV* kv = c11__at(c11_smallmap_s2n_KV, &vm->names.interned, i); + InternedEntry* entry = (InternedEntry*)kv->value; pk__mark_value(&entry->obj); } diff --git a/src/objects/codeobject.c b/src/objects/codeobject.c index 6483bfe5..0be7711f 100644 --- a/src/objects/codeobject.c +++ b/src/objects/codeobject.c @@ -123,10 +123,12 @@ void CodeObject__ctor(CodeObject* self, SourceData_ src, c11_sv name) { c11_vector__ctor(&self->codes_ex, sizeof(BytecodeEx)); c11_vector__ctor(&self->consts, sizeof(py_TValue)); - c11_vector__ctor(&self->varnames, sizeof(uint16_t)); + c11_vector__ctor(&self->varnames, sizeof(py_Name)); + c11_vector__ctor(&self->names, sizeof(py_Name)); self->nlocals = 0; c11_smallmap_n2i__ctor(&self->varnames_inv); + c11_smallmap_n2i__ctor(&self->names_inv); c11_vector__ctor(&self->blocks, sizeof(CodeBlock)); c11_vector__ctor(&self->func_decls, sizeof(FuncDecl_)); @@ -147,8 +149,10 @@ void CodeObject__dtor(CodeObject* self) { c11_vector__dtor(&self->consts); c11_vector__dtor(&self->varnames); + c11_vector__dtor(&self->names); c11_smallmap_n2i__dtor(&self->varnames_inv); + c11_smallmap_n2i__dtor(&self->names_inv); c11_vector__dtor(&self->blocks); @@ -172,13 +176,22 @@ void Function__ctor(Function* self, FuncDecl_ decl, py_GlobalRef module, py_Ref int CodeObject__add_varname(CodeObject* self, py_Name name) { int index = c11_smallmap_n2i__get(&self->varnames_inv, name, -1); if(index >= 0) return index; - c11_vector__push(uint16_t, &self->varnames, name); + c11_vector__push(py_Name, &self->varnames, name); self->nlocals++; index = self->varnames.length - 1; c11_smallmap_n2i__set(&self->varnames_inv, name, index); return index; } +int CodeObject__add_name(CodeObject* self, py_Name name) { + int index = c11_smallmap_n2i__get(&self->names_inv, name, -1); + if(index >= 0) return index; + c11_vector__push(py_Name, &self->names, name); + index = self->names.length - 1; + c11_smallmap_n2i__set(&self->names_inv, name, index); + return index; +} + void Function__dtor(Function* self) { // printf("%s() in %s freed!\n", self->decl->code.name->data, // self->decl->code.src->filename->data);