mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
remove vm
for Dict()
This commit is contained in:
parent
3a475a78b3
commit
2081dcf979
@ -52,12 +52,12 @@ static PyVar convert_cjson_to_list(const cJSON * const item, VM* vm){
|
||||
}
|
||||
|
||||
static PyVar convert_cjson_to_dict(const cJSON* const item, VM* vm){
|
||||
Dict output(vm);
|
||||
Dict output;
|
||||
cJSON *child = item->child;
|
||||
while(child != NULL){
|
||||
const char* key = child->string;
|
||||
const cJSON *child_value = cJSON_GetObjectItemCaseSensitive(item, key);
|
||||
output.set(VAR(key), convert_cjson_to_python_object(child_value, vm));
|
||||
output.set(vm, VAR(key), convert_cjson_to_python_object(child_value, vm));
|
||||
child = child->next;
|
||||
}
|
||||
return VAR(std::move(output));
|
||||
|
@ -23,7 +23,6 @@ struct Dict{
|
||||
static_assert(sizeof(Item) * __Capacity <= 128);
|
||||
static_assert(sizeof(ItemNode) * __Capacity <= 64);
|
||||
|
||||
VM* vm;
|
||||
int _capacity;
|
||||
int _mask;
|
||||
int _size;
|
||||
@ -33,7 +32,7 @@ struct Dict{
|
||||
Item* _items;
|
||||
ItemNode* _nodes; // for order preserving
|
||||
|
||||
Dict(VM* vm);
|
||||
Dict();
|
||||
Dict(Dict&& other);
|
||||
Dict(const Dict& other);
|
||||
Dict& operator=(const Dict&) = delete;
|
||||
@ -41,17 +40,17 @@ struct Dict{
|
||||
|
||||
int size() const { return _size; }
|
||||
|
||||
void _probe_0(PyVar key, bool& ok, int& i) const;
|
||||
void _probe_1(PyVar key, bool& ok, int& i) const;
|
||||
void _probe_0(VM* vm, PyVar key, bool& ok, int& i) const;
|
||||
void _probe_1(VM* vm, PyVar key, bool& ok, int& i) const;
|
||||
|
||||
void set(PyVar key, PyVar val);
|
||||
void _rehash();
|
||||
void set(VM* vm, PyVar key, PyVar val);
|
||||
void _rehash(VM* vm);
|
||||
|
||||
PyVar try_get(PyVar key) const;
|
||||
PyVar try_get(VM* vm, PyVar key) const;
|
||||
|
||||
bool contains(PyVar key) const;
|
||||
bool erase(PyVar key);
|
||||
void update(const Dict& other);
|
||||
bool contains(VM* vm, PyVar key) const;
|
||||
bool erase(VM* vm, PyVar key);
|
||||
void update(VM* vm, const Dict& other);
|
||||
|
||||
template<typename __Func>
|
||||
void apply(__Func f) const {
|
||||
|
@ -393,7 +393,7 @@ __NEXT_STEP:
|
||||
} DISPATCH()
|
||||
case OP_BUILD_DICT:{
|
||||
if(byte.arg == 0){
|
||||
PUSH(VAR(Dict(this)));
|
||||
PUSH(VAR(Dict()));
|
||||
DISPATCH()
|
||||
}
|
||||
PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list());
|
||||
@ -439,7 +439,7 @@ __NEXT_STEP:
|
||||
} DISPATCH()
|
||||
case OP_BUILD_DICT_UNPACK: {
|
||||
auto _lock = heap.gc_scope_lock();
|
||||
Dict dict(this);
|
||||
Dict dict;
|
||||
__unpack_as_dict(STACK_VIEW(byte.arg), dict);
|
||||
STACK_SHRINK(byte.arg);
|
||||
PyVar _0 = VAR(std::move(dict));
|
||||
@ -769,7 +769,7 @@ __NEXT_STEP:
|
||||
case OP_DICT_ADD: {
|
||||
PyVar _0 = POPX();
|
||||
const Tuple& t = PK_OBJ_GET(Tuple, _0);
|
||||
PK_OBJ_GET(Dict, SECOND()).set(t[0], t[1]);
|
||||
PK_OBJ_GET(Dict, SECOND()).set(this, t[0], t[1]);
|
||||
} DISPATCH()
|
||||
case OP_SET_ADD:{
|
||||
PyVar _0 = POPX();
|
||||
|
@ -80,9 +80,9 @@ __NEXT_LINE:
|
||||
if(row.size() != header.size()){
|
||||
vm->ValueError("row.size() != header.size()");
|
||||
}
|
||||
Dict row_dict(vm);
|
||||
Dict row_dict;
|
||||
for(int j=0; j<header.size(); j++){
|
||||
row_dict.set(header[j], row[j]);
|
||||
row_dict.set(vm, header[j], row[j]);
|
||||
}
|
||||
new_ret.push_back(VAR(std::move(row_dict)));
|
||||
}
|
||||
|
@ -105,9 +105,9 @@ void add_module_dataclasses(VM* vm){
|
||||
vm->bind_func(mod, "asdict", 1, [](VM* vm, ArgsView args){
|
||||
const auto& fields = vm->_tp_info(args[0])->annotated_fields;
|
||||
const NameDict& obj_d = args[0]->attr();
|
||||
Dict d(vm);
|
||||
Dict d;
|
||||
for(StrName field: fields){
|
||||
d.set(VAR(field.sv()), obj_d[field]);
|
||||
d.set(vm, VAR(field.sv()), obj_d[field]);
|
||||
}
|
||||
return VAR(std::move(d));
|
||||
});
|
||||
|
30
src/dict.cpp
30
src/dict.cpp
@ -2,7 +2,7 @@
|
||||
|
||||
namespace pkpy{
|
||||
|
||||
Dict::Dict(VM* vm): vm(vm), _capacity(__Capacity),
|
||||
Dict::Dict(): _capacity(__Capacity),
|
||||
_mask(__Capacity-1),
|
||||
_size(0), _critical_size(__Capacity*__LoadFactor+0.5f), _head_idx(-1), _tail_idx(-1){
|
||||
_items = (Item*)pool128_alloc(_capacity * sizeof(Item));
|
||||
@ -12,7 +12,6 @@ namespace pkpy{
|
||||
}
|
||||
|
||||
Dict::Dict(Dict&& other){
|
||||
vm = other.vm;
|
||||
_capacity = other._capacity;
|
||||
_mask = other._mask;
|
||||
_size = other._size;
|
||||
@ -26,7 +25,6 @@ namespace pkpy{
|
||||
}
|
||||
|
||||
Dict::Dict(const Dict& other){
|
||||
vm = other.vm;
|
||||
_capacity = other._capacity;
|
||||
_mask = other._mask;
|
||||
_size = other._size;
|
||||
@ -39,11 +37,11 @@ namespace pkpy{
|
||||
memcpy(_nodes, other._nodes, _capacity * sizeof(ItemNode));
|
||||
}
|
||||
|
||||
void Dict::set(PyVar key, PyVar val){
|
||||
void Dict::set(VM* vm, PyVar key, PyVar val){
|
||||
// do possible rehash
|
||||
if(_size+1 > _critical_size) _rehash();
|
||||
if(_size+1 > _critical_size) _rehash(vm);
|
||||
bool ok; int i;
|
||||
_probe_1(key, ok, i);
|
||||
_probe_1(vm, key, ok, i);
|
||||
if(!ok) {
|
||||
_size++;
|
||||
_items[i].first = key;
|
||||
@ -61,7 +59,7 @@ namespace pkpy{
|
||||
_items[i].second = val;
|
||||
}
|
||||
|
||||
void Dict::_rehash(){
|
||||
void Dict::_rehash(VM* vm){
|
||||
Item* old_items = _items;
|
||||
ItemNode* old_nodes = _nodes;
|
||||
int old_head_idx = _head_idx;
|
||||
@ -81,7 +79,7 @@ namespace pkpy{
|
||||
// copy old items to new dict
|
||||
int i = old_head_idx;
|
||||
while(i != -1){
|
||||
set(old_items[i].first, old_items[i].second);
|
||||
set(vm, old_items[i].first, old_items[i].second);
|
||||
i = old_nodes[i].next;
|
||||
}
|
||||
pool128_dealloc(old_items);
|
||||
@ -89,22 +87,22 @@ namespace pkpy{
|
||||
}
|
||||
|
||||
|
||||
PyVar Dict::try_get(PyVar key) const{
|
||||
PyVar Dict::try_get(VM* vm, PyVar key) const{
|
||||
bool ok; int i;
|
||||
_probe_0(key, ok, i);
|
||||
_probe_0(vm, key, ok, i);
|
||||
if(!ok) return nullptr;
|
||||
return _items[i].second;
|
||||
}
|
||||
|
||||
bool Dict::contains(PyVar key) const{
|
||||
bool Dict::contains(VM* vm, PyVar key) const{
|
||||
bool ok; int i;
|
||||
_probe_0(key, ok, i);
|
||||
_probe_0(vm, key, ok, i);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool Dict::erase(PyVar key){
|
||||
bool Dict::erase(VM* vm, PyVar key){
|
||||
bool ok; int i;
|
||||
_probe_0(key, ok, i);
|
||||
_probe_0(vm, key, ok, i);
|
||||
if(!ok) return false;
|
||||
_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
|
||||
@ -130,8 +128,8 @@ namespace pkpy{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Dict::update(const Dict& other){
|
||||
other.apply([&](PyVar k, PyVar v){ set(k, v); });
|
||||
void Dict::update(VM* vm, const Dict& other){
|
||||
other.apply([&](PyVar k, PyVar v){ set(vm, k, v); });
|
||||
}
|
||||
|
||||
Tuple Dict::keys() const{
|
||||
|
@ -1264,7 +1264,7 @@ void __init_builtins(VM* _vm) {
|
||||
// tp_dict
|
||||
_vm->bind_func(VM::tp_dict, __new__, -1, [](VM* vm, ArgsView args){
|
||||
Type cls_t = PK_OBJ_GET(Type, args[0]);
|
||||
return vm->new_object<Dict>(cls_t, vm);
|
||||
return vm->new_object<Dict>(cls_t);
|
||||
});
|
||||
|
||||
_vm->bind_func(VM::tp_dict, __init__, -1, [](VM* vm, ArgsView args){
|
||||
@ -1274,7 +1274,7 @@ void __init_builtins(VM* _vm) {
|
||||
Dict& self = PK_OBJ_GET(Dict, args[0]);
|
||||
if(is_type(args[1], vm->tp_dict)){
|
||||
Dict& other = CAST(Dict&, args[1]);
|
||||
self.update(other);
|
||||
self.update(vm, other);
|
||||
return vm->None;
|
||||
}
|
||||
if(is_type(args[1], vm->tp_list)){
|
||||
@ -1285,7 +1285,7 @@ void __init_builtins(VM* _vm) {
|
||||
vm->ValueError("dict() takes a list of tuples (key, value)");
|
||||
return vm->None;
|
||||
}
|
||||
self.set(t[0], t[1]);
|
||||
self.set(vm, t[0], t[1]);
|
||||
}
|
||||
return vm->None;
|
||||
}
|
||||
@ -1301,7 +1301,7 @@ void __init_builtins(VM* _vm) {
|
||||
|
||||
_vm->bind__getitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
|
||||
Dict& self = PK_OBJ_GET(Dict, _0);
|
||||
PyVar ret = self.try_get(_1);
|
||||
PyVar ret = self.try_get(vm, _1);
|
||||
if(ret == nullptr){
|
||||
// try __missing__
|
||||
PyVar self;
|
||||
@ -1316,12 +1316,12 @@ void __init_builtins(VM* _vm) {
|
||||
|
||||
_vm->bind__setitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1, PyVar _2) {
|
||||
Dict& self = _CAST(Dict&, _0);
|
||||
self.set(_1, _2);
|
||||
self.set(vm, _1, _2);
|
||||
});
|
||||
|
||||
_vm->bind__delitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
|
||||
Dict& self = _CAST(Dict&, _0);
|
||||
bool ok = self.erase(_1);
|
||||
bool ok = self.erase(vm, _1);
|
||||
if(!ok) vm->KeyError(_1);
|
||||
});
|
||||
|
||||
@ -1331,20 +1331,20 @@ void __init_builtins(VM* _vm) {
|
||||
return vm->None;
|
||||
}
|
||||
Dict& self = _CAST(Dict&, args[0]);
|
||||
PyVar value = self.try_get(args[1]);
|
||||
PyVar value = self.try_get(vm, args[1]);
|
||||
if(value == nullptr){
|
||||
if(args.size() == 2) vm->KeyError(args[1]);
|
||||
if(args.size() == 3){
|
||||
return args[2];
|
||||
}
|
||||
}
|
||||
self.erase(args[1]);
|
||||
self.erase(vm, args[1]);
|
||||
return value;
|
||||
});
|
||||
|
||||
_vm->bind__contains__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
|
||||
Dict& self = _CAST(Dict&, _0);
|
||||
return VAR(self.contains(_1));
|
||||
return VAR(self.contains(vm, _1));
|
||||
});
|
||||
|
||||
_vm->bind__iter__(VM::tp_dict, [](VM* vm, PyVar _0) {
|
||||
@ -1355,11 +1355,11 @@ void __init_builtins(VM* _vm) {
|
||||
_vm->bind_func(VM::tp_dict, "get", -1, [](VM* vm, ArgsView args) {
|
||||
Dict& self = _CAST(Dict&, args[0]);
|
||||
if(args.size() == 1+1){
|
||||
PyVar ret = self.try_get(args[1]);
|
||||
PyVar ret = self.try_get(vm, args[1]);
|
||||
if(ret != nullptr) return ret;
|
||||
return vm->None;
|
||||
}else if(args.size() == 1+2){
|
||||
PyVar ret = self.try_get(args[1]);
|
||||
PyVar ret = self.try_get(vm, args[1]);
|
||||
if(ret != nullptr) return ret;
|
||||
return args[2];
|
||||
}
|
||||
@ -1384,7 +1384,7 @@ void __init_builtins(VM* _vm) {
|
||||
_vm->bind_func(VM::tp_dict, "update", 2, [](VM* vm, ArgsView args) {
|
||||
Dict& self = _CAST(Dict&, args[0]);
|
||||
const Dict& other = CAST(Dict&, args[1]);
|
||||
self.update(other);
|
||||
self.update(vm, other);
|
||||
return vm->None;
|
||||
});
|
||||
|
||||
@ -1424,7 +1424,7 @@ void __init_builtins(VM* _vm) {
|
||||
for(int i=0; i<self._capacity; i++){
|
||||
auto item = self._items[i];
|
||||
if(item.first == nullptr) continue;
|
||||
PyVar value = other.try_get(item.first);
|
||||
PyVar value = other.try_get(vm, item.first);
|
||||
if(value == nullptr) return vm->False;
|
||||
if(!vm->py_eq(item.second, value)) return vm->False;
|
||||
}
|
||||
|
16
src/vm.cpp
16
src/vm.cpp
@ -566,14 +566,14 @@ PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar local
|
||||
if(globals_dict){
|
||||
globals_dict->clear();
|
||||
globals_obj->attr().apply([&](StrName k, PyVar v){
|
||||
globals_dict->set(VAR(k.sv()), v);
|
||||
globals_dict->set(vm, VAR(k.sv()), v);
|
||||
});
|
||||
}
|
||||
|
||||
if(locals_dict){
|
||||
locals_dict->clear();
|
||||
locals_closure->apply([&](StrName k, PyVar v){
|
||||
locals_dict->set(VAR(k.sv()), v);
|
||||
locals_dict->set(vm, VAR(k.sv()), v);
|
||||
});
|
||||
}
|
||||
return retval;
|
||||
@ -921,11 +921,11 @@ void VM::__unpack_as_dict(ArgsView args, Dict& dict){
|
||||
// maybe this check should be done in the compile time
|
||||
if(w.level != 2) TypeError("expected level 2 star wrapper");
|
||||
const Dict& other = CAST(Dict&, w.obj);
|
||||
dict.update(other);
|
||||
dict.update(this, other);
|
||||
}else{
|
||||
const Tuple& t = CAST(Tuple&, obj);
|
||||
if(t.size() != 2) TypeError("expected tuple of length 2");
|
||||
dict.set(t[0], t[1]);
|
||||
dict.set(this, t[0], t[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -966,7 +966,7 @@ void VM::__prepare_py_call(PyVar* buffer, ArgsView args, ArgsView kwargs, const
|
||||
|
||||
PyVar vkwargs;
|
||||
if(decl->starred_kwarg != -1){
|
||||
vkwargs = VAR(Dict(this));
|
||||
vkwargs = VAR(Dict());
|
||||
buffer[decl->starred_kwarg] = vkwargs;
|
||||
}else{
|
||||
vkwargs = nullptr;
|
||||
@ -984,7 +984,7 @@ void VM::__prepare_py_call(PyVar* buffer, ArgsView args, ArgsView kwargs, const
|
||||
TypeError(_S(key.escape(), " is an invalid keyword argument for ", co->name, "()"));
|
||||
}else{
|
||||
Dict& dict = _CAST(Dict&, vkwargs);
|
||||
dict.set(VAR(key.sv()), kwargs[j+1]);
|
||||
dict.set(this, VAR(key.sv()), kwargs[j+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1559,7 +1559,7 @@ void VM::bind__len__(Type type, i64 (*f)(VM*, PyVar)){
|
||||
#undef BIND_BINARY_SPECIAL
|
||||
|
||||
|
||||
void Dict::_probe_0(PyVar key, bool &ok, int &i) const{
|
||||
void Dict::_probe_0(VM* vm, PyVar key, bool &ok, int &i) const{
|
||||
ok = false;
|
||||
i64 hash = vm->py_hash(key);
|
||||
i = hash & _mask;
|
||||
@ -1574,7 +1574,7 @@ void Dict::_probe_0(PyVar key, bool &ok, int &i) const{
|
||||
}
|
||||
}
|
||||
|
||||
void Dict::_probe_1(PyVar key, bool &ok, int &i) const{
|
||||
void Dict::_probe_1(VM* vm, PyVar key, bool &ok, int &i) const{
|
||||
ok = false;
|
||||
i = vm->py_hash(key) & _mask;
|
||||
while(_items[i].first != nullptr) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user