diff --git a/3rd/cjson/src/cJSONw.cpp b/3rd/cjson/src/cJSONw.cpp index 61657213..061d7f1c 100644 --- a/3rd/cjson/src/cJSONw.cpp +++ b/3rd/cjson/src/cJSONw.cpp @@ -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)); diff --git a/include/pocketpy/dict.h b/include/pocketpy/dict.h index 120e4cd3..46647722 100644 --- a/include/pocketpy/dict.h +++ b/include/pocketpy/dict.h @@ -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 void apply(__Func f) const { diff --git a/src/ceval.cpp b/src/ceval.cpp index d7ed2d4d..fb711af9 100644 --- a/src/ceval.cpp +++ b/src/ceval.cpp @@ -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(); diff --git a/src/csv.cpp b/src/csv.cpp index 68e44dca..e7f4c755 100644 --- a/src/csv.cpp +++ b/src/csv.cpp @@ -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; jbind_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)); }); diff --git a/src/dict.cpp b/src/dict.cpp index dbe63ce1..1e37632e 100644 --- a/src/dict.cpp +++ b/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{ diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index e590c29d..34607bcd 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -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(cls_t, vm); + return vm->new_object(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; iFalse; if(!vm->py_eq(item.second, value)) return vm->False; } diff --git a/src/vm.cpp b/src/vm.cpp index d8f51a26..2ad6034d 100644 --- a/src/vm.cpp +++ b/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) {