blueloveTH 2 tahun lalu
induk
melakukan
a5b7a0d1ae
4 mengubah file dengan 40 tambahan dan 17 penghapusan
  1. 24 1
      include/pocketpy/namedict.h
  2. 11 11
      src/ceval.cpp
  3. 1 1
      src/pocketpy.cpp
  4. 4 4
      src/vm.cpp

+ 24 - 1
include/pocketpy/namedict.h

@@ -184,6 +184,26 @@ while(!_items[i].first.empty()) {           \
         return &_items[i].second;
     }
 
+    T try_get_likely_found(StrName key) const{
+        uint16_t i = key.index & _mask;
+        if(_items[i].first == key) return _items[i].second;
+        i = (i + 1) & _mask;
+        if(_items[i].first == key) return _items[i].second;
+        i = (i + 1) & _mask;
+        if(_items[i].first == key) return _items[i].second;
+        return try_get(key);
+    }
+
+    T* try_get_2_likely_found(StrName key) {
+        uint16_t i = key.index & _mask;
+        if(_items[i].first == key) return &_items[i].second;
+        i = (i + 1) & _mask;
+        if(_items[i].first == key) return &_items[i].second;
+        i = (i + 1) & _mask;
+        if(_items[i].first == key) return &_items[i].second;
+        return try_get_2(key);
+    }
+
     bool contains(StrName key) const {
         bool ok; uint16_t i;
         HASH_PROBE_0(key, ok, i);
@@ -279,8 +299,11 @@ struct NameDictImpl{
     bool contains(StrName key) const { return is_small() ?_small.contains(key) : _large.contains(key); }
     bool del(StrName key){ return is_small() ?_small.del(key) : _large.del(key); }
 
+    V try_get_likely_found(StrName key) const { return is_small() ?_small.try_get(key) : _large.try_get_likely_found(key); }
+    V* try_get_2_likely_found(StrName key) { return is_small() ?_small.try_get_2(key) : _large.try_get_2_likely_found(key); }
+
     V operator[](StrName key) const {
-        V val = try_get(key);
+        V val = try_get_likely_found(key);
         if(val == default_invalid_value<V>()){
             throw std::runtime_error(fmt("NameDict key not found: ", key.escape()));
         }

+ 11 - 11
src/ceval.cpp

@@ -121,9 +121,9 @@ __NEXT_STEP:;
         }
         _0 = frame->f_closure_try_get(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
-        _0 = frame->f_globals().try_get(_name);
+        _0 = frame->f_globals().try_get_likely_found(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
-        _0 = vm->builtins->attr().try_get(_name);
+        _0 = vm->builtins->attr().try_get_likely_found(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
         vm->NameError(_name);
     } DISPATCH();
@@ -132,18 +132,18 @@ __NEXT_STEP:;
         _name = StrName(byte.arg);
         _0 = frame->f_closure_try_get(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
-        _0 = frame->f_globals().try_get(_name);
+        _0 = frame->f_globals().try_get_likely_found(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
-        _0 = vm->builtins->attr().try_get(_name);
+        _0 = vm->builtins->attr().try_get_likely_found(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
         vm->NameError(_name);
     } DISPATCH();
     TARGET(LOAD_GLOBAL)
         heap._auto_collect();
         _name = StrName(byte.arg);
-        _0 = frame->f_globals().try_get(_name);
+        _0 = frame->f_globals().try_get_likely_found(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
-        _0 = vm->builtins->attr().try_get(_name);
+        _0 = vm->builtins->attr().try_get_likely_found(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
         vm->NameError(_name);
         DISPATCH();
@@ -236,7 +236,7 @@ __NEXT_STEP:;
     /*****************************************/
     TARGET(BUILD_LONG) {
         PK_LOCAL_STATIC const StrName m_long("long");
-        _0 = builtins->attr().try_get(m_long);
+        _0 = builtins->attr().try_get_likely_found(m_long);
         if(_0 == nullptr) AttributeError(builtins, m_long);
         TOP() = call(_0, TOP());
     } DISPATCH();
@@ -493,7 +493,7 @@ __NEXT_STEP:;
         DISPATCH();
     TARGET(GOTO) {
         _name = StrName(byte.arg);
-        int index = co->labels.try_get(_name);
+        int index = co->labels.try_get_likely_found(_name);
         if(index < 0) _error("KeyError", fmt("label ", _name.escape(), " not found"));
         frame->jump_abs_break(index);
     } DISPATCH();
@@ -607,7 +607,7 @@ __NEXT_STEP:;
         if(_1 != nullptr){
             for(PyObject* key: CAST(List&, _1)){
                 _name = StrName::get(CAST(Str&, key).sv());
-                PyObject* value = _0->attr().try_get(_name);
+                PyObject* value = _0->attr().try_get_likely_found(_name);
                 if(value == nullptr){
                     ImportError(fmt("cannot import name ", _name.escape()));
                 }else{
@@ -716,13 +716,13 @@ __NEXT_STEP:;
     } DISPATCH();
     TARGET(INC_GLOBAL){
         _name = StrName(byte.arg);
-        PyObject** p = frame->f_globals().try_get_2(_name);
+        PyObject** p = frame->f_globals().try_get_2_likely_found(_name);
         if(p == nullptr) vm->NameError(_name);
         *p = VAR(CAST(i64, *p) + 1);
     } DISPATCH();
     TARGET(DEC_GLOBAL){
         _name = StrName(byte.arg);
-        PyObject** p = frame->f_globals().try_get_2(_name);
+        PyObject** p = frame->f_globals().try_get_2_likely_found(_name);
         if(p == nullptr) vm->NameError(_name);
         *p = VAR(CAST(i64, *p) - 1);
     } DISPATCH();

+ 1 - 1
src/pocketpy.cpp

@@ -123,7 +123,7 @@ void init_builtins(VM* _vm) {
         }else if(args.size() == 0){
             FrameId frame = vm->top_frame();
             if(frame->_callable != nullptr){
-                class_arg = frame->_callable->attr().try_get(__class__);
+                class_arg = frame->_callable->attr().try_get_likely_found(__class__);
                 if(frame->_locals.size() > 0) self_arg = frame->_locals[0];
             }
             if(class_arg == nullptr || self_arg == nullptr){

+ 4 - 4
src/vm.cpp

@@ -150,7 +150,7 @@ namespace pkpy{
     }
 
     PyObject* VM::_find_type_object(const Str& type){
-        PyObject* obj = builtins->attr().try_get(type);
+        PyObject* obj = builtins->attr().try_get_likely_found(type);
         if(obj == nullptr){
             for(auto& t: _all_types) if(t.name == type) return t.obj;
             throw std::runtime_error(fmt("type not found: ", type));
@@ -166,7 +166,7 @@ namespace pkpy{
     }
 
     PyTypeInfo* VM::_type_info(const Str& type){
-        PyObject* obj = builtins->attr().try_get(type);
+        PyObject* obj = builtins->attr().try_get_likely_found(type);
         if(obj == nullptr){
             for(auto& t: _all_types) if(t.name == type) return &t;
             FATAL_ERROR();
@@ -548,7 +548,7 @@ Str VM::disassemble(CodeObject_ co){
         }
         if(byte.op == OP_GOTO){
             // TODO: pre-compute jump targets for OP_GOTO
-            int* target = co->labels.try_get_2(StrName(byte.arg));
+            int* target = co->labels.try_get_2_likely_found(StrName(byte.arg));
             if(target != nullptr) jumpTargets.push_back(*target);
         }
     }
@@ -776,7 +776,7 @@ void VM::_prepare_py_call(PyObject** buffer, ArgsView args, ArgsView kwargs, con
 
     for(int j=0; j<kwargs.size(); j+=2){
         StrName key(CAST(int, kwargs[j]));
-        int index = co->varnames_inv.try_get(key);
+        int index = co->varnames_inv.try_get_likely_found(key);
         if(index < 0){
             if(vkwargs == nullptr){
                 TypeError(fmt(key.escape(), " is an invalid keyword argument for ", co->name, "()"));