mirror of
https://github.com/pocketpy/pocketpy
synced 2025-11-07 04:00:17 +00:00
Compare commits
6 Commits
2ef24dd1d9
...
93ca8d88f3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93ca8d88f3 | ||
|
|
4cf9199c72 | ||
|
|
c329e09fac | ||
|
|
6b0c96bb7c | ||
|
|
6d2547723f | ||
|
|
fb8e963905 |
@ -5,4 +5,16 @@ label: gc
|
|||||||
|
|
||||||
### `gc.collect()`
|
### `gc.collect()`
|
||||||
|
|
||||||
Invoke the garbage collector.
|
Invoke the garbage collector.
|
||||||
|
|
||||||
|
### `gc.enable()`
|
||||||
|
|
||||||
|
Enable automatic garbage collection.
|
||||||
|
|
||||||
|
### `gc.disable()`
|
||||||
|
|
||||||
|
Disable automatic garbage collection.
|
||||||
|
|
||||||
|
### `gc.isenabled()`
|
||||||
|
|
||||||
|
Return `True` if automatic garbage collection is enabled, `False` otherwise.
|
||||||
@ -45,6 +45,6 @@ typedef struct RefCounted {
|
|||||||
do { \
|
do { \
|
||||||
if(--(obj)->rc.count == 0) { \
|
if(--(obj)->rc.count == 0) { \
|
||||||
(obj)->rc.dtor(obj); \
|
(obj)->rc.dtor(obj); \
|
||||||
free(obj); \
|
PK_FREE(obj); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|||||||
@ -8,6 +8,11 @@
|
|||||||
|
|
||||||
/*************** feature settings ***************/
|
/*************** feature settings ***************/
|
||||||
|
|
||||||
|
// Reduce the startup memory usage for embedded systems
|
||||||
|
#ifndef PK_LOW_MEMORY_MODE // can be overridden by cmake
|
||||||
|
#define PK_LOW_MEMORY_MODE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
// Whether to compile os-related modules or not
|
// Whether to compile os-related modules or not
|
||||||
#ifndef PK_ENABLE_OS // can be overridden by cmake
|
#ifndef PK_ENABLE_OS // can be overridden by cmake
|
||||||
#define PK_ENABLE_OS 1
|
#define PK_ENABLE_OS 1
|
||||||
@ -15,27 +20,37 @@
|
|||||||
|
|
||||||
// GC min threshold
|
// GC min threshold
|
||||||
#ifndef PK_GC_MIN_THRESHOLD // can be overridden by cmake
|
#ifndef PK_GC_MIN_THRESHOLD // can be overridden by cmake
|
||||||
#define PK_GC_MIN_THRESHOLD 16384
|
#if PK_LOW_MEMORY_MODE
|
||||||
|
#define PK_GC_MIN_THRESHOLD 2048
|
||||||
|
#else
|
||||||
|
#define PK_GC_MIN_THRESHOLD 16384
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*************** debug settings ***************/
|
// Memory allocation functions
|
||||||
// Do not edit the following settings unless you know what you are doing
|
#ifndef PK_MALLOC
|
||||||
#define PK_DEBUG_CEVAL_STEP 0
|
#define PK_MALLOC(size) malloc(size)
|
||||||
#define PK_DEBUG_MEMORY_POOL 0
|
#define PK_REALLOC(ptr, size) realloc(ptr, size)
|
||||||
#define PK_DEBUG_NO_AUTO_GC 0
|
#define PK_FREE(ptr) free(ptr)
|
||||||
#define PK_DEBUG_GC_STATS 0
|
#endif
|
||||||
#define PK_DEBUG_COMPILER 0
|
|
||||||
|
|
||||||
/*************** internal settings ***************/
|
|
||||||
|
|
||||||
// This is the maximum size of the value stack in py_TValue units
|
// This is the maximum size of the value stack in py_TValue units
|
||||||
// The actual size in bytes equals `sizeof(py_TValue) * PK_VM_STACK_SIZE`
|
// The actual size in bytes equals `sizeof(py_TValue) * PK_VM_STACK_SIZE`
|
||||||
#define PK_VM_STACK_SIZE 16384
|
#ifndef PK_VM_STACK_SIZE // can be overridden by cmake
|
||||||
|
#if PK_LOW_MEMORY_MODE
|
||||||
|
#define PK_VM_STACK_SIZE 2048
|
||||||
|
#else
|
||||||
|
#define PK_VM_STACK_SIZE 16384
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// This is the maximum number of local variables in a function
|
// This is the maximum number of local variables in a function
|
||||||
// (not recommended to change this)
|
// (not recommended to change this)
|
||||||
|
#ifndef PK_MAX_CO_VARNAMES // can be overridden by cmake
|
||||||
#define PK_MAX_CO_VARNAMES 64
|
#define PK_MAX_CO_VARNAMES 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*************** internal settings ***************/
|
||||||
// This is the maximum character length of a module path
|
// This is the maximum character length of a module path
|
||||||
#define PK_MAX_MODULE_PATH_LEN 63
|
#define PK_MAX_MODULE_PATH_LEN 63
|
||||||
|
|
||||||
@ -49,4 +64,4 @@
|
|||||||
#define PK_PLATFORM_SEP '\\'
|
#define PK_PLATFORM_SEP '\\'
|
||||||
#else
|
#else
|
||||||
#define PK_PLATFORM_SEP '/'
|
#define PK_PLATFORM_SEP '/'
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -11,11 +11,10 @@ py_TValue* FastLocals__try_get_by_name(py_TValue* locals, const CodeObject* co,
|
|||||||
NameDict* FastLocals__to_namedict(py_TValue* locals, const CodeObject* co);
|
NameDict* FastLocals__to_namedict(py_TValue* locals, const CodeObject* co);
|
||||||
|
|
||||||
typedef struct ValueStack {
|
typedef struct ValueStack {
|
||||||
// We allocate extra PK_VM_STACK_SIZE/128 places to keep `_sp` valid when `is_overflow() ==
|
|
||||||
// true`.
|
|
||||||
py_TValue* sp;
|
py_TValue* sp;
|
||||||
py_TValue* end;
|
py_TValue* end;
|
||||||
py_TValue begin[PK_VM_STACK_SIZE + PK_VM_STACK_SIZE / 128];
|
// We allocate extra places to keep `_sp` valid to detect stack overflow
|
||||||
|
py_TValue begin[PK_VM_STACK_SIZE + PK_MAX_CO_VARNAMES * 2];
|
||||||
} ValueStack;
|
} ValueStack;
|
||||||
|
|
||||||
void ValueStack__ctor(ValueStack* self);
|
void ValueStack__ctor(ValueStack* self);
|
||||||
|
|||||||
@ -6,6 +6,8 @@ typedef struct ManagedHeap{
|
|||||||
|
|
||||||
int gc_threshold;
|
int gc_threshold;
|
||||||
int gc_counter;
|
int gc_counter;
|
||||||
|
bool gc_enabled;
|
||||||
|
|
||||||
VM* vm;
|
VM* vm;
|
||||||
|
|
||||||
void (*gc_on_delete)(VM*, PyObject*);
|
void (*gc_on_delete)(VM*, PyObject*);
|
||||||
|
|||||||
@ -59,14 +59,14 @@ void METHOD(ctor)(NAME* self) {
|
|||||||
void METHOD(dtor)(NAME* self) { c11_vector__dtor(self); }
|
void METHOD(dtor)(NAME* self) { c11_vector__dtor(self); }
|
||||||
|
|
||||||
NAME* METHOD(new)() {
|
NAME* METHOD(new)() {
|
||||||
NAME* self = malloc(sizeof(NAME));
|
NAME* self = PK_MALLOC(sizeof(NAME));
|
||||||
METHOD(ctor)(self);
|
METHOD(ctor)(self);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
void METHOD(delete)(NAME* self) {
|
void METHOD(delete)(NAME* self) {
|
||||||
METHOD(dtor)(self);
|
METHOD(dtor)(self);
|
||||||
free(self);
|
PK_FREE(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void METHOD(set)(NAME* self, K key, V value) {
|
void METHOD(set)(NAME* self, K key, V value) {
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
#include "pocketpy/common/algorithm.h"
|
#include "pocketpy/common/algorithm.h"
|
||||||
|
#include "pocketpy/config.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
static bool merge(char* a,
|
static bool _stable_sort_merge(char* a,
|
||||||
char* a_end,
|
char* a_end,
|
||||||
char* b,
|
char* b,
|
||||||
char* b_end,
|
char* b_end,
|
||||||
@ -38,19 +39,19 @@ bool c11__stable_sort(void* ptr_,
|
|||||||
int (*f_lt)(const void* a, const void* b, void* extra),
|
int (*f_lt)(const void* a, const void* b, void* extra),
|
||||||
void* extra) {
|
void* extra) {
|
||||||
// merge sort
|
// merge sort
|
||||||
char *ptr = ptr_, *tmp = malloc(length * elem_size);
|
char *ptr = ptr_, *tmp = PK_MALLOC(length * elem_size);
|
||||||
for(int seg = 1; seg < length; seg *= 2) {
|
for(int seg = 1; seg < length; seg *= 2) {
|
||||||
for(char* a = ptr; a < ptr + (length - seg) * elem_size; a += 2 * seg * elem_size) {
|
for(char* a = ptr; a < ptr + (length - seg) * elem_size; a += 2 * seg * elem_size) {
|
||||||
char *b = a + seg * elem_size, *a_end = b, *b_end = b + seg * elem_size;
|
char *b = a + seg * elem_size, *a_end = b, *b_end = b + seg * elem_size;
|
||||||
if(b_end > ptr + length * elem_size) b_end = ptr + length * elem_size;
|
if(b_end > ptr + length * elem_size) b_end = ptr + length * elem_size;
|
||||||
bool ok = merge(a, a_end, b, b_end, tmp, elem_size, f_lt, extra);
|
bool ok = _stable_sort_merge(a, a_end, b, b_end, tmp, elem_size, f_lt, extra);
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
free(tmp);
|
PK_FREE(tmp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy(a, tmp, b_end - a);
|
memcpy(a, tmp, b_end - a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(tmp);
|
PK_FREE(tmp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,7 +136,7 @@ static void MemoryPool__ctor(MemoryPool* self) {
|
|||||||
static void* MemoryPool__alloc(MemoryPool* self) {
|
static void* MemoryPool__alloc(MemoryPool* self) {
|
||||||
MemoryPoolArena* arena;
|
MemoryPoolArena* arena;
|
||||||
if(self->_arenas.length == 0){
|
if(self->_arenas.length == 0){
|
||||||
arena = malloc(sizeof(MemoryPoolArena));
|
arena = PK_MALLOC(sizeof(MemoryPoolArena));
|
||||||
MemoryPoolArena__ctor(arena);
|
MemoryPoolArena__ctor(arena);
|
||||||
LinkedList__push_back(&self->_arenas, (LinkedListNode*)arena);
|
LinkedList__push_back(&self->_arenas, (LinkedListNode*)arena);
|
||||||
} else {
|
} else {
|
||||||
@ -169,14 +169,14 @@ static void MemoryPool__shrink_to_fit(MemoryPool* self) {
|
|||||||
MemoryPoolArena* arena = (MemoryPoolArena*)node;
|
MemoryPoolArena* arena = (MemoryPoolArena*)node;
|
||||||
if(MemoryPoolArena__full(arena)) {
|
if(MemoryPoolArena__full(arena)) {
|
||||||
LinkedList__erase(&self->_arenas, node);
|
LinkedList__erase(&self->_arenas, node);
|
||||||
free(arena);
|
PK_FREE(arena);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void MemoryPool__dtor(MemoryPool* self) {
|
static void MemoryPool__dtor(MemoryPool* self) {
|
||||||
LinkedList__apply(&self->_arenas, free(node););
|
LinkedList__apply(&self->_arenas, PK_FREE(node););
|
||||||
LinkedList__apply(&self->_empty_arenas, free(node););
|
LinkedList__apply(&self->_empty_arenas, PK_FREE(node););
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct FixedMemoryPool {
|
typedef struct FixedMemoryPool {
|
||||||
@ -195,9 +195,9 @@ static void FixedMemoryPool__ctor(FixedMemoryPool* self, int BlockSize, int Bloc
|
|||||||
self->BlockSize = BlockSize;
|
self->BlockSize = BlockSize;
|
||||||
self->BlockCount = BlockCount;
|
self->BlockCount = BlockCount;
|
||||||
self->exceeded_bytes = 0;
|
self->exceeded_bytes = 0;
|
||||||
self->data = malloc(BlockSize * BlockCount);
|
self->data = PK_MALLOC(BlockSize * BlockCount);
|
||||||
self->data_end = self->data + BlockSize * BlockCount;
|
self->data_end = self->data + BlockSize * BlockCount;
|
||||||
self->_free_list = malloc(sizeof(void*) * BlockCount);
|
self->_free_list = PK_MALLOC(sizeof(void*) * BlockCount);
|
||||||
self->_free_list_end = self->_free_list;
|
self->_free_list_end = self->_free_list;
|
||||||
for(int i = 0; i < BlockCount; i++) {
|
for(int i = 0; i < BlockCount; i++) {
|
||||||
self->_free_list[i] = self->data + i * BlockSize;
|
self->_free_list[i] = self->data + i * BlockSize;
|
||||||
@ -205,8 +205,8 @@ static void FixedMemoryPool__ctor(FixedMemoryPool* self, int BlockSize, int Bloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void FixedMemoryPool__dtor(FixedMemoryPool* self) {
|
static void FixedMemoryPool__dtor(FixedMemoryPool* self) {
|
||||||
free(self->_free_list);
|
PK_FREE(self->_free_list);
|
||||||
free(self->data);
|
PK_FREE(self->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* FixedMemoryPool__alloc(FixedMemoryPool* self) {
|
static void* FixedMemoryPool__alloc(FixedMemoryPool* self) {
|
||||||
@ -215,7 +215,7 @@ static void* FixedMemoryPool__alloc(FixedMemoryPool* self) {
|
|||||||
return *self->_free_list_end;
|
return *self->_free_list_end;
|
||||||
} else {
|
} else {
|
||||||
self->exceeded_bytes += self->BlockSize;
|
self->exceeded_bytes += self->BlockSize;
|
||||||
return malloc(self->BlockSize);
|
return PK_MALLOC(self->BlockSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ static void FixedMemoryPool__dealloc(FixedMemoryPool* self, void* p) {
|
|||||||
self->_free_list_end++;
|
self->_free_list_end++;
|
||||||
} else {
|
} else {
|
||||||
self->exceeded_bytes -= self->BlockSize;
|
self->exceeded_bytes -= self->BlockSize;
|
||||||
free(p);
|
PK_FREE(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@ SourceData_ SourceData__rcnew(const char* source,
|
|||||||
const char* filename,
|
const char* filename,
|
||||||
enum py_CompileMode mode,
|
enum py_CompileMode mode,
|
||||||
bool is_dynamic) {
|
bool is_dynamic) {
|
||||||
SourceData_ self = malloc(sizeof(struct SourceData));
|
SourceData_ self = PK_MALLOC(sizeof(struct SourceData));
|
||||||
SourceData__ctor(self, source, filename, mode, is_dynamic);
|
SourceData__ctor(self, source, filename, mode, is_dynamic);
|
||||||
self->rc.count = 1;
|
self->rc.count = 1;
|
||||||
self->rc.dtor = (void (*)(void*))SourceData__dtor;
|
self->rc.dtor = (void (*)(void*))SourceData__dtor;
|
||||||
|
|||||||
@ -100,6 +100,7 @@ void c11_sbuf__write_quoted(c11_sbuf* self, c11_sv sv, char quote) {
|
|||||||
case '\b': c11_sbuf__write_cstrn(self, "\\b", 2); break;
|
case '\b': c11_sbuf__write_cstrn(self, "\\b", 2); break;
|
||||||
default: {
|
default: {
|
||||||
int u8bytes = c11__u8_header(c, true);
|
int u8bytes = c11__u8_header(c, true);
|
||||||
|
if(i + u8bytes > sv.size) u8bytes = 0; // invalid utf8
|
||||||
if(u8bytes <= 1) {
|
if(u8bytes <= 1) {
|
||||||
// not a valid utf8 char, or ascii
|
// not a valid utf8 char, or ascii
|
||||||
if(!isprint(c)) {
|
if(!isprint(c)) {
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
c11_string* c11_string__new(const char* data) { return c11_string__new2(data, strlen(data)); }
|
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) {
|
c11_string* c11_string__new2(const char* data, int size) {
|
||||||
c11_string* retval = malloc(sizeof(c11_string) + size + 1);
|
c11_string* retval = PK_MALLOC(sizeof(c11_string) + size + 1);
|
||||||
c11_string__ctor2(retval, data, size);
|
c11_string__ctor2(retval, data, size);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -46,12 +46,12 @@ void c11_string__ctor3(c11_string* self, int size) {
|
|||||||
|
|
||||||
c11_string* c11_string__copy(c11_string* self) {
|
c11_string* c11_string__copy(c11_string* self) {
|
||||||
int total_size = sizeof(c11_string) + self->size + 1;
|
int total_size = sizeof(c11_string) + self->size + 1;
|
||||||
c11_string* retval = malloc(total_size);
|
c11_string* retval = PK_MALLOC(total_size);
|
||||||
memcpy(retval, self, total_size);
|
memcpy(retval, self, total_size);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void c11_string__delete(c11_string* self) { free(self); }
|
void c11_string__delete(c11_string* self) { PK_FREE(self); }
|
||||||
|
|
||||||
c11_sv c11_string__sv(c11_string* self) { return (c11_sv){self->data, self->size}; }
|
c11_sv c11_string__sv(c11_string* self) { return (c11_sv){self->data, self->size}; }
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ static c11_vector /*T=char* */ _r_interned;
|
|||||||
void py_Name__initialize() {
|
void py_Name__initialize() {
|
||||||
c11_smallmap_s2n__ctor(&_interned);
|
c11_smallmap_s2n__ctor(&_interned);
|
||||||
for(int i = 0; i < _r_interned.length; i++) {
|
for(int i = 0; i < _r_interned.length; i++) {
|
||||||
free(c11__at(char*, &_r_interned, i));
|
PK_FREE(c11__at(char*, &_r_interned, i));
|
||||||
}
|
}
|
||||||
c11_vector__ctor(&_r_interned, sizeof(c11_sv));
|
c11_vector__ctor(&_r_interned, sizeof(c11_sv));
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ void py_Name__initialize() {
|
|||||||
void py_Name__finalize() {
|
void py_Name__finalize() {
|
||||||
// free all char*
|
// free all char*
|
||||||
for(int i = 0; i < _r_interned.length; i++) {
|
for(int i = 0; i < _r_interned.length; i++) {
|
||||||
free(c11__getitem(char*, &_r_interned, i));
|
PK_FREE(c11__getitem(char*, &_r_interned, i));
|
||||||
}
|
}
|
||||||
c11_smallmap_s2n__dtor(&_interned);
|
c11_smallmap_s2n__dtor(&_interned);
|
||||||
c11_vector__dtor(&_r_interned);
|
c11_vector__dtor(&_r_interned);
|
||||||
@ -41,7 +41,7 @@ py_Name py_namev(c11_sv name) {
|
|||||||
// generate new index
|
// generate new index
|
||||||
if(_interned.length > 65530) c11__abort("py_Name index overflow");
|
if(_interned.length > 65530) c11__abort("py_Name index overflow");
|
||||||
// NOTE: we must allocate the string in the heap so iterators are not invalidated
|
// NOTE: we must allocate the string in the heap so iterators are not invalidated
|
||||||
char* p = malloc(name.size + 1);
|
char* p = PK_MALLOC(name.size + 1);
|
||||||
memcpy(p, name.data, name.size);
|
memcpy(p, name.data, name.size);
|
||||||
p[name.size] = '\0';
|
p[name.size] = '\0';
|
||||||
c11_vector__push(char*, &_r_interned, p);
|
c11_vector__push(char*, &_r_interned, p);
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "pocketpy/common/utils.h"
|
#include "pocketpy/common/utils.h"
|
||||||
|
#include "pocketpy/config.h"
|
||||||
|
|
||||||
void c11_vector__ctor(c11_vector* self, int elem_size) {
|
void c11_vector__ctor(c11_vector* self, int elem_size) {
|
||||||
self->data = NULL;
|
self->data = NULL;
|
||||||
@ -12,7 +13,7 @@ void c11_vector__ctor(c11_vector* self, int elem_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void c11_vector__dtor(c11_vector* self) {
|
void c11_vector__dtor(c11_vector* self) {
|
||||||
if(self->data) free(self->data);
|
if(self->data) PK_FREE(self->data);
|
||||||
self->data = NULL;
|
self->data = NULL;
|
||||||
self->length = 0;
|
self->length = 0;
|
||||||
self->capacity = 0;
|
self->capacity = 0;
|
||||||
@ -31,7 +32,7 @@ void c11_vector__reserve(c11_vector* self, int capacity) {
|
|||||||
if(capacity < 4) capacity = 4;
|
if(capacity < 4) capacity = 4;
|
||||||
if(capacity <= self->capacity) return;
|
if(capacity <= self->capacity) return;
|
||||||
// self->elem_size * capacity may overflow
|
// self->elem_size * capacity may overflow
|
||||||
self->data = realloc(self->data, (size_t)self->elem_size * (size_t)capacity);
|
self->data = PK_REALLOC(self->data, (size_t)self->elem_size * (size_t)capacity);
|
||||||
if(self->data == NULL) c11__abort("c11_vector__reserve(): out of memory");
|
if(self->data == NULL) c11__abort("c11_vector__reserve(): out of memory");
|
||||||
self->capacity = capacity;
|
self->capacity = capacity;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -464,7 +464,7 @@ void SequenceExpr__dtor(Expr* self_) {
|
|||||||
for(int i = 0; i < self->itemCount; i++) {
|
for(int i = 0; i < self->itemCount; i++) {
|
||||||
vtdelete(self->items[i]);
|
vtdelete(self->items[i]);
|
||||||
}
|
}
|
||||||
free(self->items);
|
PK_FREE(self->items);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TupleExpr__emit_store(Expr* self_, Ctx* ctx) {
|
bool TupleExpr__emit_store(Expr* self_, Ctx* ctx) {
|
||||||
@ -526,7 +526,7 @@ static SequenceExpr* SequenceExpr__new(int line, const ExprVt* vt, int count, Op
|
|||||||
self->vt = vt;
|
self->vt = vt;
|
||||||
self->line = line;
|
self->line = line;
|
||||||
self->opcode = opcode;
|
self->opcode = opcode;
|
||||||
self->items = malloc(sizeof(Expr*) * count);
|
self->items = PK_MALLOC(sizeof(Expr*) * count);
|
||||||
self->itemCount = count;
|
self->itemCount = count;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -1318,11 +1318,11 @@ static void Compiler__dtor(Compiler* self) {
|
|||||||
// free tokens
|
// free tokens
|
||||||
for(int i = 0; i < self->tokens_length; i++) {
|
for(int i = 0; i < self->tokens_length; i++) {
|
||||||
if(self->tokens[i].value.index == TokenValue_STR) {
|
if(self->tokens[i].value.index == TokenValue_STR) {
|
||||||
// free internal string
|
// PK_FREE internal string
|
||||||
c11_string__delete(self->tokens[i].value._str);
|
c11_string__delete(self->tokens[i].value._str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(self->tokens);
|
PK_FREE(self->tokens);
|
||||||
// free contexts
|
// free contexts
|
||||||
c11__foreach(Ctx, &self->contexts, ctx) Ctx__dtor(ctx);
|
c11__foreach(Ctx, &self->contexts, ctx) Ctx__dtor(ctx);
|
||||||
c11_vector__dtor(&self->contexts);
|
c11_vector__dtor(&self->contexts);
|
||||||
@ -1359,7 +1359,7 @@ static NameScope name_scope(Compiler* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error* SyntaxError(Compiler* self, const char* fmt, ...) {
|
Error* SyntaxError(Compiler* self, const char* fmt, ...) {
|
||||||
Error* err = malloc(sizeof(Error));
|
Error* err = PK_MALLOC(sizeof(Error));
|
||||||
err->src = self->src;
|
err->src = self->src;
|
||||||
PK_INCREF(self->src);
|
PK_INCREF(self->src);
|
||||||
Token* t = self->i == self->tokens_length ? prev() : curr();
|
Token* t = self->i == self->tokens_length ? prev() : curr();
|
||||||
|
|||||||
@ -186,7 +186,7 @@ static bool is_possible_number_char(char c) {
|
|||||||
|
|
||||||
/******************************/
|
/******************************/
|
||||||
static Error* LexerError(Lexer* self, const char* fmt, ...) {
|
static Error* LexerError(Lexer* self, const char* fmt, ...) {
|
||||||
Error* err = malloc(sizeof(Error));
|
Error* err = PK_MALLOC(sizeof(Error));
|
||||||
err->src = self->src;
|
err->src = self->src;
|
||||||
PK_INCREF(self->src);
|
PK_INCREF(self->src);
|
||||||
err->lineno = self->current_line;
|
err->lineno = self->current_line;
|
||||||
|
|||||||
@ -13,6 +13,14 @@ static bool stack_format_object(VM* self, c11_sv spec);
|
|||||||
#define CHECK_RETURN_FROM_EXCEPT_OR_FINALLY() \
|
#define CHECK_RETURN_FROM_EXCEPT_OR_FINALLY() \
|
||||||
if(self->is_curr_exc_handled) py_clearexc(NULL)
|
if(self->is_curr_exc_handled) py_clearexc(NULL)
|
||||||
|
|
||||||
|
#define CHECK_STACK_OVERFLOW() \
|
||||||
|
do { \
|
||||||
|
if(self->stack.sp > self->stack.end) { \
|
||||||
|
py_exception(tp_StackOverflowError, ""); \
|
||||||
|
goto __ERROR; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#define DISPATCH() \
|
#define DISPATCH() \
|
||||||
do { \
|
do { \
|
||||||
frame->ip++; \
|
frame->ip++; \
|
||||||
@ -92,7 +100,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
pk_print_stack(self, frame, byte);
|
pk_print_stack(self, frame, byte);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(self->is_signal_interrupted){
|
if(self->is_signal_interrupted) {
|
||||||
self->is_signal_interrupted = false;
|
self->is_signal_interrupted = false;
|
||||||
py_exception(tp_KeyboardInterrupt, "");
|
py_exception(tp_KeyboardInterrupt, "");
|
||||||
goto __ERROR;
|
goto __ERROR;
|
||||||
@ -132,15 +140,40 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
POP();
|
POP();
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_LOAD_CONST: PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg)); DISPATCH();
|
case OP_LOAD_CONST: {
|
||||||
case OP_LOAD_NONE: py_newnone(SP()++); DISPATCH();
|
CHECK_STACK_OVERFLOW();
|
||||||
case OP_LOAD_TRUE: py_newbool(SP()++, true); DISPATCH();
|
PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg));
|
||||||
case OP_LOAD_FALSE: py_newbool(SP()++, false); DISPATCH();
|
DISPATCH();
|
||||||
|
}
|
||||||
|
case OP_LOAD_NONE: {
|
||||||
|
CHECK_STACK_OVERFLOW();
|
||||||
|
py_newnone(SP()++);
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
case OP_LOAD_TRUE: {
|
||||||
|
CHECK_STACK_OVERFLOW();
|
||||||
|
py_newbool(SP()++, true);
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
case OP_LOAD_FALSE: {
|
||||||
|
CHECK_STACK_OVERFLOW();
|
||||||
|
py_newbool(SP()++, false);
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_LOAD_SMALL_INT: py_newint(SP()++, (int16_t)byte.arg); DISPATCH();
|
case OP_LOAD_SMALL_INT: {
|
||||||
|
CHECK_STACK_OVERFLOW();
|
||||||
|
py_newint(SP()++, (int16_t)byte.arg);
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_LOAD_ELLIPSIS: py_newellipsis(SP()++); DISPATCH();
|
case OP_LOAD_ELLIPSIS: {
|
||||||
|
CHECK_STACK_OVERFLOW();
|
||||||
|
py_newellipsis(SP()++);
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
case OP_LOAD_FUNCTION: {
|
case OP_LOAD_FUNCTION: {
|
||||||
|
CHECK_STACK_OVERFLOW();
|
||||||
FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
|
FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
|
||||||
Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
|
Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
|
||||||
Function__ctor(ud, decl, frame->module);
|
Function__ctor(ud, decl, frame->module);
|
||||||
@ -952,8 +985,12 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
goto __ERROR;
|
goto __ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
py_Type type =
|
py_Type type = pk_newtype(py_name2str(name),
|
||||||
pk_newtype(py_name2str(name), base, frame->module, NULL, base_ti->is_python, false);
|
base,
|
||||||
|
frame->module,
|
||||||
|
NULL,
|
||||||
|
base_ti->is_python,
|
||||||
|
false);
|
||||||
PUSH(py_tpobject(type));
|
PUSH(py_tpobject(type));
|
||||||
self->__curr_class = TOP();
|
self->__curr_class = TOP();
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
|
|||||||
@ -28,14 +28,14 @@ NameDict* FastLocals__to_namedict(py_TValue* locals, const CodeObject* co) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UnwindTarget* UnwindTarget__new(UnwindTarget* next, int iblock, int offset) {
|
UnwindTarget* UnwindTarget__new(UnwindTarget* next, int iblock, int offset) {
|
||||||
UnwindTarget* self = malloc(sizeof(UnwindTarget));
|
UnwindTarget* self = PK_MALLOC(sizeof(UnwindTarget));
|
||||||
self->next = next;
|
self->next = next;
|
||||||
self->iblock = iblock;
|
self->iblock = iblock;
|
||||||
self->offset = offset;
|
self->offset = offset;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnwindTarget__delete(UnwindTarget* self) { free(self); }
|
void UnwindTarget__delete(UnwindTarget* self) { PK_FREE(self); }
|
||||||
|
|
||||||
Frame* Frame__new(const CodeObject* co,
|
Frame* Frame__new(const CodeObject* co,
|
||||||
py_GlobalRef module,
|
py_GlobalRef module,
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include "pocketpy/interpreter/heap.h"
|
#include "pocketpy/interpreter/heap.h"
|
||||||
#include "pocketpy/common/memorypool.h"
|
#include "pocketpy/common/memorypool.h"
|
||||||
|
#include "pocketpy/config.h"
|
||||||
#include "pocketpy/objects/base.h"
|
#include "pocketpy/objects/base.h"
|
||||||
|
|
||||||
void ManagedHeap__ctor(ManagedHeap* self, VM* vm) {
|
void ManagedHeap__ctor(ManagedHeap* self, VM* vm) {
|
||||||
@ -8,6 +9,8 @@ void ManagedHeap__ctor(ManagedHeap* self, VM* vm) {
|
|||||||
|
|
||||||
self->gc_threshold = PK_GC_MIN_THRESHOLD;
|
self->gc_threshold = PK_GC_MIN_THRESHOLD;
|
||||||
self->gc_counter = 0;
|
self->gc_counter = 0;
|
||||||
|
self->gc_enabled = true;
|
||||||
|
|
||||||
self->vm = vm;
|
self->vm = vm;
|
||||||
|
|
||||||
self->gc_on_delete = NULL;
|
self->gc_on_delete = NULL;
|
||||||
@ -27,6 +30,7 @@ void ManagedHeap__dtor(ManagedHeap* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ManagedHeap__collect_if_needed(ManagedHeap* self) {
|
void ManagedHeap__collect_if_needed(ManagedHeap* self) {
|
||||||
|
if(!self->gc_enabled) return;
|
||||||
if(self->gc_counter < self->gc_threshold) return;
|
if(self->gc_counter < self->gc_threshold) return;
|
||||||
self->gc_counter = 0;
|
self->gc_counter = 0;
|
||||||
ManagedHeap__collect(self);
|
ManagedHeap__collect(self);
|
||||||
@ -91,11 +95,11 @@ PyObject* PyObject__new(py_Type type, int slots, int size) {
|
|||||||
PyObject* self;
|
PyObject* self;
|
||||||
// header + slots + udsize
|
// header + slots + udsize
|
||||||
size = sizeof(PyObject) + PK_OBJ_SLOTS_SIZE(slots) + size;
|
size = sizeof(PyObject) + PK_OBJ_SLOTS_SIZE(slots) + size;
|
||||||
if(size <= kPoolObjectBlockSize) {
|
if(!PK_LOW_MEMORY_MODE && size <= kPoolObjectBlockSize) {
|
||||||
self = PoolObject_alloc();
|
self = PoolObject_alloc();
|
||||||
self->gc_is_large = false;
|
self->gc_is_large = false;
|
||||||
} else {
|
} else {
|
||||||
self = malloc(size);
|
self = PK_MALLOC(size);
|
||||||
self->gc_is_large = true;
|
self->gc_is_large = true;
|
||||||
}
|
}
|
||||||
self->type = type;
|
self->type = type;
|
||||||
|
|||||||
@ -10,7 +10,7 @@ void TypeList__ctor(TypeList* self) {
|
|||||||
|
|
||||||
void TypeList__dtor(TypeList* self) {
|
void TypeList__dtor(TypeList* self) {
|
||||||
for (int i = 0; i < self->length; i++) {
|
for (int i = 0; i < self->length; i++) {
|
||||||
if(self->chunks[i]) free(self->chunks[i]);
|
if(self->chunks[i]) PK_FREE(self->chunks[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ py_TypeInfo* TypeList__emplace(TypeList* self){
|
|||||||
int offset = self->length & (CHUNK_SIZE - 1);
|
int offset = self->length & (CHUNK_SIZE - 1);
|
||||||
assert(chunk < 256);
|
assert(chunk < 256);
|
||||||
if(self->chunks[chunk] == NULL){
|
if(self->chunks[chunk] == NULL){
|
||||||
self->chunks[chunk] = malloc(sizeof(py_TypeInfo) * CHUNK_SIZE);
|
self->chunks[chunk] = PK_MALLOC(sizeof(py_TypeInfo) * CHUNK_SIZE);
|
||||||
memset(self->chunks[chunk], 0, sizeof(py_TypeInfo) * CHUNK_SIZE);
|
memset(self->chunks[chunk], 0, sizeof(py_TypeInfo) * CHUNK_SIZE);
|
||||||
}
|
}
|
||||||
self->length++;
|
self->length++;
|
||||||
|
|||||||
@ -17,7 +17,7 @@ static char* pk_default_importfile(const char* path) {
|
|||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
long size = ftell(f);
|
long size = ftell(f);
|
||||||
fseek(f, 0, SEEK_SET);
|
fseek(f, 0, SEEK_SET);
|
||||||
char* buffer = malloc(size + 1);
|
char* buffer = PK_MALLOC(size + 1);
|
||||||
size = fread(buffer, 1, size, f);
|
size = fread(buffer, 1, size, f);
|
||||||
buffer[size] = 0;
|
buffer[size] = 0;
|
||||||
fclose(f);
|
fclose(f);
|
||||||
@ -572,7 +572,7 @@ void PyObject__delete(PyObject* self) {
|
|||||||
if(ti->dtor) ti->dtor(PyObject__userdata(self));
|
if(ti->dtor) ti->dtor(PyObject__userdata(self));
|
||||||
if(self->slots == -1) NameDict__dtor(PyObject__dict(self));
|
if(self->slots == -1) NameDict__dtor(PyObject__dict(self));
|
||||||
if(self->gc_is_large) {
|
if(self->gc_is_large) {
|
||||||
free(self);
|
PK_FREE(self);
|
||||||
} else {
|
} else {
|
||||||
PoolObject_dealloc(self);
|
PoolObject_dealloc(self);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,4 @@
|
|||||||
#include "pocketpy/pocketpy.h"
|
#include "pocketpy/pocketpy.h"
|
||||||
|
|
||||||
#include "pocketpy/common/utils.h"
|
|
||||||
#include "pocketpy/objects/object.h"
|
|
||||||
#include "pocketpy/common/sstream.h"
|
|
||||||
#include "pocketpy/interpreter/vm.h"
|
#include "pocketpy/interpreter/vm.h"
|
||||||
|
|
||||||
static bool gc_collect(int argc, py_Ref argv){
|
static bool gc_collect(int argc, py_Ref argv){
|
||||||
@ -13,8 +9,34 @@ static bool gc_collect(int argc, py_Ref argv){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool gc_enable(int argc, py_Ref argv){
|
||||||
|
PY_CHECK_ARGC(0);
|
||||||
|
ManagedHeap* heap = &pk_current_vm->heap;
|
||||||
|
heap->gc_enabled = true;
|
||||||
|
py_newnone(py_retval());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool gc_disable(int argc, py_Ref argv){
|
||||||
|
PY_CHECK_ARGC(0);
|
||||||
|
ManagedHeap* heap = &pk_current_vm->heap;
|
||||||
|
heap->gc_enabled = false;
|
||||||
|
py_newnone(py_retval());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool gc_isenabled(int argc, py_Ref argv){
|
||||||
|
PY_CHECK_ARGC(0);
|
||||||
|
ManagedHeap* heap = &pk_current_vm->heap;
|
||||||
|
py_newbool(py_retval(), heap->gc_enabled);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void pk__add_module_gc() {
|
void pk__add_module_gc() {
|
||||||
py_Ref mod = py_newmodule("gc");
|
py_Ref mod = py_newmodule("gc");
|
||||||
|
|
||||||
py_bindfunc(mod, "collect", gc_collect);
|
py_bindfunc(mod, "collect", gc_collect);
|
||||||
|
py_bindfunc(mod, "enable", gc_enable);
|
||||||
|
py_bindfunc(mod, "disable", gc_disable);
|
||||||
|
py_bindfunc(mod, "isenabled", gc_isenabled);
|
||||||
}
|
}
|
||||||
@ -157,10 +157,10 @@ static bool io_FileIO_read(int argc, py_Ref argv) {
|
|||||||
int actual_size = fread(dst, 1, size, ud->file);
|
int actual_size = fread(dst, 1, size, ud->file);
|
||||||
py_bytes_resize(py_retval(), actual_size);
|
py_bytes_resize(py_retval(), actual_size);
|
||||||
} else {
|
} else {
|
||||||
void* dst = malloc(size);
|
void* dst = PK_MALLOC(size);
|
||||||
int actual_size = fread(dst, 1, size, ud->file);
|
int actual_size = fread(dst, 1, size, ud->file);
|
||||||
py_newstrv(py_retval(), (c11_sv){dst, actual_size});
|
py_newstrv(py_retval(), (c11_sv){dst, actual_size});
|
||||||
free(dst);
|
PK_FREE(dst);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,14 +41,14 @@ typedef struct {
|
|||||||
|
|
||||||
static void PickleObject__ctor(PickleObject* self) {
|
static void PickleObject__ctor(PickleObject* self) {
|
||||||
self->used_types_length = pk_current_vm->types.length;
|
self->used_types_length = pk_current_vm->types.length;
|
||||||
self->used_types = malloc(self->used_types_length);
|
self->used_types = PK_MALLOC(self->used_types_length);
|
||||||
memset(self->used_types, 0, self->used_types_length);
|
memset(self->used_types, 0, self->used_types_length);
|
||||||
c11_smallmap_p2i__ctor(&self->memo);
|
c11_smallmap_p2i__ctor(&self->memo);
|
||||||
c11_vector__ctor(&self->codes, sizeof(char));
|
c11_vector__ctor(&self->codes, sizeof(char));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PickleObject__dtor(PickleObject* self) {
|
static void PickleObject__dtor(PickleObject* self) {
|
||||||
free(self->used_types);
|
PK_FREE(self->used_types);
|
||||||
c11_smallmap_p2i__dtor(&self->memo);
|
c11_smallmap_p2i__dtor(&self->memo);
|
||||||
c11_vector__dtor(&self->codes);
|
c11_vector__dtor(&self->codes);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -225,7 +225,7 @@ static bool Random_choices(int argc, py_Ref argv) {
|
|||||||
if(!py_checktype(py_arg(3), tp_int)) return false;
|
if(!py_checktype(py_arg(3), tp_int)) return false;
|
||||||
py_i64 k = py_toint(py_arg(3));
|
py_i64 k = py_toint(py_arg(3));
|
||||||
|
|
||||||
py_f64* cum_weights = malloc(sizeof(py_f64) * length);
|
py_f64* cum_weights = PK_MALLOC(sizeof(py_f64) * length);
|
||||||
if(py_isnone(weights)) {
|
if(py_isnone(weights)) {
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
cum_weights[i] = i + 1;
|
cum_weights[i] = i + 1;
|
||||||
@ -233,21 +233,21 @@ static bool Random_choices(int argc, py_Ref argv) {
|
|||||||
py_TValue* w;
|
py_TValue* w;
|
||||||
int wlen = pk_arrayview(weights, &w);
|
int wlen = pk_arrayview(weights, &w);
|
||||||
if(wlen == -1) {
|
if(wlen == -1) {
|
||||||
free(cum_weights);
|
PK_FREE(cum_weights);
|
||||||
return TypeError("choices(): weights must be a list or tuple");
|
return TypeError("choices(): weights must be a list or tuple");
|
||||||
}
|
}
|
||||||
if(wlen != length) {
|
if(wlen != length) {
|
||||||
free(cum_weights);
|
PK_FREE(cum_weights);
|
||||||
return ValueError("len(weights) != len(population)");
|
return ValueError("len(weights) != len(population)");
|
||||||
}
|
}
|
||||||
if(!py_castfloat(&w[0], &cum_weights[0])) {
|
if(!py_castfloat(&w[0], &cum_weights[0])) {
|
||||||
free(cum_weights);
|
PK_FREE(cum_weights);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for(int i = 1; i < length; i++) {
|
for(int i = 1; i < length; i++) {
|
||||||
py_f64 tmp;
|
py_f64 tmp;
|
||||||
if(!py_castfloat(&w[i], &tmp)) {
|
if(!py_castfloat(&w[i], &tmp)) {
|
||||||
free(cum_weights);
|
PK_FREE(cum_weights);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cum_weights[i] = cum_weights[i - 1] + tmp;
|
cum_weights[i] = cum_weights[i - 1] + tmp;
|
||||||
@ -256,7 +256,7 @@ static bool Random_choices(int argc, py_Ref argv) {
|
|||||||
|
|
||||||
py_f64 total = cum_weights[length - 1];
|
py_f64 total = cum_weights[length - 1];
|
||||||
if(total <= 0) {
|
if(total <= 0) {
|
||||||
free(cum_weights);
|
PK_FREE(cum_weights);
|
||||||
return ValueError("total of weights must be greater than zero");
|
return ValueError("total of weights must be greater than zero");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ static bool Random_choices(int argc, py_Ref argv) {
|
|||||||
py_list_setitem(py_retval(), i, p + index);
|
py_list_setitem(py_retval(), i, p + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(cum_weights);
|
PK_FREE(cum_weights);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ static bool traceback_format_exc(int argc, py_Ref argv) {
|
|||||||
py_newnone(py_retval());
|
py_newnone(py_retval());
|
||||||
} else {
|
} else {
|
||||||
py_newstr(py_retval(), s);
|
py_newstr(py_retval(), s);
|
||||||
free(s);
|
PK_FREE(s);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ static void FuncDecl__dtor(FuncDecl* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FuncDecl_ FuncDecl__rcnew(SourceData_ src, c11_sv name) {
|
FuncDecl_ FuncDecl__rcnew(SourceData_ src, c11_sv name) {
|
||||||
FuncDecl* self = malloc(sizeof(FuncDecl));
|
FuncDecl* self = PK_MALLOC(sizeof(FuncDecl));
|
||||||
self->rc.count = 1;
|
self->rc.count = 1;
|
||||||
self->rc.dtor = (void (*)(void*))FuncDecl__dtor;
|
self->rc.dtor = (void (*)(void*))FuncDecl__dtor;
|
||||||
CodeObject__ctor(&self->code, src, name);
|
CodeObject__ctor(&self->code, src, name);
|
||||||
|
|||||||
@ -17,11 +17,11 @@ void ModuleDict__ctor(ModuleDict* self, const char* path, py_TValue module) {
|
|||||||
void ModuleDict__dtor(ModuleDict* self) {
|
void ModuleDict__dtor(ModuleDict* self) {
|
||||||
if(self->left) {
|
if(self->left) {
|
||||||
ModuleDict__dtor(self->left);
|
ModuleDict__dtor(self->left);
|
||||||
free(self->left);
|
PK_FREE(self->left);
|
||||||
}
|
}
|
||||||
if(self->right) {
|
if(self->right) {
|
||||||
ModuleDict__dtor(self->right);
|
ModuleDict__dtor(self->right);
|
||||||
free(self->right);
|
PK_FREE(self->right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,14 +35,14 @@ void ModuleDict__set(ModuleDict* self, const char* key, py_TValue val) {
|
|||||||
if(self->left) {
|
if(self->left) {
|
||||||
ModuleDict__set(self->left, key, val);
|
ModuleDict__set(self->left, key, val);
|
||||||
} else {
|
} else {
|
||||||
self->left = malloc(sizeof(ModuleDict));
|
self->left = PK_MALLOC(sizeof(ModuleDict));
|
||||||
ModuleDict__ctor(self->left, key, val);
|
ModuleDict__ctor(self->left, key, val);
|
||||||
}
|
}
|
||||||
} else if(cmp > 0) {
|
} else if(cmp > 0) {
|
||||||
if(self->right) {
|
if(self->right) {
|
||||||
ModuleDict__set(self->right, key, val);
|
ModuleDict__set(self->right, key, val);
|
||||||
} else {
|
} else {
|
||||||
self->right = malloc(sizeof(ModuleDict));
|
self->right = PK_MALLOC(sizeof(ModuleDict));
|
||||||
ModuleDict__ctor(self->right, key, val);
|
ModuleDict__ctor(self->right, key, val);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -30,7 +30,7 @@ bool _py_compile(CodeObject* out,
|
|||||||
PK_DECREF(src);
|
PK_DECREF(src);
|
||||||
|
|
||||||
PK_DECREF(err->src);
|
PK_DECREF(err->src);
|
||||||
free(err);
|
PK_FREE(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PK_DECREF(src);
|
PK_DECREF(src);
|
||||||
|
|||||||
@ -51,7 +51,7 @@ void py_finalize() {
|
|||||||
// TODO: refactor VM__ctor and VM__dtor
|
// TODO: refactor VM__ctor and VM__dtor
|
||||||
pk_current_vm = vm;
|
pk_current_vm = vm;
|
||||||
VM__dtor(vm);
|
VM__dtor(vm);
|
||||||
free(vm);
|
PK_FREE(vm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pk_current_vm = &pk_default_vm;
|
pk_current_vm = &pk_default_vm;
|
||||||
@ -64,7 +64,7 @@ void py_finalize() {
|
|||||||
void py_switchvm(int index) {
|
void py_switchvm(int index) {
|
||||||
if(index < 0 || index >= 16) c11__abort("invalid vm index");
|
if(index < 0 || index >= 16) c11__abort("invalid vm index");
|
||||||
if(!pk_all_vm[index]) {
|
if(!pk_all_vm[index]) {
|
||||||
pk_current_vm = pk_all_vm[index] = malloc(sizeof(VM));
|
pk_current_vm = pk_all_vm[index] = PK_MALLOC(sizeof(VM));
|
||||||
memset(pk_current_vm, 0, sizeof(VM));
|
memset(pk_current_vm, 0, sizeof(VM));
|
||||||
VM__ctor(pk_all_vm[index]);
|
VM__ctor(pk_all_vm[index]);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -155,7 +155,7 @@ __SUCCESS:
|
|||||||
|
|
||||||
c11_string__delete(filename);
|
c11_string__delete(filename);
|
||||||
c11_string__delete(slashed_path);
|
c11_string__delete(slashed_path);
|
||||||
if(need_free) free((void*)data);
|
if(need_free) PK_FREE((void*)data);
|
||||||
return ok ? 1 : -1;
|
return ok ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -78,7 +78,7 @@ typedef struct {
|
|||||||
static void Dict__ctor(Dict* self, uint32_t capacity, int entries_capacity) {
|
static void Dict__ctor(Dict* self, uint32_t capacity, int entries_capacity) {
|
||||||
self->length = 0;
|
self->length = 0;
|
||||||
self->capacity = capacity;
|
self->capacity = capacity;
|
||||||
self->indices = malloc(self->capacity * sizeof(DictIndex));
|
self->indices = PK_MALLOC(self->capacity * sizeof(DictIndex));
|
||||||
memset(self->indices, -1, self->capacity * sizeof(DictIndex));
|
memset(self->indices, -1, self->capacity * sizeof(DictIndex));
|
||||||
c11_vector__ctor(&self->entries, sizeof(DictEntry));
|
c11_vector__ctor(&self->entries, sizeof(DictEntry));
|
||||||
c11_vector__reserve(&self->entries, entries_capacity);
|
c11_vector__reserve(&self->entries, entries_capacity);
|
||||||
@ -87,7 +87,7 @@ static void Dict__ctor(Dict* self, uint32_t capacity, int entries_capacity) {
|
|||||||
static void Dict__dtor(Dict* self) {
|
static void Dict__dtor(Dict* self) {
|
||||||
self->length = 0;
|
self->length = 0;
|
||||||
self->capacity = 0;
|
self->capacity = 0;
|
||||||
free(self->indices);
|
PK_FREE(self->indices);
|
||||||
c11_vector__dtor(&self->entries);
|
c11_vector__dtor(&self->entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ __RETRY:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void Dict__compact_entries(Dict* self) {
|
static void Dict__compact_entries(Dict* self) {
|
||||||
int* mappings = malloc(self->entries.length * sizeof(int));
|
int* mappings = PK_MALLOC(self->entries.length * sizeof(int));
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for(int i = 0; i < self->entries.length; i++) {
|
for(int i = 0; i < self->entries.length; i++) {
|
||||||
@ -176,7 +176,7 @@ static void Dict__compact_entries(Dict* self) {
|
|||||||
self->indices[i]._[j] = mappings[idx];
|
self->indices[i]._[j] = mappings[idx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(mappings);
|
PK_FREE(mappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Dict__set(Dict* self, py_TValue* key, py_TValue* val) {
|
static bool Dict__set(Dict* self, py_TValue* key, py_TValue* val) {
|
||||||
@ -442,7 +442,7 @@ static bool dict_copy(int argc, py_Ref argv) {
|
|||||||
new_dict->length = self->length;
|
new_dict->length = self->length;
|
||||||
new_dict->entries = c11_vector__copy(&self->entries);
|
new_dict->entries = c11_vector__copy(&self->entries);
|
||||||
// copy indices
|
// copy indices
|
||||||
new_dict->indices = malloc(new_dict->capacity * sizeof(DictIndex));
|
new_dict->indices = PK_MALLOC(new_dict->capacity * sizeof(DictIndex));
|
||||||
memcpy(new_dict->indices, self->indices, new_dict->capacity * sizeof(DictIndex));
|
memcpy(new_dict->indices, self->indices, new_dict->capacity * sizeof(DictIndex));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -164,7 +164,7 @@ void py_printexc() {
|
|||||||
if(!msg) return;
|
if(!msg) return;
|
||||||
pk_current_vm->callbacks.print(msg);
|
pk_current_vm->callbacks.print(msg);
|
||||||
pk_current_vm->callbacks.print("\n");
|
pk_current_vm->callbacks.print("\n");
|
||||||
free(msg);
|
PK_FREE(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void c11_sbuf__write_exc(c11_sbuf* self, py_Ref exc) {
|
static void c11_sbuf__write_exc(c11_sbuf* self, py_Ref exc) {
|
||||||
@ -218,7 +218,7 @@ char* py_formatexc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c11_string* res = c11_sbuf__submit(&ss);
|
c11_string* res = c11_sbuf__submit(&ss);
|
||||||
char* dup = malloc(res->size + 1);
|
char* dup = PK_MALLOC(res->size + 1);
|
||||||
memcpy(dup, res->data, res->size);
|
memcpy(dup, res->data, res->size);
|
||||||
dup[res->size] = '\0';
|
dup[res->size] = '\0';
|
||||||
c11_string__delete(res);
|
c11_string__delete(res);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user