mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
some fix
This commit is contained in:
parent
a59a68b6f5
commit
ab0f07bbd7
@ -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);
|
||||
|
@ -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
|
||||
|
@ -7,40 +7,29 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct PyObject{
|
||||
typedef struct PyObject {
|
||||
py_Type type; // we have a duplicated type here for convenience
|
||||
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
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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: {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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){
|
||||
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){
|
||||
py_TValue* PyObject__slots(PyObject* self) {
|
||||
assert(self->slots >= 0);
|
||||
return (py_TValue*)((char*)self + 8);
|
||||
return (py_TValue*)(self->flex);
|
||||
}
|
@ -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; }
|
||||
|
@ -4,19 +4,23 @@
|
||||
#include "pocketpy/objects/object.h"
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
|
||||
py_Ref py_getmodule(const char *name){
|
||||
py_Ref py_getmodule(const char* name) {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
return pk_NameDict__try_get(&vm->modules, py_name(name));
|
||||
}
|
||||
|
||||
py_Ref py_newmodule(const char *name, const char *package){
|
||||
py_Ref py_newmodule(const char* name, const char* package) {
|
||||
pk_ManagedHeap* heap = &pk_current_vm->heap;
|
||||
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_module, -1, 0);
|
||||
|
||||
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);
|
||||
@ -27,7 +31,7 @@ py_Ref py_newmodule(const char *name, const char *package){
|
||||
py_setdict(r0, __package__, r1);
|
||||
|
||||
// convert to fullname
|
||||
if(package[0] != '\0'){
|
||||
if(package[0] != '\0') {
|
||||
// package.name
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf), "%s.%s", package, name);
|
||||
|
@ -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
68
src/public/py_str.c
Normal 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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user