This commit is contained in:
blueloveTH 2024-07-02 11:47:56 +08:00
parent a59a68b6f5
commit ab0f07bbd7
15 changed files with 118 additions and 89 deletions

View File

@ -22,6 +22,12 @@ typedef struct c11_string{
const char data[]; // flexible array member
} c11_string;
/* bytes */
typedef struct c11_bytes{
int size;
unsigned char data[]; // flexible array member
} c11_bytes;
int c11_sv__cmp(c11_sv self, c11_sv other);
int c11_sv__cmp2(c11_sv self, const char* other, int size);
int c11_sv__cmp3(c11_sv self, const char* other);

View File

@ -89,6 +89,8 @@ py_Type pk_VM__new_type(pk_VM* self,
bool subclass_enabled);
// type registration
py_Type pk_str__register();
py_Type pk_bytes__register();
py_Type pk_list__register();
#ifdef __cplusplus

View File

@ -12,35 +12,24 @@ typedef struct PyObject{
bool gc_is_large;
bool gc_marked;
int slots; // number of slots in the object
char flex[];
} PyObject;
// slots >= 0, allocate N slots
// slots == -1, allocate a dict
// | 8 bytes HEADER | <N slots> | <value>
// | 8 bytes HEADER | <dict> | <value>
static_assert(sizeof(PyObject) <= 8, "!(sizeof(PyObject) <= 8)");
// | HEADER | <N slots> | <userdata>
// | HEADER | <dict> | <userdata>
py_TValue* PyObject__slots(PyObject* self);
pk_NameDict* PyObject__dict(PyObject* self);
void* PyObject__value(PyObject* self);
void* PyObject__userdata(PyObject* self);
#define PK_OBJ_HEADER_SIZE(slots) ((slots)>=0 ? 8+sizeof(py_TValue)*(slots) : 8+sizeof(pk_NameDict))
#define PK_OBJ_SLOTS_SIZE(slots) ((slots) >= 0 ? sizeof(py_TValue) * (slots) : sizeof(pk_NameDict))
PyObject* PyObject__new(py_Type type, int slots, int size);
void PyObject__delete(PyObject* self);
PK_INLINE py_TValue PyVar__fromobj(PyObject* obj){
if(!obj) return PY_NULL;
py_TValue retval = {
.type = obj->type,
.is_ptr = true,
._obj = obj
};
return retval;
}
#ifdef __cplusplus
}
#endif

View File

@ -55,7 +55,7 @@ void py_newbool(py_Ref, bool);
void py_newstr(py_Ref, const char*);
void py_newstrn(py_Ref, const char*, int);
// void py_newfstr(py_Ref, const char*, ...);
void py_newbytes(py_Ref, const unsigned char*, int);
unsigned char* py_newbytes(py_Ref, int);
void py_newnone(py_Ref);
void py_newnotimplemented(py_Ref out);
void py_newellipsis(py_Ref out);
@ -104,7 +104,7 @@ bool py_tobool(const py_Ref);
py_Type py_totype(const py_Ref);
const char* py_tostr(const py_Ref);
const char* py_tostrn(const py_Ref, int* size);
const unsigned char* py_tobytes(const py_Ref, int* size);
unsigned char* py_tobytes(const py_Ref, int* size);
void* py_touserdata(const py_Ref);

View File

@ -8,6 +8,7 @@
#include <ctype.h>
#include <stdio.h>
c11_string* c11_string__new(const char* data) { return c11_string__new2(data, strlen(data)); }
c11_string* c11_string__new2(const char* data, int size) {

View File

@ -1354,7 +1354,7 @@ int Ctx__add_const_string(Ctx* self, c11_sv key) {
c11_vector__push(py_TValue, &self->co->consts, tmp);
int index = self->co->consts.count - 1;
c11_smallmap_s2n__set(&self->co_consts_string_dedup_map,
c11_string__sv(PyObject__value(tmp._obj)),
c11_string__sv(PyObject__userdata(tmp._obj)),
index);
return index;
}

View File

@ -426,9 +426,8 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
case OP_BUILD_BYTES: {
int size;
const char* data = py_tostrn(TOP(), &size);
unsigned char* p = (unsigned char*)malloc(size);
unsigned char* p = py_newbytes(TOP(), size);
memcpy(p, data, size);
py_newbytes(TOP(), p, size);
DISPATCH();
}
case OP_BUILD_TUPLE: {

View File

@ -1,5 +1,6 @@
#include "pocketpy/interpreter/gc.h"
#include "pocketpy/common/memorypool.h"
#include "pocketpy/objects/base.h"
void pk_ManagedHeap__ctor(pk_ManagedHeap *self, pk_VM *vm){
c11_vector__ctor(&self->no_gc, sizeof(PyObject*));
@ -104,7 +105,8 @@ PyObject* pk_ManagedHeap__gcnew(pk_ManagedHeap *self, py_Type type, int slots, i
PyObject* PyObject__new(py_Type type, int slots, int size){
assert(slots >= 0 || slots == -1);
PyObject* self;
size += PK_OBJ_HEADER_SIZE(slots);
// header + slots + udsize
size = sizeof(PyObject) + PK_OBJ_SLOTS_SIZE(slots) + size;
if(size <= kPoolObjectBlockSize){
self = PoolObject_alloc();
self->gc_is_large = false;

View File

@ -38,7 +38,11 @@ void pk_TypeInfo__ctor(pk_TypeInfo* self,
// create type object with __dict__
pk_ManagedHeap* heap = &pk_current_vm->heap;
PyObject* typeobj = pk_ManagedHeap__new(heap, tp_type, -1, sizeof(py_Type));
self->self = PyVar__fromobj(typeobj);
self->self = (py_TValue){
.type = typeobj->type,
.is_ptr = true,
._obj = typeobj,
};
self->module = module ? *module : PY_NULL;
self->subclass_enabled = subclass_enabled;
@ -84,7 +88,7 @@ void pk_VM__ctor(pk_VM* self) {
validate(tp_int, pk_VM__new_type(self, "int", tp_object, NULL, false));
validate(tp_float, pk_VM__new_type(self, "float", tp_object, NULL, false));
validate(tp_bool, pk_VM__new_type(self, "bool", tp_object, NULL, false));
validate(tp_str, pk_VM__new_type(self, "str", tp_object, NULL, false));
validate(tp_str, pk_str__register());
validate(tp_list, pk_list__register());
validate(tp_tuple, pk_VM__new_type(self, "tuple", tp_object, NULL, false));
@ -99,7 +103,7 @@ void pk_VM__ctor(pk_VM* self) {
validate(tp_super, pk_VM__new_type(self, "super", tp_object, NULL, false));
validate(tp_exception, pk_VM__new_type(self, "Exception", tp_object, NULL, true));
validate(tp_bytes, pk_VM__new_type(self, "bytes", tp_object, NULL, false));
validate(tp_bytes, pk_bytes__register());
validate(tp_mappingproxy, pk_VM__new_type(self, "mappingproxy", tp_object, NULL, false));
validate(tp_dict, pk_VM__new_type(self, "dict", tp_object, NULL, true));
@ -191,7 +195,7 @@ py_Type pk_VM__new_type(pk_VM* self,
/****************************************/
void PyObject__delete(PyObject* self) {
pk_TypeInfo* ti = c11__at(pk_TypeInfo, &pk_current_vm->types, self->type);
if(ti->dtor) ti->dtor(PyObject__value(self));
if(ti->dtor) ti->dtor(PyObject__userdata(self));
if(self->slots == -1) pk_NameDict__dtor(PyObject__dict(self));
if(self->gc_is_large) {
free(self);

View File

@ -2,16 +2,14 @@
#include "pocketpy/pocketpy.h"
#include <assert.h>
void* PyObject__value(PyObject* self){
return (char*)self + PK_OBJ_HEADER_SIZE(self->slots);
}
void* PyObject__userdata(PyObject* self) { return self->flex + PK_OBJ_SLOTS_SIZE(self->slots); }
pk_NameDict* PyObject__dict(PyObject* self) {
assert(self->slots == -1);
return (pk_NameDict*)((char*)self + 8);
return (pk_NameDict*)(self->flex);
}
py_TValue* PyObject__slots(PyObject* self) {
assert(self->slots >= 0);
return (py_TValue*)((char*)self + 8);
return (py_TValue*)(self->flex);
}

View File

@ -1,3 +1,4 @@
#include "pocketpy/common/str.h"
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/utils.h"
@ -33,29 +34,9 @@ py_Type py_totype(const py_Ref self) {
return *ud;
}
const char* py_tostr(const py_Ref self) {
assert(self->type == tp_str);
c11_string* ud = PyObject__value(self->_obj);
return ud->data;
}
const char* py_tostrn(const py_Ref self, int* size) {
assert(self->type == tp_str);
c11_string* ud = PyObject__value(self->_obj);
*size = ud->size;
return ud->data;
}
const unsigned char* py_tobytes(const py_Ref self, int* size) {
assert(self->type == tp_bytes);
int* ud = PyObject__value(self->_obj);
*size = *ud;
return (unsigned char*)(ud + 1);
}
void* py_touserdata(const py_Ref self) {
assert(self && self->is_ptr);
return PyObject__value(self->_obj);
return PyObject__userdata(self->_obj);
}
bool py_istype(const py_Ref self, py_Type type) { return self->type == type; }

View File

@ -16,7 +16,11 @@ py_Ref py_newmodule(const char *name, const char *package){
py_Ref r0 = py_pushtmp();
py_Ref r1 = py_pushtmp();
*r0 = PyVar__fromobj(obj);
*r0 = (py_TValue){
.type = obj->type,
.is_ptr = true,
._obj = obj,
};
py_newstr(r1, name);
py_setdict(r0, __name__, r1);

View File

@ -17,7 +17,7 @@ py_Type pk_list__register() {
void py_newlist(py_Ref out) {
pk_VM* vm = pk_current_vm;
PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_list, 0, sizeof(List));
List* userdata = PyObject__value(obj);
List* userdata = PyObject__userdata(obj);
c11_vector__ctor(userdata, sizeof(py_TValue));
out->type = tp_list;
out->is_ptr = true;

68
src/public/py_str.c Normal file
View File

@ -0,0 +1,68 @@
#include "pocketpy/common/str.h"
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/utils.h"
#include "pocketpy/objects/object.h"
#include "pocketpy/interpreter/vm.h"
py_Type pk_str__register() {
pk_VM* vm = pk_current_vm;
py_Type type = pk_VM__new_type(vm, "str", tp_object, NULL, false);
// no need to dtor because the memory is controlled by the object
return type;
}
py_Type pk_bytes__register() {
pk_VM* vm = pk_current_vm;
py_Type type = pk_VM__new_type(vm, "bytes", tp_object, NULL, false);
// no need to dtor because the memory is controlled by the object
return type;
}
void py_newstr(py_Ref out, const char* data) {
return py_newstrn(out, data, strlen(data));
}
void py_newstrn(py_Ref out, const char* data, int size) {
pk_ManagedHeap* heap = &pk_current_vm->heap;
int total_size = sizeof(c11_string) + size + 1;
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_str, 0, total_size);
c11_string* ud = PyObject__userdata(obj);
c11_string__ctor2(ud, data, size);
out->type = tp_str;
out->is_ptr = true;
out->_obj = obj;
}
unsigned char* py_newbytes(py_Ref out, int size) {
pk_ManagedHeap* heap = &pk_current_vm->heap;
// 4 bytes size + data
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_bytes, 0, sizeof(c11_bytes) + size);
c11_bytes* ud = PyObject__userdata(obj);
ud->size = size;
out->type = tp_bytes;
out->is_ptr = true;
out->_obj = obj;
return ud->data;
}
const char* py_tostr(const py_Ref self) {
assert(self->type == tp_str);
c11_string* ud = PyObject__userdata(self->_obj);
return ud->data;
}
const char* py_tostrn(const py_Ref self, int* size) {
assert(self->type == tp_str);
c11_string* ud = PyObject__userdata(self->_obj);
*size = ud->size;
return ud->data;
}
unsigned char* py_tobytes(const py_Ref self, int* size) {
assert(self->type == tp_bytes);
c11_bytes* ud = PyObject__userdata(self->_obj);
*size = ud->size;
return ud->data;
}

View File

@ -1,3 +1,5 @@
#include "pocketpy/common/str.h"
#include "pocketpy/common/vector.h"
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/utils.h"
@ -37,35 +39,8 @@ void py_newellipsis(py_Ref out) {
out->is_ptr = false;
}
void py_newnull(py_Ref out) { out->type = 0; }
void py_newstr(py_Ref out, const char* data) {
return py_newstrn(out, data, strlen(data));
}
void py_newstrn(py_Ref out, const char* data, int size) {
pk_ManagedHeap* heap = &pk_current_vm->heap;
int total_size = sizeof(c11_string) + size + 1;
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_str, 0, total_size);
c11_string* ud = PyObject__value(obj);
c11_string__ctor2(ud, data, size);
out->type = tp_str;
out->is_ptr = true;
out->_obj = obj;
}
void py_newbytes(py_Ref out, const unsigned char* data, int size) {
pk_ManagedHeap* heap = &pk_current_vm->heap;
// 4 bytes size + data
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_bytes, 0, sizeof(int) + size);
int* psize = (int*)PyObject__value(obj);
*psize = size;
memcpy(psize + 1, data, size);
out->type = tp_bytes;
out->is_ptr = true;
out->_obj = obj;
}
void py_newfunction(py_Ref out, py_CFunction f, const char* sig) {
py_newfunction2(out, f, sig, BindType_FUNCTION, NULL, NULL);