Author: Philip Jenvey <pjen...@underboss.org> Branch: py3.3 Changeset: r73636:ac2759ae7eb6 Date: 2014-09-18 21:14 -0700 http://bitbucket.org/pypy/pypy/changeset/ac2759ae7eb6/
Log: merge py3k diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst --- a/pypy/doc/windows.rst +++ b/pypy/doc/windows.rst @@ -85,10 +85,13 @@ Abridged method (for -Ojit builds using Visual Studio 2008) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Download the versions of all the external packages -from +Download the versions of all the external packages from +https://bitbucket.org/pypy/pypy/downloads/local_2.4.zip +(for 2.4 release and later) or https://bitbucket.org/pypy/pypy/downloads/local.zip -Then expand it into the base directory (base_dir) and modify your environment to reflect this:: +(for pre-2.4 versions) +Then expand it into the base directory (base_dir) and modify your environment +to reflect this:: set PATH=<base_dir>\bin;<base_dir>\tcltk\bin;%PATH% set INCLUDE=<base_dir>\include;<base_dir>\tcltk\include;%INCLUDE% diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -46,6 +46,7 @@ def cpython_code_signature(code): "([list-of-arg-names], vararg-name-or-None, kwarg-name-or-None)." argcount = code.co_argcount + varnames = code.co_varnames if we_are_translated(): kwonlyargcount = code.co_kwonlyargcount else: @@ -53,16 +54,18 @@ kwonlyargcount = getattr(code, 'co_kwonlyargcount', 0) assert argcount >= 0 # annotator hint assert kwonlyargcount >= 0 - argnames = list(code.co_varnames[:argcount]) - kwonlyargs = list(code.co_varnames[argcount:argcount + kwonlyargcount]) + argnames = list(varnames[:argcount]) + if argcount < len(varnames): + kwonlyargs = list(varnames[argcount:argcount + kwonlyargcount]) + else: + kwonlyargs = None if code.co_flags & CO_VARARGS: - varargname = code.co_varnames[argcount] + varargname = varnames[argcount] argcount += 1 else: varargname = None if code.co_flags & CO_VARKEYWORDS: kwargname = code.co_varnames[argcount + kwonlyargcount] - argcount += 1 else: kwargname = None return Signature(argnames, varargname, kwargname, kwonlyargs) diff --git a/pypy/interpreter/pyparser/parsestring.py b/pypy/interpreter/pyparser/parsestring.py --- a/pypy/interpreter/pyparser/parsestring.py +++ b/pypy/interpreter/pyparser/parsestring.py @@ -82,12 +82,6 @@ v = PyString_DecodeEscape(space, substr, 'strict', encoding) return space.wrapbytes(v) -def hexbyte(val): - result = "%x" % val - if len(result) == 1: - result = "0" + result - return result - def decode_unicode_utf8(space, s, ps, q): # ****The Python 2.7 version, producing UTF-32 escapes**** # String is utf8-encoded, but 'unicode_escape' expects @@ -107,15 +101,14 @@ # instead. lis.append("u005c") if ord(s[ps]) & 0x80: # XXX inefficient - w, ps = decode_utf8(space, s, ps, end, "utf-32-be") - rn = len(w) - assert rn % 4 == 0 - for i in range(0, rn, 4): - lis.append('\\U') - lis.append(hexbyte(ord(w[i]))) - lis.append(hexbyte(ord(w[i+1]))) - lis.append(hexbyte(ord(w[i+2]))) - lis.append(hexbyte(ord(w[i+3]))) + w, ps = decode_utf8(space, s, ps, end) + for c in w: + # The equivalent of %08x, which is not supported by RPython. + # 7 zeroes are enough for the unicode range, and the + # result still fits in 32-bit. + hexa = hex(ord(c) + 0x10000000) + lis.append('\\U0') + lis.append(hexa[3:]) # Skip 0x and the leading 1 else: lis.append(s[ps]) ps += 1 @@ -135,7 +128,7 @@ # note that the C code has a label here. # the logic is the same. if recode_encoding and ord(s[ps]) & 0x80: - w, ps = decode_utf8(space, s, ps, end, recode_encoding) + w, ps = decode_utf8_recode(space, s, ps, end, recode_encoding) # Append bytes to output buffer. builder.append(w) else: @@ -222,14 +215,18 @@ ch >= 'A' and ch <= 'F') -def decode_utf8(space, s, ps, end, encoding): +def decode_utf8(space, s, ps, end): assert ps >= 0 pt = ps # while (s < end && *s != '\\') s++; */ /* inefficient for u".." while ps < end and ord(s[ps]) & 0x80: ps += 1 - w_u = space.wrap(unicodehelper.decode_utf8(space, s[pt:ps])) - w_v = unicodehelper.encode(space, w_u, encoding) + u = unicodehelper.decode_utf8(space, s[pt:ps]) + return u, ps + +def decode_utf8_recode(space, s, ps, end, recode_encoding): + u, ps = decode_utf8(space, s, ps, end) + w_v = unicodehelper.encode(space, space.wrap(u), recode_encoding) v = space.bytes_w(w_v) return v, ps diff --git a/pypy/interpreter/pyparser/test/test_parsestring.py b/pypy/interpreter/pyparser/test/test_parsestring.py --- a/pypy/interpreter/pyparser/test/test_parsestring.py +++ b/pypy/interpreter/pyparser/test/test_parsestring.py @@ -100,11 +100,11 @@ def test_simple_enc_roundtrip(self): space = self.space - s = "'\x81'" + s = "'\x81\\t'" s = s.decode("koi8-u").encode("utf8") w_ret = parsestring.parsestr(self.space, 'koi8-u', s) ret = space.unwrap(w_ret) - assert ret == eval("# -*- coding: koi8-u -*-\nu'\x81'") + assert ret == eval("# -*- coding: koi8-u -*-\nu'\x81\\t'") def test_multiline_unicode_strings_with_backslash(self): space = self.space diff --git a/pypy/interpreter/test/test_app_main.py b/pypy/interpreter/test/test_app_main.py --- a/pypy/interpreter/test/test_app_main.py +++ b/pypy/interpreter/test/test_app_main.py @@ -1064,7 +1064,7 @@ prefix = udir.join('pathtest').ensure(dir=1) fake_exe = 'bin/pypy-c' if sys.platform == 'win32': - fake_exe += '.exe' + fake_exe = 'pypy-c.exe' fake_exe = prefix.join(fake_exe).ensure(file=1) expected_path = [str(prefix.join(subdir).ensure(dir=1)) for subdir in ('lib_pypy', @@ -1104,8 +1104,10 @@ assert sys.path == old_sys_path + [self.goal_dir] app_main.setup_bootstrap_path(self.fake_exe) - assert sys.executable == '' # not executable! - assert sys.path == old_sys_path + [self.goal_dir] + if not sys.platform == 'win32': + # an existing file is always 'executable' on windows + assert sys.executable == '' # not executable! + assert sys.path == old_sys_path + [self.goal_dir] os.chmod(self.fake_exe, 0o755) app_main.setup_bootstrap_path(self.fake_exe) diff --git a/pypy/interpreter/test/test_code.py b/pypy/interpreter/test/test_code.py --- a/pypy/interpreter/test/test_code.py +++ b/pypy/interpreter/test/test_code.py @@ -194,3 +194,9 @@ # CO_NESTED assert d['f'](4).__code__.co_flags & 0x10 assert d['f'].__code__.co_flags & 0x10 == 0 + + def test_issue1844(self): + import types + args = (1, 0, 1, 0, 0, b'', (), (), (), '', 'operator', 0, b'') + # previously raised a MemoryError when translated + types.CodeType(*args) diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -13,6 +13,7 @@ @specialize.memo() def decode_error_handler(space): + # Fast version of the "strict" errors handler. def raise_unicode_exception_decode(errors, encoding, msg, s, startingpos, endingpos): raise OperationError(space.w_UnicodeDecodeError, @@ -25,6 +26,7 @@ @specialize.memo() def encode_error_handler(space): + # Fast version of the "strict" errors handler. def raise_unicode_exception_encode(errors, encoding, msg, u, startingpos, endingpos): raise OperationError(space.w_UnicodeEncodeError, diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -8,6 +8,7 @@ from rpython.rlib.jit_libffi import (CIF_DESCRIPTION, CIF_DESCRIPTION_P, FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP, SIZE_OF_FFI_ARG) from rpython.rlib.objectmodel import we_are_translated, instantiate +from rpython.rlib.objectmodel import keepalive_until_here from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from pypy.interpreter.error import OperationError, oefmt @@ -160,6 +161,7 @@ raw_cdata = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_cdata, flavor='raw') lltype.free(buffer, flavor='raw') + keepalive_until_here(args_w) return w_res def get_mustfree_flag(data): diff --git a/pypy/module/operator/app_operator.py b/pypy/module/operator/app_operator.py --- a/pypy/module/operator/app_operator.py +++ b/pypy/module/operator/app_operator.py @@ -4,7 +4,8 @@ This module exports a set of operators as functions. E.g. operator.add(x,y) is equivalent to x+y. ''' -from __pypy__ import builtinify + +import types def countOf(a,b): @@ -15,51 +16,78 @@ count += 1 return count +def _resolve_attr_chain(chain, obj, idx=0): + obj = getattr(obj, chain[idx]) + if idx + 1 == len(chain): + return obj + else: + return _resolve_attr_chain(chain, obj, idx + 1) + + +class _simple_attrgetter(object): + def __init__(self, attr): + self._attr = attr + + def __call__(self, obj): + return getattr(obj, self._attr) + + +class _single_attrgetter(object): + def __init__(self, attrs): + self._attrs = attrs + + def __call__(self, obj): + return _resolve_attr_chain(self._attrs, obj) + + +class _multi_attrgetter(object): + def __init__(self, attrs): + self._attrs = attrs + + def __call__(self, obj): + return tuple([ + _resolve_attr_chain(attrs, obj) + for attrs in self._attrs + ]) + + def attrgetter(attr, *attrs): + if ( + not isinstance(attr, str) or + not all(isinstance(a, str) for a in attrs) + ): + raise TypeError("attribute name must be a string, not %r" % + type(attr).__name__) if attrs: - getters = [single_attr_getter(a) for a in (attr,) + attrs] - def getter(obj): - return tuple([getter(obj) for getter in getters]) + return _multi_attrgetter([ + a.split(".") for a in [attr] + list(attrs) + ]) + elif "." not in attr: + return _simple_attrgetter(attr) else: - getter = single_attr_getter(attr) - return builtinify(getter) + return _single_attrgetter(attr.split(".")) -def single_attr_getter(attr): - if not isinstance(attr, str): - raise TypeError("attribute name must be a string, not {!r}".format( - type(attr).__name__)) - # - def make_getter(name, prevfn=None): - if prevfn is None: - def getter(obj): - return getattr(obj, name) + +class itemgetter(object): + def __init__(self, item, *items): + self._single = not bool(items) + if self._single: + self._idx = item else: - def getter(obj): - return getattr(prevfn(obj), name) - return getter - # - last = 0 - getter = None - while True: - dot = attr.find(".", last) - if dot < 0: break - getter = make_getter(attr[last:dot], getter) - last = dot + 1 - return make_getter(attr[last:], getter) + self._idx = [item] + list(items) + def __call__(self, obj): + if self._single: + return obj[self._idx] + else: + return tuple([obj[i] for i in self._idx]) -def itemgetter(item, *items): - if items: - list_of_indices = [item] + list(items) - def getter(obj): - return tuple([obj[i] for i in list_of_indices]) - else: - def getter(obj): - return obj[item] - return builtinify(getter) +class methodcaller(object): + def __init__(self, method_name, *args, **kwargs): + self._method_name = method_name + self._args = args + self._kwargs = kwargs -def methodcaller(method_name, *args, **kwargs): - def call(obj): - return getattr(obj, method_name)(*args, **kwargs) - return builtinify(call) + def __call__(self, obj): + return getattr(obj, self._method_name)(*self._args, **self._kwargs) diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py --- a/pypy/module/posix/__init__.py +++ b/pypy/module/posix/__init__.py @@ -168,6 +168,11 @@ # not visible via os, inconsistency in nt: if hasattr(posix, '_getfullpathname'): interpleveldefs['_getfullpathname'] = 'interp_posix._getfullpathname' + if os.name == 'nt': + interpleveldefs.update({ + '_getfileinformation': 'interp_posix._getfileinformation', + '_getfinalpathname': 'interp_posix._getfinalpathname', + }) if hasattr(os, 'chroot'): interpleveldefs['chroot'] = 'interp_posix.chroot' diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -5,8 +5,7 @@ from rpython.rlib.objectmodel import specialize from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.unroll import unrolling_iterable -from rpython.rtyper.module import ll_os_stat -from rpython.rtyper.module.ll_os import RegisterOs +from rpython.rtyper.module import ll_os, ll_os_stat from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 @@ -1234,7 +1233,7 @@ raise wrap_oserror(space, e) def declare_new_w_star(name): - if name in RegisterOs.w_star_returning_int: + if name in ll_os.RegisterOs.w_star_returning_int: @unwrap_spec(status=c_int) def WSTAR(space, status): return space.wrap(getattr(os, name)(status)) @@ -1246,7 +1245,7 @@ WSTAR.func_name = name return WSTAR -for name in RegisterOs.w_star: +for name in ll_os.RegisterOs.w_star: if hasattr(os, name): func = declare_new_w_star(name) globals()[name] = func @@ -1412,3 +1411,25 @@ if codeset: return space.wrap(codeset) return space.w_None + +if _WIN32: + @unwrap_spec(fd=c_int) + def _getfileinformation(space, fd): + try: + info = ll_os._getfileinformation(fd) + except OSError as e: + raise wrap_oserror(space, e) + return space.newtuple([space.wrap(info[0]), + space.wrap(info[1]), + space.wrap(info[2])]) + + def _getfinalpathname(space, w_path): + path = space.unicode_w(w_path) + try: + result = ll_os._getfinalpathname(path) + except ll_os.LLNotImplemented as e: + raise OperationError(space.w_NotImplementedError, + space.wrap(e.msg)) + except OSError as e: + raise wrap_oserror2(space, e, w_path) + return space.wrap(result) diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -1069,6 +1069,24 @@ # just ensure it returns something reasonable assert encoding is None or type(encoding) is str + if os.name == 'nt': + def test__getfileinformation(self): + import os + path = os.path.join(self.pdir, 'file1') + with open(path) as fp: + info = self.posix._getfileinformation(fp.fileno()) + assert len(info) == 3 + assert all(isinstance(obj, int) for obj in info) + + def test__getfinalpathname(self): + import os + path = os.path.join(self.pdir, 'file1') + try: + result = self.posix._getfinalpathname(path) + except NotImplementedError: + skip("_getfinalpathname not supported on this platform") + assert os.path.exists(result) + def test_rtld_constants(self): # check presence of major RTLD_* constants self.posix.RTLD_LAZY @@ -1076,6 +1094,7 @@ self.posix.RTLD_GLOBAL self.posix.RTLD_LOCAL + class AppTestEnvironment(object): def setup_class(cls): cls.space = space diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py --- a/pypy/module/sys/test/test_sysmodule.py +++ b/pypy/module/sys/test/test_sysmodule.py @@ -127,9 +127,9 @@ assert isinstance(sys.__stdin__, io.IOBase) assert sys.__stderr__.errors == 'backslashreplace' - assert sys.__stdin__.name == "<stdin>" - assert sys.__stdout__.name == "<stdout>" - assert sys.__stderr__.name == "<stderr>" + #assert sys.__stdin__.name == "<stdin>" + #assert sys.__stdout__.name == "<stdout>" + #assert sys.__stderr__.name == "<stderr>" if self.appdirect and not isinstance(sys.stdin, io.IOBase): return diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py --- a/pypy/tool/release/package.py +++ b/pypy/tool/release/package.py @@ -306,10 +306,10 @@ import imp argparse = imp.load_source('argparse', 'lib-python/2.7/argparse.py') if sys.platform == 'win32': - pypy_exe = 'pypy.exe' + pypy_exe = 'pypy3.exe' license_base = os.path.join(basedir, r'..\..\..\local') # as on buildbot YMMV else: - pypy_exe = 'pypy' + pypy_exe = 'pypy3' license_base = '/usr/share/doc' parser = argparse.ArgumentParser() args = list(args) diff --git a/rpython/jit/backend/arm/callbuilder.py b/rpython/jit/backend/arm/callbuilder.py --- a/rpython/jit/backend/arm/callbuilder.py +++ b/rpython/jit/backend/arm/callbuilder.py @@ -92,7 +92,8 @@ self.mc.LDR_ri(r.r7.value, r.r5.value) # change 'rpy_fastgil' to 0 (it should be non-zero right now) - self.mc.DMB() + if self.asm.cpu.cpuinfo.arch_version >= 7: + self.mc.DMB() self.mc.gen_load_int(r.r6.value, fastgil) self.mc.MOV_ri(r.ip.value, 0) self.mc.STR_ri(r.ip.value, r.r6.value) @@ -112,7 +113,8 @@ self.mc.STREX(r.r3.value, r.ip.value, r.r6.value, c=c.EQ) # try to claim the lock self.mc.CMP_ri(r.r3.value, 0, cond=c.EQ) # did this succeed? - self.mc.DMB() + if self.asm.cpu.cpuinfo.arch_version >= 7: + self.mc.DMB() # the success of the lock acquisition is defined by # 'EQ is true', or equivalently by 'r3 == 0'. # diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -333,6 +333,8 @@ | (rn & 0xF) << 16) def DMB(self): + # ARMv7 only. I guess ARMv6 CPUs cannot be used in symmetric + # multi-processing at all? That would make this instruction unneeded. # note: 'cond' is only permitted on Thumb here, but don't # write literally 0xf57ff05f, because it's larger than 31 bits c = cond.AL diff --git a/rpython/jit/backend/arm/instructions.py b/rpython/jit/backend/arm/instructions.py --- a/rpython/jit/backend/arm/instructions.py +++ b/rpython/jit/backend/arm/instructions.py @@ -142,6 +142,7 @@ #'VCVT' : {'opc1':0xB, 'opc2':0xE, 'opc3':0x1, 'base': False}, } +# ARMv7 only simd_instructions_3regs = { 'VADD_i64': {'A': 0x8, 'B': 0, 'U': 0}, 'VSUB_i64': {'A': 0x8, 'B': 0, 'U': 1}, diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -1,3 +1,4 @@ +from rpython.rlib import rgc from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.lltypesystem import llmemory from rpython.jit.metainterp import history @@ -390,8 +391,8 @@ val = op.getarg(0) if val not in self.write_barrier_applied: v = op.getarg(1) - if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and - bool(v.value)): # store a non-NULL + if (isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and + rgc.needs_write_barrier(v.value))): self.gen_write_barrier(val) #op = op.copy_and_change(rop.SETFIELD_RAW) self.newops.append(op) @@ -400,8 +401,8 @@ val = op.getarg(0) if val not in self.write_barrier_applied: v = op.getarg(2) - if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and - bool(v.value)): # store a non-NULL + if (isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and + rgc.needs_write_barrier(v.value))): self.gen_write_barrier_array(val, op.getarg(1)) #op = op.copy_and_change(rop.SET{ARRAYITEM,INTERIORFIELD}_RAW) self.newops.append(op) diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py --- a/rpython/rlib/rdynload.py +++ b/rpython/rlib/rdynload.py @@ -158,3 +158,4 @@ return res LoadLibrary = rwin32.LoadLibrary + GetModuleHandle = rwin32.GetModuleHandle diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -86,6 +86,14 @@ collect(i) i += 1 +def needs_write_barrier(obj): + """ We need to emit write barrier if the right hand of assignment + is in nursery, used by the JIT for handling set*_gc(Const) + """ + if not obj: + return False + return can_move(obj) + def _heap_stats(): raise NotImplementedError # can't be run directly diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py --- a/rpython/rlib/rwin32.py +++ b/rpython/rlib/rwin32.py @@ -130,6 +130,7 @@ # is hidden by operations in ll2ctypes. Call it now. GetLastError() + GetModuleHandle = winexternal('GetModuleHandleA', [rffi.CCHARP], HMODULE) LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], HMODULE) GetProcAddress = winexternal('GetProcAddress', [HMODULE, rffi.CCHARP], diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py b/rpython/rtyper/lltypesystem/ll2ctypes.py --- a/rpython/rtyper/lltypesystem/ll2ctypes.py +++ b/rpython/rtyper/lltypesystem/ll2ctypes.py @@ -361,7 +361,9 @@ functype = ctypes.CFUNCTYPE if sys.platform == 'win32': from rpython.rlib.clibffi import FFI_STDCALL, FFI_DEFAULT_ABI - if getattr(T.TO, 'ABI', FFI_DEFAULT_ABI) == FFI_STDCALL: + # XXX: + #if getattr(T.TO, 'ABI', FFI_DEFAULT_ABI) == FFI_STDCALL: + if getattr(T.TO, 'ABI', FFI_DEFAULT_ABI) == 'FFI_STDCALL': # for win32 system call functype = ctypes.WINFUNCTYPE argtypes = [get_ctypes_type(ARG) for ARG in T.TO.ARGS diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -1,16 +1,17 @@ -from types import NoneType, MethodType import weakref +from types import MethodType, NoneType + +from rpython.annotator.bookkeeper import analyzer_for, immutablevalue from rpython.annotator.model import ( - SomeInteger, SomeBool, SomeObject, AnnotatorError) + AnnotatorError, SomeBool, SomeInteger, SomeObject) +from rpython.rlib.objectmodel import Symbolic from rpython.rlib.rarithmetic import ( - r_int, r_uint, intmask, r_singlefloat, r_ulonglong, r_longlong, - r_longfloat, r_longlonglong, base_int, normalizedinttype, longlongmask, - longlonglongmask, maxint, is_valid_int, is_emulated_long) -from rpython.rlib.objectmodel import Symbolic + base_int, intmask, is_emulated_long, is_valid_int, longlonglongmask, + longlongmask, maxint, normalizedinttype, r_int, r_longfloat, r_longlong, + r_longlonglong, r_singlefloat, r_uint, r_ulonglong) +from rpython.rtyper.extregistry import ExtRegistryEntry +from rpython.tool import leakfinder from rpython.tool.identity_dict import identity_dict -from rpython.tool import leakfinder -from rpython.annotator.bookkeeper import analyzer_for, immutablevalue -from rpython.rtyper.extregistry import ExtRegistryEntry class State(object): pass @@ -313,14 +314,12 @@ except KeyError: return ContainerType.__getattr__(self, name) - def _nofield(self, name): raise AttributeError('struct %s has no field %r' % (self._name, name)) def _names_without_voids(self): - names_without_voids = [name for name in self._names if self._flds[name] is not Void] - return names_without_voids + return [name for name in self._names if self._flds[name] is not Void] def _str_fields_without_voids(self): return ', '.join(['%s: %s' % (name, self._flds[name]) @@ -576,8 +575,10 @@ _gckind = 'raw' def __init__(self, tag, hints={}): - """ if hints['render_structure'] is set, the type is internal and not considered - to come from somewhere else (it should be rendered as a structure) """ + """If hints['render_structure'] is set, the type is internal and + not considered to come from somewhere else (it should be + rendered as a structure) + """ self.tag = tag self.__name__ = tag self.hints = frozendict(hints) @@ -675,7 +676,8 @@ _numbertypes = {int: Number("Signed", int, intmask)} _numbertypes[r_int] = _numbertypes[int] -_numbertypes[r_longlonglong] = Number("SignedLongLongLong", r_longlonglong, longlonglongmask) +_numbertypes[r_longlonglong] = Number("SignedLongLongLong", r_longlonglong, + longlonglongmask) if r_longlong is not r_int: _numbertypes[r_longlong] = Number("SignedLongLong", r_longlong, longlongmask) @@ -702,8 +704,8 @@ UnsignedLongLong = build_number("UnsignedLongLong", r_ulonglong) Float = Primitive("Float", 0.0) # C type 'double' -SingleFloat = Primitive("SingleFloat", r_singlefloat(0.0)) # C type 'float' -LongFloat = Primitive("LongFloat", r_longfloat(0.0)) # C type 'long double' +SingleFloat = Primitive("SingleFloat", r_singlefloat(0.0)) # 'float' +LongFloat = Primitive("LongFloat", r_longfloat(0.0)) # 'long double' r_singlefloat._TYPE = SingleFloat Char = Primitive("Char", '\x00') @@ -876,9 +878,11 @@ @analyzer_for(cast_primitive) def ann_cast_primitive(T, s_v): - from rpython.rtyper.llannotation import annotation_to_lltype, ll_to_annotation + from rpython.rtyper.llannotation import ( + annotation_to_lltype, ll_to_annotation) assert T.is_constant() - return ll_to_annotation(cast_primitive(T.const, annotation_to_lltype(s_v)._defl())) + return ll_to_annotation(cast_primitive(T.const, + annotation_to_lltype(s_v)._defl())) def _cast_whatever(TGT, value): @@ -905,7 +909,8 @@ elif TGT == llmemory.Address and isinstance(ORIG, Ptr): return llmemory.cast_ptr_to_adr(value) elif TGT == Signed and isinstance(ORIG, Ptr) and ORIG.TO._gckind == 'raw': - return llmemory.cast_adr_to_int(llmemory.cast_ptr_to_adr(value), 'symbolic') + return llmemory.cast_adr_to_int(llmemory.cast_ptr_to_adr(value), + 'symbolic') raise TypeError("don't know how to cast from %r to %r" % (ORIG, TGT)) @@ -1176,8 +1181,8 @@ except DelayedPointer: return True # assume it's not a delayed null - # _setobj, _getobj and _obj0 are really _internal_ implementations details of _ptr, - # use _obj if necessary instead ! + # _setobj, _getobj and _obj0 are really _internal_ implementations + # details of _ptr, use _obj if necessary instead ! def _setobj(self, pointing_to, solid=False): if pointing_to is None: obj0 = None @@ -1244,12 +1249,12 @@ if T1 == T2: setattr(self._obj, field_name, val) else: - raise TypeError("%r instance field %r:\n" - "expects %r\n" - " got %r" % (self._T, field_name, T1, T2)) + raise TypeError( + "%r instance field %r:\nexpects %r\n got %r" % + (self._T, field_name, T1, T2)) return - raise AttributeError("%r instance has no field %r" % (self._T, - field_name)) + raise AttributeError("%r instance has no field %r" % + (self._T, field_name)) def __getitem__(self, i): # ! can only return basic or ptr ! if isinstance(self._T, (Array, FixedSizeArray)): @@ -1266,7 +1271,8 @@ if isinstance(self._T, (Array, FixedSizeArray)): T1 = self._T.OF if isinstance(T1, ContainerType): - raise TypeError("cannot directly assign to container array items") + raise TypeError("cannot directly assign to container array " + "items") T2 = typeOf(val) if T2 != T1: from rpython.rtyper.lltypesystem import rffi @@ -1316,7 +1322,8 @@ from rpython.rtyper.lltypesystem import rffi if isinstance(self._T, FuncType): if len(args) != len(self._T.ARGS): - raise TypeError("calling %r with wrong argument number: %r" % (self._T, args)) + raise TypeError("calling %r with wrong argument number: %r" % + (self._T, args)) for i, a, ARG in zip(range(len(self._T.ARGS)), args, self._T.ARGS): if typeOf(a) != ARG: # ARG could be Void @@ -1415,11 +1422,13 @@ raise RuntimeError("widening to trash: %r" % self) PARENTTYPE = struc._parent_type if getattr(parent, PARENTTYPE._names[0]) != struc: - raise InvalidCast(CURTYPE, PTRTYPE) # xxx different exception perhaps? + # xxx different exception perhaps? + raise InvalidCast(CURTYPE, PTRTYPE) struc = parent u -= 1 if PARENTTYPE != PTRTYPE.TO: - raise RuntimeError("widening %r inside %r instead of %r" % (CURTYPE, PARENTTYPE, PTRTYPE.TO)) + raise RuntimeError("widening %r inside %r instead of %r" % + (CURTYPE, PARENTTYPE, PTRTYPE.TO)) return _ptr(PTRTYPE, struc, solid=self._solid) def _cast_to_int(self, check=True): @@ -1430,7 +1439,9 @@ return obj # special case for cast_int_to_ptr() results obj = normalizeptr(self, check)._getobj(check) if isinstance(obj, int): - return obj # special case for cast_int_to_ptr() results put into opaques + # special case for cast_int_to_ptr() results put into + # opaques + return obj if getattr(obj, '_read_directly_intval', False): return obj.intval # special case for _llgcopaque result = intmask(obj._getid()) @@ -1468,7 +1479,8 @@ """XXX A nice docstring here""" T = typeOf(val) if isinstance(T, ContainerType): - if self._T._gckind == 'gc' and T._gckind == 'raw' and not isinstance(T, OpaqueType): + if (self._T._gckind == 'gc' and T._gckind == 'raw' and + not isinstance(T, OpaqueType)): val = _interior_ptr(T, self._obj, [offset]) else: val = _ptr(Ptr(T), val, solid=self._solid) @@ -1531,12 +1543,14 @@ setattr(example, s_attr.const, v_lltype._defl()) def call(self, args): - from rpython.rtyper.llannotation import annotation_to_lltype, ll_to_annotation + from rpython.rtyper.llannotation import ( + annotation_to_lltype, ll_to_annotation) args_s, kwds_s = args.unpack() if kwds_s: raise Exception("keyword arguments to call to a low-level fn ptr") info = 'argument to ll function pointer call' - llargs = [annotation_to_lltype(s_arg, info)._defl() for s_arg in args_s] + llargs = [annotation_to_lltype(s_arg, info)._defl() + for s_arg in args_s] v = self.ll_ptrtype._example()(*llargs) return ll_to_annotation(v) @@ -1593,7 +1607,6 @@ return val - assert not '__dict__' in dir(_interior_ptr) class _container(object): @@ -1721,11 +1734,13 @@ __slots__ = ('_hash_cache_', '_compilation_info') - def __new__(self, TYPE, n=None, initialization=None, parent=None, parentindex=None): + def __new__(self, TYPE, n=None, initialization=None, parent=None, + parentindex=None): my_variety = _struct_variety(TYPE._names) return object.__new__(my_variety) - def __init__(self, TYPE, n=None, initialization=None, parent=None, parentindex=None): + def __init__(self, TYPE, n=None, initialization=None, parent=None, + parentindex=None): _parentable.__init__(self, TYPE) if n is not None and TYPE._arrayfld is None: raise TypeError("%r is not variable-sized" % (TYPE,)) @@ -1734,9 +1749,11 @@ first, FIRSTTYPE = TYPE._first_struct() for fld, typ in TYPE._flds.items(): if fld == TYPE._arrayfld: - value = _array(typ, n, initialization=initialization, parent=self, parentindex=fld) + value = _array(typ, n, initialization=initialization, + parent=self, parentindex=fld) else: - value = typ._allocate(initialization=initialization, parent=self, parentindex=fld) + value = typ._allocate(initialization=initialization, + parent=self, parentindex=fld) setattr(self, fld, value) if parent is not None: self._setparentstructure(parent, parentindex) @@ -1795,7 +1812,8 @@ __slots__ = ('items',) - def __init__(self, TYPE, n, initialization=None, parent=None, parentindex=None): + def __init__(self, TYPE, n, initialization=None, parent=None, + parentindex=None): if not is_valid_int(n): raise TypeError("array length must be an int") if n < 0: @@ -1964,7 +1982,8 @@ if not key._was_freed(): newcache[key] = value except RuntimeError: - pass # ignore "accessing subxxx, but already gc-ed parent" + # ignore "accessing subxxx, but already gc-ed parent" + pass if newcache: _subarray._cache[T] = newcache else: @@ -2020,8 +2039,10 @@ attrs.setdefault('_name', '?') attrs.setdefault('_callable', None) self.__dict__.update(attrs) - if '_callable' in attrs and hasattr(attrs['_callable'], '_compilation_info'): - self.__dict__['compilation_info'] = attrs['_callable']._compilation_info + if '_callable' in attrs and hasattr(attrs['_callable'], + '_compilation_info'): + self.__dict__['compilation_info'] = \ + attrs['_callable']._compilation_info def __repr__(self): return '<%s>' % (self,) @@ -2126,8 +2147,8 @@ return _ptr(Ptr(T), o, solid) @analyzer_for(malloc) -def ann_malloc(s_T, s_n=None, s_flavor=None, s_zero=None, s_track_allocation=None, - s_add_memory_pressure=None): +def ann_malloc(s_T, s_n=None, s_flavor=None, s_zero=None, + s_track_allocation=None, s_add_memory_pressure=None): assert (s_n is None or s_n.knowntype == int or issubclass(s_n.knowntype, base_int)) assert s_T.is_constant() @@ -2303,7 +2324,8 @@ @analyzer_for(runtime_type_info) def ann_runtime_type_info(s_p): - assert isinstance(s_p, SomePtr), "runtime_type_info of non-pointer: %r" % s_p + assert isinstance(s_p, SomePtr), \ + "runtime_type_info of non-pointer: %r" % s_p return SomePtr(typeOf(runtime_type_info(s_p.ll_ptrtype._example()))) 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 @@ -105,6 +105,12 @@ _CYGWIN = sys.platform == 'cygwin' +# plain NotImplementedError is invalid RPython +class LLNotImplemented(NotImplementedError): + + def __init__(self, msg): + self.msg = msg + class CConfig: """ Definitions for platform integration. @@ -1179,7 +1185,7 @@ condition=sys.platform=='win32') def register_posix__getfullpathname(self, traits): # this nt function is not exposed via os, but needed - # to get a correct implementation of os.abspath + # to get a correct implementation of os.path.abspath from rpython.rtyper.module.ll_win32file import make_getfullpathname_impl getfullpathname_llimpl = make_getfullpathname_impl(traits) @@ -1963,10 +1969,12 @@ return OsEnvironController() # ____________________________________________________________ -# Support for the WindowsError exception +# Support for the WindowsError exception and misc functions if sys.platform == 'win32': from rpython.rlib import rwin32 + from rpython.rtyper.module.ll_win32file import ( + make__getfileinformation_impl, make__getfinalpathname_impl) class RegisterFormatError(BaseLazyRegistering): def __init__(self): @@ -1977,3 +1985,6 @@ return extdef([lltype.Signed], str, "rwin32_FormatError", llimpl=rwin32.llimpl_FormatError) + + _getfileinformation = make__getfileinformation_impl(UnicodeTraits()) + _getfinalpathname = make__getfinalpathname_impl(UnicodeTraits()) diff --git a/rpython/rtyper/module/ll_os_stat.py b/rpython/rtyper/module/ll_os_stat.py --- a/rpython/rtyper/module/ll_os_stat.py +++ b/rpython/rtyper/module/ll_os_stat.py @@ -186,7 +186,10 @@ _name_struct_stat = '_stati64' INCLUDES = ['sys/types.h', 'sys/stat.h', 'sys/statvfs.h'] else: - _name_struct_stat = 'stat' + if sys.platform.startswith('linux'): + _name_struct_stat = 'stat64' + else: + _name_struct_stat = 'stat' INCLUDES = ['sys/types.h', 'sys/stat.h', 'sys/statvfs.h', 'unistd.h'] compilation_info = ExternalCompilationInfo( diff --git a/rpython/rtyper/module/ll_win32file.py b/rpython/rtyper/module/ll_win32file.py --- a/rpython/rtyper/module/ll_win32file.py +++ b/rpython/rtyper/module/ll_win32file.py @@ -55,6 +55,15 @@ FILE_TYPE_CHAR = platform.ConstantInteger('FILE_TYPE_CHAR') FILE_TYPE_PIPE = platform.ConstantInteger('FILE_TYPE_PIPE') + FILE_WRITE_ATTRIBUTES = platform.ConstantInteger( + 'FILE_WRITE_ATTRIBUTES') + OPEN_EXISTING = platform.ConstantInteger( + 'OPEN_EXISTING') + FILE_FLAG_BACKUP_SEMANTICS = platform.ConstantInteger( + 'FILE_FLAG_BACKUP_SEMANTICS') + VOLUME_NAME_DOS = platform.ConstantInteger('VOLUME_NAME_DOS') + VOLUME_NAME_NT = platform.ConstantInteger('VOLUME_NAME_NT') + WIN32_FILE_ATTRIBUTE_DATA = platform.Struct( 'WIN32_FILE_ATTRIBUTE_DATA', [('dwFileAttributes', rwin32.DWORD), @@ -67,14 +76,15 @@ BY_HANDLE_FILE_INFORMATION = platform.Struct( 'BY_HANDLE_FILE_INFORMATION', [('dwFileAttributes', rwin32.DWORD), + ('ftCreationTime', rwin32.FILETIME), + ('ftLastAccessTime', rwin32.FILETIME), + ('ftLastWriteTime', rwin32.FILETIME), + ('dwVolumeSerialNumber', rwin32.DWORD), ('nFileSizeHigh', rwin32.DWORD), ('nFileSizeLow', rwin32.DWORD), ('nNumberOfLinks', rwin32.DWORD), ('nFileIndexHigh', rwin32.DWORD), - ('nFileIndexLow', rwin32.DWORD), - ('ftCreationTime', rwin32.FILETIME), - ('ftLastAccessTime', rwin32.FILETIME), - ('ftLastWriteTime', rwin32.FILETIME)]) + ('nFileIndexLow', rwin32.DWORD)]) config = platform.configure(CConfig) @@ -92,6 +102,8 @@ INVALID_FILE_ATTRIBUTES _S_IFDIR _S_IFREG _S_IFCHR _S_IFIFO FILE_TYPE_UNKNOWN FILE_TYPE_CHAR FILE_TYPE_PIPE + FILE_WRITE_ATTRIBUTES OPEN_EXISTING FILE_FLAG_BACKUP_SEMANTICS + VOLUME_NAME_DOS VOLUME_NAME_NT ERROR_FILE_NOT_FOUND ERROR_NO_MORE_FILES ERROR_SHARING_VIOLATION '''.split(): @@ -163,6 +175,13 @@ [traits.CCHARP, traits.CCHARP], rwin32.BOOL) + CreateFile = external( + 'CreateFile' + apisuffix, + [traits.CCHARP, rwin32.DWORD, rwin32.DWORD, + rwin32.LPSECURITY_ATTRIBUTES, rwin32.DWORD, rwin32.DWORD, + rwin32.HANDLE], + rwin32.HANDLE) + DeleteFile = external( 'DeleteFile' + suffix, [traits.CCHARP], @@ -173,7 +192,29 @@ [traits.CCHARP, traits.CCHARP], rwin32.BOOL) - return Win32Traits + GETFINALPATHNAMEBYHANDLE_TP = lltype.Ptr(lltype.FuncType( + [rwin32.HANDLE, traits.CCHARP, rwin32.DWORD, rwin32.DWORD], + rwin32.DWORD, abi='FFI_STDCALL')) + # dynamically loaded + GetFinalPathNameByHandle = lltype.nullptr( + GETFINALPATHNAMEBYHANDLE_TP.TO) + + def check_GetFinalPathNameByHandle(self): + if self.GetFinalPathNameByHandle: + return True + + from rpython.rlib.rdynload import GetModuleHandle, dlsym + hKernel32 = GetModuleHandle("KERNEL32") + try: + func = dlsym(hKernel32, 'GetFinalPathNameByHandle' + suffix) + except KeyError: + return False + + self.GetFinalPathNameByHandle = rffi.cast( + Win32Traits.GETFINALPATHNAMEBYHANDLE_TP, func) + return True + + return Win32Traits() #_______________________________________________________________ # listdir @@ -336,27 +377,6 @@ win32traits = make_win32_traits(traits) from rpython.rtyper.module.ll_os_stat import time_t_to_FILE_TIME - class CConfig: - _compilation_info_ = ExternalCompilationInfo( - includes = ['windows.h'], - ) - - FILE_WRITE_ATTRIBUTES = platform.ConstantInteger( - 'FILE_WRITE_ATTRIBUTES') - OPEN_EXISTING = platform.ConstantInteger( - 'OPEN_EXISTING') - FILE_FLAG_BACKUP_SEMANTICS = platform.ConstantInteger( - 'FILE_FLAG_BACKUP_SEMANTICS') - globals().update(platform.configure(CConfig)) - - CreateFile = rffi.llexternal( - 'CreateFile' + win32traits.apisuffix, - [traits.CCHARP, rwin32.DWORD, rwin32.DWORD, - rwin32.LPSECURITY_ATTRIBUTES, rwin32.DWORD, rwin32.DWORD, - rwin32.HANDLE], - rwin32.HANDLE, - calling_conv='win') - GetSystemTime = rffi.llexternal( 'GetSystemTime', [lltype.Ptr(rwin32.SYSTEMTIME)], @@ -381,10 +401,10 @@ @specialize.argtype(1) def os_utime_llimpl(path, tp): - hFile = CreateFile(path, - FILE_WRITE_ATTRIBUTES, 0, - None, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, + hFile = win32traits.CreateFile(path, + win32traits.FILE_WRITE_ATTRIBUTES, 0, + None, win32traits.OPEN_EXISTING, + win32traits.FILE_FLAG_BACKUP_SEMANTICS, rwin32.NULL_HANDLE) if hFile == rwin32.INVALID_HANDLE_VALUE: raise rwin32.lastWindowsError() @@ -413,3 +433,68 @@ lltype.free(mtime, flavor='raw') return os_utime_llimpl + +#_______________________________________________________________ +# _getfileinformation (py3) + +def make__getfileinformation_impl(traits): + from rpython.rlib import rwin32 + win32traits = make_win32_traits(traits) + + def _getfileinformation_llimpl(fd): + hFile = rwin32.get_osfhandle(fd) + with lltype.scoped_alloc( + win32traits.BY_HANDLE_FILE_INFORMATION) as info: + if win32traits.GetFileInformationByHandle(hFile, info) == 0: + raise rwin32.lastWindowsError("_getfileinformation") + return (rffi.cast(lltype.Signed, info.c_dwVolumeSerialNumber), + rffi.cast(lltype.Signed, info.c_nFileIndexHigh), + rffi.cast(lltype.Signed, info.c_nFileIndexLow)) + + return _getfileinformation_llimpl + +#_______________________________________________________________ +# _getfinalpathname (py3) + +def make__getfinalpathname_impl(traits): + from rpython.rlib import rwin32 + from rpython.rtyper.module.ll_os import LLNotImplemented + assert traits.str is unicode, 'Currently only handles unicode paths' + win32traits = make_win32_traits(traits) + + def _getfinalpathname_llimpl(path): + if not win32traits.check_GetFinalPathNameByHandle(): + raise LLNotImplemented("GetFinalPathNameByHandle not available on " + "this platform") + + hFile = win32traits.CreateFile(path, 0, 0, None, + win32traits.OPEN_EXISTING, + win32traits.FILE_FLAG_BACKUP_SEMANTICS, + rwin32.NULL_HANDLE) + if hFile == rwin32.INVALID_HANDLE_VALUE: + raise rwin32.lastWindowsError("CreateFile") + + VOLUME_NAME_DOS = rffi.cast(rwin32.DWORD, win32traits.VOLUME_NAME_DOS) + try: + size = win32traits.GetFinalPathNameByHandle( + hFile, + lltype.nullptr(traits.CCHARP.TO), + rffi.cast(rwin32.DWORD, 0), + VOLUME_NAME_DOS) + if size == 0: + raise rwin32.lastWindowsError("GetFinalPathNameByHandle") + + with lltype.scoped_alloc(traits.CCHARP.TO, size + 1) as target_path: + result = win32traits.GetFinalPathNameByHandle( + hFile, + target_path, + size, + VOLUME_NAME_DOS) + if result == 0: + raise rwin32.lastWindowsError("GetFinalPathNameByHandle") + return traits.charpsize2str(target_path, + rffi.cast(lltype.Signed, result)) + finally: + rwin32.CloseHandle(hFile) + + return _getfinalpathname_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 @@ -49,6 +49,7 @@ CHAR = rffi.CHAR CCHARP = rffi.CCHARP charp2str = staticmethod(rffi.charp2str) + charpsize2str = staticmethod(rffi.charpsize2str) scoped_str2charp = staticmethod(rffi.scoped_str2charp) str2charp = staticmethod(rffi.str2charp) free_charp = staticmethod(rffi.free_charp) @@ -68,6 +69,7 @@ CHAR = rffi.WCHAR_T CCHARP = rffi.CWCHARP charp2str = staticmethod(rffi.wcharp2unicode) + charpsize2str = staticmethod(rffi.wcharpsize2unicode) str2charp = staticmethod(rffi.unicode2wcharp) scoped_str2charp = staticmethod(rffi.scoped_unicode2wcharp) free_charp = staticmethod(rffi.free_wcharp) diff --git a/rpython/rtyper/module/test/test_ll_win32file.py b/rpython/rtyper/module/test/test_ll_win32file.py new file mode 100644 --- /dev/null +++ b/rpython/rtyper/module/test/test_ll_win32file.py @@ -0,0 +1,26 @@ +import os + +import py + +from rpython.rtyper.module import ll_os + +if not ll_os._WIN32: + py.test.skip("requires Windows") + + +def test__getfileinformation(): + with open(__file__) as fp: + stat = os.fstat(fp.fileno()) + info = ll_os._getfileinformation(fp.fileno()) + serial, high, low = info + assert type(serial) in (int, long) + assert (high << 32) + low == stat.st_ino + + +def test__getfinalpathname(): + path = __file__.decode('mbcs') + try: + result = ll_os._getfinalpathname(path) + except ll_os.LLNotImplemented: + py.test.skip("_getfinalpathname not supported on this platform") + assert os.path.exists(result) diff --git a/rpython/translator/platform/test/test_makefile.py b/rpython/translator/platform/test/test_makefile.py --- a/rpython/translator/platform/test/test_makefile.py +++ b/rpython/translator/platform/test/test_makefile.py @@ -44,6 +44,7 @@ assert res.returncode == 0 def test_900_files(self): + tmpdir = udir.join('test_900_files').ensure(dir=1) txt = '#include <stdio.h>\n' for i in range(900): txt += 'int func%03d();\n' % i @@ -52,11 +53,11 @@ txt += ' j += func%03d();\n' % i txt += ' printf("%d\\n", j);\n' txt += ' return 0;};\n' - cfile = udir.join('test_900_files.c') + cfile = tmpdir.join('test_900_files.c') cfile.write(txt) cfiles = [cfile] for i in range(900): - cfile2 = udir.join('implement%03d.c' %i) + cfile2 = tmpdir.join('implement%03d.c' %i) cfile2.write(''' int func%03d() { @@ -64,10 +65,10 @@ } ''' % (i, i)) cfiles.append(cfile2) - mk = self.platform.gen_makefile(cfiles, ExternalCompilationInfo(), path=udir) + mk = self.platform.gen_makefile(cfiles, ExternalCompilationInfo(), path=tmpdir) mk.write() self.platform.execute_makefile(mk) - res = self.platform.execute(udir.join('test_900_files')) + res = self.platform.execute(tmpdir.join('test_900_files')) self.check_res(res, '%d\n' %sum(range(900))) def test_precompiled_headers(self): diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py --- a/rpython/translator/platform/windows.py +++ b/rpython/translator/platform/windows.py @@ -203,6 +203,9 @@ # the assembler still has the old behavior that all options # must come first, and after the file name all options are ignored. # So please be careful with the order of parameters! ;-) + pdb_dir = oname.dirname + if pdb_dir: + compile_args += ['/Fd%s\\' % (pdb_dir,)] args = ['/nologo', '/c'] + compile_args + ['/Fo%s' % (oname,), str(cfile)] self._execute_c_compiler(cc, args, oname) return oname diff --git a/rpython/translator/sandbox/rsandbox.py b/rpython/translator/sandbox/rsandbox.py --- a/rpython/translator/sandbox/rsandbox.py +++ b/rpython/translator/sandbox/rsandbox.py @@ -60,8 +60,7 @@ def need_more_data(self): buflen = self.buflen - buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') - try: + with lltype.scoped_alloc(rffi.CCHARP.TO, buflen) as buf: buflen = rffi.cast(rffi.SIZE_T, buflen) count = ll_read_not_sandboxed(self.fd, buf, buflen) count = rffi.cast(lltype.Signed, count) @@ -69,20 +68,15 @@ raise IOError self.buf += ''.join([buf[i] for i in range(count)]) self.buflen *= 2 - finally: - lltype.free(buf, flavor='raw') def sandboxed_io(buf): STDIN = 0 STDOUT = 1 # send the buffer with the marshalled fnname and input arguments to STDOUT - p = lltype.malloc(rffi.CCHARP.TO, len(buf), flavor='raw') - try: + with lltype.scoped_alloc(rffi.CCHARP.TO, len(buf)) as p: for i in range(len(buf)): p[i] = buf[i] writeall_not_sandboxed(STDOUT, p, len(buf)) - finally: - lltype.free(p, flavor='raw') # build a Loader that will get the answer from STDIN loader = FdLoader(STDIN) # check for errors @@ -108,9 +102,8 @@ @signature(types.str(), returns=types.impossible()) def not_implemented_stub(msg): STDERR = 2 - buf = rffi.str2charp(msg + '\n') - writeall_not_sandboxed(STDERR, buf, len(msg) + 1) - rffi.free_charp(buf) + with rffi.scoped_str2charp(msg + '\n') as buf: + writeall_not_sandboxed(STDERR, buf, len(msg) + 1) raise RuntimeError(msg) # XXX in RPython, the msg is ignored at the moment dump_string = rmarshal.get_marshaller(str) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit