mirror of
https://github.com/pocketpy/pocketpy
synced 2026-03-24 14:10:18 +00:00
Compare commits
9 Commits
51047f07a5
...
c0d5f1e575
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0d5f1e575 | ||
|
|
8fe2e4457f | ||
|
|
6b80817a98 | ||
|
|
785bb6841e | ||
|
|
9281ebec56 | ||
|
|
6b592b11df | ||
|
|
a21765a9ca | ||
|
|
59e60cf3c0 | ||
|
|
2404c6fe2b |
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
@ -2,7 +2,6 @@ name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- 'web/**'
|
||||
|
||||
1
.github/workflows/pybind11.yml
vendored
1
.github/workflows/pybind11.yml
vendored
@ -2,7 +2,6 @@ name: PKBIND Build and Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths-ignore:
|
||||
- "docs/**"
|
||||
- "web/**"
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
#include "http/HttpMessage.h"
|
||||
#include "base/hplatform.h"
|
||||
|
||||
#include "pocketpy/common/name.h"
|
||||
|
||||
extern "C" void pk__add_module_libhv();
|
||||
|
||||
void libhv_HttpRequest_create(py_OutRef out, HttpRequestPtr ptr);
|
||||
|
||||
@ -53,6 +53,11 @@ if(PK_ENABLE_WATCHDOG)
|
||||
add_definitions(-DPK_ENABLE_WATCHDOG=1)
|
||||
endif()
|
||||
|
||||
if(PK_ENABLE_CUSTOM_SNAME)
|
||||
add_definitions(-DPK_ENABLE_CUSTOM_SNAME=1)
|
||||
endif()
|
||||
|
||||
|
||||
if(PK_BUILD_MODULE_LZ4)
|
||||
add_subdirectory(3rd/lz4)
|
||||
add_definitions(-DPK_BUILD_MODULE_LZ4)
|
||||
|
||||
@ -9,6 +9,7 @@ endif()
|
||||
option(PK_ENABLE_OS "" OFF)
|
||||
option(PK_ENABLE_DETERMINISM "" OFF)
|
||||
option(PK_ENABLE_WATCHDOG "" OFF)
|
||||
option(PK_ENABLE_CUSTOM_SNAME "" OFF)
|
||||
|
||||
# modules
|
||||
option(PK_BUILD_MODULE_LZ4 "" OFF)
|
||||
|
||||
@ -7,4 +7,9 @@ void pk_names_finalize();
|
||||
|
||||
#define MAGIC_METHOD(x) extern py_Name x;
|
||||
#include "pocketpy/xmacros/magics.h"
|
||||
#undef MAGIC_METHOD
|
||||
#undef MAGIC_METHOD
|
||||
|
||||
py_Name py_namev(c11_sv name);
|
||||
c11_sv py_name2sv(py_Name index);
|
||||
py_Name py_name(const char* name);
|
||||
const char* py_name2str(py_Name index);
|
||||
@ -20,6 +20,10 @@
|
||||
#define PK_ENABLE_WATCHDOG 0
|
||||
#endif
|
||||
|
||||
#ifndef PK_ENABLE_CUSTOM_SNAME // can be overridden by cmake
|
||||
#define PK_ENABLE_CUSTOM_SNAME 0
|
||||
#endif
|
||||
|
||||
// GC min threshold
|
||||
#ifndef PK_GC_MIN_THRESHOLD // can be overridden by cmake
|
||||
#define PK_GC_MIN_THRESHOLD 32768
|
||||
@ -62,9 +66,9 @@
|
||||
|
||||
// Hash table load factor (smaller ones mean less collision but more memory)
|
||||
// For class instance
|
||||
#define PK_INST_ATTR_LOAD_FACTOR 0.67
|
||||
#define PK_INST_ATTR_LOAD_FACTOR 0.67f
|
||||
// For class itself
|
||||
#define PK_TYPE_ATTR_LOAD_FACTOR 0.5
|
||||
#define PK_TYPE_ATTR_LOAD_FACTOR 0.5f
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PK_PLATFORM_SEP '\\'
|
||||
|
||||
@ -30,8 +30,8 @@ public:
|
||||
auto& info = type_info::of<T>();
|
||||
info.name = name;
|
||||
|
||||
py_newfunction(
|
||||
py_tpgetmagic(this->index(), __new__),
|
||||
py_bind(
|
||||
py_tpobject(this->index()),
|
||||
"__new__(type, *args, **kwargs)",
|
||||
[](int, py_Ref stack) {
|
||||
auto cls = py_offset(stack, 0);
|
||||
@ -44,9 +44,7 @@ public:
|
||||
py_newobject(py_retval(), steal<type>(cls).index(), slot, sizeof(instance));
|
||||
new (data) instance{instance::Flag::Own, operator new (info->size), info};
|
||||
return true;
|
||||
},
|
||||
nullptr,
|
||||
0);
|
||||
});
|
||||
}
|
||||
|
||||
/// bind constructor
|
||||
|
||||
@ -101,25 +101,25 @@ inline object::operator bool () const { return raise_call<py_bool>(m_ptr); }
|
||||
return object::from_ret(); \
|
||||
}
|
||||
|
||||
PKBIND_BINARY_OPERATOR(==, __eq__, __eq__)
|
||||
PKBIND_BINARY_OPERATOR(!=, __ne__, __ne__)
|
||||
PKBIND_BINARY_OPERATOR(<, __lt__, __gt__)
|
||||
PKBIND_BINARY_OPERATOR(<=, __le__, __ge__)
|
||||
PKBIND_BINARY_OPERATOR(>, __gt__, __lt__)
|
||||
PKBIND_BINARY_OPERATOR(>=, __ge__, __le__)
|
||||
PKBIND_BINARY_OPERATOR(==, py_name("__eq__"), py_name("__eq__"))
|
||||
PKBIND_BINARY_OPERATOR(!=, py_name("__ne__"), py_name("__ne__"))
|
||||
PKBIND_BINARY_OPERATOR(<, py_name("__lt__"), py_name("__gt__"))
|
||||
PKBIND_BINARY_OPERATOR(<=, py_name("__le__"), py_name("__ge__"))
|
||||
PKBIND_BINARY_OPERATOR(>, py_name("__gt__"), py_name("__lt__"))
|
||||
PKBIND_BINARY_OPERATOR(>=, py_name("__ge__"), py_name("__le__"))
|
||||
|
||||
PKBIND_BINARY_OPERATOR(+, __add__, __radd__)
|
||||
PKBIND_BINARY_OPERATOR(-, __sub__, __rsub__)
|
||||
PKBIND_BINARY_OPERATOR(*, __mul__, __rmul__)
|
||||
PKBIND_BINARY_OPERATOR(/, __truediv__, __rtruediv__)
|
||||
PKBIND_BINARY_OPERATOR(%, __mod__, __rmod__)
|
||||
PKBIND_BINARY_OPERATOR(+, py_name("__add__"), py_name("__radd__"))
|
||||
PKBIND_BINARY_OPERATOR(-, py_name("__sub__"), py_name("__rsub__"))
|
||||
PKBIND_BINARY_OPERATOR(*, py_name("__mul__"), py_name("__rmul__"))
|
||||
PKBIND_BINARY_OPERATOR(/, py_name("__truediv__"), py_name("__rtruediv__"))
|
||||
PKBIND_BINARY_OPERATOR(%, py_name("__mod__"), py_name("__rmod__"))
|
||||
|
||||
// FIXME: support __rand__ ...
|
||||
PKBIND_BINARY_OPERATOR(&, __and__, 0)
|
||||
PKBIND_BINARY_OPERATOR(|, __or__, 0)
|
||||
PKBIND_BINARY_OPERATOR(^, __xor__, 0)
|
||||
PKBIND_BINARY_OPERATOR(<<, __lshift__, 0)
|
||||
PKBIND_BINARY_OPERATOR(>>, __rshift__, 0)
|
||||
PKBIND_BINARY_OPERATOR(&, py_name("__and__"), nullptr)
|
||||
PKBIND_BINARY_OPERATOR(|, py_name("__or__"), nullptr)
|
||||
PKBIND_BINARY_OPERATOR(^, py_name("__xor__"), nullptr)
|
||||
PKBIND_BINARY_OPERATOR(<<, py_name("__lshift__"), nullptr)
|
||||
PKBIND_BINARY_OPERATOR(>>, py_name("__rshift__"), nullptr)
|
||||
|
||||
#undef PKBIND_BINARY_OPERATOR
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#if PK_ENABLE_CUSTOM_SNAME == 0
|
||||
|
||||
#include "pocketpy/common/name.h"
|
||||
#include "pocketpy/common/str.h"
|
||||
#include "pocketpy/pocketpy.h"
|
||||
@ -14,7 +16,7 @@ typedef struct NameBucket {
|
||||
|
||||
static struct {
|
||||
NameBucket* table[0x10000];
|
||||
atomic_bool lock;
|
||||
atomic_flag lock;
|
||||
} pk_string_table;
|
||||
|
||||
#define MAGIC_METHOD(x) py_Name x;
|
||||
@ -40,24 +42,25 @@ void pk_names_finalize() {
|
||||
}
|
||||
|
||||
py_Name py_namev(c11_sv name) {
|
||||
while(atomic_exchange(&pk_string_table.lock, true)) {
|
||||
while(atomic_flag_test_and_set(&pk_string_table.lock)) {
|
||||
// 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];
|
||||
NameBucket* prev = NULL;
|
||||
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;
|
||||
}
|
||||
prev = p;
|
||||
p = p->next;
|
||||
}
|
||||
if(found) {
|
||||
atomic_store(&pk_string_table.lock, false);
|
||||
atomic_flag_clear(&pk_string_table.lock);
|
||||
return (py_Name)p;
|
||||
}
|
||||
|
||||
@ -68,13 +71,13 @@ py_Name py_namev(c11_sv name) {
|
||||
bucket->size = name.size;
|
||||
memcpy(bucket->data, name.data, name.size);
|
||||
bucket->data[name.size] = '\0';
|
||||
if(p == NULL) {
|
||||
if(prev == NULL) {
|
||||
pk_string_table.table[index] = bucket;
|
||||
} else {
|
||||
assert(p->next == NULL);
|
||||
p->next = bucket;
|
||||
assert(prev->next == NULL);
|
||||
prev->next = bucket;
|
||||
}
|
||||
atomic_store(&pk_string_table.lock, false);
|
||||
atomic_flag_clear(&pk_string_table.lock);
|
||||
return (py_Name)bucket;
|
||||
}
|
||||
|
||||
@ -93,4 +96,6 @@ py_Name py_name(const char* name) {
|
||||
const char* py_name2str(py_Name index) {
|
||||
NameBucket* p = (NameBucket*)index;
|
||||
return p->data;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -92,6 +92,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
py_exception(tp_RecursionError, "maximum recursion depth exceeded");
|
||||
goto __ERROR;
|
||||
}
|
||||
// NOTE: remember to change another occurrence after __ERROR_RE_RAISE:
|
||||
co_codes = frame->co->codes.data;
|
||||
co_names = frame->co->names.data;
|
||||
frame->ip++;
|
||||
@ -901,7 +902,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
case OP_POP_IMPORT_STAR: {
|
||||
// [module]
|
||||
NameDict* dict = PyObject__dict(TOP()->_obj);
|
||||
py_Ref all = NameDict__try_get(dict, __all__);
|
||||
py_ItemRef all = NameDict__try_get(dict, __all__);
|
||||
if(all) {
|
||||
py_TValue* p;
|
||||
int length = pk_arrayview(all, &p);
|
||||
@ -911,7 +912,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
for(int i = 0; i < length; i++) {
|
||||
py_Name name = py_namev(py_tosv(p + i));
|
||||
py_Ref value = NameDict__try_get(dict, name);
|
||||
py_ItemRef value = NameDict__try_get(dict, name);
|
||||
if(value == NULL) {
|
||||
ImportError("cannot import name '%n'", name);
|
||||
goto __ERROR;
|
||||
@ -920,7 +921,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < dict->length; i++) {
|
||||
for(int i = 0; i < dict->capacity; i++) {
|
||||
NameDict_KV* kv = &dict->items[i];
|
||||
if(kv->key == NULL) continue;
|
||||
c11_sv name = py_name2sv(kv->key);
|
||||
@ -1239,6 +1240,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
}
|
||||
frame = self->top_frame;
|
||||
co_codes = frame->co->codes.data;
|
||||
co_names = frame->co->names.data;
|
||||
goto __ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@ -678,9 +678,9 @@ void ManagedHeap__mark(ManagedHeap* self) {
|
||||
for(int i = 0; i < obj->slots; i++)
|
||||
pk__mark_value(p + i);
|
||||
} else if(obj->slots == -1) {
|
||||
NameDict* namedict = PyObject__dict(obj);
|
||||
for(int i = 0; i < namedict->length; i++) {
|
||||
NameDict_KV* kv = &namedict->items[i];
|
||||
NameDict* dict = PyObject__dict(obj);
|
||||
for(int i = 0; i < dict->capacity; i++) {
|
||||
NameDict_KV* kv = &dict->items[i];
|
||||
if(kv->key == NULL) continue;
|
||||
pk__mark_value(&kv->value);
|
||||
}
|
||||
|
||||
@ -84,7 +84,8 @@ static bool disassemble(CodeObject* co) {
|
||||
case OP_BEGIN_CLASS:
|
||||
case OP_DELETE_GLOBAL:
|
||||
case OP_STORE_CLASS_ATTR: {
|
||||
pk_sprintf(&ss, " (%n)", byte.arg);
|
||||
py_Name name = c11__getitem(py_Name, &co->names, byte.arg);
|
||||
pk_sprintf(&ss, " (%n)", name);
|
||||
break;
|
||||
}
|
||||
case OP_LOAD_FAST:
|
||||
|
||||
@ -374,7 +374,7 @@ static bool pkl__write_object(PickleObject* buf, py_TValue* obj) {
|
||||
}
|
||||
if(ti->is_python) {
|
||||
NameDict* dict = PyObject__dict(obj->_obj);
|
||||
for(int i = dict->length - 1; i >= 0; i--) {
|
||||
for(int i = dict->capacity - 1; i >= 0; i--) {
|
||||
NameDict_KV* kv = &dict->items[i];
|
||||
if(kv->key == NULL) continue;
|
||||
if(!pkl__write_object(buf, &kv->value)) return false;
|
||||
@ -383,7 +383,7 @@ static bool pkl__write_object(PickleObject* buf, py_TValue* obj) {
|
||||
pkl__emit_int(buf, obj->type);
|
||||
buf->used_types[obj->type] = true;
|
||||
pkl__emit_int(buf, dict->length);
|
||||
for(int i = 0; i < dict->length; i++) {
|
||||
for(int i = 0; i < dict->capacity; i++) {
|
||||
NameDict_KV* kv = &dict->items[i];
|
||||
if(kv->key == NULL) continue;
|
||||
c11_sv field = py_name2sv(kv->key);
|
||||
|
||||
@ -217,7 +217,8 @@ 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(), atomic_load(&self->is_done));
|
||||
bool value = atomic_load(&self->is_done);
|
||||
py_newbool(py_retval(), value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -764,9 +764,9 @@ void function__gc_mark(void* ud, c11_vector* p_stack) {
|
||||
Function* func = ud;
|
||||
if(func->globals) pk__mark_value(func->globals);
|
||||
if(func->closure) {
|
||||
NameDict* namedict = func->closure;
|
||||
for(int i = 0; i < namedict->length; i++) {
|
||||
NameDict_KV* kv = &namedict->items[i];
|
||||
NameDict* dict = func->closure;
|
||||
for(int i = 0; i < dict->capacity; i++) {
|
||||
NameDict_KV* kv = &dict->items[i];
|
||||
if(kv->key == NULL) continue;
|
||||
pk__mark_value(&kv->value);
|
||||
}
|
||||
|
||||
@ -225,6 +225,13 @@ char* py_formatexc() {
|
||||
}
|
||||
|
||||
bool py_exception(py_Type type, const char* fmt, ...) {
|
||||
#ifndef NDEBUG
|
||||
if(py_checkexc(true)) {
|
||||
const char* name = py_tpname(pk_current_vm->curr_exception.type);
|
||||
c11__abort("py_exception(): `%s` was already set!", name);
|
||||
}
|
||||
#endif
|
||||
|
||||
c11_sbuf buf;
|
||||
c11_sbuf__ctor(&buf);
|
||||
va_list args;
|
||||
|
||||
@ -52,11 +52,11 @@ static bool namedict_items(int argc, py_Ref argv) {
|
||||
py_Ref object = py_getslot(argv, 0);
|
||||
NameDict* dict = PyObject__dict(object->_obj);
|
||||
py_newlist(py_retval());
|
||||
for(int i = 0; i < dict->length; i++) {
|
||||
py_Ref slot = py_list_emplace(py_retval());
|
||||
py_Ref p = py_newtuple(slot, 2);
|
||||
for(int i = 0; i < dict->capacity; i++) {
|
||||
NameDict_KV* kv = &dict->items[i];
|
||||
if(kv->key == NULL) continue;
|
||||
py_Ref slot = py_list_emplace(py_retval());
|
||||
py_Ref p = py_newtuple(slot, 2);
|
||||
p[0] = *py_name2ref(kv->key);
|
||||
p[1] = kv->value;
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ py_ItemRef py_emplacedict(py_Ref self, py_Name name) {
|
||||
bool py_applydict(py_Ref self, bool (*f)(py_Name, py_Ref, void*), void* ctx) {
|
||||
assert(self && self->is_ptr);
|
||||
NameDict* dict = PyObject__dict(self->_obj);
|
||||
for(int i = 0; i < dict->length; i++) {
|
||||
for(int i = 0; i < dict->capacity; i++) {
|
||||
NameDict_KV* kv = &dict->items[i];
|
||||
if(kv->key == NULL) continue;
|
||||
bool ok = f(kv->key, &kv->value, ctx);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user