Compare commits

...

4 Commits

Author SHA1 Message Date
blueloveTH
04a44a4aa6 fix path_len 2025-06-14 19:26:14 +08:00
blueloveTH
f9debd804e add py_resetallvm 2025-06-14 18:16:28 +08:00
blueloveTH
8f48c7d081 Update internal.c 2025-06-14 18:12:53 +08:00
blueloveTH
25cbd9c1f1 some refactor 2025-06-14 15:44:18 +08:00
5 changed files with 90 additions and 77 deletions

View File

@ -108,6 +108,8 @@ PK_API int py_currentvm();
PK_API void py_switchvm(int index);
/// Reset the current VM.
PK_API void py_resetvm();
/// Reset All VMs.
PK_API void py_resetallvm();
/// Get the current VM context. This is used for user-defined data.
PK_API void* py_getvmctx();
/// Set the current VM context. This is used for user-defined data.
@ -251,8 +253,6 @@ PK_API py_Name py_namev(c11_sv);
/// Convert a name to a `c11_sv`.
PK_API c11_sv py_name2sv(py_Name);
#define py_ismagicname(name) (true)
/************* Meta Operations *************/
/// Create a new type.
@ -612,12 +612,18 @@ PK_API int py_equal(py_Ref lhs, py_Ref rhs) PY_RAISE;
/// 1: lhs < rhs, 0: lhs >= rhs, -1: error
PK_API int py_less(py_Ref lhs, py_Ref rhs) PY_RAISE;
#define py_eq(lhs, rhs) py_binaryop(lhs, rhs, __eq__, __eq__)
#define py_ne(lhs, rhs) py_binaryop(lhs, rhs, __ne__, __ne__)
#define py_lt(lhs, rhs) py_binaryop(lhs, rhs, __lt__, __gt__)
#define py_le(lhs, rhs) py_binaryop(lhs, rhs, __le__, __ge__)
#define py_gt(lhs, rhs) py_binaryop(lhs, rhs, __gt__, __lt__)
#define py_ge(lhs, rhs) py_binaryop(lhs, rhs, __ge__, __le__)
/// lhs == rhs
PK_API bool py_eq(py_Ref lhs, py_Ref rhs) PY_RAISE PY_RETURN;
/// lhs != rhs
PK_API bool py_ne(py_Ref lhs, py_Ref rhs) PY_RAISE PY_RETURN;
/// lhs < rhs
PK_API bool py_lt(py_Ref lhs, py_Ref rhs) PY_RAISE PY_RETURN;
/// lhs <= rhs
PK_API bool py_le(py_Ref lhs, py_Ref rhs) PY_RAISE PY_RETURN;
/// lhs > rhs
PK_API bool py_gt(py_Ref lhs, py_Ref rhs) PY_RAISE PY_RETURN;
/// lhs >= rhs
PK_API bool py_ge(py_Ref lhs, py_Ref rhs) PY_RAISE PY_RETURN;
/// Python equivalent to `callable(val)`.
PK_API bool py_callable(py_Ref val);

View File

@ -602,32 +602,32 @@ FrameResult VM__run_top_frame(VM* self) {
DISPATCH();
}
/*****************************/
#define CASE_BINARY_OP(label, op, rop)\
case label: {\
if(!pk_stack_binaryop(self, op, rop)) goto __ERROR;\
POP();\
*TOP() = self->last_retval;\
DISPATCH();\
}
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__)
#define CASE_BINARY_OP(label, op, rop) \
case label: { \
if(!pk_stack_binaryop(self, op, rop)) goto __ERROR; \
POP(); \
*TOP() = self->last_retval; \
DISPATCH(); \
}
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
case OP_IS_OP: {
bool res = py_isidentical(SECOND(), TOP());
@ -1319,17 +1319,11 @@ bool py_binaryop(py_Ref lhs, py_Ref rhs, py_Name op, py_Name rop) {
return ok;
}
bool py_binaryadd(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __add__, __radd__);
}
bool py_binaryadd(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __add__, __radd__); }
bool py_binarysub(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __sub__, __rsub__);
}
bool py_binarysub(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __sub__, __rsub__); }
bool py_binarymul(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __mul__, __rmul__);
}
bool py_binarymul(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __mul__, __rmul__); }
bool py_binarytruediv(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __truediv__, __rtruediv__);
@ -1339,37 +1333,33 @@ bool py_binaryfloordiv(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __floordiv__, __rfloordiv__);
}
bool py_binarymod(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __mod__, __rmod__);
}
bool py_binarymod(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __mod__, __rmod__); }
bool py_binarypow(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __pow__, __rpow__);
}
bool py_binarypow(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __pow__, __rpow__); }
bool py_binarylshift(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __lshift__, 0);
}
bool py_binarylshift(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __lshift__, 0); }
bool py_binaryrshift(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __rshift__, 0);
}
bool py_binaryrshift(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __rshift__, 0); }
bool py_binaryand(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __and__, 0);
}
bool py_binaryand(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __and__, 0); }
bool py_binaryor(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __or__, 0);
}
bool py_binaryor(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __or__, 0); }
bool py_binaryxor(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __xor__, 0);
}
bool py_binaryxor(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __xor__, 0); }
bool py_binarymatmul(py_Ref lhs, py_Ref rhs) {
return py_binaryop(lhs, rhs, __matmul__, 0);
}
bool py_binarymatmul(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __matmul__, 0); }
bool py_eq(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __eq__, __eq__); }
bool py_ne(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __ne__, __ne__); }
bool py_lt(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __lt__, __gt__); }
bool py_le(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __le__, __ge__); }
bool py_gt(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __gt__, __lt__); }
bool py_ge(py_Ref lhs, py_Ref rhs) { return py_binaryop(lhs, rhs, __ge__, __le__); }
static bool stack_format_object(VM* self, c11_sv spec) {
// format TOS via `spec` inplace

View File

@ -72,14 +72,12 @@ static int BinTree__cmp_cstr(void* lhs, void* rhs) {
return strcmp(l, r);
}
static int BinTree__cmp_voidp(void* lhs, void* rhs) {
return lhs < rhs ? -1 : (lhs > rhs ? 1 : 0);
}
static int BinTree__cmp_voidp(void* lhs, void* rhs) { return lhs < rhs ? -1 : (lhs > rhs ? 1 : 0); }
void VM__ctor(VM* self) {
self->top_frame = NULL;
static const BinTreeConfig modules_config = {
const static BinTreeConfig modules_config = {
.f_cmp = BinTree__cmp_cstr,
.need_free_key = true,
};
@ -114,7 +112,7 @@ void VM__ctor(VM* self) {
ManagedHeap__ctor(&self->heap);
ValueStack__ctor(&self->stack);
static const BinTreeConfig cached_names_config = {
const static BinTreeConfig cached_names_config = {
.f_cmp = BinTree__cmp_voidp,
.need_free_key = false,
};
@ -417,6 +415,7 @@ py_Type pk_newtype(const char* name,
}
py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) {
if(strlen(name) == 0) c11__abort("type name cannot be empty");
py_Type type = pk_newtype(name, base, module, dtor, false, false);
if(module) py_setdict(module, py_name(name), py_tpobject(type));
return type;

View File

@ -9,11 +9,15 @@
_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;
@ -52,6 +56,9 @@ py_GlobalRef py_None() { return &_None; }
py_GlobalRef py_NIL() { return &_NIL; }
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) {
@ -87,6 +94,14 @@ void py_resetvm() {
VM__ctor(vm);
}
void py_resetallvm() {
for(int i = 0; i < 16; i++) {
py_switchvm(i);
py_resetvm();
}
py_switchvm(0);
}
int py_currentvm() {
for(int i = 0; i < 16; i++) {
if(pk_all_vm[i] == pk_current_vm) return i;
@ -233,7 +248,7 @@ bool pk_loadmethod(py_StackRef self, py_Name name) {
}
py_Ref py_tpfindmagic(py_Type t, py_Name name) {
assert(py_ismagicname(name));
// assert(py_ismagicname(name));
return py_tpfindname(t, name);
}
@ -260,7 +275,7 @@ py_Type py_tpbase(py_Type t) {
}
PK_DEPRECATED py_Ref py_tpgetmagic(py_Type type, py_Name name) {
assert(py_ismagicname(name));
// assert(py_ismagicname(name));
py_TypeInfo* ti = pk__type_info(type);
py_Ref retval = py_getdict(&ti->self, name);
return retval != NULL ? retval : py_NIL();
@ -283,7 +298,7 @@ bool py_tpcall(py_Type type, int argc, py_Ref argv) {
bool pk_callmagic(py_Name name, int argc, py_Ref argv) {
assert(argc >= 1);
assert(py_ismagicname(name));
// assert(py_ismagicname(name));
py_Ref tmp = py_tpfindmagic(argv->type, name);
if(!tmp) return AttributeError(argv, name);
return py_call(tmp, argc, argv);

View File

@ -24,7 +24,10 @@ void py_setglobal(py_Name name, py_Ref val) { py_setdict(&pk_current_vm->main, n
py_Ref py_newmodule(const char* path) {
ManagedHeap* heap = &pk_current_vm->heap;
if(strlen(path) > PK_MAX_MODULE_PATH_LEN) c11__abort("module path too long: %s", path);
int path_len = strlen(path);
if(path_len > PK_MAX_MODULE_PATH_LEN) c11__abort("module path too long: %s", path);
if(path_len == 0) c11__abort("module path cannot be empty");
py_Ref r0 = py_pushtmp();
py_Ref r1 = py_pushtmp();
@ -35,7 +38,7 @@ py_Ref py_newmodule(const char* path) {
._obj = ManagedHeap__new(heap, tp_module, -1, 0),
};
int last_dot = c11_sv__rindex((c11_sv){path, strlen(path)}, '.');
int last_dot = c11_sv__rindex((c11_sv){path, path_len}, '.');
if(last_dot == -1) {
py_newstr(r1, path);
py_setdict(r0, __name__, r1);