Author: David Schneider <david.schnei...@picle.org> Branch: Changeset: r63518:6885a43961e2 Date: 2013-04-20 01:34 +0200 http://bitbucket.org/pypy/pypy/changeset/6885a43961e2/
Log: merge heads diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -527,6 +527,7 @@ s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) +s_Unicode0 = SomeUnicodeString(no_nul=True) # ____________________________________________________________ diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -58,7 +58,7 @@ if we_are_translated(): self.debug = False self.current_clt = looptoken.compiled_loop_token - self.mc = InstrBuilder(self.cpu.arch_version) + self.mc = InstrBuilder(self.cpu.cpuinfo.arch_version) self.pending_guards = [] assert self.datablockwrapper is None allblocks = self.get_asmmemmgr_blocks(looptoken) @@ -82,7 +82,7 @@ if not self.cpu.propagate_exception_descr: return # not supported (for tests, or non-translated) # - mc = InstrBuilder(self.cpu.arch_version) + mc = InstrBuilder(self.cpu.cpuinfo.arch_version) self._store_and_reset_exception(mc, r.r0) ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') # make sure ofs fits into a register @@ -167,7 +167,7 @@ # | my own retaddr | <-- sp # +-----------------------+ # - mc = InstrBuilder(self.cpu.arch_version) + mc = InstrBuilder(self.cpu.cpuinfo.arch_version) # save argument registers and return address mc.PUSH([reg.value for reg in r.argument_regs] + [r.ip.value, r.lr.value]) # stack is aligned here @@ -208,7 +208,7 @@ # write barriers. It must save all registers, and optionally # all vfp registers. It takes a single argument which is in r0. # It must keep stack alignment accordingly. - mc = InstrBuilder(self.cpu.arch_version) + mc = InstrBuilder(self.cpu.cpuinfo.arch_version) # exc0 = exc1 = None mc.PUSH([r.ip.value, r.lr.value]) # push two words to keep alignment @@ -265,7 +265,7 @@ This function must preserve all registers apart from r0 and r1. """ assert kind in ['fixed', 'str', 'unicode', 'var'] - mc = InstrBuilder(self.cpu.arch_version) + mc = InstrBuilder(self.cpu.cpuinfo.arch_version) # self._push_all_regs_to_jitframe(mc, [r.r0, r.r1], self.cpu.supports_floats) # @@ -399,7 +399,7 @@ self.load_reg(mc, vfpr, r.fp, ofs) def _build_failure_recovery(self, exc, withfloats=False): - mc = InstrBuilder(self.cpu.arch_version) + mc = InstrBuilder(self.cpu.cpuinfo.arch_version) self._push_all_regs_to_jitframe(mc, [], withfloats) if exc: @@ -682,7 +682,7 @@ expected_size=expected_size) def _patch_frame_depth(self, adr, allocated_depth): - mc = InstrBuilder(self.cpu.arch_version) + mc = InstrBuilder(self.cpu.cpuinfo.arch_version) mc.gen_load_int(r.lr.value, allocated_depth) mc.copy_to_raw_memory(adr) @@ -758,7 +758,7 @@ # f) store the address of the new jitframe in the shadowstack # c) set the gcmap field to 0 in the new jitframe # g) restore registers and return - mc = InstrBuilder(self.cpu.arch_version) + mc = InstrBuilder(self.cpu.cpuinfo.arch_version) self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats) # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame # and the expected_size pushed in _check_stack_frame @@ -818,7 +818,7 @@ self.target_tokens_currently_compiling = None def _patch_stackadjust(self, adr, allocated_depth): - mc = InstrBuilder(self.cpu.arch_version) + mc = InstrBuilder(self.cpu.cpuinfo.arch_version) mc.gen_load_int(r.lr.value, allocated_depth) mc.copy_to_raw_memory(adr) @@ -858,7 +858,7 @@ # patch the guard jumpt to the stub # overwrite the generate NOP with a B_offs to the pos of the # stub - mc = InstrBuilder(self.cpu.arch_version) + mc = InstrBuilder(self.cpu.cpuinfo.arch_version) mc.B_offs(relative_offset, c.get_opposite_of(tok.fcond)) mc.copy_to_raw_memory(guard_pos) else: @@ -937,7 +937,7 @@ self.mc.ASR_ri(resloc.value, resloc.value, 16) def patch_trace(self, faildescr, looptoken, bridge_addr, regalloc): - b = InstrBuilder(self.cpu.arch_version) + b = InstrBuilder(self.cpu.cpuinfo.arch_version) patch_addr = faildescr._arm_failure_recovery_block assert patch_addr != 0 b.B(bridge_addr) @@ -1397,7 +1397,7 @@ self.mc.LSL_ri(targetreg.value, sourcereg.value, get_scale(itemsize)) else: - mc.gen_load_int(targetreg.value, itemsize.value) + mc.gen_load_int(targetreg.value, itemsize) mc.MUL(targetreg.value, sourcereg.value, targetreg.value) # return shiftsize diff --git a/rpython/jit/backend/arm/detect.py b/rpython/jit/backend/arm/detect.py --- a/rpython/jit/backend/arm/detect.py +++ b/rpython/jit/backend/arm/detect.py @@ -1,8 +1,8 @@ import os from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.rtyper.tool import rffi_platform from rpython.rlib.clibffi import FFI_DEFAULT_ABI, FFI_SYSV, FFI_VFP -from rpython.rtyper.tool import rffi_platform from rpython.translator.platform import CompilationError from rpython.rlib.debug import debug_print, debug_start, debug_stop @@ -46,9 +46,11 @@ # "Processor : ARMv%d-compatible processor rev 7 (v6l)" i = buf.find('ARMv') if i == -1: - raise ValueError("Unknown Processor entry") - - n = int(buf[i + 4]) + n = 6 + debug_print("Could not detect architecture version, " + "falling back to", "ARMv%d" % n) + else: + n = int(buf[i + 4]) if n < 6: raise ValueError("Unsupported ARM architecture version") diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -354,7 +354,7 @@ # whether to worry about a CALL that can collect; this # is always true except in call_release_gil can_collect=True): - if self.cpu.hf_abi: + if self.cpu.cpuinfo.hf_abi: stack_args, adr = self._setup_call_hf(adr, arglocs, fcond, resloc, result_info) else: @@ -382,7 +382,7 @@ # ensure the result is wellformed and stored in the correct location if resloc is not None: - if resloc.is_vfp_reg() and not self.cpu.hf_abi: + if resloc.is_vfp_reg() and not self.cpu.cpuinfo.hf_abi: # move result to the allocated register self.mov_to_vfp_loc(r.r0, r.r1, resloc) elif resloc.is_reg() and result_info != (-1, -1): @@ -1230,7 +1230,7 @@ baseofs = self.cpu.get_baseofs_of_frame_field() newlooptoken.compiled_loop_token.update_frame_info( oldlooptoken.compiled_loop_token, baseofs) - mc = InstrBuilder(self.cpu.arch_version) + mc = InstrBuilder(self.cpu.cpuinfo.arch_version) mc.B(target) mc.copy_to_raw_memory(oldadr) diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -11,6 +11,10 @@ jitframe.STATICSIZE = JITFRAME_FIXED_SIZE +class CPUInfo(object): + hf_abi = False + arch_version = 6 + class AbstractARMCPU(AbstractLLCPU): IS_64_BIT = False @@ -27,13 +31,11 @@ float_regs = VFPRegisterManager.all_regs frame_reg = fp - hf_abi = False # use hard float abi flag - arch_version = 6 # assume ARMv6 as base case - def __init__(self, rtyper, stats, opts=None, translate_support_code=False, gcdescr=None): AbstractLLCPU.__init__(self, rtyper, stats, opts, translate_support_code, gcdescr) + self.cpuinfo = CPUInfo() def set_debug(self, flag): return self.assembler.set_debug(flag) @@ -48,8 +50,8 @@ self.assembler = AssemblerARM(self, self.translate_support_code) def setup_once(self): - self.arch_version = detect_arch_version() - self.hf_abi = detect_hardfloat() + self.cpuinfo.arch_version = detect_arch_version() + self.cpuinfo.hf_abi = detect_hardfloat() self.assembler.setup_once() def finish_once(self): @@ -93,7 +95,7 @@ from rpython.jit.backend.arm.codebuilder import InstrBuilder for jmp, tgt in looptoken.compiled_loop_token.invalidate_positions: - mc = InstrBuilder(self.arch_version) + mc = InstrBuilder(self.cpuinfo.arch_version) mc.B_offs(tgt) mc.copy_to_raw_memory(jmp) # positions invalidated diff --git a/rpython/jit/backend/arm/test/test_detect.py b/rpython/jit/backend/arm/test/test_detect.py --- a/rpython/jit/backend/arm/test/test_detect.py +++ b/rpython/jit/backend/arm/test/test_detect.py @@ -3,7 +3,32 @@ from rpython.jit.backend.arm.detect import detect_arch_version cpuinfo = "Processor : ARMv%d-compatible processor rev 7 (v6l)""" - +cpuinfo2 = """processor : 0 +vendor_id : GenuineIntel +cpu family : 6 +model : 23 +model name : Intel(R) Core(TM)2 Duo CPU E8400 @ 3.00GHz +stepping : 10 +microcode : 0xa07 +cpu MHz : 2997.000 +cache size : 6144 KB +physical id : 0 +siblings : 2 +core id : 0 +cpu cores : 2 +apicid : 0 +initial apicid : 0 +fpu : yes +fpu_exception : yes +cpuid level : 13 +wp : yes +flags : fpu vme ... +bogomips : 5993.08 +clflush size : 64 +cache_alignment : 64 +address sizes : 36 bits physical, 48 bits virtual +power management: +""" def write_cpuinfo(info): filepath = udir.join('get_arch_version') @@ -20,5 +45,4 @@ assert detect_arch_version(write_cpuinfo(cpuinfo % 8)) == 7 py.test.raises(ValueError, 'detect_arch_version(write_cpuinfo(cpuinfo % 5))') - py.test.raises(ValueError, - 'detect_arch_version(write_cpuinfo("Lorem ipsum dolor sit amet, consectetur"))') + assert detect_arch_version(write_cpuinfo(cpuinfo2)) == 6 diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -10,6 +10,7 @@ from rpython.rtyper.annlowlevel import llhelper from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.history import JitCellToken, TargetToken +from rpython.jit.backend.arm.detect import detect_arch_version CPU = getcpuclass() @@ -27,7 +28,8 @@ bridge_loop_instructions = ['ldr', 'mov', 'nop', 'cmp', 'bge', 'push', 'mov', 'mov', 'push', 'mov', 'mov', 'blx', 'mov', 'mov', 'bx'] - if CPU.arch_version == 7: + arch_version = detect_arch_version() + if arch_version == 7: bridge_loop_instructions = ['ldr', 'mov', 'nop', 'cmp', 'bge', 'push', 'mov', 'mov', 'push', 'mov', 'mov', 'blx', 'mov', 'mov', 'bx'] diff --git a/rpython/memory/gc/env.py b/rpython/memory/gc/env.py --- a/rpython/memory/gc/env.py +++ b/rpython/memory/gc/env.py @@ -279,7 +279,7 @@ def best_nursery_size_for_L2cache(L2cache): # Heuristically, the best nursery size to choose is about half # of the L2 cache. - if L2cache > 1024 * 1024: # we don't want to have nursery estimated + if L2cache > 2 * 1024 * 1024: # we don't want to have nursery estimated # on L2 when L3 is present return L2cache // 2 else: diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -351,8 +351,6 @@ # hacking at the current nursery position in collect_and_reserve(). if newsize <= 0: newsize = env.estimate_best_nursery_size() - # 4*1024*1024 # fixed to 4MB by default - # (it was env.estimate_best_nursery_size()) if newsize <= 0: newsize = defaultsize if newsize < minsize: diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py --- a/rpython/rlib/rwin32.py +++ b/rpython/rlib/rwin32.py @@ -5,6 +5,7 @@ import os import errno +from rpython.rtyper.module.ll_os_environ import make_env_impls from rpython.rtyper.tool import rffi_platform from rpython.tool.udir import udir from rpython.translator.tool.cbuild import ExternalCompilationInfo @@ -390,3 +391,5 @@ raise lastWindowsError('os_kill failed to terminate process') finally: CloseHandle(handle) + + _wenviron_items, _wgetenv, _wputenv = make_env_impls(win32=True) diff --git a/rpython/rlib/test/test_rwin32.py b/rpython/rlib/test/test_rwin32.py --- a/rpython/rlib/test/test_rwin32.py +++ b/rpython/rlib/test/test_rwin32.py @@ -1,3 +1,4 @@ +# encoding: utf-8 import os, py if os.name != 'nt': py.test.skip('tests for win32 only') @@ -47,3 +48,13 @@ rwin32.CloseHandle(handle) assert proc.wait() == signal.SIGTERM +@py.test.mark.dont_track_allocations('putenv intentionally keeps strings alive') +def test_wenviron(): + name, value = u'PYPY_TEST_日本', u'foobar日本' + rwin32._wputenv(name, value) + assert rwin32._wgetenv(name) == value + env = dict(rwin32._wenviron_items()) + assert env[name] == value + for key, value in env.iteritems(): + assert type(key) is unicode + assert type(value) is unicode diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py --- a/rpython/rtyper/module/ll_os.py +++ b/rpython/rtyper/module/ll_os.py @@ -7,14 +7,15 @@ import os, sys, errno import py -from rpython.rtyper.module.support import OOSupport +from rpython.rtyper.module.support import ( + _WIN32, OOSupport, StringTraits, UnicodeTraits, underscore_on_windows) from rpython.tool.sourcetools import func_renamer from rpython.rlib.rarithmetic import r_longlong from rpython.rtyper.extfunc import ( BaseLazyRegistering, register_external) from rpython.rtyper.extfunc import registering, registering_if, extdef from rpython.annotator.model import ( - SomeInteger, SomeString, SomeTuple, SomeFloat, SomeUnicodeString) + SomeInteger, SomeString, SomeTuple, SomeFloat, s_Str0, s_Unicode0) from rpython.annotator.model import s_ImpossibleValue, s_None, s_Bool from rpython.rtyper.lltypesystem import rffi from rpython.rtyper.lltypesystem import lltype @@ -25,8 +26,8 @@ from rpython.rtyper.lltypesystem.rstr import STR from rpython.rlib.objectmodel import specialize -str0 = SomeString(no_nul=True) -unicode0 = SomeUnicodeString(no_nul=True) +str0 = s_Str0 +unicode0 = s_Unicode0 def monkeypatch_rposix(posixfunc, unicodefunc, signature): func_name = posixfunc.__name__ @@ -66,42 +67,6 @@ # Monkeypatch the function in rpython.rlib.rposix setattr(rposix, func_name, new_func) -class StringTraits: - str = str - str0 = str0 - CHAR = rffi.CHAR - CCHARP = rffi.CCHARP - charp2str = staticmethod(rffi.charp2str) - str2charp = staticmethod(rffi.str2charp) - free_charp = staticmethod(rffi.free_charp) - scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_buffer) - - @staticmethod - def posix_function_name(name): - return underscore_on_windows + name - - @staticmethod - def ll_os_name(name): - return 'll_os.ll_os_' + name - -class UnicodeTraits: - str = unicode - str0 = unicode0 - CHAR = rffi.WCHAR_T - CCHARP = rffi.CWCHARP - charp2str = staticmethod(rffi.wcharp2unicode) - str2charp = staticmethod(rffi.unicode2wcharp) - free_charp = staticmethod(rffi.free_wcharp) - scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_unicodebuffer) - - @staticmethod - def posix_function_name(name): - return underscore_on_windows + 'w' + name - - @staticmethod - def ll_os_name(name): - return 'll_os.ll_os_w' + name - def registering_str_unicode(posixfunc, condition=True): if not condition or posixfunc is None: return registering(None, condition=False) @@ -129,16 +94,6 @@ posix = __import__(os.name) -if sys.platform.startswith('win'): - _WIN32 = True -else: - _WIN32 = False - -if _WIN32: - underscore_on_windows = '_' -else: - underscore_on_windows = '' - includes = [] if not _WIN32: # XXX many of these includes are not portable at all diff --git a/rpython/rtyper/module/ll_os_environ.py b/rpython/rtyper/module/ll_os_environ.py --- a/rpython/rtyper/module/ll_os_environ.py +++ b/rpython/rtyper/module/ll_os_environ.py @@ -4,10 +4,10 @@ from rpython.rtyper.controllerentry import Controller from rpython.rtyper.extfunc import register_external from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.rtyper.module import ll_os -from rpython.rlib import rposix +from rpython.rtyper.module.support import _WIN32, StringTraits, UnicodeTraits +from rpython.translator.tool.cbuild import ExternalCompilationInfo -str0 = ll_os.str0 +str0 = annmodel.s_Str0 # ____________________________________________________________ # @@ -59,85 +59,8 @@ return r_getenv # ____________________________________________________________ -# -# Lower-level interface: dummy placeholders and external registations - -def r_getenv(name): - just_a_placeholder # should return None if name not found - -os_getenv = rffi.llexternal('getenv', [rffi.CCHARP], rffi.CCHARP, - threadsafe=False) - -def getenv_llimpl(name): - with rffi.scoped_str2charp(name) as l_name: - l_result = os_getenv(l_name) - return rffi.charp2str(l_result) if l_result else None - -register_external(r_getenv, [str0], - annmodel.SomeString(can_be_None=True, no_nul=True), - export_name='ll_os.ll_os_getenv', - llimpl=getenv_llimpl) - -# ____________________________________________________________ - -def r_putenv(name, value): - just_a_placeholder - -class EnvKeepalive: - pass -envkeepalive = EnvKeepalive() -envkeepalive.byname = {} - -os_putenv = rffi.llexternal('putenv', [rffi.CCHARP], rffi.INT) - -def putenv_llimpl(name, value): - l_string = rffi.str2charp('%s=%s' % (name, value)) - error = rffi.cast(lltype.Signed, os_putenv(l_string)) - if error: - rffi.free_charp(l_string) - raise OSError(rposix.get_errno(), "os_putenv failed") - # keep 'l_string' alive - we know that the C library needs it - # until the next call to putenv() with the same 'name'. - l_oldstring = envkeepalive.byname.get(name, lltype.nullptr(rffi.CCHARP.TO)) - envkeepalive.byname[name] = l_string - if l_oldstring: - rffi.free_charp(l_oldstring) - -register_external(r_putenv, [str0, str0], annmodel.s_None, - export_name='ll_os.ll_os_putenv', - llimpl=putenv_llimpl) - -# ____________________________________________________________ - -def r_unsetenv(name): - # default implementation for platforms without a real unsetenv() - r_putenv(name, '') - -if hasattr(__import__(os.name), 'unsetenv'): - os_unsetenv = rffi.llexternal('unsetenv', [rffi.CCHARP], rffi.INT) - - def unsetenv_llimpl(name): - with rffi.scoped_str2charp(name) as l_name: - error = rffi.cast(lltype.Signed, os_unsetenv(l_name)) - if error: - raise OSError(rposix.get_errno(), "os_unsetenv failed") - try: - l_oldstring = envkeepalive.byname[name] - except KeyError: - pass - else: - del envkeepalive.byname[name] - rffi.free_charp(l_oldstring) - - register_external(r_unsetenv, [str0], annmodel.s_None, - export_name='ll_os.ll_os_unsetenv', - llimpl=unsetenv_llimpl) - -# ____________________________________________________________ # Access to the 'environ' external variable -from rpython.translator.tool.cbuild import ExternalCompilationInfo - if sys.platform.startswith('darwin'): CCHARPPP = rffi.CArrayPtr(rffi.CCHARPP) _os_NSGetEnviron = rffi.llexternal( @@ -146,16 +69,21 @@ ) def os_get_environ(): return _os_NSGetEnviron()[0] -elif sys.platform.startswith('win'): +elif _WIN32: + eci = ExternalCompilationInfo(includes=['stdlib.h']) + CWCHARPP = lltype.Ptr(lltype.Array(rffi.CWCHARP, hints={'nolength': True})) + os_get_environ, _os_set_environ = rffi.CExternVariable( - rffi.CCHARPP, - '_environ', - ExternalCompilationInfo(includes=['stdlib.h'])) + rffi.CCHARPP, '_environ', eci) + get__wenviron, _set__wenviron = rffi.CExternVariable( + CWCHARPP, '_wenviron', eci, c_type='wchar_t **') else: os_get_environ, _os_set_environ = rffi.CExternVariable( rffi.CCHARPP, 'environ', ExternalCompilationInfo()) # ____________________________________________________________ +# +# Lower-level interface: dummy placeholders and external registations def r_envkeys(): just_a_placeholder @@ -181,18 +109,109 @@ def r_envitems(): just_a_placeholder -def envitems_llimpl(): - environ = os_get_environ() - result = [] - i = 0 - while environ[i]: - name_value = rffi.charp2str(environ[i]) - p = name_value.find('=') - if p >= 0: - result.append((name_value[:p], name_value[p+1:])) - i += 1 - return result +def r_getenv(name): + just_a_placeholder # should return None if name not found + +def r_putenv(name, value): + just_a_placeholder + +os_getenv = rffi.llexternal('getenv', [rffi.CCHARP], rffi.CCHARP, + threadsafe=False) +os_putenv = rffi.llexternal('putenv', [rffi.CCHARP], rffi.INT) +if _WIN32: + _wgetenv = rffi.llexternal('_wgetenv', [rffi.CWCHARP], rffi.CWCHARP, + compilation_info=eci, threadsafe=False) + _wputenv = rffi.llexternal('_wputenv', [rffi.CWCHARP], rffi.INT, + compilation_info=eci) + +class EnvKeepalive: + pass +envkeepalive = EnvKeepalive() +envkeepalive.byname = {} +envkeepalive.bywname = {} + +def make_env_impls(win32=False): + if not win32: + traits = StringTraits() + get_environ, getenv, putenv = os_get_environ, os_getenv, os_putenv + byname, eq = envkeepalive.byname, '=' + def last_error(msg): + from rpython.rlib import rposix + raise OSError(rposix.get_errno(), msg) + else: + traits = UnicodeTraits() + get_environ, getenv, putenv = get__wenviron, _wgetenv, _wputenv + byname, eq = envkeepalive.bywname, u'=' + from rpython.rlib.rwin32 import lastWindowsError as last_error + + def envitems_llimpl(): + environ = get_environ() + result = [] + i = 0 + while environ[i]: + name_value = traits.charp2str(environ[i]) + p = name_value.find(eq) + if p >= 0: + result.append((name_value[:p], name_value[p+1:])) + i += 1 + return result + + def getenv_llimpl(name): + with traits.scoped_str2charp(name) as l_name: + l_result = getenv(l_name) + return traits.charp2str(l_result) if l_result else None + + def putenv_llimpl(name, value): + l_string = traits.str2charp(name + eq + value) + error = rffi.cast(lltype.Signed, putenv(l_string)) + if error: + traits.free_charp(l_string) + last_error("putenv failed") + # keep 'l_string' alive - we know that the C library needs it + # until the next call to putenv() with the same 'name'. + l_oldstring = byname.get(name, lltype.nullptr(traits.CCHARP.TO)) + byname[name] = l_string + if l_oldstring: + traits.free_charp(l_oldstring) + + return envitems_llimpl, getenv_llimpl, putenv_llimpl + +envitems_llimpl, getenv_llimpl, putenv_llimpl = make_env_impls() register_external(r_envitems, [], [(str0, str0)], export_name='ll_os.ll_os_envitems', llimpl=envitems_llimpl) +register_external(r_getenv, [str0], + annmodel.SomeString(can_be_None=True, no_nul=True), + export_name='ll_os.ll_os_getenv', + llimpl=getenv_llimpl) +register_external(r_putenv, [str0, str0], annmodel.s_None, + export_name='ll_os.ll_os_putenv', + llimpl=putenv_llimpl) + +# ____________________________________________________________ + +def r_unsetenv(name): + # default implementation for platforms without a real unsetenv() + r_putenv(name, '') + +if hasattr(__import__(os.name), 'unsetenv'): + os_unsetenv = rffi.llexternal('unsetenv', [rffi.CCHARP], rffi.INT) + + def unsetenv_llimpl(name): + with rffi.scoped_str2charp(name) as l_name: + error = rffi.cast(lltype.Signed, os_unsetenv(l_name)) + if error: + from rpython.rlib import rposix + raise OSError(rposix.get_errno(), "os_unsetenv failed") + try: + l_oldstring = envkeepalive.byname[name] + except KeyError: + pass + else: + del envkeepalive.byname[name] + rffi.free_charp(l_oldstring) + + register_external(r_unsetenv, [str0], annmodel.s_None, + export_name='ll_os.ll_os_unsetenv', + llimpl=unsetenv_llimpl) diff --git a/rpython/rtyper/module/support.py b/rpython/rtyper/module/support.py --- a/rpython/rtyper/module/support.py +++ b/rpython/rtyper/module/support.py @@ -1,6 +1,12 @@ -from rpython.rtyper.lltypesystem import lltype +import os +import sys + +from rpython.annotator import model as annmodel +from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rtyper.ootypesystem import ootype -import os + +_WIN32 = sys.platform.startswith('win') +underscore_on_windows = '_' if _WIN32 else '' # utility conversion functions class LLSupport: @@ -64,6 +70,45 @@ from_rstr_nonnull = staticmethod(from_rstr_nonnull) +class StringTraits: + str = str + str0 = annmodel.s_Str0 + CHAR = rffi.CHAR + CCHARP = rffi.CCHARP + charp2str = staticmethod(rffi.charp2str) + scoped_str2charp = staticmethod(rffi.scoped_str2charp) + str2charp = staticmethod(rffi.str2charp) + free_charp = staticmethod(rffi.free_charp) + scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_buffer) + + @staticmethod + def posix_function_name(name): + return underscore_on_windows + name + + @staticmethod + def ll_os_name(name): + return 'll_os.ll_os_' + name + +class UnicodeTraits: + str = unicode + str0 = annmodel.s_Unicode0 + CHAR = rffi.WCHAR_T + CCHARP = rffi.CWCHARP + charp2str = staticmethod(rffi.wcharp2unicode) + str2charp = staticmethod(rffi.unicode2wcharp) + scoped_str2charp = staticmethod(rffi.scoped_unicode2wcharp) + free_charp = staticmethod(rffi.free_wcharp) + scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_unicodebuffer) + + @staticmethod + def posix_function_name(name): + return underscore_on_windows + 'w' + name + + @staticmethod + def ll_os_name(name): + return 'll_os.ll_os_w' + name + + def ll_strcpy(dst_s, src_s, n): dstchars = dst_s.chars srcchars = src_s.chars @@ -78,5 +123,3 @@ while i < n: dstchars[i] = srcchars[i] i += 1 - - _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit