diff --git a/include/pocketpy/common/smallmap.h b/include/pocketpy/common/smallmap.h index 26f3ccea..74556202 100644 --- a/include/pocketpy/common/smallmap.h +++ b/include/pocketpy/common/smallmap.h @@ -20,8 +20,8 @@ #define SMALLMAP_T__HEADER #define K c11_sv -#define V py_Name -#define NAME c11_smallmap_v2n +#define V int +#define NAME c11_smallmap_v2d #define less(a, b) (c11_sv__cmp((a), (b)) < 0) #define equal(a, b) (c11_sv__cmp((a), (b)) == 0) #include "pocketpy/xmacros/smallmap.h" diff --git a/include/pocketpy/interpreter/name.h b/include/pocketpy/interpreter/name.h deleted file mode 100644 index e69de29b..00000000 diff --git a/include/pocketpy/interpreter/vm.h b/include/pocketpy/interpreter/vm.h index 00381d7a..78065bed 100644 --- a/include/pocketpy/interpreter/vm.h +++ b/include/pocketpy/interpreter/vm.h @@ -1,12 +1,12 @@ #pragma once #include "pocketpy/common/memorypool.h" +#include "pocketpy/common/name.h" #include "pocketpy/objects/codeobject.h" #include "pocketpy/pocketpy.h" #include "pocketpy/interpreter/heap.h" #include "pocketpy/interpreter/frame.h" #include "pocketpy/interpreter/typeinfo.h" -#include "pocketpy/interpreter/name.h" #include "pocketpy/interpreter/line_profiler.h" #include @@ -49,6 +49,8 @@ typedef struct VM { py_TValue reg[8]; // users' registers void* ctx; // user-defined context + NameDict cached_names; + py_StackRef curr_class; py_StackRef curr_decl_based_function; TraceInfo trace_info; @@ -56,7 +58,6 @@ typedef struct VM { LineProfiler line_profiler; py_TValue vectorcall_buffer[PK_MAX_CO_VARNAMES]; - InternedNames names; FixedMemoryPool pool_frame; ManagedHeap heap; ValueStack stack; // put `stack` at the end for better cache locality diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 4762d707..93c68986 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -237,13 +237,13 @@ PK_API py_Name py_name(const char*); /// Convert a name to a null-terminated string. PK_API const char* py_name2str(py_Name); /// Convert a name to a python `str` object with cache. -PK_API py_GlobalRef py_name2ref(py_Name); +PK_API py_ItemRef py_name2ref(py_Name); /// Convert a `c11_sv` to a name. PK_API py_Name py_namev(c11_sv); /// Convert a name to a `c11_sv`. PK_API c11_sv py_name2sv(py_Name); -/// Check if the name matches the two underscores pattern. e.g. `__init__`, `__str__`, etc. -PK_API bool py_ismagicname(py_Name); + +#define py_ismagicname(name) (true) /************* Meta Operations *************/ diff --git a/src/common/name.c b/src/common/name.c index 191d9480..2c479131 100644 --- a/src/common/name.c +++ b/src/common/name.c @@ -1,25 +1,96 @@ #include "pocketpy/common/name.h" +#include "pocketpy/common/str.h" +#include "pocketpy/pocketpy.h" #include -typedef struct InternedEntry InternedEntry; -typedef struct InternedEntry{ - InternedEntry* prev; - InternedEntry* next; - py_i64 hash; - int size; // size of the data excluding the null-terminator - char data[]; // null-terminated data -} InternedEntry; +typedef struct NameBucket NameBucket; -typedef struct { - InternedEntry* table[1 << 16]; +typedef struct NameBucket { + NameBucket* next; + uint64_t hash; + int size; // size of the data excluding the null-terminator + char data[]; // null-terminated data +} NameBucket; + +static struct { + NameBucket* table[0x10000]; atomic_bool lock; -} InternedNames; +} pk_string_table; + +#define MAGIC_METHOD(x) py_Name x; +#include "pocketpy/xmacros/magics.h" +#undef MAGIC_METHOD void pk_names_initialize() { - +#define MAGIC_METHOD(x) x = py_name(#x); +#include "pocketpy/xmacros/magics.h" +#undef MAGIC_METHOD } - void pk_names_finalize() { - + for(int i = 0; i < 0x10000; i++) { + NameBucket* p = pk_string_table.table[i]; + while(p) { + NameBucket* next = p->next; + PK_FREE(p); + p = next; + } + pk_string_table.table[i] = NULL; + } +} + +py_Name py_namev(c11_sv name) { + while(atomic_exchange(&pk_string_table.lock, true)) { + // busy-wait until the lock is released + } + uint64_t hash = c11_sv__hash(name); + int index = hash & 0xFFFF; + NameBucket* p = pk_string_table.table[index]; + bool found = false; + while(p) { + c11_sv p_sv = {p->data, p->size}; + if(p->hash == hash && c11__sveq(p_sv, name)) { + found = true; + break; + } else { + p = p->next; + } + } + if(found) { + atomic_store(&pk_string_table.lock, false); + return (py_Name)p; + } + + // generate new index + NameBucket* entry = PK_MALLOC(sizeof(NameBucket) + name.size + 1); + entry->next = NULL; + entry->hash = hash; + entry->size = name.size; + memcpy(entry->data, name.data, name.size); + entry->data[name.size] = '\0'; + if(p == NULL) { + pk_string_table.table[index] = entry; + } else { + assert(p->next == NULL); + p->next = entry; + } + atomic_store(&pk_string_table.lock, false); + return (py_Name)entry; +} + +c11_sv py_name2sv(py_Name index) { + NameBucket* p = (NameBucket*)index; + return (c11_sv){p->data, p->size}; +} + +py_Name py_name(const char* name) { + c11_sv sv; + sv.data = name; + sv.size = strlen(name); + return py_namev(sv); +} + +const char* py_name2str(py_Name index) { + NameBucket* p = (NameBucket*)index; + return p->data; } \ No newline at end of file diff --git a/src/common/smallmap.c b/src/common/smallmap.c index fa017811..228fd42f 100644 --- a/src/common/smallmap.c +++ b/src/common/smallmap.c @@ -16,8 +16,8 @@ #define SMALLMAP_T__SOURCE #define K c11_sv -#define V py_Name -#define NAME c11_smallmap_v2n +#define V int +#define NAME c11_smallmap_v2d #define less(a, b) (c11_sv__cmp((a), (b)) < 0) #define equal(a, b) (c11_sv__cmp((a), (b)) == 0) #include "pocketpy/xmacros/smallmap.h" diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 4ca7785e..c557630b 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -1,5 +1,6 @@ #include "pocketpy/compiler/compiler.h" #include "pocketpy/common/vector.h" +#include "pocketpy/common/name.h" #include "pocketpy/compiler/lexer.h" #include "pocketpy/objects/base.h" #include "pocketpy/objects/codeobject.h" @@ -63,7 +64,7 @@ typedef struct Ctx { bool is_compiling_class; c11_vector /*T=Expr_p*/ s_expr; c11_smallmap_n2d global_names; - c11_smallmap_v2n co_consts_string_dedup_map; // this stores 0-based index instead of pointer + c11_smallmap_v2d co_consts_string_dedup_map; // this stores 0-based index instead of pointer } Ctx; typedef struct Expr Expr; @@ -1076,7 +1077,7 @@ static void Ctx__ctor(Ctx* self, CodeObject* co, FuncDecl* func, int level) { self->is_compiling_class = false; c11_vector__ctor(&self->s_expr, sizeof(Expr*)); c11_smallmap_n2d__ctor(&self->global_names); - c11_smallmap_v2n__ctor(&self->co_consts_string_dedup_map); + c11_smallmap_v2d__ctor(&self->co_consts_string_dedup_map); } static void Ctx__dtor(Ctx* self) { @@ -1087,11 +1088,11 @@ static void Ctx__dtor(Ctx* self) { c11_vector__dtor(&self->s_expr); c11_smallmap_n2d__dtor(&self->global_names); // free the dedup map - c11__foreach(c11_smallmap_v2n_KV, &self->co_consts_string_dedup_map, p_kv) { + c11__foreach(c11_smallmap_v2d_KV, &self->co_consts_string_dedup_map, p_kv) { const char* p = p_kv->key.data; PK_FREE((void*)p); } - c11_smallmap_v2n__dtor(&self->co_consts_string_dedup_map); + c11_smallmap_v2d__dtor(&self->co_consts_string_dedup_map); } static int Ctx__prepare_loop_divert(Ctx* self, int line, bool is_break) { @@ -1200,9 +1201,7 @@ 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_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) { @@ -1211,7 +1210,7 @@ static int Ctx__add_const_string(Ctx* self, c11_sv key) { int index = self->co->consts.length - 1; return index; } - uintptr_t* val = c11_smallmap_v2n__try_get(&self->co_consts_string_dedup_map, key); + int* val = c11_smallmap_v2d__try_get(&self->co_consts_string_dedup_map, key); if(val) { return *val; } else { @@ -1222,7 +1221,7 @@ static int Ctx__add_const_string(Ctx* self, c11_sv key) { char* new_buf = PK_MALLOC(key.size + 1); memcpy(new_buf, key.data, key.size); new_buf[key.size] = 0; - c11_smallmap_v2n__set(&self->co_consts_string_dedup_map, + c11_smallmap_v2d__set(&self->co_consts_string_dedup_map, (c11_sv){new_buf, key.size}, index); return index; @@ -2376,7 +2375,7 @@ static Error* compile_function(Compiler* self, int decorators) { } } - Ctx__emit_(ctx(), OP_STORE_CLASS_ATTR, decl_name, prev()->line); + Ctx__emit_(ctx(), OP_STORE_CLASS_ATTR, Ctx__add_name(ctx(), decl_name), prev()->line); } else { NameExpr* e = NameExpr__new(prev()->line, decl_name, name_scope(self)); vtemit_store((Expr*)e, ctx()); @@ -2404,7 +2403,7 @@ static Error* compile_class(Compiler* self, int decorators) { } else { Ctx__s_emit_top(ctx()); // [] } - Ctx__emit_(ctx(), OP_BEGIN_CLASS, name, BC_KEEPLINE); + Ctx__emit_(ctx(), OP_BEGIN_CLASS, Ctx__add_name(ctx(), name), BC_KEEPLINE); c11__foreach(Ctx, &self->contexts, it) { if(it->is_compiling_class) return SyntaxError(self, "nested class is not allowed"); @@ -2788,7 +2787,10 @@ 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, Ctx__add_name(ctx(), ne->name), BC_KEEPLINE); + Ctx__emit_(ctx(), + OP_ADD_CLASS_ANNOTATION, + Ctx__add_name(ctx(), ne->name), + BC_KEEPLINE); } } } diff --git a/src/interpreter/name.c b/src/interpreter/name.c deleted file mode 100644 index 529e3dcc..00000000 --- a/src/interpreter/name.c +++ /dev/null @@ -1,67 +0,0 @@ -#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_v2n__ctor(&self->interned); - - // initialize all magic names -#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->interned.length; i++) { - c11_smallmap_v2n_KV* kv = c11__at(c11_smallmap_v2n_KV, &self->interned, i); - PK_FREE((void*)kv->value); - } - c11_smallmap_v2n__dtor(&self->interned); -} - -py_Name py_name(const char* name) { - c11_sv sv; - sv.data = name; - sv.size = strlen(name); - return py_namev(sv); -} - -py_Name py_namev(c11_sv name) { - InternedNames* self = &pk_current_vm->names; - py_Name index = c11_smallmap_v2n__get(&self->interned, name, 0); - if(index != 0) return index; - // generate new index - 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_v2n__set(&self->interned, (c11_sv){p->data, name.size}, index); - return index; -} - -const char* py_name2str(py_Name index) { - InternedEntry* p = (InternedEntry*)index; - return p->data; -} - -c11_sv py_name2sv(py_Name index) { - InternedEntry* p = (InternedEntry*)index; - return (c11_sv){p->data, p->size}; -} - -py_GlobalRef py_name2ref(py_Name index) { - InternedEntry* p = (InternedEntry*)index; - if(p->obj.type == tp_nil) { - c11_sv sv; - sv.data = p->data; - sv.size = p->size; - py_newstrv(&p->obj, sv); - } - return &p->obj; -} diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 135f395b..3afe0c70 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -65,7 +65,6 @@ static void py_TypeInfo__ctor(py_TypeInfo* self, void VM__ctor(VM* self) { self->top_frame = NULL; - InternedNames__ctor(&self->names); ModuleDict__ctor(&self->modules, "", *py_NIL()); TypeList__ctor(&self->types); @@ -97,6 +96,7 @@ void VM__ctor(VM* self) { ManagedHeap__ctor(&self->heap); ValueStack__ctor(&self->stack); + NameDict__ctor(&self->cached_names, PK_INST_ATTR_LOAD_FACTOR); /* Init Builtin Types */ // 0: unused @@ -274,7 +274,7 @@ void VM__dtor(VM* self) { TypeList__dtor(&self->types); FixedMemoryPool__dtor(&self->pool_frame); ValueStack__dtor(&self->stack); - InternedNames__dtor(&self->names); + NameDict__dtor(&self->cached_names); } void VM__push_frame(VM* self, py_Frame* frame) { @@ -666,13 +666,6 @@ void ManagedHeap__mark(ManagedHeap* self) { for(int i = 0; i < c11__count_array(vm->reg); i++) { pk__mark_value(&vm->reg[i]); } - // mark interned names - for(int i = 0; i < vm->names.interned.length; i++) { - c11_smallmap_v2n_KV* kv = c11__at(c11_smallmap_v2n_KV, &vm->names.interned, i); - InternedEntry* entry = (InternedEntry*)kv->value; - pk__mark_value(&entry->obj); - } - /*****************************/ while(p_stack->length > 0) { PyObject* obj = c11_vector__back(PyObject*, p_stack); @@ -842,4 +835,16 @@ int py_replinput(char* buf, int max_size) { buf[size] = '\0'; return size; +} + +py_Ref py_name2ref(py_Name name) { + assert(name != NULL); + NameDict* d = &pk_current_vm->cached_names; + py_Ref res = NameDict__try_get(d, name); + if(res != NULL) return res; + // not found, create a new one + py_TValue tmp; + py_newstrv(&tmp, py_name2sv(name)); + NameDict__set(d, name, &tmp); + return NameDict__try_get(d, name); } \ No newline at end of file diff --git a/src/modules/dis.c b/src/modules/dis.c index 85c7fc68..cc750b09 100644 --- a/src/modules/dis.c +++ b/src/modules/dis.c @@ -99,11 +99,31 @@ static bool disassemble(CodeObject* co) { pk_sprintf(&ss, " (%s)", decl->code.name->data); break; } - case OP_BINARY_OP: { - py_Name name = byte.arg & 0xFF; - pk_sprintf(&ss, " (%s)", pk_op2str(name)); - break; - } +#define CASE_BINARY_OP(label, op, rop) \ + case label: { \ + pk_sprintf(&ss, " (%s)", pk_op2str(op)); \ + break; \ + } + CASE_BINARY_OP(OP_BINARY_ADD, __add__, __radd__) + CASE_BINARY_OP(OP_BINARY_SUB, __sub__, __rsub__) + CASE_BINARY_OP(OP_BINARY_MUL, __mul__, __rmul__) + CASE_BINARY_OP(OP_BINARY_TRUEDIV, __truediv__, __rtruediv__) + CASE_BINARY_OP(OP_BINARY_FLOORDIV, __floordiv__, __rfloordiv__) + CASE_BINARY_OP(OP_BINARY_MOD, __mod__, __rmod__) + CASE_BINARY_OP(OP_BINARY_POW, __pow__, __rpow__) + CASE_BINARY_OP(OP_BINARY_LSHIFT, __lshift__, 0) + CASE_BINARY_OP(OP_BINARY_RSHIFT, __rshift__, 0) + CASE_BINARY_OP(OP_BINARY_AND, __and__, 0) + CASE_BINARY_OP(OP_BINARY_OR, __or__, 0) + CASE_BINARY_OP(OP_BINARY_XOR, __xor__, 0) + CASE_BINARY_OP(OP_BINARY_MATMUL, __matmul__, 0) + CASE_BINARY_OP(OP_COMPARE_LT, __lt__, __gt__) + CASE_BINARY_OP(OP_COMPARE_LE, __le__, __ge__) + CASE_BINARY_OP(OP_COMPARE_EQ, __eq__, __eq__) + CASE_BINARY_OP(OP_COMPARE_NE, __ne__, __ne__) + CASE_BINARY_OP(OP_COMPARE_GT, __gt__, __lt__) + CASE_BINARY_OP(OP_COMPARE_GE, __ge__, __le__) +#undef CASE_BINARY_OP } } while(0); diff --git a/src/modules/pkpy.c b/src/modules/pkpy.c index 45d75ff1..1edd036c 100644 --- a/src/modules/pkpy.c +++ b/src/modules/pkpy.c @@ -160,7 +160,7 @@ static void static bool _pk_compute_thread_flags[16]; static void c11_ComputeThread__dtor(c11_ComputeThread* self) { - if(!self->is_done) { + if(!atomic_load(&self->is_done)) { c11__abort("ComputeThread(%d) is not done yet!! But the object was deleted.", self->vm_index); } @@ -187,7 +187,7 @@ static bool ComputeThread__new__(int argc, py_Ref argv) { c11_ComputeThread* self = py_newobject(py_retval(), py_totype(argv), 0, sizeof(c11_ComputeThread)); self->vm_index = 0; - self->is_done = true; + atomic_store(&self->is_done, true); self->last_retval_data = NULL; self->last_retval_size = 0; self->last_error = NULL; @@ -217,15 +217,16 @@ static bool ComputeThread__init__(int argc, py_Ref argv) { static bool ComputeThread_is_done(int argc, py_Ref argv) { PY_CHECK_ARGC(1); c11_ComputeThread* self = py_touserdata(argv); - py_newbool(py_retval(), self->is_done); + py_newbool(py_retval(), atomic_load(&self->is_done)); return true; } static bool ComputeThread_wait_for_done(int argc, py_Ref argv) { PY_CHECK_ARGC(1); c11_ComputeThread* self = py_touserdata(argv); - while(!self->is_done) + while(!atomic_load(&self->is_done)) { c11_thrd_yield(); + } py_newnone(py_retval()); return true; } @@ -233,7 +234,7 @@ static bool ComputeThread_wait_for_done(int argc, py_Ref argv) { static bool ComputeThread_last_error(int argc, py_Ref argv) { PY_CHECK_ARGC(1); c11_ComputeThread* self = py_touserdata(argv); - if(!self->is_done) return OSError("thread is not done yet"); + if(!atomic_load(&self->is_done)) return OSError("thread is not done yet"); if(self->last_error) { py_newstr(py_retval(), self->last_error); } else { @@ -245,7 +246,7 @@ static bool ComputeThread_last_error(int argc, py_Ref argv) { static bool ComputeThread_last_retval(int argc, py_Ref argv) { PY_CHECK_ARGC(1); c11_ComputeThread* self = py_touserdata(argv); - if(!self->is_done) return OSError("thread is not done yet"); + if(!atomic_load(&self->is_done)) return OSError("thread is not done yet"); if(self->last_retval_data == NULL) return ValueError("no retval available"); return py_pickle_loads(self->last_retval_data, self->last_retval_size); } @@ -273,12 +274,12 @@ static c11_thrd_retval_t ComputeThreadJob_call(void* arg) { unsigned char* retval_data = py_tobytes(py_retval(), &retval_size); self->last_retval_data = c11_memdup(retval_data, retval_size); self->last_retval_size = retval_size; - self->is_done = true; + atomic_store(&self->is_done, true); return (c11_thrd_retval_t)0; __ERROR: self->last_error = py_formatexc(); - self->is_done = true; + atomic_store(&self->is_done, true); py_clearexc(p0); py_newnone(py_retval()); return (c11_thrd_retval_t)0; @@ -296,12 +297,12 @@ static c11_thrd_retval_t ComputeThreadJob_exec(void* arg) { unsigned char* retval_data = py_tobytes(py_retval(), &retval_size); self->last_retval_data = c11_memdup(retval_data, retval_size); self->last_retval_size = retval_size; - self->is_done = true; + atomic_store(&self->is_done, true); return (c11_thrd_retval_t)0; __ERROR: self->last_error = py_formatexc(); - self->is_done = true; + atomic_store(&self->is_done, true); py_clearexc(p0); return (c11_thrd_retval_t)0; } @@ -309,7 +310,7 @@ __ERROR: static bool ComputeThread_submit_exec(int argc, py_Ref argv) { PY_CHECK_ARGC(2); c11_ComputeThread* self = py_touserdata(py_arg(0)); - if(!self->is_done) return OSError("thread is not done yet"); + if(!atomic_load(&self->is_done)) return OSError("thread is not done yet"); PY_CHECK_ARG_TYPE(1, tp_str); const char* source = py_tostr(py_arg(1)); /**************************/ @@ -319,10 +320,10 @@ static bool ComputeThread_submit_exec(int argc, py_Ref argv) { job->mode = EXEC_MODE; c11_ComputeThread__reset_job(self, job, ComputeThreadJobExec__dtor); /**************************/ - self->is_done = false; + atomic_store(&self->is_done, false); bool ok = c11_thrd_create(&self->thread, ComputeThreadJob_exec, job); if(!ok) { - self->is_done = true; + atomic_store(&self->is_done, true); return OSError("thrd_create() failed"); } py_newnone(py_retval()); @@ -332,7 +333,7 @@ static bool ComputeThread_submit_exec(int argc, py_Ref argv) { static bool ComputeThread_submit_eval(int argc, py_Ref argv) { PY_CHECK_ARGC(2); c11_ComputeThread* self = py_touserdata(py_arg(0)); - if(!self->is_done) return OSError("thread is not done yet"); + if(!atomic_load(&self->is_done)) return OSError("thread is not done yet"); PY_CHECK_ARG_TYPE(1, tp_str); const char* source = py_tostr(py_arg(1)); /**************************/ @@ -342,10 +343,10 @@ static bool ComputeThread_submit_eval(int argc, py_Ref argv) { job->mode = EVAL_MODE; c11_ComputeThread__reset_job(self, job, ComputeThreadJobExec__dtor); /**************************/ - self->is_done = false; + atomic_store(&self->is_done, false); bool ok = c11_thrd_create(&self->thread, ComputeThreadJob_exec, job); if(!ok) { - self->is_done = true; + atomic_store(&self->is_done, true); return OSError("thrd_create() failed"); } py_newnone(py_retval()); @@ -355,7 +356,7 @@ static bool ComputeThread_submit_eval(int argc, py_Ref argv) { static bool ComputeThread_submit_call(int argc, py_Ref argv) { PY_CHECK_ARGC(4); c11_ComputeThread* self = py_touserdata(py_arg(0)); - if(!self->is_done) return OSError("thread is not done yet"); + if(!atomic_load(&self->is_done)) return OSError("thread is not done yet"); PY_CHECK_ARG_TYPE(1, tp_str); PY_CHECK_ARG_TYPE(2, tp_tuple); PY_CHECK_ARG_TYPE(3, tp_dict); @@ -379,10 +380,10 @@ static bool ComputeThread_submit_call(int argc, py_Ref argv) { job->kwargs_size = kwargs_size; c11_ComputeThread__reset_job(self, job, ComputeThreadJobCall__dtor); /**************************/ - self->is_done = false; + atomic_store(&self->is_done, false); bool ok = c11_thrd_create(&self->thread, ComputeThreadJob_call, job); if(!ok) { - self->is_done = true; + atomic_store(&self->is_done, true); return OSError("thrd_create() failed"); } py_newnone(py_retval()); @@ -392,8 +393,8 @@ static bool ComputeThread_submit_call(int argc, py_Ref argv) { static bool c11_ComputeThread__exec_blocked(c11_ComputeThread* self, const char* source, enum py_CompileMode mode) { - if(!self->is_done) return OSError("thread is not done yet"); - self->is_done = false; + if(!atomic_load(&self->is_done)) return OSError("thread is not done yet"); + atomic_store(&self->is_done, false); char* err = NULL; int old_vm_index = py_currentvm(); py_switchvm(self->vm_index); @@ -405,14 +406,14 @@ static bool c11_ComputeThread__exec_blocked(c11_ComputeThread* self, unsigned char* retval_data = py_tobytes(py_retval(), &retval_size); py_switchvm(old_vm_index); bool ok = py_pickle_loads(retval_data, retval_size); - self->is_done = true; + atomic_store(&self->is_done, true); return ok; __ERROR: err = py_formatexc(); py_clearexc(p0); py_switchvm(old_vm_index); - self->is_done = true; + atomic_store(&self->is_done, true); RuntimeError("c11_ComputeThread__exec_blocked() failed:\n%s", err); PK_FREE(err); return false; @@ -454,7 +455,7 @@ static void pk_ComputeThread__register(py_Ref mod) { py_bindmethod(type, "eval", ComputeThread_eval); } -static void pkpy_configmacros_add(py_Ref dict, const char* key, int val){ +static void pkpy_configmacros_add(py_Ref dict, const char* key, int val) { assert(dict->type == tp_dict); py_TValue tmp; py_newint(&tmp, val); diff --git a/src/public/internal.c b/src/public/internal.c index cd7c5945..5a2912fc 100644 --- a/src/public/internal.c +++ b/src/public/internal.c @@ -3,6 +3,7 @@ #include "pocketpy/pocketpy.h" #include "pocketpy/common/utils.h" +#include "pocketpy/common/name.h" #include "pocketpy/interpreter/vm.h" _Thread_local VM* pk_current_vm; @@ -18,6 +19,8 @@ void py_initialize() { return; } + pk_names_initialize(); + // check endianness int x = 1; bool is_little_endian = *(char*)&x == 1; @@ -62,6 +65,8 @@ void py_finalize() { pk_current_vm = &pk_default_vm; VM__dtor(&pk_default_vm); pk_current_vm = NULL; + + pk_names_finalize(); } void py_switchvm(int index) {