remove vm for Dict()

This commit is contained in:
blueloveTH 2024-05-19 19:54:36 +08:00
parent 3a475a78b3
commit 2081dcf979
8 changed files with 53 additions and 56 deletions

View File

@ -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){ static PyVar convert_cjson_to_dict(const cJSON* const item, VM* vm){
Dict output(vm); Dict output;
cJSON *child = item->child; cJSON *child = item->child;
while(child != NULL){ while(child != NULL){
const char* key = child->string; const char* key = child->string;
const cJSON *child_value = cJSON_GetObjectItemCaseSensitive(item, key); 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; child = child->next;
} }
return VAR(std::move(output)); return VAR(std::move(output));

View File

@ -23,7 +23,6 @@ struct Dict{
static_assert(sizeof(Item) * __Capacity <= 128); static_assert(sizeof(Item) * __Capacity <= 128);
static_assert(sizeof(ItemNode) * __Capacity <= 64); static_assert(sizeof(ItemNode) * __Capacity <= 64);
VM* vm;
int _capacity; int _capacity;
int _mask; int _mask;
int _size; int _size;
@ -33,7 +32,7 @@ struct Dict{
Item* _items; Item* _items;
ItemNode* _nodes; // for order preserving ItemNode* _nodes; // for order preserving
Dict(VM* vm); Dict();
Dict(Dict&& other); Dict(Dict&& other);
Dict(const Dict& other); Dict(const Dict& other);
Dict& operator=(const Dict&) = delete; Dict& operator=(const Dict&) = delete;
@ -41,17 +40,17 @@ struct Dict{
int size() const { return _size; } int size() const { return _size; }
void _probe_0(PyVar key, bool& ok, int& i) const; void _probe_0(VM* vm, PyVar key, bool& ok, int& i) const;
void _probe_1(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 set(VM* vm, PyVar key, PyVar val);
void _rehash(); void _rehash(VM* vm);
PyVar try_get(PyVar key) const; PyVar try_get(VM* vm, PyVar key) const;
bool contains(PyVar key) const; bool contains(VM* vm, PyVar key) const;
bool erase(PyVar key); bool erase(VM* vm, PyVar key);
void update(const Dict& other); void update(VM* vm, const Dict& other);
template<typename __Func> template<typename __Func>
void apply(__Func f) const { void apply(__Func f) const {

View File

@ -393,7 +393,7 @@ __NEXT_STEP:
} DISPATCH() } DISPATCH()
case OP_BUILD_DICT:{ case OP_BUILD_DICT:{
if(byte.arg == 0){ if(byte.arg == 0){
PUSH(VAR(Dict(this))); PUSH(VAR(Dict()));
DISPATCH() DISPATCH()
} }
PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list()); PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list());
@ -439,7 +439,7 @@ __NEXT_STEP:
} DISPATCH() } DISPATCH()
case OP_BUILD_DICT_UNPACK: { case OP_BUILD_DICT_UNPACK: {
auto _lock = heap.gc_scope_lock(); auto _lock = heap.gc_scope_lock();
Dict dict(this); Dict dict;
__unpack_as_dict(STACK_VIEW(byte.arg), dict); __unpack_as_dict(STACK_VIEW(byte.arg), dict);
STACK_SHRINK(byte.arg); STACK_SHRINK(byte.arg);
PyVar _0 = VAR(std::move(dict)); PyVar _0 = VAR(std::move(dict));
@ -769,7 +769,7 @@ __NEXT_STEP:
case OP_DICT_ADD: { case OP_DICT_ADD: {
PyVar _0 = POPX(); PyVar _0 = POPX();
const Tuple& t = PK_OBJ_GET(Tuple, _0); 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() } DISPATCH()
case OP_SET_ADD:{ case OP_SET_ADD:{
PyVar _0 = POPX(); PyVar _0 = POPX();

View File

@ -80,9 +80,9 @@ __NEXT_LINE:
if(row.size() != header.size()){ if(row.size() != header.size()){
vm->ValueError("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++){ 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))); new_ret.push_back(VAR(std::move(row_dict)));
} }

View File

@ -105,9 +105,9 @@ void add_module_dataclasses(VM* vm){
vm->bind_func(mod, "asdict", 1, [](VM* vm, ArgsView args){ vm->bind_func(mod, "asdict", 1, [](VM* vm, ArgsView args){
const auto& fields = vm->_tp_info(args[0])->annotated_fields; const auto& fields = vm->_tp_info(args[0])->annotated_fields;
const NameDict& obj_d = args[0]->attr(); const NameDict& obj_d = args[0]->attr();
Dict d(vm); Dict d;
for(StrName field: fields){ 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)); return VAR(std::move(d));
}); });

View File

@ -2,7 +2,7 @@
namespace pkpy{ namespace pkpy{
Dict::Dict(VM* vm): vm(vm), _capacity(__Capacity), Dict::Dict(): _capacity(__Capacity),
_mask(__Capacity-1), _mask(__Capacity-1),
_size(0), _critical_size(__Capacity*__LoadFactor+0.5f), _head_idx(-1), _tail_idx(-1){ _size(0), _critical_size(__Capacity*__LoadFactor+0.5f), _head_idx(-1), _tail_idx(-1){
_items = (Item*)pool128_alloc(_capacity * sizeof(Item)); _items = (Item*)pool128_alloc(_capacity * sizeof(Item));
@ -12,7 +12,6 @@ namespace pkpy{
} }
Dict::Dict(Dict&& other){ Dict::Dict(Dict&& other){
vm = other.vm;
_capacity = other._capacity; _capacity = other._capacity;
_mask = other._mask; _mask = other._mask;
_size = other._size; _size = other._size;
@ -26,7 +25,6 @@ namespace pkpy{
} }
Dict::Dict(const Dict& other){ Dict::Dict(const Dict& other){
vm = other.vm;
_capacity = other._capacity; _capacity = other._capacity;
_mask = other._mask; _mask = other._mask;
_size = other._size; _size = other._size;
@ -39,11 +37,11 @@ namespace pkpy{
memcpy(_nodes, other._nodes, _capacity * sizeof(ItemNode)); 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 // do possible rehash
if(_size+1 > _critical_size) _rehash(); if(_size+1 > _critical_size) _rehash(vm);
bool ok; int i; bool ok; int i;
_probe_1(key, ok, i); _probe_1(vm, key, ok, i);
if(!ok) { if(!ok) {
_size++; _size++;
_items[i].first = key; _items[i].first = key;
@ -61,7 +59,7 @@ namespace pkpy{
_items[i].second = val; _items[i].second = val;
} }
void Dict::_rehash(){ void Dict::_rehash(VM* vm){
Item* old_items = _items; Item* old_items = _items;
ItemNode* old_nodes = _nodes; ItemNode* old_nodes = _nodes;
int old_head_idx = _head_idx; int old_head_idx = _head_idx;
@ -81,7 +79,7 @@ namespace pkpy{
// copy old items to new dict // copy old items to new dict
int i = old_head_idx; int i = old_head_idx;
while(i != -1){ 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; i = old_nodes[i].next;
} }
pool128_dealloc(old_items); 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; bool ok; int i;
_probe_0(key, ok, i); _probe_0(vm, key, ok, i);
if(!ok) return nullptr; if(!ok) return nullptr;
return _items[i].second; return _items[i].second;
} }
bool Dict::contains(PyVar key) const{ bool Dict::contains(VM* vm, PyVar key) const{
bool ok; int i; bool ok; int i;
_probe_0(key, ok, i); _probe_0(vm, key, ok, i);
return ok; return ok;
} }
bool Dict::erase(PyVar key){ bool Dict::erase(VM* vm, PyVar key){
bool ok; int i; bool ok; int i;
_probe_0(key, ok, i); _probe_0(vm, 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
@ -130,8 +128,8 @@ namespace pkpy{
return true; return true;
} }
void Dict::update(const Dict& other){ void Dict::update(VM* vm, const Dict& other){
other.apply([&](PyVar k, PyVar v){ set(k, v); }); other.apply([&](PyVar k, PyVar v){ set(vm, k, v); });
} }
Tuple Dict::keys() const{ Tuple Dict::keys() const{

View File

@ -1264,7 +1264,7 @@ void __init_builtins(VM* _vm) {
// tp_dict // tp_dict
_vm->bind_func(VM::tp_dict, __new__, -1, [](VM* vm, ArgsView args){ _vm->bind_func(VM::tp_dict, __new__, -1, [](VM* vm, ArgsView args){
Type cls_t = PK_OBJ_GET(Type, args[0]); 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){ _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]); Dict& self = PK_OBJ_GET(Dict, args[0]);
if(is_type(args[1], vm->tp_dict)){ if(is_type(args[1], vm->tp_dict)){
Dict& other = CAST(Dict&, args[1]); Dict& other = CAST(Dict&, args[1]);
self.update(other); self.update(vm, other);
return vm->None; return vm->None;
} }
if(is_type(args[1], vm->tp_list)){ 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)"); vm->ValueError("dict() takes a list of tuples (key, value)");
return vm->None; return vm->None;
} }
self.set(t[0], t[1]); self.set(vm, t[0], t[1]);
} }
return vm->None; return vm->None;
} }
@ -1301,7 +1301,7 @@ void __init_builtins(VM* _vm) {
_vm->bind__getitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) { _vm->bind__getitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
Dict& self = PK_OBJ_GET(Dict, _0); Dict& self = PK_OBJ_GET(Dict, _0);
PyVar ret = self.try_get(_1); PyVar ret = self.try_get(vm, _1);
if(ret == nullptr){ if(ret == nullptr){
// try __missing__ // try __missing__
PyVar self; 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) { _vm->bind__setitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1, PyVar _2) {
Dict& self = _CAST(Dict&, _0); 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) { _vm->bind__delitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
Dict& self = _CAST(Dict&, _0); Dict& self = _CAST(Dict&, _0);
bool ok = self.erase(_1); bool ok = self.erase(vm, _1);
if(!ok) vm->KeyError(_1); if(!ok) vm->KeyError(_1);
}); });
@ -1331,20 +1331,20 @@ void __init_builtins(VM* _vm) {
return vm->None; return vm->None;
} }
Dict& self = _CAST(Dict&, args[0]); 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(value == nullptr){
if(args.size() == 2) vm->KeyError(args[1]); if(args.size() == 2) vm->KeyError(args[1]);
if(args.size() == 3){ if(args.size() == 3){
return args[2]; return args[2];
} }
} }
self.erase(args[1]); self.erase(vm, args[1]);
return value; return value;
}); });
_vm->bind__contains__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) { _vm->bind__contains__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
Dict& self = _CAST(Dict&, _0); 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) { _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) { _vm->bind_func(VM::tp_dict, "get", -1, [](VM* vm, ArgsView args) {
Dict& self = _CAST(Dict&, args[0]); Dict& self = _CAST(Dict&, args[0]);
if(args.size() == 1+1){ 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; if(ret != nullptr) return ret;
return vm->None; return vm->None;
}else if(args.size() == 1+2){ }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; if(ret != nullptr) return ret;
return args[2]; return args[2];
} }
@ -1384,7 +1384,7 @@ void __init_builtins(VM* _vm) {
_vm->bind_func(VM::tp_dict, "update", 2, [](VM* vm, ArgsView args) { _vm->bind_func(VM::tp_dict, "update", 2, [](VM* vm, ArgsView args) {
Dict& self = _CAST(Dict&, args[0]); Dict& self = _CAST(Dict&, args[0]);
const Dict& other = CAST(Dict&, args[1]); const Dict& other = CAST(Dict&, args[1]);
self.update(other); self.update(vm, other);
return vm->None; return vm->None;
}); });
@ -1424,7 +1424,7 @@ void __init_builtins(VM* _vm) {
for(int i=0; i<self._capacity; i++){ for(int i=0; i<self._capacity; i++){
auto item = self._items[i]; auto item = self._items[i];
if(item.first == nullptr) continue; 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(value == nullptr) return vm->False;
if(!vm->py_eq(item.second, value)) return vm->False; if(!vm->py_eq(item.second, value)) return vm->False;
} }

View File

@ -566,14 +566,14 @@ PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar local
if(globals_dict){ if(globals_dict){
globals_dict->clear(); globals_dict->clear();
globals_obj->attr().apply([&](StrName k, PyVar v){ 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){ if(locals_dict){
locals_dict->clear(); locals_dict->clear();
locals_closure->apply([&](StrName k, PyVar v){ locals_closure->apply([&](StrName k, PyVar v){
locals_dict->set(VAR(k.sv()), v); locals_dict->set(vm, VAR(k.sv()), v);
}); });
} }
return retval; 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 // maybe this check should be done in the compile time
if(w.level != 2) TypeError("expected level 2 star wrapper"); if(w.level != 2) TypeError("expected level 2 star wrapper");
const Dict& other = CAST(Dict&, w.obj); const Dict& other = CAST(Dict&, w.obj);
dict.update(other); dict.update(this, other);
}else{ }else{
const Tuple& t = CAST(Tuple&, obj); const Tuple& t = CAST(Tuple&, obj);
if(t.size() != 2) TypeError("expected tuple of length 2"); 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; PyVar vkwargs;
if(decl->starred_kwarg != -1){ if(decl->starred_kwarg != -1){
vkwargs = VAR(Dict(this)); vkwargs = VAR(Dict());
buffer[decl->starred_kwarg] = vkwargs; buffer[decl->starred_kwarg] = vkwargs;
}else{ }else{
vkwargs = nullptr; 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, "()")); TypeError(_S(key.escape(), " is an invalid keyword argument for ", co->name, "()"));
}else{ }else{
Dict& dict = _CAST(Dict&, vkwargs); 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 #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; ok = false;
i64 hash = vm->py_hash(key); i64 hash = vm->py_hash(key);
i = hash & _mask; 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; ok = false;
i = vm->py_hash(key) & _mask; i = vm->py_hash(key) & _mask;
while(_items[i].first != nullptr) { while(_items[i].first != nullptr) {