mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
backup
This commit is contained in:
parent
5a72730853
commit
2d5561441d
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "pocketpy/common/str.h"
|
|
||||||
|
|
||||||
void py_Name__initialize();
|
|
||||||
void py_Name__finalize();
|
|
@ -4,7 +4,6 @@
|
|||||||
#include "pocketpy/objects/codeobject.h"
|
#include "pocketpy/objects/codeobject.h"
|
||||||
#include "pocketpy/objects/namedict.h"
|
#include "pocketpy/objects/namedict.h"
|
||||||
#include "pocketpy/objects/object.h"
|
#include "pocketpy/objects/object.h"
|
||||||
#include "pocketpy/common/strname.h"
|
|
||||||
#include "pocketpy/pocketpy.h"
|
#include "pocketpy/pocketpy.h"
|
||||||
|
|
||||||
py_TValue* FastLocals__try_get_by_name(py_TValue* locals, const CodeObject* co, py_Name name);
|
py_TValue* FastLocals__try_get_by_name(py_TValue* locals, const CodeObject* co, py_Name name);
|
||||||
|
18
include/pocketpy/interpreter/name.h
Normal file
18
include/pocketpy/interpreter/name.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "pocketpy/objects/base.h"
|
||||||
|
#include "pocketpy/common/smallmap.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* data; // null-terminated data
|
||||||
|
int size; // size of the data excluding the null-terminator
|
||||||
|
py_TValue obj; // cached `str` object (lazy initialized)
|
||||||
|
} RInternedEntry;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
c11_smallmap_s2n interned;
|
||||||
|
c11_vector /* T=RInternedEntry */ r_interned;
|
||||||
|
} InternedNames;
|
||||||
|
|
||||||
|
void InternedNames__ctor(InternedNames* self);
|
||||||
|
void InternedNames__dtor(InternedNames* self);
|
@ -7,6 +7,7 @@
|
|||||||
#include "pocketpy/interpreter/frame.h"
|
#include "pocketpy/interpreter/frame.h"
|
||||||
#include "pocketpy/interpreter/modules.h"
|
#include "pocketpy/interpreter/modules.h"
|
||||||
#include "pocketpy/interpreter/typeinfo.h"
|
#include "pocketpy/interpreter/typeinfo.h"
|
||||||
|
#include "pocketpy/interpreter/name.h"
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// 1. __eq__ and __ne__ fallbacks
|
// 1. __eq__ and __ne__ fallbacks
|
||||||
@ -41,6 +42,7 @@ typedef struct VM {
|
|||||||
py_StackRef __curr_function;
|
py_StackRef __curr_function;
|
||||||
py_TValue __vectorcall_buffer[PK_MAX_CO_VARNAMES];
|
py_TValue __vectorcall_buffer[PK_MAX_CO_VARNAMES];
|
||||||
|
|
||||||
|
InternedNames names;
|
||||||
FixedMemoryPool pool_frame;
|
FixedMemoryPool pool_frame;
|
||||||
ManagedHeap heap;
|
ManagedHeap heap;
|
||||||
ValueStack stack; // put `stack` at the end for better cache locality
|
ValueStack stack; // put `stack` at the end for better cache locality
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "pocketpy/common/str.h"
|
|
||||||
#include "pocketpy/common/strname.h"
|
|
||||||
#include "pocketpy/objects/codeobject.h"
|
|
||||||
#include "pocketpy/objects/sourcedata.h"
|
#include "pocketpy/objects/sourcedata.h"
|
||||||
#include "pocketpy/objects/object.h"
|
|
||||||
#include "pocketpy/pocketpy.h"
|
#include "pocketpy/pocketpy.h"
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
#include "pocketpy/common/strname.h"
|
|
||||||
#include "pocketpy/common/smallmap.h"
|
|
||||||
#include "pocketpy/common/utils.h"
|
|
||||||
#include "pocketpy/common/vector.h"
|
|
||||||
#include "pocketpy/pocketpy.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char* data; // null-terminated data
|
|
||||||
int size; // size of the data excluding the null-terminator
|
|
||||||
py_TValue* ref; // cached `str` object (lazy initialized)
|
|
||||||
} RInternedEntry;
|
|
||||||
|
|
||||||
// TODO: use a more efficient data structure
|
|
||||||
static c11_smallmap_s2n _interned;
|
|
||||||
static c11_vector /* T=RInternedEntry */ _r_interned;
|
|
||||||
|
|
||||||
void py_Name__initialize() {
|
|
||||||
c11_smallmap_s2n__ctor(&_interned);
|
|
||||||
c11_vector__ctor(&_r_interned, sizeof(RInternedEntry));
|
|
||||||
|
|
||||||
#define MAGIC_METHOD(x) \
|
|
||||||
if(x != py_name(#x)) abort();
|
|
||||||
#include "pocketpy/xmacros/magics.h"
|
|
||||||
#undef MAGIC_METHOD
|
|
||||||
}
|
|
||||||
|
|
||||||
void py_Name__finalize() {
|
|
||||||
// free all char*
|
|
||||||
for(int i = 0; i < _r_interned.length; i++) {
|
|
||||||
PK_FREE(c11__getitem(RInternedEntry, &_r_interned, i).data);
|
|
||||||
}
|
|
||||||
c11_smallmap_s2n__dtor(&_interned);
|
|
||||||
c11_vector__dtor(&_r_interned);
|
|
||||||
}
|
|
||||||
|
|
||||||
py_Name py_name(const char* name) { return py_namev((c11_sv){name, strlen(name)}); }
|
|
||||||
|
|
||||||
py_Name py_namev(c11_sv name) {
|
|
||||||
uint16_t index = c11_smallmap_s2n__get(&_interned, name, 0);
|
|
||||||
if(index != 0) return index;
|
|
||||||
// generate new index
|
|
||||||
if(_interned.length > 65530) c11__abort("py_Name index overflow");
|
|
||||||
// NOTE: we must allocate the string in the heap so iterators are not invalidated
|
|
||||||
char* p = PK_MALLOC(name.size + 1);
|
|
||||||
memcpy(p, name.data, name.size);
|
|
||||||
p[name.size] = '\0';
|
|
||||||
RInternedEntry entry;
|
|
||||||
entry.data = p;
|
|
||||||
entry.size = name.size;
|
|
||||||
entry.ref = NULL;
|
|
||||||
c11_vector__push(RInternedEntry, &_r_interned, entry);
|
|
||||||
index = _r_interned.length; // 1-based
|
|
||||||
// save to _interned
|
|
||||||
c11_smallmap_s2n__set(&_interned, (c11_sv){p, name.size}, index);
|
|
||||||
assert(_interned.length == _r_interned.length);
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* py_name2str(py_Name index) {
|
|
||||||
assert(index > 0 && index <= _interned.length);
|
|
||||||
return c11__getitem(RInternedEntry, &_r_interned, index - 1).data;
|
|
||||||
}
|
|
||||||
|
|
||||||
c11_sv py_name2sv(py_Name index) {
|
|
||||||
assert(index > 0 && index <= _interned.length);
|
|
||||||
RInternedEntry entry = c11__getitem(RInternedEntry, &_r_interned, index - 1);
|
|
||||||
return (c11_sv){entry.data, entry.size};
|
|
||||||
}
|
|
||||||
|
|
||||||
py_GlobalRef py_name2ref(py_Name index) {
|
|
||||||
assert(index > 0 && index <= _interned.length);
|
|
||||||
RInternedEntry entry = c11__getitem(RInternedEntry, &_r_interned, index - 1);
|
|
||||||
if(entry.ref == NULL){
|
|
||||||
entry.ref = PK_MALLOC(16); // ...
|
|
||||||
c11_sv sv;
|
|
||||||
sv.data = entry.data;
|
|
||||||
sv.size = entry.size;
|
|
||||||
py_newstrv(entry.ref, sv);
|
|
||||||
}
|
|
||||||
return entry.ref;
|
|
||||||
}
|
|
77
src/interpreter/name.c
Normal file
77
src/interpreter/name.c
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include "pocketpy/interpreter/name.h"
|
||||||
|
#include "pocketpy/interpreter/vm.h"
|
||||||
|
|
||||||
|
void InternedNames__ctor(InternedNames* self) {
|
||||||
|
c11_smallmap_s2n__ctor(&self->interned);
|
||||||
|
c11_vector__ctor(&self->r_interned, sizeof(RInternedEntry));
|
||||||
|
|
||||||
|
// initialize all magic names
|
||||||
|
#define MAGIC_METHOD(x) \
|
||||||
|
if(x != py_name(#x)) abort();
|
||||||
|
#include "pocketpy/xmacros/magics.h"
|
||||||
|
#undef MAGIC_METHOD
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternedNames__dtor(InternedNames* self) {
|
||||||
|
for(int i = 0; i < self->r_interned.length; i++) {
|
||||||
|
PK_FREE(c11__getitem(RInternedEntry, &self->r_interned, i).data);
|
||||||
|
}
|
||||||
|
c11_smallmap_s2n__dtor(&self->interned);
|
||||||
|
c11_vector__dtor(&self->r_interned);
|
||||||
|
}
|
||||||
|
|
||||||
|
py_Name py_name(const char* name) {
|
||||||
|
c11_sv sv;
|
||||||
|
sv.data = name;
|
||||||
|
sv.size = strlen(name);
|
||||||
|
return py_namev(sv);
|
||||||
|
}
|
||||||
|
|
||||||
|
py_Name py_namev(c11_sv name) {
|
||||||
|
InternedNames* self = &pk_current_vm->names;
|
||||||
|
uint16_t index = c11_smallmap_s2n__get(&self->interned, name, 0);
|
||||||
|
if(index != 0) return index;
|
||||||
|
// generate new index
|
||||||
|
if(self->interned.length > 65530) c11__abort("py_Name index overflow");
|
||||||
|
// NOTE: we must allocate the string in the heap so iterators are not invalidated
|
||||||
|
char* p = PK_MALLOC(name.size + 1);
|
||||||
|
memcpy(p, name.data, name.size);
|
||||||
|
p[name.size] = '\0';
|
||||||
|
RInternedEntry entry;
|
||||||
|
entry.data = p;
|
||||||
|
entry.size = name.size;
|
||||||
|
entry.obj.type = tp_nil;
|
||||||
|
c11_vector__push(RInternedEntry, &self->r_interned, entry);
|
||||||
|
index = self->r_interned.length; // 1-based
|
||||||
|
// save to _interned
|
||||||
|
c11_smallmap_s2n__set(&self->interned, (c11_sv){p, name.size}, index);
|
||||||
|
assert(self->interned.length == self->r_interned.length);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* py_name2str(py_Name index) {
|
||||||
|
InternedNames* self = &pk_current_vm->names;
|
||||||
|
assert(index > 0 && index <= self->interned.length);
|
||||||
|
return c11__getitem(RInternedEntry, &self->r_interned, index - 1).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
c11_sv py_name2sv(py_Name index) {
|
||||||
|
InternedNames* self = &pk_current_vm->names;
|
||||||
|
assert(index > 0 && index <= self->interned.length);
|
||||||
|
RInternedEntry entry = c11__getitem(RInternedEntry, &self->r_interned, index - 1);
|
||||||
|
return (c11_sv){entry.data, entry.size};
|
||||||
|
}
|
||||||
|
|
||||||
|
py_GlobalRef py_name2ref(py_Name index) {
|
||||||
|
InternedNames* self = &pk_current_vm->names;
|
||||||
|
assert(index > 0 && index <= self->interned.length);
|
||||||
|
RInternedEntry* entry = c11__at(RInternedEntry, &self->r_interned, index - 1);
|
||||||
|
if(entry->obj.type == tp_nil){
|
||||||
|
c11_sv sv;
|
||||||
|
sv.data = entry->data;
|
||||||
|
sv.size = entry->size;
|
||||||
|
py_newstrv(&entry->obj, sv);
|
||||||
|
}
|
||||||
|
return &entry->obj;
|
||||||
|
}
|
||||||
|
|
@ -57,6 +57,7 @@ static void py_TypeInfo__ctor(py_TypeInfo* self,
|
|||||||
|
|
||||||
void VM__ctor(VM* self) {
|
void VM__ctor(VM* self) {
|
||||||
self->top_frame = NULL;
|
self->top_frame = NULL;
|
||||||
|
InternedNames__ctor(&self->names);
|
||||||
|
|
||||||
ModuleDict__ctor(&self->modules, NULL, *py_NIL());
|
ModuleDict__ctor(&self->modules, NULL, *py_NIL());
|
||||||
TypeList__ctor(&self->types);
|
TypeList__ctor(&self->types);
|
||||||
@ -258,6 +259,7 @@ void VM__dtor(VM* self) {
|
|||||||
TypeList__dtor(&self->types);
|
TypeList__dtor(&self->types);
|
||||||
FixedMemoryPool__dtor(&self->pool_frame);
|
FixedMemoryPool__dtor(&self->pool_frame);
|
||||||
ValueStack__clear(&self->stack);
|
ValueStack__clear(&self->stack);
|
||||||
|
InternedNames__dtor(&self->names);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VM__push_frame(VM* self, Frame* frame) {
|
void VM__push_frame(VM* self, Frame* frame) {
|
||||||
@ -281,7 +283,11 @@ static void _clip_int(int* value, int min, int max) {
|
|||||||
if(*value > max) *value = max;
|
if(*value > max) *value = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pk__parse_int_slice(py_Ref slice, int length, int* restrict start, int* restrict stop, int* restrict step) {
|
bool pk__parse_int_slice(py_Ref slice,
|
||||||
|
int length,
|
||||||
|
int* restrict start,
|
||||||
|
int* restrict stop,
|
||||||
|
int* restrict step) {
|
||||||
if(py_isint(slice)) {
|
if(py_isint(slice)) {
|
||||||
int index = py_toint(slice);
|
int index = py_toint(slice);
|
||||||
bool ok = pk__normalize_index(&index, length);
|
bool ok = pk__normalize_index(&index, length);
|
||||||
@ -431,9 +437,8 @@ static bool
|
|||||||
co->name->data);
|
co->name->data);
|
||||||
} else {
|
} else {
|
||||||
// add to **kwargs
|
// add to **kwargs
|
||||||
bool ok = py_dict_setitem(&buffer[decl->starred_kwarg],
|
bool ok =
|
||||||
py_name2ref(key),
|
py_dict_setitem(&buffer[decl->starred_kwarg], py_name2ref(key), &p1[2 * j + 1]);
|
||||||
&p1[2 * j + 1]);
|
|
||||||
if(!ok) return false;
|
if(!ok) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -480,7 +485,8 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
|
|||||||
// submit the call
|
// submit the call
|
||||||
if(!fn->cfunc) {
|
if(!fn->cfunc) {
|
||||||
// python function
|
// python function
|
||||||
VM__push_frame(self, Frame__new(co, p0, fn->module, fn->globals, argv, true, false));
|
VM__push_frame(self,
|
||||||
|
Frame__new(co, p0, fn->module, fn->globals, argv, true, false));
|
||||||
return opcall ? RES_CALL : VM__run_top_frame(self);
|
return opcall ? RES_CALL : VM__run_top_frame(self);
|
||||||
} else {
|
} else {
|
||||||
// decl-based binding
|
// decl-based binding
|
||||||
@ -509,7 +515,8 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
|
|||||||
// submit the call
|
// submit the call
|
||||||
if(!fn->cfunc) {
|
if(!fn->cfunc) {
|
||||||
// python function
|
// python function
|
||||||
VM__push_frame(self, Frame__new(co, p0, fn->module, fn->globals, argv, true, false));
|
VM__push_frame(self,
|
||||||
|
Frame__new(co, p0, fn->module, fn->globals, argv, true, false));
|
||||||
return opcall ? RES_CALL : VM__run_top_frame(self);
|
return opcall ? RES_CALL : VM__run_top_frame(self);
|
||||||
} else {
|
} else {
|
||||||
// decl-based binding
|
// decl-based binding
|
||||||
@ -693,6 +700,11 @@ void ManagedHeap__mark(ManagedHeap* self) {
|
|||||||
for(int i = 0; i < c11__count_array(vm->reg); i++) {
|
for(int i = 0; i < c11__count_array(vm->reg); i++) {
|
||||||
pk__mark_value(&vm->reg[i]);
|
pk__mark_value(&vm->reg[i]);
|
||||||
}
|
}
|
||||||
|
// mark interned names
|
||||||
|
for(int i = 0; i < vm->names.r_interned.length; i++) {
|
||||||
|
RInternedEntry* entry = c11__at(RInternedEntry, &vm->names.r_interned, i);
|
||||||
|
pk__mark_value(&entry->obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pk_print_stack(VM* self, Frame* frame, Bytecode byte) {
|
void pk_print_stack(VM* self, Frame* frame, Bytecode byte) {
|
||||||
|
@ -27,8 +27,6 @@ void py_initialize() {
|
|||||||
static_assert(sizeof(py_TValue) == 16, "sizeof(py_TValue) != 16");
|
static_assert(sizeof(py_TValue) == 16, "sizeof(py_TValue) != 16");
|
||||||
static_assert(offsetof(py_TValue, extra) == 4, "offsetof(py_TValue, extra) != 4");
|
static_assert(offsetof(py_TValue, extra) == 4, "offsetof(py_TValue, extra) != 4");
|
||||||
|
|
||||||
py_Name__initialize();
|
|
||||||
|
|
||||||
pk_current_vm = pk_all_vm[0] = &pk_default_vm;
|
pk_current_vm = pk_all_vm[0] = &pk_default_vm;
|
||||||
|
|
||||||
// initialize some convenient references
|
// initialize some convenient references
|
||||||
@ -61,7 +59,6 @@ void py_finalize() {
|
|||||||
pk_current_vm = &pk_default_vm;
|
pk_current_vm = &pk_default_vm;
|
||||||
VM__dtor(&pk_default_vm);
|
VM__dtor(&pk_default_vm);
|
||||||
pk_current_vm = NULL;
|
pk_current_vm = NULL;
|
||||||
py_Name__finalize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void py_switchvm(int index) {
|
void py_switchvm(int index) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user