[pypy-commit] cffi static-callback-embedding: in-progress: a comment about eggs, and hacks to run the tests on pypy (some failures so far)
Author: Armin Rigo Branch: static-callback-embedding Changeset: r2514:2e002aebe5fa Date: 2016-01-02 08:46 + http://bitbucket.org/cffi/cffi/changeset/2e002aebe5fa/ Log:in-progress: a comment about eggs, and hacks to run the tests on pypy (some failures so far) diff --git a/testing/embedding/test_basic.py b/testing/embedding/test_basic.py --- a/testing/embedding/test_basic.py +++ b/testing/embedding/test_basic.py @@ -23,6 +23,12 @@ if name not in self._compiled_modules: path = self.get_path() filename = '%s.py' % name +# NOTE: if you have an .egg globally installed with an older +# version of cffi, this will not work, because sys.path ends +# up with the .egg before the PYTHONPATH entries. I didn't +# find a solution to that: we can hack sys.path inside the +# script run here, but we can't hack it in the same way in +# execute(). env = os.environ.copy() env['PYTHONPATH'] = os.path.dirname(os.path.dirname(local_dir)) self._run([sys.executable, os.path.join(local_dir, filename)], @@ -33,9 +39,22 @@ path = self.get_path() filename = '%s.c' % name shutil.copy(os.path.join(local_dir, filename), path) -self._run(['gcc', '-g', filename, '-o', name, '-L.'] + - ['%s.so' % modname for modname in modules] + - ['-lpython2.7', '-Wl,-rpath=$ORIGIN/'] + extra) +if '__pypy__' in sys.builtin_module_names: +# xxx a bit hackish, maybe ffi.compile() should do a better job +executable = os.path.abspath(sys.executable) +libpypy_c = os.path.join(os.path.dirname(executable), + 'libpypy-c.so') +try: +os.symlink(libpypy_c, os.path.join(path, 'libpypy-c.so')) +except OSError: +pass +self._run(['gcc', '-g', filename, '-o', name, '-L.'] + + ['%s.pypy-26.so' % modname for modname in modules] + + ['-lpypy-c', '-Wl,-rpath=$ORIGIN/'] + extra) +else: +self._run(['gcc', '-g', filename, '-o', name, '-L.'] + + ['%s.so' % modname for modname in modules] + + ['-lpython2.7', '-Wl,-rpath=$ORIGIN/'] + extra) def execute(self, name): path = self.get_path() ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] cffi static-callback-embedding: We need fflush(stdout) here, for a possibly bad reason: cpython 2.x
Author: Armin Rigo Branch: static-callback-embedding Changeset: r2515:cb13da0c37ca Date: 2016-01-02 08:51 + http://bitbucket.org/cffi/cffi/changeset/cb13da0c37ca/ Log:We need fflush(stdout) here, for a possibly bad reason: cpython 2.x writes to stdout, so it gets in the correct order, but pypy (and likely cpython 3.x) writes directly to the file descriptor diff --git a/testing/embedding/add_recursive-test.c b/testing/embedding/add_recursive-test.c --- a/testing/embedding/add_recursive-test.c +++ b/testing/embedding/add_recursive-test.c @@ -6,6 +6,7 @@ static int some_callback(int x) { printf("some_callback(%d)\n", x); +fflush(stdout); return add_rec(x, 9); } diff --git a/testing/embedding/thread1-test.c b/testing/embedding/thread1-test.c --- a/testing/embedding/thread1-test.c +++ b/testing/embedding/thread1-test.c @@ -30,6 +30,7 @@ assert(status == 0); printf("starting\n"); +fflush(stdout); for (i = 0; i < NTHREADS; i++) { status = pthread_create(&th, NULL, start_routine, NULL); assert(status == 0); diff --git a/testing/embedding/thread2-test.c b/testing/embedding/thread2-test.c --- a/testing/embedding/thread2-test.c +++ b/testing/embedding/thread2-test.c @@ -43,6 +43,7 @@ assert(status == 0); printf("starting\n"); +fflush(stdout); status = pthread_create(&th, NULL, start_routine_1, NULL); assert(status == 0); status = pthread_create(&th, NULL, start_routine_2, NULL); diff --git a/testing/embedding/thread3-test.c b/testing/embedding/thread3-test.c --- a/testing/embedding/thread3-test.c +++ b/testing/embedding/thread3-test.c @@ -40,6 +40,7 @@ assert(status == 0); printf("starting\n"); +fflush(stdout); for (i = 0; i < 10; i++) { status = pthread_create(&th, NULL, start_routine_2, NULL); assert(status == 0); ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy s390x-backend: did not think of the following scenario: in a bridge you cannot 'just' use volatile registers as some might be allocated in the trace it is exiting (fixed)
Author: Richard Plangger Branch: s390x-backend Changeset: r81521:8184205817a7 Date: 2016-01-02 10:42 +0100 http://bitbucket.org/pypy/pypy/changeset/8184205817a7/ Log:did not think of the following scenario: in a bridge you cannot 'just' use volatile registers as some might be allocated in the trace it is exiting (fixed) added edge case to gc_load which I have added to gc_load_indexed, but not gc_load 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 @@ -300,14 +300,14 @@ self.mc = mc # signature of this _frame_realloc_slowpath function: -# * on entry, r3 is the new size -# * on entry, r2 is the gcmap +# * on entry, r0 is the new size +# * on entry, r1 is the gcmap # * no managed register must be modified ofs2 = self.cpu.get_ofs_of_frame_field('jf_gcmap') -mc.STG(r.r2, l.addr(ofs2, r.SPP)) +mc.STG(r.SCRATCH, l.addr(ofs2, r.SPP)) -self._push_core_regs_to_jitframe(mc) +self._push_core_regs_to_jitframe(mc, r.MANAGED_REGS) self._push_fp_regs_to_jitframe(mc) self.mc.store_link() @@ -317,6 +317,7 @@ # no need to move second argument (frame_depth), # it is already in register r3! +mc.LGR(r.r3, r.SCRATCH2) RCS2 = r.r10 RCS3 = r.r12 @@ -343,8 +344,7 @@ mc.store(r.r3.value, r.r5.value, -WORD) mc.restore_link() -# do not restore r2, thus [1:] -self._pop_core_regs_from_jitframe(mc, r.MANAGED_REGS[1:]) +self._pop_core_regs_from_jitframe(mc) self._pop_fp_regs_from_jitframe(mc) mc.BCR(c.ANY, r.RETURN) @@ -492,17 +492,17 @@ """ 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.SCRATCH2, l.addr(ofs, r.SPP)) patch_pos = mc.currpos() # placeholder for the following instructions -# CGFI r2, ... (6 bytes) +# CGFI r1, ... (6 bytes) # BRC c, ... (4 bytes) -# LGHI r3, ... (4 bytes) +# LGHI r0, ... (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.load_gcmap(mc, r.SCRATCH, gcmap) mc.raw_call() self.mc.pop_std_frame() @@ -934,6 +934,8 @@ self.jmpto(r.r14) def _push_all_regs_to_stack(self, mc, withfloats, callee_only=False): +# not used!! +# XXX remove if not needed base_ofs = 2*WORD if callee_only: regs = ZARCHRegisterManager.save_around_call_regs diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py --- a/rpython/jit/backend/zarch/opassembler.py +++ b/rpython/jit/backend/zarch/opassembler.py @@ -807,7 +807,11 @@ def _emit_gc_load(self, op, arglocs, regalloc): result_loc, base_loc, ofs_loc, size_loc, sign_loc = arglocs -src_addr = l.addr(0, base_loc, ofs_loc) +if ofs_loc.is_imm(): +assert self._mem_offset_supported(ofs_loc.value) +src_addr = l.addr(ofs_loc.value, base_loc) +else: +src_addr = l.addr(0, base_loc, ofs_loc) self._memory_read(result_loc, src_addr, size_loc.value, sign_loc.value) emit_gc_load_i = _emit_gc_load ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy s390x-backend: added some sanity checks, s390x only fails 4 (in test_runner)
Author: Richard Plangger Branch: s390x-backend Changeset: r81522:6d2f6b85c6e0 Date: 2016-01-02 10:48 +0100 http://bitbucket.org/pypy/pypy/changeset/6d2f6b85c6e0/ Log:added some sanity checks, s390x only fails 4 (in test_runner) diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py --- a/rpython/jit/backend/zarch/opassembler.py +++ b/rpython/jit/backend/zarch/opassembler.py @@ -807,6 +807,7 @@ def _emit_gc_load(self, op, arglocs, regalloc): result_loc, base_loc, ofs_loc, size_loc, sign_loc = arglocs +assert not ofs_loc.is_in_pool() if ofs_loc.is_imm(): assert self._mem_offset_supported(ofs_loc.value) src_addr = l.addr(ofs_loc.value, base_loc) @@ -820,6 +821,7 @@ def _emit_gc_load_indexed(self, op, arglocs, regalloc): result_loc, base_loc, index_loc, offset_loc, size_loc, sign_loc =arglocs +assert not offset_loc.is_in_pool() if offset_loc.is_imm() and self._mem_offset_supported(offset_loc.value): addr_loc = l.addr(offset_loc.value, base_loc, index_loc) else: @@ -834,6 +836,7 @@ def emit_gc_store(self, op, arglocs, regalloc): (base_loc, index_loc, value_loc, size_loc) = arglocs +assert not index_loc.is_in_pool() if index_loc.is_imm() and self._mem_offset_supported(index_loc.value): addr_loc = l.addr(index_loc.value, base_loc) else: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy s390x-backend: asmlen test failed, because more instructions in the entry of a bridge are now compiled (realloc check), seems about right what other backends implement!
Author: Richard Plangger Branch: s390x-backend Changeset: r81523:72ff734c842f Date: 2016-01-02 10:55 +0100 http://bitbucket.org/pypy/pypy/changeset/72ff734c842f/ Log:asmlen test failed, because more instructions in the entry of a bridge are now compiled (realloc check), seems about right what other backends implement! diff --git a/rpython/jit/backend/zarch/test/test_runner.py b/rpython/jit/backend/zarch/test/test_runner.py --- a/rpython/jit/backend/zarch/test/test_runner.py +++ b/rpython/jit/backend/zarch/test/test_runner.py @@ -24,6 +24,6 @@ cpu.setup_once() return cpu -# TODO verify: the lgr might be redundant! add_loop_instructions = "lg; lgr; larl; agr; cgfi; je; j;$" -bridge_loop_instructions = ("larl; lg; br;") +bridge_loop_instructions = "larl; lg; cgfi; je; lghi; stg; " \ + "lay; lgfi; lgfi; basr; lay; lg; br;$" ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Fix: we need to "acquire/release the GIL" even around RPython_Startup(), like entrypoint.c does
Author: Armin Rigo Branch: Changeset: r81524:2b962d433084 Date: 2016-01-02 10:22 + http://bitbucket.org/pypy/pypy/changeset/2b962d433084/ Log:Fix: we need to "acquire/release the GIL" even around RPython_Startup(), like entrypoint.c does diff --git a/rpython/rlib/entrypoint.py b/rpython/rlib/entrypoint.py --- a/rpython/rlib/entrypoint.py +++ b/rpython/rlib/entrypoint.py @@ -120,9 +120,6 @@ _nowrapper=True, random_effects_on_gcobjs=True) -@entrypoint_lowlevel('main', [], c_name='rpython_startup_code') +@entrypoint_highlevel('main', [], c_name='rpython_startup_code') def rpython_startup_code(): -rffi.stackcounter.stacks_counter += 1 -llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py RPython_StartupCode() -rffi.stackcounter.stacks_counter -= 1 ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cffi-static-callback-embedding: Fixes. Yay! The cffi tests (after translation) pass.
Author: Armin Rigo Branch: cffi-static-callback-embedding Changeset: r81525:db64914878b9 Date: 2016-01-02 10:37 + http://bitbucket.org/pypy/pypy/changeset/db64914878b9/ Log:Fixes. Yay! The cffi tests (after translation) pass. 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 @@ -54,7 +54,9 @@ name = rffi.charp2str(init_struct.name) # space = glob.space +must_leave = False try: +must_leave = space.threadlocals.try_enter_thread(space) load_embedded_cffi_module(space, version, init_struct) res = 0 except OperationError, operr: @@ -67,6 +69,8 @@ sys.stderr.write('sys.path: %r\n' % (sys.path,)) """) res = -1 +if must_leave: +space.threadlocals.leave_thread(space) except Exception, e: # oups! last-level attempt to recover. try: @@ -110,7 +114,6 @@ rpython_startup_code(); RPyGilAllocate(); -RPyGilRelease(); if (dladdr(&_cffi_init, &info) == 0) { _cffi_init_error("dladdr() failed: ", dlerror()); diff --git a/rpython/rlib/entrypoint.py b/rpython/rlib/entrypoint.py --- a/rpython/rlib/entrypoint.py +++ b/rpython/rlib/entrypoint.py @@ -120,9 +120,6 @@ _nowrapper=True, random_effects_on_gcobjs=True) -@entrypoint_lowlevel('main', [], c_name='rpython_startup_code') +@entrypoint_highlevel('main', [], c_name='rpython_startup_code') def rpython_startup_code(): -rffi.stackcounter.stacks_counter += 1 -llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py RPython_StartupCode() -rffi.stackcounter.stacks_counter -= 1 ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy s390x-backend: exchanged AGHI with LAY, same effect, but LAY does not change the condition code which is needed by the write barrier helper!
Author: Richard Plangger Branch: s390x-backend Changeset: r81526:b2f6253a910d Date: 2016-01-02 11:56 +0100 http://bitbucket.org/pypy/pypy/changeset/b2f6253a910d/ Log:exchanged AGHI with LAY, same effect, but LAY does not change the condition code which is needed by the write barrier helper! 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 @@ -170,7 +170,7 @@ self.mc = mc # save the information -mc.STG(r.r14, l.addr(14*WORD, r.SP)) # save the link +mc.store_link() RCS2 = r.r10 RCS3 = r.r12 @@ -240,7 +240,7 @@ if withcards: # A final andix before the blr, for the caller. Careful to # not follow this instruction with another one that changes -# the status of cr0! +# the status of the condition code card_marking_mask = descr.jit_wb_cards_set_singlebyte mc.LLGC(RCS2, l.addr(descr.jit_wb_if_flag_byteofs, RCS2)) mc.NILL(RCS2, l.imm(card_marking_mask & 0xFF)) @@ -253,7 +253,7 @@ self._pop_core_regs_from_jitframe(mc, saved_regs) self._pop_fp_regs_from_jitframe(mc, saved_fp_regs) -mc.LG(r.RETURN, l.addr(14*WORD, r.SP)) # restore the link +mc.restore_link() mc.BCR(c.ANY, r.RETURN) self.mc = old_mc @@ -935,7 +935,7 @@ def _push_all_regs_to_stack(self, mc, withfloats, callee_only=False): # not used!! -# XXX remove if not needed +# TODO remove if not needed base_ofs = 2*WORD if callee_only: regs = ZARCHRegisterManager.save_around_call_regs diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py --- a/rpython/jit/backend/zarch/opassembler.py +++ b/rpython/jit/backend/zarch/opassembler.py @@ -454,10 +454,10 @@ mc.load_imm(r.r14, self.wb_slowpath[helper_num]) # alloc a stack frame -mc.AGHI(r.SP, l.imm(-STD_FRAME_SIZE_IN_BYTES)) +mc.push_std_frame() mc.BASR(r.r14, r.r14) # destory the frame -mc.AGHI(r.SP, l.imm(STD_FRAME_SIZE_IN_BYTES)) +mc.pop_std_frame() if card_marking_mask: # The helper ends again with a check of the flag in the object. @@ -480,26 +480,28 @@ tmp_loc = arglocs[2] n = descr.jit_wb_card_page_shift +assert tmp_loc is not r.SCRATCH +assert tmp_loc is not r.SCRATCH2 + # compute in tmp_loc the byte offset: -# ~(index >> (card_page_shift + 3)) ('~' is 'not_' below) +# ~(index >> (card_page_shift + 3)) mc.SRAG(tmp_loc, loc_index, l.addr(n+3)) -#mc.srli_op(tmp_loc.value, loc_index.value, n + 3) -# invert the bits + +# compute in SCRATCH the index of the bit inside the byte: +# (index >> card_page_shift) & 7 +# not supported on the development s390x :(, extension is not installed +# 0x80 sets zero flag. will store 0 into all selected bits +# mc.RISBGN(r.SCRATCH, loc_index, l.imm(3), l.imm(0x80 | 63), l.imm(61)) +mc.SRAG(r.SCRATCH, loc_index, l.addr(n)) +mc.NILL(r.SCRATCH, l.imm(0x7)) + +# invert the bits of tmp_loc mc.XIHF(tmp_loc, l.imm(0x)) mc.XILF(tmp_loc, l.imm(0x)) -# compute in r2 the index of the bit inside the byte: -# (index >> card_page_shift) & 7 -# 0x80 sets zero flag. will store 0 into all selected bits -# cannot be used on the VM -# mc.RISBGN(r.SCRATCH, loc_index, l.imm(3), l.imm(0x80 | 63), l.imm(61)) -mc.SLAG(r.SCRATCH, loc_index, l.addr(3)) -mc.NILL(r.SCRATCH, l.imm(0xff)) -#mc.rldicl(r.SCRATCH2.value, loc_index.value, 64 - n, 61) - -# set r2 to 1 << r2 +# set SCRATCH to 1 << r2 mc.LGHI(r.SCRATCH2, l.imm(1)) -mc.SLAG(r.SCRATCH, r.SCRATCH2, l.addr(0,r.SCRATCH)) +mc.SLAG(r.SCRATCH2, r.SCRATCH2, l.addr(0,r.SCRATCH)) # set this bit inside the byte of interest addr = l.addr(0, loc_base, tmp_loc) @@ -507,7 +509,6 @@ mc.OGR(r.SCRATCH, r.SCRATCH2) mc.STCY(r.SCRATCH, addr) # done - else: byte_index = loc_index.value >> descr.jit_wb_card_page_shift byte_ofs = ~(byte_index >> 3) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] cffi static-callback-embedding: Pseudo-tests that print some performance numbers for calling an embedded
Author: Armin Rigo Branch: static-callback-embedding Changeset: r2516:63c49bc07ecc Date: 2016-01-02 15:33 +0100 http://bitbucket.org/cffi/cffi/changeset/63c49bc07ecc/ Log:Pseudo-tests that print some performance numbers for calling an embedded "extern Python" function in a loop, with or without threads. diff --git a/testing/embedding/perf-test.c b/testing/embedding/perf-test.c new file mode 100644 --- /dev/null +++ b/testing/embedding/perf-test.c @@ -0,0 +1,86 @@ +#include +#include +#include +#ifdef PTEST_USE_THREAD +# include +# include +static sem_t done; +#endif + + +extern int add1(int, int); + + +static double time_delta(struct timeval *stop, struct timeval *start) +{ +return (stop->tv_sec - start->tv_sec) + +1e-6 * (stop->tv_usec - start->tv_usec); +} + +static double measure(void) +{ +long long i, iterations; +int result; +struct timeval start, stop; +double elapsed; + +add1(0, 0); /* prepare off-line */ + +i = 0; +iterations = 1000; +result = gettimeofday(&start, NULL); +assert(result == 0); + +while (1) { +for (; i < iterations; i++) { +add1(((int)i) & 0xaa, ((int)i) & 0x55); +} +result = gettimeofday(&stop, NULL); +assert(result == 0); + +elapsed = time_delta(&stop, &start); +assert(elapsed >= 0.0); +if (elapsed > 2.5) +break; +iterations = iterations * 3 / 2; +} + +return elapsed / (double)iterations; +} + +static void *start_routine(void *arg) +{ +double t = measure(); +printf("time per call: %.3g\n", t); + +#ifdef PTEST_USE_THREAD +int status = sem_post(&done); +assert(status == 0); +#endif + +return arg; +} + + +int main(void) +{ +#ifndef PTEST_USE_THREAD +start_routine(0); +#else +pthread_t th; +int i, status = sem_init(&done, 0, 0); +assert(status == 0); + +add1(0, 0); /* this is the main thread */ + +for (i = 0; i < PTEST_USE_THREAD; i++) { +status = pthread_create(&th, NULL, start_routine, NULL); +assert(status == 0); +} +for (i = 0; i < PTEST_USE_THREAD; i++) { +status = sem_wait(&done); +assert(status == 0); +} +#endif +return 0; +} diff --git a/testing/embedding/perf.py b/testing/embedding/perf.py new file mode 100644 --- /dev/null +++ b/testing/embedding/perf.py @@ -0,0 +1,18 @@ +import cffi + +ffi = cffi.FFI() + +ffi.cdef(""" +extern "Python" int add1(int, int); +""", dllexport=True) + +ffi.embedding_init_code(r""" +@ffi.def_extern() +def add1(x, y): +return x + y +""") + +ffi.set_source("_perf_cffi", """ +""") + +ffi.compile(verbose=True) diff --git a/testing/embedding/test_performance.py b/testing/embedding/test_performance.py new file mode 100644 --- /dev/null +++ b/testing/embedding/test_performance.py @@ -0,0 +1,47 @@ +from testing.embedding.test_basic import EmbeddingTests + + +class TestPerformance(EmbeddingTests): +def test_perf_single_threaded(self): +self.prepare_module('perf') +self.compile('perf-test', ['_perf_cffi'], ['-O2']) +output = self.execute('perf-test') +print '='*79 +print output.rstrip() +print '='*79 + +def test_perf_in_1_thread(self): +self.prepare_module('perf') +self.compile('perf-test', ['_perf_cffi'], + ['-pthread', '-O2', '-DPTEST_USE_THREAD=1']) +output = self.execute('perf-test') +print '='*79 +print output.rstrip() +print '='*79 + +def test_perf_in_2_threads(self): +self.prepare_module('perf') +self.compile('perf-test', ['_perf_cffi'], + ['-pthread', '-O2', '-DPTEST_USE_THREAD=2']) +output = self.execute('perf-test') +print '='*79 +print output.rstrip() +print '='*79 + +def test_perf_in_4_threads(self): +self.prepare_module('perf') +self.compile('perf-test', ['_perf_cffi'], + ['-pthread', '-O2', '-DPTEST_USE_THREAD=4']) +output = self.execute('perf-test') +print '='*79 +print output.rstrip() +print '='*79 + +def test_perf_in_8_threads(self): +self.prepare_module('perf') +self.compile('perf-test', ['_perf_cffi'], + ['-pthread', '-O2', '-DPTEST_USE_THREAD=8']) +output = self.execute('perf-test') +print '='*79 +print output.rstrip() +print '='*79 ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] cffi static-callback-embedding: A test checking that thread-local values are saved, even though
Author: Armin Rigo Branch: static-callback-embedding Changeset: r2517:652f66e41c7b Date: 2016-01-02 15:55 +0100 http://bitbucket.org/cffi/cffi/changeset/652f66e41c7b/ Log:A test checking that thread-local values are saved, even though there is no underlying official Python thread diff --git a/testing/embedding/test_tlocal.py b/testing/embedding/test_tlocal.py new file mode 100644 --- /dev/null +++ b/testing/embedding/test_tlocal.py @@ -0,0 +1,10 @@ +from testing.embedding.test_basic import EmbeddingTests + + +class TestThreadLocal(EmbeddingTests): +def test_thread_local(self): +self.prepare_module('tlocal') +self.compile('tlocal-test', ['_tlocal_cffi'], ['-pthread']) +for i in range(50): +output = self.execute('tlocal-test') +assert output == "done\n" diff --git a/testing/embedding/thread1-test.c b/testing/embedding/thread1-test.c --- a/testing/embedding/thread1-test.c +++ b/testing/embedding/thread1-test.c @@ -13,7 +13,7 @@ static void *start_routine(void *arg) { -int x, y, status; +int x, status; x = add1(40, 2); assert(x == 42); diff --git a/testing/embedding/tlocal-test.c b/testing/embedding/tlocal-test.c new file mode 100644 --- /dev/null +++ b/testing/embedding/tlocal-test.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +#define NTHREADS 10 + + +extern int add1(int, int); + +static sem_t done; + + +static void *start_routine(void *arg) +{ +int i, x, expected, status; + +expected = add1(40, 2); +assert((expected % 1000) == 42); + +for (i=0; i<10; i++) { +x = add1(40, 2); +assert(x == expected); +} + +status = sem_post(&done); +assert(status == 0); + +return arg; +} + +int main(void) +{ +pthread_t th; +int i, status = sem_init(&done, 0, 0); +assert(status == 0); + +for (i = 0; i < NTHREADS; i++) { +status = pthread_create(&th, NULL, start_routine, NULL); +assert(status == 0); +} +for (i = 0; i < NTHREADS; i++) { +status = sem_wait(&done); +assert(status == 0); +} +printf("done\n"); +return 0; +} diff --git a/testing/embedding/tlocal.py b/testing/embedding/tlocal.py new file mode 100644 --- /dev/null +++ b/testing/embedding/tlocal.py @@ -0,0 +1,26 @@ +import cffi + +ffi = cffi.FFI() + +ffi.cdef(""" +extern "Python" int add1(int, int); +""", dllexport=True) + +ffi.embedding_init_code(r""" +import thread, itertools +tloc = thread._local() +g_seen = itertools.count() + +@ffi.def_extern() +def add1(x, y): +try: +num = tloc.num +except AttributeError: +num = tloc.num = g_seen.next() * 1000 +return x + y + num +""") + +ffi.set_source("_tlocal_cffi", """ +""") + +ffi.compile(verbose=True) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] extradoc extradoc: Draft blog post
Author: Armin Rigo Branch: extradoc Changeset: r5576:4e6f2b0b4afb Date: 2016-01-02 19:22 +0100 http://bitbucket.org/pypy/extradoc/changeset/4e6f2b0b4afb/ Log:Draft blog post diff --git a/blog/draft/cffi-embedding.rst b/blog/draft/cffi-embedding.rst new file mode 100644 --- /dev/null +++ b/blog/draft/cffi-embedding.rst @@ -0,0 +1,81 @@ + +Using CFFI for embedding + + +CFFI_ has been a great success so far to call C libraries in your +Python programs, in a way that is both simple and that works across +CPython 2.x and 3.x and PyPy. + +We are now adding support for *embedding* Python inside non-Python +programs. This is traditionally done using the CPython C API: from C +code, you call ``Py_Initialize()`` and then some other functions like +``PyRun_SimpleString()``. In the simple cases it is, indeed, simple +enough; but it can become a more complicated story if you throw in +supporting application-dependent object types, and correctly running +on multiple threads, and so on. + +Moreover, this approach is specific to CPython (2.x or 3.x, which you +can do in a similar way). It does not work on PyPy, which has its own +smaller `embedding API`_. + +CFFI now supports embedding directly---and there is no fixed API at +all. The idea is to write some Python script with a ``cdef()`` which +declares a number of ``extern "Python"`` functions. When running the +script, it creates the C source code and compile it to a +dynamically-linked library (``.so`` on Linux). This is the same as in +the regular API-mode usage, and ``extern "Python"`` was `introduced in +CFFI 1.4`_. What is new is that you also give a bit of +initialization-time Python code directly in the script, which will be +compiled into the ``.so`` too---and the ``extern "Python"`` are now +also "exported" from the dynamically-linked library as regular C +functions. + +In other words, this library can now be used directly from any C +program (and it is still importable in Python). It exposes the C API +of your choice, which you specified with the ``extern "Python"`` +declarations. You can use it to make whatever custom API makes sense +in your particular case. You can even make directly a "plug-in" for +any program that supports them, just by exporting the API expected for +such plugins. + +This is still being finalized, but please try it out. (You can also +see `embedding.py`_ directly online here for a quick glance.) + +* get the branch ``static-callback-embedding`` of CFFI (``hg clone https://bitbucket.org/cffi/cffi && hg up static-callback-embedding``) + +* make the ``_cffi_backend.so`` (``python setup_base.py build_ext -f -i``) + +* run ``embedding`` in the ``demo`` directory (``cd demo; PYTHONPATH=.. python embedding.py``) + +* run ``gcc`` to build the C sources (``gcc -shared -fPIC _embedding_cffi.c -o _embedding_cffi.so -lpython2.7 -I/usr/include/python2.7``) + +* try out the demo C program in ``embedding_test.c`` (``gcc embedding_test.c _embedding_cffi.so && PYTHONPATH=.. LD_LIBRARY_PATH=. a.out``). + +Note that if you get ``ImportError: cffi extension module +'_embedding_cffi' has unknown version 0x2701``, it means that the +``_cffi_backend`` module loaded is a pre-installed one instead of the +more recent one in ``..``. Be sure to use ``PYTHONPATH`` for now. + +Very similar steps can be followed on PyPy, but it requires the +``cffi-static-callback-embedding`` branch of PyPy, which you must +first translate from sources. + +You get a CPython/PyPy that is automatically initialized (using locks +in case of multi-threading) the first time any of the ``extern +"Python"`` functions is called from the C program. The custom +initialization-time Python code is run at that time too. If this code +starts to be big, you may consider moving it to several modules or +packages and importing them from the initialization-time Python code; +in that case you have to be careful about setting up the correct +``sys.path``. + +Note that right now it does not support CPython's notion of multiple +subinterpreters. The logic creates a single global Python interpreter, +and everything is run in that context. Idea about how to support that +cleanly would be welcome ``:-)`` More generally, any feedback is +appreciated. + + +Have fun, + +Armin ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] extradoc extradoc: updates
Author: Armin Rigo Branch: extradoc Changeset: r5577:478b903db2f9 Date: 2016-01-02 19:37 +0100 http://bitbucket.org/pypy/extradoc/changeset/478b903db2f9/ Log:updates diff --git a/blog/draft/cffi-embedding.rst b/blog/draft/cffi-embedding.rst --- a/blog/draft/cffi-embedding.rst +++ b/blog/draft/cffi-embedding.rst @@ -18,62 +18,80 @@ can do in a similar way). It does not work on PyPy, which has its own smaller `embedding API`_. -CFFI now supports embedding directly---and there is no fixed API at -all. The idea is to write some Python script with a ``cdef()`` which -declares a number of ``extern "Python"`` functions. When running the -script, it creates the C source code and compile it to a -dynamically-linked library (``.so`` on Linux). This is the same as in -the regular API-mode usage, and ``extern "Python"`` was `introduced in -CFFI 1.4`_. What is new is that you also give a bit of -initialization-time Python code directly in the script, which will be -compiled into the ``.so`` too---and the ``extern "Python"`` are now -also "exported" from the dynamically-linked library as regular C -functions. +The new-and-coming thing about CFFI, meant as replacement of the above +solutions, is direct embedding support---and it does that with no +fixed API at all. The idea is to write some Python script with a +``cdef()`` which declares a number of ``extern "Python"`` functions. +When running the script, it creates the C source code and compiles it +to a dynamically-linked library (``.so`` on Linux). This is the same +as in the regular API-mode usage, and ``extern "Python"`` was +`introduced in CFFI 1.4`_. What is new is that these ``extern +"Python"`` can now also be *exported* from the ``.so``, in the C +sense. You also give a bit of initialization-time Python code +directly in the script, which will be compiled into the ``.so`` +too. In other words, this library can now be used directly from any C program (and it is still importable in Python). It exposes the C API of your choice, which you specified with the ``extern "Python"`` declarations. You can use it to make whatever custom API makes sense -in your particular case. You can even make directly a "plug-in" for +in your particular case. You can even directly make a "plug-in" for any program that supports them, just by exporting the API expected for such plugins. This is still being finalized, but please try it out. (You can also -see `embedding.py`_ directly online here for a quick glance.) +see `embedding.py`_ directly online for a quick glance.) These are +the instructions on Linux with CPython 2.7:: -* get the branch ``static-callback-embedding`` of CFFI (``hg clone https://bitbucket.org/cffi/cffi && hg up static-callback-embedding``) +* get the branch ``static-callback-embedding`` of CFFI:: -* make the ``_cffi_backend.so`` (``python setup_base.py build_ext -f -i``) + hg clone https://bitbucket.org/cffi/cffi + hg up static-callback-embedding -* run ``embedding`` in the ``demo`` directory (``cd demo; PYTHONPATH=.. python embedding.py``) +* make the ``_cffi_backend.so``:: -* run ``gcc`` to build the C sources (``gcc -shared -fPIC _embedding_cffi.c -o _embedding_cffi.so -lpython2.7 -I/usr/include/python2.7``) + python setup_base.py build_ext -f -i -* try out the demo C program in ``embedding_test.c`` (``gcc embedding_test.c _embedding_cffi.so && PYTHONPATH=.. LD_LIBRARY_PATH=. a.out``). +* run ``embedding.py`` in the ``demo`` directory:: + + cd demo + PYTHONPATH=.. python embedding.py + +* run ``gcc`` to build the C sources---on Linux:: + + gcc -shared -fPIC _embedding_cffi.c -o _embedding_cffi.so -lpython2.7 -I/usr/include/python2.7 + +* try out the demo C program in ``embedding_test.c``:: + + gcc embedding_test.c _embedding_cffi.so + PYTHONPATH=.. LD_LIBRARY_PATH=. a.out Note that if you get ``ImportError: cffi extension module '_embedding_cffi' has unknown version 0x2701``, it means that the ``_cffi_backend`` module loaded is a pre-installed one instead of the -more recent one in ``..``. Be sure to use ``PYTHONPATH`` for now. +more recent one in ``..``. Be sure to use ``PYTHONPATH=..`` for now. Very similar steps can be followed on PyPy, but it requires the ``cffi-static-callback-embedding`` branch of PyPy, which you must first translate from sources. -You get a CPython/PyPy that is automatically initialized (using locks -in case of multi-threading) the first time any of the ``extern -"Python"`` functions is called from the C program. The custom -initialization-time Python code is run at that time too. If this code -starts to be big, you may consider moving it to several modules or -packages and importing them from the initialization-time Python code; -in that case you have to be careful about setting up the correct -``sys.path``. +CPython 3.x and non-Linux platforms are still a work in progress right +now, but this should be quickly fixed. -Note that r
[pypy-commit] cffi static-callback-embedding: updates
Author: Armin Rigo Branch: static-callback-embedding Changeset: r2518:59062d93c601 Date: 2016-01-02 19:37 +0100 http://bitbucket.org/cffi/cffi/changeset/59062d93c601/ Log:updates diff --git a/demo/embedding.py b/demo/embedding.py --- a/demo/embedding.py +++ b/demo/embedding.py @@ -7,9 +7,7 @@ """, dllexport=True) ffi.embedding_init_code(""" -print "preparing" - -intern("foo") +print "preparing" # printed once @ffi.def_extern() def add(x, y): @@ -20,4 +18,9 @@ ffi.set_source("_embedding_cffi", """ """) -ffi.compile() +#ffi.compile() -- should be fixed to do the right thing + +ffi.emit_c_code('_embedding_cffi.c') +# then call the compiler manually with the proper options, like: +#gcc -shared -fPIC _embedding_cffi.c -o _embedding_cffi.so -lpython2.7 +#-I/usr/include/python2.7 diff --git a/demo/embedding_test.c b/demo/embedding_test.c --- a/demo/embedding_test.c +++ b/demo/embedding_test.c @@ -1,7 +1,7 @@ /* Link this program with libembedding_test.so. E.g. with gcc: - gcc -o embedding_test embedding_test.c _embedding_cffi.so -lpython2.7 + gcc -o embedding_test embedding_test.c _embedding_cffi.so */ #include diff --git a/testing/embedding/test_tlocal.py b/testing/embedding/test_tlocal.py --- a/testing/embedding/test_tlocal.py +++ b/testing/embedding/test_tlocal.py @@ -5,6 +5,6 @@ def test_thread_local(self): self.prepare_module('tlocal') self.compile('tlocal-test', ['_tlocal_cffi'], ['-pthread']) -for i in range(50): +for i in range(10): output = self.execute('tlocal-test') assert output == "done\n" ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] extradoc extradoc: tweaks
Author: Armin Rigo Branch: extradoc Changeset: r5578:5f72fa7e28b4 Date: 2016-01-02 19:41 +0100 http://bitbucket.org/pypy/extradoc/changeset/5f72fa7e28b4/ Log:tweaks diff --git a/blog/draft/cffi-embedding.rst b/blog/draft/cffi-embedding.rst --- a/blog/draft/cffi-embedding.rst +++ b/blog/draft/cffi-embedding.rst @@ -16,7 +16,7 @@ Moreover, this approach is specific to CPython (2.x or 3.x, which you can do in a similar way). It does not work on PyPy, which has its own -smaller `embedding API`_. +smaller but very different `embedding API`_. The new-and-coming thing about CFFI, meant as replacement of the above solutions, is direct embedding support---and it does that with no @@ -39,9 +39,11 @@ any program that supports them, just by exporting the API expected for such plugins. -This is still being finalized, but please try it out. (You can also -see `embedding.py`_ directly online for a quick glance.) These are -the instructions on Linux with CPython 2.7:: +This is still being finalized, but please try it out. (You can also see +`embedding.py`_ directly online for a quick glance.) These are the +instructions on Linux with CPython 2.7 (CPython 3.x and non-Linux +platforms are still a work in progress right now, but this should be +quickly fixed): * get the branch ``static-callback-embedding`` of CFFI:: @@ -75,9 +77,6 @@ ``cffi-static-callback-embedding`` branch of PyPy, which you must first translate from sources. -CPython 3.x and non-Linux platforms are still a work in progress right -now, but this should be quickly fixed. - Note that CPython/PyPy is automatically initialized (using locks in case of multi-threading) the first time any of the ``extern "Python"`` functions is called from the C program. At that time, the custom ___ 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: r687:3a738e4c8bd7 Date: 2016-01-02 19:46 +0100 http://bitbucket.org/pypy/pypy.org/changeset/3a738e4c8bd7/ Log:update the values diff --git a/don1.html b/don1.html --- a/don1.html +++ b/don1.html @@ -9,13 +9,13 @@ $(function() { $("#progressbar").progressbar({ - value: 58.7 + value: 59.6 }); }); - $61658 of $105000 (58.7%) + $62631 of $105000 (59.6%) @@ -23,7 +23,7 @@ This donation goes towards supporting Python 3 in PyPy. Current status: -we have $6927 left +we have $7819 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 default: Fix the test. _PyLong_FromByteArray() always produces nonsense (i.e. a
Author: Armin Rigo Branch: Changeset: r81527:e205bcf52d2f Date: 2016-01-03 02:10 +0100 http://bitbucket.org/pypy/pypy/changeset/e205bcf52d2f/ Log:Fix the test. _PyLong_FromByteArray() always produces nonsense (i.e. a different result than CPython), which needs to be fixed. diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py --- a/pypy/module/cpyext/test/test_longobject.py +++ b/pypy/module/cpyext/test/test_longobject.py @@ -175,10 +175,10 @@ little_endian, is_signed); """), ]) -assert module.from_bytearray(True, False) == 0x9ABC -assert module.from_bytearray(True, True) == -0x6543 -assert module.from_bytearray(False, False) == 0xBC9A -assert module.from_bytearray(False, True) == -0x4365 +assert module.from_bytearray(True, False) == 0xBC9A +assert module.from_bytearray(True, True) == -0x4366 +assert module.from_bytearray(False, False) == 0x9ABC +assert module.from_bytearray(False, True) == -0x6544 def test_fromunicode(self): module = self.import_extension('foo', [ ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Fix _PyLong_FromByteArray() for e205bcf52d2f
Author: Armin Rigo Branch: Changeset: r81528:c626616a34fa Date: 2016-01-03 02:15 +0100 http://bitbucket.org/pypy/pypy/changeset/c626616a34fa/ Log:Fix _PyLong_FromByteArray() for e205bcf52d2f diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -5,7 +5,7 @@ from pypy.objspace.std.longobject import W_LongObject from pypy.interpreter.error import OperationError from pypy.module.cpyext.intobject import PyInt_AsUnsignedLongMask -from rpython.rlib.rbigint import rbigint +from rpython.rlib.rbigint import rbigint, NULLRBIGINT, ONERBIGINT from rpython.rlib.rarithmetic import intmask @@ -229,25 +229,21 @@ little_endian = rffi.cast(lltype.Signed, little_endian) signed = rffi.cast(lltype.Signed, signed) -result = rbigint() -negative = False +# xxx not the most efficient implementation possible, but should work +result = NULLRBIGINT +c = 0 for i in range(0, n): if little_endian: +c = intmask(bytes[n - i - 1]) +else: c = intmask(bytes[i]) -else: -c = intmask(bytes[n - i - 1]) -if i == 0 and signed and c & 0x80: -negative = True -if negative: -c = c ^ 0xFF digit = rbigint.fromint(c) result = result.lshift(8) result = result.add(digit) -if negative: -result = result.neg() +if signed and c >= 0x80: +result = result.sub(ONERBIGINT.lshift(8 * n)) return space.newlong_from_rbigint(result) - ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Minor performance improvement
Author: Armin Rigo Branch: Changeset: r81530:9dd3ef98eeae Date: 2016-01-03 02:22 +0100 http://bitbucket.org/pypy/pypy/changeset/9dd3ef98eeae/ Log:Minor performance improvement diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -238,10 +238,9 @@ c = intmask(bytes[n - i - 1]) else: c = intmask(bytes[i]) -digit = rbigint.fromint(c) result = result.lshift(8) -result = result.add(digit) +result = result.int_add(c) if signed and c >= 0x80: result = result.sub(ONERBIGINT.lshift(8 * n)) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Mention here the _PyLong_FromByteArray() fix
Author: Armin Rigo Branch: Changeset: r81529:a3691b49bded Date: 2016-01-03 02:20 +0100 http://bitbucket.org/pypy/pypy/changeset/a3691b49bded/ Log:Mention here the _PyLong_FromByteArray() fix 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 @@ -5,6 +5,8 @@ .. this is a revision shortly after release-4.0.1 .. startrev: 4b5c840d0da2 +Fixed ``_PyLong_FromByteArray()``, which was buggy. + .. branch: numpy-1.10 Fix tests to run cleanly with -A and start to fix micronumpy for upstream numpy ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: More tests, more fixes
Author: Armin Rigo Branch: Changeset: r81531:6a1567a45cc7 Date: 2016-01-03 02:26 +0100 http://bitbucket.org/pypy/pypy/changeset/6a1567a45cc7/ Log:More tests, more fixes diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -231,18 +231,20 @@ # xxx not the most efficient implementation possible, but should work result = NULLRBIGINT -c = 0 +most_significant = 0 for i in range(0, n): if little_endian: c = intmask(bytes[n - i - 1]) else: c = intmask(bytes[i]) +if i == 0: +most_significant = c result = result.lshift(8) result = result.int_add(c) -if signed and c >= 0x80: +if signed and most_significant >= 0x80: result = result.sub(ONERBIGINT.lshift(8 * n)) return space.newlong_from_rbigint(result) diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py --- a/pypy/module/cpyext/test/test_longobject.py +++ b/pypy/module/cpyext/test/test_longobject.py @@ -180,6 +180,22 @@ assert module.from_bytearray(False, False) == 0x9ABC assert module.from_bytearray(False, True) == -0x6544 +def test_frombytearray_2(self): +module = self.import_extension('foo', [ +("from_bytearray", "METH_VARARGS", + """ + int little_endian, is_signed; + if (!PyArg_ParseTuple(args, "ii", &little_endian, &is_signed)) + return NULL; + return _PyLong_FromByteArray("\x9A\xBC\x41", 3, + little_endian, is_signed); + """), +]) +assert module.from_bytearray(True, False) == 0x41BC9A +assert module.from_bytearray(True, True) == 0x41BC9A +assert module.from_bytearray(False, False) == 0x9ABC41 +assert module.from_bytearray(False, True) == -0x6543BF + def test_fromunicode(self): module = self.import_extension('foo', [ ("from_unicode", "METH_O", ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Meh! The rbigint class has already got a frombytes() method, which
Author: Armin Rigo Branch: Changeset: r81532:c8029737eae2 Date: 2016-01-03 02:35 +0100 http://bitbucket.org/pypy/pypy/changeset/c8029737eae2/ Log:Meh! The rbigint class has already got a frombytes() method, which is a better (and bug-free) version. diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -5,7 +5,7 @@ from pypy.objspace.std.longobject import W_LongObject from pypy.interpreter.error import OperationError from pypy.module.cpyext.intobject import PyInt_AsUnsignedLongMask -from rpython.rlib.rbigint import rbigint, NULLRBIGINT, ONERBIGINT +from rpython.rlib.rbigint import rbigint from rpython.rlib.rarithmetic import intmask @@ -228,23 +228,11 @@ def _PyLong_FromByteArray(space, bytes, n, little_endian, signed): little_endian = rffi.cast(lltype.Signed, little_endian) signed = rffi.cast(lltype.Signed, signed) - -# xxx not the most efficient implementation possible, but should work -result = NULLRBIGINT -most_significant = 0 - -for i in range(0, n): -if little_endian: -c = intmask(bytes[n - i - 1]) -else: -c = intmask(bytes[i]) -if i == 0: -most_significant = c - -result = result.lshift(8) -result = result.int_add(c) - -if signed and most_significant >= 0x80: -result = result.sub(ONERBIGINT.lshift(8 * n)) - +s = rffi.charpsize2str(rffi.cast(rffi.CCHARP, bytes), + rffi.cast(lltype.Signed, n)) +if little_endian: +byteorder = 'little' +else: +byteorder = 'big' +result = rbigint.frombytes(s, byteorder, signed != 0) return space.newlong_from_rbigint(result) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit