mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
add smallmap
This commit is contained in:
parent
649fb3cd98
commit
2093f6f10f
@ -8,7 +8,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define c11__less(a, b) ((a) < (b))
|
#define c11__less(a, b) ((a) < (b))
|
||||||
|
|
||||||
#define c11__lower_bound(T, ptr, count, key, less, out) \
|
#define c11__lower_bound(T, ptr, count, key, less, out_index) \
|
||||||
do { \
|
do { \
|
||||||
T* __first = ptr; \
|
T* __first = ptr; \
|
||||||
int __len = count; \
|
int __len = count; \
|
||||||
@ -22,7 +22,7 @@ extern "C" {
|
|||||||
__len = __l2; \
|
__len = __l2; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
*(out) = __first; \
|
*(out_index) = __first - (T*)(ptr); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "pocketpy/common/algorithm.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "pocketpy/common/algorithm.h"
|
#include <stdbool.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -17,7 +20,6 @@ typedef struct c11_array{
|
|||||||
void c11_array__ctor(c11_array* self, int elem_size, int count);
|
void c11_array__ctor(c11_array* self, int elem_size, int count);
|
||||||
void c11_array__dtor(c11_array* self);
|
void c11_array__dtor(c11_array* self);
|
||||||
c11_array c11_array__copy(const c11_array* self);
|
c11_array c11_array__copy(const c11_array* self);
|
||||||
void* c11_array__at(c11_array* self, int index);
|
|
||||||
|
|
||||||
typedef struct c11_vector{
|
typedef struct c11_vector{
|
||||||
void* data;
|
void* data;
|
||||||
@ -29,12 +31,12 @@ typedef struct c11_vector{
|
|||||||
void c11_vector__ctor(c11_vector* self, int elem_size);
|
void c11_vector__ctor(c11_vector* self, int elem_size);
|
||||||
void c11_vector__dtor(c11_vector* self);
|
void c11_vector__dtor(c11_vector* self);
|
||||||
c11_vector c11_vector__copy(const c11_vector* self);
|
c11_vector c11_vector__copy(const c11_vector* self);
|
||||||
void* c11_vector__at(c11_vector* self, int index);
|
|
||||||
void c11_vector__reserve(c11_vector* self, int capacity);
|
void c11_vector__reserve(c11_vector* self, int capacity);
|
||||||
void c11_vector__clear(c11_vector* self);
|
void c11_vector__clear(c11_vector* self);
|
||||||
|
|
||||||
#define c11__getitem(T, self, index) ((T*)(self)->data)[index]
|
#define c11__getitem(T, self, index) (((T*)(self)->data)[index])
|
||||||
#define c11__setitem(T, self, index, value) ((T*)(self)->data)[index] = value;
|
#define c11__setitem(T, self, index, value) ((T*)(self)->data)[index] = value;
|
||||||
|
#define c11__at(T, self, index) ((T*)(self)->data + index)
|
||||||
|
|
||||||
#define c11_vector__push(T, self, elem) \
|
#define c11_vector__push(T, self, elem) \
|
||||||
do{ \
|
do{ \
|
||||||
@ -56,19 +58,19 @@ void c11_vector__clear(c11_vector* self);
|
|||||||
}while(0)
|
}while(0)
|
||||||
|
|
||||||
|
|
||||||
#define c11_vector__insert(T, self, p, elem) \
|
#define c11_vector__insert(T, self, index, elem) \
|
||||||
do{ \
|
do{ \
|
||||||
if((self)->count == (self)->capacity) c11_vector__reserve((self), (self)->capacity*2); \
|
if((self)->count == (self)->capacity) c11_vector__reserve((self), (self)->capacity*2); \
|
||||||
int __n = (self)->count - (p - (T*)(self)->data); \
|
T* p = (T*)(self)->data + (index); \
|
||||||
memmove(p + 1, p, __n * sizeof(T)); \
|
memmove(p + 1, p, ((self)->count - (index)) * sizeof(T)); \
|
||||||
*p = (elem); \
|
*p = (elem); \
|
||||||
(self)->count++; \
|
(self)->count++; \
|
||||||
}while(0)
|
}while(0)
|
||||||
|
|
||||||
#define c11_vector__erase(T, self, p) \
|
#define c11_vector__erase(T, self, index) \
|
||||||
do{ \
|
do{ \
|
||||||
int __n = (self)->count - (p - (T*)(self)->data) - 1; \
|
T* p = (T*)(self)->data + (index); \
|
||||||
memmove(p, p + 1, __n * sizeof(T)); \
|
memmove(p, p + 1, ((self)->count - (index) - 1) * sizeof(T)); \
|
||||||
(self)->count--; \
|
(self)->count--; \
|
||||||
}while(0)
|
}while(0)
|
||||||
|
|
||||||
|
@ -189,7 +189,6 @@ public:
|
|||||||
PyObject* __last_exception;
|
PyObject* __last_exception;
|
||||||
PyObject* __curr_class;
|
PyObject* __curr_class;
|
||||||
PyVar __cached_object_new;
|
PyVar __cached_object_new;
|
||||||
small_map<std::string_view, CodeObject_> __cached_codes;
|
|
||||||
small_map<std::string_view, PyVar> __cached_op_funcs;
|
small_map<std::string_view, PyVar> __cached_op_funcs;
|
||||||
FuncDecl_ __dynamic_func_decl;
|
FuncDecl_ __dynamic_func_decl;
|
||||||
PyVar __vectorcall_buffer[PK_MAX_CO_VARNAMES];
|
PyVar __vectorcall_buffer[PK_MAX_CO_VARNAMES];
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "pocketpy/objects/tuplelist.hpp"
|
#include "pocketpy/objects/tuplelist.hpp"
|
||||||
#include "pocketpy/objects/namedict.hpp"
|
#include "pocketpy/objects/namedict.hpp"
|
||||||
#include "pocketpy/objects/sourcedata.hpp"
|
#include "pocketpy/objects/sourcedata.hpp"
|
||||||
|
#include "pocketpy/common/smallmap.h"
|
||||||
|
|
||||||
namespace pkpy {
|
namespace pkpy {
|
||||||
|
|
||||||
@ -126,15 +127,22 @@ struct FuncDecl {
|
|||||||
const char* docstring; // docstring of this function (weak ref)
|
const char* docstring; // docstring of this function (weak ref)
|
||||||
|
|
||||||
FuncType type = FuncType::UNSET;
|
FuncType type = FuncType::UNSET;
|
||||||
|
c11_smallmap_uint16_t_int kw_to_index;
|
||||||
small_map<StrName, int> kw_to_index;
|
|
||||||
|
|
||||||
void add_kwarg(int index, StrName key, PyVar value) {
|
void add_kwarg(int index, StrName key, PyVar value) {
|
||||||
kw_to_index.insert(key, index);
|
c11_smallmap_uint16_t_int__set(&kw_to_index, key.index, index);
|
||||||
kwargs.push_back(KwArg{index, key, value});
|
kwargs.push_back(KwArg{index, key, value});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _gc_mark(VM*) const;
|
void _gc_mark(VM*) const;
|
||||||
|
|
||||||
|
FuncDecl(){
|
||||||
|
c11_smallmap_uint16_t_int__ctor(&kw_to_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
~FuncDecl(){
|
||||||
|
c11_smallmap_uint16_t_int__dtor(&kw_to_index);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NativeFunc {
|
struct NativeFunc {
|
||||||
|
108
include/pocketpy/xmacros/smallmap.h
Normal file
108
include/pocketpy/xmacros/smallmap.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(SMALLMAP_T__HEADER) && !defined(SMALLMAP_T__SOURCE)
|
||||||
|
#include "pocketpy/common/vector.h"
|
||||||
|
|
||||||
|
/* Input */
|
||||||
|
#define K int
|
||||||
|
#define V float
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Optional Input */
|
||||||
|
#ifndef less
|
||||||
|
#define less(a, b) ((a.key) < (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Temprary macros */
|
||||||
|
#define CONCAT(A, B) CONCAT_(A, B)
|
||||||
|
#define CONCAT_(A, B) A##B
|
||||||
|
|
||||||
|
#define KV CONCAT(CONCAT(c11_smallmap_entry_, K), CONCAT(_, V))
|
||||||
|
#define SMALLMAP CONCAT(CONCAT(c11_smallmap_, K), CONCAT(_, V))
|
||||||
|
#define SMALLMAP_METHOD(name) CONCAT(SMALLMAP, CONCAT(__, name))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
K key;
|
||||||
|
V value;
|
||||||
|
} KV;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
c11_vector entries;
|
||||||
|
} SMALLMAP;
|
||||||
|
|
||||||
|
void SMALLMAP_METHOD(ctor)(SMALLMAP* self);
|
||||||
|
void SMALLMAP_METHOD(dtor)(SMALLMAP* self);
|
||||||
|
void SMALLMAP_METHOD(set)(SMALLMAP* self, K key, V value);
|
||||||
|
V* SMALLMAP_METHOD(try_get)(SMALLMAP* self, K key);
|
||||||
|
V SMALLMAP_METHOD(get)(SMALLMAP* self, K key, V default_value);
|
||||||
|
bool SMALLMAP_METHOD(contains)(SMALLMAP* self, K key);
|
||||||
|
bool SMALLMAP_METHOD(del)(SMALLMAP* self, K key);
|
||||||
|
void SMALLMAP_METHOD(clear)(SMALLMAP* self);
|
||||||
|
|
||||||
|
#ifdef SMALLMAP_T__SOURCE
|
||||||
|
/* Implementation */
|
||||||
|
|
||||||
|
void SMALLMAP_METHOD(ctor)(SMALLMAP* self) {
|
||||||
|
c11_vector__ctor(&self->entries, sizeof(KV));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMALLMAP_METHOD(dtor)(SMALLMAP* self) {
|
||||||
|
c11_vector__dtor(&self->entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMALLMAP_METHOD(set)(SMALLMAP* self, K key, V value) {
|
||||||
|
int index;
|
||||||
|
c11__lower_bound(KV, self->entries.data, self->entries.count, key, less, &index);
|
||||||
|
KV* it = c11__at(KV, &self->entries, index);
|
||||||
|
if(index != self->entries.count && it->key == key) {
|
||||||
|
it->value = value;
|
||||||
|
} else {
|
||||||
|
KV kv = {key, value};
|
||||||
|
c11_vector__insert(KV, &self->entries, index, kv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
V* SMALLMAP_METHOD(try_get)(SMALLMAP* self, K key) {
|
||||||
|
int index;
|
||||||
|
c11__lower_bound(KV, self->entries.data, self->entries.count, key, less, &index);
|
||||||
|
KV* it = c11__at(KV, &self->entries, index);
|
||||||
|
if(index != self->entries.count && it->key == key) {
|
||||||
|
return &it->value;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
V SMALLMAP_METHOD(get)(SMALLMAP* self, K key, V default_value) {
|
||||||
|
V* p = SMALLMAP_METHOD(try_get)(self, key);
|
||||||
|
return p ? *p : default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMALLMAP_METHOD(contains)(SMALLMAP* self, K key) {
|
||||||
|
return SMALLMAP_METHOD(try_get)(self, key) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMALLMAP_METHOD(del)(SMALLMAP* self, K key) {
|
||||||
|
int index;
|
||||||
|
c11__lower_bound(KV, self->entries.data, self->entries.count, key, less, &index);
|
||||||
|
KV* it = c11__at(KV, &self->entries, index);
|
||||||
|
if(index != self->entries.count && it->key == key) {
|
||||||
|
c11_vector__erase(KV, &self->entries, index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMALLMAP_METHOD(clear)(SMALLMAP* self) {
|
||||||
|
c11_vector__clear(&self->entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef KV
|
||||||
|
#undef SMALLMAP
|
||||||
|
#undef SMALLMAP_METHOD
|
||||||
|
|
||||||
|
#undef K
|
||||||
|
#undef V
|
||||||
|
#undef less
|
8
src/common/smallmap.c
Normal file
8
src/common/smallmap.c
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "pocketpy/common/vector.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define SMALLMAP_T__SOURCE
|
||||||
|
#define K uint16_t
|
||||||
|
#define V int
|
||||||
|
#include "pocketpy/xmacros/smallmap.h"
|
||||||
|
#undef SMALLMAP_T__SOURCE
|
@ -386,9 +386,8 @@ static const int kLoRangeB[] = {170,186,443,451,660,1514,1522,1599,1610,1647,174
|
|||||||
|
|
||||||
bool c11__is_unicode_Lo_char(int c){
|
bool c11__is_unicode_Lo_char(int c){
|
||||||
if(c == 0x1f955) return true;
|
if(c == 0x1f955) return true;
|
||||||
const int* p;
|
int index;
|
||||||
c11__lower_bound(const int, kLoRangeA, 476, c, c11__less, &p);
|
c11__lower_bound(const int, kLoRangeA, 476, c, c11__less, &index);
|
||||||
int index = p - kLoRangeA;
|
|
||||||
if(c == kLoRangeA[index]) return true;
|
if(c == kLoRangeA[index]) return true;
|
||||||
index -= 1;
|
index -= 1;
|
||||||
if(index < 0) return false;
|
if(index < 0) return false;
|
||||||
|
@ -22,10 +22,6 @@ c11_array c11_array__copy(const c11_array* self){
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* c11_array__at(c11_array* self, int index){
|
|
||||||
return (char*)self->data + self->elem_size * index;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
self->count = 0;
|
self->count = 0;
|
||||||
@ -49,10 +45,6 @@ c11_vector c11_vector__copy(const c11_vector* self){
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* c11_vector__at(c11_vector* self, int index){
|
|
||||||
return (char*)self->data + self->elem_size * index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void c11_vector__reserve(c11_vector* self, int capacity){
|
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;
|
||||||
|
@ -789,14 +789,8 @@ PyVar VM::__run_top_frame() {
|
|||||||
case OP_FSTRING_EVAL: {
|
case OP_FSTRING_EVAL: {
|
||||||
PyVar _0 = frame->co->consts[byte.arg];
|
PyVar _0 = frame->co->consts[byte.arg];
|
||||||
std::string_view string = CAST(Str&, _0).sv();
|
std::string_view string = CAST(Str&, _0).sv();
|
||||||
auto it = __cached_codes.try_get(string);
|
// TODO: optimize this
|
||||||
CodeObject_ code;
|
CodeObject_ code = vm->compile(string, "<eval>", EVAL_MODE, true);
|
||||||
if(it == nullptr) {
|
|
||||||
code = vm->compile(string, "<eval>", EVAL_MODE, true);
|
|
||||||
__cached_codes.insert(string, code);
|
|
||||||
} else {
|
|
||||||
code = *it;
|
|
||||||
}
|
|
||||||
_0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
|
_0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
|
||||||
PUSH(_0);
|
PUSH(_0);
|
||||||
}
|
}
|
||||||
|
@ -1009,7 +1009,7 @@ void VM::__prepare_py_call(PyVar* buffer, ArgsView args, ArgsView kwargs, const
|
|||||||
|
|
||||||
for(int j = 0; j < kwargs.size(); j += 2) {
|
for(int j = 0; j < kwargs.size(); j += 2) {
|
||||||
StrName key(_CAST(uint16_t, kwargs[j]));
|
StrName key(_CAST(uint16_t, kwargs[j]));
|
||||||
int index = decl->kw_to_index.get(key, -1);
|
int index = c11_smallmap_uint16_t_int__get(&decl->kw_to_index, key.index, -1);
|
||||||
// if key is an explicit key, set as local variable
|
// if key is an explicit key, set as local variable
|
||||||
if(index >= 0) {
|
if(index >= 0) {
|
||||||
buffer[index] = kwargs[j + 1];
|
buffer[index] = kwargs[j + 1];
|
||||||
@ -1865,8 +1865,6 @@ void ManagedHeap::mark() {
|
|||||||
vm->callstack.apply([this](Frame& frame) {
|
vm->callstack.apply([this](Frame& frame) {
|
||||||
frame._gc_mark(vm);
|
frame._gc_mark(vm);
|
||||||
});
|
});
|
||||||
for(auto [_, co]: vm->__cached_codes)
|
|
||||||
co->_gc_mark(vm);
|
|
||||||
vm->obj_gc_mark(vm->__last_exception);
|
vm->obj_gc_mark(vm->__last_exception);
|
||||||
vm->obj_gc_mark(vm->__curr_class);
|
vm->obj_gc_mark(vm->__curr_class);
|
||||||
vm->obj_gc_mark(vm->__c.error);
|
vm->obj_gc_mark(vm->__c.error);
|
||||||
|
@ -199,9 +199,9 @@ struct Random {
|
|||||||
List result(k);
|
List result(k);
|
||||||
for(int i = 0; i < k; i++) {
|
for(int i = 0; i < k; i++) {
|
||||||
f64 key = self.gen.uniform(0.0, cum_weights[size - 1]);
|
f64 key = self.gen.uniform(0.0, cum_weights[size - 1]);
|
||||||
f64* p;
|
int index;
|
||||||
c11__lower_bound(f64, cum_weights.begin(), cum_weights.size(), key, c11__less, &p);
|
c11__lower_bound(f64, cum_weights.begin(), cum_weights.size(), key, c11__less, &index);
|
||||||
result[i] = data[p - cum_weights.begin()];
|
result[i] = data[index];
|
||||||
}
|
}
|
||||||
return VAR(std::move(result));
|
return VAR(std::move(result));
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user