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__lower_bound(T, ptr, count, key, less, out) \
|
||||
#define c11__lower_bound(T, ptr, count, key, less, out_index) \
|
||||
do { \
|
||||
T* __first = ptr; \
|
||||
int __len = count; \
|
||||
@ -22,7 +22,7 @@ extern "C" {
|
||||
__len = __l2; \
|
||||
} \
|
||||
} \
|
||||
*(out) = __first; \
|
||||
*(out_index) = __first - (T*)(ptr); \
|
||||
} while(0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "pocketpy/common/algorithm.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "pocketpy/common/algorithm.h"
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
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__dtor(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{
|
||||
void* data;
|
||||
@ -29,12 +31,12 @@ typedef struct c11_vector{
|
||||
void c11_vector__ctor(c11_vector* self, int elem_size);
|
||||
void c11_vector__dtor(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__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__at(T, self, index) ((T*)(self)->data + index)
|
||||
|
||||
#define c11_vector__push(T, self, elem) \
|
||||
do{ \
|
||||
@ -56,19 +58,19 @@ void c11_vector__clear(c11_vector* self);
|
||||
}while(0)
|
||||
|
||||
|
||||
#define c11_vector__insert(T, self, p, elem) \
|
||||
#define c11_vector__insert(T, self, index, elem) \
|
||||
do{ \
|
||||
if((self)->count == (self)->capacity) c11_vector__reserve((self), (self)->capacity*2); \
|
||||
int __n = (self)->count - (p - (T*)(self)->data); \
|
||||
memmove(p + 1, p, __n * sizeof(T)); \
|
||||
T* p = (T*)(self)->data + (index); \
|
||||
memmove(p + 1, p, ((self)->count - (index)) * sizeof(T)); \
|
||||
*p = (elem); \
|
||||
(self)->count++; \
|
||||
}while(0)
|
||||
|
||||
#define c11_vector__erase(T, self, p) \
|
||||
#define c11_vector__erase(T, self, index) \
|
||||
do{ \
|
||||
int __n = (self)->count - (p - (T*)(self)->data) - 1; \
|
||||
memmove(p, p + 1, __n * sizeof(T)); \
|
||||
T* p = (T*)(self)->data + (index); \
|
||||
memmove(p, p + 1, ((self)->count - (index) - 1) * sizeof(T)); \
|
||||
(self)->count--; \
|
||||
}while(0)
|
||||
|
||||
|
@ -189,7 +189,6 @@ public:
|
||||
PyObject* __last_exception;
|
||||
PyObject* __curr_class;
|
||||
PyVar __cached_object_new;
|
||||
small_map<std::string_view, CodeObject_> __cached_codes;
|
||||
small_map<std::string_view, PyVar> __cached_op_funcs;
|
||||
FuncDecl_ __dynamic_func_decl;
|
||||
PyVar __vectorcall_buffer[PK_MAX_CO_VARNAMES];
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "pocketpy/objects/tuplelist.hpp"
|
||||
#include "pocketpy/objects/namedict.hpp"
|
||||
#include "pocketpy/objects/sourcedata.hpp"
|
||||
#include "pocketpy/common/smallmap.h"
|
||||
|
||||
namespace pkpy {
|
||||
|
||||
@ -126,15 +127,22 @@ struct FuncDecl {
|
||||
const char* docstring; // docstring of this function (weak ref)
|
||||
|
||||
FuncType type = FuncType::UNSET;
|
||||
|
||||
small_map<StrName, int> kw_to_index;
|
||||
c11_smallmap_uint16_t_int kw_to_index;
|
||||
|
||||
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});
|
||||
}
|
||||
|
||||
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 {
|
||||
|
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){
|
||||
if(c == 0x1f955) return true;
|
||||
const int* p;
|
||||
c11__lower_bound(const int, kLoRangeA, 476, c, c11__less, &p);
|
||||
int index = p - kLoRangeA;
|
||||
int index;
|
||||
c11__lower_bound(const int, kLoRangeA, 476, c, c11__less, &index);
|
||||
if(c == kLoRangeA[index]) return true;
|
||||
index -= 1;
|
||||
if(index < 0) return false;
|
||||
|
@ -22,10 +22,6 @@ c11_array c11_array__copy(const c11_array* self){
|
||||
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){
|
||||
self->data = NULL;
|
||||
self->count = 0;
|
||||
@ -49,10 +45,6 @@ c11_vector c11_vector__copy(const c11_vector* self){
|
||||
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){
|
||||
if(capacity < 4) capacity = 4;
|
||||
if(capacity <= self->capacity) return;
|
||||
|
@ -789,14 +789,8 @@ PyVar VM::__run_top_frame() {
|
||||
case OP_FSTRING_EVAL: {
|
||||
PyVar _0 = frame->co->consts[byte.arg];
|
||||
std::string_view string = CAST(Str&, _0).sv();
|
||||
auto it = __cached_codes.try_get(string);
|
||||
CodeObject_ code;
|
||||
if(it == nullptr) {
|
||||
code = vm->compile(string, "<eval>", EVAL_MODE, true);
|
||||
__cached_codes.insert(string, code);
|
||||
} else {
|
||||
code = *it;
|
||||
}
|
||||
// TODO: optimize this
|
||||
CodeObject_ code = vm->compile(string, "<eval>", EVAL_MODE, true);
|
||||
_0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
|
||||
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) {
|
||||
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(index >= 0) {
|
||||
buffer[index] = kwargs[j + 1];
|
||||
@ -1865,8 +1865,6 @@ void ManagedHeap::mark() {
|
||||
vm->callstack.apply([this](Frame& frame) {
|
||||
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->__curr_class);
|
||||
vm->obj_gc_mark(vm->__c.error);
|
||||
|
@ -199,9 +199,9 @@ struct Random {
|
||||
List result(k);
|
||||
for(int i = 0; i < k; i++) {
|
||||
f64 key = self.gen.uniform(0.0, cum_weights[size - 1]);
|
||||
f64* p;
|
||||
c11__lower_bound(f64, cum_weights.begin(), cum_weights.size(), key, c11__less, &p);
|
||||
result[i] = data[p - cum_weights.begin()];
|
||||
int index;
|
||||
c11__lower_bound(f64, cum_weights.begin(), cum_weights.size(), key, c11__less, &index);
|
||||
result[i] = data[index];
|
||||
}
|
||||
return VAR(std::move(result));
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user