Exemplo n.º 1
0
    def create_lowlevel_type(self):
        entry_methods = {
            "valid": LLOrderedDict.ll_valid_from_flag,
            "everused": LLOrderedDict.ll_everused_from_flag,
            "mark_deleted": LLOrderedDict.ll_mark_deleted_in_flag,
            "must_clear_key": self._must_clear(self.key_repr.lowleveltype),
            "must_clear_value": self._must_clear(self.value_repr.lowleveltype),
        }
        fields = [
            ("key", self.key_repr.lowleveltype),
            ("value", self.value_repr.lowleveltype),
            ("next", lltype.Signed),
            ("prev", lltype.Signed),
            ("everused", lltype.Bool),
            ("valid", lltype.Bool),
        ]
        fast_hash_func = None
        if not self.hash_func_repr:
            fast_hash_func = self.key_repr.get_ll_hash_function()
        if fast_hash_func is None:
            fields.append(("hash", lltype.Signed))
            entry_methods["hash"] = LLOrderedDict.ll_hash_from_cache
        else:
            entry_methods["hash"] = LLOrderedDict.ll_hash_recompute
            entry_methods["fast_hash_func"] = fast_hash_func
        DICTENTRY = lltype.Struct("ORDEREDDICTENTRY", *fields)

        fields = [
            ("num_items", lltype.Signed),
            ("resize_counter", lltype.Signed),
            ("first_entry", lltype.Signed),
            ("last_entry", lltype.Signed),
            ("entries",
             lltype.Ptr(lltype.GcArray(DICTENTRY, adtmeths=entry_methods))),
        ]
        dict_methods = {}
        if self.eq_func_repr and self.hash_func_repr:
            dict_methods["paranoia"] = True
            dict_methods["hashkey"] = LLOrderedDict.ll_hashkey_custom
            dict_methods["keyeq"] = LLOrderedDict.ll_keyeq_custom

            dict_methods["r_hashkey"] = self.hash_func_repr
            dict_methods["r_keyeq"] = self.eq_func_repr

            fields.append(("hashkey_func", self.hash_func_repr.lowleveltype))
            fields.append(("keyeq_func", self.eq_func_repr.lowleveltype))
        else:
            dict_methods["paranoia"] = False
            dict_methods["hashkey"] = lltype.staticAdtMethod(
                self.key_repr.get_ll_hash_function())
            ll_keyeq = self.key_repr.get_ll_eq_function()
            if ll_keyeq is not None:
                ll_keyeq = lltype.staticAdtMethod(ll_keyeq)
            dict_methods["keyeq"] = ll_keyeq

        DICT = lltype.GcStruct("ORDEREDDICT", *fields, adtmeths=dict_methods)
        return lltype.Ptr(DICT)
Exemplo n.º 2
0
    def create_lowlevel_type(self):
        entry_methods = {
            "valid": LLOrderedDict.ll_valid_from_flag,
            "everused": LLOrderedDict.ll_everused_from_flag,
            "mark_deleted": LLOrderedDict.ll_mark_deleted_in_flag,
            "must_clear_key": self._must_clear(self.key_repr.lowleveltype),
            "must_clear_value": self._must_clear(self.value_repr.lowleveltype),
        }
        fields = [
            ("key", self.key_repr.lowleveltype),
            ("value", self.value_repr.lowleveltype),
            ("next", lltype.Signed),
            ("prev", lltype.Signed),
            ("everused", lltype.Bool),
            ("valid", lltype.Bool),
        ]
        fast_hash_func = None
        if not self.hash_func_repr:
            fast_hash_func = self.key_repr.get_ll_hash_function()
        if fast_hash_func is None:
            fields.append(("hash", lltype.Signed))
            entry_methods["hash"] = LLOrderedDict.ll_hash_from_cache
        else:
            entry_methods["hash"] = LLOrderedDict.ll_hash_recompute
            entry_methods["fast_hash_func"] = fast_hash_func
        DICTENTRY = lltype.Struct("ORDEREDDICTENTRY", *fields)

        fields = [
            ("num_items", lltype.Signed),
            ("resize_counter", lltype.Signed),
            ("first_entry", lltype.Signed),
            ("last_entry", lltype.Signed),
            ("entries", lltype.Ptr(lltype.GcArray(DICTENTRY, adtmeths=entry_methods))),
        ]
        dict_methods = {}
        if self.eq_func_repr and self.hash_func_repr:
            dict_methods["paranoia"] = True
            dict_methods["hashkey"] = LLOrderedDict.ll_hashkey_custom
            dict_methods["keyeq"] = LLOrderedDict.ll_keyeq_custom

            dict_methods["r_hashkey"] = self.hash_func_repr
            dict_methods["r_keyeq"] = self.eq_func_repr

            fields.append(("hashkey_func", self.hash_func_repr.lowleveltype))
            fields.append(("keyeq_func", self.eq_func_repr.lowleveltype))
        else:
            dict_methods["paranoia"] = False
            dict_methods["hashkey"] = lltype.staticAdtMethod(self.key_repr.get_ll_hash_function())
            ll_keyeq = self.key_repr.get_ll_eq_function()
            if ll_keyeq is not None:
                ll_keyeq = lltype.staticAdtMethod(ll_keyeq)
            dict_methods["keyeq"] = ll_keyeq

        DICT = lltype.GcStruct("ORDEREDDICT", *fields, adtmeths=dict_methods)
        return lltype.Ptr(DICT)
Exemplo n.º 3
0
    def test_adt_method(self):
        def ll_callme(n):
            return n

        ll_callme = lltype.staticAdtMethod(ll_callme)
        S = lltype.GcStruct('S', ('x', lltype.Signed),
                            adtmeths={
                                'yep': True,
                                'callme': ll_callme
                            })

        def g(x, y, z):
            p = lltype.malloc(S)
            p.x = x
            if p.yep:
                z *= p.callme(y)
            return z

        def f(x, y, z):
            return g(x, y, z)

        t, wa = self.translate(f, [int, int, int])
        fgraph = graphof(t, f)
        assert fgraph.startblock.operations[-1].opname == 'direct_call'

        result = wa.analyze(fgraph.startblock.operations[-1])
        assert list(result) == [("struct", lltype.Ptr(S), "x")]
Exemplo n.º 4
0
    def __init__(self, rtyper, r_key):
        self.rtyper = rtyper
        self.r_key = r_key

        fasthashfn = r_key.get_ll_fasthash_function()
        self.ll_keyhash = r_key.get_ll_hash_function()
        ll_keyeq = lltype.staticAdtMethod(r_key.get_ll_eq_function())

        def ll_valid(entries, i):
            value = entries[i].value
            return bool(value) and bool(weakref_deref(rclass.OBJECTPTR, value))

        def ll_everused(entries, i):
            return bool(entries[i].value)

        def ll_hash(entries, i):
            return fasthashfn(entries[i].key)

        entrymeths = {
            'allocate': lltype.typeMethod(rdict._ll_malloc_entries),
            'delete': rdict._ll_free_entries,
            'valid': ll_valid,
            'everused': ll_everused,
            'hash': ll_hash,
            }
        WEAKDICTENTRY = lltype.Struct("weakdictentry",
                                      ("key", r_key.lowleveltype),
                                      ("value", llmemory.WeakRefPtr))
        WEAKDICTENTRYARRAY = lltype.GcArray(WEAKDICTENTRY,
                                            adtmeths=entrymeths,
                                            hints={'weakarray': 'value'})
        # NB. the 'hints' is not used so far ^^^

        dictmeths = {
            'll_get': self.ll_get,
            'll_set': self.ll_set,
            'keyeq': ll_keyeq,
            'paranoia': False,
            }

        self.WEAKDICT = lltype.GcStruct(
            "weakvaldict",
            ("num_items", lltype.Signed),
            ("num_pristine_entries", lltype.Signed),
            ("entries", lltype.Ptr(WEAKDICTENTRYARRAY)),
            adtmeths=dictmeths)

        self.lowleveltype = lltype.Ptr(self.WEAKDICT)
        self.dict_cache = {}
Exemplo n.º 5
0
    def __init__(self, rtyper, r_key):
        self.rtyper = rtyper
        self.r_key = r_key

        fasthashfn = r_key.get_ll_fasthash_function()
        self.ll_keyhash = r_key.get_ll_hash_function()
        ll_keyeq = lltype.staticAdtMethod(r_key.get_ll_eq_function())

        def ll_valid(entries, i):
            value = entries[i].value
            return bool(value) and bool(weakref_deref(rclass.OBJECTPTR, value))

        def ll_everused(entries, i):
            return bool(entries[i].value)

        def ll_hash(entries, i):
            return fasthashfn(entries[i].key)

        entrymeths = {
            'allocate': lltype.typeMethod(rdict._ll_malloc_entries),
            'delete': rdict._ll_free_entries,
            'valid': ll_valid,
            'everused': ll_everused,
            'hash': ll_hash,
        }
        WEAKDICTENTRY = lltype.Struct("weakdictentry",
                                      ("key", r_key.lowleveltype),
                                      ("value", llmemory.WeakRefPtr))
        WEAKDICTENTRYARRAY = lltype.GcArray(WEAKDICTENTRY,
                                            adtmeths=entrymeths,
                                            hints={'weakarray': 'value'})
        # NB. the 'hints' is not used so far ^^^

        dictmeths = {
            'll_get': self.ll_get,
            'll_set': self.ll_set,
            'keyeq': ll_keyeq,
            'paranoia': False,
        }

        self.WEAKDICT = lltype.GcStruct(
            "weakvaldict", ("num_items", lltype.Signed),
            ("resize_counter", lltype.Signed),
            ("entries", lltype.Ptr(WEAKDICTENTRYARRAY)),
            adtmeths=dictmeths)

        self.lowleveltype = lltype.Ptr(self.WEAKDICT)
        self.dict_cache = {}
Exemplo n.º 6
0
    def __init__(self, rtyper, r_key):
        self.rtyper = rtyper
        self.r_key = r_key

        fasthashfn = r_key.get_ll_fasthash_function()
        self.ll_keyhash = r_key.get_ll_hash_function()
        ll_keyeq = lltype.staticAdtMethod(r_key.get_ll_eq_function())

        def ll_valid(entries, i):
            value = entries[i].value
            return bool(value) and bool(weakref_deref(rclass.OBJECTPTR, value))

        def ll_everused(entries, i):
            return bool(entries[i].value)

        def ll_hash(entries, i):
            return fasthashfn(entries[i].key)

        entrymeths = {
            "allocate": lltype.typeMethod(rdict._ll_malloc_entries),
            "delete": rdict._ll_free_entries,
            "valid": ll_valid,
            "everused": ll_everused,
            "hash": ll_hash,
        }
        WEAKDICTENTRY = lltype.Struct("weakdictentry", ("key", r_key.lowleveltype), ("value", llmemory.WeakRefPtr))
        WEAKDICTENTRYARRAY = lltype.GcArray(WEAKDICTENTRY, adtmeths=entrymeths, hints={"weakarray": "value"})
        # NB. the 'hints' is not used so far ^^^

        dictmeths = {"ll_get": self.ll_get, "ll_set": self.ll_set, "keyeq": ll_keyeq, "paranoia": False}

        self.WEAKDICT = lltype.GcStruct(
            "weakvaldict",
            ("num_items", lltype.Signed),
            ("resize_counter", lltype.Signed),
            ("entries", lltype.Ptr(WEAKDICTENTRYARRAY)),
            adtmeths=dictmeths,
        )

        self.lowleveltype = lltype.Ptr(self.WEAKDICT)
        self.dict_cache = {}
Exemplo n.º 7
0
    def test_adt_method(self):
        def ll_callme(n):
            return n
        ll_callme = lltype.staticAdtMethod(ll_callme)
        S = lltype.GcStruct('S', ('x', lltype.Signed),
                            adtmeths = {'yep': True,
                                        'callme': ll_callme})
        def g(x, y, z):
            p = lltype.malloc(S)
            p.x = x
            if p.yep:
                z *= p.callme(y)
            return z
        def f(x, y, z):
            return g(x, y, z)

        t, wa = self.translate(f, [int, int, int])
        fgraph = graphof(t, f)
        assert fgraph.startblock.operations[-1].opname == 'direct_call'

        result = wa.analyze(fgraph.startblock.operations[-1])
        assert list(result) == [("struct", lltype.Ptr(S), "x")]
Exemplo n.º 8
0
        src = llmemory.cast_ptr_to_adr(s1) + _str_ofs(s1start)
        dest = llmemory.cast_ptr_to_adr(s2) + _str_ofs(s2start)
        llmemory.raw_memcopy(src, dest, llmemory.sizeof(CHAR_TP) * lgt)

    copy_string_contents._always_inline_ = True
    return func_with_new_name(copy_string_contents, 'copy_%s_contents' % name)


copy_string_contents = _new_copy_contents_fun(STR, Char, 'string')
copy_unicode_contents = _new_copy_contents_fun(UNICODE, UniChar, 'unicode')

STR.become(
    GcStruct('rpy_string', ('hash', Signed),
             ('chars', Array(Char, hints={'immutable': True})),
             adtmeths={
                 'malloc': staticAdtMethod(mallocstr),
                 'empty': staticAdtMethod(emptystrfun),
                 'copy_contents': staticAdtMethod(copy_string_contents)
             }))
UNICODE.become(
    GcStruct('rpy_unicode', ('hash', Signed),
             ('chars', Array(UniChar, hints={'immutable': True})),
             adtmeths={
                 'malloc': staticAdtMethod(mallocunicode),
                 'empty': staticAdtMethod(emptyunicodefun),
                 'copy_contents': staticAdtMethod(copy_unicode_contents)
             }))
SIGNED_ARRAY = GcArray(Signed)
CONST_STR_CACHE = WeakValueDictionary()
CONST_UNICODE_CACHE = WeakValueDictionary()
Exemplo n.º 9
0
        newbuf = mallocfn(new_allocated)
        copycontentsfn(ll_builder.buf, newbuf, 0, 0, ll_builder.allocated)
        ll_builder.buf = newbuf
        ll_builder.allocated = new_allocated
    return func_with_new_name(stringbuilder_grow, name)

stringbuilder_grow = new_grow_func('stringbuilder_grow', rstr.mallocstr,
                                   rstr.copy_string_contents)
unicodebuilder_grow = new_grow_func('unicodebuilder_grow', rstr.mallocunicode,
                                    rstr.copy_unicode_contents)

STRINGBUILDER = lltype.GcStruct('stringbuilder',
                               ('allocated', lltype.Signed),
                               ('used', lltype.Signed),
                               ('buf', lltype.Ptr(STR)),
                               adtmeths={'grow':staticAdtMethod(stringbuilder_grow)})

UNICODEBUILDER = lltype.GcStruct('unicodebuilder',
                                 ('allocated', lltype.Signed),
                                 ('used', lltype.Signed),
                                 ('buf', lltype.Ptr(UNICODE)),
                              adtmeths={'grow':staticAdtMethod(unicodebuilder_grow)})

MAX = 16*1024*1024

class BaseStringBuilderRepr(AbstractStringBuilderRepr):
    @classmethod
    def ll_new(cls, init_size):
        if init_size < 0 or init_size > MAX:
            init_size = MAX
        ll_builder = lltype.malloc(cls.lowleveltype.TO)
Exemplo n.º 10
0
    def _setup_repr(self):
        if 'key_repr' not in self.__dict__:
            key_repr = self._key_repr_computer()
            self.external_key_repr, self.key_repr = self.pickkeyrepr(key_repr)
        if 'value_repr' not in self.__dict__:
            self.external_value_repr, self.value_repr = self.pickrepr(
                self._value_repr_computer())
        if isinstance(self.DICT, lltype.GcForwardReference):
            self.DICTKEY = self.key_repr.lowleveltype
            self.DICTVALUE = self.value_repr.lowleveltype

            # compute the shape of the DICTENTRY structure
            entryfields = []
            entrymeths = {
                'allocate':
                lltype.typeMethod(_ll_malloc_entries),
                'delete':
                _ll_free_entries,
                'must_clear_key': (isinstance(self.DICTKEY, lltype.Ptr)
                                   and self.DICTKEY._needsgc()),
                'must_clear_value': (isinstance(self.DICTVALUE, lltype.Ptr)
                                     and self.DICTVALUE._needsgc()),
            }

            # * the key
            entryfields.append(("key", self.DICTKEY))

            # * if NULL is not a valid ll value for the key or the value
            #   field of the entry, it can be used as a marker for
            #   never-used entries.  Otherwise, we need an explicit flag.
            s_key = self.dictkey.s_value
            s_value = self.dictvalue.s_value
            nullkeymarker = not self.key_repr.can_ll_be_null(s_key)
            nullvaluemarker = not self.value_repr.can_ll_be_null(s_value)
            dummykeyobj = self.key_repr.get_ll_dummyval_obj(self.rtyper, s_key)
            dummyvalueobj = self.value_repr.get_ll_dummyval_obj(
                self.rtyper, s_value)

            # * the state of the entry - trying to encode it as dummy objects
            if nullkeymarker and dummykeyobj:
                # all the state can be encoded in the key
                entrymeths['everused'] = ll_everused_from_key
                entrymeths['dummy_obj'] = dummykeyobj
                entrymeths['valid'] = ll_valid_from_key
                entrymeths['mark_deleted'] = ll_mark_deleted_in_key
                # the key is overwritten by 'dummy' when the entry is deleted
                entrymeths['must_clear_key'] = False

            elif nullvaluemarker and dummyvalueobj:
                # all the state can be encoded in the value
                entrymeths['everused'] = ll_everused_from_value
                entrymeths['dummy_obj'] = dummyvalueobj
                entrymeths['valid'] = ll_valid_from_value
                entrymeths['mark_deleted'] = ll_mark_deleted_in_value
                # value is overwritten by 'dummy' when entry is deleted
                entrymeths['must_clear_value'] = False

            else:
                # we need a flag to know if the entry was ever used
                # (we cannot use a NULL as a marker for this, because
                # the key and value will be reset to NULL to clear their
                # reference)
                entryfields.append(("f_everused", lltype.Bool))
                entrymeths['everused'] = ll_everused_from_flag

                # can we still rely on a dummy obj to mark deleted entries?
                if dummykeyobj:
                    entrymeths['dummy_obj'] = dummykeyobj
                    entrymeths['valid'] = ll_valid_from_key
                    entrymeths['mark_deleted'] = ll_mark_deleted_in_key
                    # key is overwritten by 'dummy' when entry is deleted
                    entrymeths['must_clear_key'] = False
                elif dummyvalueobj:
                    entrymeths['dummy_obj'] = dummyvalueobj
                    entrymeths['valid'] = ll_valid_from_value
                    entrymeths['mark_deleted'] = ll_mark_deleted_in_value
                    # value is overwritten by 'dummy' when entry is deleted
                    entrymeths['must_clear_value'] = False
                else:
                    entryfields.append(("f_valid", lltype.Bool))
                    entrymeths['valid'] = ll_valid_from_flag
                    entrymeths['mark_deleted'] = ll_mark_deleted_in_flag

            # * the value
            entryfields.append(("value", self.DICTVALUE))

            # * the hash, if needed
            if self.custom_eq_hash:
                fasthashfn = None
            else:
                fasthashfn = self.key_repr.get_ll_fasthash_function()
            if fasthashfn is None:
                entryfields.append(("f_hash", lltype.Signed))
                entrymeths['hash'] = ll_hash_from_cache
            else:
                entrymeths['hash'] = ll_hash_recomputed
                entrymeths['fasthashfn'] = fasthashfn

            # Build the lltype data structures
            self.DICTENTRY = lltype.Struct("dictentry", *entryfields)
            self.DICTENTRYARRAY = lltype.GcArray(self.DICTENTRY,
                                                 adtmeths=entrymeths)
            fields = [("num_items", lltype.Signed),
                      ("num_pristine_entries", lltype.Signed),
                      ("entries", lltype.Ptr(self.DICTENTRYARRAY))]
            if self.custom_eq_hash:
                self.r_rdict_eqfn, self.r_rdict_hashfn = self._custom_eq_hash_repr(
                )
                fields.extend([("fnkeyeq", self.r_rdict_eqfn.lowleveltype),
                               ("fnkeyhash", self.r_rdict_hashfn.lowleveltype)
                               ])
                adtmeths = {
                    'keyhash': ll_keyhash_custom,
                    'keyeq': ll_keyeq_custom,
                    'r_rdict_eqfn': self.r_rdict_eqfn,
                    'r_rdict_hashfn': self.r_rdict_hashfn,
                    'paranoia': True,
                }
            else:
                # figure out which functions must be used to hash and compare
                ll_keyhash = self.key_repr.get_ll_hash_function()
                ll_keyeq = self.key_repr.get_ll_eq_function()  # can be None
                ll_keyhash = lltype.staticAdtMethod(ll_keyhash)
                if ll_keyeq is not None:
                    ll_keyeq = lltype.staticAdtMethod(ll_keyeq)
                adtmeths = {
                    'keyhash': ll_keyhash,
                    'keyeq': ll_keyeq,
                    'paranoia': False,
                }
            adtmeths['KEY'] = self.DICTKEY
            adtmeths['VALUE'] = self.DICTVALUE
            adtmeths['allocate'] = lltype.typeMethod(_ll_malloc_dict)
            self.DICT.become(
                lltype.GcStruct("dicttable", adtmeths=adtmeths, *fields))
Exemplo n.º 11
0
        # the entry must still be marked as everused().
        d.entries[i].value = llmemory.dead_wref
        d.entries[i].key = lltype.nullptr(rstr.STR)
        #llop.debug_print(lltype.Void, i, 'zero')


def ll_weakdict_resize(d):
    # first set num_items to its correct, up-to-date value
    entries = d.entries
    num_items = 0
    for i in range(len(entries)):
        if entries.valid(i):
            num_items += 1
    d.num_items = num_items
    rdict.ll_dict_resize(d)


str_keyeq = lltype.staticAdtMethod(rstr.string_repr.get_ll_eq_function())

dictmeths = {
    'll_get': ll_get,
    'll_set': ll_set,
    'keyeq': str_keyeq,
    'paranoia': False,
}

WEAKDICT = lltype.GcStruct("weakdict", ("num_items", lltype.Signed),
                           ("num_pristine_entries", lltype.Signed),
                           ("entries", lltype.Ptr(WEAKDICTENTRYARRAY)),
                           adtmeths=dictmeths)
Exemplo n.º 12
0
            new_allocated = ovfcheck(new_allocated + needed)
        except OverflowError:
            raise MemoryError
        ll_builder.buf = rgc.resize_buffer(ll_builder.buf, ll_builder.used,
                                           new_allocated)
        ll_builder.allocated = new_allocated
    return func_with_new_name(stringbuilder_grow, name)

stringbuilder_grow = new_grow_func('stringbuilder_grow')
unicodebuilder_grow = new_grow_func('unicodebuilder_grow')

STRINGBUILDER = lltype.GcStruct('stringbuilder',
                              ('allocated', lltype.Signed),
                              ('used', lltype.Signed),
                              ('buf', lltype.Ptr(STR)),
                                adtmeths={'grow':staticAdtMethod(stringbuilder_grow)})

UNICODEBUILDER = lltype.GcStruct('unicodebuilder',
                                 ('allocated', lltype.Signed),
                                 ('used', lltype.Signed),
                                 ('buf', lltype.Ptr(UNICODE)),
                                 adtmeths={'grow':staticAdtMethod(unicodebuilder_grow)})

MAX = 16*1024*1024

class BaseStringBuilderRepr(AbstractStringBuilderRepr):
    @classmethod
    def ll_new(cls, init_size):
        if init_size < 0 or init_size > MAX:
            init_size = MAX
        ll_builder = lltype.malloc(cls.lowleveltype.TO)
Exemplo n.º 13
0
    def _setup_repr(self):
        if 'key_repr' not in self.__dict__:
            key_repr = self._key_repr_computer()
            self.external_key_repr, self.key_repr = self.pickkeyrepr(key_repr)
        if 'value_repr' not in self.__dict__:
            self.external_value_repr, self.value_repr = self.pickrepr(self._value_repr_computer())
        if isinstance(self.DICT, lltype.GcForwardReference):
            self.DICTKEY = self.key_repr.lowleveltype
            self.DICTVALUE = self.value_repr.lowleveltype

            # compute the shape of the DICTENTRY structure
            entryfields = []
            entrymeths = {
                'allocate': lltype.typeMethod(_ll_malloc_entries),
                'delete': _ll_free_entries,
                'must_clear_key':   (isinstance(self.DICTKEY, lltype.Ptr)
                                     and self.DICTKEY._needsgc()),
                'must_clear_value': (isinstance(self.DICTVALUE, lltype.Ptr)
                                     and self.DICTVALUE._needsgc()),
                }

            # * the key
            entryfields.append(("key", self.DICTKEY))

            # * if NULL is not a valid ll value for the key or the value
            #   field of the entry, it can be used as a marker for
            #   never-used entries.  Otherwise, we need an explicit flag.
            s_key   = self.dictkey.s_value
            s_value = self.dictvalue.s_value
            nullkeymarker = not self.key_repr.can_ll_be_null(s_key)
            nullvaluemarker = not self.value_repr.can_ll_be_null(s_value)
            if self.force_non_null:
                if not nullkeymarker:
                    rmodel.warning("%s can be null, but forcing non-null in dict key" % s_key)
                    nullkeymarker = True
                if not nullvaluemarker:
                    rmodel.warning("%s can be null, but forcing non-null in dict value" % s_value)
                    nullvaluemarker = True
            dummykeyobj = self.key_repr.get_ll_dummyval_obj(self.rtyper,
                                                            s_key)
            dummyvalueobj = self.value_repr.get_ll_dummyval_obj(self.rtyper,
                                                                s_value)

            # * the state of the entry - trying to encode it as dummy objects
            if nullkeymarker and dummykeyobj:
                # all the state can be encoded in the key
                entrymeths['everused'] = ll_everused_from_key
                entrymeths['dummy_obj'] = dummykeyobj
                entrymeths['valid'] = ll_valid_from_key
                entrymeths['mark_deleted'] = ll_mark_deleted_in_key
                # the key is overwritten by 'dummy' when the entry is deleted
                entrymeths['must_clear_key'] = False

            elif nullvaluemarker and dummyvalueobj:
                # all the state can be encoded in the value
                entrymeths['everused'] = ll_everused_from_value
                entrymeths['dummy_obj'] = dummyvalueobj
                entrymeths['valid'] = ll_valid_from_value
                entrymeths['mark_deleted'] = ll_mark_deleted_in_value
                # value is overwritten by 'dummy' when entry is deleted
                entrymeths['must_clear_value'] = False

            else:
                # we need a flag to know if the entry was ever used
                # (we cannot use a NULL as a marker for this, because
                # the key and value will be reset to NULL to clear their
                # reference)
                entryfields.append(("f_everused", lltype.Bool))
                entrymeths['everused'] = ll_everused_from_flag

                # can we still rely on a dummy obj to mark deleted entries?
                if dummykeyobj:
                    entrymeths['dummy_obj'] = dummykeyobj
                    entrymeths['valid'] = ll_valid_from_key
                    entrymeths['mark_deleted'] = ll_mark_deleted_in_key
                    # key is overwritten by 'dummy' when entry is deleted
                    entrymeths['must_clear_key'] = False
                elif dummyvalueobj:
                    entrymeths['dummy_obj'] = dummyvalueobj
                    entrymeths['valid'] = ll_valid_from_value
                    entrymeths['mark_deleted'] = ll_mark_deleted_in_value
                    # value is overwritten by 'dummy' when entry is deleted
                    entrymeths['must_clear_value'] = False
                else:
                    entryfields.append(("f_valid", lltype.Bool))
                    entrymeths['valid'] = ll_valid_from_flag
                    entrymeths['mark_deleted'] = ll_mark_deleted_in_flag

            # * the value
            entryfields.append(("value", self.DICTVALUE))

            # * the hash, if needed
            if self.custom_eq_hash:
                fasthashfn = None
            else:
                fasthashfn = self.key_repr.get_ll_fasthash_function()
            if fasthashfn is None:
                entryfields.append(("f_hash", lltype.Signed))
                entrymeths['hash'] = ll_hash_from_cache
            else:
                entrymeths['hash'] = ll_hash_recomputed
                entrymeths['fasthashfn'] = fasthashfn

            # Build the lltype data structures
            self.DICTENTRY = lltype.Struct("dictentry", *entryfields)
            self.DICTENTRYARRAY = lltype.GcArray(self.DICTENTRY,
                                                 adtmeths=entrymeths)
            fields =          [ ("num_items", lltype.Signed),
                                ("resize_counter", lltype.Signed),
                                ("entries", lltype.Ptr(self.DICTENTRYARRAY)) ]
            if self.custom_eq_hash:
                self.r_rdict_eqfn, self.r_rdict_hashfn = self._custom_eq_hash_repr()
                fields.extend([ ("fnkeyeq", self.r_rdict_eqfn.lowleveltype),
                                ("fnkeyhash", self.r_rdict_hashfn.lowleveltype) ])
                adtmeths = {
                    'keyhash':        ll_keyhash_custom,
                    'keyeq':          ll_keyeq_custom,
                    'r_rdict_eqfn':   self.r_rdict_eqfn,
                    'r_rdict_hashfn': self.r_rdict_hashfn,
                    'paranoia':       True,
                    }
            else:
                # figure out which functions must be used to hash and compare
                ll_keyhash = self.key_repr.get_ll_hash_function()
                ll_keyeq = self.key_repr.get_ll_eq_function()  # can be None
                ll_keyhash = lltype.staticAdtMethod(ll_keyhash)
                if ll_keyeq is not None:
                    ll_keyeq = lltype.staticAdtMethod(ll_keyeq)
                adtmeths = {
                    'keyhash':  ll_keyhash,
                    'keyeq':    ll_keyeq,
                    'paranoia': False,
                    }
            adtmeths['KEY']   = self.DICTKEY
            adtmeths['VALUE'] = self.DICTVALUE
            adtmeths['allocate'] = lltype.typeMethod(_ll_malloc_dict)
            self.DICT.become(lltype.GcStruct("dicttable", adtmeths=adtmeths,
                                             *fields))
Exemplo n.º 14
0
        copycontentsfn(ll_builder.buf, newbuf, 0, 0, ll_builder.allocated)
        ll_builder.buf = newbuf
        ll_builder.allocated = new_allocated

    return func_with_new_name(stringbuilder_grow, name)


stringbuilder_grow = new_grow_func("stringbuilder_grow", rstr.mallocstr, rstr.copy_string_contents)
unicodebuilder_grow = new_grow_func("unicodebuilder_grow", rstr.mallocunicode, rstr.copy_unicode_contents)

STRINGBUILDER = lltype.GcStruct(
    "stringbuilder",
    ("allocated", lltype.Signed),
    ("used", lltype.Signed),
    ("buf", lltype.Ptr(STR)),
    adtmeths={"grow": staticAdtMethod(stringbuilder_grow)},
)

UNICODEBUILDER = lltype.GcStruct(
    "unicodebuilder",
    ("allocated", lltype.Signed),
    ("used", lltype.Signed),
    ("buf", lltype.Ptr(UNICODE)),
    adtmeths={"grow": staticAdtMethod(unicodebuilder_grow)},
)

MAX = 16 * 1024 * 1024


class BaseStringBuilderRepr(AbstractStringBuilderRepr):
    @classmethod
Exemplo n.º 15
0
        return hop.gendirectcall(cls.ll_join_strs, size, vtemp)

    do_stringformat = classmethod(do_stringformat)


TEMP = GcArray(Ptr(STR))

# ____________________________________________________________

STR.become(
    GcStruct(
        "rpy_string",
        ("hash", Signed),
        ("chars", Array(Char, hints={"immutable": True})),
        adtmeths={
            "malloc": staticAdtMethod(mallocstr),
            "empty": staticAdtMethod(emptystrfun),
            "copy_contents": staticAdtMethod(copy_string_contents),
            "gethash": LLHelpers.ll_strhash,
        },
    )
)
UNICODE.become(
    GcStruct(
        "rpy_unicode",
        ("hash", Signed),
        ("chars", Array(UniChar, hints={"immutable": True})),
        adtmeths={
            "malloc": staticAdtMethod(mallocunicode),
            "empty": staticAdtMethod(emptyunicodefun),
            "copy_contents": staticAdtMethod(copy_unicode_contents),
Exemplo n.º 16
0
mallocunicode = new_malloc(UNICODE)


def emptystrfun():
    return emptystr


def emptyunicodefun():
    return emptyunicode


STR.become(
    GcStruct('rpy_string', ('hash', Signed),
             ('chars', Array(Char, hints={'immutable': True})),
             adtmeths={
                 'malloc': staticAdtMethod(mallocstr),
                 'empty': staticAdtMethod(emptystrfun)
             }))
UNICODE.become(
    GcStruct('rpy_unicode', ('hash', Signed),
             ('chars', Array(UniChar, hints={'immutable': True})),
             adtmeths={
                 'malloc': staticAdtMethod(mallocunicode),
                 'empty': staticAdtMethod(emptyunicodefun)
             }))
SIGNED_ARRAY = GcArray(Signed)
CONST_STR_CACHE = WeakValueDictionary()
CONST_UNICODE_CACHE = WeakValueDictionary()


class BaseLLStringRepr(Repr):
Exemplo n.º 17
0
        # We don't store a NULL value, but a dead weakref, because
        # the entry must still be marked as everused().
        d.entries[i].value = llmemory.dead_wref
        d.entries[i].key = lltype.nullptr(rstr.STR)
        #llop.debug_print(lltype.Void, i, 'zero')

def ll_weakdict_resize(d):
    # first set num_items to its correct, up-to-date value
    entries = d.entries
    num_items = 0
    for i in range(len(entries)):
        if entries.valid(i):
            num_items += 1
    d.num_items = num_items
    rdict.ll_dict_resize(d)

str_keyeq = lltype.staticAdtMethod(rstr.string_repr.get_ll_eq_function())

dictmeths = {
    'll_get': ll_get,
    'll_set': ll_set,
    'keyeq': str_keyeq,
    'paranoia': False,
    }

WEAKDICT = lltype.GcStruct("weakdict",
                           ("num_items", lltype.Signed),
                           ("num_pristine_entries", lltype.Signed),
                           ("entries", lltype.Ptr(WEAKDICTENTRYARRAY)),
                           adtmeths=dictmeths)
Exemplo n.º 18
0
Arquivo: rstr.py Projeto: alkorzt/pypy
                from pypy.rpython.lltypesystem.rstr import string_repr
                vchunk = inputconst(string_repr, thing)
            i = inputconst(Signed, i)
            hop.genop('setarrayitem', [vtemp, i, vchunk])

        hop.exception_cannot_occur()   # to ignore the ZeroDivisionError of '%'
        return hop.gendirectcall(cls.ll_join_strs, size, vtemp)
    do_stringformat = classmethod(do_stringformat)

TEMP = GcArray(Ptr(STR))

# ____________________________________________________________

STR.become(GcStruct('rpy_string', ('hash',  Signed),
                    ('chars', Array(Char, hints={'immutable': True})),
                    adtmeths={'malloc' : staticAdtMethod(mallocstr),
                              'empty'  : staticAdtMethod(emptystrfun),
                              'copy_contents' : staticAdtMethod(copy_string_contents),
                              'gethash': LLHelpers.ll_strhash}))
UNICODE.become(GcStruct('rpy_unicode', ('hash', Signed),
                        ('chars', Array(UniChar, hints={'immutable': True})),
                        adtmeths={'malloc' : staticAdtMethod(mallocunicode),
                                  'empty'  : staticAdtMethod(emptyunicodefun),
                                  'copy_contents' : staticAdtMethod(copy_unicode_contents),
                                  'gethash': LLHelpers.ll_strhash}
                        ))


# TODO: make the public interface of the rstr module cleaner
ll_strconcat = LLHelpers.ll_strconcat
ll_join = LLHelpers.ll_join
Exemplo n.º 19
0
        return r
    mallocstr._annspecialcase_ = 'specialize:semierased'
    return mallocstr

mallocstr = new_malloc(STR)
mallocunicode = new_malloc(UNICODE)

def emptystrfun():
    return emptystr

def emptyunicodefun():
    return emptyunicode

STR.become(GcStruct('rpy_string', ('hash',  Signed),
                    ('chars', Array(Char, hints={'immutable': True})),
                    adtmeths={'malloc' : staticAdtMethod(mallocstr),
                              'empty'  : staticAdtMethod(emptystrfun)}))
UNICODE.become(GcStruct('rpy_unicode', ('hash', Signed),
                        ('chars', Array(UniChar, hints={'immutable': True})),
                        adtmeths={'malloc' : staticAdtMethod(mallocunicode),
                                  'empty'  : staticAdtMethod(emptyunicodefun)}
                        ))
SIGNED_ARRAY = GcArray(Signed)
CONST_STR_CACHE = WeakValueDictionary()
CONST_UNICODE_CACHE = WeakValueDictionary()

class BaseLLStringRepr(Repr):
    def convert_const(self, value):
        if value is None:
            return nullptr(self.lowleveltype.TO)
        #value = getattr(value, '__self__', value)  # for bound string methods