mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
more fix...
This commit is contained in:
parent
7f3d89b264
commit
da62a1906b
@ -41,7 +41,8 @@ struct Dict{
|
|||||||
|
|
||||||
int size() const { return _size; }
|
int size() const { return _size; }
|
||||||
|
|
||||||
void _probe(PyObject* key, bool& ok, int& i) const;
|
void _probe_0(PyObject* key, bool& ok, int& i) const;
|
||||||
|
void _probe_1(PyObject* key, bool& ok, int& i) const;
|
||||||
|
|
||||||
void set(PyObject* key, PyObject* val);
|
void set(PyObject* key, PyObject* val);
|
||||||
void _rehash();
|
void _rehash();
|
||||||
|
@ -29,7 +29,7 @@ struct NameDictImpl {
|
|||||||
uint16_t _mask;
|
uint16_t _mask;
|
||||||
Item* _items;
|
Item* _items;
|
||||||
|
|
||||||
#define HASH_PROBE(key, ok, i) \
|
#define HASH_PROBE_0(key, ok, i) \
|
||||||
ok = false; \
|
ok = false; \
|
||||||
i = _hash(key, _mask, _hash_seed); \
|
i = _hash(key, _mask, _hash_seed); \
|
||||||
for(int _j=0; _j<_capacity; _j++) { \
|
for(int _j=0; _j<_capacity; _j++) { \
|
||||||
@ -41,6 +41,14 @@ for(int _j=0; _j<_capacity; _j++) { \
|
|||||||
i = (i + 1) & _mask; \
|
i = (i + 1) & _mask; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define HASH_PROBE_1(key, ok, i) \
|
||||||
|
ok = false; \
|
||||||
|
i = _hash(key, _mask, _hash_seed); \
|
||||||
|
while(!_items[i].first.empty()) { \
|
||||||
|
if(_items[i].first == (key)) { ok = true; break; } \
|
||||||
|
i = (i + 1) & _mask; \
|
||||||
|
}
|
||||||
|
|
||||||
#define NAMEDICT_ALLOC() \
|
#define NAMEDICT_ALLOC() \
|
||||||
_items = (Item*)pool128_alloc(_capacity * sizeof(Item)); \
|
_items = (Item*)pool128_alloc(_capacity * sizeof(Item)); \
|
||||||
memset(_items, 0, _capacity * sizeof(Item)); \
|
memset(_items, 0, _capacity * sizeof(Item)); \
|
||||||
@ -73,19 +81,19 @@ for(int _j=0; _j<_capacity; _j++) { \
|
|||||||
|
|
||||||
T operator[](StrName key) const {
|
T operator[](StrName key) const {
|
||||||
bool ok; uint16_t i;
|
bool ok; uint16_t i;
|
||||||
HASH_PROBE(key, ok, i);
|
HASH_PROBE_0(key, ok, i);
|
||||||
if(!ok) throw std::out_of_range(fmt("NameDict key not found: ", key));
|
if(!ok) throw std::out_of_range(fmt("NameDict key not found: ", key));
|
||||||
return _items[i].second;
|
return _items[i].second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(StrName key, T val){
|
void set(StrName key, T val){
|
||||||
bool ok; uint16_t i;
|
bool ok; uint16_t i;
|
||||||
HASH_PROBE(key, ok, i);
|
HASH_PROBE_1(key, ok, i);
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
_size++;
|
_size++;
|
||||||
if(_size > _capacity*_load_factor){
|
if(_size > _capacity*_load_factor){
|
||||||
_rehash(true);
|
_rehash(true);
|
||||||
HASH_PROBE(key, ok, i);
|
HASH_PROBE_1(key, ok, i);
|
||||||
}
|
}
|
||||||
_items[i].first = key;
|
_items[i].first = key;
|
||||||
}
|
}
|
||||||
@ -103,7 +111,7 @@ for(int _j=0; _j<_capacity; _j++) { \
|
|||||||
for(uint16_t i=0; i<old_capacity; i++){
|
for(uint16_t i=0; i<old_capacity; i++){
|
||||||
if(old_items[i].first.empty()) continue;
|
if(old_items[i].first.empty()) continue;
|
||||||
bool ok; uint16_t j;
|
bool ok; uint16_t j;
|
||||||
HASH_PROBE(old_items[i].first, ok, j);
|
HASH_PROBE_1(old_items[i].first, ok, j);
|
||||||
if(ok) FATAL_ERROR();
|
if(ok) FATAL_ERROR();
|
||||||
_items[j] = old_items[i];
|
_items[j] = old_items[i];
|
||||||
}
|
}
|
||||||
@ -117,7 +125,7 @@ for(int _j=0; _j<_capacity; _j++) { \
|
|||||||
|
|
||||||
T try_get(StrName key) const{
|
T try_get(StrName key) const{
|
||||||
bool ok; uint16_t i;
|
bool ok; uint16_t i;
|
||||||
HASH_PROBE(key, ok, i);
|
HASH_PROBE_0(key, ok, i);
|
||||||
if(!ok){
|
if(!ok){
|
||||||
if constexpr(std::is_pointer_v<T>) return nullptr;
|
if constexpr(std::is_pointer_v<T>) return nullptr;
|
||||||
else if constexpr(std::is_same_v<int, T>) return -1;
|
else if constexpr(std::is_same_v<int, T>) return -1;
|
||||||
@ -128,14 +136,14 @@ for(int _j=0; _j<_capacity; _j++) { \
|
|||||||
|
|
||||||
T* try_get_2(StrName key) {
|
T* try_get_2(StrName key) {
|
||||||
bool ok; uint16_t i;
|
bool ok; uint16_t i;
|
||||||
HASH_PROBE(key, ok, i);
|
HASH_PROBE_0(key, ok, i);
|
||||||
if(!ok) return nullptr;
|
if(!ok) return nullptr;
|
||||||
return &_items[i].second;
|
return &_items[i].second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool try_set(StrName key, T val){
|
bool try_set(StrName key, T val){
|
||||||
bool ok; uint16_t i;
|
bool ok; uint16_t i;
|
||||||
HASH_PROBE(key, ok, i);
|
HASH_PROBE_1(key, ok, i);
|
||||||
if(!ok) return false;
|
if(!ok) return false;
|
||||||
_items[i].second = val;
|
_items[i].second = val;
|
||||||
return true;
|
return true;
|
||||||
@ -143,7 +151,7 @@ for(int _j=0; _j<_capacity; _j++) { \
|
|||||||
|
|
||||||
bool contains(StrName key) const {
|
bool contains(StrName key) const {
|
||||||
bool ok; uint16_t i;
|
bool ok; uint16_t i;
|
||||||
HASH_PROBE(key, ok, i);
|
HASH_PROBE_0(key, ok, i);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +164,7 @@ for(int _j=0; _j<_capacity; _j++) { \
|
|||||||
|
|
||||||
void erase(StrName key){
|
void erase(StrName key){
|
||||||
bool ok; uint16_t i;
|
bool ok; uint16_t i;
|
||||||
HASH_PROBE(key, ok, i);
|
HASH_PROBE_0(key, ok, i);
|
||||||
if(!ok) throw std::out_of_range(fmt("NameDict key not found: ", key));
|
if(!ok) throw std::out_of_range(fmt("NameDict key not found: ", key));
|
||||||
_items[i].first = StrName();
|
_items[i].first = StrName();
|
||||||
// _items[i].second = PY_DELETED_SLOT; // do not change .second if it is not zero, it means the slot is occupied by a deleted item
|
// _items[i].second = PY_DELETED_SLOT; // do not change .second if it is not zero, it means the slot is occupied by a deleted item
|
||||||
|
@ -43,7 +43,7 @@ namespace pkpy{
|
|||||||
// do possible rehash
|
// do possible rehash
|
||||||
if(_size+1 > _critical_size) _rehash();
|
if(_size+1 > _critical_size) _rehash();
|
||||||
bool ok; int i;
|
bool ok; int i;
|
||||||
_probe(key, ok, i);
|
_probe_1(key, ok, i);
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
_size++;
|
_size++;
|
||||||
_items[i].first = key;
|
_items[i].first = key;
|
||||||
@ -91,20 +91,20 @@ namespace pkpy{
|
|||||||
|
|
||||||
PyObject* Dict::try_get(PyObject* key) const{
|
PyObject* Dict::try_get(PyObject* key) const{
|
||||||
bool ok; int i;
|
bool ok; int i;
|
||||||
_probe(key, ok, i);
|
_probe_0(key, ok, i);
|
||||||
if(!ok) return nullptr;
|
if(!ok) return nullptr;
|
||||||
return _items[i].second;
|
return _items[i].second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dict::contains(PyObject* key) const{
|
bool Dict::contains(PyObject* key) const{
|
||||||
bool ok; int i;
|
bool ok; int i;
|
||||||
_probe(key, ok, i);
|
_probe_0(key, ok, i);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dict::erase(PyObject* key){
|
bool Dict::erase(PyObject* key){
|
||||||
bool ok; int i;
|
bool ok; int i;
|
||||||
_probe(key, ok, i);
|
_probe_0(key, ok, i);
|
||||||
if(!ok) return false;
|
if(!ok) return false;
|
||||||
_items[i].first = nullptr;
|
_items[i].first = nullptr;
|
||||||
// _items[i].second = PY_DELETED_SLOT; // do not change .second if it is not NULL, it means the slot is occupied by a deleted item
|
// _items[i].second = PY_DELETED_SLOT; // do not change .second if it is not NULL, it means the slot is occupied by a deleted item
|
||||||
|
12
src/vm.cpp
12
src/vm.cpp
@ -1031,7 +1031,7 @@ void VM::bind__len__(Type type, i64 (*f)(VM*, PyObject*)){
|
|||||||
PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
|
PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dict::_probe(PyObject *key, bool &ok, int &i) const{
|
void Dict::_probe_0(PyObject *key, bool &ok, int &i) const{
|
||||||
ok = false;
|
ok = false;
|
||||||
i64 hash = vm->py_hash(key);
|
i64 hash = vm->py_hash(key);
|
||||||
i = hash & _mask;
|
i = hash & _mask;
|
||||||
@ -1048,6 +1048,16 @@ void Dict::_probe(PyObject *key, bool &ok, int &i) const{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Dict::_probe_1(PyObject *key, bool &ok, int &i) const{
|
||||||
|
ok = false;
|
||||||
|
i = vm->py_hash(key) & _mask;
|
||||||
|
while(_items[i].first != nullptr) {
|
||||||
|
if(vm->py_equals(_items[i].first, key)) { ok = true; break; }
|
||||||
|
// https://github.com/python/cpython/blob/3.8/Objects/dictobject.c#L166
|
||||||
|
i = ((5*i) + 1) & _mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CodeObjectSerializer::write_object(VM *vm, PyObject *obj){
|
void CodeObjectSerializer::write_object(VM *vm, PyObject *obj){
|
||||||
if(is_int(obj)) write_int(_CAST(i64, obj));
|
if(is_int(obj)) write_int(_CAST(i64, obj));
|
||||||
else if(is_float(obj)) write_float(_CAST(f64, obj));
|
else if(is_float(obj)) write_float(_CAST(f64, obj));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user