Author: David Schneider <[email protected]>
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
[email protected]_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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit