[pypy-commit] pypy s390x-backend: implementing realloc frame
Author: Richard Plangger Branch: s390x-backend Changeset: r81505:35dcb2c4de31 Date: 2015-12-31 09:50 +0100 http://bitbucket.org/pypy/pypy/changeset/35dcb2c4de31/ Log:implementing realloc frame diff --git a/rpython/jit/backend/zarch/assembler.py b/rpython/jit/backend/zarch/assembler.py --- a/rpython/jit/backend/zarch/assembler.py +++ b/rpython/jit/backend/zarch/assembler.py @@ -298,10 +298,9 @@ # g) restore registers and return mc = InstrBuilder() self.mc = mc -return # signature of this _frame_realloc_slowpath function: -# * on entry, r0 is the new size +# * on entry, r3 is the new size # * on entry, r2 is the gcmap # * no managed register must be modified @@ -311,38 +310,43 @@ self._push_core_regs_to_jitframe(mc) self._push_fp_regs_to_jitframe(mc) -# Save away the LR inside r30 -#mc.mflr(r.RCS1.value) +self.mc.store_link() # First argument is SPP (= r31), which is the jitframe -mc.mr(r.r3.value, r.SPP.value) +mc.LGR(r.r2, r.SPP) -# Second argument is the new size, which is still in r0 here -mc.mr(r.r4.value, r.r0.value) +# no need to move second argument (frame_depth), +# it is already in register r3! + +RCS2 = r.r10 +RCS3 = r.r12 # This trashes r0 and r2 -self._store_and_reset_exception(mc, r.RCS2, r.RCS3) +self._store_and_reset_exception(mc, RCS2, RCS3) # Do the call adr = rffi.cast(lltype.Signed, self.cpu.realloc_frame) +mc.push_std_frame() mc.load_imm(mc.RAW_CALL_REG, adr) mc.raw_call() +mc.pop_std_frame() # The result is stored back into SPP (= r31) -mc.mr(r.SPP.value, r.r3.value) +mc.LGR(r.SPP, r.r2) -self._restore_exception(mc, r.RCS2, r.RCS3) +self._restore_exception(mc, RCS2, RCS3) gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: +xxx diff = mc.load_imm_plus(r.r5, gcrootmap.get_root_stack_top_addr()) mc.load(r.r5.value, r.r5.value, diff) mc.store(r.r3.value, r.r5.value, -WORD) -mc.mtlr(r.RCS1.value) # restore LR +mc.restore_link() self._pop_core_regs_from_jitframe(mc) self._pop_fp_regs_from_jitframe(mc) -mc.blr() +mc.BCR(c.ANY, r.RETURN) self._frame_realloc_slowpath = mc.materialize(self.cpu, []) self.mc = None @@ -492,17 +496,19 @@ """ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) -#mc.LG(r.r2, l.addr(ofs, r.SPP)) +mc.LG(r.r2, l.addr(ofs, r.SPP)) patch_pos = mc.currpos() -# XXX TODO -#self.mc.trap() -#mc.TRAP2() # placeholder for cmpdi(0, r2, ...) -#mc.TRAP2() # placeholder for bge -#mc.TRAP2() # placeholder for li(r0, ...) -#mc.load_imm(r.SCRATCH2, self._frame_realloc_slowpath) -#mc.mtctr(r.SCRATCH2.value) -#self.load_gcmap(mc, r.r2, gcmap) -#mc.bctrl() +# placeholder for the following instructions +# CGRL r2, ... (6 bytes) +# BRC c, ... (4 bytes) +# LGHI r3, ... (4 bytes) +# sum -> (14 bytes) +mc.write('\x00'*14) +mc.load_imm(r.RETURN, self._frame_realloc_slowpath) +self.load_gcmap(mc, r.r2, gcmap) +self.mc.push_std_frame() +mc.BCR(c.ANY, r.RETURN) +self.mc.pop_std_frame() self.frame_depth_to_patch.append((patch_pos, mc.currpos())) @@ -846,10 +852,10 @@ for traps_pos, jmp_target in self.frame_depth_to_patch: pmc = OverwritingBuilder(self.mc, traps_pos, 3) # three traps, so exactly three instructions to patch here -#pmc.cmpdi(0, r.r2.value, frame_depth) # 1 -#pmc.bc(7, 0, jmp_target - (traps_pos + 4))# 2 "bge+" -#pmc.li(r.r0.value, frame_depth) # 3 -#pmc.overwrite() +pmc.CGRL(r.r2, l.imm(frame_depth)) +pmc.BRC(c.EQ, jmp_target - (traps_pos + 6)) +pmc.LGHI(r.r3, frame_depth) +pmc.overwrite() def materialize_loop(self, looptoken): self.datablockwrapper.done() diff --git a/rpython/jit/backend/zarch/codebuilder.py b/rpython/jit/backend/zarch/codebuilder.py --- a/rpython/jit/backend/zarch/codebuilder.py +++ b/rpython/jit/backend/zarch/codebuilder.py @@ -10,6 +10,7 @@ from rpython.rtyper.lltypesystem import lltype, rffi, llmemory from rpython.tool.udir import udir from rpython.jit.backend.detect_cpu import autodetect +from rpython.jit.backend.zarch.arch import WORD clear_cache = rffi.llexternal( "__clear_cache", @@ -197,11 +198,17 @@ """ self.BASR(r.RETURN, call_reg)
[pypy-commit] pypy s390x-backend: realloc frame is nearly working, it seems though the token is not different from the frame?
Author: Richard Plangger Branch: s390x-backend Changeset: r81506:25e9fedba6e8 Date: 2015-12-31 11:03 +0100 http://bitbucket.org/pypy/pypy/changeset/25e9fedba6e8/ Log:realloc frame is nearly working, it seems though the token is not different from the frame? diff --git a/rpython/jit/backend/zarch/assembler.py b/rpython/jit/backend/zarch/assembler.py --- a/rpython/jit/backend/zarch/assembler.py +++ b/rpython/jit/backend/zarch/assembler.py @@ -321,7 +321,6 @@ RCS2 = r.r10 RCS3 = r.r12 -# This trashes r0 and r2 self._store_and_reset_exception(mc, RCS2, RCS3) # Do the call @@ -344,7 +343,8 @@ mc.store(r.r3.value, r.r5.value, -WORD) mc.restore_link() -self._pop_core_regs_from_jitframe(mc) +# do not restore r2, thus [1:] +self._pop_core_regs_from_jitframe(mc, r.MANAGED_REGS[1:]) self._pop_fp_regs_from_jitframe(mc) mc.BCR(c.ANY, r.RETURN) @@ -409,13 +409,9 @@ self._push_fp_regs_to_jitframe(mc) # allocate a stack frame! -mc.STG(r.SP, l.addr(-STD_FRAME_SIZE_IN_BYTES, r.SP)) # store the backchain -mc.AGHI(r.SP, l.imm(-STD_FRAME_SIZE_IN_BYTES)) - -# Do the call +mc.push_std_frame() mc.raw_call(r.r12) - -mc.AGHI(r.SP, l.imm(STD_FRAME_SIZE_IN_BYTES)) +mc.pop_std_frame() # Finish self._reload_frame_if_necessary(mc) @@ -437,15 +433,14 @@ # registers). mc = InstrBuilder() # -mc.STG(r.r14, l.addr(14*WORD, r.SP)) +mc.trap() +# mc.STG(r.r14, l.addr(14*WORD, r.SP)) # Do the call -# use SP as single parameter for the call -mc.STG(r.SP, l.addr(0, r.SP)) # store the backchain -mc.AGHI(r.SP, l.imm(-STD_FRAME_SIZE_IN_BYTES)) +mc.push_std_frame() mc.LGR(r.r2, r.SP) mc.load_imm(mc.RAW_CALL_REG, slowpathaddr) mc.raw_call() -mc.AGHI(r.SP, l.imm(STD_FRAME_SIZE_IN_BYTES)) +mc.pop_std_frame() # # Check if it raised StackOverflow mc.load_imm(r.SCRATCH, self.cpu.pos_exception()) @@ -455,7 +450,7 @@ mc.cmp_op(r.SCRATCH, 0, imm=True) # # So we return to our caller, conditionally if "EQ" -mc.LG(r.r14, l.addr(14*WORD, r.SP)) +# mc.LG(r.r14, l.addr(14*WORD, r.SP)) mc.BCR(c.EQ, r.r14) # # Else, jump to propagate_exception_path @@ -479,6 +474,7 @@ endaddr, lengthaddr, _ = self.cpu.insert_stack_check() diff = lengthaddr - endaddr assert check_imm_value(diff) +xxx mc = self.mc mc.load_imm(r.SCRATCH, self.stack_check_slowpath) @@ -499,15 +495,15 @@ mc.LG(r.r2, l.addr(ofs, r.SPP)) patch_pos = mc.currpos() # placeholder for the following instructions -# CGRL r2, ... (6 bytes) +# CGFI r2, ... (6 bytes) # BRC c, ... (4 bytes) # LGHI r3, ... (4 bytes) # sum -> (14 bytes) mc.write('\x00'*14) +self.mc.push_std_frame() mc.load_imm(r.RETURN, self._frame_realloc_slowpath) self.load_gcmap(mc, r.r2, gcmap) -self.mc.push_std_frame() -mc.BCR(c.ANY, r.RETURN) +mc.raw_call() self.mc.pop_std_frame() self.frame_depth_to_patch.append((patch_pos, mc.currpos())) @@ -852,9 +848,9 @@ for traps_pos, jmp_target in self.frame_depth_to_patch: pmc = OverwritingBuilder(self.mc, traps_pos, 3) # three traps, so exactly three instructions to patch here -pmc.CGRL(r.r2, l.imm(frame_depth)) -pmc.BRC(c.EQ, jmp_target - (traps_pos + 6)) -pmc.LGHI(r.r3, frame_depth) +pmc.CGFI(r.r2, l.imm(frame_depth)) +pmc.BRC(c.EQ, l.imm(jmp_target - (traps_pos + 6))) +pmc.LGHI(r.r3, l.imm(frame_depth)) pmc.overwrite() def materialize_loop(self, looptoken): @@ -910,11 +906,6 @@ relative_target)) def _call_header(self): -# Reserve space for a function descriptor, 3 words -#self.mc.write64(0) -#self.mc.write64(0) -#self.mc.write64(0) - # Build a new stackframe of size STD_FRAME_SIZE_IN_BYTES self.mc.STMG(r.r6, r.r15, l.addr(6*WORD, r.SP)) # save the back chain diff --git a/rpython/jit/backend/zarch/codebuilder.py b/rpython/jit/backend/zarch/codebuilder.py --- a/rpython/jit/backend/zarch/codebuilder.py +++ b/rpython/jit/backend/zarch/codebuilder.py @@ -206,10 +206,10 @@ def push_std_frame(self): self.STG(r.SP, l.addr(-STD_FRAME_SIZE_IN_BYTES, r.SP)) -self.AGHI(r.SP, l.imm(-STD_FRAME_SIZE_IN_BYTES)) +self.LAY(r.SP, l.addr(-STD_FRAME_SIZE_IN_BYTES, r.SP)) def pop_std_frame(self): -self.AGHI(r.SP, l.imm(STD_FRAME_SIZE_IN_BYTES)) +
[pypy-commit] cffi static-callback-embedding: tweaks
Author: Armin Rigo Branch: static-callback-embedding Changeset: r2500:eb5b30231847 Date: 2015-12-30 15:46 +0100 http://bitbucket.org/cffi/cffi/changeset/eb5b30231847/ Log:tweaks diff --git a/cffi/_embedding.h b/cffi/_embedding.h --- a/cffi/_embedding.h +++ b/cffi/_embedding.h @@ -4,7 +4,7 @@ #if defined(_MSC_VER) # define CFFI_DLLEXPORT __declspec(dllexport) #elif defined(__GNUC__) -# define CFFI_DLLEXPORT __attribute__ ((visibility("default"))) +# define CFFI_DLLEXPORT __attribute__((visibility("default"))) #else # define CFFI_DLLEXPORT /* nothing */ #endif @@ -33,12 +33,19 @@ #ifndef _MSC_VER /* --- Assuming a GCC not infinitely old --- */ -# define compare_and_swap(l,o,n) __sync_bool_compare_and_swap(l,o,n) -# define write_barrier() __sync_synchronize() +# define cffi_compare_and_swap(l,o,n) __sync_bool_compare_and_swap(l,o,n) +# define cffi_write_barrier() __sync_synchronize() +# if !defined(__amd64__) && !defined(__x86_64__) && \ + !defined(__i386__) && !defined(__i386) +# define cffi_read_barrier() __sync_synchronize() +# else +# define cffi_read_barrier() (void)0 +# endif #else /* --- Windows threads version --- */ -# define compare_and_swap(l,o,n) InterlockedCompareExchangePointer(l,n,o) -# define write_barrier() InterlockedCompareExchange(&_cffi_dummy,0,0) +# define cffi_compare_and_swap(l,o,n) InterlockedCompareExchangePointer(l,n,o) +# define cffi_write_barrier() InterlockedCompareExchange(&_cffi_dummy,0,0) +# define cffi_read_barrier() (void)0 static volatile LONG _cffi_dummy; #endif @@ -56,7 +63,7 @@ { static volatile void *lock = NULL; -while (!compare_and_swap(&lock, NULL, (void *)1)) { +while (!cffi_compare_and_swap(&lock, NULL, (void *)1)) { /* should ideally do a spin loop instruction here, but hard to do it portably and doesn't really matter I think: PyEval_InitThreads() should be very fast, and @@ -77,7 +84,7 @@ } #endif -while (!compare_and_swap(&lock, (void *)1, NULL)) +while (!cffi_compare_and_swap(&lock, (void *)1, NULL)) ; #ifndef _MSC_VER @@ -237,7 +244,7 @@ old_value = *lock; if (old_value[0] == 'E') { assert(old_value[1] == 'N'); -if (compare_and_swap(lock, old_value, old_value + 1)) +if (cffi_compare_and_swap(lock, old_value, old_value + 1)) break; } else { @@ -253,11 +260,11 @@ PyEval_InitThreads();/* makes the GIL */ PyEval_ReleaseLock();/* then release it */ } -/* else: we already have the GIL, but we still needed to do the +/* else: there is already a GIL, but we still needed to do the spinlock dance to make sure that we see it as fully ready */ /* release the lock */ -while (!compare_and_swap(lock, old_value + 1, old_value)) +while (!cffi_compare_and_swap(lock, old_value + 1, old_value)) ; #endif } @@ -364,7 +371,7 @@ after that read barrier, we see everything done here before the write barrier. */ -write_barrier(); +cffi_write_barrier(); assert(_cffi_call_python_org != NULL); _cffi_call_python = (_cffi_call_python_fnptr)_cffi_call_python_org; @@ -406,9 +413,6 @@ fnptr(externpy, args); } -#undef compare_and_swap -#undef write_barrier - /* The cffi_start_python() function makes sure Python is initialized and our cffi module is set up. It can be called manually from the @@ -422,5 +426,10 @@ if (_cffi_start_python() == NULL) return -1; } +cffi_read_barrier(); return 0; } + +#undef cffi_compare_and_swap +#undef cffi_write_barrier +#undef cffi_read_barrier ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] cffi static-callback-embedding: hg merge default
Author: Armin Rigo Branch: static-callback-embedding Changeset: r2499:2075cb3f448f Date: 2015-12-29 14:33 +0100 http://bitbucket.org/cffi/cffi/changeset/2075cb3f448f/ Log:hg merge default diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -266,18 +266,7 @@ /* whenever running Python code, the errno is saved in this thread-local variable */ #ifndef MS_WIN32 -# ifdef USE__THREAD -/* This macro ^^^ is defined by setup.py if it finds that it is - syntactically valid to use "__thread" with this C compiler. */ -static __thread int cffi_saved_errno = 0; -static void save_errno(void) { cffi_saved_errno = errno; } -static void restore_errno(void) { errno = cffi_saved_errno; } -static void init_errno(void) { } -# else -# include "misc_thread.h" -# endif -# define save_errno_only save_errno -# define restore_errno_only restore_errno +# include "misc_thread_posix.h" #endif #include "minibuffer.h" @@ -290,8 +279,11 @@ # include "wchar_helper.h" #endif -typedef PyObject *const cffi_allocator_t[3]; -static cffi_allocator_t default_allocator = { NULL, NULL, NULL }; +typedef struct _cffi_allocator_s { +PyObject *ca_alloc, *ca_free; +int ca_dont_clear; +} cffi_allocator_t; +static const cffi_allocator_t default_allocator = { NULL, NULL, 0 }; static PyObject *FFIError; static PyObject *unique_cache; @@ -3030,21 +3022,18 @@ static CDataObject *allocate_with_allocator(Py_ssize_t basesize, Py_ssize_t datasize, CTypeDescrObject *ct, -cffi_allocator_t allocator) +const cffi_allocator_t *allocator) { CDataObject *cd; -PyObject *my_alloc = allocator[0]; -PyObject *my_free = allocator[1]; -PyObject *dont_clear_after_alloc = allocator[2]; - -if (my_alloc == NULL) { /* alloc */ + +if (allocator->ca_alloc == NULL) { cd = allocate_owning_object(basesize + datasize, ct); if (cd == NULL) return NULL; cd->c_data = ((char *)cd) + basesize; } else { -PyObject *res = PyObject_CallFunction(my_alloc, "n", datasize); +PyObject *res = PyObject_CallFunction(allocator->ca_alloc, "n", datasize); if (res == NULL) return NULL; @@ -3069,16 +3058,16 @@ return NULL; } -cd = allocate_gcp_object(cd, ct, my_free); +cd = allocate_gcp_object(cd, ct, allocator->ca_free); Py_DECREF(res); } -if (dont_clear_after_alloc == NULL) +if (!allocator->ca_dont_clear) memset(cd->c_data, 0, datasize); return cd; } static PyObject *direct_newp(CTypeDescrObject *ct, PyObject *init, - cffi_allocator_t allocator) + const cffi_allocator_t *allocator) { CTypeDescrObject *ctitem; CDataObject *cd; @@ -3183,7 +3172,7 @@ PyObject *init = Py_None; if (!PyArg_ParseTuple(args, "O!|O:newp", &CTypeDescr_Type, &ct, &init)) return NULL; -return direct_newp(ct, init, default_allocator); +return direct_newp(ct, init, &default_allocator); } static int @@ -4659,7 +4648,9 @@ if (cif_descr != NULL) { /* exchange data size */ -cif_descr->exchange_size = exchange_offset; +/* we also align it to the next multiple of 8, in an attempt to + work around bugs(?) of libffi like #241 */ +cif_descr->exchange_size = ALIGN_ARG(exchange_offset); } return 0; } @@ -5101,15 +5092,9 @@ { save_errno(); { -#ifdef WITH_THREAD -PyGILState_STATE state = PyGILState_Ensure(); -#endif - +PyGILState_STATE state = gil_ensure(); general_invoke_callback(1, result, (char *)args, userdata); - -#ifdef WITH_THREAD -PyGILState_Release(state); -#endif +gil_release(state); } restore_errno(); } @@ -6515,7 +6500,7 @@ if (v == NULL || PyModule_AddObject(m, "_C_API", v) < 0) INITERROR; -v = PyText_FromString("1.3.1"); +v = PyText_FromString("1.4.2"); if (v == NULL || PyModule_AddObject(m, "__version__", v) < 0) INITERROR; @@ -6542,7 +6527,7 @@ INITERROR; } -init_errno(); +init_cffi_tls(); if (PyErr_Occurred()) INITERROR; diff --git a/c/call_python.c b/c/call_python.c --- a/c/call_python.c +++ b/c/call_python.c @@ -24,9 +24,6 @@ static PyObject *_ffi_def_extern_decorator(PyObject *outer_args, PyObject *fn) { -#if PY_MAJOR_VERSION >= 3 -# error review! -#endif char *s; PyObject *error, *onerror, *infotuple, *old1; int index, err; @@ -43,10 +40,10 @@ return NULL; if (s == NULL) { -PyObject *name = PyObject_GetAttrString(fn, "__name__"); +name = PyObject_GetAttrString(fn, "__name__"); if (name == NULL) r
[pypy-commit] pypy cffi-static-callback-embedding: continue the cffi-static-callback-embedding branch, merge from default
Author: Armin Rigo Branch: cffi-static-callback-embedding Changeset: r81507:81e85ede3e5a Date: 2015-12-30 15:52 +0100 http://bitbucket.org/pypy/pypy/changeset/81e85ede3e5a/ Log:continue the cffi-static-callback-embedding branch, merge from default diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -10,8 +10,6 @@ from rpython.config.config import ConflictConfigError from pypy.tool.option import make_objspace from pypy.conftest import pypydir -from rpython.rlib import rthread -from pypy.module.thread import os_thread thisdir = py.path.local(__file__).dirpath() @@ -78,108 +76,8 @@ return 1 return exitcode -# register the minimal equivalent of running a small piece of code. This -# should be used as sparsely as possible, just to register callbacks - -from rpython.rlib.entrypoint import entrypoint_highlevel -from rpython.rtyper.lltypesystem import rffi, lltype - -w_pathsetter = space.appexec([], """(): -def f(path): -import sys -sys.path[:] = path -return f -""") - -@entrypoint_highlevel('main', [rffi.CCHARP, rffi.INT], - c_name='pypy_setup_home') -def pypy_setup_home(ll_home, verbose): -from pypy.module.sys.initpath import pypy_find_stdlib -verbose = rffi.cast(lltype.Signed, verbose) -if ll_home: -home1 = rffi.charp2str(ll_home) -home = os.path.join(home1, 'x') # <- so that 'll_home' can be -# directly the root directory -else: -home = home1 = pypydir -w_path = pypy_find_stdlib(space, home) -if space.is_none(w_path): -if verbose: -debug("pypy_setup_home: directories 'lib-python' and 'lib_pypy'" - " not found in '%s' or in any parent directory" % home1) -return rffi.cast(rffi.INT, 1) -space.startup() -space.call_function(w_pathsetter, w_path) -# import site -try: -space.setattr(space.getbuiltinmodule('sys'), - space.wrap('executable'), - space.wrap(home)) -import_ = space.getattr(space.getbuiltinmodule('__builtin__'), -space.wrap('__import__')) -space.call_function(import_, space.wrap('site')) -return rffi.cast(rffi.INT, 0) -except OperationError, e: -if verbose: -debug("OperationError:") -debug(" operror-type: " + e.w_type.getname(space)) -debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space -return rffi.cast(rffi.INT, -1) - -@entrypoint_highlevel('main', [rffi.CCHARP], c_name='pypy_execute_source') -def pypy_execute_source(ll_source): -return pypy_execute_source_ptr(ll_source, 0) - -@entrypoint_highlevel('main', [rffi.CCHARP, lltype.Signed], - c_name='pypy_execute_source_ptr') -def pypy_execute_source_ptr(ll_source, ll_ptr): -source = rffi.charp2str(ll_source) -res = _pypy_execute_source(source, ll_ptr) -return rffi.cast(rffi.INT, res) - -@entrypoint_highlevel('main', [], c_name='pypy_init_threads') -def pypy_init_threads(): -if not space.config.objspace.usemodules.thread: -return -os_thread.setup_threads(space) - -@entrypoint_highlevel('main', [], c_name='pypy_thread_attach') -def pypy_thread_attach(): -if not space.config.objspace.usemodules.thread: -return -os_thread.setup_threads(space) -os_thread.bootstrapper.acquire(space, None, None) -rthread.gc_thread_start() -os_thread.bootstrapper.nbthreads += 1 -os_thread.bootstrapper.release() - -def _pypy_execute_source(source, c_argument): -try: -w_globals = space.newdict(module=True) -space.setitem(w_globals, space.wrap('__builtins__'), - space.builtin_modules['__builtin__']) -space.setitem(w_globals, space.wrap('c_argument'), - space.wrap(c_argument)) -space.appexec([space.wrap(source), w_globals], """(src, glob): -import sys -stmt = compile(src, 'c callback', 'exec') -if not hasattr(sys, '_pypy_execute_source'): -sys._pypy_execute_source = [] -sys._pypy_execute_source.append(glob) -exec stmt in glob -""") -except OperationError, e: -debug("OperationError:") -debug(" operror-type: " + e.w_type.getname(space)) -debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space -return -1 -return 0 - -retu
[pypy-commit] pypy cffi-static-callback-embedding: revert some changes, and roughly finish the logic. Need to think about how to test that
Author: Armin Rigo Branch: cffi-static-callback-embedding Changeset: r81508:381dbfd502eb Date: 2015-12-30 18:31 +0100 http://bitbucket.org/pypy/pypy/changeset/381dbfd502eb/ Log:revert some changes, and roughly finish the logic. Need to think about how to test that diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -10,6 +10,8 @@ from rpython.config.config import ConflictConfigError from pypy.tool.option import make_objspace from pypy.conftest import pypydir +from rpython.rlib import rthread +from pypy.module.thread import os_thread thisdir = py.path.local(__file__).dirpath() @@ -76,8 +78,107 @@ return 1 return exitcode -from pypy.interpreter import embedding -return entry_point, embedding.capture(space, debug) +# register the minimal equivalent of running a small piece of code. This +# should be used as sparsely as possible, just to register callbacks + +from rpython.rlib.entrypoint import entrypoint_highlevel +from rpython.rtyper.lltypesystem import rffi, lltype + +@entrypoint_highlevel('main', [rffi.CCHARP, rffi.INT], + c_name='pypy_setup_home') +def pypy_setup_home(ll_home, verbose): +from pypy.module.sys.initpath import pypy_find_stdlib +verbose = rffi.cast(lltype.Signed, verbose) +if ll_home: +home1 = rffi.charp2str(ll_home) +home = os.path.join(home1, 'x') # <- so that 'll_home' can be +# directly the root directory +else: +home = home1 = pypydir +w_path = pypy_find_stdlib(space, home) +if space.is_none(w_path): +if verbose: +debug("pypy_setup_home: directories 'lib-python' and 'lib_pypy'" + " not found in '%s' or in any parent directory" % home1) +return rffi.cast(rffi.INT, 1) +space.startup() +space.appexec([w_path], """(path): +import sys +sys.path[:] = path +""") +# import site +try: +space.setattr(space.getbuiltinmodule('sys'), + space.wrap('executable'), + space.wrap(home)) +import_ = space.getattr(space.getbuiltinmodule('__builtin__'), +space.wrap('__import__')) +space.call_function(import_, space.wrap('site')) +return rffi.cast(rffi.INT, 0) +except OperationError, e: +if verbose: +debug("OperationError:") +debug(" operror-type: " + e.w_type.getname(space)) +debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space +return rffi.cast(rffi.INT, -1) + +@entrypoint_highlevel('main', [rffi.CCHARP], c_name='pypy_execute_source') +def pypy_execute_source(ll_source): +return pypy_execute_source_ptr(ll_source, 0) + +@entrypoint_highlevel('main', [rffi.CCHARP, lltype.Signed], + c_name='pypy_execute_source_ptr') +def pypy_execute_source_ptr(ll_source, ll_ptr): +source = rffi.charp2str(ll_source) +res = _pypy_execute_source(source, ll_ptr) +return rffi.cast(rffi.INT, res) + +@entrypoint_highlevel('main', [], c_name='pypy_init_threads') +def pypy_init_threads(): +if not space.config.objspace.usemodules.thread: +return +os_thread.setup_threads(space) + +@entrypoint_highlevel('main', [], c_name='pypy_thread_attach') +def pypy_thread_attach(): +if not space.config.objspace.usemodules.thread: +return +os_thread.setup_threads(space) +os_thread.bootstrapper.acquire(space, None, None) +# XXX this doesn't really work. Don't use os.fork(), and +# if your embedder program uses fork(), don't use any PyPy +# code in the fork +rthread.gc_thread_start() +os_thread.bootstrapper.nbthreads += 1 +os_thread.bootstrapper.release() + +def _pypy_execute_source(source, c_argument): +try: +w_globals = space.newdict(module=True) +space.setitem(w_globals, space.wrap('__builtins__'), + space.builtin_modules['__builtin__']) +space.setitem(w_globals, space.wrap('c_argument'), + space.wrap(c_argument)) +space.appexec([space.wrap(source), w_globals], """(src, glob): +import sys +stmt = compile(src, 'c callback', 'exec') +if not hasattr(sys, '_pypy_execute_source'): +sys._pypy_execute_source = [] +sys._pypy_execute_source.append(glob) +exec stmt in glob +""") +except OperationError, e: +debug("OperationError
[pypy-commit] pypy default: Remove the hacks in optimizeopt introduced by 'faster-rstruct' and
Author: Armin Rigo Branch: Changeset: r81509:c46508226ad9 Date: 2015-12-31 10:46 + http://bitbucket.org/pypy/pypy/changeset/c46508226ad9/ Log:Remove the hacks in optimizeopt introduced by 'faster-rstruct' and instead add a 'llop.gc_load_indexed' operation that turns into a regular GC_LOAD_INDEXED resop. diff --git a/pypy/module/pypyjit/test_pypy_c/test_struct.py b/pypy/module/pypyjit/test_pypy_c/test_struct.py --- a/pypy/module/pypyjit/test_pypy_c/test_struct.py +++ b/pypy/module/pypyjit/test_pypy_c/test_struct.py @@ -45,7 +45,7 @@ # the newstr and the strsetitems are because the string is forced, # which is in turn because the optimizer doesn't know how to handle a -# getarrayitem_gc_i on a virtual string. It could be improved, but it +# gc_load_indexed_i on a virtual string. It could be improved, but it # is also true that in real life cases struct.unpack is called on # strings which come from the outside, so it's a minor issue. assert loop.match_by_id("unpack", """ @@ -55,17 +55,17 @@ strsetitem(p88, 1, i14) strsetitem(p88, 2, i17) strsetitem(p88, 3, i20) -i91 = getarrayitem_gc_i(p88, 0, descr=) +i91 = gc_load_indexed_i(p88, 0, 1, _, -4) """) def test_struct_object(self): def main(n): import struct -s = struct.Struct("i") +s = struct.Struct("ii") i = 1 while i < n: -buf = s.pack(i) # ID: pack -x = s.unpack(buf)[0] # ID: unpack +buf = s.pack(-1, i) # ID: pack +x = s.unpack(buf)[1]# ID: unpack i += x / i return i @@ -88,10 +88,15 @@ assert loop.match_by_id('unpack', """ # struct.unpack -p88 = newstr(4) -strsetitem(p88, 0, i11) -strsetitem(p88, 1, i14) -strsetitem(p88, 2, i17) -strsetitem(p88, 3, i20) -i91 = getarrayitem_gc_i(p88, 0, descr=) +p88 = newstr(8) +strsetitem(p88, 0, 255) +strsetitem(p88, 1, 255) +strsetitem(p88, 2, 255) +strsetitem(p88, 3, 255) +strsetitem(p88, 4, i11) +strsetitem(p88, 5, i14) +strsetitem(p88, 6, i17) +strsetitem(p88, 7, i20) +i90 = gc_load_indexed_i(p88, 0, 1, _, -4) +i91 = gc_load_indexed_i(p88, 4, 1, _, -4) """) 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 @@ -13,6 +13,7 @@ from rpython.rtyper.llinterp import LLInterpreter, LLException from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr +from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper import rclass from rpython.rlib.clibffi import FFI_DEFAULT_ABI @@ -638,18 +639,9 @@ return array.getlength() def bh_getarrayitem_gc(self, a, index, descr): +a = support.cast_arg(lltype.Ptr(descr.A), a) +array = a._obj assert index >= 0 -if descr.A is descr.OUTERA: -a = support.cast_arg(lltype.Ptr(descr.A), a) -else: -# we use rffi.cast instead of support.cast_arg because the types -# might not be "compatible" enough from the lltype point of -# view. In particular, this happens when we use -# str_storage_getitem, in which an rpy_string is casted to -# rpy_string_as_Signed (or similar) -a = rffi.cast(lltype.Ptr(descr.OUTERA), a) -a = getattr(a, descr.OUTERA._arrayfld) -array = a._obj return support.cast_result(descr.A.OF, array.getitem(index)) bh_getarrayitem_gc_pure_i = bh_getarrayitem_gc @@ -714,6 +706,24 @@ else: return self.bh_raw_load_i(struct, offset, descr) +def bh_gc_load_indexed_i(self, struct, index, scale, base_ofs, bytes): +if bytes == 1: T = rffi.UCHAR +elif bytes == 2: T = rffi.USHORT +elif bytes == 4: T = rffi.UINT +elif bytes == 8: T = rffi.ULONGLONG +elif bytes == -1: T = rffi.SIGNEDCHAR +elif bytes == -2: T = rffi.SHORT +elif bytes == -4: T = rffi.INT +elif bytes == -8: T = rffi.LONGLONG +else: raise NotImplementedError(bytes) +x = llop.gc_load_indexed(T, struct, index, scale, base_ofs) +return lltype.cast_primitive(lltype.Signed, x) + +def bh_gc_load_indexed_f(self, struct, index, scale, base_ofs, bytes): +if bytes != 8: +raise Exception("gc_load_indexed_f is only for 'double'!") +return llop.gc_load_indexed(rffi.DOUBLE, struct, index, scale, base_ofs) + def bh_increment_debug_counter(self, addr): p = rffi.cast(rffi.CArrayPtr(l
[pypy-commit] cffi static-callback-embedding: more tweaks; tests needed...
Author: Armin Rigo Branch: static-callback-embedding Changeset: r2501:c3084bd75943 Date: 2015-12-30 22:36 +0100 http://bitbucket.org/cffi/cffi/changeset/c3084bd75943/ Log:more tweaks; tests needed... diff --git a/cffi/_embedding.h b/cffi/_embedding.h --- a/cffi/_embedding.h +++ b/cffi/_embedding.h @@ -195,8 +195,9 @@ f = PySys_GetObject((char *)"stderr"); if (f != NULL && f != Py_None) { -PyFile_WriteString("\ncffi version: 1.3.1", f); -PyFile_WriteString("\n_cffi_backend module: ", f); +PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME + "\ncompiled with cffi version: 1.4.2" + "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); if (mod == NULL) { @@ -218,7 +219,7 @@ PyAPI_DATA(char *) _PyParser_TokenNames[]; /* from CPython */ -static void _cffi_carefully_make_gil(void) +static int _cffi_carefully_make_gil(void) { /* This initializes the GIL. It can be called completely concurrently from unrelated threads. It assumes that we don't @@ -267,6 +268,7 @@ while (!cffi_compare_and_swap(lock, old_value + 1, old_value)) ; #endif +return 0; } /** end CPython-specific section **/ @@ -289,10 +291,12 @@ _CFFI_PYTHON_STARTUP_CODE, }; +extern int pypy_carefully_make_gil(const char *); extern int pypy_init_embedded_cffi_module(int, struct _cffi_pypy_init_s *); -static void _cffi_carefully_make_gil(void) +static int _cffi_carefully_make_gil(void) { +return pypy_carefully_make_gil(_CFFI_MODULE_NAME); } static int _cffi_initialize_python(void) @@ -345,14 +349,16 @@ */ static char called = 0; -_cffi_carefully_make_gil(); +if (_cffi_carefully_make_gil() != 0) +return NULL; + _cffi_acquire_reentrant_mutex(); /* Here the GIL exists, but we don't have it. We're only protected from concurrency by the reentrant mutex. */ -/* This file ignores subinterpreters and can only initialize the - embedded module once, in the main interpreter. */ +/* This file only initializes the embedded module once, the first + time this is called, even if there are subinterpreters. */ if (!called) { called = 1; /* invoke _cffi_initialize_python() only once, but don't set '_cffi_call_python' right now, @@ -365,13 +371,13 @@ '_cffi_call_python' without also seeing the rest of the data initialized. However, this is not possible. But the new value of '_cffi_call_python' is the function - 'cffi_call_python()' from _cffi_backend. We can put a - write barrier here, and a corresponding read barrier at - the start of cffi_call_python(). This ensures that - after that read barrier, we see everything done here - before the write barrier. + 'cffi_call_python()' from _cffi_backend. So: */ +cffi_write_barrier(); +/* ^^^ we put a write barrier here, and a corresponding + read barrier at the start of cffi_call_python(). This + ensures that after that read barrier, we see everything + done here before the write barrier. */ -cffi_write_barrier(); assert(_cffi_call_python_org != NULL); _cffi_call_python = (_cffi_call_python_fnptr)_cffi_call_python_org; diff --git a/testing/cffi0/test_version.py b/testing/cffi0/test_version.py --- a/testing/cffi0/test_version.py +++ b/testing/cffi0/test_version.py @@ -53,3 +53,10 @@ content = open(p).read() #v = BACKEND_VERSIONS.get(v, v) assert (('assert __version__ == "%s"' % v) in content) + +def test_embedding_h(): +parent = os.path.dirname(os.path.dirname(cffi.__file__)) +v = cffi.__version__ +p = os.path.join(parent, 'cffi', '_embedding.h') +content = open(p).read() +assert ('cffi version: %s"' % (v,)) in content ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy.org extradoc: update the values
Author: Armin Rigo Branch: extradoc Changeset: r685:0c65712acd39 Date: 2015-12-31 13:41 +0100 http://bitbucket.org/pypy/pypy.org/changeset/0c65712acd39/ Log:update the values diff --git a/don1.html b/don1.html --- a/don1.html +++ b/don1.html @@ -15,7 +15,7 @@ - $61634 of $105000 (58.7%) + $61639 of $105000 (58.7%) @@ -23,7 +23,7 @@ This donation goes towards supporting Python 3 in PyPy. Current status: -we have $6906 left +we have $6910 left in the account. Read proposal ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy llvm-translation-backend: Implement inhibit_tail_call marker.
Author: Manuel Jacob Branch: llvm-translation-backend Changeset: r81510:56cf0a68905a Date: 2015-12-31 16:55 +0100 http://bitbucket.org/pypy/pypy/changeset/56cf0a68905a/ Log:Implement inhibit_tail_call marker. This raises the required LLVM version to 3.8 (as of now unreleased). diff --git a/rpython/translator/llvm/genllvm.py b/rpython/translator/llvm/genllvm.py --- a/rpython/translator/llvm/genllvm.py +++ b/rpython/translator/llvm/genllvm.py @@ -1216,10 +1216,17 @@ tmp.append('{arg.TV}'.format(arg=arg)) args = ', '.join(tmp) +tailmarker = '' +try: +if fn.value._obj.graph.inhibit_tail_call: +tailmarker = 'notail ' +except AttributeError: +pass + if result.type is LLVMVoid: -fmt = 'call void {fn.V}({args})' +fmt = '{tailmarker}call void {fn.V}({args})' else: -fmt = '{result.V} = call {result.T} {fn.V}({args})' +fmt = '{result.V} = {tailmarker}call {result.T} {fn.V}({args})' self.w(fmt.format(**locals())) op_indirect_call = op_direct_call diff --git a/rpython/translator/llvm/test/test_genllvm.py b/rpython/translator/llvm/test/test_genllvm.py --- a/rpython/translator/llvm/test/test_genllvm.py +++ b/rpython/translator/llvm/test/test_genllvm.py @@ -655,6 +655,16 @@ assert not fc(r_longfloat(0.0)) assert fc(r_longfloat(1.0)) +def test_recursive_notail(self): +def f(n): +if n <= 0: +return 42 +return f(n+1) +def entry_point(): +return f(1) +fc = self.getcompiled(entry_point, []) +fc(expected_exception_name='StackOverflow') + class TestLowLevelTypeLLVM(_LLVMMixin, test_lltyped.TestLowLevelType): def getcompiled(self, func, argtypes): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cffi-static-callback-embedding: Translation fixes, manual testing...
Author: Armin Rigo Branch: cffi-static-callback-embedding Changeset: r81511:d5c92fe3af5b Date: 2015-12-31 15:30 + http://bitbucket.org/pypy/pypy/changeset/d5c92fe3af5b/ Log:Translation fixes, manual testing... diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -1,6 +1,7 @@ import sys from pypy.interpreter.mixedmodule import MixedModule -from rpython.rlib import rdynload, clibffi +from rpython.rlib import rdynload, clibffi, entrypoint +from rpython.rtyper.lltypesystem import rffi VERSION = "1.4.2" @@ -66,8 +67,8 @@ interpleveldefs['FFI_STDCALL'] = 'space.wrap(%d)' % FFI_STDCALL def startup(self, space): -from pypy.module._cffi_backend import cffi1_module -cffi1_module.glob.space = space +from pypy.module._cffi_backend import embedding +embedding.glob.space = space def get_dict_rtld_constants(): @@ -82,3 +83,11 @@ for _name, _value in get_dict_rtld_constants().items(): Module.interpleveldefs[_name] = 'space.wrap(%d)' % _value + + +# write this entrypoint() here, to make sure it is registered early enough +@entrypoint.entrypoint_highlevel('main', [rffi.INT, rffi.VOIDP], + c_name='pypy_init_embedded_cffi_module') +def pypy_init_embedded_cffi_module(version, init_struct): +from pypy.module._cffi_backend import embedding +return embedding.pypy_init_embedded_cffi_module(version, init_struct) diff --git a/pypy/module/_cffi_backend/cffi1_module.py b/pypy/module/_cffi_backend/cffi1_module.py --- a/pypy/module/_cffi_backend/cffi1_module.py +++ b/pypy/module/_cffi_backend/cffi1_module.py @@ -1,7 +1,7 @@ +import os from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.entrypoint import entrypoint -from pypy.interpreter.error import OperationError, oefmt +from pypy.interpreter.error import oefmt from pypy.interpreter.module import Module from pypy.module._cffi_backend import parse_c_type from pypy.module._cffi_backend.ffi_obj import W_FFIObject @@ -47,81 +47,3 @@ space.setitem(w_modules_dict, w_name, space.wrap(module)) space.setitem(w_modules_dict, space.wrap(name + '.lib'), space.wrap(lib)) return module - - -# - - -EMBED_VERSION_MIN= 0xB011 -EMBED_VERSION_MAX= 0xB0FF - -STDERR = 2 -INITSTRUCTPTR = lltype.Ptr(lltype.Struct('CFFI_INIT', - ('name', rffi.CCHARP), - ('func', rffi.VOIDP), - ('code', rffi.CCHARP))) - -def load_embedded_cffi_module(space, version, init_struct): -from pypy.module._cffi_backend.embedding import declare_c_function -declare_c_function() # translation-time hint only: - # declare _cffi_carefully_make_gil() -# -version = rffi.cast(lltype.Signed, version) -if not (VERSION_MIN <= version <= VERSION_MAX): -raise oefmt(space.w_ImportError, -"cffi embedded module has got unknown version tag %s", -hex(version)) -# -if space.config.objspace.usemodules.thread: -from pypy.module.thread import os_thread -os_thread.setup_threads(space) -# -name = rffi.charp2str(init_struct.name) -module = load_cffi1_module(space, name, None, init_struct.func) -code = rffi.charp2str(init_struct.code) -compiler = space.createcompiler() -pycode = compiler.compile(code, "" % name, 'exec', 0) -w_globals = module.getdict(space) -space.call_method(w_globals, "setdefault", space.wrap("__builtins__"), - space.wrap(space.builtin)) -pycode.exec_code(space, w_globals, w_globals) - - -class Global: -pass -glob = Global() - -@entrypoint('main', [rffi.INT, rffi.VOIDP], -c_name='_pypy_init_embedded_cffi_module') -def _pypy_init_embedded_cffi_module(version, init_struct): -name = "?" -try: -init_struct = rffi.cast(INITSTRUCTPTR, init_struct) -name = rffi.charp2str(init_struct.name) -# -space = glob.space -try: -load_embedded_cffi_module(space, version, init_struct) -res = 0 -except OperationError, operr: -operr.write_unraisable(space, "initialization of '%s'" % name, - with_traceback=True) -space.appexec([], """(): -import sys -sys.stderr.write('pypy version: %s.%s.%s\n' % - sys.pypy_version_info[:3]) -sys.stderr.write('sys.path: %r\n' % (sys.path,)) -""") -res = -1 -except Exception, e: -# oups! last-level attempt to recover. -try: -os.write(STDERR, "From initialization of '") -os.write(STDERR, name) -
[pypy-commit] pypy cffi-static-callback-embedding: Translation fix
Author: Armin Rigo Branch: cffi-static-callback-embedding Changeset: r81512:e4b349baee63 Date: 2015-12-31 16:02 + http://bitbucket.org/pypy/pypy/changeset/e4b349baee63/ Log:Translation fix diff --git a/pypy/module/_cffi_backend/cffi1_module.py b/pypy/module/_cffi_backend/cffi1_module.py --- a/pypy/module/_cffi_backend/cffi1_module.py +++ b/pypy/module/_cffi_backend/cffi1_module.py @@ -1,4 +1,3 @@ -import os from rpython.rtyper.lltypesystem import lltype, rffi from pypy.interpreter.error import oefmt diff --git a/pypy/module/_cffi_backend/embedding.py b/pypy/module/_cffi_backend/embedding.py --- a/pypy/module/_cffi_backend/embedding.py +++ b/pypy/module/_cffi_backend/embedding.py @@ -1,3 +1,4 @@ +import os from rpython.rtyper.lltypesystem import lltype, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy remove-getfield-pure: Merge with default
Author: Spenser Andrew Bauman Branch: remove-getfield-pure Changeset: r81513:3e4151de2899 Date: 2015-12-23 20:29 -0500 http://bitbucket.org/pypy/pypy/changeset/3e4151de2899/ Log:Merge with default diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,4 @@ release/ !pypy/tool/release/ rpython/_cache/ -__pycache__/ +.cache/ 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 @@ -44,6 +44,9 @@ .. branch: fix-setslice-can-resize +Make rlist's ll_listsetslice() able to resize the target list to help +simplify objspace/std/listobject.py. Was issue #2196. + .. branch: anntype2 A somewhat random bunch of changes and fixes following up on branch 'anntype'. Highlights: @@ -83,10 +86,18 @@ Trivial cleanups in flowspace.operation : fix comment & duplicated method .. branch: test-AF_NETLINK + +Add a test for pre-existing AF_NETLINK support. Was part of issue #1942. + .. branch: small-cleanups-misc + +Trivial misc cleanups: typo, whitespace, obsolete comments + .. branch: cpyext-slotdefs .. branch: fix-missing-canraise +.. branch: whatsnew .. branch: fix-2211 -Fix the cryptic exception message when attempting to use extended slicing in rpython +Fix the cryptic exception message when attempting to use extended slicing +in rpython. Was issue #2211. diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py --- a/pypy/module/cpyext/slotdefs.py +++ b/pypy/module/cpyext/slotdefs.py @@ -380,6 +380,17 @@ space.call_function(delattr_fn, w_self, w_name) return 0 api_func = slot_tp_setattro.api_func +elif name == 'tp_getattro': +getattr_fn = w_type.getdictvalue(space, '__getattribute__') +if getattr_fn is None: +return + +@cpython_api([PyObject, PyObject], PyObject, + error=lltype.nullptr(rffi.VOIDP.TO), external=True) +@func_renamer("cpyext_tp_getattro_%s" % (typedef.name,)) +def slot_tp_getattro(space, w_self, w_name): +return space.call_function(getattr_fn, w_self, w_name) +api_func = slot_tp_getattro.api_func else: return diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py --- a/pypy/module/cpyext/test/test_typeobject.py +++ b/pypy/module/cpyext/test/test_typeobject.py @@ -385,12 +385,53 @@ PyErr_SetString(PyExc_ValueError, "recursive tp_setattro"); return NULL; } + if (!args->ob_type->tp_getattro) + { + PyErr_SetString(PyExc_ValueError, "missing tp_getattro"); + return NULL; + } + if (args->ob_type->tp_getattro == + args->ob_type->tp_base->tp_getattro) + { + PyErr_SetString(PyExc_ValueError, "recursive tp_getattro"); + return NULL; + } Py_RETURN_TRUE; ''' ) ]) assert module.test_type(type(None)) +def test_tp_getattro(self): +module = self.import_extension('foo', [ +("test_tp_getattro", "METH_VARARGS", + ''' + PyObject *obj = PyTuple_GET_ITEM(args, 0); + PyIntObject *value = PyTuple_GET_ITEM(args, 1); + if (!obj->ob_type->tp_getattro) + { + PyErr_SetString(PyExc_ValueError, "missing tp_getattro"); + return NULL; + } + PyObject *name = PyString_FromString("attr1"); + PyIntObject *attr1 = obj->ob_type->tp_getattro(obj, name); + if (attr1->ob_ival != value->ob_ival) + { + PyErr_SetString(PyExc_ValueError, + "tp_getattro returned wrong value"); + return NULL; + } + Py_DECREF(name); + Py_DECREF(attr1); + Py_RETURN_TRUE; + ''' + ) +]) +class C: +def __init__(self): +self.attr1 = 123 +assert module.test_tp_getattro(C(), 123) + def test_nb_int(self): module = self.import_extension('foo', [ ("nb_int", "METH_O", diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py --- a/pypy/module/cpyext/typeobject.py +++ b/pypy/module/cpyext/typeobject.py @@ -582,6 +582,8 @@ pto.c_tp_free = base.c_tp_free if not pto.c_tp_setattro: pto.c_tp_setattro = base.c_tp_setattro +if not pto.c_tp_getattro: +pto.c_tp_getattro = base.c_tp_getattro finally: Py_DecRef(space, base_pyo) @@ -651,6 +653,12 @@ PyObject_G
[pypy-commit] pypy remove-getfield-pure: Sync with master
Author: Spenser Andrew Bauman Branch: remove-getfield-pure Changeset: r81514:b131bc726e2b Date: 2015-12-31 11:49 -0500 http://bitbucket.org/pypy/pypy/changeset/b131bc726e2b/ Log:Sync with master diff too long, truncating to 2000 out of 2109 lines diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.4.1 +Version: 1.4.2 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,8 +4,8 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "1.4.1" -__version_info__ = (1, 4, 1) +__version__ = "1.4.2" +__version_info__ = (1, 4, 2) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/pypy/module/_cffi_backend/cglob.py b/pypy/module/_cffi_backend/cglob.py --- a/pypy/module/_cffi_backend/cglob.py +++ b/pypy/module/_cffi_backend/cglob.py @@ -3,6 +3,7 @@ from pypy.interpreter.typedef import TypeDef from pypy.module._cffi_backend.cdataobj import W_CData from pypy.module._cffi_backend import newtype +from rpython.rlib import rgil from rpython.rlib.objectmodel import we_are_translated from rpython.rtyper.lltypesystem import lltype, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo @@ -26,7 +27,9 @@ if not we_are_translated(): FNPTR = rffi.CCallback([], rffi.VOIDP) fetch_addr = rffi.cast(FNPTR, self.fetch_addr) +rgil.release() result = fetch_addr() +rgil.acquire() else: # careful in translated versions: we need to call fetch_addr, # but in a GIL-releasing way. The easiest is to invoke a diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -423,7 +423,9 @@ exchange_offset += rffi.getintfield(self.atypes[i], 'c_size') # store the exchange data size -cif_descr.exchange_size = exchange_offset +# we also align it to the next multiple of 8, in an attempt to +# work around bugs(?) of libffi (see cffi issue #241) +cif_descr.exchange_size = self.align_arg(exchange_offset) def fb_extra_fields(self, cif_descr): cif_descr.abi = self.fabi diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py --- a/pypy/module/cpyext/slotdefs.py +++ b/pypy/module/cpyext/slotdefs.py @@ -386,7 +386,7 @@ return @cpython_api([PyObject, PyObject], PyObject, - error=lltype.nullptr(rffi.VOIDP.TO), external=True) + external=True) @func_renamer("cpyext_tp_getattro_%s" % (typedef.name,)) def slot_tp_getattro(space, w_self, w_name): return space.call_function(getattr_fn, w_self, w_name) diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py --- a/pypy/module/cpyext/test/test_typeobject.py +++ b/pypy/module/cpyext/test/test_typeobject.py @@ -414,15 +414,26 @@ return NULL; } PyObject *name = PyString_FromString("attr1"); - PyIntObject *attr1 = obj->ob_type->tp_getattro(obj, name); - if (attr1->ob_ival != value->ob_ival) + PyIntObject *attr = obj->ob_type->tp_getattro(obj, name); + if (attr->ob_ival != value->ob_ival) { PyErr_SetString(PyExc_ValueError, "tp_getattro returned wrong value"); return NULL; } Py_DECREF(name); - Py_DECREF(attr1); + Py_DECREF(attr); + name = PyString_FromString("attr2"); + attr = obj->ob_type->tp_getattro(obj, name); + if (attr == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) + { + PyErr_Clear(); + } else { + PyErr_SetString(PyExc_ValueError, + "tp_getattro should have raised"); + return NULL; + } + Py_DECREF(name); Py_RETURN_TRUE; ''' ) @@ -637,7 +648,7 @@ IntLikeObject *intObj; long intval; -if (!PyArg_ParseTuple(args, "i", &intval)) +