Author: Ronan Lamy <[email protected]>
Branch: py3k
Changeset: r83527:e186dd71a5e7
Date: 2016-04-05 19:13 +0100
http://bitbucket.org/pypy/pypy/changeset/e186dd71a5e7/
Log: hg merge default
diff too long, truncating to 2000 out of 10146 lines
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -67,7 +67,8 @@
subvalue = subfield.ctype
fields[subname] = Field(subname,
relpos,
subvalue._sizeofinstances(),
- subvalue, i, is_bitfield)
+ subvalue, i, is_bitfield,
+ inside_anon_field=fields[name])
else:
resnames.append(name)
names = resnames
@@ -77,13 +78,15 @@
class Field(object):
- def __init__(self, name, offset, size, ctype, num, is_bitfield):
+ def __init__(self, name, offset, size, ctype, num, is_bitfield,
+ inside_anon_field=None):
self.__dict__['name'] = name
self.__dict__['offset'] = offset
self.__dict__['size'] = size
self.__dict__['ctype'] = ctype
self.__dict__['num'] = num
self.__dict__['is_bitfield'] = is_bitfield
+ self.__dict__['inside_anon_field'] = inside_anon_field
def __setattr__(self, name, value):
raise AttributeError(name)
@@ -95,6 +98,8 @@
def __get__(self, obj, cls=None):
if obj is None:
return self
+ if self.inside_anon_field is not None:
+ return getattr(self.inside_anon_field.__get__(obj), self.name)
if self.is_bitfield:
# bitfield member, use direct access
return obj._buffer.__getattr__(self.name)
@@ -105,6 +110,9 @@
return fieldtype._CData_output(suba, obj, offset)
def __set__(self, obj, value):
+ if self.inside_anon_field is not None:
+ setattr(self.inside_anon_field.__get__(obj), self.name, value)
+ return
fieldtype = self.ctype
cobj = fieldtype.from_param(value)
key = keepalive_key(self.num)
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -48,7 +48,6 @@
except detect_cpu.ProcessorAutodetectError:
pass
-
translation_modules = default_modules.copy()
translation_modules.update([
"fcntl", "time", "select", "signal", "_rawffi", "zlib", "struct",
diff --git a/pypy/doc/__pypy__-module.rst b/pypy/doc/__pypy__-module.rst
--- a/pypy/doc/__pypy__-module.rst
+++ b/pypy/doc/__pypy__-module.rst
@@ -18,6 +18,7 @@
- ``bytebuffer(length)``: return a new read-write buffer of the given length.
It works like a simplified array of characters (actually, depending on the
configuration the ``array`` module internally uses this).
+ - ``attach_gdb()``: start a GDB at the interpreter-level (or a PDB before
translation).
Transparent Proxy Functionality
@@ -37,4 +38,3 @@
--------------------------------------------------------
- ``isfake(obj)``: returns True if ``obj`` is faked.
- - ``interp_pdb()``: start a pdb at interpreter-level.
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -23,3 +23,15 @@
Implement yet another strange numpy indexing compatibility; indexing by a
scalar
returns a scalar
+
+.. branch: fix_transpose_for_list_v3
+
+Allow arguments to transpose to be sequences
+
+.. branch: jit-leaner-frontend
+
+Improve the tracing speed in the frontend as well as heapcache by using a more
compact representation
+of traces
+
+.. branch: win32-lib-name
+
diff --git a/pypy/goal/targetpypystandalone.py
b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -247,8 +247,9 @@
"when --shared is on (it is by default). "
"See issue #1971.")
if sys.platform == 'win32':
- config.translation.libname = '..\\..\\libs\\python27.lib'
- thisdir.join('..', '..', 'libs').ensure(dir=1)
+ libdir = thisdir.join('..', '..', 'libs')
+ libdir.ensure(dir=1)
+ config.translation.libname = str(libdir.join('python27.lib'))
if config.translation.thread:
config.objspace.usemodules.thread = True
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -316,13 +316,7 @@
return tb
def set_traceback(self, traceback):
- """Set the current traceback. It should either be a traceback
- pointing to some already-escaped frame, or a traceback for the
- current frame. To support the latter case we do not mark the
- frame as escaped. The idea is that it will be marked as escaping
- only if the exception really propagates out of this frame, by
- executioncontext.leave() being called with got_exception=True.
- """
+ """Set the current traceback."""
self._application_traceback = traceback
def remove_traceback_module_frames(self, module_name):
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -88,6 +88,7 @@
'save_module_content_for_future_reload':
'interp_magic.save_module_content_for_future_reload',
'decode_long' : 'interp_magic.decode_long',
+ '_promote' : 'interp_magic._promote',
'normalize_exc' : 'interp_magic.normalize_exc',
'StdErrPrinter' : 'interp_stderrprinter.W_StdErrPrinter',
}
diff --git a/pypy/module/__pypy__/interp_magic.py
b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -148,6 +148,26 @@
raise oefmt(space.w_ValueError, "invalid byteorder argument")
return space.newlong_from_rbigint(result)
+def _promote(space, w_obj):
+ """ Promote the first argument of the function and return it. Promote is by
+ value for ints, floats, strs, unicodes (but not subclasses thereof) and by
+ reference otherwise. (Unicodes not supported right now.)
+
+ This function is experimental!"""
+ from rpython.rlib import jit
+ if space.is_w(space.type(w_obj), space.w_int):
+ jit.promote(space.int_w(w_obj))
+ elif space.is_w(space.type(w_obj), space.w_float):
+ jit.promote(space.float_w(w_obj))
+ elif space.is_w(space.type(w_obj), space.w_str):
+ jit.promote_string(space.str_w(w_obj))
+ elif space.is_w(space.type(w_obj), space.w_unicode):
+ raise OperationError(space.w_TypeError, space.wrap(
+ "promoting unicode unsupported"))
+ else:
+ jit.promote(w_obj)
+ return w_obj
+
@unwrap_spec(w_value=WrappedDefault(None), w_tb=WrappedDefault(None))
def normalize_exc(space, w_type, w_value=None, w_tb=None):
operr = OperationError(w_type, w_value, w_tb)
diff --git a/pypy/module/__pypy__/test/test_magic.py
b/pypy/module/__pypy__/test/test_magic.py
--- a/pypy/module/__pypy__/test/test_magic.py
+++ b/pypy/module/__pypy__/test/test_magic.py
@@ -51,3 +51,16 @@
assert decode_long(b'\x00\x80', 'little', False) == 32768
assert decode_long(b'\x00\x80', 'little', True) == -32768
raises(ValueError, decode_long, '', 'foo')
+
+ def test_promote(self):
+ from __pypy__ import _promote
+ assert _promote(1) == 1
+ assert _promote(1.1) == 1.1
+ assert _promote("abc") == "abc"
+ assert _promote(u"abc") == u"abc"
+ l = []
+ assert _promote(l) is l
+ class A(object):
+ pass
+ a = A()
+ assert _promote(a) is a
diff --git a/pypy/module/_multibytecodec/src/cjkcodecs/cjkcodecs.h
b/pypy/module/_multibytecodec/src/cjkcodecs/cjkcodecs.h
--- a/pypy/module/_multibytecodec/src/cjkcodecs/cjkcodecs.h
+++ b/pypy/module/_multibytecodec/src/cjkcodecs/cjkcodecs.h
@@ -10,6 +10,7 @@
#define _CJKCODECS_H_
#include "src/cjkcodecs/multibytecodec.h"
+#include "src/cjkcodecs/fixnames.h"
/* a unicode "undefined" codepoint */
diff --git a/pypy/module/_multibytecodec/src/cjkcodecs/fixnames.h
b/pypy/module/_multibytecodec/src/cjkcodecs/fixnames.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/_multibytecodec/src/cjkcodecs/fixnames.h
@@ -0,0 +1,9 @@
+
+/* this is only included from the .c files in this directory: rename
+ these pypymbc-prefixed names to locally define the CPython names */
+typedef pypymbc_ssize_t Py_ssize_t;
+#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t) -1) >> 1))
+#define Py_UNICODE_SIZE pypymbc_UNICODE_SIZE
+typedef pypymbc_wchar_t Py_UNICODE;
+typedef pypymbc_ucs4_t ucs4_t;
+typedef pypymbc_ucs2_t ucs2_t, DBCHAR;
diff --git a/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.c
b/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.c
--- a/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.c
+++ b/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.c
@@ -1,6 +1,7 @@
#include <stdlib.h>
#include <string.h>
#include "src/cjkcodecs/multibytecodec.h"
+#include "src/cjkcodecs/fixnames.h"
struct pypy_cjk_dec_s *pypy_cjk_dec_new(const MultibyteCodec *codec)
diff --git a/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h
b/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h
--- a/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h
+++ b/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h
@@ -9,31 +9,28 @@
#include <assert.h>
#ifdef _WIN64
-typedef __int64 ssize_t
+typedef __int64 pypymbc_ssize_t
#elif defined(_WIN32)
-typedef int ssize_t;
+typedef int pypymbc_ssize_t;
#else
#include <unistd.h>
-#endif
-
-#ifndef Py_UNICODE_SIZE
-#ifdef _WIN32
-#define Py_UNICODE_SIZE 2
-#else
-#define Py_UNICODE_SIZE 4
-#endif
-typedef wchar_t Py_UNICODE;
-typedef ssize_t Py_ssize_t;
-#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t) -1) >> 1))
+typedef ssize_t pypymbc_ssize_t;
#endif
#ifdef _WIN32
-typedef unsigned int ucs4_t;
-typedef unsigned short ucs2_t, DBCHAR;
+#define pypymbc_UNICODE_SIZE 2
+#else
+#define pypymbc_UNICODE_SIZE 4
+#endif
+typedef wchar_t pypymbc_wchar_t;
+
+#ifdef _WIN32
+typedef unsigned int pypymbc_ucs4_t;
+typedef unsigned short pypymbc_ucs2_t;
#else
#include <stdint.h>
-typedef uint32_t ucs4_t;
-typedef uint16_t ucs2_t, DBCHAR;
+typedef uint32_t pypymbc_ucs4_t;
+typedef uint16_t pypymbc_ucs2_t;
#endif
@@ -42,28 +39,28 @@
void *p;
int i;
unsigned char c[8];
- ucs2_t u2[4];
- ucs4_t u4[2];
+ pypymbc_ucs2_t u2[4];
+ pypymbc_ucs4_t u4[2];
} MultibyteCodec_State;
typedef int (*mbcodec_init)(const void *config);
-typedef Py_ssize_t (*mbencode_func)(MultibyteCodec_State *state,
+typedef pypymbc_ssize_t (*mbencode_func)(MultibyteCodec_State *state,
const void *config,
- const Py_UNICODE **inbuf, Py_ssize_t inleft,
- unsigned char **outbuf, Py_ssize_t outleft,
+ const pypymbc_wchar_t **inbuf, pypymbc_ssize_t inleft,
+ unsigned char **outbuf, pypymbc_ssize_t outleft,
int flags);
typedef int (*mbencodeinit_func)(MultibyteCodec_State *state,
const void *config);
-typedef Py_ssize_t (*mbencodereset_func)(MultibyteCodec_State *state,
+typedef pypymbc_ssize_t (*mbencodereset_func)(MultibyteCodec_State *state,
const void *config,
- unsigned char **outbuf, Py_ssize_t outleft);
-typedef Py_ssize_t (*mbdecode_func)(MultibyteCodec_State *state,
+ unsigned char **outbuf, pypymbc_ssize_t outleft);
+typedef pypymbc_ssize_t (*mbdecode_func)(MultibyteCodec_State *state,
const void *config,
- const unsigned char **inbuf, Py_ssize_t inleft,
- Py_UNICODE **outbuf, Py_ssize_t outleft);
+ const unsigned char **inbuf, pypymbc_ssize_t inleft,
+ pypymbc_wchar_t **outbuf, pypymbc_ssize_t outleft);
typedef int (*mbdecodeinit_func)(MultibyteCodec_State *state,
const void *config);
-typedef Py_ssize_t (*mbdecodereset_func)(MultibyteCodec_State *state,
+typedef pypymbc_ssize_t (*mbdecodereset_func)(MultibyteCodec_State *state,
const void *config);
typedef struct MultibyteCodec_s {
@@ -94,59 +91,59 @@
const MultibyteCodec *codec;
MultibyteCodec_State state;
const unsigned char *inbuf_start, *inbuf, *inbuf_end;
- Py_UNICODE *outbuf_start, *outbuf, *outbuf_end;
+ pypymbc_wchar_t *outbuf_start, *outbuf, *outbuf_end;
};
RPY_EXTERN
struct pypy_cjk_dec_s *pypy_cjk_dec_new(const MultibyteCodec *codec);
RPY_EXTERN
-Py_ssize_t pypy_cjk_dec_init(struct pypy_cjk_dec_s *d,
- char *inbuf, Py_ssize_t inlen);
+pypymbc_ssize_t pypy_cjk_dec_init(struct pypy_cjk_dec_s *d,
+ char *inbuf, pypymbc_ssize_t inlen);
RPY_EXTERN
void pypy_cjk_dec_free(struct pypy_cjk_dec_s *);
RPY_EXTERN
-Py_ssize_t pypy_cjk_dec_chunk(struct pypy_cjk_dec_s *);
+pypymbc_ssize_t pypy_cjk_dec_chunk(struct pypy_cjk_dec_s *);
RPY_EXTERN
-Py_UNICODE *pypy_cjk_dec_outbuf(struct pypy_cjk_dec_s *);
+pypymbc_wchar_t *pypy_cjk_dec_outbuf(struct pypy_cjk_dec_s *);
RPY_EXTERN
-Py_ssize_t pypy_cjk_dec_outlen(struct pypy_cjk_dec_s *);
+pypymbc_ssize_t pypy_cjk_dec_outlen(struct pypy_cjk_dec_s *);
RPY_EXTERN
-Py_ssize_t pypy_cjk_dec_inbuf_remaining(struct pypy_cjk_dec_s *d);
+pypymbc_ssize_t pypy_cjk_dec_inbuf_remaining(struct pypy_cjk_dec_s *d);
RPY_EXTERN
-Py_ssize_t pypy_cjk_dec_inbuf_consumed(struct pypy_cjk_dec_s* d);
+pypymbc_ssize_t pypy_cjk_dec_inbuf_consumed(struct pypy_cjk_dec_s* d);
RPY_EXTERN
-Py_ssize_t pypy_cjk_dec_replace_on_error(struct pypy_cjk_dec_s* d,
- Py_UNICODE *, Py_ssize_t, Py_ssize_t);
+pypymbc_ssize_t pypy_cjk_dec_replace_on_error(struct pypy_cjk_dec_s* d,
+ pypymbc_wchar_t *, pypymbc_ssize_t,
pypymbc_ssize_t);
struct pypy_cjk_enc_s {
const MultibyteCodec *codec;
MultibyteCodec_State state;
- const Py_UNICODE *inbuf_start, *inbuf, *inbuf_end;
+ const pypymbc_wchar_t *inbuf_start, *inbuf, *inbuf_end;
unsigned char *outbuf_start, *outbuf, *outbuf_end;
};
RPY_EXTERN
struct pypy_cjk_enc_s *pypy_cjk_enc_new(const MultibyteCodec *codec);
RPY_EXTERN
-Py_ssize_t pypy_cjk_enc_init(struct pypy_cjk_enc_s *d,
- Py_UNICODE *inbuf, Py_ssize_t inlen);
+pypymbc_ssize_t pypy_cjk_enc_init(struct pypy_cjk_enc_s *d,
+ pypymbc_wchar_t *inbuf, pypymbc_ssize_t inlen);
RPY_EXTERN
void pypy_cjk_enc_free(struct pypy_cjk_enc_s *);
RPY_EXTERN
-Py_ssize_t pypy_cjk_enc_chunk(struct pypy_cjk_enc_s *, Py_ssize_t);
+pypymbc_ssize_t pypy_cjk_enc_chunk(struct pypy_cjk_enc_s *, pypymbc_ssize_t);
RPY_EXTERN
-Py_ssize_t pypy_cjk_enc_reset(struct pypy_cjk_enc_s *);
+pypymbc_ssize_t pypy_cjk_enc_reset(struct pypy_cjk_enc_s *);
RPY_EXTERN
char *pypy_cjk_enc_outbuf(struct pypy_cjk_enc_s *);
RPY_EXTERN
-Py_ssize_t pypy_cjk_enc_outlen(struct pypy_cjk_enc_s *);
+pypymbc_ssize_t pypy_cjk_enc_outlen(struct pypy_cjk_enc_s *);
RPY_EXTERN
-Py_ssize_t pypy_cjk_enc_inbuf_remaining(struct pypy_cjk_enc_s *d);
+pypymbc_ssize_t pypy_cjk_enc_inbuf_remaining(struct pypy_cjk_enc_s *d);
RPY_EXTERN
-Py_ssize_t pypy_cjk_enc_inbuf_consumed(struct pypy_cjk_enc_s* d);
+pypymbc_ssize_t pypy_cjk_enc_inbuf_consumed(struct pypy_cjk_enc_s* d);
RPY_EXTERN
-Py_ssize_t pypy_cjk_enc_replace_on_error(struct pypy_cjk_enc_s* d,
- char *, Py_ssize_t, Py_ssize_t);
+pypymbc_ssize_t pypy_cjk_enc_replace_on_error(struct pypy_cjk_enc_s* d,
+ char *, pypymbc_ssize_t,
pypymbc_ssize_t);
RPY_EXTERN
const MultibyteCodec *pypy_cjk_enc_getcodec(struct pypy_cjk_enc_s *);
@@ -191,5 +188,7 @@
DEFINE_CODEC(big5)
DEFINE_CODEC(cp950)
+#undef DEFINE_CODEC
+
#endif
diff --git a/pypy/module/cpyext/test/test_sequence.py
b/pypy/module/cpyext/test/test_sequence.py
--- a/pypy/module/cpyext/test/test_sequence.py
+++ b/pypy/module/cpyext/test/test_sequence.py
@@ -90,8 +90,10 @@
self.raises(space, api, IndexError, api.PySequence_SetItem,
l, 3, w_value)
+ t = api.PyTuple_New(1)
+ api.PyTuple_SetItem(t, 0, l)
self.raises(space, api, TypeError, api.PySequence_SetItem,
- api.PyTuple_New(1), 0, w_value)
+ t, 0, w_value)
self.raises(space, api, TypeError, api.PySequence_SetItem,
space.newdict(), 0, w_value)
diff --git a/pypy/module/cpyext/test/test_tupleobject.py
b/pypy/module/cpyext/test/test_tupleobject.py
--- a/pypy/module/cpyext/test/test_tupleobject.py
+++ b/pypy/module/cpyext/test/test_tupleobject.py
@@ -5,6 +5,7 @@
from pypy.module.cpyext.test.test_api import BaseApiTest
from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rlib.debug import FatalError
class TestTupleObject(BaseApiTest):
@@ -18,29 +19,44 @@
#assert api.PyTuple_GET_SIZE(atuple) == 3 --- now a C macro
raises(TypeError, api.PyTuple_Size(space.newlist([])))
api.PyErr_Clear()
-
+
+ def test_tuple_realize_refuses_nulls(self, space, api):
+ py_tuple = api.PyTuple_New(1)
+ py.test.raises(FatalError, from_ref, space, py_tuple)
+
def test_tuple_resize(self, space, api):
w_42 = space.wrap(42)
+ w_43 = space.wrap(43)
+ w_44 = space.wrap(44)
ar = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
py_tuple = api.PyTuple_New(3)
# inside py_tuple is an array of "PyObject *" items which each hold
# a reference
rffi.cast(PyTupleObject, py_tuple).c_ob_item[0] = make_ref(space, w_42)
+ rffi.cast(PyTupleObject, py_tuple).c_ob_item[1] = make_ref(space, w_43)
ar[0] = py_tuple
api._PyTuple_Resize(ar, 2)
w_tuple = from_ref(space, ar[0])
assert space.int_w(space.len(w_tuple)) == 2
assert space.int_w(space.getitem(w_tuple, space.wrap(0))) == 42
+ assert space.int_w(space.getitem(w_tuple, space.wrap(1))) == 43
api.Py_DecRef(ar[0])
py_tuple = api.PyTuple_New(3)
rffi.cast(PyTupleObject, py_tuple).c_ob_item[0] = make_ref(space, w_42)
+ rffi.cast(PyTupleObject, py_tuple).c_ob_item[1] = make_ref(space, w_43)
+ rffi.cast(PyTupleObject, py_tuple).c_ob_item[2] = make_ref(space, w_44)
ar[0] = py_tuple
api._PyTuple_Resize(ar, 10)
+ assert api.PyTuple_Size(ar[0]) == 10
+ for i in range(3, 10):
+ rffi.cast(PyTupleObject, py_tuple).c_ob_item[i] = make_ref(
+ space, space.wrap(42 + i))
w_tuple = from_ref(space, ar[0])
assert space.int_w(space.len(w_tuple)) == 10
- assert space.int_w(space.getitem(w_tuple, space.wrap(0))) == 42
+ for i in range(10):
+ assert space.int_w(space.getitem(w_tuple, space.wrap(i))) == 42 + i
api.Py_DecRef(ar[0])
lltype.free(ar, flavor='raw')
diff --git a/pypy/module/cpyext/tupleobject.py
b/pypy/module/cpyext/tupleobject.py
--- a/pypy/module/cpyext/tupleobject.py
+++ b/pypy/module/cpyext/tupleobject.py
@@ -1,5 +1,6 @@
from pypy.interpreter.error import OperationError
from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rlib.debug import fatalerror_notb
from pypy.module.cpyext.api import (cpython_api, Py_ssize_t, CANNOT_FAIL,
build_type_checkers, PyObjectFields,
cpython_struct, bootstrap_function)
@@ -91,14 +92,22 @@
def tuple_realize(space, py_obj):
"""
Creates the tuple in the interpreter. The PyTupleObject must not
- be modified after this call.
+ be modified after this call. We check that it does not contain
+ any NULLs at this point (which would correspond to half-broken
+ W_TupleObjects).
"""
py_tup = rffi.cast(PyTupleObject, py_obj)
l = py_tup.c_ob_size
p = py_tup.c_ob_item
items_w = [None] * l
for i in range(l):
- items_w[i] = from_ref(space, p[i])
+ w_item = from_ref(space, p[i])
+ if w_item is None:
+ fatalerror_notb(
+ "Fatal error in cpyext, CPython compatibility layer: "
+ "converting a PyTupleObject into a W_TupleObject, "
+ "but found NULLs as items")
+ items_w[i] = w_item
w_obj = space.newtuple(items_w)
track_reference(space, py_obj, w_obj)
return w_obj
diff --git a/pypy/module/micronumpy/ndarray.py
b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -502,29 +502,34 @@
return W_NDimArray(self.implementation.transpose(self, axes))
def descr_transpose(self, space, args_w):
- if len(args_w) == 1 and space.isinstance_w(args_w[0], space.w_tuple):
- args_w = space.fixedview(args_w[0])
- if (len(args_w) == 0 or
- len(args_w) == 1 and space.is_none(args_w[0])):
+ if len(args_w) == 0 or len(args_w) == 1 and space.is_none(args_w[0]):
return self.descr_get_transpose(space)
else:
- if len(args_w) != self.ndims():
- raise oefmt(space.w_ValueError, "axes don't match array")
- axes = []
- axes_seen = [False] * self.ndims()
- for w_arg in args_w:
- try:
- axis = support.index_w(space, w_arg)
- except OperationError:
- raise oefmt(space.w_TypeError, "an integer is required")
- if axis < 0 or axis >= self.ndims():
- raise oefmt(space.w_ValueError, "invalid axis for this
array")
- if axes_seen[axis] is True:
- raise oefmt(space.w_ValueError, "repeated axis in
transpose")
- axes.append(axis)
- axes_seen[axis] = True
- return self.descr_get_transpose(space, axes)
+ if len(args_w) > 1:
+ axes = args_w
+ else: # Iterable in the only argument (len(arg_w) == 1 and
arg_w[0] is not None)
+ axes = space.fixedview(args_w[0])
+ axes = self._checked_axes(axes, space)
+ return self.descr_get_transpose(space, axes)
+
+ def _checked_axes(self, axes_raw, space):
+ if len(axes_raw) != self.ndims():
+ raise oefmt(space.w_ValueError, "axes don't match array")
+ axes = []
+ axes_seen = [False] * self.ndims()
+ for elem in axes_raw:
+ try:
+ axis = support.index_w(space, elem)
+ except OperationError:
+ raise oefmt(space.w_TypeError, "an integer is required")
+ if axis < 0 or axis >= self.ndims():
+ raise oefmt(space.w_ValueError, "invalid axis for this array")
+ if axes_seen[axis] is True:
+ raise oefmt(space.w_ValueError, "repeated axis in transpose")
+ axes.append(axis)
+ axes_seen[axis] = True
+ return axes
@unwrap_spec(axis1=int, axis2=int)
def descr_swapaxes(self, space, axis1, axis2):
diff --git a/pypy/module/micronumpy/test/test_ndarray.py
b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -2951,6 +2951,36 @@
assert (a.transpose() == b).all()
assert (a.transpose(None) == b).all()
+ def test_transpose_arg_tuple(self):
+ import numpy as np
+ a = np.arange(24).reshape(2, 3, 4)
+ transpose_args = a.transpose(1, 2, 0)
+
+ transpose_test = a.transpose((1, 2, 0))
+
+ assert transpose_test.shape == (3, 4, 2)
+ assert (transpose_args == transpose_test).all()
+
+ def test_transpose_arg_list(self):
+ import numpy as np
+ a = np.arange(24).reshape(2, 3, 4)
+ transpose_args = a.transpose(1, 2, 0)
+
+ transpose_test = a.transpose([1, 2, 0])
+
+ assert transpose_test.shape == (3, 4, 2)
+ assert (transpose_args == transpose_test).all()
+
+ def test_transpose_arg_array(self):
+ import numpy as np
+ a = np.arange(24).reshape(2, 3, 4)
+ transpose_args = a.transpose(1, 2, 0)
+
+ transpose_test = a.transpose(np.array([1, 2, 0]))
+
+ assert transpose_test.shape == (3, 4, 2)
+ assert (transpose_args == transpose_test).all()
+
def test_transpose_error(self):
import numpy as np
a = np.arange(24).reshape(2, 3, 4)
@@ -2959,6 +2989,11 @@
raises(ValueError, a.transpose, 1, 0, 1)
raises(TypeError, a.transpose, 1, 0, '2')
+ def test_transpose_unexpected_argument(self):
+ import numpy as np
+ a = np.array([[1, 2], [3, 4], [5, 6]])
+ raises(TypeError, 'a.transpose(axes=(1,2,0))')
+
def test_flatiter(self):
from numpy import array, flatiter, arange, zeros
a = array([[10, 30], [40, 60]])
diff --git a/pypy/module/operator/app_operator.py
b/pypy/module/operator/app_operator.py
--- a/pypy/module/operator/app_operator.py
+++ b/pypy/module/operator/app_operator.py
@@ -23,51 +23,42 @@
else:
return _resolve_attr_chain(chain, obj, idx + 1)
-
-class _simple_attrgetter(object):
- def __init__(self, attr):
- self._attr = attr
+class attrgetter(object):
+ def __init__(self, attr, *attrs):
+ if (
+ not isinstance(attr, str) or
+ not all(isinstance(a, str) for a in attrs)
+ ):
+ raise TypeError("attribute name must be a string, not %r" %
+ type(attr).__name__)
+ elif attrs:
+ self._multi_attrs = [
+ a.split(".") for a in [attr] + list(attrs)
+ ]
+ self._call = self._multi_attrgetter
+ elif "." not in attr:
+ self._simple_attr = attr
+ self._call = self._simple_attrgetter
+ else:
+ self._single_attr = attr.split(".")
+ self._call = self._single_attrgetter
def __call__(self, obj):
- return getattr(obj, self._attr)
+ return self._call(obj)
+ def _simple_attrgetter(self, obj):
+ return getattr(obj, self._simple_attr)
-class _single_attrgetter(object):
- def __init__(self, attrs):
- self._attrs = attrs
+ def _single_attrgetter(self, obj):
+ return _resolve_attr_chain(self._single_attr, obj)
- def __call__(self, obj):
- return _resolve_attr_chain(self._attrs, obj)
-
-
-class _multi_attrgetter(object):
- def __init__(self, attrs):
- self._attrs = attrs
-
- def __call__(self, obj):
+ def _multi_attrgetter(self, obj):
return tuple([
_resolve_attr_chain(attrs, obj)
- for attrs in self._attrs
+ for attrs in self._multi_attrs
])
-def attrgetter(attr, *attrs):
- if (
- not isinstance(attr, str) or
- not all(isinstance(a, str) for a in attrs)
- ):
- raise TypeError("attribute name must be a string, not %r" %
- type(attr).__name__)
- if attrs:
- return _multi_attrgetter([
- a.split(".") for a in [attr] + list(attrs)
- ])
- elif "." not in attr:
- return _simple_attrgetter(attr)
- else:
- return _single_attrgetter(attr.split("."))
-
-
class itemgetter(object):
def __init__(self, item, *items):
self._single = not bool(items)
diff --git a/pypy/module/operator/test/test_operator.py
b/pypy/module/operator/test/test_operator.py
--- a/pypy/module/operator/test/test_operator.py
+++ b/pypy/module/operator/test/test_operator.py
@@ -50,7 +50,13 @@
a.name = "hello"
a.child = A()
a.child.name = "world"
+ a.child.foo = "bar"
assert attrgetter("child.name")(a) == "world"
+ assert attrgetter("child.name", "child.foo")(a) == ("world", "bar")
+
+ def test_attrgetter_type(self):
+ from operator import attrgetter
+ assert type(attrgetter("child.name")) is attrgetter
def test_concat(self):
class Seq1:
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py
b/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py
@@ -57,3 +57,32 @@
assert Y.y.offset == sizeof(c_int) * 2
assert Y._names_ == ['x', 'a', 'b', 'y']
+
+ def test_anonymous_fields_on_instance(self):
+ # this is about the *instance-level* access of anonymous fields,
+ # which you'd guess is the most common, but used not to work
+ # (issue #2230)
+
+ class B(Structure):
+ _fields_ = [("x", c_int), ("y", c_int), ("z", c_int)]
+ class A(Structure):
+ _anonymous_ = ["b"]
+ _fields_ = [("b", B)]
+
+ a = A()
+ a.x = 5
+ assert a.x == 5
+ assert a.b.x == 5
+ a.b.x += 1
+ assert a.x == 6
+
+ class C(Structure):
+ _anonymous_ = ["a"]
+ _fields_ = [("v", c_int), ("a", A)]
+
+ c = C()
+ c.v = 3
+ c.y = -8
+ assert c.v == 3
+ assert c.y == c.a.y == c.a.b.y == -8
+ assert not hasattr(c, 'b')
diff --git a/pypy/module/test_lib_pypy/pyrepl/infrastructure.py
b/pypy/module/test_lib_pypy/pyrepl/infrastructure.py
--- a/pypy/module/test_lib_pypy/pyrepl/infrastructure.py
+++ b/pypy/module/test_lib_pypy/pyrepl/infrastructure.py
@@ -18,6 +18,9 @@
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import print_function
+from contextlib import contextmanager
+import os
+
from pyrepl.reader import Reader
from pyrepl.console import Console, Event
@@ -71,3 +74,14 @@
con = TestConsole(test_spec, verbose=True)
reader = reader_class(con)
reader.readline()
+
+
+@contextmanager
+def sane_term():
+ """Ensure a TERM that supports clear"""
+ old_term, os.environ['TERM'] = os.environ.get('TERM'), 'xterm'
+ yield
+ if old_term is not None:
+ os.environ['TERM'] = old_term
+ else:
+ del os.environ['TERM']
diff --git a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py
b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py
--- a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py
+++ b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py
@@ -18,7 +18,7 @@
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from pyrepl.historical_reader import HistoricalReader
-from .infrastructure import EA, BaseTestReader, read_spec
+from .infrastructure import EA, BaseTestReader, sane_term, read_spec
# this test case should contain as-verbatim-as-possible versions of
# (applicable) bug reports
@@ -46,7 +46,8 @@
read_spec(spec, HistoricalTestReader)
[email protected]("os.name != 'posix' or 'darwin' in sys.platform")
[email protected]("os.name != 'posix' or 'darwin' in sys.platform or "
+ "'kfreebsd' in sys.platform")
def test_signal_failure(monkeypatch):
import os
import pty
@@ -61,13 +62,14 @@
mfd, sfd = pty.openpty()
try:
- c = UnixConsole(sfd, sfd)
- c.prepare()
- c.restore()
- monkeypatch.setattr(signal, 'signal', failing_signal)
- c.prepare()
- monkeypatch.setattr(signal, 'signal', really_failing_signal)
- c.restore()
+ with sane_term():
+ c = UnixConsole(sfd, sfd)
+ c.prepare()
+ c.restore()
+ monkeypatch.setattr(signal, 'signal', failing_signal)
+ c.prepare()
+ monkeypatch.setattr(signal, 'signal', really_failing_signal)
+ c.restore()
finally:
os.close(mfd)
os.close(sfd)
diff --git a/pypy/module/test_lib_pypy/pyrepl/test_readline.py
b/pypy/module/test_lib_pypy/pyrepl/test_readline.py
--- a/pypy/module/test_lib_pypy/pyrepl/test_readline.py
+++ b/pypy/module/test_lib_pypy/pyrepl/test_readline.py
@@ -1,7 +1,10 @@
import pytest
+from .infrastructure import sane_term
[email protected]("os.name != 'posix' or 'darwin' in sys.platform")
+
[email protected]("os.name != 'posix' or 'darwin' in sys.platform or "
+ "'kfreebsd' in sys.platform")
def test_raw_input():
import os
import pty
@@ -11,7 +14,8 @@
readline_wrapper = _ReadlineWrapper(slave, slave)
os.write(master, b'input\n')
- result = readline_wrapper.get_reader().readline()
+ with sane_term():
+ result = readline_wrapper.get_reader().readline()
#result = readline_wrapper.raw_input('prompt:')
assert result == 'input'
# A bytes string on python2, a unicode string on python3.
diff --git a/pypy/objspace/std/objectobject.py
b/pypy/objspace/std/objectobject.py
--- a/pypy/objspace/std/objectobject.py
+++ b/pypy/objspace/std/objectobject.py
@@ -110,7 +110,7 @@
def descr__init__(space, w_obj, __args__):
# don't allow arguments unless __new__ is overridden
w_type = space.type(w_obj)
- w_parent_new, _ = w_type.lookup_where('__new__')
+ w_parent_new, _ = space.lookup_in_type_where(w_type, '__new__')
if w_parent_new is space.w_object:
try:
__args__.fixedunpack(0)
diff --git a/pypy/tool/gdb_pypy.py b/pypy/tool/gdb_pypy.py
--- a/pypy/tool/gdb_pypy.py
+++ b/pypy/tool/gdb_pypy.py
@@ -288,9 +288,11 @@
RPyListPrinter.recursive = True
try:
itemlist = []
- for i in range(length):
+ for i in range(min(length, MAX_DISPLAY_LENGTH)):
item = items[i]
itemlist.append(str(item)) # may recurse here
+ if length > MAX_DISPLAY_LENGTH:
+ itemlist.append("...")
str_items = ', '.join(itemlist)
finally:
RPyListPrinter.recursive = False
diff --git a/requirements.txt b/requirements.txt
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,3 @@
# hypothesis is used for test generation on untranslated jit tests
hypothesis
-enum>=0.4.6 # is a dependency, but old pip does not pick it up
enum34>=1.1.2
diff --git a/rpython/config/translationoption.py
b/rpython/config/translationoption.py
--- a/rpython/config/translationoption.py
+++ b/rpython/config/translationoption.py
@@ -126,6 +126,9 @@
ChoiceOption("jit_profiler", "integrate profiler support into the JIT",
["off", "oprofile"],
default="off"),
+ ChoiceOption("jit_opencoder_model", "the model limits the maximal length"
+ " of traces. Use big if you want to go bigger than "
+ "the default", ["big", "normal"], default="normal"),
BoolOption("check_str_without_nul",
"Forbid NUL chars in strings in some external function calls",
default=False, cmdline=None),
diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py
--- a/rpython/flowspace/specialcase.py
+++ b/rpython/flowspace/specialcase.py
@@ -77,6 +77,7 @@
for c in s:
buf.append(c)
buf.append(' ')
+rpython_print_item._annenforceargs_ = (str,)
def rpython_print_newline():
buf = stdoutbuffer.linebuf
diff --git a/rpython/jit/backend/arm/assembler.py
b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -939,9 +939,9 @@
op = operations[i]
self.mc.mark_op(op)
opnum = op.getopnum()
- if op.has_no_side_effect() and op not in regalloc.longevity:
+ if rop.has_no_side_effect(opnum) and op not in regalloc.longevity:
regalloc.possibly_free_vars_for_op(op)
- elif not we_are_translated() and op.getopnum() == -127:
+ elif not we_are_translated() and op.getopnum() == rop.FORCE_SPILL:
regalloc.prepare_force_spill(op, fcond)
else:
arglocs = regalloc_operations[opnum](regalloc, op, fcond)
@@ -949,7 +949,7 @@
fcond = asm_operations[opnum](self, op, arglocs,
regalloc, fcond)
assert fcond is not None
- if op.is_guard():
+ if rop.is_guard(opnum):
regalloc.possibly_free_vars(op.getfailargs())
if op.type != 'v':
regalloc.possibly_free_var(op)
diff --git a/rpython/jit/backend/arm/detect.py
b/rpython/jit/backend/arm/detect.py
--- a/rpython/jit/backend/arm/detect.py
+++ b/rpython/jit/backend/arm/detect.py
@@ -63,3 +63,44 @@
"falling back to", "ARMv%d" % n)
debug_stop("jit-backend-arch")
return n
+
+
+# Once we can rely on the availability of glibc >= 2.16, replace this with:
+# from rpython.rtyper.lltypesystem import lltype, rffi
+# getauxval = rffi.llexternal("getauxval", [lltype.Unsigned], lltype.Unsigned)
+def getauxval(type_, filename='/proc/self/auxv'):
+ fd = os.open(filename, os.O_RDONLY, 0644)
+
+ buf_size = 2048
+ struct_size = 8 # 2x uint32
+ try:
+ buf = os.read(fd, buf_size)
+ finally:
+ os.close(fd)
+
+ # decode chunks of 8 bytes (a_type, a_val), and
+ # return the a_val whose a_type corresponds to type_,
+ # or zero if not found.
+ i = 0
+ while i <= buf_size - struct_size:
+ # We only support little-endian ARM
+ a_type = (ord(buf[i]) |
+ (ord(buf[i+1]) << 8) |
+ (ord(buf[i+2]) << 16) |
+ (ord(buf[i+3]) << 24))
+ a_val = (ord(buf[i+4]) |
+ (ord(buf[i+5]) << 8) |
+ (ord(buf[i+6]) << 16) |
+ (ord(buf[i+7]) << 24))
+ i += struct_size
+ if a_type == type_:
+ return a_val
+
+ return 0
+
+
+def detect_neon():
+ AT_HWCAP = 16
+ HWCAP_NEON = 1 << 12
+ hwcap = getauxval(AT_HWCAP)
+ return bool(hwcap & HWCAP_NEON)
diff --git a/rpython/jit/backend/arm/opassembler.py
b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -1092,8 +1092,8 @@
self.mc.VCVT_int_to_float(res.value, r.svfp_ip.value)
return fcond
- # the following five instructions are only ARMv7;
- # regalloc.py won't call them at all on ARMv6
+ # the following five instructions are only ARMv7 with NEON;
+ # regalloc.py won't call them at all, in other cases
emit_opx_llong_add = gen_emit_float_op('llong_add', 'VADD_i64')
emit_opx_llong_sub = gen_emit_float_op('llong_sub', 'VSUB_i64')
emit_opx_llong_and = gen_emit_float_op('llong_and', 'VAND_i64')
diff --git a/rpython/jit/backend/arm/regalloc.py
b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -530,7 +530,7 @@
EffectInfo.OS_LLONG_AND,
EffectInfo.OS_LLONG_OR,
EffectInfo.OS_LLONG_XOR):
- if self.cpu.cpuinfo.arch_version >= 7:
+ if self.cpu.cpuinfo.neon:
args = self._prepare_llong_binop_xx(op, fcond)
self.perform_extra(op, args, fcond)
return
diff --git a/rpython/jit/backend/arm/runner.py
b/rpython/jit/backend/arm/runner.py
--- a/rpython/jit/backend/arm/runner.py
+++ b/rpython/jit/backend/arm/runner.py
@@ -7,13 +7,14 @@
from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER
from rpython.rtyper.lltypesystem import lltype, llmemory
from rpython.jit.backend.arm.detect import detect_hardfloat
-from rpython.jit.backend.arm.detect import detect_arch_version
+from rpython.jit.backend.arm.detect import detect_arch_version, detect_neon
jitframe.STATICSIZE = JITFRAME_FIXED_SIZE
class CPUInfo(object):
hf_abi = False
arch_version = 6
+ neon = False
class AbstractARMCPU(AbstractLLCPU):
@@ -48,6 +49,7 @@
def setup_once(self):
self.cpuinfo.arch_version = detect_arch_version()
self.cpuinfo.hf_abi = detect_hardfloat()
+ self.cpuinfo.neon = detect_neon()
#self.codemap.setup()
self.assembler.setup_once()
diff --git a/rpython/jit/backend/arm/test/test_detect.py
b/rpython/jit/backend/arm/test/test_detect.py
--- a/rpython/jit/backend/arm/test/test_detect.py
+++ b/rpython/jit/backend/arm/test/test_detect.py
@@ -1,6 +1,6 @@
import py
from rpython.tool.udir import udir
-from rpython.jit.backend.arm.detect import detect_arch_version
+from rpython.jit.backend.arm.detect import detect_arch_version, getauxval
cpuinfo = "Processor : ARMv%d-compatible processor rev 7 (v6l)"""
cpuinfo2 = """processor : 0
@@ -29,6 +29,19 @@
address sizes : 36 bits physical, 48 bits virtual
power management:
"""
+# From a Marvell Armada 370/XP
+auxv = (
+ '\x10\x00\x00\x00\xd7\xa8\x1e\x00\x06\x00\x00\x00\x00\x10\x00\x00\x11\x00'
+ '\x00\x00d\x00\x00\x00\x03\x00\x00\x004\x00\x01\x00\x04\x00\x00\x00 \x00'
+ '\x00\x00\x05\x00\x00\x00\t\x00\x00\x00\x07\x00\x00\x00\x00\xe0\xf3\xb6'
+ '\x08\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00t\xcf\x04\x00\x0b\x00\x00'
+ '\x000\x0c\x00\x00\x0c\x00\x00\x000\x0c\x00\x00\r\x00\x00\x000\x0c\x00\x00'
+ '\x0e\x00\x00\x000\x0c\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00'
+ '\x00\x8a\xf3\x87\xbe\x1a\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\xec'
+ '\xff\x87\xbe\x0f\x00\x00\x00\x9a\xf3\x87\xbe\x00\x00\x00\x00\x00\x00\x00'
+ '\x00'
+)
+
def write_cpuinfo(info):
filepath = udir.join('get_arch_version')
@@ -46,3 +59,10 @@
py.test.raises(ValueError,
'detect_arch_version(write_cpuinfo(cpuinfo % 5))')
assert detect_arch_version(write_cpuinfo(cpuinfo2)) == 6
+
+
+def test_getauxval_no_neon():
+ path = udir.join('auxv')
+ path.write(auxv, 'wb')
+ AT_HWCAP = 16
+ assert getauxval(AT_HWCAP, filename=str(path)) == 2009303
diff --git a/rpython/jit/backend/llgraph/runner.py
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -455,7 +455,7 @@
if box is not frame.current_op:
value = frame.env[box]
else:
- value = box.getvalue() # 0 or 0.0 or NULL
+ value = 0 # box.getvalue() # 0 or 0.0 or NULL
else:
value = None
values.append(value)
@@ -472,6 +472,13 @@
# ------------------------------------------------------------
+ def setup_descrs(self):
+ all_descrs = []
+ for k, v in self.descrs.iteritems():
+ v.descr_index = len(all_descrs)
+ all_descrs.append(v)
+ return all_descrs
+
def calldescrof(self, FUNC, ARGS, RESULT, effect_info):
key = ('call', getkind(RESULT),
tuple([getkind(A) for A in ARGS]),
diff --git a/rpython/jit/backend/llsupport/assembler.py
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -331,7 +331,7 @@
counter = self._register_counter(tp, number, token)
c_adr = ConstInt(rffi.cast(lltype.Signed, counter))
operations.append(
- ResOperation(rop.INCREMENT_DEBUG_COUNTER, [c_adr], None))
+ ResOperation(rop.INCREMENT_DEBUG_COUNTER, [c_adr]))
def _register_counter(self, tp, number, token):
# YYY very minor leak -- we need the counters to stay alive
diff --git a/rpython/jit/backend/llsupport/descr.py
b/rpython/jit/backend/llsupport/descr.py
--- a/rpython/jit/backend/llsupport/descr.py
+++ b/rpython/jit/backend/llsupport/descr.py
@@ -21,6 +21,30 @@
self._cache_call = {}
self._cache_interiorfield = {}
+ def setup_descrs(self):
+ all_descrs = []
+ for k, v in self._cache_size.iteritems():
+ v.descr_index = len(all_descrs)
+ all_descrs.append(v)
+ for k, v in self._cache_field.iteritems():
+ for k1, v1 in v.iteritems():
+ v1.descr_index = len(all_descrs)
+ all_descrs.append(v1)
+ for k, v in self._cache_array.iteritems():
+ v.descr_index = len(all_descrs)
+ all_descrs.append(v)
+ for k, v in self._cache_arraylen.iteritems():
+ v.descr_index = len(all_descrs)
+ all_descrs.append(v)
+ for k, v in self._cache_call.iteritems():
+ v.descr_index = len(all_descrs)
+ all_descrs.append(v)
+ for k, v in self._cache_interiorfield.iteritems():
+ v.descr_index = len(all_descrs)
+ all_descrs.append(v)
+ assert len(all_descrs) < 2**15
+ return all_descrs
+
def init_size_descr(self, STRUCT, sizedescr):
pass
diff --git a/rpython/jit/backend/llsupport/llmodel.py
b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -316,6 +316,9 @@
return ll_frame
return execute_token
+ def setup_descrs(self):
+ return self.gc_ll_descr.setup_descrs()
+
# ------------------- helpers and descriptions --------------------
@staticmethod
diff --git a/rpython/jit/backend/llsupport/regalloc.py
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -683,7 +683,7 @@
for i in range(len(operations)-1, -1, -1):
op = operations[i]
if op.type != 'v':
- if op not in last_used and op.has_no_side_effect():
+ if op not in last_used and rop.has_no_side_effect(op.opnum):
continue
opnum = op.getopnum()
for j in range(op.numargs()):
@@ -695,7 +695,7 @@
if opnum != rop.JUMP and opnum != rop.LABEL:
if arg not in last_real_usage:
last_real_usage[arg] = i
- if op.is_guard():
+ if rop.is_guard(op.opnum):
for arg in op.getfailargs():
if arg is None: # hole
continue
@@ -732,14 +732,7 @@
return longevity, last_real_usage
def is_comparison_or_ovf_op(opnum):
- from rpython.jit.metainterp.resoperation import opclasses
- cls = opclasses[opnum]
- # hack hack: in theory they are instance method, but they don't use
- # any instance field, we can use a fake object
- class Fake(cls):
- pass
- op = Fake()
- return op.is_comparison() or op.is_ovf()
+ return rop.is_comparison(opnum) or rop.is_ovf(opnum)
def valid_addressing_size(size):
return size == 1 or size == 2 or size == 4 or size == 8
diff --git a/rpython/jit/backend/llsupport/rewrite.py
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -103,7 +103,7 @@
orig_op.set_forwarded(op)
replaced = True
op.setarg(i, arg)
- if op.is_guard():
+ if rop.is_guard(op.opnum):
if not replaced:
op = op.copy_and_change(op.getopnum())
orig_op.set_forwarded(op)
@@ -212,7 +212,7 @@
#
self._emit_mul_if_factor_offset_not_supported(v_length, scale, 0)
# op.setarg(1, ConstInt(scale))
# op.setarg(2, v_length)
- if op.is_getarrayitem() or \
+ if rop.is_getarrayitem(opnum) or \
opnum in (rop.GETARRAYITEM_RAW_I,
rop.GETARRAYITEM_RAW_F):
self.handle_getarrayitem(op)
@@ -324,13 +324,13 @@
if self.transform_to_gc_load(op):
continue
# ---------- turn NEWxxx into CALL_MALLOC_xxx ----------
- if op.is_malloc():
+ if rop.is_malloc(op.opnum):
self.handle_malloc_operation(op)
continue
- if (op.is_guard() or
+ if (rop.is_guard(op.opnum) or
self.could_merge_with_next_guard(op, i, operations)):
self.emit_pending_zeros()
- elif op.can_malloc():
+ elif rop.can_malloc(op.opnum):
self.emitting_an_operation_that_can_collect()
elif op.getopnum() == rop.LABEL:
self.emitting_an_operation_that_can_collect()
@@ -370,8 +370,8 @@
# return True in cases where the operation and the following guard
# should likely remain together. Simplified version of
# can_merge_with_next_guard() in llsupport/regalloc.py.
- if not op.is_comparison():
- return op.is_ovf() # int_xxx_ovf() / guard_no_overflow()
+ if not rop.is_comparison(op.opnum):
+ return rop.is_ovf(op.opnum) # int_xxx_ovf() /
guard_no_overflow()
if i + 1 >= len(operations):
return False
next_op = operations[i + 1]
@@ -400,7 +400,6 @@
# it's hard to test all cases). Rewrite it away.
value = int(opnum == rop.GUARD_FALSE)
op1 = ResOperation(rop.SAME_AS_I, [ConstInt(value)])
- op1.setint(value)
self.emit_op(op1)
lst = op.getfailargs()[:]
lst[i] = op1
@@ -633,8 +632,7 @@
args = [frame, arglist[jd.index_of_virtualizable]]
else:
args = [frame]
- call_asm = ResOperation(op.getopnum(), args,
- op.getdescr())
+ call_asm = ResOperation(op.getopnum(), args, descr=op.getdescr())
self.replace_op_with(self.get_box_replacement(op), call_asm)
self.emit_op(call_asm)
@@ -708,7 +706,7 @@
def _gen_call_malloc_gc(self, args, v_result, descr):
"""Generate a CALL_MALLOC_GC with the given args."""
self.emitting_an_operation_that_can_collect()
- op = ResOperation(rop.CALL_MALLOC_GC, args, descr)
+ op = ResOperation(rop.CALL_MALLOC_GC, args, descr=descr)
self.replace_op_with(v_result, op)
self.emit_op(op)
# In general, don't add v_result to write_barrier_applied:
diff --git a/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py
b/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py
--- a/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py
+++ b/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py
@@ -6,6 +6,7 @@
from rpython.rlib import rthread
from rpython.translator.translator import TranslationContext
from rpython.jit.backend.detect_cpu import getcpuclass
+from rpython.rlib.rweaklist import RWeakListMixin
class CompiledVmprofTest(CCompiledMixin):
CPUClass = getcpuclass()
@@ -21,6 +22,7 @@
class MyCode:
_vmprof_unique_id = 0
+ _vmprof_weak_list = RWeakListMixin() ;
_vmprof_weak_list.initialize()
def __init__(self, name):
self.name = name
diff --git a/rpython/jit/backend/ppc/regalloc.py
b/rpython/jit/backend/ppc/regalloc.py
--- a/rpython/jit/backend/ppc/regalloc.py
+++ b/rpython/jit/backend/ppc/regalloc.py
@@ -286,7 +286,8 @@
self.assembler.mc.mark_op(op)
self.rm.position = i
self.fprm.position = i
- if op.has_no_side_effect() and op not in self.longevity:
+ opnum = op.opnum
+ if rop.has_no_side_effect(opnum) and op not in self.longevity:
i += 1
self.possibly_free_vars_for_op(op)
continue
@@ -298,8 +299,7 @@
else:
self.fprm.temp_boxes.append(box)
#
- opnum = op.getopnum()
- if not we_are_translated() and opnum == -127:
+ if not we_are_translated() and opnum == rop.FORCE_SPILL:
self._consider_force_spill(op)
else:
arglocs = oplist[opnum](self, op)
diff --git a/rpython/jit/backend/test/test_ll_random.py
b/rpython/jit/backend/test/test_ll_random.py
--- a/rpython/jit/backend/test/test_ll_random.py
+++ b/rpython/jit/backend/test/test_ll_random.py
@@ -2,6 +2,7 @@
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr
from rpython.rtyper import rclass
from rpython.jit.backend.test import test_random
+from rpython.jit.backend.test.test_random import getint, getref_base, getref
from rpython.jit.metainterp.resoperation import ResOperation, rop, optypes
from rpython.jit.metainterp.history import ConstInt, ConstPtr, getkind
from rpython.jit.codewriter import heaptracker
@@ -169,7 +170,7 @@
if length == 0:
raise test_random.CannotProduceOperation
v_index = r.choice(self.intvars)
- if not (0 <= v_index.getint() < length):
+ if not (0 <= getint(v_index) < length):
v_index = ConstInt(r.random_integer() % length)
return v_index
@@ -311,7 +312,7 @@
def field_descr(self, builder, r):
v, A = builder.get_structptr_var(r, type=lltype.Array,
array_of_structs=True)
- array = v.getref(lltype.Ptr(A))
+ array = getref(lltype.Ptr(A), v)
v_index = builder.get_index(len(array), r)
choice = []
for name in A.OF._names:
@@ -344,7 +345,7 @@
w = ConstInt(r.random_integer())
else:
w = r.choice(builder.intvars)
- value = w.getint()
+ value = getint(w)
if rffi.cast(lltype.Signed, rffi.cast(TYPE, value)) == value:
break
builder.do(self.opnum, [v, w], descr)
@@ -357,7 +358,7 @@
w = ConstInt(r.random_integer())
else:
w = r.choice(builder.intvars)
- value = w.getint()
+ value = getint(w)
if rffi.cast(lltype.Signed, rffi.cast(TYPE, value)) == value:
break
builder.do(self.opnum, [v, v_index, w], descr)
@@ -389,7 +390,7 @@
class GetArrayItemOperation(ArrayOperation):
def field_descr(self, builder, r):
v, A = builder.get_arrayptr_var(r)
- array = v.getref(lltype.Ptr(A))
+ array = getref(lltype.Ptr(A), v)
v_index = builder.get_index(len(array), r)
descr = self.array_descr(builder, A)
return v, A, v_index, descr
@@ -411,7 +412,7 @@
w = ConstInt(r.random_integer())
else:
w = r.choice(builder.intvars)
- value = w.getint()
+ value = getint(w)
if rffi.cast(lltype.Signed, rffi.cast(A.OF, value)) == value:
break
builder.do(self.opnum, [v, v_index, w], descr)
@@ -455,7 +456,7 @@
v_ptr = builder.do(self.opnum, [v_length])
getattr(builder, self.builder_cache).append(v_ptr)
# Initialize the string. Is there a better way to do this?
- for i in range(v_length.getint()):
+ for i in range(getint(v_length)):
v_index = ConstInt(i)
v_char = ConstInt(r.random_integer() % self.max)
builder.do(self.set_char, [v_ptr, v_index, v_char])
@@ -471,9 +472,9 @@
current = getattr(builder, self.builder_cache)
if current and r.random() < .8:
v_string = r.choice(current)
- string = v_string.getref(self.ptr)
+ string = getref(self.ptr, v_string)
else:
- string = self.alloc(builder.get_index(500, r).getint())
+ string = self.alloc(getint(builder.get_index(500, r)))
v_string = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, string))
current.append(v_string)
for i in range(len(string.chars)):
@@ -484,7 +485,7 @@
class AbstractGetItemOperation(AbstractStringOperation):
def produce_into(self, builder, r):
v_string = self.get_string(builder, r)
- v_index = builder.get_index(len(v_string.getref(self.ptr).chars), r)
+ v_index = builder.get_index(len(getref(self.ptr, v_string).chars), r)
builder.do(self.opnum, [v_string, v_index])
class AbstractSetItemOperation(AbstractStringOperation):
@@ -492,7 +493,7 @@
v_string = self.get_string(builder, r)
if isinstance(v_string, ConstPtr):
raise test_random.CannotProduceOperation # setitem(Const, ...)
- v_index = builder.get_index(len(v_string.getref(self.ptr).chars), r)
+ v_index = builder.get_index(len(getref(self.ptr, v_string).chars), r)
v_target = ConstInt(r.random_integer() % self.max)
builder.do(self.opnum, [v_string, v_index, v_target])
@@ -505,15 +506,15 @@
def produce_into(self, builder, r):
v_srcstring = self.get_string(builder, r)
v_dststring = self.get_string(builder, r)
- src = v_srcstring.getref(self.ptr)
- dst = v_dststring.getref(self.ptr)
+ src = getref(self.ptr, v_srcstring)
+ dst = getref(self.ptr, v_dststring)
if src == dst: # because it's not a
raise test_random.CannotProduceOperation # memmove(), but memcpy()
srclen = len(src.chars)
dstlen = len(dst.chars)
v_length = builder.get_index(min(srclen, dstlen), r)
- v_srcstart = builder.get_index(srclen - v_length.getint() + 1, r)
- v_dststart = builder.get_index(dstlen - v_length.getint() + 1, r)
+ v_srcstart = builder.get_index(srclen - getint(v_length) + 1, r)
+ v_dststart = builder.get_index(dstlen - getint(v_length) + 1, r)
builder.do(self.opnum, [v_srcstring, v_dststring,
v_srcstart, v_dststart, v_length])
@@ -585,7 +586,7 @@
""" % funcargs).compile()
vtableptr = v._hints['vtable']._as_ptr()
d = {
- 'ptr': S.getref_base(),
+ 'ptr': getref_base(S),
'vtable' : vtableptr,
'LLException' : LLException,
}
diff --git a/rpython/jit/backend/test/test_random.py
b/rpython/jit/backend/test/test_random.py
--- a/rpython/jit/backend/test/test_random.py
+++ b/rpython/jit/backend/test/test_random.py
@@ -11,11 +11,9 @@
from rpython.jit.metainterp.executor import _execute_arglist, wrap_constant
from rpython.jit.metainterp.resoperation import opname
from rpython.jit.codewriter import longlong
-from rpython.rtyper.lltypesystem import lltype, rstr
+from rpython.rtyper.lltypesystem import lltype, llmemory, rstr
from rpython.rtyper import rclass
-class PleaseRewriteMe(Exception):
- pass
class DummyLoop(object):
def __init__(self, subops):
@@ -27,6 +25,41 @@
def execute_raised(self, exc, constant=False):
self._got_exc = exc
+
+def getint(v):
+ if isinstance(v, (ConstInt, InputArgInt)):
+ return v.getint()
+ else:
+ return v._example_int
+
+def getfloatstorage(v):
+ if isinstance(v, (ConstFloat, InputArgFloat)):
+ return v.getfloatstorage()
+ else:
+ return v._example_float
+
+def getfloat(v):
+ return longlong.getrealfloat(getfloatstorage(v))
+
+def getref_base(v):
+ if isinstance(v, (ConstPtr, InputArgRef)):
+ return v.getref_base()
+ else:
+ return v._example_ref
+
+def getref(PTR, v):
+ return lltype.cast_opaque_ptr(PTR, getref_base(v))
+
+def constbox(v):
+ if v.type == INT:
+ return ConstInt(getint(v))
+ if v.type == FLOAT:
+ return ConstFloat(getfloatstorage(v))
+ if v.type == REF:
+ return ConstPtr(getref_base(v))
+ assert 0, v.type
+
+
class OperationBuilder(object):
def __init__(self, cpu, loop, vars):
self.cpu = cpu
@@ -57,11 +90,21 @@
def do(self, opnum, argboxes, descr=None):
self.fakemetainterp._got_exc = None
op = ResOperation(opnum, argboxes, descr)
+ argboxes = map(constbox, argboxes)
result = _execute_arglist(self.cpu, self.fakemetainterp,
opnum, argboxes, descr)
if result is not None:
- c_result = wrap_constant(result)
- op.copy_value_from(c_result)
+ if lltype.typeOf(result) == lltype.Signed:
+ op._example_int = result
+ elif isinstance(result, bool):
+ op._example_int = int(result)
+ elif lltype.typeOf(result) == longlong.FLOATSTORAGE:
+ op._example_float = result
+ elif isinstance(result, float):
+ op._example_float = longlong.getfloatstorage(result)
+ else:
+ assert lltype.typeOf(result) == llmemory.GCREF
+ op._example_ref = result
self.loop.operations.append(op)
return op
@@ -101,7 +144,7 @@
if v in names:
args.append(names[v])
elif isinstance(v, ConstPtr):
- assert not v.getref_base() # otherwise should be in the names
+ assert not getref_base(v) # otherwise should be in the names
args.append('ConstPtr(lltype.nullptr(llmemory.GCREF.TO))')
elif isinstance(v, ConstFloat):
args.append('ConstFloat(longlong.getfloatstorage(%r))'
@@ -198,10 +241,10 @@
#
def writevar(v, nameprefix, init=''):
if nameprefix == 'const_ptr':
- if not v.getref_base():
+ if not getref_base(v):
return 'lltype.nullptr(llmemory.GCREF.TO)'
- TYPE = v.getref_base()._obj.ORIGTYPE
- cont = lltype.cast_opaque_ptr(TYPE, v.getref_base())
+ TYPE = getref_base(v)._obj.ORIGTYPE
+ cont = lltype.cast_opaque_ptr(TYPE, getref_base(v))
if TYPE.TO._is_varsize():
if isinstance(TYPE.TO, lltype.GcStruct):
lgt = len(cont.chars)
@@ -252,9 +295,9 @@
for i, v in enumerate(self.loop.inputargs):
assert not isinstance(v, Const)
if v.type == FLOAT:
- vals.append("longlong.getfloatstorage(%r)" % v.getfloat())
+ vals.append("longlong.getfloatstorage(%r)" % getfloat(v))
else:
- vals.append("%r" % v.getint())
+ vals.append("%r" % getint(v))
print >>s, ' loop_args = [%s]' % ", ".join(vals)
print >>s, ' frame = cpu.execute_token(looptoken, *loop_args)'
if self.should_fail_by is None:
@@ -264,10 +307,10 @@
for i, v in enumerate(fail_args):
if v.type == FLOAT:
print >>s, (' assert longlong.getrealfloat('
- 'cpu.get_float_value(frame, %d)) == %r' % (i,
v.getfloatstorage()))
+ 'cpu.get_float_value(frame, %d)) == %r' % (i,
getfloatstorage(v)))
else:
print >>s, (' assert cpu.get_int_value(frame, %d) == %d'
- % (i, v.getint()))
+ % (i, getint(v)))
self.names = names
s.flush()
@@ -295,7 +338,7 @@
builder.intvars.append(v_result)
boolres = self.boolres
if boolres == 'sometimes':
- boolres = v_result.getint() in [0, 1]
+ boolres = getint(v_result) in [0, 1]
if boolres:
builder.boolvars.append(v_result)
elif v_result.type == FLOAT:
@@ -346,10 +389,10 @@
v_second = ConstInt((value & self.and_mask) | self.or_mask)
else:
v = r.choice(builder.intvars)
- v_value = v.getint()
+ v_value = getint(v)
if (v_value & self.and_mask) != v_value:
v = builder.do(rop.INT_AND, [v, ConstInt(self.and_mask)])
- v_value = v.getint()
+ v_value = getint(v)
if (v_value | self.or_mask) != v_value:
v = builder.do(rop.INT_OR, [v, ConstInt(self.or_mask)])
v_second = v
@@ -395,9 +438,9 @@
v_second = ConstFloat(r.random_float_storage())
else:
v_second = r.choice(builder.floatvars)
- if abs(v_first.getfloat()) > 1E100 or abs(v_second.getfloat()) > 1E100:
+ if abs(getfloat(v_first)) > 1E100 or abs(getfloat(v_second)) > 1E100:
raise CannotProduceOperation # avoid infinities
- if abs(v_second.getfloat()) < 1E-100:
+ if abs(getfloat(v_second)) < 1E-100:
raise CannotProduceOperation # e.g. division by zero error
self.put(builder, [v_first, v_second])
@@ -432,7 +475,7 @@
if not builder.floatvars:
raise CannotProduceOperation
box = r.choice(builder.floatvars)
- if not (-sys.maxint-1 <= box.getfloat() <= sys.maxint):
+ if not (-sys.maxint-1 <= getfloat(box) <= sys.maxint):
raise CannotProduceOperation # would give an overflow
self.put(builder, [box])
@@ -440,8 +483,8 @@
def gen_guard(self, builder, r):
v = builder.get_bool_var(r)
op = ResOperation(self.opnum, [v])
- passing = ((self.opnum == rop.GUARD_TRUE and v.getint()) or
- (self.opnum == rop.GUARD_FALSE and not v.getint()))
+ passing = ((self.opnum == rop.GUARD_TRUE and getint(v)) or
+ (self.opnum == rop.GUARD_FALSE and not getint(v)))
return op, passing
def produce_into(self, builder, r):
@@ -459,8 +502,8 @@
raise CannotProduceOperation
box = r.choice(builder.ptrvars)[0]
op = ResOperation(self.opnum, [box])
- passing = ((self.opnum == rop.GUARD_NONNULL and box.getref_base()) or
- (self.opnum == rop.GUARD_ISNULL and not box.getref_base()))
+ passing = ((self.opnum == rop.GUARD_NONNULL and getref_base(box)) or
+ (self.opnum == rop.GUARD_ISNULL and not getref_base(box)))
return op, passing
class GuardValueOperation(GuardOperation):
@@ -470,14 +513,14 @@
other = r.choice(builder.intvars)
else:
if r.random() < 0.75:
- value = v.getint()
+ value = getint(v)
elif r.random() < 0.5:
- value = v.getint() ^ 1
+ value = getint(v) ^ 1
else:
value = r.random_integer()
other = ConstInt(value)
op = ResOperation(self.opnum, [v, other])
- return op, (v.getint() == other.getint())
+ return op, (getint(v) == getint(other))
# ____________________________________________________________
@@ -675,7 +718,7 @@
assert not hasattr(loop, '_targettoken')
for i in range(position):
op = loop.operations[i]
- if (not op.has_no_side_effect()
+ if (not rop.has_no_side_effect(op.opnum)
or op.type not in (INT, FLOAT)):
position = i
break # cannot move the LABEL later
@@ -728,9 +771,9 @@
self.expected = {}
for v in endvars:
if v.type == INT:
- self.expected[v] = v.getint()
+ self.expected[v] = getint(v)
elif v.type == FLOAT:
- self.expected[v] = v.getfloatstorage()
+ self.expected[v] = getfloatstorage(v)
else:
assert 0, v.type
@@ -742,7 +785,7 @@
args = []
for box in self.startvars:
if box not in self.loop.inputargs:
- box = box.constbox()
+ box = constbox(box)
args.append(box)
self.cpu.compile_loop(self.loop.inputargs,
[ResOperation(rop.JUMP, args,
@@ -760,7 +803,7 @@
def clear_state(self):
for v, S, fields in self.prebuilt_ptr_consts:
- container = v.getref_base()._obj.container
+ container = getref_base(v)._obj.container
for name, value in fields.items():
if isinstance(name, str):
setattr(container, name, value)
@@ -781,9 +824,9 @@
arguments = []
for box in self.loop.inputargs:
if box.type == INT:
- arguments.append(box.getint())
+ arguments.append(getint(box))
elif box.type == FLOAT:
- arguments.append(box.getfloatstorage())
+ arguments.append(getfloatstorage(box))
else:
assert 0, box.type
deadframe = cpu.execute_token(self.runjitcelltoken(), *arguments)
@@ -795,7 +838,7 @@
if v not in self.expected:
assert v.getopnum() == rop.SAME_AS_I # special case
assert isinstance(v.getarg(0), ConstInt)
- self.expected[v] = v.getarg(0).getint()
+ self.expected[v] = getint(v.getarg(0))
if v.type == FLOAT:
value = cpu.get_float_value(deadframe, i)
else:
@@ -807,7 +850,7 @@
)
exc = cpu.grab_exc_value(deadframe)
if (self.guard_op is not None and
- self.guard_op.is_guard_exception()):
+ rop.is_guard_exception(self.guard_op.getopnum())):
if self.guard_op.getopnum() == rop.GUARD_NO_EXCEPTION:
do_assert(exc,
"grab_exc_value() should not be %r" % (exc,))
@@ -840,7 +883,7 @@
# generate the branch: a sequence of operations that ends in a FINISH
subloop = DummyLoop([])
self.subloops.append(subloop) # keep around for debugging
- if guard_op.is_guard_exception():
+ if rop.is_guard_exception(guard_op.getopnum()):
subloop.operations.append(exc_handling(guard_op))
bridge_builder = self.builder.fork(self.builder.cpu, subloop,
op.getfailargs()[:])
@@ -876,9 +919,9 @@
args = []
for x in subset:
if x.type == INT:
- args.append(InputArgInt(x.getint()))
+ args.append(InputArgInt(getint(x)))
elif x.type == FLOAT:
- args.append(InputArgFloat(x.getfloatstorage()))
+ args.append(InputArgFloat(getfloatstorage(x)))
else:
assert 0, x.type
rl = RandomLoop(self.builder.cpu, self.builder.fork,
diff --git a/rpython/jit/backend/x86/assembler.py
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -645,15 +645,28 @@
pass
elif gloc is not bloc:
self.mov(gloc, bloc)
+ offset = self.mc.get_relative_pos()
self.mc.JMP_l(0)
+ self.mc.writeimm32(0)
self.mc.force_frame_size(DEFAULT_FRAME_BYTES)
- offset = self.mc.get_relative_pos() - 4
rawstart = self.materialize_loop(looptoken)
- # update the jump to the real trace
- self._patch_jump_for_descr(rawstart + offset, asminfo.rawstart)
+ # update the jump (above) to the real trace
+ self._patch_jump_to(rawstart + offset, asminfo.rawstart)
# update the guard to jump right to this custom piece of assembler
self.patch_jump_for_descr(faildescr, rawstart)
+ def _patch_jump_to(self, adr_jump_offset, adr_new_target):
+ assert adr_jump_offset != 0
+ offset = adr_new_target - (adr_jump_offset + 5)
+ mc = codebuf.MachineCodeBlockWrapper()
+ mc.force_frame_size(DEFAULT_FRAME_BYTES)
+ if rx86.fits_in_32bits(offset):
+ mc.JMP_l(offset)
+ else:
+ mc.MOV_ri(X86_64_SCRATCH_REG.value, adr_new_target)
+ mc.JMP_r(X86_64_SCRATCH_REG.value)
+ mc.copy_to_raw_memory(adr_jump_offset)
+
def write_pending_failure_recoveries(self, regalloc):
# for each pending guard, generate the code of the recovery stub
# at the end of self.mc.
@@ -791,10 +804,6 @@
def patch_jump_for_descr(self, faildescr, adr_new_target):
adr_jump_offset = faildescr.adr_jump_offset
- self._patch_jump_for_descr(adr_jump_offset, adr_new_target)
- faildescr.adr_jump_offset = 0 # means "patched"
-
- def _patch_jump_for_descr(self, adr_jump_offset, adr_new_target):
assert adr_jump_offset != 0
offset = adr_new_target - (adr_jump_offset + 4)
# If the new target fits within a rel32 of the jump, just patch
@@ -815,6 +824,7 @@
p = rffi.cast(rffi.INTP, adr_jump_offset)
adr_target = adr_jump_offset + 4 + rffi.cast(lltype.Signed, p[0])
mc.copy_to_raw_memory(adr_target)
+ faildescr.adr_jump_offset = 0 # means "patched"
def fixup_target_tokens(self, rawstart):
for targettoken in self.target_tokens_currently_compiling:
diff --git a/rpython/jit/backend/x86/regalloc.py
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -358,11 +358,11 @@
assert self.assembler.mc._frame_size == DEFAULT_FRAME_BYTES
self.rm.position = i
self.xrm.position = i
- if op.has_no_side_effect() and op not in self.longevity:
+ if rop.has_no_side_effect(op.opnum) and op not in self.longevity:
i += 1
self.possibly_free_vars_for_op(op)
continue
- if not we_are_translated() and op.getopnum() == -127:
+ if not we_are_translated() and op.getopnum() == rop.FORCE_SPILL:
self._consider_force_spill(op)
else:
oplist[op.getopnum()](self, op)
diff --git a/rpython/jit/backend/zarch/pool.py
b/rpython/jit/backend/zarch/pool.py
--- a/rpython/jit/backend/zarch/pool.py
+++ b/rpython/jit/backend/zarch/pool.py
@@ -33,7 +33,7 @@
def ensure_can_hold_constants(self, asm, op):
# allocates 8 bytes in memory for pointers, long integers or floats
- if op.is_jit_debug():
+ if rop.is_jit_debug(op.getopnum()):
return
for arg in op.getarglist():
diff --git a/rpython/jit/backend/zarch/regalloc.py
b/rpython/jit/backend/zarch/regalloc.py
--- a/rpython/jit/backend/zarch/regalloc.py
+++ b/rpython/jit/backend/zarch/regalloc.py
@@ -476,7 +476,8 @@
self.assembler.mc.mark_op(op)
self.rm.position = i
self.fprm.position = i
- if op.has_no_side_effect() and op not in self.longevity:
+ opnum = op.getopnum()
+ if rop.has_no_side_effect(opnum) and op not in self.longevity:
i += 1
self.possibly_free_vars_for_op(op)
continue
@@ -488,8 +489,7 @@
else:
self.fprm.temp_boxes.append(box)
#
- opnum = op.getopnum()
- if not we_are_translated() and opnum == -127:
+ if not we_are_translated() and opnum == rop.FORCE_SPILL:
self._consider_force_spill(op)
else:
arglocs = prepare_oplist[opnum](self, op)
diff --git a/rpython/jit/codewriter/jtransform.py
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -688,6 +688,10 @@
ARRAY = op.args[0].concretetype.TO
if self._array_of_voids(ARRAY):
return []
+ if isinstance(ARRAY, lltype.FixedSizeArray):
+ raise NotImplementedError(
+ "%r uses %r, which is not supported by the JIT codewriter"
+ % (self.graph, ARRAY))
if op.args[0] in self.vable_array_vars: # for virtualizables
vars = self.vable_array_vars[op.args[0]]
(v_base, arrayfielddescr, arraydescr) = vars
@@ -718,6 +722,10 @@
ARRAY = op.args[0].concretetype.TO
if self._array_of_voids(ARRAY):
return []
+ if isinstance(ARRAY, lltype.FixedSizeArray):
+ raise NotImplementedError(
+ "%r uses %r, which is not supported by the JIT codewriter"
+ % (self.graph, ARRAY))
if op.args[0] in self.vable_array_vars: # for virtualizables
vars = self.vable_array_vars[op.args[0]]
(v_base, arrayfielddescr, arraydescr) = vars
diff --git a/rpython/jit/codewriter/test/test_jtransform.py
b/rpython/jit/codewriter/test/test_jtransform.py
--- a/rpython/jit/codewriter/test/test_jtransform.py
+++ b/rpython/jit/codewriter/test/test_jtransform.py
@@ -1316,6 +1316,21 @@
tr = Transformer(None, None)
py.test.raises(NotImplementedError, tr.rewrite_operation, op)
+def test_no_fixedsizearray():
+ A = lltype.FixedSizeArray(lltype.Signed, 5)
+ v_x = varoftype(lltype.Ptr(A))
+ op = SpaceOperation('getarrayitem', [v_x, Constant(0, lltype.Signed)],
+ varoftype(lltype.Signed))
+ tr = Transformer(None, None)
+ tr.graph = 'demo'
+ py.test.raises(NotImplementedError, tr.rewrite_operation, op)
+ op = SpaceOperation('setarrayitem', [v_x, Constant(0, lltype.Signed),
+ Constant(42, lltype.Signed)],
+ varoftype(lltype.Void))
+ e = py.test.raises(NotImplementedError, tr.rewrite_operation, op)
+ assert str(e.value) == (
+ "'demo' uses %r, which is not supported by the JIT codewriter" % (A,))
+
def _test_threadlocalref_get(loop_inv):
from rpython.rlib.rthread import ThreadLocalField
tlfield = ThreadLocalField(lltype.Signed, 'foobar_test_',
diff --git a/rpython/jit/metainterp/blackhole.py
b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -1585,7 +1585,6 @@
def _done_with_this_frame(self):
# rare case: we only get there if the blackhole interps all returned
# normally (in general we get a ContinueRunningNormally exception).
- sd = self.builder.metainterp_sd
kind = self._return_type
if kind == 'v':
raise jitexc.DoneWithThisFrameVoid()
diff --git a/rpython/jit/metainterp/compile.py
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -27,12 +27,11 @@
class CompileData(object):
memo = None
+ log_noopt = True
def forget_optimization_info(self):
- for arg in self.start_label.getarglist():
+ for arg in self.trace.inputargs:
arg.set_forwarded(None)
- for op in self.operations:
- op.set_forwarded(None)
class LoopCompileData(CompileData):
""" An object that accumulates all of the necessary info for
@@ -40,15 +39,13 @@
This is the case of label() ops label()
"""
- def __init__(self, start_label, end_label, operations,
- call_pure_results=None, enable_opts=None):
- self.start_label = start_label
- self.end_label = end_label
+ def __init__(self, trace, runtime_boxes, call_pure_results=None,
+ enable_opts=None):
self.enable_opts = enable_opts
- assert start_label.getopnum() == rop.LABEL
- assert end_label.getopnum() == rop.LABEL
- self.operations = operations
+ self.trace = trace
self.call_pure_results = call_pure_results
+ assert runtime_boxes is not None
+ self.runtime_boxes = runtime_boxes
def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll):
from rpython.jit.metainterp.optimizeopt.unroll import (UnrollOptimizer,
@@ -56,23 +53,21 @@
if unroll:
opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations)
- return opt.optimize_preamble(self.start_label, self.end_label,
- self.operations,
+ return opt.optimize_preamble(self.trace,
+ self.runtime_boxes,
self.call_pure_results,
self.box_names_memo)
else:
opt = Optimizer(metainterp_sd, jitdriver_sd, optimizations)
- return opt.propagate_all_forward(self.start_label.getarglist(),
- self.operations, self.call_pure_results)
+ return opt.propagate_all_forward(self.trace,
self.call_pure_results)
class SimpleCompileData(CompileData):
""" This represents label() ops jump with no extra info associated with
the label
"""
- def __init__(self, start_label, operations, call_pure_results=None,
+ def __init__(self, trace, call_pure_results=None,
enable_opts=None):
- self.start_label = start_label
- self.operations = operations
+ self.trace = trace
self.call_pure_results = call_pure_results
self.enable_opts = enable_opts
@@ -81,17 +76,17 @@
#assert not unroll
opt = Optimizer(metainterp_sd, jitdriver_sd, optimizations)
- return opt.propagate_all_forward(self.start_label.getarglist(),
- self.operations, self.call_pure_results)
+ return opt.propagate_all_forward(self.trace.get_iter(),
+ self.call_pure_results)
class BridgeCompileData(CompileData):
""" This represents ops() with a jump at the end that goes to some
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit