Ejemplo n.º 1
0
def normalize_simple_slice(space, length, w_start, w_stop):
    """Helper for the {get,set,del}slice implementations."""
    # this returns a pair (start, stop) which is usable for slicing
    # a sequence of the given length in the most friendly way, i.e.
    # guaranteeing that 0 <= start <= stop <= length.
    start = space.int_w(w_start)
    stop = space.int_w(w_stop)
    assert length >= 0
    if start < 0:
        start = 0
    # hack for the JIT, for slices with no end specified:
    # this avoids the two comparisons that follow
    if jit.isconstant(stop) and stop == sys.maxint:
        pass
    else:
        if stop < start:
            stop = start
        if stop <= length:
            return start, stop
    # here is the case where 'stop' is larger than the list
    stop = length
    if jit.isconstant(start) and start == 0:
        pass    # no need to do the following check here
    elif start > stop:
        start = stop
    return start, stop
Ejemplo n.º 2
0
def normalize_simple_slice(space, length, w_start, w_stop):
    """Helper for the {get,set,del}slice implementations."""
    # this returns a pair (start, stop) which is usable for slicing
    # a sequence of the given length in the most friendly way, i.e.
    # guaranteeing that 0 <= start <= stop <= length.
    start = space.int_w(w_start)
    stop = space.int_w(w_stop)
    assert length >= 0
    if start < 0:
        start = 0
    # hack for the JIT, for slices with no end specified:
    # this avoids the two comparisons that follow
    if jit.isconstant(stop) and stop == sys.maxint:
        pass
    else:
        if stop < start:
            stop = start
        if stop <= length:
            return start, stop
    # here is the case where 'stop' is larger than the list
    stop = length
    if jit.isconstant(start) and start == 0:
        pass    # no need to do the following check here
    elif start > stop:
        start = stop
    return start, stop
Ejemplo n.º 3
0
 def read(self, obj, selector):
     attr = self.find_map_attr(selector)
     if attr is None:
         return self.terminator._read_terminator(obj, selector)
     if jit.isconstant(attr.storageindex) and jit.isconstant(obj) and not attr.ever_mutated:
         return self._pure_mapdict_read_storage(obj, attr.storageindex)
     else:
         return obj._mapdict_read_storage(attr.storageindex)
Ejemplo n.º 4
0
 def eq(self, other):
     # slightly evil
     if jit.isconstant(self):
         jit.promote(other)
     elif jit.isconstant(other):
         jit.promote(self)
     return self is other or (self.numargs == other.numargs
                              and self.name == other.name)
Ejemplo n.º 5
0
 def eq(self, other):
     # slightly evil
     if jit.isconstant(self):
         jit.promote(other)
     elif jit.isconstant(other):
         jit.promote(self)
     return self is other or (
             self.numargs == other.numargs and
             self.name == other.name)
Ejemplo n.º 6
0
 def read(self, obj, name, index):
     attr = self.find_map_attr(name, index)
     if attr is None:
         return self.terminator._read_terminator(obj, name, index)
     if (jit.isconstant(attr.storageindex) and jit.isconstant(obj)
             and not attr.ever_mutated):
         return self._pure_mapdict_read_storage(obj, attr.storageindex)
     else:
         return obj._mapdict_read_storage(attr.storageindex)
Ejemplo n.º 7
0
 def read(self, obj, name, attrkind):
     attr = self.find_map_attr(name, attrkind)
     if attr is None:
         return self.terminator._read_terminator(obj, name, attrkind)
     if (jit.isconstant(attr) and jit.isconstant(obj)
             and not attr.ever_mutated):
         return attr._pure_direct_read(obj)
     else:
         return attr._direct_read(obj)
Ejemplo n.º 8
0
def _ll_list_resize_le(l, newsize):
    """This is called with 'newsize' smaller than the current length of the
    list.  If 'newsize' falls lower than half the allocated size, proceed
    with the realloc() to shrink the list.
    """
    cond = newsize < (len(l.items) >> 1) - 5
    if jit.isconstant(len(l.items)) and jit.isconstant(newsize):
        if cond:
            _ll_list_resize_hint_really(l, newsize, False)
    else:
        jit.conditional_call(cond, _ll_list_resize_hint_really, l, newsize,
                             False)
    l.length = newsize
Ejemplo n.º 9
0
def _ll_list_resize_ge(l, newsize):
    """This is called with 'newsize' larger than the current length of the
    list.  If the list storage doesn't have enough space, then really perform
    a realloc().  In the common case where we already overallocated enough,
    then this is a very fast operation.
    """
    cond = len(l.items) < newsize
    if jit.isconstant(len(l.items)) and jit.isconstant(newsize):
        if cond:
            _ll_list_resize_hint_really(l, newsize, True)
    else:
        jit.conditional_call(cond,
                             _ll_list_resize_hint_really, l, newsize, True)
    l.length = newsize
Ejemplo n.º 10
0
def _ll_list_resize_le(l, newsize):
    """This is called with 'newsize' smaller than the current length of the
    list.  If 'newsize' falls lower than half the allocated size, proceed
    with the realloc() to shrink the list.
    """
    cond = newsize < (len(l.items) >> 1) - 5
    # note: overallocate=False should be safe here
    if jit.isconstant(len(l.items)) and jit.isconstant(newsize):
        if cond:
            _ll_list_resize_hint_really(l, newsize, False)
    else:
        jit.conditional_call(cond, _ll_list_resize_hint_really, l, newsize,
                             False)
    l.length = newsize
Ejemplo n.º 11
0
    def __init__(self,
                 space,
                 args_w,
                 keywords=None,
                 keywords_w=None,
                 w_stararg=None,
                 w_starstararg=None,
                 keyword_names_w=None):
        self.space = space
        assert isinstance(args_w, list)
        self.arguments_w = args_w

        self.keywords = keywords
        self.keywords_w = keywords_w
        self.keyword_names_w = keyword_names_w  # matches the tail of .keywords
        if keywords is not None:
            assert keywords_w is not None
            assert len(keywords_w) == len(keywords)
            assert (keyword_names_w is None
                    or len(keyword_names_w) <= len(keywords))
            make_sure_not_resized(self.keywords)
            make_sure_not_resized(self.keywords_w)

        make_sure_not_resized(self.arguments_w)
        self._combine_wrapped(w_stararg, w_starstararg)
        # a flag that specifies whether the JIT can unroll loops that operate
        # on the keywords
        self._jit_few_keywords = self.keywords is None or jit.isconstant(
            len(self.keywords))
Ejemplo n.º 12
0
    def __init__(self, space, args_w, keywords=None, keywords_w=None,
                 w_stararg=None, w_starstararg=None, keyword_names_w=None,
                 methodcall=False):
        self.space = space
        assert isinstance(args_w, list)
        self.arguments_w = args_w
        self.keywords = keywords
        self.keywords_w = keywords_w
        self.keyword_names_w = keyword_names_w  # matches the tail of .keywords
        if keywords is not None:
            assert keywords_w is not None
            assert len(keywords_w) == len(keywords)
            assert (keyword_names_w is None or
                    len(keyword_names_w) <= len(keywords))
            make_sure_not_resized(self.keywords)
            make_sure_not_resized(self.keywords_w)

        make_sure_not_resized(self.arguments_w)
        self._combine_wrapped(w_stararg, w_starstararg)
        # a flag that specifies whether the JIT can unroll loops that operate
        # on the keywords
        self._jit_few_keywords = self.keywords is None or jit.isconstant(len(self.keywords))
        # a flag whether this is likely a method call, which doesn't change the
        # behaviour but produces better error messages
        self.methodcall = methodcall
Ejemplo n.º 13
0
    def __init__(self,
                 space,
                 args_w,
                 keywords=None,
                 keywords_w=None,
                 w_stararg=None,
                 w_starstararg=None,
                 keyword_names_w=None,
                 methodcall=False,
                 fnname_parens=None):
        self.space = space
        assert isinstance(args_w, list)
        self.arguments_w = args_w
        self.keywords = keywords
        self.keywords_w = keywords_w
        self.keyword_names_w = keyword_names_w  # matches the tail of .keywords
        if keywords is not None:
            assert keywords_w is not None
            assert len(keywords_w) == len(keywords)
            assert (keyword_names_w is None
                    or len(keyword_names_w) <= len(keywords))
            make_sure_not_resized(self.keywords)
            make_sure_not_resized(self.keywords_w)

        make_sure_not_resized(self.arguments_w)
        self._combine_wrapped(w_stararg, w_starstararg, fnname_parens)
        # a flag that specifies whether the JIT can unroll loops that operate
        # on the keywords
        self._jit_few_keywords = self.keywords is None or jit.isconstant(
            len(self.keywords))
        # a flag whether this is likely a method call, which doesn't change the
        # behaviour but produces better error messages
        self.methodcall = methodcall
Ejemplo n.º 14
0
 def size(self):
     sz = jit.conditional_call_elidable(self._exposed_size,
                                        calculate_exposed_size_for_big_int,
                                        self.value)
     if not jit.isconstant(self):
         self._exposed_size = sz
     return sz
Ejemplo n.º 15
0
 def ffi_type(self, w_x, accept):
     space = self.space
     if (accept & ACCEPT_STRING) and (space.isinstance_w(
             w_x, space.w_basestring)):
         string = space.text_w(w_x)
         consider_fn_as_fnptr = (accept & CONSIDER_FN_AS_FNPTR) != 0
         if jit.isconstant(string):
             try:
                 return self.get_string_to_type(string,
                                                consider_fn_as_fnptr)
             except KeyError:
                 pass
         return self.parse_string_to_type(string, consider_fn_as_fnptr)
     if (accept & ACCEPT_CTYPE) and isinstance(w_x, W_CType):
         return w_x
     if (accept & ACCEPT_CDATA) and isinstance(w_x, W_CData):
         return w_x.ctype
     #
     m1 = "string" if accept & ACCEPT_STRING else ""
     m2 = "ctype object" if accept & ACCEPT_CTYPE else ""
     m3 = "cdata object" if accept & ACCEPT_CDATA else ""
     s12 = " or " if m1 and (m2 or m3) else ""
     s23 = " or " if m2 and m3 else ""
     raise oefmt(space.w_TypeError, "expected a %s%s%s%s%s, got '%T'", m1,
                 s12, m2, s23, m3, w_x)
Ejemplo n.º 16
0
 def pow_small_int(self, n):
     if n >= 0:
         if jit.isconstant(n) and n == 2:
             return self.mul(self)
         return self.pow_positive_int(n)
     else:
         return w_one.div(self.pow_positive_int(-n))
Ejemplo n.º 17
0
def w_dict_unrolling_heuristic(w_dct):
    """In which cases iterating over dict items can be unrolled.
    Note that w_dct is an instance of W_DictMultiObject, not necesarilly
    an actual dict
    """
    return jit.isvirtual(w_dct) or (jit.isconstant(w_dct) and
                                    w_dct.length() <= UNROLL_CUTOFF)
Ejemplo n.º 18
0
def string_append(args):
    if jit.isconstant(len(args)):
        return string_append_fastpath(args)
    if not args:
        return W_String.fromascii("")
    builder = StringBuilder(len(args))
    unibuilder = None
    ascii_idx = 0
    try:
        for ascii_idx in range(len(args)):
            arg = args[ascii_idx]
            if not isinstance(arg, W_String):
                raise SchemeException("string-append: expected a string")
            builder.append(arg.as_str_ascii())
    except ValueError:
        unibuilder = UnicodeBuilder(len(args))
        unibuilder.append(unicode(builder.build()))
        builder = None
        for i in range(ascii_idx, len(args)):
            arg = args[i]
            if not isinstance(arg, W_String):
                raise SchemeException("string-append: expected a string")
            unibuilder.append(arg.as_unicode())
    if unibuilder is None:
        assert builder is not None
        return W_String.fromascii(builder.build())
    else:
        assert unibuilder is not None
        return W_String.fromunicode(unibuilder.build())
Ejemplo n.º 19
0
def string_append(args):
    if jit.isconstant(len(args)):
        return string_append_fastpath(args)
    if not args:
        return W_String.fromascii("")
    builder = StringBuilder(len(args))
    unibuilder = None
    ascii_idx = 0
    try:
        for ascii_idx in range(len(args)):
            arg = args[ascii_idx]
            if not isinstance(arg, W_String):
                raise SchemeException("string-append: expected a string")
            builder.append(arg.as_str_ascii())
    except ValueError:
        unibuilder = UnicodeBuilder(len(args))
        unibuilder.append(unicode(builder.build()))
        builder = None
        for i in range(ascii_idx, len(args)):
            arg = args[i]
            if not isinstance(arg, W_String):
                raise SchemeException("string-append: expected a string")
            unibuilder.append(arg.as_unicode())
    if unibuilder is None:
        assert builder is not None
        return W_String.fromascii(builder.build())
    else:
        assert unibuilder is not None
        return W_String.fromunicode(unibuilder.build())
Ejemplo n.º 20
0
 def descr_new(space,
               w_stringtype,
               w_source=None,
               encoding=None,
               errors=None):
     if (w_source and space.is_w(w_stringtype, space.w_bytes)
             and encoding is None and errors is None):
         # special-case 'bytes(byte_object)'
         w_srctype = space.type(w_source)
         if w_srctype is space.w_bytes:
             return w_source
         # special-case 'bytes([single_integer])' or 'bytes((single_int,))'
         # for JITted performance only, when we clearly see the
         # length of the list/tuple being constant and equal to 1
         if w_srctype is space.w_list or w_srctype is space.w_tuple:
             length = space.len_w(w_source)
             if jit.isconstant(length) and length == 1:
                 w_item = space.getitem(w_source, space.newint(0))
                 value = space.byte_w(w_item)
                 return W_BytesObject(value)
         else:
             # special-case 'bytes(X)' if X has a __bytes__() method:
             # we must return the result unmodified even if it is a
             # subclass of bytes
             w_result = invoke_bytes_method(space, w_source)
             if w_result is not None:
                 return w_result
         value = newbytesdata_w_tail(space, w_source)
     else:
         value = newbytesdata_w(space, w_source, encoding, errors)
     w_obj = space.allocate_instance(W_BytesObject, w_stringtype)
     W_BytesObject.__init__(w_obj, value)
     return w_obj
Ejemplo n.º 21
0
 def pow_small_int(self, n):
     if n >= 0:
         if jit.isconstant(n) and n == 2:
             return self.mul(self)
         return self.pow_positive_int(n)
     else:
         return w_one.div(self.pow_positive_int(-n))
Ejemplo n.º 22
0
def convert_string_to_number(s, can_be_octal=False):
    """Returns (wrapped number, flag: number-fully-processed)."""
    length = len(s)
    if jit.isconstant(length) and length == 1:
        # 's' is actually a char.
        return _convert_char_to_number(s[0])
    else:
        return _convert_string_to_number(s, can_be_octal)
Ejemplo n.º 23
0
 def size(self):
     sz = jit.conditional_call_elidable(
         self._exposed_size,
         calculate_exposed_size_for_big_int,
         self.value)
     if not jit.isconstant(self):
         self._exposed_size = sz
     return sz
Ejemplo n.º 24
0
 def getitem_unicode(self, w_dict, w_key):
     storage_w = self.unerase(w_dict.dstorage)
     if jit.isconstant(w_key):
         jit.promote(self)
     index = self.jsonmap.get_index(w_key)
     if index == -1:
         return None
     return storage_w[index]
Ejemplo n.º 25
0
Archivo: misc.py Proyecto: kipras/pypy
def _raw_memcopy(source, dest, size):
    if jit.isconstant(size):
        # for the JIT: first handle the case where 'size' is known to be
        # a constant equal to 1, 2, 4, 8
        for TP, TPP in _prim_unsigned_types:
            if size == rffi.sizeof(TP):
                _raw_memcopy_tp(TPP, source, dest)
                return
    _raw_memcopy_opaque(source, dest, size)
Ejemplo n.º 26
0
 def decrement_ticker(self, by):
     value = self._ticker
     if self.has_bytecode_counter:    # this 'if' is constant-folded
         if jit.isconstant(by) and by == 0:
             pass     # normally constant-folded too
         else:
             value -= by
             self._ticker = value
     return value
Ejemplo n.º 27
0
def _raw_memcopy(source, dest, size):
    if jit.isconstant(size):
        # for the JIT: first handle the case where 'size' is known to be
        # a constant equal to 1, 2, 4, 8
        for TP, TPP in _prim_unsigned_types:
            if size == rffi.sizeof(TP):
                _raw_memcopy_tp(TPP, source, dest)
                return
    _raw_memcopy_opaque(source, dest, size)
Ejemplo n.º 28
0
 def decrement_ticker(self, by):
     p = pypysig_getaddr_occurred()
     value = p.c_value
     if self.has_bytecode_counter:  # this 'if' is constant-folded
         if jit.isconstant(by) and by == 0:
             pass  # normally constant-folded too
         else:
             value -= by
             p.c_value = value
     return value
Ejemplo n.º 29
0
def _pack(space, format, args_w):
    if jit.isconstant(format):
        size = _calcsize(space, format)
    else:
        size = 8
    fmtiter = PackFormatIterator(space, args_w, size)
    try:
        fmtiter.interpret(format)
    except StructOverflowError, e:
        raise OperationError(space.w_OverflowError, space.wrap(e.msg))
Ejemplo n.º 30
0
def pack(space, format, args_w):
    if jit.isconstant(format):
        size = _calcsize(space, format)
    else:
        size = 8
    fmtiter = PackFormatIterator(space, args_w, size)
    try:
        fmtiter.interpret(format)
    except StructOverflowError, e:
        raise OperationError(space.w_OverflowError, space.wrap(e.msg))
Ejemplo n.º 31
0
 def decrement_ticker(self, by):
     p = pypysig_getaddr_occurred()
     value = p.c_value
     if self.has_bytecode_counter:    # this 'if' is constant-folded
         if jit.isconstant(by) and by == 0:
             pass     # normally constant-folded too
         else:
             value -= by
             p.c_value = value
     return value
Ejemplo n.º 32
0
class StringFormatter(object):
    """ From https://github.com/topazproject/topaz"""
    def __init__(self, fmt, items_w):
        assert isinstance(fmt, unicode)
        self.fmt = fmt
        self.items_w = items_w
        self.item_index = 0

    @jit.look_inside_iff(lambda self: jit.isconstant(self.fmt))
    def format(self):
        i = 0
        result_w = []
        while True:
            start = i
            while i < len(self.fmt):
                if self.fmt[i] == "%":
                    break
                i += 1
            else:
                result_w.append(self.fmt[start:i])
                break
            result_w.append(self.fmt[start:i])
            i += 1
            if self.fmt[i] == '.':  # ignore dots TODO
                i += 1
            width = 0
            while self.fmt[i] in [unicode(str(s)) for s in range(0, 9)]:
                width = width * 10 + (ord(self.fmt[i]) - ord("0"))
                i += 1
            format_char = self.fmt[i]
            w_item = self.items_w[self.item_index]
            self.item_index += 1
            i += 1
            for c in FORMAT_CHARS:
                if c == format_char:
                    w_res = getattr(self, "fmt_" + c)(w_item, width)
                    result_w.append(w_res)
                    break
            else:
                raise NotImplementedError(format_char)
        return u''.join(result_w)

    def _fmt_num(self, num, width):
        return (width - len(num)) * u"0" + num

    def fmt_s(self, w_item, width):
        return w_item.str()

    def fmt_d(self, w_item, width):
        num = w_item.str()
        return self._fmt_num(num, width)

    def fmt_f(self, w_item, width):
        num = w_item.to_number()
        return self._fmt_num(unicode(formatd(num, "f", width)), width)
Ejemplo n.º 33
0
 def pushNewArrayBytecode(self, interp, current_bytecode, descriptor):
     arraySize, popIntoArray = splitter[7, 1](descriptor)
     newArray = None
     if popIntoArray == 1:
         if jit.we_are_jitted() and jit.isconstant(arraySize) and arraySize < vmconstants.LITERAL_LIST_UNROLL_SIZE:
             newArray = interp.space.wrap_list_unroll_safe(self.pop_and_return_n(arraySize))
         else:
             newArray = interp.space.wrap_list(self.pop_and_return_n(arraySize))
     else:
         newArray = interp.space.w_Array.as_class_get_shadow(interp.space).new(arraySize)
     self.push(newArray)
Ejemplo n.º 34
0
class W_SRE_Match(W_Root):
    flatten_cache = None

    def __init__(self, srepat, ctx):
        self.space = srepat.space
        self.srepat = srepat
        self.ctx = ctx

    def cannot_copy_w(self):
        space = self.space
        raise OperationError(space.w_TypeError,
                             space.wrap("cannot copy this match object"))

    @jit.look_inside_iff(lambda self, args_w: jit.isconstant(len(args_w)))
    def group_w(self, args_w):
        space = self.space
        ctx = self.ctx
        if len(args_w) <= 1:
            if len(args_w) == 0:
                start, end = ctx.match_start, ctx.match_end
            else:
                start, end = self.do_span(args_w[0])
            return slice_w(space, ctx, start, end, space.w_None)
        else:
            results = [None] * len(args_w)
            for i in range(len(args_w)):
                start, end = self.do_span(args_w[i])
                results[i] = slice_w(space, ctx, start, end, space.w_None)
            return space.newtuple(results)

    @unwrap_spec(w_default=WrappedDefault(None))
    def groups_w(self, w_default=None):
        fmarks = self.flatten_marks()
        num_groups = self.srepat.num_groups
        return allgroups_w(self.space, self.ctx, fmarks, num_groups, w_default)

    @unwrap_spec(w_default=WrappedDefault(None))
    def groupdict_w(self, w_default=None):
        space = self.space
        w_dict = space.newdict()
        w_groupindex = self.srepat.w_groupindex
        w_iterator = space.iter(w_groupindex)
        while True:
            try:
                w_key = space.next(w_iterator)
            except OperationError, e:
                if not e.match(space, space.w_StopIteration):
                    raise
                break  # done
            w_value = space.getitem(w_groupindex, w_key)
            start, end = self.do_span(w_value)
            w_grp = slice_w(space, self.ctx, start, end, w_default)
            space.setitem(w_dict, w_key, w_grp)
        return w_dict
Ejemplo n.º 35
0
def _pack(space, format, args_w):
    if jit.isconstant(format):
        size = _calcsize(space, format)
    else:
        size = 8
    fmtiter = PackFormatIterator(space, args_w, size)
    try:
        fmtiter.interpret(format)
    except StructOverflowError as e:
        raise OperationError(space.w_OverflowError, space.wrap(e.msg))
    except StructError as e:
        raise OperationError(get_error(space), space.wrap(e.msg))
    return fmtiter.result.build()
Ejemplo n.º 36
0
def _pack(space, format, args_w):
    if jit.isconstant(format):
        size = _calcsize(space, format)
    else:
        size = 8
    fmtiter = PackFormatIterator(space, args_w, size)
    try:
        fmtiter.interpret(format)
    except StructOverflowError as e:
        raise OperationError(space.w_OverflowError, space.newtext(e.msg))
    except StructError as e:
        raise OperationError(get_error(space), space.newtext(e.msg))
    return fmtiter.result.build()
Ejemplo n.º 37
0
class StringFormatter(object):
    def __init__(self, fmt, items_w):
        self.fmt = fmt
        self.items_w = items_w
        self.item_index = 0

    @jit.look_inside_iff(lambda self, space: jit.isconstant(self.fmt))
    def format(self, space):
        i = 0
        result_w = []
        while True:
            start = i
            while i < len(self.fmt):
                if self.fmt[i] == "%":
                    break
                i += 1
            else:
                result_w.append(space.newstr_fromstr(self.fmt[start:i]))
                break
            result_w.append(space.newstr_fromstr(self.fmt[start:i]))
            i += 1
            width = 0
            while self.fmt[i].isdigit():
                width = width * 10 + (ord(self.fmt[i]) - ord("0"))
                i += 1
            format_char = self.fmt[i]
            w_item = self.items_w[self.item_index]
            self.item_index += 1
            i += 1
            for c in FORMAT_CHARS:
                if c == format_char:
                    w_res = getattr(self, "fmt_" + c)(space, w_item, width)
                    result_w.append(w_res)
                    break
            else:
                raise NotImplementedError(format_char)
        return result_w

    def _fmt_num(self, space, num, width):
        return space.newstr_fromstr((width - len(num)) * "0" + num)

    def fmt_s(self, space, w_item, width):
        return space.send(w_item, space.newsymbol("to_s"))

    def fmt_d(self, space, w_item, width):
        num = space.int_w(w_item)
        return self._fmt_num(space, str(num), width)

    def fmt_f(self, space, w_item, width):
        num = space.float_w(w_item)
        return self._fmt_num(space, formatd(num, "f", 6), width)
Ejemplo n.º 38
0
def ll_jit_try_append_multiple_char(ll_builder, char, size):
    if jit.isconstant(size):
        if size == 0:
            return True
        # a special case: if the builder's pos and end are still contants
        # (typically if the builder is still virtual), and if 'size' fits,
        # then we don't need any reallocation and can just set the
        # characters in the buffer, in a way that won't force anything.
        if (jit.isconstant(ll_builder.current_pos)
                and jit.isconstant(ll_builder.current_end) and size <=
            (ll_builder.current_end - ll_builder.current_pos) and size <= 16):
            pos = ll_builder.current_pos
            buf = ll_builder.current_buf
            stop = pos + size
            ll_builder.current_pos = stop
            while pos < stop:
                buf.chars[pos] = char
                pos += 1
            return True
        if size == 1:
            ll_append_char(ll_builder, char)
            return True
    return False  # use the fall-back path
Ejemplo n.º 39
0
class UnwrappedVectorStrategyMixin(object):
    # the concrete class needs to implement:
    # erase, unerase, is_correct_type, wrap, unwrap

    def _copy_storage(self, w_vector, immutable=False):
        strategy = self if not immutable else self.immutable_variant()
        l = self.unerase(w_vector.get_storage())[:]
        return W_Vector(strategy, self.erase(l), w_vector.len)

    def _storage(self, w_vector):
        l = self.unerase(w_vector.get_storage())
        debug.make_sure_not_resized(l)
        return l

    def _ref(self, w_vector, i):
        assert i >= 0
        return self.wrap(self._storage(w_vector)[i])

    def _set(self, w_vector, i, w_val):
        assert i >= 0
        self._storage(w_vector)[i] = self.unwrap(w_val)

    @jit.look_inside_iff(lambda strategy, w_vector: jit.isconstant(
        w_vector.length()) and w_vector.length() < UNROLLING_CUTOFF)
    def ref_all(self, w_vector):
        unwrapped = self._storage(w_vector)
        return [self.wrap(i) for i in unwrapped]

    def create_storage_for_element(self, element, times):
        e = self.unwrap(element)
        return self.erase([e] * times)

    @jit.look_inside_iff(lambda self, elements_w: jit.loop_unrolling_heuristic(
        elements_w, len(elements_w), UNROLLING_CUTOFF))
    def create_storage_for_elements(self, elements_w):
        if not elements_w:
            return self.erase([])
        l = [self.unwrap(e) for e in elements_w]
        return self.erase(l)

    def wrap(self, obj):
        return obj

    def unwrap(self, w_obj):
        return w_obj

    def unrolling_heuristic(self, w_vector):
        storage = self._storage(w_vector)
        return jit.loop_unrolling_heuristic(storage, w_vector.len,
                                            UNROLLING_CUTOFF)
Ejemplo n.º 40
0
def _pack(space, format, args_w):
    """Return string containing values v1, v2, ... packed according to fmt."""
    if jit.isconstant(format):
        size = _calcsize(space, format)
    else:
        size = 8
    fmtiter = PackFormatIterator(space, args_w, size)
    try:
        fmtiter.interpret(format)
    except StructOverflowError as e:
        raise OperationError(space.w_OverflowError, space.newtext(e.msg))
    except StructError as e:
        raise OperationError(get_error(space), space.newtext(e.msg))
    return fmtiter.result.build()
Ejemplo n.º 41
0
 def get(self):
     if jit.isconstant(self):
         # ever_mutated is False if we never see a transition from not-None to
         # not-None. That means _elidable_get might return an out-of-date
         # None, and by now the cell was to, with a not-None. So if we see a
         # None, we don't return that and instead read self.w_value in the
         # code below.
         if not self.family.ever_mutated:
             w_res = self._elidable_get()
             if w_res is not None:
                 return w_res
     if self.w_value is None:
         raise ValueError("get() from an empty cell")
     return self.w_value
Ejemplo n.º 42
0
def ll_jit_try_append_slice(ll_builder, ll_str, start, size):
    if jit.isconstant(size):
        if size == 0:
            return True
        # a special case: if the builder's pos and end are still contants
        # (typically if the builder is still virtual), and if 'size' fits,
        # then we don't need any reallocation and can just set the
        # characters in the buffer, in a way that won't force anything.
        if (jit.isconstant(ll_builder.current_pos) and
            jit.isconstant(ll_builder.current_end) and
            size <= (ll_builder.current_end - ll_builder.current_pos) and
            size <= 16):
            pos = ll_builder.current_pos
            buf = ll_builder.current_buf
            stop = pos + size
            ll_builder.current_pos = stop
            while pos < stop:
                buf.chars[pos] = ll_str.chars[start]
                pos += 1
                start += 1
            return True
        # turn appends of length 1 into ll_append_char().
        if size == 1:
            ll_append_char(ll_builder, ll_str.chars[start])
            return True
        # turn appends of length 2 to 10 into residual calls to
        # specialized functions, for the lengths 2 to 10, where
        # gcc will optimize the known-length copy_string_contents()
        # as much as possible.
        for func0, funcstart, for_size in unroll_func_for_size:
            if size == for_size:
                if jit.isconstant(start) and start == 0:
                    func0(ll_builder, ll_str)
                else:
                    funcstart(ll_builder, ll_str, start)
                return True
    return False     # use the fall-back path
Ejemplo n.º 43
0
def ll_jit_try_append_slice(ll_builder, ll_str, start, size):
    if jit.isconstant(size):
        if size == 0:
            return True
        # a special case: if the builder's pos and end are still contants
        # (typically if the builder is still virtual), and if 'size' fits,
        # then we don't need any reallocation and can just set the
        # characters in the buffer, in a way that won't force anything.
        if (jit.isconstant(ll_builder.current_pos)
                and jit.isconstant(ll_builder.current_end) and size <=
            (ll_builder.current_end - ll_builder.current_pos) and size <= 16):
            pos = ll_builder.current_pos
            buf = ll_builder.current_buf
            stop = pos + size
            ll_builder.current_pos = stop
            while pos < stop:
                buf.chars[pos] = ll_str.chars[start]
                pos += 1
                start += 1
            return True
        # turn appends of length 1 into ll_append_char().
        if size == 1:
            ll_append_char(ll_builder, ll_str.chars[start])
            return True
        # turn appends of length 2 to 10 into residual calls to
        # specialized functions, for the lengths 2 to 10, where
        # gcc will optimize the known-length copy_string_contents()
        # as much as possible.
        for func0, funcstart, for_size in unroll_func_for_size:
            if size == for_size:
                if jit.isconstant(start) and start == 0:
                    func0(ll_builder, ll_str)
                else:
                    funcstart(ll_builder, ll_str, start)
                return True
    return False  # use the fall-back path
Ejemplo n.º 44
0
def ll_jit_try_append_multiple_char(ll_builder, char, size):
    if jit.isconstant(size):
        if size == 0:
            return True
        # a special case: if the builder's pos and end are still contants
        # (typically if the builder is still virtual), and if 'size' fits,
        # then we don't need any reallocation and can just set the
        # characters in the buffer, in a way that won't force anything.
        if (jit.isconstant(ll_builder.current_pos) and
            jit.isconstant(ll_builder.current_end) and
            size <= (ll_builder.current_end - ll_builder.current_pos) and
            size <= 16):
            pos = ll_builder.current_pos
            buf = ll_builder.current_buf
            stop = pos + size
            ll_builder.current_pos = stop
            while pos < stop:
                buf.chars[pos] = char
                pos += 1
            return True
        if size == 1:
            ll_append_char(ll_builder, char)
            return True
    return False     # use the fall-back path
Ejemplo n.º 45
0
 def pushNewArrayBytecode(self, interp, current_bytecode, descriptor):
     arraySize, popIntoArray = splitter[7, 1](descriptor)
     newArray = None
     if popIntoArray == 1:
         if jit.we_are_jitted() and jit.isconstant(
                 arraySize
         ) and arraySize < vmconstants.LITERAL_LIST_UNROLL_SIZE:
             newArray = interp.space.wrap_list_unroll_safe(
                 self.pop_and_return_n(arraySize))
         else:
             newArray = interp.space.wrap_list(
                 self.pop_and_return_n(arraySize))
     else:
         newArray = interp.space.w_Array.as_class_get_shadow(
             interp.space).new(arraySize)
     self.push(newArray)
Ejemplo n.º 46
0
 def text_w(self, space):
     try:
         identifier = jit.conditional_call_elidable(self._utf8,
                                                    g_encode_utf8,
                                                    self._value)
     except SurrogateError as e:
         raise OperationError(
             space.w_UnicodeEncodeError,
             space.newtuple([
                 space.newtext('utf-8'), self,
                 space.newint(e.index - 1),
                 space.newint(e.index),
                 space.newtext("surrogates not allowed")
             ]))
     if not jit.isconstant(self):
         self._utf8 = identifier
     return identifier
Ejemplo n.º 47
0
    def __init__(self, space, args_w, keywords=None, keywords_w=None,
                 w_stararg=None, w_starstararg=None, keyword_names_w=None):
        self.space = space
        assert isinstance(args_w, list)
        self.arguments_w = args_w
        self.keywords = keywords
        self.keywords_w = keywords_w
        self.keyword_names_w = keyword_names_w  # matches the tail of .keywords
        if keywords is not None:
            assert keywords_w is not None
            assert len(keywords_w) == len(keywords)
            assert (keyword_names_w is None or
                    len(keyword_names_w) <= len(keywords))
            make_sure_not_resized(self.keywords)
            make_sure_not_resized(self.keywords_w)

        make_sure_not_resized(self.arguments_w)
        self._combine_wrapped(w_stararg, w_starstararg)
        # a flag that specifies whether the JIT can unroll loops that operate
        # on the keywords
        self._jit_few_keywords = self.keywords is None or jit.isconstant(len(self.keywords))
Ejemplo n.º 48
0
 def ffi_type(self, w_x, accept):
     space = self.space
     if (accept & ACCEPT_STRING) and (space.isinstance_w(w_x, space.w_unicode)):
         string = space.str_w(w_x)
         consider_fn_as_fnptr = (accept & CONSIDER_FN_AS_FNPTR) != 0
         if jit.isconstant(string):
             try:
                 return self.get_string_to_type(string, consider_fn_as_fnptr)
             except KeyError:
                 pass
         return self.parse_string_to_type(string, consider_fn_as_fnptr)
     if (accept & ACCEPT_CTYPE) and isinstance(w_x, W_CType):
         return w_x
     if (accept & ACCEPT_CDATA) and isinstance(w_x, W_CData):
         return w_x.ctype
     #
     m1 = "string" if accept & ACCEPT_STRING else ""
     m2 = "ctype object" if accept & ACCEPT_CTYPE else ""
     m3 = "cdata object" if accept & ACCEPT_CDATA else ""
     s12 = " or " if m1 and (m2 or m3) else ""
     s23 = " or " if m2 and m3 else ""
     raise oefmt(space.w_TypeError, "expected a %s%s%s%s%s, got '%T'", m1, s12, m2, s23, m3, w_x)
Ejemplo n.º 49
0
def _rshift(space, a, b):
    if r_uint(b) >= LONG_BIT: # not (0 <= b < LONG_BIT)
        if b < 0:
            raise oefmt(space.w_ValueError, "negative shift count")
        # b >= LONG_BIT
        if a == 0:
            return wrapint(space, a)
        a = -1 if a < 0 else 0
    else:
        a = a >> b
    return wrapint(space, a)


@jit.look_inside_iff(lambda space, iv, iw, iz:
                     jit.isconstant(iw) and jit.isconstant(iz))
def _pow(space, iv, iw, iz):
    """Helper for pow"""
    if iw < 0:
        if iz != 0:
            raise oefmt(space.w_TypeError,
                        "pow() 2nd argument cannot be negative when 3rd "
                        "argument specified")
        # bounce it, since it always returns float
        raise ValueError
    temp = iv
    ix = 1
    while iw > 0:
        if iw & 1:
            ix = ovfcheck(ix * temp)
        iw >>= 1   # Shift exponent down by 1 bit
Ejemplo n.º 50
0
class FormatIterator(object):
    """
    An iterator-like object that follows format strings step by step.
    It provides input to the packer/unpacker and accumulates their output.
    The subclasses are specialized for either packing, unpacking, or
    just computing the size.
    """
    _mixin_ = True
    _operate_is_specialized_ = False

    @jit.look_inside_iff(lambda self, fmt: jit.isconstant(fmt))
    def interpret(self, fmt):
        # decode the byte order, size and alignment based on the 1st char
        table = unroll_native_fmtdescs
        self.bigendian = native_is_bigendian
        index = 0
        if len(fmt) > 0:
            c = fmt[0]
            index = 1
            if c == '@':
                pass
            elif c == '=':
                table = unroll_standard_fmtdescs
            elif c == '<':
                table = unroll_standard_fmtdescs
                self.bigendian = False
            elif c == '>' or c == '!':
                table = unroll_standard_fmtdescs
                self.bigendian = True
            else:
                index = 0

        # interpret the format string,
        # calling self.operate() for each format unit
        while index < len(fmt):
            c = fmt[index]
            index += 1
            if c.isspace():
                continue
            if c.isdigit():
                repetitions = ord(c) - ord('0')
                while True:
                    if index == len(fmt):
                        raise StructError("incomplete struct format")
                    c = fmt[index]
                    index += 1
                    if not c.isdigit():
                        break
                    try:
                        repetitions = ovfcheck(repetitions * 10)
                        repetitions = ovfcheck(repetitions + (ord(c) -
                                                              ord('0')))
                    except OverflowError:
                        raise StructError("overflow in item count")
                assert repetitions >= 0
            else:
                repetitions = 1

            for fmtdesc in table:
                if c == fmtdesc.fmtchar:
                    if self._operate_is_specialized_:
                        if fmtdesc.alignment > 1:
                            self.align(fmtdesc.mask)
                        self.operate(fmtdesc, repetitions)
                    break
            else:
                if c == '\0':
                    raise StructError("embedded null character")
                raise StructError("bad char in struct format")
            if not self._operate_is_specialized_:
                if fmtdesc.alignment > 1:
                    self.align(fmtdesc.mask)
                self.operate(fmtdesc, repetitions)
        self.finished()

    def finished(self):
        pass
Ejemplo n.º 51
0
class BaseTransform(object):
    pass


class ViewTransform(BaseTransform):
    def __init__(self, chunks):
        # 4-tuple specifying slicing
        self.chunks = chunks


class BroadcastTransform(BaseTransform):
    def __init__(self, res_shape):
        self.res_shape = res_shape


@jit.look_inside_iff(lambda chunks: jit.isconstant(len(chunks)))
def enumerate_chunks(chunks):
    result = []
    i = -1
    for chunk in chunks:
        i += chunk.axis_step
        result.append((i, chunk))
    return result


@jit.look_inside_iff(lambda shape, start, strides, backstrides, chunks:
                     jit.isconstant(len(chunks)))
def calculate_slice_strides(shape, start, strides, backstrides, chunks):
    size = 0
    for chunk in chunks:
        if chunk.step != 0:
Ejemplo n.º 52
0
#  The maximal length of RPython lists is bounded by the assumption that
#  we can never allocate arrays more than sys.maxint bytes in size.
#  Our arrays have a length and some GC headers, so a list of characters
#  could come near sys.maxint in length (but not reach it).  A list of
#  pointers could only come near sys.maxint/sizeof(void*) elements.  There
#  is the list of Voids that could reach exactly sys.maxint elements,
#  but for now let's ignore this case -- the reasoning is that even if
#  the length of a Void list overflows, nothing bad memory-wise can be
#  done with it.  So in the sequel we don't bother checking for overflow
#  when we compute "ll_length() + 1".


# jit note: this is normally special-cased by the oopspec,
# but if item != const(0), then the special-casing fails and
# we fall back to the look_inside_iff.
@jit.look_inside_iff(lambda LIST, count, item: jit.isconstant(count) and count < 137)
@jit.oopspec("newlist(count, item)")
def ll_alloc_and_set(LIST, count, item):
    if count < 0:
        count = 0
    l = LIST.ll_newlist(count)
    T = typeOf(item)
    if T is Char or T is UniChar:
        check = ord(item)
    elif isinstance(T, Number):
        check = widen(item)
    else:
        check = item
    # as long as malloc is known to zero the allocated memory avoid zeroing
    # twice
    if jit.we_are_jitted() or (not malloc_zero_filled) or check:
Ejemplo n.º 53
0
def slice_w(space, ctx, start, end, w_default):
    if 0 <= start <= end:
        if isinstance(ctx, rsre_core.BufMatchContext):
            return space.newbytes(ctx._buffer.getslice(start, end, 1,
                                                        end-start))
        if isinstance(ctx, rsre_core.StrMatchContext):
            return space.newbytes(ctx._string[start:end])
        elif isinstance(ctx, rsre_core.UnicodeMatchContext):
            return space.newunicode(ctx._unicodestr[start:end])
        else:
            # unreachable
            raise SystemError
    return w_default


@jit.look_inside_iff(lambda ctx, num_groups: jit.isconstant(num_groups))
def do_flatten_marks(ctx, num_groups):
    # Returns a list of RPython-level integers.
    # Unlike the app-level groups() method, groups are numbered from 0
    # and the returned list does not start with the whole match range.
    if num_groups == 0:
        return None
    result = [-1] * (2 * num_groups)
    mark = ctx.match_marks
    while mark is not None:
        index = jit.promote(mark.gid)
        if result[index] == -1:
            result[index] = mark.position
        mark = mark.prev
    return result
Ejemplo n.º 54
0
        return 'FixedSizeListR %s' % (self.item_repr.compact_repr(),)

    def prepare_const(self, n):
        result = malloc(self.LIST, n, immortal=True)
        return result


# ____________________________________________________________
#
#  Low-level methods.  These can be run for testing, but are meant to
#  be direct_call'ed from rtyped flow graphs, which means that they will
#  get flowed and annotated, mostly with SomePtr.

# adapted C code

@jit.look_inside_iff(lambda l, newsize, overallocate: jit.isconstant(len(l.items)) and jit.isconstant(newsize))
@signature(types.any(), types.int(), types.bool(), returns=types.none())
def _ll_list_resize_hint_really(l, newsize, overallocate):
    """
    Ensure l.items has room for at least newsize elements.  Note that
    l.items may change, and even if newsize is less than l.length on
    entry.
    """
    # This over-allocates proportional to the list size, making room
    # for additional growth.  The over-allocation is mild, but is
    # enough to give linear-time amortized behavior over a long
    # sequence of appends() in the presence of a poorly-performing
    # system malloc().
    # The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
    if newsize <= 0:
        ll_assert(newsize == 0, "negative list length")
Ejemplo n.º 55
0
 def f(n):
     assert isconstant(n) is False
     l = []
     l.append(n)
     return len(l)
Ejemplo n.º 56
0
@unwrap_spec(depth=int)
def _getframe(space, depth=0):
    """Return a frame object from the call stack.  If optional integer depth is
given, return the frame object that many calls below the top of the stack.
If that is deeper than the call stack, ValueError is raised.  The default
for depth is zero, returning the frame at the top of the call stack.

This function should be used for internal and specialized
purposes only."""
    if depth < 0:
        raise OperationError(space.w_ValueError,
                             space.wrap("frame index must not be negative"))
    return getframe(space, depth)


@jit.look_inside_iff(lambda space, depth: jit.isconstant(depth))
def getframe(space, depth):
    ec = space.getexecutioncontext()
    f = ec.gettopframe_nohidden()
    while True:
        if f is None:
            raise OperationError(space.w_ValueError,
                                 space.wrap("call stack is not deep enough"))
        if depth == 0:
            f.mark_as_escaped()
            return space.wrap(f)
        depth -= 1
        f = ec.getnextframe_nohidden(f)


@unwrap_spec(new_limit="c_int")
Ejemplo n.º 57
0
    def _compare(self, w_left, w_right, strict=False, ignore_order=False):

        w_left = w_left.deref()
        w_right = w_right.deref()

        left_tp = w_left.tp
        right_tp = w_right.tp

        if strict:
            if left_tp != right_tp:
                return 1

        if(left_tp == self.tp_float and right_tp == self.tp_float):
            return my_cmp(self.float_w(w_left), self.float_w(w_right),
                          ignore_order)

        if(left_tp == self.tp_int and right_tp == self.tp_float):
            return my_cmp(self.float_w(w_left), self.float_w(w_right),
                          ignore_order)

        if(left_tp == self.tp_float and right_tp == self.tp_int):
            return my_cmp(self.float_w(w_left), self.float_w(w_right),
                          ignore_order)

        elif(left_tp == self.tp_int and right_tp == self.tp_int):
            return my_cmp(self.int_w(w_left), self.int_w(w_right),
                          ignore_order)

        elif(left_tp == self.tp_array and right_tp == self.tp_array):
            return self._compare_array(w_left, w_right, strict)

        elif(left_tp == self.tp_null and right_tp == self.tp_null):
            return 0

        elif(left_tp == self.tp_null and right_tp == self.tp_bool):
            if self.is_true(w_right):
                return -1
            return 0

        elif(left_tp == self.tp_bool and right_tp == self.tp_null):
            if self.is_true(w_left):
                return 1
            return 0

        elif(left_tp == self.tp_bool and right_tp == self.tp_bool):
            return my_cmp(self.is_true(w_left), self.is_true(w_right),
                          ignore_order)

        elif(left_tp == self.tp_str and right_tp == self.tp_str):
            left  = self.str_w(w_left)
            right = self.str_w(w_right)
            if not strict:
                # a small optimimization first, if both are single-char
                left_length  = len(left)
                right_length = len(right)
                if (jit.isconstant(left_length)  and left_length  == 1 and
                    jit.isconstant(right_length) and right_length == 1):
                    return my_cmp(ord(left[0]), ord(right[0]), ignore_order)
                #
                w_right_num, right_valid = convert_string_to_number(right)
                if right_valid:
                    w_left_num, left_valid = convert_string_to_number(left)
                    if left_valid:
                        return self._compare(w_left_num, w_right_num,
                                             ignore_order=ignore_order)
            return my_cmp(left, right, ignore_order)

        elif(left_tp == self.tp_null and right_tp == self.tp_str):
            return my_cmp("", self.str_w(w_right), ignore_order)

        elif(left_tp == self.tp_str and right_tp == self.tp_null):
            return my_cmp(self.str_w(w_left), "", ignore_order)

        elif(left_tp == self.tp_object and right_tp == self.tp_null):
            return 1

        elif(left_tp == self.tp_null and right_tp == self.tp_object):
            return -1

        elif(left_tp == self.tp_object and right_tp == self.tp_object):
            return w_left.compare(w_right, self, strict)

        else:
            if(left_tp == self.tp_null):
                if self.is_true(w_right):
                    return -1
                return 0
            elif(right_tp == self.tp_null):
                if self.is_true(w_left):
                    return 1
                return 0
            elif(left_tp == self.tp_bool or right_tp == self.tp_bool):
                return my_cmp(self.is_true(w_left), self.is_true(w_right),
                              ignore_order)
            elif(left_tp == self.tp_array):
                return 1
            elif(right_tp == self.tp_array):
                return -1
            elif(left_tp == self.tp_object):
                return 1
            elif(right_tp == self.tp_object):
                return -1
            else:
                return self._compare(self.as_number(w_left),
                                     self.as_number(w_right),
                                     ignore_order=ignore_order)
        raise NotImplementedError()
Ejemplo n.º 58
0
    fmt = args[0]
    if not isinstance(fmt, values_string.W_String):
        raise SchemeException("printf: expected a format string, got something else")
    return do_print(format(fmt, args[1:], "printf"), None, env, cont)

@expose("eprintf", simple=False)
def eprintf(args, env, cont):
    if not args:
        raise SchemeException("eprintf: expected at least one argument, got 0")
    fmt = args[0]
    if not isinstance(fmt, values_string.W_String):
        raise SchemeException("eprintf: expected a format string, got something else")
    return do_print(format(fmt, args[1:], "eprintf"), current_error_param.get(cont), env, cont)

@expose("format")
@jit.look_inside_iff(lambda args: jit.isconstant(args[0]))
def do_format(args):
    if len(args) == 0:
        raise SchemeException("format: expects format string")
    fmt = args[0]
    if not isinstance(fmt, values_string.W_String):
        raise SchemeException("format: expected a format string, got something else")
    vals = args[1:]
    return values_string.W_String.fromstr_utf8(format(fmt, vals, "format"))

@expose("fprintf", simple=False)
def do_fprintf(args, env, cont):
    out, form, v = args[0], args[1], args[2:]
    assert isinstance(out, values.W_OutputPort)
    assert isinstance(form, values_string.W_String)
    out.write(format(form, v, "fprintf"))