This commit is contained in:
blueloveTH 2025-06-04 19:37:30 +08:00
parent c5a70ec4aa
commit 1bb104086b
12 changed files with 178 additions and 140 deletions

View File

@ -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"

View File

@ -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 <time.h>
@ -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

View File

@ -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 *************/

View File

@ -1,25 +1,96 @@
#include "pocketpy/common/name.h"
#include "pocketpy/common/str.h"
#include "pocketpy/pocketpy.h"
#include <stdatomic.h>
typedef struct InternedEntry InternedEntry;
typedef struct InternedEntry{
InternedEntry* prev;
InternedEntry* next;
py_i64 hash;
typedef struct NameBucket NameBucket;
typedef struct NameBucket {
NameBucket* next;
uint64_t hash;
int size; // size of the data excluding the null-terminator
char data[]; // null-terminated data
} InternedEntry;
} NameBucket;
typedef struct {
InternedEntry* table[1 << 16];
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;
}

View File

@ -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"

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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);
@ -843,3 +836,15 @@ 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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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) {