mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +00:00
162 lines
3.8 KiB
C
162 lines
3.8 KiB
C
#include "pocketpy/objects/codeobject.h"
|
|
#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;
|
|
|
|
static bool pk_initialized;
|
|
static bool pk_finalized;
|
|
|
|
static VM pk_default_vm;
|
|
static VM* pk_all_vm[16];
|
|
static py_TValue _True, _False, _None, _NIL;
|
|
|
|
void py_initialize() {
|
|
c11__rtassert(!pk_finalized);
|
|
|
|
if(pk_initialized) {
|
|
// c11__abort("py_initialize() can only be called once!");
|
|
return;
|
|
}
|
|
|
|
pk_names_initialize();
|
|
|
|
// check endianness
|
|
int x = 1;
|
|
bool is_little_endian = *(char*)&x == 1;
|
|
if(!is_little_endian) c11__abort("is_little_endian != true");
|
|
|
|
_Static_assert(sizeof(py_TValue) == 24, "sizeof(py_TValue) != 24");
|
|
_Static_assert(offsetof(py_TValue, extra) == 4, "offsetof(py_TValue, extra) != 4");
|
|
|
|
pk_current_vm = pk_all_vm[0] = &pk_default_vm;
|
|
|
|
// initialize some convenient references
|
|
py_newbool(&_True, true);
|
|
py_newbool(&_False, false);
|
|
py_newnone(&_None);
|
|
py_newnil(&_NIL);
|
|
VM__ctor(&pk_default_vm);
|
|
|
|
pk_initialized = true;
|
|
}
|
|
|
|
void py_finalize() {
|
|
if(pk_finalized) c11__abort("py_finalize() can only be called once!");
|
|
pk_finalized = true;
|
|
|
|
for(int i = 1; i < 16; i++) {
|
|
VM* vm = pk_all_vm[i];
|
|
if(vm) {
|
|
// temp fix https://github.com/pocketpy/pocketpy/issues/315
|
|
// TODO: refactor VM__ctor and VM__dtor
|
|
pk_current_vm = vm;
|
|
VM__dtor(vm);
|
|
PK_FREE(vm);
|
|
}
|
|
}
|
|
pk_current_vm = &pk_default_vm;
|
|
VM__dtor(&pk_default_vm);
|
|
pk_current_vm = NULL;
|
|
|
|
pk_names_finalize();
|
|
}
|
|
|
|
int py_currentvm() {
|
|
for(int i = 0; i < 16; i++) {
|
|
if(pk_all_vm[i] == pk_current_vm) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void py_switchvm(int index) {
|
|
if(index < 0 || index >= 16) c11__abort("invalid vm index");
|
|
if(!pk_all_vm[index]) {
|
|
pk_current_vm = pk_all_vm[index] = PK_MALLOC(sizeof(VM));
|
|
memset(pk_current_vm, 0, sizeof(VM));
|
|
VM__ctor(pk_all_vm[index]);
|
|
} else {
|
|
pk_current_vm = pk_all_vm[index];
|
|
}
|
|
}
|
|
|
|
void py_resetvm() {
|
|
VM* vm = pk_current_vm;
|
|
VM__dtor(vm);
|
|
memset(vm, 0, sizeof(VM));
|
|
VM__ctor(vm);
|
|
}
|
|
|
|
void py_resetallvm() {
|
|
for(int i = 0; i < 16; i++) {
|
|
py_switchvm(i);
|
|
py_resetvm();
|
|
}
|
|
py_switchvm(0);
|
|
}
|
|
|
|
void* py_getvmctx() { return pk_current_vm->ctx; }
|
|
|
|
void py_setvmctx(void* ctx) { pk_current_vm->ctx = ctx; }
|
|
|
|
py_Callbacks* py_callbacks() { return &pk_current_vm->callbacks; }
|
|
|
|
/////////////////////////////
|
|
|
|
void py_sys_setargv(int argc, char** argv) {
|
|
py_GlobalRef sys = py_getmodule("sys");
|
|
py_Ref argv_list = py_getdict(sys, py_name("argv"));
|
|
py_list_clear(argv_list);
|
|
for(int i = 0; i < argc; i++) {
|
|
py_newstr(py_list_emplace(argv_list), argv[i]);
|
|
}
|
|
}
|
|
|
|
void py_sys_settrace(py_TraceFunc func, bool reset) {
|
|
TraceInfo* info = &pk_current_vm->trace_info;
|
|
info->func = func;
|
|
if(!reset) return;
|
|
if(info->prev_loc.src) {
|
|
PK_DECREF(info->prev_loc.src);
|
|
info->prev_loc.src = NULL;
|
|
}
|
|
info->prev_loc.lineno = -1;
|
|
}
|
|
|
|
int py_gc_collect() {
|
|
ManagedHeap* heap = &pk_current_vm->heap;
|
|
return ManagedHeap__collect(heap);
|
|
}
|
|
|
|
/////////////////////////////
|
|
|
|
void* py_malloc(size_t size) { return PK_MALLOC(size); }
|
|
|
|
void* py_realloc(void* ptr, size_t size) { return PK_REALLOC(ptr, size); }
|
|
|
|
void py_free(void* ptr) { PK_FREE(ptr); }
|
|
|
|
/////////////////////////////
|
|
|
|
py_GlobalRef py_True() { return &_True; }
|
|
|
|
py_GlobalRef py_False() { return &_False; }
|
|
|
|
py_GlobalRef py_None() { return &_None; }
|
|
|
|
py_GlobalRef py_NIL() { return &_NIL; }
|
|
|
|
/////////////////////////////
|
|
|
|
const char* pk_opname(Opcode op) {
|
|
const static char* OP_NAMES[] = {
|
|
#define OPCODE(name) #name,
|
|
#include "pocketpy/xmacros/opcodes.h"
|
|
#undef OPCODE
|
|
};
|
|
return OP_NAMES[op];
|
|
}
|