[pypy-svn] r76293 - in pypy/branch/x86-64-jit-backend: . lib-python/modified-2.5.2 lib_pypy lib_pypy/pypy_test pypy/annotation pypy/annotation/test pypy/interpreter pypy/interpreter/astcompiler pypy/interpreter/astcompiler/tools pypy/interpreter/test pypy/jit/backend/llgraph pypy/jit/backend/llsupport pypy/jit/backend/llsupport/test pypy/jit/backend/x86 pypy/jit/backend/x86/test pypy/jit/codewriter pypy/jit/codewriter/test pypy/jit/metainterp pypy/jit/metainterp/test pypy/jit/tool pypy/module/_file pypy/module/_file/test pypy/module/_locale pypy/module/cpyext pypy/module/marshal pypy/module/posix pypy/module/posix/test pypy/module/termios pypy/module/test_lib_pypy/ctypes_tests pypy/objspace/std pypy/rlib pypy/rlib/test pypy/rpython pypy/rpython/lltypesystem pypy/rpython/lltypesystem/test pypy/rpython/memory pypy/rpython/module pypy/rpython/module/test pypy/rpython/test pypy/translator/c/test pypy/translator/platform
jcreigh at codespeak.net
jcreigh at codespeak.net
Tue Jul 20 20:55:35 CEST 2010
Author: jcreigh
Date: Tue Jul 20 20:55:30 2010
New Revision: 76293
Added:
pypy/branch/x86-64-jit-backend/pypy/jit/tool/gen-trace-mode-keywords.py
- copied unchanged from r76292, pypy/trunk/pypy/jit/tool/gen-trace-mode-keywords.py
pypy/branch/x86-64-jit-backend/pypy/jit/tool/pypytrace-mode.el
- copied unchanged from r76292, pypy/trunk/pypy/jit/tool/pypytrace-mode.el
pypy/branch/x86-64-jit-backend/pypy/rlib/test/test_rposix.py
- copied unchanged from r76292, pypy/trunk/pypy/rlib/test/test_rposix.py
pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_win32file.py
- copied unchanged from r76292, pypy/trunk/pypy/rpython/module/ll_win32file.py
Modified:
pypy/branch/x86-64-jit-backend/ (props changed)
pypy/branch/x86-64-jit-backend/lib-python/modified-2.5.2/site.py
pypy/branch/x86-64-jit-backend/lib_pypy/ (props changed)
pypy/branch/x86-64-jit-backend/lib_pypy/dbm.py (props changed)
pypy/branch/x86-64-jit-backend/lib_pypy/pypy_test/test_functools.py (props changed)
pypy/branch/x86-64-jit-backend/pypy/annotation/bookkeeper.py
pypy/branch/x86-64-jit-backend/pypy/annotation/model.py
pypy/branch/x86-64-jit-backend/pypy/annotation/test/test_model.py
pypy/branch/x86-64-jit-backend/pypy/annotation/unaryop.py
pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/ast.py
pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/codegen.py
pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/symtable.py
pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/tools/asdl_py.py
pypy/branch/x86-64-jit-backend/pypy/interpreter/baseobjspace.py
pypy/branch/x86-64-jit-backend/pypy/interpreter/error.py
pypy/branch/x86-64-jit-backend/pypy/interpreter/gateway.py
pypy/branch/x86-64-jit-backend/pypy/interpreter/pyopcode.py
pypy/branch/x86-64-jit-backend/pypy/interpreter/test/test_compiler.py
pypy/branch/x86-64-jit-backend/pypy/interpreter/test/test_gateway.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/llgraph/llimpl.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/llgraph/runner.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/descr.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/gc.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/llmodel.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/support.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/symbolic.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/test/test_descr.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/test/test_symbolic.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/regalloc.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_gc_integration.py
pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/codewriter.py
pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/jtransform.py
pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/support.py
pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/test/test_codewriter.py
pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/test/test_flatten.py
pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/blackhole.py
pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/executor.py
pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/optimizeopt.py
pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/pyjitpl.py
pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/resoperation.py
pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_basic.py
pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_optimizeopt.py
pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_recursive.py
pypy/branch/x86-64-jit-backend/pypy/module/_file/interp_file.py
pypy/branch/x86-64-jit-backend/pypy/module/_file/test/test_file.py
pypy/branch/x86-64-jit-backend/pypy/module/_locale/interp_locale.py
pypy/branch/x86-64-jit-backend/pypy/module/cpyext/api.py
pypy/branch/x86-64-jit-backend/pypy/module/cpyext/methodobject.py
pypy/branch/x86-64-jit-backend/pypy/module/marshal/interp_marshal.py
pypy/branch/x86-64-jit-backend/pypy/module/posix/interp_posix.py
pypy/branch/x86-64-jit-backend/pypy/module/posix/test/test_posix2.py
pypy/branch/x86-64-jit-backend/pypy/module/termios/interp_termios.py
pypy/branch/x86-64-jit-backend/pypy/module/test_lib_pypy/ctypes_tests/ (props changed)
pypy/branch/x86-64-jit-backend/pypy/objspace/std/stringobject.py
pypy/branch/x86-64-jit-backend/pypy/rlib/libffi.py
pypy/branch/x86-64-jit-backend/pypy/rlib/rarithmetic.py
pypy/branch/x86-64-jit-backend/pypy/rlib/rdynload.py
pypy/branch/x86-64-jit-backend/pypy/rlib/rposix.py
pypy/branch/x86-64-jit-backend/pypy/rlib/rwin32.py
pypy/branch/x86-64-jit-backend/pypy/rlib/streamio.py
pypy/branch/x86-64-jit-backend/pypy/rlib/test/test_rarithmetic.py
pypy/branch/x86-64-jit-backend/pypy/rpython/extfunc.py
pypy/branch/x86-64-jit-backend/pypy/rpython/lltypesystem/rffi.py
pypy/branch/x86-64-jit-backend/pypy/rpython/lltypesystem/test/test_rffi.py
pypy/branch/x86-64-jit-backend/pypy/rpython/memory/lltypelayout.py
pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_os.py
pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_os_stat.py
pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_termios.py
pypy/branch/x86-64-jit-backend/pypy/rpython/module/test/test_ll_os_stat.py
pypy/branch/x86-64-jit-backend/pypy/rpython/rstr.py
pypy/branch/x86-64-jit-backend/pypy/rpython/test/test_extfunc.py
pypy/branch/x86-64-jit-backend/pypy/rpython/test/test_rstr.py
pypy/branch/x86-64-jit-backend/pypy/translator/c/test/test_typed.py
pypy/branch/x86-64-jit-backend/pypy/translator/platform/__init__.py
pypy/branch/x86-64-jit-backend/pypy/translator/platform/darwin.py
pypy/branch/x86-64-jit-backend/pypy/translator/platform/posix.py
pypy/branch/x86-64-jit-backend/pypy/translator/platform/windows.py
Log:
merged changes from trunk through r76292
Modified: pypy/branch/x86-64-jit-backend/lib-python/modified-2.5.2/site.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/lib-python/modified-2.5.2/site.py (original)
+++ pypy/branch/x86-64-jit-backend/lib-python/modified-2.5.2/site.py Tue Jul 20 20:55:30 2010
@@ -175,7 +175,7 @@
def addsitepackages(known_paths):
"""Add site-packages to sys.path, in a PyPy-specific way."""
- if hasattr(sys, 'pypy_version_info'):
+ if hasattr(sys, 'pypy_version_info') and hasattr(sys, 'prefix'):
from distutils.sysconfig import get_python_lib
sitedir = get_python_lib(standard_lib=False)
if os.path.isdir(sitedir):
Modified: pypy/branch/x86-64-jit-backend/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/annotation/bookkeeper.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/annotation/bookkeeper.py Tue Jul 20 20:55:30 2010
@@ -739,7 +739,7 @@
"""
w_tuple = SomeTuple
def newtuple(self, items_s):
- if items_s == [Ellipsis]:
+ if len(items_s) == 1 and items_s[0] is Ellipsis:
res = SomeObject() # hack to get a SomeObject as the *arg
res.from_ellipsis = True
return res
Modified: pypy/branch/x86-64-jit-backend/pypy/annotation/model.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/annotation/model.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/annotation/model.py Tue Jul 20 20:55:30 2010
@@ -34,7 +34,7 @@
from pypy.tool.pairtype import pair, extendabletype
from pypy.tool.tls import tlsobject
from pypy.rlib.rarithmetic import r_uint, r_ulonglong, base_int
-from pypy.rlib.rarithmetic import r_singlefloat
+from pypy.rlib.rarithmetic import r_singlefloat, isnan
import inspect, weakref
DEBUG = False # set to False to disable recording of debugging information
@@ -162,6 +162,13 @@
# pretend it's a float.
immutable = True
+ def __eq__(self, other):
+ # NaN unpleasantness.
+ if (self.is_constant() and other.is_constant() and
+ isnan(self.const) and isnan(other.const)):
+ return True
+ return super(SomeFloat, self).__eq__(other)
+
def can_be_none(self):
return False
@@ -229,11 +236,15 @@
class SomeChar(SomeString):
"Stands for an object known to be a string of length 1."
+ can_be_None = False
+ def __init__(self): # no 'can_be_None' argument here
+ pass
class SomeUnicodeCodePoint(SomeUnicodeString):
"Stands for an object known to be a unicode codepoint."
- def can_be_none(self):
- return False
+ can_be_None = False
+ def __init__(self): # no 'can_be_None' argument here
+ pass
SomeString.basestringclass = SomeString
SomeString.basecharclass = SomeChar
Modified: pypy/branch/x86-64-jit-backend/pypy/annotation/test/test_model.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/annotation/test/test_model.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/annotation/test/test_model.py Tue Jul 20 20:55:30 2010
@@ -200,6 +200,15 @@
s2.const=cls
assert s1.contains(s2)
+def test_nan():
+ f1 = SomeFloat()
+ f1.const = float("nan")
+ f2 = SomeFloat()
+ f2.const = float("nan")
+ assert f1.contains(f1)
+ assert f2.contains(f1)
+ assert f1.contains(f2)
+
if __name__ == '__main__':
for name, value in globals().items():
if name.startswith('test_'):
Modified: pypy/branch/x86-64-jit-backend/pypy/annotation/unaryop.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/annotation/unaryop.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/annotation/unaryop.py Tue Jul 20 20:55:30 2010
@@ -5,7 +5,7 @@
from types import MethodType
from pypy.annotation.model import \
SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \
- SomeDict, SomeTuple, SomeImpossibleValue, \
+ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \
SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \
SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \
s_ImpossibleValue, s_Bool, s_None, \
@@ -494,9 +494,6 @@
def getanyitem(str):
return str.basecharclass()
- def ord(str):
- return SomeInteger(nonneg=True)
-
def method_split(str, patt): # XXX
getbookkeeper().count("str_split", str, patt)
return getbookkeeper().newlist(str.basestringclass())
@@ -541,11 +538,16 @@
return SomeUnicodeString()
method_decode.can_only_throw = [UnicodeDecodeError]
-class __extend__(SomeChar):
+class __extend__(SomeChar, SomeUnicodeCodePoint):
def len(chr):
return immutablevalue(1)
+ def ord(str):
+ return SomeInteger(nonneg=True)
+
+class __extend__(SomeChar):
+
def method_isspace(chr):
return s_Bool
Modified: pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/ast.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/ast.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/ast.py Tue Jul 20 20:55:30 2010
@@ -230,6 +230,7 @@
visitor.visit_FunctionDef(self)
def mutate_over(self, visitor):
+ self.args = self.args.mutate_over(visitor)
if self.body:
visitor._mutate_sequence(self.body)
if self.decorators:
@@ -784,6 +785,8 @@
def mutate_over(self, visitor):
if self.body:
visitor._mutate_sequence(self.body)
+ if self.handlers:
+ visitor._mutate_sequence(self.handlers)
if self.orelse:
visitor._mutate_sequence(self.orelse)
return visitor.visit_TryExcept(self)
@@ -927,6 +930,8 @@
visitor.visit_Import(self)
def mutate_over(self, visitor):
+ if self.names:
+ visitor._mutate_sequence(self.names)
return visitor.visit_Import(self)
def sync_app_attrs(self, space):
@@ -965,6 +970,8 @@
visitor.visit_ImportFrom(self)
def mutate_over(self, visitor):
+ if self.names:
+ visitor._mutate_sequence(self.names)
return visitor.visit_ImportFrom(self)
def sync_app_attrs(self, space):
@@ -1282,6 +1289,7 @@
visitor.visit_Lambda(self)
def mutate_over(self, visitor):
+ self.args = self.args.mutate_over(visitor)
self.body = self.body.mutate_over(visitor)
return visitor.visit_Lambda(self)
@@ -1398,6 +1406,8 @@
def mutate_over(self, visitor):
self.elt = self.elt.mutate_over(visitor)
+ if self.generators:
+ visitor._mutate_sequence(self.generators)
return visitor.visit_ListComp(self)
def sync_app_attrs(self, space):
@@ -1437,6 +1447,8 @@
def mutate_over(self, visitor):
self.elt = self.elt.mutate_over(visitor)
+ if self.generators:
+ visitor._mutate_sequence(self.generators)
return visitor.visit_GeneratorExp(self)
def sync_app_attrs(self, space):
@@ -1562,6 +1574,8 @@
self.func = self.func.mutate_over(visitor)
if self.args:
visitor._mutate_sequence(self.args)
+ if self.keywords:
+ visitor._mutate_sequence(self.keywords)
if self.starargs:
self.starargs = self.starargs.mutate_over(visitor)
if self.kwargs:
@@ -2293,6 +2307,13 @@
self.w_ifs = None
self.initialization_state = 7
+ def mutate_over(self, visitor):
+ self.target = self.target.mutate_over(visitor)
+ self.iter = self.iter.mutate_over(visitor)
+ if self.ifs:
+ visitor._mutate_sequence(self.ifs)
+ return visitor.visit_comprehension(self)
+
def walkabout(self, visitor):
visitor.visit_comprehension(self)
@@ -2327,6 +2348,15 @@
self.col_offset = col_offset
self.initialization_state = 31
+ def mutate_over(self, visitor):
+ if self.type:
+ self.type = self.type.mutate_over(visitor)
+ if self.name:
+ self.name = self.name.mutate_over(visitor)
+ if self.body:
+ visitor._mutate_sequence(self.body)
+ return visitor.visit_excepthandler(self)
+
def walkabout(self, visitor):
visitor.visit_excepthandler(self)
@@ -2366,6 +2396,13 @@
self.w_defaults = None
self.initialization_state = 15
+ def mutate_over(self, visitor):
+ if self.args:
+ visitor._mutate_sequence(self.args)
+ if self.defaults:
+ visitor._mutate_sequence(self.defaults)
+ return visitor.visit_arguments(self)
+
def walkabout(self, visitor):
visitor.visit_arguments(self)
@@ -2407,6 +2444,10 @@
self.value = value
self.initialization_state = 3
+ def mutate_over(self, visitor):
+ self.value = self.value.mutate_over(visitor)
+ return visitor.visit_keyword(self)
+
def walkabout(self, visitor):
visitor.visit_keyword(self)
@@ -2426,6 +2467,9 @@
self.asname = asname
self.initialization_state = 3
+ def mutate_over(self, visitor):
+ return visitor.visit_alias(self)
+
def walkabout(self, visitor):
visitor.visit_alias(self)
Modified: pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/codegen.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/codegen.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/codegen.py Tue Jul 20 20:55:30 2010
@@ -258,9 +258,11 @@
# Load decorators first, but apply them after the function is created.
if func.decorators:
self.visit_sequence(func.decorators)
- if func.args.defaults:
- self.visit_sequence(func.args.defaults)
- num_defaults = len(func.args.defaults)
+ args = func.args
+ assert isinstance(args, ast.arguments)
+ if args.defaults:
+ self.visit_sequence(args.defaults)
+ num_defaults = len(args.defaults)
else:
num_defaults = 0
code = self.sub_scope(FunctionCodeGenerator, func.name, func,
@@ -274,9 +276,11 @@
def visit_Lambda(self, lam):
self.update_position(lam.lineno)
- if lam.args.defaults:
- self.visit_sequence(lam.args.defaults)
- default_count = len(lam.args.defaults)
+ args = lam.args
+ assert isinstance(args, ast.arguments)
+ if args.defaults:
+ self.visit_sequence(args.defaults)
+ default_count = len(args.defaults)
else:
default_count = 0
code = self.sub_scope(LambdaCodeGenerator, "<lambda>", lam, lam.lineno)
@@ -1275,9 +1279,11 @@
else:
self.add_const(self.space.w_None)
start = 0
- if func.args.args:
- self._handle_nested_args(func.args.args)
- self.argcount = len(func.args.args)
+ args = func.args
+ assert isinstance(args, ast.arguments)
+ if args.args:
+ self._handle_nested_args(args.args)
+ self.argcount = len(args.args)
for i in range(start, len(func.body)):
func.body[i].walkabout(self)
@@ -1286,9 +1292,11 @@
def _compile(self, lam):
assert isinstance(lam, ast.Lambda)
- if lam.args.args:
- self._handle_nested_args(lam.args.args)
- self.argcount = len(lam.args.args)
+ args = lam.args
+ assert isinstance(args, ast.arguments)
+ if args.args:
+ self._handle_nested_args(args.args)
+ self.argcount = len(args.args)
# Prevent a string from being the first constant and thus a docstring.
self.add_const(self.space.w_None)
lam.body.walkabout(self)
Modified: pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/symtable.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/symtable.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/symtable.py Tue Jul 20 20:55:30 2010
@@ -353,8 +353,10 @@
def visit_FunctionDef(self, func):
self.note_symbol(func.name, SYM_ASSIGNED)
# Function defaults and decorators happen in the outer scope.
- if func.args.defaults:
- self.visit_sequence(func.args.defaults)
+ args = func.args
+ assert isinstance(args, ast.arguments)
+ if args.defaults:
+ self.visit_sequence(args.defaults)
if func.decorators:
self.visit_sequence(func.decorators)
new_scope = FunctionScope(func.name, func.lineno, func.col_offset)
@@ -420,8 +422,10 @@
self.note_symbol(name, SYM_GLOBAL)
def visit_Lambda(self, lamb):
- if lamb.args.defaults:
- self.visit_sequence(lamb.args.defaults)
+ args = lamb.args
+ assert isinstance(args, ast.arguments)
+ if args.defaults:
+ self.visit_sequence(args.defaults)
new_scope = FunctionScope("lambda", lamb.lineno, lamb.col_offset)
self.push_scope(new_scope, lamb)
lamb.args.walkabout(self)
Modified: pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/tools/asdl_py.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/tools/asdl_py.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/interpreter/astcompiler/tools/asdl_py.py Tue Jul 20 20:55:30 2010
@@ -100,6 +100,7 @@
self.emit("")
self.make_constructor(product.fields, product)
self.emit("")
+ self.make_mutate_over(product, name)
self.emit("def walkabout(self, visitor):", 1)
self.emit("visitor.visit_%s(self)" % (name,), 2)
self.emit("")
@@ -183,6 +184,26 @@
have_everything = self.data.required_masks[node] | \
self.data.optional_masks[node]
self.emit("self.initialization_state = %i" % (have_everything,), 2)
+
+ def make_mutate_over(self, cons, name):
+ self.emit("def mutate_over(self, visitor):", 1)
+ for field in cons.fields:
+ if (field.type.value not in asdl.builtin_types and
+ field.type.value not in self.data.simple_types):
+ if field.opt or field.seq:
+ level = 3
+ self.emit("if self.%s:" % (field.name,), 2)
+ else:
+ level = 2
+ if field.seq:
+ sub = (field.name,)
+ self.emit("visitor._mutate_sequence(self.%s)" % sub, level)
+ else:
+ sub = (field.name, field.name)
+ self.emit("self.%s = self.%s.mutate_over(visitor)" % sub,
+ level)
+ self.emit("return visitor.visit_%s(self)" % (name,), 2)
+ self.emit("")
def visitConstructor(self, cons, base, extra_attributes):
self.emit("class %s(%s):" % (cons.name, base))
@@ -199,24 +220,7 @@
self.emit("def walkabout(self, visitor):", 1)
self.emit("visitor.visit_%s(self)" % (cons.name,), 2)
self.emit("")
- self.emit("def mutate_over(self, visitor):", 1)
- for field in cons.fields:
- if field.type.value not in asdl.builtin_types and \
- field.type.value not in self.data.prod_simple:
- if field.opt or field.seq:
- level = 3
- self.emit("if self.%s:" % (field.name,), 2)
- else:
- level = 2
- if field.seq:
- sub = (field.name,)
- self.emit("visitor._mutate_sequence(self.%s)" % sub, level)
- else:
- sub = (field.name, field.name)
- self.emit("self.%s = self.%s.mutate_over(visitor)" % sub,
- level)
- self.emit("return visitor.visit_%s(self)" % (cons.name,), 2)
- self.emit("")
+ self.make_mutate_over(cons, cons.name)
self.make_var_syncer(cons.fields + self.data.cons_attributes[cons],
cons, cons.name)
Modified: pypy/branch/x86-64-jit-backend/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/interpreter/baseobjspace.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/interpreter/baseobjspace.py Tue Jul 20 20:55:30 2010
@@ -1102,17 +1102,6 @@
self.wrap('argument must be a unicode'))
return self.unicode_w(w_obj)
- def path_w(self, w_obj):
- """ Like str_w, but if the object is unicode, encode it using
- filesystemencoding
- """
- filesystemencoding = self.sys.filesystemencoding
- if (filesystemencoding and
- self.is_true(self.isinstance(w_obj, self.w_unicode))):
- w_obj = self.call_method(w_obj, "encode",
- self.wrap(filesystemencoding))
- return self.str_w(w_obj)
-
def bool_w(self, w_obj):
# Unwraps a bool, also accepting an int for compatibility.
# This is here mostly just for gateway.int_unwrapping_space_method().
Modified: pypy/branch/x86-64-jit-backend/pypy/interpreter/error.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/interpreter/error.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/interpreter/error.py Tue Jul 20 20:55:30 2010
@@ -344,7 +344,7 @@
else:
_WINDOWS = True
- def wrap_windowserror(space, e, filename=None):
+ def wrap_windowserror(space, e, w_filename=None):
from pypy.rlib import rwin32
winerror = e.winerror
@@ -353,19 +353,19 @@
except ValueError:
msg = 'Windows Error %d' % winerror
exc = space.w_WindowsError
- if filename is not None:
+ if w_filename is not None:
w_error = space.call_function(exc, space.wrap(winerror),
- space.wrap(msg), space.wrap(filename))
+ space.wrap(msg), w_filename)
else:
w_error = space.call_function(exc, space.wrap(winerror),
space.wrap(msg))
return OperationError(exc, w_error)
-def wrap_oserror(space, e, filename=None, exception_name='w_OSError'):
+def wrap_oserror2(space, e, w_filename=None, exception_name='w_OSError'):
assert isinstance(e, OSError)
if _WINDOWS and isinstance(e, WindowsError):
- return wrap_windowserror(space, e, filename)
+ return wrap_windowserror(space, e, w_filename)
errno = e.errno
try:
@@ -373,10 +373,21 @@
except ValueError:
msg = 'error %d' % errno
exc = getattr(space, exception_name)
- if filename is not None:
+ if w_filename is not None:
w_error = space.call_function(exc, space.wrap(errno),
- space.wrap(msg), space.wrap(filename))
+ space.wrap(msg), w_filename)
else:
- w_error = space.call_function(exc, space.wrap(errno), space.wrap(msg))
+ w_error = space.call_function(exc, space.wrap(errno),
+ space.wrap(msg))
return OperationError(exc, w_error)
+wrap_oserror2._annspecialcase_ = 'specialize:arg(3)'
+
+def wrap_oserror(space, e, filename=None, exception_name='w_OSError'):
+ if filename is not None:
+ return wrap_oserror2(space, e, space.wrap(filename),
+ exception_name=exception_name)
+ else:
+ return wrap_oserror2(space, e, None,
+ exception_name=exception_name)
wrap_oserror._annspecialcase_ = 'specialize:arg(3)'
+
Modified: pypy/branch/x86-64-jit-backend/pypy/interpreter/gateway.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/interpreter/gateway.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/interpreter/gateway.py Tue Jul 20 20:55:30 2010
@@ -137,9 +137,6 @@
def visit_c_nonnegint(self, el, app_sig):
self.checked_space_method(el, app_sig)
- def visit_path(self, el, app_sig):
- self.checked_space_method(el, app_sig)
-
def visit__Wrappable(self, el, app_sig):
name = el.__name__
argname = self.orig_arg()
@@ -241,9 +238,6 @@
def visit_bufferstr(self, typ):
self.run_args.append("space.bufferstr_w(%s)" % (self.scopenext(),))
- def visit_path(self, typ):
- self.run_args.append("space.path_w(%s)" % (self.scopenext(),))
-
def visit_nonnegint(self, typ):
self.run_args.append("space.nonnegint_w(%s)" % (self.scopenext(),))
@@ -371,9 +365,6 @@
def visit_bufferstr(self, typ):
self.unwrap.append("space.bufferstr_w(%s)" % (self.nextarg(),))
- def visit_path(self, typ):
- self.unwrap.append("space.path_w(%s)" % (self.nextarg(),))
-
def visit_nonnegint(self, typ):
self.unwrap.append("space.nonnegint_w(%s)" % (self.nextarg(),))
Modified: pypy/branch/x86-64-jit-backend/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/interpreter/pyopcode.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/interpreter/pyopcode.py Tue Jul 20 20:55:30 2010
@@ -14,6 +14,7 @@
from pypy.rlib import jit, rstackovf, rstack
from pypy.rlib.rarithmetic import r_uint, intmask
from pypy.rlib.unroll import unrolling_iterable
+from pypy.rlib.debug import check_nonneg
from pypy.tool.stdlib_opcode import (bytecode_spec, host_bytecode_spec,
unrolling_all_opcode_descs, opmap,
host_opmap)
@@ -186,7 +187,7 @@
lo = ord(co_code[next_instr])
hi = ord(co_code[next_instr+1])
next_instr += 2
- oparg = (hi << 8) | lo
+ oparg = (hi * 256) | lo
else:
oparg = 0
@@ -197,7 +198,7 @@
lo = ord(co_code[next_instr+1])
hi = ord(co_code[next_instr+2])
next_instr += 3
- oparg = (oparg << 16) | (hi << 8) | lo
+ oparg = (oparg * 65536) | (hi * 256) | lo
if opcode == self.opcodedesc.RETURN_VALUE.index:
w_returnvalue = self.popvalue()
@@ -210,10 +211,6 @@
next_instr = block.handle(self, unroller)
return next_instr # now inside a 'finally' block
- if opcode == self.opcodedesc.YIELD_VALUE.index:
- #self.last_instr = intmask(next_instr - 1) XXX clean up!
- raise Yield
-
if opcode == self.opcodedesc.END_FINALLY.index:
unroller = self.end_finally()
if isinstance(unroller, SuspendedUnroller):
@@ -238,7 +235,7 @@
if not opdesc.is_enabled(space):
continue
if opdesc.methodname in (
- 'EXTENDED_ARG', 'RETURN_VALUE', 'YIELD_VALUE',
+ 'EXTENDED_ARG', 'RETURN_VALUE',
'END_FINALLY', 'JUMP_ABSOLUTE'):
continue # opcodes implemented above
@@ -323,7 +320,9 @@
##
def NOP(self, oparg, next_instr):
- pass
+ # annotation-time check: if it fails, it means that the decoding
+ # of oparg failed to produce an integer which is annotated as non-neg
+ check_nonneg(oparg)
def LOAD_FAST(self, varindex, next_instr):
# access a local variable directly
@@ -811,6 +810,9 @@
self.space.str_w(w_name))
self.pushvalue(w_obj)
+ def YIELD_VALUE(self, oparg, next_instr):
+ raise Yield
+
def jump_absolute(self, jumpto, next_instr, ec):
return jumpto
Modified: pypy/branch/x86-64-jit-backend/pypy/interpreter/test/test_compiler.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/interpreter/test/test_compiler.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/interpreter/test/test_compiler.py Tue Jul 20 20:55:30 2010
@@ -838,6 +838,23 @@
sys.stdout = save_stdout
output = s.getvalue()
assert "STOP_CODE" not in output
+
+ def test_optimize_list_comp(self):
+ source = """def _f(a):
+ return [x for x in a if None]
+ """
+ exec source
+ code = _f.func_code
+
+ import StringIO, sys, dis
+ s = StringIO.StringIO()
+ sys.stdout = s
+ try:
+ dis.dis(code)
+ finally:
+ sys.stdout = sys.__stdout__
+ output = s.getvalue()
+ assert "LOAD_GLOBAL" not in output
class AppTestExceptions:
def test_indentation_error(self):
Modified: pypy/branch/x86-64-jit-backend/pypy/interpreter/test/test_gateway.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/interpreter/test/test_gateway.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/interpreter/test/test_gateway.py Tue Jul 20 20:55:30 2010
@@ -454,16 +454,6 @@
assert len(l) == 1
assert space.eq_w(l[0], w("foo"))
- def test_interp2app_unwrap_spec_path(self, monkeypatch):
- space = self.space
- def g(space, p):
- return p
-
- app_g = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, 'path'])
- w_app_g = space.wrap(app_g)
- monkeypatch.setattr(space.sys, "filesystemencoding", "utf-8")
- w_res = space.call_function(w_app_g, space.wrap(u"ą"))
-
def test_interp2app_classmethod(self):
space = self.space
w = space.wrap
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/llgraph/llimpl.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/llgraph/llimpl.py Tue Jul 20 20:55:30 2010
@@ -421,11 +421,9 @@
global _last_exception
assert _last_exception is None, "exception left behind"
verbose = True
- operations = self.loop.operations
- opindex = 0
+ self.opindex = 0
while True:
- self.opindex = opindex
- op = operations[opindex]
+ op = self.loop.operations[self.opindex]
args = [self.getenv(v) for v in op.args]
if not op.is_final():
try:
@@ -439,8 +437,8 @@
args = [self.getenv(v) for v in op.fail_args if v]
assert len(op.jump_target.inputargs) == len(args)
self.env = dict(zip(op.jump_target.inputargs, args))
- operations = op.jump_target.operations
- opindex = 0
+ self.loop = op.jump_target
+ self.opindex = 0
continue
else:
self._populate_fail_args(op)
@@ -465,14 +463,13 @@
raise Exception("op.result.concretetype is %r"
% (RESTYPE,))
self.env[op.result] = x
- opindex += 1
+ self.opindex += 1
continue
if op.opnum == rop.JUMP:
assert len(op.jump_target.inputargs) == len(args)
self.env = dict(zip(op.jump_target.inputargs, args))
self.loop = op.jump_target
- operations = self.loop.operations
- opindex = 0
+ self.opindex = 0
_stats.exec_jumps += 1
elif op.opnum == rop.FINISH:
if self.verbose:
@@ -1199,10 +1196,18 @@
array = array._obj.container
return cast_to_int(array.getitem(index))
+def do_getarrayitem_raw_int(array, index):
+ array = array.adr.ptr._obj
+ return cast_to_int(array.getitem(index))
+
def do_getarrayitem_gc_float(array, index):
array = array._obj.container
return cast_to_float(array.getitem(index))
+def do_getarrayitem_raw_float(array, index):
+ array = array.adr.ptr._obj
+ return cast_to_float(array.getitem(index))
+
def do_getarrayitem_gc_ptr(array, index):
array = array._obj.container
return cast_to_ptr(array.getitem(index))
@@ -1251,12 +1256,24 @@
newvalue = cast_from_int(ITEMTYPE, newvalue)
array.setitem(index, newvalue)
+def do_setarrayitem_raw_int(array, index, newvalue):
+ array = array.adr.ptr
+ ITEMTYPE = lltype.typeOf(array).TO.OF
+ newvalue = cast_from_int(ITEMTYPE, newvalue)
+ array._obj.setitem(index, newvalue)
+
def do_setarrayitem_gc_float(array, index, newvalue):
array = array._obj.container
ITEMTYPE = lltype.typeOf(array).OF
newvalue = cast_from_float(ITEMTYPE, newvalue)
array.setitem(index, newvalue)
+def do_setarrayitem_raw_float(array, index, newvalue):
+ array = array.adr.ptr
+ ITEMTYPE = lltype.typeOf(array).TO.OF
+ newvalue = cast_from_int(ITEMTYPE, newvalue)
+ array._obj.setitem(index, newvalue)
+
def do_setarrayitem_gc_ptr(array, index, newvalue):
array = array._obj.container
ITEMTYPE = lltype.typeOf(array).OF
@@ -1529,6 +1546,8 @@
setannotation(do_getarrayitem_gc_int, annmodel.SomeInteger())
setannotation(do_getarrayitem_gc_ptr, annmodel.SomePtr(llmemory.GCREF))
setannotation(do_getarrayitem_gc_float, annmodel.SomeFloat())
+setannotation(do_getarrayitem_raw_int, annmodel.SomeInteger())
+setannotation(do_getarrayitem_raw_float, annmodel.SomeFloat())
setannotation(do_getfield_gc_int, annmodel.SomeInteger())
setannotation(do_getfield_gc_ptr, annmodel.SomePtr(llmemory.GCREF))
setannotation(do_getfield_gc_float, annmodel.SomeFloat())
@@ -1540,6 +1559,8 @@
setannotation(do_setarrayitem_gc_int, annmodel.s_None)
setannotation(do_setarrayitem_gc_ptr, annmodel.s_None)
setannotation(do_setarrayitem_gc_float, annmodel.s_None)
+setannotation(do_setarrayitem_raw_int, annmodel.s_None)
+setannotation(do_setarrayitem_raw_float, annmodel.s_None)
setannotation(do_setfield_gc_int, annmodel.s_None)
setannotation(do_setfield_gc_ptr, annmodel.s_None)
setannotation(do_setfield_gc_float, annmodel.s_None)
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/llgraph/runner.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/llgraph/runner.py Tue Jul 20 20:55:30 2010
@@ -294,7 +294,6 @@
return llimpl.grab_exc_value()
def arraydescrof(self, A):
- assert isinstance(A, lltype.GcArray)
assert A.OF != lltype.Void
size = symbolic.get_size(A)
token = history.getkind(A.OF)
@@ -317,12 +316,18 @@
def bh_getarrayitem_gc_i(self, arraydescr, array, index):
assert isinstance(arraydescr, Descr)
return llimpl.do_getarrayitem_gc_int(array, index)
+ def bh_getarrayitem_raw_i(self, arraydescr, array, index):
+ assert isinstance(arraydescr, Descr)
+ return llimpl.do_getarrayitem_raw_int(array, index)
def bh_getarrayitem_gc_r(self, arraydescr, array, index):
assert isinstance(arraydescr, Descr)
return llimpl.do_getarrayitem_gc_ptr(array, index)
def bh_getarrayitem_gc_f(self, arraydescr, array, index):
assert isinstance(arraydescr, Descr)
return llimpl.do_getarrayitem_gc_float(array, index)
+ def bh_getarrayitem_raw_f(self, arraydescr, array, index):
+ assert isinstance(arraydescr, Descr)
+ return llimpl.do_getarrayitem_raw_float(array, index)
def bh_getfield_gc_i(self, struct, fielddescr):
assert isinstance(fielddescr, Descr)
@@ -372,6 +377,10 @@
assert isinstance(arraydescr, Descr)
llimpl.do_setarrayitem_gc_int(array, index, newvalue)
+ def bh_setarrayitem_raw_i(self, arraydescr, array, index, newvalue):
+ assert isinstance(arraydescr, Descr)
+ llimpl.do_setarrayitem_raw_int(array, index, newvalue)
+
def bh_setarrayitem_gc_r(self, arraydescr, array, index, newvalue):
assert isinstance(arraydescr, Descr)
llimpl.do_setarrayitem_gc_ptr(array, index, newvalue)
@@ -380,6 +389,10 @@
assert isinstance(arraydescr, Descr)
llimpl.do_setarrayitem_gc_float(array, index, newvalue)
+ def bh_setarrayitem_raw_f(self, arraydescr, array, index, newvalue):
+ assert isinstance(arraydescr, Descr)
+ llimpl.do_setarrayitem_raw_float(array, index, newvalue)
+
def bh_setfield_gc_i(self, struct, fielddescr, newvalue):
assert isinstance(fielddescr, Descr)
llimpl.do_setfield_gc_int(struct, fielddescr.ofs, newvalue)
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/descr.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/descr.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/descr.py Tue Jul 20 20:55:30 2010
@@ -23,10 +23,10 @@
self._cache_call = {}
def init_size_descr(self, STRUCT, sizedescr):
- pass
+ assert isinstance(STRUCT, lltype.GcStruct)
def init_array_descr(self, ARRAY, arraydescr):
- pass
+ assert isinstance(ARRAY, lltype.GcArray)
# ____________________________________________________________
@@ -67,9 +67,11 @@
class BaseFieldDescr(AbstractDescr):
offset = 0 # help translation
+ name = ''
_clsname = ''
- def __init__(self, offset):
+ def __init__(self, name, offset):
+ self.name = name
self.offset = offset
def sort_key(self):
@@ -88,7 +90,7 @@
return self._is_float_field
def repr_of_descr(self):
- return '<%s %s>' % (self._clsname, self.offset)
+ return '<%s %s %s>' % (self._clsname, self.name, self.offset)
class NonGcPtrFieldDescr(BaseFieldDescr):
@@ -113,7 +115,8 @@
offset, _ = symbolic.get_field_token(STRUCT, fieldname,
gccache.translate_support_code)
FIELDTYPE = getattr(STRUCT, fieldname)
- fielddescr = getFieldDescrClass(FIELDTYPE)(offset)
+ name = '%s.%s' % (STRUCT._name, fieldname)
+ fielddescr = getFieldDescrClass(FIELDTYPE)(name, offset)
cachedict = cache.setdefault(STRUCT, {})
cachedict[fieldname] = fielddescr
return fielddescr
@@ -151,7 +154,6 @@
def repr_of_descr(self):
return '<%s>' % self._clsname
-
class NonGcPtrArrayDescr(BaseArrayDescr):
_clsname = 'NonGcPtrArrayDescr'
def get_item_size(self, translate_support_code):
@@ -161,24 +163,53 @@
_clsname = 'GcPtrArrayDescr'
_is_array_of_pointers = True
+_CA = rffi.CArray(lltype.Signed)
+
+class BaseArrayNoLengthDescr(BaseArrayDescr):
+ def get_base_size(self, translate_support_code):
+ basesize, _, _ = symbolic.get_array_token(_CA, translate_support_code)
+ return basesize
+
+ def get_ofs_length(self, translate_support_code):
+ _, _, ofslength = symbolic.get_array_token(_CA, translate_support_code)
+ return ofslength
+
+class NonGcPtrArrayNoLengthDescr(BaseArrayNoLengthDescr):
+ _clsname = 'NonGcPtrArrayNoLengthDescr'
+ def get_item_size(self, translate_support_code):
+ return symbolic.get_size_of_ptr(translate_support_code)
+
+class GcPtrArrayNoLengthDescr(NonGcPtrArrayNoLengthDescr):
+ _clsname = 'GcPtrArrayNoLengthDescr'
+ _is_array_of_pointers = True
+
def getArrayDescrClass(ARRAY):
return getDescrClass(ARRAY.OF, BaseArrayDescr, GcPtrArrayDescr,
NonGcPtrArrayDescr, 'Array', 'get_item_size',
'_is_array_of_floats')
+def getArrayNoLengthDescrClass(ARRAY):
+ return getDescrClass(ARRAY.OF, BaseArrayNoLengthDescr, GcPtrArrayNoLengthDescr,
+ NonGcPtrArrayNoLengthDescr, 'ArrayNoLength', 'get_item_size',
+ '_is_array_of_floats')
+
def get_array_descr(gccache, ARRAY):
cache = gccache._cache_array
try:
return cache[ARRAY]
except KeyError:
- arraydescr = getArrayDescrClass(ARRAY)()
+ if ARRAY._hints.get('nolength', False):
+ arraydescr = getArrayNoLengthDescrClass(ARRAY)()
+ else:
+ arraydescr = getArrayDescrClass(ARRAY)()
# verify basic assumption that all arrays' basesize and ofslength
# are equal
basesize, itemsize, ofslength = symbolic.get_array_token(ARRAY, False)
assert basesize == arraydescr.get_base_size(False)
assert itemsize == arraydescr.get_item_size(False)
assert ofslength == arraydescr.get_ofs_length(False)
- gccache.init_array_descr(ARRAY, arraydescr)
+ if isinstance(ARRAY, lltype.GcArray):
+ gccache.init_array_descr(ARRAY, arraydescr)
cache[ARRAY] = arraydescr
return arraydescr
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/gc.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/gc.py Tue Jul 20 20:55:30 2010
@@ -351,7 +351,7 @@
gcrootmap = cls()
self.gcrootmap = gcrootmap
self.gcrefs = GcRefList()
- self.single_gcref_descr = GcPtrFieldDescr(0)
+ self.single_gcref_descr = GcPtrFieldDescr('', 0)
# make a TransformerLayoutBuilder and save it on the translator
# where it can be fished and reused by the FrameworkGCTransformer
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/llmodel.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/llmodel.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/llmodel.py Tue Jul 20 20:55:30 2010
@@ -250,6 +250,7 @@
ofs = arraydescr.get_ofs_length(self.translate_support_code)
return rffi.cast(rffi.CArrayPtr(lltype.Signed), array)[ofs/WORD]
+ @specialize.argtype(2)
def bh_getarrayitem_gc_i(self, arraydescr, gcref, itemindex):
ofs, size = self.unpack_arraydescr_size(arraydescr)
# --- start of GC unsafe code (no GC operation!) ---
@@ -272,6 +273,7 @@
# --- end of GC unsafe code ---
return pval
+ @specialize.argtype(2)
def bh_getarrayitem_gc_f(self, arraydescr, gcref, itemindex):
ofs = self.unpack_arraydescr(arraydescr)
# --- start of GC unsafe code (no GC operation!) ---
@@ -281,6 +283,7 @@
# --- end of GC unsafe code ---
return fval
+ @specialize.argtype(2)
def bh_setarrayitem_gc_i(self, arraydescr, gcref, itemindex, newvalue):
ofs, size = self.unpack_arraydescr_size(arraydescr)
# --- start of GC unsafe code (no GC operation!) ---
@@ -303,6 +306,7 @@
items[itemindex] = self.cast_gcref_to_int(newvalue)
# --- end of GC unsafe code ---
+ @specialize.argtype(2)
def bh_setarrayitem_gc_f(self, arraydescr, gcref, itemindex, newvalue):
ofs = self.unpack_arraydescr(arraydescr)
# --- start of GC unsafe code (no GC operation!) ---
@@ -311,6 +315,12 @@
items[itemindex] = newvalue
# --- end of GC unsafe code ---
+ bh_setarrayitem_raw_i = bh_setarrayitem_gc_i
+ bh_setarrayitem_raw_f = bh_setarrayitem_gc_f
+
+ bh_getarrayitem_raw_i = bh_getarrayitem_gc_i
+ bh_getarrayitem_raw_f = bh_getarrayitem_gc_f
+
def bh_strlen(self, string):
s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string)
return len(s.chars)
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/support.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/support.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/support.py Tue Jul 20 20:55:30 2010
@@ -30,7 +30,13 @@
funcobj = get_funcobj(fnptr)
if hasattr(funcobj, 'graph'):
- llinterp = LLInterpreter(rtyper) #, exc_data_ptr=exc_data_ptr)
+ # cache the llinterp; otherwise the remember_malloc/remember_free
+ # done on the LLInterpreter don't match
+ try:
+ llinterp = rtyper._on_top_of_llinterp_llinterp
+ except AttributeError:
+ llinterp = LLInterpreter(rtyper) #, exc_data_ptr=exc_data_ptr)
+ rtyper._on_top_of_llinterp_llinterp = llinterp
def on_top_of_llinterp(*args):
real_args = process_args(args)
return llinterp.eval_graph(funcobj.graph, real_args)
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/symbolic.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/symbolic.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/symbolic.py Tue Jul 20 20:55:30 2010
@@ -36,8 +36,11 @@
ofs_length = (llmemory.offsetof(T, T._arrayfld) +
llmemory.ArrayLengthOffset(SUBARRAY))
else:
+ if T._hints.get('nolength', None):
+ ofs_length = -1
+ else:
+ ofs_length = llmemory.ArrayLengthOffset(T)
itemsize = llmemory.sizeof(T.OF)
- ofs_length = llmemory.ArrayLengthOffset(T)
else:
if isinstance(T, lltype.Struct):
assert T._arrayfld is not None, "%r is not variable-sized" % (T,)
@@ -48,8 +51,11 @@
else:
before_array_part = 0
carray = ll2ctypes.get_ctypes_type(T)
- assert carray.length.size == WORD
- ofs_length = before_array_part + carray.length.offset
+ if T._hints.get('nolength', None):
+ ofs_length = -1
+ else:
+ assert carray.length.size == WORD
+ ofs_length = before_array_part + carray.length.offset
basesize = before_array_part + carray.items.offset
carrayitem = ll2ctypes.get_ctypes_type(T.OF)
itemsize = ctypes.sizeof(carrayitem)
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/test/test_descr.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/test/test_descr.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/test/test_descr.py Tue Jul 20 20:55:30 2010
@@ -53,6 +53,10 @@
assert descr_y.__class__ is GcPtrFieldDescr
assert descr_z.__class__ is NonGcPtrFieldDescr
assert descr_f.__class__ is clsf
+ assert descr_x.name == 'S.x'
+ assert descr_y.name == 'S.y'
+ assert descr_z.name == 'S.z'
+ assert descr_f.name == 'S.f'
if not tsc:
assert descr_x.offset < descr_y.offset < descr_z.offset
assert descr_x.sort_key() < descr_y.sort_key() < descr_z.sort_key()
@@ -140,7 +144,25 @@
assert isinstance(descr2.get_item_size(True), Symbolic)
assert isinstance(descr3.get_item_size(True), Symbolic)
assert isinstance(descr4.get_item_size(True), Symbolic)
-
+ CA = rffi.CArray(lltype.Signed)
+ descr = get_array_descr(c0, CA)
+ assert not descr.is_array_of_floats()
+ assert descr.get_base_size(False) == 0
+ assert descr.get_ofs_length(False) == -1
+ CA = rffi.CArray(lltype.Ptr(lltype.GcStruct('S')))
+ descr = get_array_descr(c0, CA)
+ assert descr.is_array_of_pointers()
+ assert descr.get_base_size(False) == 0
+ assert descr.get_ofs_length(False) == -1
+ CA = rffi.CArray(lltype.Ptr(lltype.Struct('S')))
+ descr = get_array_descr(c0, CA)
+ assert descr.get_base_size(False) == 0
+ assert descr.get_ofs_length(False) == -1
+ CA = rffi.CArray(lltype.Float)
+ descr = get_array_descr(c0, CA)
+ assert descr.is_array_of_floats()
+ assert descr.get_base_size(False) == 0
+ assert descr.get_ofs_length(False) == -1
def test_get_call_descr_not_translated():
c0 = GcCache(False)
@@ -210,11 +232,11 @@
#
descr2 = get_field_descr(c0, S, 'y')
o, _ = symbolic.get_field_token(S, 'y', False)
- assert descr2.repr_of_descr() == '<GcPtrFieldDescr %d>' % o
+ assert descr2.repr_of_descr() == '<GcPtrFieldDescr S.y %d>' % o
#
descr2i = get_field_descr(c0, S, 'x')
o, _ = symbolic.get_field_token(S, 'x', False)
- assert descr2i.repr_of_descr() == '<CharFieldDescr %d>' % o
+ assert descr2i.repr_of_descr() == '<CharFieldDescr S.x %d>' % o
#
descr3 = get_array_descr(c0, lltype.GcArray(lltype.Ptr(S)))
assert descr3.repr_of_descr() == '<GcPtrArrayDescr>'
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/test/test_symbolic.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/test/test_symbolic.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/llsupport/test/test_symbolic.py Tue Jul 20 20:55:30 2010
@@ -61,6 +61,12 @@
assert basesize >= WORD # at least the 'length', maybe some gc headers
assert itemsize == WORD
assert ofs_length == basesize - WORD
+ A = rffi.CArray(lltype.Signed)
+ arraytok = get_array_token(A, translate_support_code)
+ basesize, itemsize, ofs_length = convert(arraytok)
+ assert basesize == 0
+ assert itemsize == WORD
+ assert ofs_length == -1
def test_varsized_struct_size():
S1 = lltype.GcStruct('S1', ('parent', S),
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py Tue Jul 20 20:55:30 2010
@@ -1004,6 +1004,7 @@
raise NotImplementedError()
genop_getarrayitem_gc_pure = genop_getarrayitem_gc
+ genop_getarrayitem_raw = genop_getarrayitem_gc
def genop_discard_setfield_gc(self, op, arglocs):
base_loc, ofs_loc, size_loc, value_loc = arglocs
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/regalloc.py Tue Jul 20 20:55:30 2010
@@ -881,6 +881,7 @@
result_loc = self.force_allocate_reg(op.result)
self.Perform(op, [base_loc, ofs_loc, imm(scale), imm(ofs)], result_loc)
+ consider_getarrayitem_raw = consider_getarrayitem_gc
consider_getarrayitem_gc_pure = consider_getarrayitem_gc
def consider_int_is_true(self, op, guard_op):
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_gc_integration.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_gc_integration.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_gc_integration.py Tue Jul 20 20:55:30 2010
@@ -53,7 +53,7 @@
def initialize(self):
self.gcrefs = GcRefList()
self.gcrefs.initialize()
- self.single_gcref_descr = GcPtrFieldDescr(0)
+ self.single_gcref_descr = GcPtrFieldDescr('', 0)
rewrite_assembler = GcLLDescr_framework.rewrite_assembler.im_func
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/codewriter.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/codewriter.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/codewriter.py Tue Jul 20 20:55:30 2010
@@ -14,11 +14,12 @@
class CodeWriter(object):
callcontrol = None # for tests
- def __init__(self, cpu=None, jitdrivers_sd=[]):
+ def __init__(self, cpu=None, jitdrivers_sd=[], debug=False):
self.cpu = cpu
self.assembler = Assembler()
self.callcontrol = CallControl(cpu, jitdrivers_sd)
self._seen_files = set()
+ self.debug = debug
def transform_func_to_jitcode(self, func, values, type_system='lltype'):
"""For testing."""
@@ -60,7 +61,8 @@
self.assembler.assemble(ssarepr, jitcode)
#
# print the resulting assembler
- self.print_ssa_repr(ssarepr, portal_jd, verbose)
+ if self.debug:
+ self.print_ssa_repr(ssarepr, portal_jd, verbose)
def make_jitcodes(self, verbose=False):
log.info("making JitCodes...")
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/jtransform.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/jtransform.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/jtransform.py Tue Jul 20 20:55:30 2010
@@ -420,9 +420,14 @@
return SpaceOperation('new_array', [arraydescr, op.args[2]],
op.result)
+ def rewrite_op_free(self, op):
+ assert op.args[1].value == 'raw'
+ ARRAY = op.args[0].concretetype.TO
+ return self._do_builtin_call(op, 'raw_free', [op.args[0]],
+ extra = (ARRAY,), extrakey = ARRAY)
+
def rewrite_op_getarrayitem(self, op):
ARRAY = op.args[0].concretetype.TO
- assert ARRAY._gckind == 'gc'
if self._array_of_voids(ARRAY):
return []
if op.args[0] in self.vable_array_vars: # for virtualizables
@@ -436,13 +441,12 @@
# normal case follows
arraydescr = self.cpu.arraydescrof(ARRAY)
kind = getkind(op.result.concretetype)
- return SpaceOperation('getarrayitem_gc_%s' % kind[0],
+ return SpaceOperation('getarrayitem_%s_%s' % (ARRAY._gckind, kind[0]),
[op.args[0], arraydescr, op.args[1]],
op.result)
def rewrite_op_setarrayitem(self, op):
ARRAY = op.args[0].concretetype.TO
- assert ARRAY._gckind == 'gc'
if self._array_of_voids(ARRAY):
return []
if op.args[0] in self.vable_array_vars: # for virtualizables
@@ -455,7 +459,7 @@
op.args[1], op.args[2]], None)]
arraydescr = self.cpu.arraydescrof(ARRAY)
kind = getkind(op.args[2].concretetype)
- return SpaceOperation('setarrayitem_gc_%s' % kind[0],
+ return SpaceOperation('setarrayitem_%s_%s' % (ARRAY._gckind, kind[0]),
[op.args[0], arraydescr, op.args[1], op.args[2]],
None)
@@ -663,7 +667,7 @@
return self._rewrite_symmetric(op)
def _is_gc(self, v):
- return v.concretetype.TO._gckind == 'gc'
+ return getattr(getattr(v.concretetype, "TO", None), "_gckind", "?") == 'gc'
def _rewrite_cmp_ptrs(self, op):
if self._is_gc(op.args[0]):
@@ -697,6 +701,42 @@
#return op
raise NotImplementedError("cast_ptr_to_int")
+ def rewrite_op_force_cast(self, op):
+ from pypy.rpython.lltypesystem.rffi import size_and_sign, sizeof
+ from pypy.rlib.rarithmetic import intmask
+ assert not self._is_gc(op.args[0])
+ size1, unsigned1 = size_and_sign(op.args[0].concretetype)
+ size2, unsigned2 = size_and_sign(op.result.concretetype)
+ if size2 >= sizeof(lltype.Signed):
+ return # the target type is LONG or ULONG
+ #
+ def bounds(size, unsigned):
+ if unsigned:
+ return 0, 1<<(8*size)
+ else:
+ return -(1<<(8*size-1)), 1<<(8*size-1)
+ min1, max1 = bounds(size1, unsigned1)
+ min2, max2 = bounds(size2, unsigned2)
+ if min2 <= min1 <= max1 <= max2:
+ return # the target type includes the source range
+ #
+ result = []
+ v1 = op.args[0]
+ if min2:
+ c_min2 = Constant(min2, lltype.Signed)
+ v2 = Variable(); v2.concretetype = lltype.Signed
+ result.append(SpaceOperation('int_sub', [v1, c_min2], v2))
+ else:
+ v2 = v1
+ c_mask = Constant(int((1<<(8*size2))-1), lltype.Signed)
+ v3 = Variable(); v3.concretetype = lltype.Signed
+ result.append(SpaceOperation('int_and', [v2, c_mask], v3))
+ if min2:
+ result.append(SpaceOperation('int_add', [v3, c_min2], op.result))
+ else:
+ result[-1].result = op.result
+ return result
+
# ----------
# Renames, from the _old opname to the _new one.
# The new operation is optionally further processed by rewrite_operation().
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/support.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/support.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/support.py Tue Jul 20 20:55:30 2010
@@ -297,6 +297,11 @@
return lltype.malloc(ARRAY, n, flavor='raw')
return _ll_1_raw_malloc
+ def build_ll_1_raw_free(ARRAY):
+ def _ll_1_raw_free(p):
+ lltype.free(p, flavor='raw')
+ return _ll_1_raw_free
+
class OOtypeHelpers:
# ---------- dict ----------
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/test/test_codewriter.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/test/test_codewriter.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/test/test_codewriter.py Tue Jul 20 20:55:30 2010
@@ -24,12 +24,17 @@
def as_vtable_size_descr(self):
return self
+class FakeArrayDescr(AbstractDescr):
+ def __init__(self, ARRAY):
+ self.ARRAY = ARRAY
+
class FakeCPU:
def __init__(self, rtyper):
self.rtyper = rtyper
calldescrof = FakeCallDescr
fielddescrof = FakeFieldDescr
sizeof = FakeSizeDescr
+ arraydescrof = FakeArrayDescr
class FakePolicy:
def look_inside_graph(self, graph):
@@ -163,10 +168,10 @@
def f(n):
a = lltype.malloc(TP, n, flavor='raw')
- #a[0] = n
- #res = a[0]
- #lltype.free(a, flavor='raw')
- #return res
+ a[0] = n
+ res = a[0]
+ lltype.free(a, flavor='raw')
+ return res
rtyper = support.annotate(f, [35])
jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
@@ -176,3 +181,6 @@
#
s = jitdriver_sd.mainjitcode.dump()
assert 'residual_call_ir_i $<* fn _ll_1_raw_malloc__Signed>' in s
+ assert 'setarrayitem_raw_i' in s
+ assert 'getarrayitem_raw_i' in s
+ assert 'residual_call_ir_v $<* fn _ll_1_raw_free__arrayPtr>' in s
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/test/test_flatten.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/test/test_flatten.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/codewriter/test/test_flatten.py Tue Jul 20 20:55:30 2010
@@ -729,3 +729,108 @@
int_between %i0, %i1, %i2 -> %i3
int_return %i3
""", transform=True)
+
+ def test_force_cast(self):
+ from pypy.rpython.lltypesystem import rffi
+
+ for FROM, TO, expected in [
+ (rffi.SIGNEDCHAR, rffi.SIGNEDCHAR, ""),
+ (rffi.SIGNEDCHAR, rffi.UCHAR, "int_and %i0, $255 -> %i1"),
+ (rffi.SIGNEDCHAR, rffi.SHORT, ""),
+ (rffi.SIGNEDCHAR, rffi.USHORT, "int_and %i0, $65535 -> %i1"),
+ (rffi.SIGNEDCHAR, rffi.LONG, ""),
+ (rffi.SIGNEDCHAR, rffi.ULONG, ""),
+
+ (rffi.UCHAR, rffi.SIGNEDCHAR, """int_sub %i0, $-128 -> %i1
+ int_and %i1, $255 -> %i2
+ int_add %i2, $-128 -> %i3"""),
+ (rffi.UCHAR, rffi.UCHAR, ""),
+ (rffi.UCHAR, rffi.SHORT, ""),
+ (rffi.UCHAR, rffi.USHORT, ""),
+ (rffi.UCHAR, rffi.LONG, ""),
+ (rffi.UCHAR, rffi.ULONG, ""),
+
+ (rffi.SHORT, rffi.SIGNEDCHAR, """int_sub %i0, $-128 -> %i1
+ int_and %i1, $255 -> %i2
+ int_add %i2, $-128 -> %i3"""),
+ (rffi.SHORT, rffi.UCHAR, "int_and %i0, $255 -> %i1"),
+ (rffi.SHORT, rffi.SHORT, ""),
+ (rffi.SHORT, rffi.USHORT, "int_and %i0, $65535 -> %i1"),
+ (rffi.SHORT, rffi.LONG, ""),
+ (rffi.SHORT, rffi.ULONG, ""),
+
+ (rffi.USHORT, rffi.SIGNEDCHAR, """int_sub %i0, $-128 -> %i1
+ int_and %i1, $255 -> %i2
+ int_add %i2, $-128 -> %i3"""),
+ (rffi.USHORT, rffi.UCHAR, "int_and %i0, $255 -> %i1"),
+ (rffi.USHORT, rffi.SHORT, """int_sub %i0, $-32768 -> %i1
+ int_and %i1, $65535 -> %i2
+ int_add %i2, $-32768 -> %i3"""),
+ (rffi.USHORT, rffi.USHORT, ""),
+ (rffi.USHORT, rffi.LONG, ""),
+ (rffi.USHORT, rffi.ULONG, ""),
+
+ (rffi.LONG, rffi.SIGNEDCHAR, """int_sub %i0, $-128 -> %i1
+ int_and %i1, $255 -> %i2
+ int_add %i2, $-128 -> %i3"""),
+ (rffi.LONG, rffi.UCHAR, "int_and %i0, $255 -> %i1"),
+ (rffi.LONG, rffi.SHORT, """int_sub %i0, $-32768 -> %i1
+ int_and %i1, $65535 -> %i2
+ int_add %i2, $-32768 -> %i3"""),
+ (rffi.LONG, rffi.USHORT, "int_and %i0, $65535 -> %i1"),
+ (rffi.LONG, rffi.LONG, ""),
+ (rffi.LONG, rffi.ULONG, ""),
+
+ (rffi.ULONG, rffi.SIGNEDCHAR, """int_sub %i0, $-128 -> %i1
+ int_and %i1, $255 -> %i2
+ int_add %i2, $-128 -> %i3"""),
+ (rffi.ULONG, rffi.UCHAR, "int_and %i0, $255 -> %i1"),
+ (rffi.ULONG, rffi.SHORT, """int_sub %i0, $-32768 -> %i1
+ int_and %i1, $65535 -> %i2
+ int_add %i2, $-32768 -> %i3"""),
+ (rffi.ULONG, rffi.USHORT, "int_and %i0, $65535 -> %i1"),
+ (rffi.ULONG, rffi.LONG, ""),
+ (rffi.ULONG, rffi.ULONG, ""),
+ ]:
+ expected = [s.strip() for s in expected.splitlines()]
+ check_force_cast(FROM, TO, expected, 42)
+ check_force_cast(FROM, TO, expected, -42)
+ expected.append('int_return %i' + str(len(expected)))
+ expected = '\n'.join(expected)
+ #
+ def f(n):
+ return rffi.cast(TO, n)
+ self.encoding_test(f, [rffi.cast(FROM, 42)], expected,
+ transform=True)
+
+ def test_force_cast_pointer(self):
+ from pypy.rpython.lltypesystem import rffi
+ def h(p):
+ return rffi.cast(rffi.VOIDP, p)
+ self.encoding_test(h, [lltype.nullptr(rffi.CCHARP.TO)], """
+ int_return %i0
+ """, transform=True)
+
+
+def check_force_cast(FROM, TO, operations, value):
+ """Check that the test is correctly written..."""
+ from pypy.rpython.lltypesystem import rffi
+ import re
+ r = re.compile('(\w+) \%i\d, \$(-?\d+)')
+ #
+ value = rffi.cast(FROM, value)
+ value = rffi.cast(lltype.Signed, value)
+ #
+ expected_value = rffi.cast(TO, value)
+ expected_value = rffi.cast(lltype.Signed, expected_value)
+ #
+ for op in operations:
+ match = r.match(op)
+ assert match, "line %r does not match regexp" % (op,)
+ opname = match.group(1)
+ if opname == 'int_add': value += int(match.group(2))
+ elif opname == 'int_sub': value -= int(match.group(2))
+ elif opname == 'int_and': value &= int(match.group(2))
+ else: assert 0, opname
+ #
+ assert rffi.cast(lltype.Signed, value) == expected_value
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/blackhole.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/blackhole.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/blackhole.py Tue Jul 20 20:55:30 2010
@@ -990,6 +990,13 @@
bhimpl_getarrayitem_gc_pure_r = bhimpl_getarrayitem_gc_r
bhimpl_getarrayitem_gc_pure_f = bhimpl_getarrayitem_gc_f
+ @arguments("cpu", "i", "d", "i", returns="i")
+ def bhimpl_getarrayitem_raw_i(cpu, array, arraydescr, index):
+ return cpu.bh_getarrayitem_raw_i(arraydescr, array, index)
+ @arguments("cpu", "i", "d", "i", returns="f")
+ def bhimpl_getarrayitem_raw_f(cpu, array, arraydescr, index):
+ return cpu.bh_getarrayitem_raw_f(arraydescr, array, index)
+
@arguments("cpu", "r", "d", "i", "i")
def bhimpl_setarrayitem_gc_i(cpu, array, arraydescr, index, newvalue):
cpu.bh_setarrayitem_gc_i(arraydescr, array, index, newvalue)
@@ -1000,6 +1007,15 @@
def bhimpl_setarrayitem_gc_f(cpu, array, arraydescr, index, newvalue):
cpu.bh_setarrayitem_gc_f(arraydescr, array, index, newvalue)
+ @arguments("cpu", "i", "d", "i", "i")
+ def bhimpl_setarrayitem_raw_i(cpu, array, arraydescr, index, newvalue):
+ cpu.bh_setarrayitem_raw_i(arraydescr, array, index, newvalue)
+ @arguments("cpu", "i", "d", "i", "f")
+ def bhimpl_setarrayitem_raw_f(cpu, array, arraydescr, index, newvalue):
+ cpu.bh_setarrayitem_raw_f(arraydescr, array, index, newvalue)
+
+ # note, there is no 'r' here, since it can't happen
+
@arguments("cpu", "r", "d", returns="i")
def bhimpl_arraylen_gc(cpu, array, arraydescr):
return cpu.bh_arraylen_gc(arraydescr, array)
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/executor.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/executor.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/executor.py Tue Jul 20 20:55:30 2010
@@ -90,6 +90,15 @@
else:
return BoxInt(cpu.bh_getarrayitem_gc_i(arraydescr, array, index))
+def do_getarrayitem_raw(cpu, _, arraybox, indexbox, arraydescr):
+ array = arraybox.getref_base()
+ index = indexbox.getint()
+ assert not arraydescr.is_array_of_pointers()
+ if arraydescr.is_array_of_floats():
+ return BoxFloat(cpu.bh_getarrayitem_raw_f(arraydescr, array, index))
+ else:
+ return BoxInt(cpu.bh_getarrayitem_raw_i(arraydescr, array, index))
+
def do_setarrayitem_gc(cpu, _, arraybox, indexbox, itembox, arraydescr):
array = arraybox.getref_base()
index = indexbox.getint()
@@ -101,6 +110,15 @@
else:
cpu.bh_setarrayitem_gc_i(arraydescr, array, index, itembox.getint())
+def do_setarrayitem_raw(cpu, _, arraybox, indexbox, itembox, arraydescr):
+ array = arraybox.getint()
+ index = indexbox.getint()
+ assert not arraydescr.is_array_of_pointers()
+ if arraydescr.is_array_of_floats():
+ cpu.bh_setarrayitem_raw_f(arraydescr, array, index, itembox.getfloat())
+ else:
+ cpu.bh_setarrayitem_raw_i(arraydescr, array, index, itembox.getint())
+
def do_getfield_gc(cpu, _, structbox, fielddescr):
struct = structbox.getref_base()
if fielddescr.is_pointer_field():
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/optimizeopt.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/optimizeopt.py Tue Jul 20 20:55:30 2010
@@ -18,6 +18,7 @@
from pypy.rpython.lltypesystem import lltype
from pypy.jit.metainterp.history import AbstractDescr, make_hashable_int
+
def optimize_loop_1(metainterp_sd, loop):
"""Optimize loop.operations to make it match the input of loop.specnodes
and to remove internal overheadish operations. Note that loop.specnodes
@@ -992,6 +993,14 @@
self.make_equal_to(op.result, v1)
else:
self.optimize_default(op)
+
+ def optimize_INT_SUB(self, op):
+ v1 = self.getvalue(op.args[0])
+ v2 = self.getvalue(op.args[1])
+ if v2.is_constant() and v2.box.getint() == 0:
+ self.make_equal_to(op.result, v1)
+ else:
+ return self.optimize_default(op)
optimize_ops = _findall(Optimizer, 'optimize_')
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/pyjitpl.py Tue Jul 20 20:55:30 2010
@@ -378,6 +378,14 @@
opimpl_getarrayitem_gc_f = _opimpl_getarrayitem_gc_any
@arguments("box", "descr", "box")
+ def _opimpl_getarrayitem_raw_any(self, arraybox, arraydescr, indexbox):
+ return self.execute_with_descr(rop.GETARRAYITEM_RAW,
+ arraydescr, arraybox, indexbox)
+
+ opimpl_getarrayitem_raw_i = _opimpl_getarrayitem_raw_any
+ opimpl_getarrayitem_raw_f = _opimpl_getarrayitem_raw_any
+
+ @arguments("box", "descr", "box")
def _opimpl_getarrayitem_gc_pure_any(self, arraybox, arraydescr, indexbox):
return self.execute_with_descr(rop.GETARRAYITEM_GC_PURE,
arraydescr, arraybox, indexbox)
@@ -396,6 +404,15 @@
opimpl_setarrayitem_gc_r = _opimpl_setarrayitem_gc_any
opimpl_setarrayitem_gc_f = _opimpl_setarrayitem_gc_any
+ @arguments("box", "descr", "box", "box")
+ def _opimpl_setarrayitem_raw_any(self, arraybox, arraydescr,
+ indexbox, itembox):
+ self.execute_with_descr(rop.SETARRAYITEM_RAW, arraydescr, arraybox,
+ indexbox, itembox)
+
+ opimpl_setarrayitem_raw_i = _opimpl_setarrayitem_raw_any
+ opimpl_setarrayitem_raw_f = _opimpl_setarrayitem_raw_any
+
@arguments("box", "descr")
def opimpl_arraylen_gc(self, arraybox, arraydescr):
return self.execute_with_descr(rop.ARRAYLEN_GC, arraydescr, arraybox)
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/resoperation.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/resoperation.py Tue Jul 20 20:55:30 2010
@@ -199,6 +199,7 @@
'_ALWAYS_PURE_LAST', # ----- end of always_pure operations -----
'GETARRAYITEM_GC/2d',
+ 'GETARRAYITEM_RAW/2d',
'GETFIELD_GC/1d',
'GETFIELD_RAW/1d',
'NEW/0d',
@@ -209,7 +210,7 @@
'_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations -----
'SETARRAYITEM_GC/3d',
- 'SETARRAYITEM_RAW/3d',#only added by backend.llsupport.gc.rewrite_assembler
+ 'SETARRAYITEM_RAW/3d',
'SETFIELD_GC/2d',
'SETFIELD_RAW/2d',
'ARRAYCOPY/7d', # removed before it's passed to the backend
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_basic.py Tue Jul 20 20:55:30 2010
@@ -1562,6 +1562,35 @@
res = self.interp_operations(f, [3, 2])
assert res == 1
+ def test_raw_malloc_and_access(self):
+ from pypy.rpython.lltypesystem import rffi
+
+ TP = rffi.CArray(lltype.Signed)
+
+ def f(n):
+ a = lltype.malloc(TP, n, flavor='raw')
+ a[0] = n
+ res = a[0]
+ lltype.free(a, flavor='raw')
+ return res
+
+ res = self.interp_operations(f, [10])
+ assert res == 10
+
+ def test_raw_malloc_and_access_float(self):
+ from pypy.rpython.lltypesystem import rffi
+
+ TP = rffi.CArray(lltype.Float)
+
+ def f(n, f):
+ a = lltype.malloc(TP, n, flavor='raw')
+ a[0] = f
+ res = a[0]
+ lltype.free(a, flavor='raw')
+ return res
+
+ res = self.interp_operations(f, [10, 3.5])
+ assert res == 3.5
class TestOOtype(BasicTests, OOJitMixin):
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_optimizeopt.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_optimizeopt.py Tue Jul 20 20:55:30 2010
@@ -2051,8 +2051,19 @@
jump(i1, i0)
"""
self.optimize_loop(ops, 'Not, Not', expected)
-
-
+
+ def test_fold_partially_constant_ops(self):
+ ops = """
+ [i0]
+ i1 = int_sub(i0, 0)
+ jump(i1)
+ """
+ expected = """
+ [i0]
+ jump(i0)
+ """
+ self.optimize_loop(ops, 'Not', expected)
+
# ----------
def make_fail_descr(self):
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_recursive.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_recursive.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/metainterp/test/test_recursive.py Tue Jul 20 20:55:30 2010
@@ -523,7 +523,7 @@
def test_trace_from_start(self):
def p(pc, code):
code = hlstr(code)
- return "%s %d %s" % (code, pc, code[pc])
+ return "'%s' at %d: %s" % (code, pc, code[pc])
def c(pc, code):
return "l" not in hlstr(code)
myjitdriver = JitDriver(greens=['pc', 'code'], reds=['n'],
@@ -537,9 +537,9 @@
op = code[pc]
if op == "+":
n += 7
- if op == "-":
+ elif op == "-":
n -= 1
- if op == "c":
+ elif op == "c":
n = f('---', n)
elif op == "l":
if n > 0:
@@ -556,6 +556,7 @@
result = 0
for i in range(m):
result += f('+-cl--', i)
+ g(50)
self.meta_interp(g, [50], backendopt=True)
self.check_tree_loop_count(3)
self.check_history(int_add=1)
Modified: pypy/branch/x86-64-jit-backend/pypy/module/_file/interp_file.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/module/_file/interp_file.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/module/_file/interp_file.py Tue Jul 20 20:55:30 2010
@@ -4,6 +4,7 @@
from pypy.rlib.rarithmetic import r_longlong
from pypy.module._file.interp_stream import W_AbstractStream
from pypy.module._file.interp_stream import StreamErrors, wrap_streamerror
+from pypy.module.posix.interp_posix import dispatch_filename
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments
from pypy.interpreter.typedef import TypeDef, GetSetProperty
@@ -81,11 +82,11 @@
# file lock. They don't convert StreamErrors to OperationErrors, too.
def direct___init__(self, w_name, mode='r', buffering=-1):
- name = self.space.str_w(w_name)
self.direct_close()
self.w_name = w_name
self.check_mode_ok(mode)
- stream = streamio.open_file_as_stream(name, mode, buffering)
+ stream = dispatch_filename(streamio.open_file_as_stream)(
+ self.space, w_name, mode, buffering)
fd = stream.try_to_find_file_descriptor()
self.fdopenstream(stream, fd, mode)
Modified: pypy/branch/x86-64-jit-backend/pypy/module/_file/test/test_file.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/module/_file/test/test_file.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/module/_file/test/test_file.py Tue Jul 20 20:55:30 2010
@@ -125,6 +125,15 @@
assert type(res) is str
f.close()
+ def test_unicode_filename(self):
+ import sys
+ try:
+ u'\xe9'.encode(sys.getfilesystemencoding())
+ except UnicodeEncodeError:
+ skip("encoding not good enough")
+ f = self.file(self.temppath + u'\xe9', "w")
+ f.close()
+
def test_oserror_has_filename(self):
try:
f = self.file("file that is clearly not there")
Modified: pypy/branch/x86-64-jit-backend/pypy/module/_locale/interp_locale.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/module/_locale/interp_locale.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/module/_locale/interp_locale.py Tue Jul 20 20:55:30 2010
@@ -132,7 +132,13 @@
space.is_true(space.isinstance(w_s2, space.w_str)):
s1, s2 = space.str_w(w_s1), space.str_w(w_s2)
- return space.wrap(_strcoll(rffi.str2charp(s1), rffi.str2charp(s2)))
+ s1_c = rffi.str2charp(s1)
+ s2_c = rffi.str2charp(s2)
+ try:
+ return space.wrap(_strcoll(s1_c, s2_c))
+ finally:
+ rffi.free_charp(s1_c)
+ rffi.free_charp(s2_c)
#if not space.is_true(space.isinstance(w_s1, space.w_unicode)) and \
# not space.is_true(space.isinstance(w_s2, space.w_unicode)):
@@ -143,7 +149,12 @@
s1_c = rffi.unicode2wcharp(s1)
s2_c = rffi.unicode2wcharp(s2)
- result = _wcscoll(s1_c, s2_c)
+ try:
+ result = _wcscoll(s1_c, s2_c)
+ finally:
+ rffi.free_wcharp(s1_c)
+ rffi.free_wcharp(s2_c)
+
return space.wrap(result)
strcoll.unwrap_spec = [ObjSpace, W_Root, W_Root]
@@ -156,13 +167,21 @@
n1 = len(s) + 1
buf = lltype.malloc(rffi.CCHARP.TO, n1, flavor="raw", zero=True)
- n2 = _strxfrm(buf, rffi.str2charp(s), n1) + 1
+ s_c = rffi.str2charp(s)
+ try:
+ n2 = _strxfrm(buf, s_c, n1) + 1
+ finally:
+ rffi.free_charp(s_c)
if n2 > n1:
# more space needed
lltype.free(buf, flavor="raw")
buf = lltype.malloc(rffi.CCHARP.TO, intmask(n2),
flavor="raw", zero=True)
- _strxfrm(buf, rffi.str2charp(s), n2)
+ s_c = rffi.str2charp(s)
+ try:
+ _strxfrm(buf, s_c, n2)
+ finally:
+ rffi.free_charp(s_c)
val = rffi.charp2str(buf)
lltype.free(buf, flavor="raw")
@@ -194,7 +213,11 @@
def gettext(space, msg):
"""gettext(msg) -> string
Return translation of msg."""
- return space.wrap(rffi.charp2str(_gettext(rffi.str2charp(msg))))
+ msg_c = rffi.str2charp(msg)
+ try:
+ return space.wrap(rffi.charp2str(_gettext(msg_c)))
+ finally:
+ rffi.free_charp(msg_c)
gettext.unwrap_spec = [ObjSpace, str]
@@ -205,10 +228,20 @@
Return translation of msg in domain."""
if space.is_w(w_domain, space.w_None):
domain = None
- result = _dgettext(domain, rffi.str2charp(msg))
+ msg_c = rffi.str2charp(msg)
+ try:
+ result = _dgettext(domain, msg_c)
+ finally:
+ rffi.free_charp(msg_c)
else:
domain = space.str_w(w_domain)
- result = _dgettext(rffi.str2charp(domain), rffi.str2charp(msg))
+ domain_c = rffi.str2charp(domain)
+ msg_c = rffi.str2charp(msg)
+ try:
+ result = _dgettext(domain_c, msg_c)
+ finally:
+ rffi.free_charp(domain_c)
+ rffi.free_charp(msg_c)
return space.wrap(rffi.charp2str(result))
@@ -223,12 +256,21 @@
if space.is_w(w_domain, space.w_None):
domain = None
- result = _dcgettext(domain, rffi.str2charp(msg),
- rffi.cast(rffi.INT, category))
+ msg_c = rffi.str2charp(msg)
+ try:
+ result = _dcgettext(domain, msg_c, rffi.cast(rffi.INT, category))
+ finally:
+ rffi.free_charp(msg_c)
else:
domain = space.str_w(w_domain)
- result = _dcgettext(rffi.str2charp(domain), rffi.str2charp(msg),
- rffi.cast(rffi.INT, category))
+ domain_c = rffi.str2charp(domain)
+ msg_c = rffi.str2charp(msg)
+ try:
+ result = _dcgettext(domain_c, msg_c,
+ rffi.cast(rffi.INT, category))
+ finally:
+ rffi.free_charp(domain_c)
+ rffi.free_charp(msg_c)
return space.wrap(rffi.charp2str(result))
@@ -246,7 +288,11 @@
result = _textdomain(domain)
else:
domain = space.str_w(w_domain)
- result = _textdomain(rffi.str2charp(domain))
+ domain_c = rffi.str2charp(domain)
+ try:
+ result = _textdomain(domain_c)
+ finally:
+ rffi.free_charp(domain_c)
return space.wrap(rffi.charp2str(result))
@@ -261,11 +307,20 @@
if space.is_w(w_dir, space.w_None):
dir = None
- dirname = _bindtextdomain(rffi.str2charp(domain), dir)
+ domain_c = rffi.str2charp(domain)
+ try:
+ dirname = _bindtextdomain(domain_c, dir)
+ finally:
+ rffi.free_charp(domain_c)
else:
dir = space.str_w(w_dir)
- dirname = _bindtextdomain(rffi.str2charp(domain),
- rffi.str2charp(dir))
+ domain_c = rffi.str2charp(domain)
+ dir_c = rffi.str2charp(dir)
+ try:
+ dirname = _bindtextdomain(domain_c, dir_c)
+ finally:
+ rffi.free_charp(domain_c)
+ rffi.free_charp(dir_c)
if not dirname:
errno = rposix.get_errno()
@@ -284,12 +339,20 @@
if space.is_w(w_codeset, space.w_None):
codeset = None
- result = _bind_textdomain_codeset(
- rffi.str2charp(domain), codeset)
+ domain_c = rffi.str2charp(domain)
+ try:
+ result = _bind_textdomain_codeset(domain_c, codeset)
+ finally:
+ rffi.free_charp(domain_c)
else:
codeset = space.str_w(w_codeset)
- result = _bind_textdomain_codeset(rffi.str2charp(domain),
- rffi.str2charp(codeset))
+ domain_c = rffi.str2charp(domain)
+ codeset_c = rffi.str2charp(codeset)
+ try:
+ result = _bind_textdomain_codeset(domain_c, codeset_c)
+ finally:
+ rffi.free_charp(domain_c)
+ rffi.free_charp(codeset_c)
if not result:
return space.w_None
Modified: pypy/branch/x86-64-jit-backend/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/module/cpyext/api.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/module/cpyext/api.py Tue Jul 20 20:55:30 2010
@@ -104,8 +104,12 @@
for name in ("pypy_decl.h", "pypy_macros.h"):
headers.append(udir.join(name))
for header in headers:
- header.copy(dstdir)
target = dstdir.join(header.basename)
+ try:
+ header.copy(dstdir)
+ except py.error.EACCES:
+ target.remove() # maybe it was a read-only file
+ header.copy(dstdir)
target.chmod(0444) # make the file read-only, to make sure that nobody
# edits it by mistake
Modified: pypy/branch/x86-64-jit-backend/pypy/module/cpyext/methodobject.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/module/cpyext/methodobject.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/module/cpyext/methodobject.py Tue Jul 20 20:55:30 2010
@@ -100,7 +100,11 @@
return generic_cpy_call(space, self.ml.c_ml_meth, w_self, w_arg)
def get_doc(space, self):
- return space.wrap(rffi.charp2str(self.ml.c_ml_doc))
+ doc = self.ml.c_ml_doc
+ if doc:
+ return space.wrap(rffi.charp2str(doc))
+ else:
+ return space.w_None
class W_PyCMethodObject(W_PyCFunctionObject):
Modified: pypy/branch/x86-64-jit-backend/pypy/module/marshal/interp_marshal.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/module/marshal/interp_marshal.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/module/marshal/interp_marshal.py Tue Jul 20 20:55:30 2010
@@ -365,8 +365,8 @@
return self.reader.read(n)
def get1(self):
- # convince typer to use a char
- return chr(ord(self.get(1)))
+ # the [0] is used to convince the annotator to return a char
+ return self.get(1)[0]
def atom_str(self, typecode):
self.start(typecode)
Modified: pypy/branch/x86-64-jit-backend/pypy/module/posix/interp_posix.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/module/posix/interp_posix.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/module/posix/interp_posix.py Tue Jul 20 20:55:30 2010
@@ -1,8 +1,9 @@
from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped
from pypy.rlib import rposix
+from pypy.rlib.objectmodel import specialize
from pypy.rlib.rarithmetic import r_longlong
from pypy.rlib.unroll import unrolling_iterable
-from pypy.interpreter.error import OperationError, wrap_oserror
+from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2
from pypy.rpython.module.ll_os import RegisterOs
from pypy.rpython.module import ll_os_stat
from pypy.rpython.lltypesystem import rffi, lltype
@@ -12,15 +13,78 @@
import os, sys
_WIN = sys.platform == 'win32'
-def open(space, fname, flag, mode=0777):
+class FileEncoder:
+ def __init__(self, space, w_obj):
+ self.space = space
+ self.w_obj = w_obj
+
+ def as_bytes(self):
+ from pypy.module.sys.interp_encoding import getfilesystemencoding
+ space = self.space
+ w_bytes = space.call_method(self.w_obj, 'encode',
+ getfilesystemencoding(space))
+ return space.str_w(w_bytes)
+
+ def as_unicode(self):
+ return self.space.unicode_w(self.w_obj)
+
+class FileDecoder:
+ def __init__(self, space, w_obj):
+ self.space = space
+ self.w_obj = w_obj
+
+ def as_bytes(self):
+ return self.space.str_w(self.w_obj)
+
+ def as_unicode(self):
+ from pypy.module.sys.interp_encoding import getfilesystemencoding
+ space = self.space
+ w_unicode = space.call_method(self.w_obj, 'decode',
+ getfilesystemencoding(space))
+ return space.unicode_w(w_unicode)
+
+ at specialize.memo()
+def dispatch_filename(func, tag=0):
+ def dispatch(space, w_fname, *args):
+ if space.isinstance_w(w_fname, space.w_unicode):
+ fname = FileEncoder(space, w_fname)
+ return func(fname, *args)
+ else:
+ fname = space.str_w(w_fname)
+ return func(fname, *args)
+ return dispatch
+
+ at specialize.memo()
+def dispatch_filename_2(func):
+ def dispatch(space, w_fname1, w_fname2, *args):
+ if space.isinstance_w(w_fname1, space.w_unicode):
+ fname1 = FileEncoder(space, w_fname1)
+ if space.isinstance_w(w_fname2, space.w_unicode):
+ fname2 = FileEncoder(space, w_fname2)
+ return func(fname1, fname2, *args)
+ else:
+ fname2 = FileDecoder(space, w_fname2)
+ return func(fname1, fname2, *args)
+ else:
+ fname1 = FileDecoder(space, w_fname1)
+ if space.isinstance_w(w_fname2, space.w_unicode):
+ fname2 = FileEncoder(space, w_fname2)
+ return func(fname1, fname2, *args)
+ else:
+ fname2 = FileDecoder(space, w_fname2)
+ return func(fname1, fname2, *args)
+ return dispatch
+
+def open(space, w_fname, flag, mode=0777):
"""Open a file (for low level IO).
Return a file descriptor (a small integer)."""
- try:
- fd = os.open(fname, flag, mode)
+ try:
+ fd = dispatch_filename(rposix.open)(
+ space, w_fname, flag, mode)
except OSError, e:
- raise wrap_oserror(space, e, fname)
+ raise wrap_oserror2(space, e, w_fname)
return space.wrap(fd)
-open.unwrap_spec = [ObjSpace, 'path', "c_int", "c_int"]
+open.unwrap_spec = [ObjSpace, W_Root, "c_int", "c_int"]
def lseek(space, fd, pos, how):
"""Set the current position of a file descriptor. Return the new position.
@@ -159,7 +223,7 @@
return build_stat_result(space, st)
fstat.unwrap_spec = [ObjSpace, "c_int"]
-def stat(space, path):
+def stat(space, w_path):
"""Perform a stat system call on the given path. Return an object
with (at least) the following attributes:
st_mode
@@ -175,22 +239,22 @@
"""
try:
- st = os.stat(path)
+ st = dispatch_filename(rposix.stat)(space, w_path)
except OSError, e:
- raise wrap_oserror(space, e, path)
+ raise wrap_oserror2(space, e, w_path)
else:
return build_stat_result(space, st)
-stat.unwrap_spec = [ObjSpace, 'path']
+stat.unwrap_spec = [ObjSpace, W_Root]
-def lstat(space, path):
+def lstat(space, w_path):
"Like stat(path), but do no follow symbolic links."
try:
- st = os.lstat(path)
+ st = dispatch_filename(rposix.lstat)(space, w_path)
except OSError, e:
- raise wrap_oserror(space, e, path)
+ raise wrap_oserror2(space, e, w_path)
else:
return build_stat_result(space, st)
-lstat.unwrap_spec = [ObjSpace, 'path']
+lstat.unwrap_spec = [ObjSpace, W_Root]
class StatState(object):
def __init__(self, space):
@@ -231,7 +295,7 @@
raise wrap_oserror(space, e)
dup2.unwrap_spec = [ObjSpace, "c_int", "c_int"]
-def access(space, path, mode):
+def access(space, w_path, mode):
"""
access(path, mode) -> 1 if granted, 0 otherwise
@@ -242,12 +306,12 @@
existence, or the inclusive-OR of R_OK, W_OK, and X_OK.
"""
try:
- ok = os.access(path, mode)
- except OSError, e:
- raise wrap_oserror(space, e, path)
+ ok = dispatch_filename(rposix.access)(space, w_path, mode)
+ except OSError, e:
+ raise wrap_oserror2(space, e, w_path)
else:
return space.wrap(ok)
-access.unwrap_spec = [ObjSpace, str, "c_int"]
+access.unwrap_spec = [ObjSpace, W_Root, "c_int"]
def times(space):
@@ -278,32 +342,38 @@
return space.wrap(rc)
system.unwrap_spec = [ObjSpace, str]
-def unlink(space, path):
+def unlink(space, w_path):
"""Remove a file (same as remove(path))."""
try:
- os.unlink(path)
- except OSError, e:
- raise wrap_oserror(space, e, path)
-unlink.unwrap_spec = [ObjSpace, 'path']
+ dispatch_filename(rposix.unlink)(space, w_path)
+ except OSError, e:
+ raise wrap_oserror2(space, e, w_path)
+unlink.unwrap_spec = [ObjSpace, W_Root]
-def remove(space, path):
+def remove(space, w_path):
"""Remove a file (same as unlink(path))."""
try:
- os.unlink(path)
- except OSError, e:
- raise wrap_oserror(space, e, path)
-remove.unwrap_spec = [ObjSpace, 'path']
+ dispatch_filename(rposix.unlink)(space, w_path)
+ except OSError, e:
+ raise wrap_oserror2(space, e, w_path)
+remove.unwrap_spec = [ObjSpace, W_Root]
-def _getfullpathname(space, path):
+def _getfullpathname(space, w_path):
"""helper for ntpath.abspath """
- posix = __import__(os.name) # nt specific
try:
- fullpath = posix._getfullpathname(path)
+ if space.isinstance_w(w_path, space.w_unicode):
+ path = FileEncoder(space, w_path)
+ fullpath = rposix._getfullpathname(path)
+ w_fullpath = space.wrap(fullpath)
+ else:
+ path = space.str_w(w_path)
+ fullpath = rposix._getfullpathname(path)
+ w_fullpath = space.wrap(fullpath)
except OSError, e:
- raise wrap_oserror(space, e, path)
- else:
- return space.wrap(fullpath)
-_getfullpathname.unwrap_spec = [ObjSpace, str]
+ raise wrap_oserror2(space, e, w_path)
+ else:
+ return w_fullpath
+_getfullpathname.unwrap_spec = [ObjSpace, W_Root]
def getcwd(space):
"""Return the current working directory."""
@@ -315,35 +385,46 @@
return space.wrap(cur)
getcwd.unwrap_spec = [ObjSpace]
-def getcwdu(space):
- """Return the current working directory as a unicode string."""
- # XXX ascii encoding for now
- return space.call_method(getcwd(space), 'decode')
+if sys.platform == 'win32':
+ def getcwdu(space):
+ """Return the current working directory as a unicode string."""
+ try:
+ cur = os.getcwdu()
+ except OSError, e:
+ raise wrap_oserror(space, e)
+ else:
+ return space.wrap(cur)
+else:
+ def getcwdu(space):
+ """Return the current working directory as a unicode string."""
+ filesystemencoding = space.sys.filesystemencoding
+ return space.call_method(getcwd(space), 'decode',
+ space.wrap(filesystemencoding))
getcwdu.unwrap_spec = [ObjSpace]
-def chdir(space, path):
+def chdir(space, w_path):
"""Change the current working directory to the specified path."""
try:
- os.chdir(path)
- except OSError, e:
- raise wrap_oserror(space, e, path)
-chdir.unwrap_spec = [ObjSpace, str]
+ dispatch_filename(rposix.chdir)(space, w_path)
+ except OSError, e:
+ raise wrap_oserror2(space, e, w_path)
+chdir.unwrap_spec = [ObjSpace, W_Root]
-def mkdir(space, path, mode=0777):
+def mkdir(space, w_path, mode=0777):
"""Create a directory."""
try:
- os.mkdir(path, mode)
- except OSError, e:
- raise wrap_oserror(space, e, path)
-mkdir.unwrap_spec = [ObjSpace, str, "c_int"]
+ dispatch_filename(rposix.mkdir)(space, w_path, mode)
+ except OSError, e:
+ raise wrap_oserror2(space, e, w_path)
+mkdir.unwrap_spec = [ObjSpace, W_Root, "c_int"]
-def rmdir(space, path):
+def rmdir(space, w_path):
"""Remove a directory."""
try:
- os.rmdir(path)
- except OSError, e:
- raise wrap_oserror(space, e, path)
-rmdir.unwrap_spec = [ObjSpace, str]
+ dispatch_filename(rposix.rmdir)(space, w_path)
+ except OSError, e:
+ raise wrap_oserror2(space, e, w_path)
+rmdir.unwrap_spec = [ObjSpace, W_Root]
def strerror(space, errno):
"""Translate an error code to a message string."""
@@ -410,7 +491,7 @@
unsetenv.unwrap_spec = [ObjSpace, str]
-def listdir(space, dirname):
+def listdir(space, w_dirname):
"""Return a list containing the names of the entries in the directory.
\tpath: path of directory to list
@@ -418,12 +499,18 @@
The list is in arbitrary order. It does not include the special
entries '.' and '..' even if they are present in the directory."""
try:
- result = os.listdir(dirname)
+ if space.isinstance_w(w_dirname, space.w_unicode):
+ dirname = FileEncoder(space, w_dirname)
+ result = rposix.listdir(dirname)
+ result_w = [space.wrap(s) for s in result]
+ else:
+ dirname = space.str_w(w_dirname)
+ result = rposix.listdir(dirname)
+ result_w = [space.wrap(s) for s in result]
except OSError, e:
- raise wrap_oserror(space, e, dirname)
- result_w = [space.wrap(s) for s in result]
+ raise wrap_oserror2(space, e, w_dirname)
return space.newlist(result_w)
-listdir.unwrap_spec = [ObjSpace, str]
+listdir.unwrap_spec = [ObjSpace, W_Root]
def pipe(space):
"Create a pipe. Returns (read_end, write_end)."
@@ -434,21 +521,21 @@
return space.newtuple([space.wrap(fd1), space.wrap(fd2)])
pipe.unwrap_spec = [ObjSpace]
-def chmod(space, path, mode):
+def chmod(space, w_path, mode):
"Change the access permissions of a file."
- try:
- os.chmod(path, mode)
- except OSError, e:
- raise wrap_oserror(space, e, path)
-chmod.unwrap_spec = [ObjSpace, str, "c_int"]
+ try:
+ dispatch_filename(rposix.chmod)(space, w_path, mode)
+ except OSError, e:
+ raise wrap_oserror2(space, e, w_path)
+chmod.unwrap_spec = [ObjSpace, W_Root, "c_int"]
-def rename(space, old, new):
+def rename(space, w_old, w_new):
"Rename a file or directory."
- try:
- os.rename(old, new)
- except OSError, e:
+ try:
+ dispatch_filename_2(rposix.rename)(space, w_old, w_new)
+ except OSError, e:
raise wrap_oserror(space, e)
-rename.unwrap_spec = [ObjSpace, str, str]
+rename.unwrap_spec = [ObjSpace, W_Root, W_Root]
def umask(space, mask):
"Set the current numeric umask and return the previous umask."
@@ -576,7 +663,7 @@
raise wrap_oserror(space, e)
execve.unwrap_spec = [ObjSpace, str, W_Root, W_Root]
-def utime(space, path, w_tuple):
+def utime(space, w_path, w_tuple):
""" utime(path, (atime, mtime))
utime(path, None)
@@ -585,10 +672,10 @@
"""
if space.is_w(w_tuple, space.w_None):
try:
- os.utime(path, None)
+ dispatch_filename(rposix.utime, 1)(space, w_path, None)
return
except OSError, e:
- raise wrap_oserror(space, e, path)
+ raise wrap_oserror2(space, e, w_path)
try:
msg = "utime() arg 2 must be a tuple (atime, mtime) or None"
args_w = space.fixedview(w_tuple)
@@ -596,14 +683,14 @@
raise OperationError(space.w_TypeError, space.wrap(msg))
actime = space.float_w(args_w[0])
modtime = space.float_w(args_w[1])
- os.utime(path, (actime, modtime))
+ dispatch_filename(rposix.utime, 2)(space, w_path, (actime, modtime))
except OSError, e:
- raise wrap_oserror(space, e, path)
+ raise wrap_oserror2(space, e, w_path)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
raise OperationError(space.w_TypeError, space.wrap(msg))
-utime.unwrap_spec = [ObjSpace, str, W_Root]
+utime.unwrap_spec = [ObjSpace, W_Root, W_Root]
def setsid(space):
"""setsid() -> pid
Modified: pypy/branch/x86-64-jit-backend/pypy/module/posix/test/test_posix2.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/module/posix/test/test_posix2.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/module/posix/test/test_posix2.py Tue Jul 20 20:55:30 2010
@@ -32,6 +32,9 @@
# even when running on top of CPython 2.4.
os.stat_float_times(True)
+ # Initialize sys.filesystemencoding
+ space.call_method(space.getbuiltinmodule('sys'), 'getfilesystemencoding')
+
def need_sparse_files():
if sys.platform == 'darwin':
py.test.skip("no sparse files on default Mac OS X file system")
@@ -706,6 +709,28 @@
except OSError:
pass
+class AppTestUnicodeFilename:
+ def setup_class(cls):
+ ufilename = (unicode(udir.join('test_unicode_filename_')) +
+ u'\u65e5\u672c.txt') # "Japan"
+ try:
+ f = file(ufilename, 'w')
+ except UnicodeEncodeError:
+ py.test.skip("encoding not good enough")
+ f.write("test")
+ f.close()
+ cls.space = space
+ cls.w_filename = space.wrap(ufilename)
+ cls.w_posix = space.appexec([], GET_POSIX)
+
+ def test_open(self):
+ fd = self.posix.open(self.filename, self.posix.O_RDONLY)
+ try:
+ content = self.posix.read(fd, 50)
+ finally:
+ self.posix.close(fd)
+ assert content == "test"
+
class TestPexpect(object):
# XXX replace with AppExpectTest class as soon as possible
Modified: pypy/branch/x86-64-jit-backend/pypy/module/termios/interp_termios.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/module/termios/interp_termios.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/module/termios/interp_termios.py Tue Jul 20 20:55:30 2010
@@ -60,8 +60,8 @@
# last one need to be chosen carefully
cc_w = [space.wrap(i) for i in cc]
if lflag & termios.ICANON:
- cc_w[termios.VMIN] = space.wrap(ord(cc[termios.VMIN]))
- cc_w[termios.VTIME] = space.wrap(ord(cc[termios.VTIME]))
+ cc_w[termios.VMIN] = space.wrap(ord(cc[termios.VMIN][0]))
+ cc_w[termios.VTIME] = space.wrap(ord(cc[termios.VTIME][0]))
w_cc = space.newlist(cc_w)
l_w.append(w_cc)
return space.newlist(l_w)
Modified: pypy/branch/x86-64-jit-backend/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/objspace/std/stringobject.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/objspace/std/stringobject.py Tue Jul 20 20:55:30 2010
@@ -863,7 +863,7 @@
space.w_TypeError,
"ord() expected a character, but string "
"of length %d found", len(u_str))
- return space.wrap(ord(u_str))
+ return space.wrap(ord(u_str[0]))
def getnewargs__String(space, w_str):
return space.newtuple([wrapstr(space, w_str._value)])
Modified: pypy/branch/x86-64-jit-backend/pypy/rlib/libffi.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rlib/libffi.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rlib/libffi.py Tue Jul 20 20:55:30 2010
@@ -402,7 +402,7 @@
restype = ffi_type_sint32
elif restype.c_size <= 8:
restype = ffi_type_sint64
-
+
res = c_ffi_prep_cif(self.ll_cif, cc,
rffi.cast(rffi.UINT, argnum), restype,
self.ll_argtypes)
Modified: pypy/branch/x86-64-jit-backend/pypy/rlib/rarithmetic.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rlib/rarithmetic.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rlib/rarithmetic.py Tue Jul 20 20:55:30 2010
@@ -33,7 +33,7 @@
"""
-import math
+import sys, math
from pypy.rpython import extregistry
from pypy.rlib import objectmodel
@@ -54,13 +54,10 @@
NAN = INFINITY / INFINITY
def isinf(x):
- return x != 0.0 and x / 2 == x
+ return x == INFINITY or x == -INFINITY
-# To get isnan, working x-platform and both on 2.3 and 2.4, is a
-# horror. I think this works (for reasons I don't really want to talk
-# about), and probably when implemented on top of pypy, too.
def isnan(v):
- return v != v*1.0 or (v == 1.0 and v == 2.0)
+ return v != v
def intmask(n):
if isinstance(n, int):
@@ -116,14 +113,23 @@
"NOT_RPYTHON"
return _local_ovfcheck(int(long(a) << b))
-FL_MAXINT = float(LONG_TEST-1)
-FL_MININT = float(-LONG_TEST)
-
-def ovfcheck_float_to_int(x):
- _, intp = math.modf(x)
- if FL_MININT < intp < FL_MAXINT:
- return int(intp)
- raise OverflowError
+# Strange things happening for float to int on 64 bit:
+# int(float(i)) != i because of rounding issues.
+# These are the minimum and maximum float value that can
+# successfully be casted to an int.
+if sys.maxint == 2147483647:
+ def ovfcheck_float_to_int(x):
+ if -2147483649.0 < x < 2147483648.0:
+ return int(x)
+ raise OverflowError
+else:
+ # The following values are not quite +/-sys.maxint.
+ # Note the "<= x <" here, as opposed to "< x <" above.
+ # This is justified by test_typed in translator/c/test.
+ def ovfcheck_float_to_int(x):
+ if -9223372036854776832.0 <= x < 9223372036854775296.0:
+ return int(x)
+ raise OverflowError
def compute_restype(self_type, other_type):
if self_type is other_type:
Modified: pypy/branch/x86-64-jit-backend/pypy/rlib/rdynload.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rlib/rdynload.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rlib/rdynload.py Tue Jul 20 20:55:30 2010
@@ -18,8 +18,6 @@
if _WIN32:
from pypy.rlib import rwin32
-
-if _WIN32:
includes = ['windows.h']
else:
includes = ['dlfcn.h']
Modified: pypy/branch/x86-64-jit-backend/pypy/rlib/rposix.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rlib/rposix.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rlib/rposix.py Tue Jul 20 20:55:30 2010
@@ -3,6 +3,7 @@
from pypy.rpython.lltypesystem import lltype, ll2ctypes, rffi
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.objectmodel import specialize
class CConstantErrno(CConstant):
# these accessors are used when calling get_errno() or set_errno()
@@ -42,3 +43,102 @@
os.close(fd)
except OSError:
pass
+
+#___________________________________________________________________
+# Wrappers around posix functions, that accept either strings, or
+# instances with a "as_bytes()" method.
+# - pypy.modules.posix.interp_posix passes an object containing a unicode path
+# which can encode itself with sys.filesystemencoding.
+# - but pypy.rpython.module.ll_os.py on Windows will replace these functions
+# with other wrappers that directly handle unicode strings.
+ at specialize.argtype(0)
+def open(path, flags, mode):
+ if isinstance(path, str):
+ return os.open(path, flags, mode)
+ else:
+ return os.open(path.as_bytes(), flags, mode)
+
+ at specialize.argtype(0)
+def stat(path):
+ if isinstance(path, str):
+ return os.stat(path)
+ else:
+ return os.stat(path.as_bytes())
+
+ at specialize.argtype(0)
+def lstat(path):
+ if isinstance(path, str):
+ return os.lstat(path)
+ else:
+ return os.lstat(path.as_bytes())
+
+ at specialize.argtype(0)
+def unlink(path):
+ if isinstance(path, str):
+ return os.unlink(path)
+ else:
+ return os.unlink(path.as_bytes())
+
+ at specialize.argtype(0, 1)
+def rename(path1, path2):
+ if isinstance(path1, str):
+ return os.rename(path1, path2)
+ else:
+ return os.rename(path1.as_bytes(), path2.as_bytes())
+
+ at specialize.argtype(0)
+def listdir(dirname):
+ if isinstance(dirname, str):
+ return os.listdir(dirname)
+ else:
+ return os.listdir(dirname.as_bytes())
+
+ at specialize.argtype(0)
+def access(path, mode):
+ if isinstance(path, str):
+ return os.access(path, mode)
+ else:
+ return os.access(path.as_bytes(), mode)
+
+ at specialize.argtype(0)
+def chmod(path, mode):
+ if isinstance(path, str):
+ return os.chmod(path, mode)
+ else:
+ return os.chmod(path.as_bytes(), mode)
+
+ at specialize.argtype(0, 1)
+def utime(path, times):
+ if isinstance(path, str):
+ return os.utime(path, times)
+ else:
+ return os.utime(path.as_bytes(), times)
+
+ at specialize.argtype(0)
+def chdir(path):
+ if isinstance(path, str):
+ return os.chdir(path)
+ else:
+ return os.chdir(path.as_bytes())
+
+ at specialize.argtype(0)
+def mkdir(path, mode=0777):
+ if isinstance(path, str):
+ return os.mkdir(path, mode)
+ else:
+ return os.mkdir(path.as_bytes(), mode)
+
+ at specialize.argtype(0)
+def rmdir(path):
+ if isinstance(path, str):
+ return os.rmdir(path)
+ else:
+ return os.rmdir(path.as_bytes())
+
+if os.name == 'nt':
+ import nt
+ def _getfullpathname(path):
+ if isinstance(path, str):
+ return nt._getfullpathname(path)
+ else:
+ return nt._getfullpathname(path.as_bytes())
Modified: pypy/branch/x86-64-jit-backend/pypy/rlib/rwin32.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rlib/rwin32.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rlib/rwin32.py Tue Jul 20 20:55:30 2010
@@ -31,6 +31,7 @@
DWORD = rffi_platform.SimpleType("DWORD", rffi.UINT)
BOOL = rffi_platform.SimpleType("BOOL", rffi.LONG)
BYTE = rffi_platform.SimpleType("BYTE", rffi.UCHAR)
+ WCHAR = rffi_platform.SimpleType("WCHAR", rffi.UCHAR)
INT = rffi_platform.SimpleType("INT", rffi.INT)
LONG = rffi_platform.SimpleType("LONG", rffi.LONG)
PLONG = rffi_platform.SimpleType("PLONG", rffi.LONGP)
@@ -38,6 +39,8 @@
LPCVOID = rffi_platform.SimpleType("LPCVOID", rffi.VOIDP)
LPSTR = rffi_platform.SimpleType("LPSTR", rffi.CCHARP)
LPCSTR = rffi_platform.SimpleType("LPCSTR", rffi.CCHARP)
+ LPWSTR = rffi_platform.SimpleType("LPWSTR", rffi.CWCHARP)
+ LPCWSTR = rffi_platform.SimpleType("LPCWSTR", rffi.CWCHARP)
LPDWORD = rffi_platform.SimpleType("LPDWORD", rffi.INTP)
SIZE_T = rffi_platform.SimpleType("SIZE_T", rffi.SIZE_T)
ULONG_PTR = rffi_platform.SimpleType("ULONG_PTR", rffi.ULONG)
@@ -87,6 +90,10 @@
GetLastError = winexternal('GetLastError', [], DWORD)
SetLastError = winexternal('SetLastError', [DWORD], lltype.Void)
+ # In tests, the first call to GetLastError is always wrong, because error
+ # is hidden by operations in ll2ctypes. Call it now.
+ GetLastError()
+
LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], rffi.VOIDP)
GetProcAddress = winexternal('GetProcAddress',
[rffi.VOIDP, rffi.CCHARP],
@@ -129,13 +136,29 @@
}
return 0;
}''')
- exename = static_platform.compile(
- [cfile], ExternalCompilationInfo(),
- outputfilename = "dosmaperr",
- standalone=True)
- output = os.popen(str(exename))
- errors = dict(map(int, line.split())
- for line in output)
+ try:
+ exename = static_platform.compile(
+ [cfile], ExternalCompilationInfo(),
+ outputfilename = "dosmaperr",
+ standalone=True)
+ except WindowsError:
+ # Fallback for the mingw32 compiler
+ errors = {
+ 2: 2, 3: 2, 4: 24, 5: 13, 6: 9, 7: 12, 8: 12, 9: 12, 10: 7,
+ 11: 8, 15: 2, 16: 13, 17: 18, 18: 2, 19: 13, 20: 13, 21: 13,
+ 22: 13, 23: 13, 24: 13, 25: 13, 26: 13, 27: 13, 28: 13,
+ 29: 13, 30: 13, 31: 13, 32: 13, 33: 13, 34: 13, 35: 13,
+ 36: 13, 53: 2, 65: 13, 67: 2, 80: 17, 82: 13, 83: 13, 89: 11,
+ 108: 13, 109: 32, 112: 28, 114: 9, 128: 10, 129: 10, 130: 9,
+ 132: 13, 145: 41, 158: 13, 161: 2, 164: 11, 167: 13, 183: 17,
+ 188: 8, 189: 8, 190: 8, 191: 8, 192: 8, 193: 8, 194: 8,
+ 195: 8, 196: 8, 197: 8, 198: 8, 199: 8, 200: 8, 201: 8,
+ 202: 8, 206: 2, 215: 11, 1816: 12,
+ }
+ else:
+ output = os.popen(str(exename))
+ errors = dict(map(int, line.split())
+ for line in output)
return errors, errno.EINVAL
# A bit like strerror...
Modified: pypy/branch/x86-64-jit-backend/pypy/rlib/streamio.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rlib/streamio.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rlib/streamio.py Tue Jul 20 20:55:30 2010
@@ -38,7 +38,9 @@
#
import os, sys
+from pypy.rlib.objectmodel import specialize
from pypy.rlib.rarithmetic import r_longlong, intmask
+from pypy.rlib import rposix
from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC
O_BINARY = getattr(os, "O_BINARY", 0)
@@ -71,6 +73,7 @@
return s.join(string.split(c))
+ at specialize.argtype(0)
def open_file_as_stream(path, mode="r", buffering=-1):
os_flags, universal, reading, writing, basemode, binary = decode_mode(mode)
stream = open_path_helper(path, os_flags, basemode == "a")
@@ -89,9 +92,10 @@
return construct_stream_tower(stream, buffering, universal, reading,
writing, binary)
+ at specialize.argtype(0)
def open_path_helper(path, os_flags, append):
# XXX for now always return DiskFile
- fd = os.open(path, os_flags, 0666)
+ fd = rposix.open(path, os_flags, 0666)
if append:
try:
os.lseek(fd, 0, 2)
Modified: pypy/branch/x86-64-jit-backend/pypy/rlib/test/test_rarithmetic.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rlib/test/test_rarithmetic.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rlib/test/test_rarithmetic.py Tue Jul 20 20:55:30 2010
@@ -271,26 +271,29 @@
assert ovfcheck_float_to_int(13.0) == 13
assert ovfcheck_float_to_int(-1.0) == -1
assert ovfcheck_float_to_int(-13.0) == -13
- # strange things happening for float to int on 64 bit
- maxint32 = 2 ** 31 - 1
- assert ovfcheck_float_to_int(float(maxint32-1)) == maxint32-1
- #assert ovfcheck_float_to_int(float(maxint32)) == maxint32
- assert ovfcheck_float_to_int(float(-maxint32)) == -maxint32
- #assert ovfcheck_float_to_int(float(-maxint32-1)) == -maxint32-1
-
- try:
- ovfcheck_float_to_int(float(-sys.maxint-1)-1)
- except OverflowError:
- pass
- else:
- assert False
-
- try:
- ovfcheck_float_to_int(float(sys.maxint)+1)
- except OverflowError:
- pass
- else:
- assert False
+
+ # strange things happening for float to int on 64 bit:
+ # int(float(i)) != i because of rounding issues
+ x = sys.maxint
+ while int(float(x)) > sys.maxint:
+ x -= 1
+ assert ovfcheck_float_to_int(float(x)) == int(float(x))
+
+ x = sys.maxint + 1
+ while int(float(x)) <= sys.maxint:
+ x += 1
+ py.test.raises(OverflowError, ovfcheck_float_to_int, x)
+
+ x = -sys.maxint-1
+ while int(float(x)) < -sys.maxint-1:
+ x += 1
+ assert ovfcheck_float_to_int(float(x)) == int(float(x))
+
+ x = -sys.maxint-1
+ while int(float(x)) >= -sys.maxint-1:
+ x -= 1
+ py.test.raises(OverflowError, ovfcheck_float_to_int, x)
+
def test_abs():
assert type(abs(r_longlong(1))) is r_longlong
Modified: pypy/branch/x86-64-jit-backend/pypy/rpython/extfunc.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rpython/extfunc.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rpython/extfunc.py Tue Jul 20 20:55:30 2010
@@ -52,7 +52,10 @@
return super(ExtRegistryEntry, self).__getattr__(attr)
raise exc, exc_inst, tb
-def registering(func):
+def registering(func, condition=True):
+ if not condition:
+ return lambda method: None
+
def decorator(method):
method._registering_func = func
return method
@@ -63,11 +66,9 @@
func = getattr(ns, name)
except AttributeError:
condition = False
+ func = None
- if condition:
- return registering(func)
- else:
- return lambda method: None
+ return registering(func, condition=condition)
class LazyRegisteringMeta(type):
def __new__(self, _name, _type, _vars):
@@ -167,8 +168,6 @@
return signature_args
def compute_result_annotation(self, *args_s):
- if hasattr(self, 'ann_hook'):
- self.ann_hook()
self.normalize_args(*args_s) # check arguments
return self.signature_result
@@ -235,7 +234,6 @@
def register_external(function, args, result=None, export_name=None,
llimpl=None, ooimpl=None,
llfakeimpl=None, oofakeimpl=None,
- annotation_hook=None,
sandboxsafe=False):
"""
function: the RPython function that will be rendered as an external function (e.g.: math.floor)
@@ -244,7 +242,6 @@
export_name: the name of the function as it will be seen by the backends
llimpl, ooimpl: optional; if provided, these RPython functions are called instead of the target function
llfakeimpl, oofakeimpl: optional; if provided, they are called by the llinterpreter
- annotationhook: optional; a callable that is called during annotation, useful for genc hacks
sandboxsafe: use True if the function performs no I/O (safe for --sandbox)
"""
@@ -271,8 +268,6 @@
lltypefakeimpl = staticmethod(llfakeimpl)
if oofakeimpl:
ootypefakeimpl = staticmethod(oofakeimpl)
- if annotation_hook:
- ann_hook = staticmethod(annotation_hook)
if export_name:
FunEntry.__name__ = export_name
Modified: pypy/branch/x86-64-jit-backend/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rpython/lltypesystem/rffi.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rpython/lltypesystem/rffi.py Tue Jul 20 20:55:30 2010
@@ -176,6 +176,15 @@
# XXX leaks if a str2charp() fails with MemoryError
# and was not the first in this function
freeme = arg
+ elif TARGET == CWCHARP:
+ if arg is None:
+ arg = lltype.nullptr(CWCHARP.TO) # None => (wchar_t*)NULL
+ freeme = arg
+ elif isinstance(arg, unicode):
+ arg = unicode2wcharp(arg)
+ # XXX leaks if a unicode2wcharp() fails with MemoryError
+ # and was not the first in this function
+ freeme = arg
elif _isfunctype(TARGET) and not _isllptr(arg):
# XXX pass additional arguments
if invoke_around_handlers:
@@ -786,6 +795,8 @@
return r_wchar_t.BITS/8
if tp is lltype.Float:
return 8
+ if tp is lltype.SingleFloat:
+ return 4
assert isinstance(tp, lltype.Number)
if tp is lltype.Signed:
return ULONG._type.BITS/8
Modified: pypy/branch/x86-64-jit-backend/pypy/rpython/lltypesystem/test/test_rffi.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rpython/lltypesystem/test/test_rffi.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rpython/lltypesystem/test/test_rffi.py Tue Jul 20 20:55:30 2010
@@ -707,6 +707,7 @@
lltype.UniChar: ctypes.c_wchar,
lltype.Char: ctypes.c_ubyte,
DOUBLE: ctypes.c_double,
+ FLOAT: ctypes.c_float,
SIGNEDCHAR: ctypes.c_byte,
UCHAR: ctypes.c_ubyte,
SHORT: ctypes.c_short,
Modified: pypy/branch/x86-64-jit-backend/pypy/rpython/memory/lltypelayout.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rpython/memory/lltypelayout.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rpython/memory/lltypelayout.py Tue Jul 20 20:55:30 2010
@@ -111,6 +111,8 @@
elif isinstance(offset, llmemory.ItemOffset):
return sizeof(offset.TYPE) * offset.repeat
elif isinstance(offset, llmemory.ArrayItemsOffset):
+ if offset.TYPE._hints.get('nolength', None):
+ return 0
return get_fixed_size(lltype.Signed)
elif isinstance(offset, llmemory.GCHeaderOffset):
return sizeof(offset.gcheaderbuilder.HDR)
Modified: pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_os.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_os.py Tue Jul 20 20:55:30 2010
@@ -6,12 +6,15 @@
# might be found in doc/rffi.txt
import os, sys, errno
+import py
from pypy.rpython.module.support import ll_strcpy, OOSupport
-from pypy.tool.sourcetools import func_with_new_name
+from pypy.tool.sourcetools import func_with_new_name, func_renamer
from pypy.rlib.rarithmetic import r_longlong
-from pypy.rpython.extfunc import BaseLazyRegistering
+from pypy.rpython.extfunc import (
+ BaseLazyRegistering, lazy_register, register_external)
from pypy.rpython.extfunc import registering, registering_if, extdef
-from pypy.annotation.model import SomeInteger, SomeString, SomeTuple, SomeFloat
+from pypy.annotation.model import (
+ SomeInteger, SomeString, SomeTuple, SomeFloat, SomeUnicodeString)
from pypy.annotation.model import s_ImpossibleValue, s_None, s_Bool
from pypy.rpython.lltypesystem import rffi
from pypy.rpython.lltypesystem import lltype
@@ -26,7 +29,99 @@
from pypy.rpython.lltypesystem.rstr import STR
from pypy.rpython.annlowlevel import llstr
from pypy.rlib import rgc
-from pypy.rlib.objectmodel import keepalive_until_here
+from pypy.rlib.objectmodel import keepalive_until_here, specialize
+
+def monkeypatch_rposix(posixfunc, unicodefunc, signature):
+ func_name = posixfunc.__name__
+
+ if hasattr(signature, '_default_signature_'):
+ signature = signature._default_signature_
+ arglist = ['arg%d' % (i,) for i in range(len(signature))]
+ transformed_arglist = arglist[:]
+ for i, arg in enumerate(signature):
+ if arg is unicode:
+ transformed_arglist[i] = transformed_arglist[i] + '.as_unicode()'
+
+ args = ', '.join(arglist)
+ transformed_args = ', '.join(transformed_arglist)
+ main_arg = 'arg%d' % (signature.index(unicode),)
+
+ source = py.code.Source("""
+ def %(func_name)s(%(args)s):
+ if isinstance(%(main_arg)s, str):
+ return posixfunc(%(args)s)
+ else:
+ return unicodefunc(%(transformed_args)s)
+ """ % locals())
+ miniglobals = {'posixfunc' : posixfunc,
+ 'unicodefunc': unicodefunc,
+ '__name__': __name__, # for module name propagation
+ }
+ exec source.compile() in miniglobals
+ new_func = miniglobals[func_name]
+ specialized_args = [i for i in range(len(signature))
+ if signature[i] in (unicode, None)]
+ new_func = specialize.argtype(*specialized_args)(new_func)
+
+ # Monkeypatch the function in pypy.rlib.rposix
+ setattr(rposix, func_name, new_func)
+
+class StringTraits:
+ str = str
+ CHAR = rffi.CHAR
+ CCHARP = rffi.CCHARP
+ charp2str = staticmethod(rffi.charp2str)
+ str2charp = staticmethod(rffi.str2charp)
+ free_charp = staticmethod(rffi.free_charp)
+
+ @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
+ CHAR = rffi.WCHAR_T
+ CCHARP = rffi.CWCHARP
+ charp2str = staticmethod(rffi.wcharp2unicode)
+ str2charp = staticmethod(rffi.unicode2wcharp)
+ free_charp = staticmethod(rffi.free_wcharp)
+
+ @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:
+ return registering(None, condition=False)
+
+ func_name = posixfunc.__name__
+
+ def register_posixfunc(self, method):
+ val = method(self, StringTraits())
+ register_external(posixfunc, *val.def_args, **val.def_kwds)
+
+ if sys.platform == 'win32':
+ val = method(self, UnicodeTraits())
+ @func_renamer(func_name + "_unicode")
+ def unicodefunc(*args):
+ return posixfunc(*args)
+ register_external(unicodefunc, *val.def_args, **val.def_kwds)
+ signature = val.def_args[0]
+ monkeypatch_rposix(posixfunc, unicodefunc, signature)
+
+ def decorator(method):
+ decorated = lambda self: register_posixfunc(self, method)
+ decorated._registering_func = posixfunc
+ return decorated
+ return decorator
posix = __import__(os.name)
@@ -282,8 +377,8 @@
return extdef([int, int], s_None, llimpl=dup2_llimpl,
export_name="ll_os.ll_os_dup2")
- @registering(os.utime)
- def register_os_utime(self):
+ @registering_str_unicode(os.utime)
+ def register_os_utime(self, traits):
UTIMBUFP = lltype.Ptr(self.UTIMBUF)
os_utime = self.llexternal('utime', [rffi.CCHARP, UTIMBUFP], rffi.INT)
@@ -336,6 +431,9 @@
# tp is known to be None, and one version where it is known
# to be a tuple of 2 floats.
if not _WIN32:
+ assert traits.str is str
+
+ @specialize.argtype(1)
def os_utime_llimpl(path, tp):
if tp is None:
error = os_utime(path, lltype.nullptr(UTIMBUFP.TO))
@@ -346,85 +444,13 @@
if error == -1:
raise OSError(rposix.get_errno(), "os_utime failed")
else:
- from pypy.rlib import rwin32
- from pypy.rpython.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(
- 'CreateFileA',
- [rwin32.LPCSTR, 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)],
- lltype.Void,
- calling_conv='win')
-
- SystemTimeToFileTime = rffi.llexternal(
- 'SystemTimeToFileTime',
- [lltype.Ptr(rwin32.SYSTEMTIME),
- lltype.Ptr(rwin32.FILETIME)],
- rwin32.BOOL,
- calling_conv='win')
-
- SetFileTime = rffi.llexternal(
- 'SetFileTime',
- [rwin32.HANDLE,
- lltype.Ptr(rwin32.FILETIME),
- lltype.Ptr(rwin32.FILETIME),
- lltype.Ptr(rwin32.FILETIME)],
- rwin32.BOOL,
- calling_conv = 'win')
+ from pypy.rpython.module.ll_win32file import make_utime_impl
+ os_utime_llimpl = make_utime_impl(traits)
- def os_utime_llimpl(path, tp):
- hFile = CreateFile(path,
- FILE_WRITE_ATTRIBUTES, 0,
- None, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, 0)
- if hFile == rwin32.INVALID_HANDLE_VALUE:
- raise rwin32.lastWindowsError()
- ctime = lltype.nullptr(rwin32.FILETIME)
- atime = lltype.malloc(rwin32.FILETIME, flavor='raw')
- mtime = lltype.malloc(rwin32.FILETIME, flavor='raw')
- try:
- if tp is None:
- now = lltype.malloc(rwin32.SYSTEMTIME, flavor='raw')
- try:
- GetSystemTime(now)
- if (not SystemTimeToFileTime(now, atime) or
- not SystemTimeToFileTime(now, mtime)):
- raise rwin32.lastWindowsError()
- finally:
- lltype.free(now, flavor='raw')
- else:
- actime, modtime = tp
- time_t_to_FILE_TIME(actime, atime)
- time_t_to_FILE_TIME(modtime, mtime)
- if not SetFileTime(hFile, ctime, atime, mtime):
- raise rwin32.lastWindowsError()
- finally:
- rwin32.CloseHandle(hFile)
- lltype.free(atime, flavor='raw')
- lltype.free(mtime, flavor='raw')
- os_utime_llimpl._annspecialcase_ = 'specialize:argtype(1)'
-
- s_string = SomeString()
+ if traits.str is str:
+ s_string = SomeString()
+ else:
+ s_string = SomeUnicodeString()
s_tuple_of_2_floats = SomeTuple([SomeFloat(), SomeFloat()])
def os_utime_normalize_args(s_path, s_times):
@@ -445,12 +471,12 @@
else:
raise Exception("os.utime() arg 2 must be None or a tuple of "
"2 floats, got %s" % (s_times,))
+ os_utime_normalize_args._default_signature_ = [traits.str, None]
return extdef(os_utime_normalize_args, s_None,
"ll_os.ll_os_utime",
llimpl=os_utime_llimpl)
-
@registering(os.times)
def register_os_times(self):
if sys.platform.startswith('win'):
@@ -687,22 +713,21 @@
def register_os_setsid(self):
return self.extdef_for_os_function_returning_int('setsid')
- @registering(os.open)
- def register_os_open(self):
- os_open = self.llexternal(underscore_on_windows+'open',
- [rffi.CCHARP, rffi.INT, rffi.MODE_T],
+ @registering_str_unicode(os.open)
+ def register_os_open(self, traits):
+ os_open = self.llexternal(traits.posix_function_name('open'),
+ [traits.CCHARP, rffi.INT, rffi.MODE_T],
rffi.INT)
-
def os_open_llimpl(path, flags, mode):
result = rffi.cast(rffi.LONG, os_open(path, flags, mode))
if result == -1:
raise OSError(rposix.get_errno(), "os_open failed")
return result
- def os_open_oofakeimpl(o_path, flags, mode):
- return os.open(o_path._str, flags, mode)
+ def os_open_oofakeimpl(path, flags, mode):
+ return os.open(OOSupport.from_rstr(path), flags, mode)
- return extdef([str, int, int], int, "ll_os.ll_os_open",
+ return extdef([traits.str, int, int], int, traits.ll_os_name('open'),
llimpl=os_open_llimpl, oofakeimpl=os_open_oofakeimpl)
# ------------------------------- os.read -------------------------------
@@ -862,10 +887,10 @@
llimpl=fdatasync_llimpl,
export_name="ll_os.ll_os_fdatasync")
- @registering(os.access)
- def register_os_access(self):
- os_access = self.llexternal(underscore_on_windows + 'access',
- [rffi.CCHARP, rffi.INT],
+ @registering_str_unicode(os.access)
+ def register_os_access(self, traits):
+ os_access = self.llexternal(traits.posix_function_name('access'),
+ [traits.CCHARP, rffi.INT],
rffi.INT)
if sys.platform.startswith('win'):
@@ -882,44 +907,22 @@
def os_access_oofakeimpl(path, mode):
return os.access(OOSupport.from_rstr(path), mode)
- return extdef([str, int], s_Bool, llimpl=access_llimpl,
- export_name="ll_os.ll_os_access",
+ return extdef([traits.str, int], s_Bool, llimpl=access_llimpl,
+ export_name=traits.ll_os_name("access"),
oofakeimpl=os_access_oofakeimpl)
- @registering_if(posix, '_getfullpathname')
- def register_posix__getfullpathname(self):
- from pypy.rlib import rwin32
+ @registering_str_unicode(getattr(posix, '_getfullpathname', None),
+ 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
- # XXX why do we ignore WINAPI conventions everywhere?
- LPSTRP = rffi.CArrayPtr(rwin32.LPSTR)
- # XXX unicode?
- GetFullPathName = self.llexternal(
- 'GetFullPathNameA',
- [rwin32.LPCSTR,
- rwin32.DWORD,
- rwin32.LPSTR,
- rffi.CArrayPtr(rwin32.LPSTR)],
- rwin32.DWORD)
-
- def _getfullpathname_llimpl(lpFileName):
- nBufferLength = rwin32.MAX_PATH + 1
- lpBuffer = lltype.malloc(rwin32.LPSTR.TO, nBufferLength, flavor='raw')
- try:
- res = GetFullPathName(
- lpFileName, rffi.cast(rwin32.DWORD, nBufferLength),
- lpBuffer, lltype.nullptr(LPSTRP.TO))
- if res == 0:
- raise rwin32.lastWindowsError("_getfullpathname failed")
- result = rffi.charp2str(lpBuffer)
- return result
- finally:
- lltype.free(lpBuffer, flavor='raw')
+ from pypy.rpython.module.ll_win32file import make_getfullpathname_impl
+ getfullpathname_llimpl = make_getfullpathname_impl(traits)
- return extdef([str], # a single argument which is a str
- str, # returns a string
- "ll_os.posix__getfullpathname",
- llimpl=_getfullpathname_llimpl)
+ return extdef([traits.str], # a single argument which is a str
+ traits.str, # returns a string
+ traits.ll_os_name('_getfullpathname'),
+ llimpl=getfullpathname_llimpl)
@registering(os.getcwd)
def register_os_getcwd(self):
@@ -953,71 +956,42 @@
"ll_os.ll_os_getcwd", llimpl=os_getcwd_llimpl,
oofakeimpl=os_getcwd_oofakeimpl)
- @registering(os.listdir)
- def register_os_listdir(self):
- # we need a different approach on Windows and on Posix
- if sys.platform.startswith('win'):
- from pypy.rlib import rwin32
- class CConfig:
- _compilation_info_ = ExternalCompilationInfo(
- includes = ['windows.h']
- )
- WIN32_FIND_DATA = platform.Struct('struct _WIN32_FIND_DATAA',
- [('cFileName', lltype.FixedSizeArray(rffi.CHAR, 1))])
- ERROR_FILE_NOT_FOUND = platform.ConstantInteger(
- 'ERROR_FILE_NOT_FOUND')
- ERROR_NO_MORE_FILES = platform.ConstantInteger(
- 'ERROR_NO_MORE_FILES')
+ @registering(os.getcwdu, condition=sys.platform=='win32')
+ def register_os_getcwdu(self):
+ os_wgetcwd = self.llexternal(underscore_on_windows + 'wgetcwd',
+ [rffi.CWCHARP, rffi.SIZE_T],
+ rffi.CWCHARP)
- config = platform.configure(CConfig)
- WIN32_FIND_DATA = config['WIN32_FIND_DATA']
- ERROR_FILE_NOT_FOUND = config['ERROR_FILE_NOT_FOUND']
- ERROR_NO_MORE_FILES = config['ERROR_NO_MORE_FILES']
- LPWIN32_FIND_DATA = lltype.Ptr(WIN32_FIND_DATA)
-
- FindFirstFile = self.llexternal('FindFirstFile',
- [rwin32.LPCSTR, LPWIN32_FIND_DATA],
- rwin32.HANDLE)
- FindNextFile = self.llexternal('FindNextFile',
- [rwin32.HANDLE, LPWIN32_FIND_DATA],
- rwin32.BOOL)
- FindClose = self.llexternal('FindClose',
- [rwin32.HANDLE],
- rwin32.BOOL)
+ def os_getcwd_llimpl():
+ bufsize = 256
+ while True:
+ buf = lltype.malloc(rffi.CWCHARP.TO, bufsize, flavor='raw')
+ res = os_wgetcwd(buf, rffi.cast(rffi.SIZE_T, bufsize))
+ if res:
+ break # ok
+ error = rposix.get_errno()
+ lltype.free(buf, flavor='raw')
+ if error != errno.ERANGE:
+ raise OSError(error, "getcwd failed")
+ # else try again with a larger buffer, up to some sane limit
+ bufsize *= 4
+ if bufsize > 1024*1024: # xxx hard-coded upper limit
+ raise OSError(error, "getcwd result too large")
+ result = rffi.wcharp2unicode(res)
+ lltype.free(buf, flavor='raw')
+ return result
- def os_listdir_llimpl(path):
- if path and path[-1] not in ('/', '\\', ':'):
- path += '/'
- path += '*.*'
- filedata = lltype.malloc(WIN32_FIND_DATA, flavor='raw')
- try:
- result = []
- hFindFile = FindFirstFile(path, filedata)
- if hFindFile == rwin32.INVALID_HANDLE_VALUE:
- error = rwin32.GetLastError()
- if error == ERROR_FILE_NOT_FOUND:
- return result
- else:
- raise WindowsError(error, "FindFirstFile failed")
- while True:
- name = rffi.charp2str(rffi.cast(rffi.CCHARP,
- filedata.c_cFileName))
- if name != "." and name != "..": # skip these
- result.append(name)
- if not FindNextFile(hFindFile, filedata):
- break
- # FindNextFile sets error to ERROR_NO_MORE_FILES if
- # it got to the end of the directory
- error = rwin32.GetLastError()
- FindClose(hFindFile)
- if error == ERROR_NO_MORE_FILES:
- return result
- else:
- raise WindowsError(error, "FindNextFile failed")
- finally:
- lltype.free(filedata, flavor='raw')
+ return extdef([], unicode,
+ "ll_os.ll_os_wgetcwd", llimpl=os_getcwd_llimpl)
+ @registering_str_unicode(os.listdir)
+ def register_os_listdir(self, traits):
+ # we need a different approach on Windows and on Posix
+ if sys.platform.startswith('win'):
+ from pypy.rpython.module.ll_win32file import make_listdir_impl
+ os_listdir_llimpl = make_listdir_impl(traits)
else:
+ assert traits.str is str
compilation_info = ExternalCompilationInfo(
includes = ['sys/types.h', 'dirent.h']
)
@@ -1057,9 +1031,9 @@
raise OSError(error, "os_readdir failed")
return result
- return extdef([str], # a single argument which is a str
- [str], # returns a list of strings
- "ll_os.ll_os_listdir",
+ return extdef([traits.str], # a single argument which is a str
+ [traits.str], # returns a list of strings
+ traits.ll_os_name('listdir'),
llimpl=os_listdir_llimpl)
@registering(os.pipe)
@@ -1234,38 +1208,40 @@
return extdef([str], int, llimpl=system_llimpl,
export_name="ll_os.ll_os_system")
- @registering(os.unlink)
- def register_os_unlink(self):
- os_unlink = self.llexternal(underscore_on_windows+'unlink', [rffi.CCHARP], rffi.INT)
+ @registering_str_unicode(os.unlink)
+ def register_os_unlink(self, traits):
+ os_unlink = self.llexternal(traits.posix_function_name('unlink'),
+ [traits.CCHARP], rffi.INT)
def unlink_llimpl(pathname):
res = rffi.cast(lltype.Signed, os_unlink(pathname))
if res < 0:
raise OSError(rposix.get_errno(), "os_unlink failed")
- return extdef([str], s_None, llimpl=unlink_llimpl,
- export_name="ll_os.ll_os_unlink")
+ return extdef([traits.str], s_None, llimpl=unlink_llimpl,
+ export_name=traits.ll_os_name('unlink'))
- @registering(os.chdir)
- def register_os_chdir(self):
- os_chdir = self.llexternal(underscore_on_windows+'chdir', [rffi.CCHARP], rffi.INT)
+ @registering_str_unicode(os.chdir)
+ def register_os_chdir(self, traits):
+ os_chdir = self.llexternal(traits.posix_function_name('chdir'),
+ [traits.CCHARP], rffi.INT)
def chdir_llimpl(path):
res = rffi.cast(lltype.Signed, os_chdir(path))
if res < 0:
raise OSError(rposix.get_errno(), "os_chdir failed")
- return extdef([str], s_None, llimpl=chdir_llimpl,
- export_name="ll_os.ll_os_chdir")
+ return extdef([traits.str], s_None, llimpl=chdir_llimpl,
+ export_name=traits.ll_os_name('chdir'))
- @registering(os.mkdir)
- def register_os_mkdir(self):
+ @registering_str_unicode(os.mkdir)
+ def register_os_mkdir(self, traits):
if os.name == 'nt':
ARG2 = [] # no 'mode' argument on Windows - just ignored
else:
ARG2 = [rffi.MODE_T]
- os_mkdir = self.llexternal(underscore_on_windows+'mkdir',
- [rffi.CCHARP]+ARG2, rffi.INT)
+ os_mkdir = self.llexternal(traits.posix_function_name('mkdir'),
+ [traits.CCHARP] + ARG2, rffi.INT)
IGNORE_MODE = len(ARG2) == 0
def mkdir_llimpl(pathname, mode):
@@ -1277,46 +1253,47 @@
if res < 0:
raise OSError(rposix.get_errno(), "os_mkdir failed")
- return extdef([str, int], s_None, llimpl=mkdir_llimpl,
- export_name="ll_os.ll_os_mkdir")
+ return extdef([traits.str, int], s_None, llimpl=mkdir_llimpl,
+ export_name=traits.ll_os_name('mkdir'))
- @registering(os.rmdir)
- def register_os_rmdir(self):
- os_rmdir = self.llexternal(underscore_on_windows+'rmdir', [rffi.CCHARP], rffi.INT)
+ @registering_str_unicode(os.rmdir)
+ def register_os_rmdir(self, traits):
+ os_rmdir = self.llexternal(traits.posix_function_name('rmdir'),
+ [traits.CCHARP], rffi.INT)
def rmdir_llimpl(pathname):
res = rffi.cast(lltype.Signed, os_rmdir(pathname))
if res < 0:
raise OSError(rposix.get_errno(), "os_rmdir failed")
- return extdef([str], s_None, llimpl=rmdir_llimpl,
- export_name="ll_os.ll_os_rmdir")
+ return extdef([traits.str], s_None, llimpl=rmdir_llimpl,
+ export_name=traits.ll_os_name('rmdir'))
- @registering(os.chmod)
- def register_os_chmod(self):
- os_chmod = self.llexternal(underscore_on_windows+'chmod', [rffi.CCHARP, rffi.MODE_T],
- rffi.INT)
+ @registering_str_unicode(os.chmod)
+ def register_os_chmod(self, traits):
+ os_chmod = self.llexternal(traits.posix_function_name('chmod'),
+ [traits.CCHARP, rffi.MODE_T], rffi.INT)
def chmod_llimpl(path, mode):
res = rffi.cast(lltype.Signed, os_chmod(path, rffi.cast(rffi.MODE_T, mode)))
if res < 0:
raise OSError(rposix.get_errno(), "os_chmod failed")
- return extdef([str, int], s_None, llimpl=chmod_llimpl,
- export_name="ll_os.ll_os_chmod")
+ return extdef([traits.str, int], s_None, llimpl=chmod_llimpl,
+ export_name=traits.ll_os_name('chmod'))
- @registering(os.rename)
- def register_os_rename(self):
- os_rename = self.llexternal('rename', [rffi.CCHARP, rffi.CCHARP],
- rffi.INT)
+ @registering_str_unicode(os.rename)
+ def register_os_rename(self, traits):
+ os_rename = self.llexternal(traits.posix_function_name('rename'),
+ [traits.CCHARP, traits.CCHARP], rffi.INT)
def rename_llimpl(oldpath, newpath):
res = rffi.cast(lltype.Signed, os_rename(oldpath, newpath))
if res < 0:
raise OSError(rposix.get_errno(), "os_rename failed")
- return extdef([str, str], s_None, llimpl=rename_llimpl,
- export_name="ll_os.ll_os_rename")
+ return extdef([traits.str, traits.str], s_None, llimpl=rename_llimpl,
+ export_name=traits.ll_os_name('rename'))
@registering(os.umask)
def register_os_umask(self):
@@ -1425,17 +1402,17 @@
@registering(os.fstat)
def register_os_fstat(self):
from pypy.rpython.module import ll_os_stat
- ll_os_stat.register_stat_variant('fstat')
+ return ll_os_stat.register_stat_variant('fstat', StringTraits())
- @registering(os.stat)
- def register_os_stat(self):
+ @registering_str_unicode(os.stat)
+ def register_os_stat(self, traits):
from pypy.rpython.module import ll_os_stat
- ll_os_stat.register_stat_variant('stat')
+ return ll_os_stat.register_stat_variant('stat', traits)
- @registering(os.lstat)
- def register_os_lstat(self):
+ @registering_str_unicode(os.lstat)
+ def register_os_lstat(self, traits):
from pypy.rpython.module import ll_os_stat
- ll_os_stat.register_stat_variant('lstat')
+ return ll_os_stat.register_stat_variant('lstat', traits)
# ------------------------------- os.W* ---------------------------------
Modified: pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_os_stat.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_os_stat.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_os_stat.py Tue Jul 20 20:55:30 2010
@@ -5,13 +5,14 @@
import os, sys
from pypy.annotation import model as annmodel
from pypy.tool.pairtype import pairtype
-from pypy.tool.sourcetools import func_with_new_name
+from pypy.tool.sourcetools import func_with_new_name, func_renamer
from pypy.rpython import extregistry
-from pypy.rpython.extfunc import register_external
+from pypy.rpython.extfunc import register_external, extdef
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.rpython.tool import rffi_platform as platform
from pypy.rpython.lltypesystem.rtupletype import TUPLE_TYPE
from pypy.rlib import rposix
+from pypy.rlib.objectmodel import specialize
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rpython.annlowlevel import hlstr
@@ -211,13 +212,27 @@
return make_stat_result(result)
-def register_stat_variant(name):
- if sys.platform.startswith('win'):
- _functions = {'stat': '_stati64',
- 'fstat': '_fstati64',
- 'lstat': '_stati64'} # no lstat on Windows
- c_func_name = _functions[name]
- elif sys.platform.startswith('linux'):
+def register_stat_variant(name, traits):
+ if name != 'fstat':
+ arg_is_path = True
+ s_arg = traits.str
+ ARG1 = traits.CCHARP
+ else:
+ arg_is_path = False
+ s_arg = int
+ ARG1 = rffi.INT
+
+ if sys.platform == 'win32':
+ # See Win32 implementation below
+ posix_stat_llimpl = make_win32_stat_impl(name, traits)
+
+ return extdef(
+ [s_arg], s_StatResult, traits.ll_os_name(name),
+ llimpl=posix_stat_llimpl)
+
+ assert traits.str is str
+
+ if sys.platform.startswith('linux'):
# because we always use _FILE_OFFSET_BITS 64 - this helps things work that are not a c compiler
_functions = {'stat': 'stat64',
'fstat': 'fstat64',
@@ -226,22 +241,26 @@
else:
c_func_name = name
- arg_is_path = (name != 'fstat')
+ posix_mystat = rffi.llexternal(c_func_name,
+ [ARG1, STAT_STRUCT], rffi.INT,
+ compilation_info=compilation_info)
+ @func_renamer('os_%s_llimpl' % (name,))
def posix_stat_llimpl(arg):
stresult = lltype.malloc(STAT_STRUCT.TO, flavor='raw')
try:
if arg_is_path:
- arg = rffi.str2charp(arg)
+ arg = traits.str2charp(arg)
error = rffi.cast(rffi.LONG, posix_mystat(arg, stresult))
if arg_is_path:
- rffi.free_charp(arg)
+ traits.free_charp(arg)
if error != 0:
raise OSError(rposix.get_errno(), "os_?stat failed")
return build_stat_result(stresult)
finally:
lltype.free(stresult, flavor='raw')
+ @func_renamer('os_%s_fake' % (name,))
def posix_fakeimpl(arg):
if s_arg == str:
arg = hlstr(arg)
@@ -259,40 +278,17 @@
setattr(ll_tup, 'item%d' % i, val)
return ll_tup
- if arg_is_path:
- s_arg = str
- ARG1 = rffi.CCHARP
- else:
- s_arg = int
- ARG1 = rffi.INT
+ return extdef(
+ [s_arg], s_StatResult, "ll_os.ll_os_%s" % (name,),
+ llimpl=posix_stat_llimpl, llfakeimpl=posix_fakeimpl)
- if sys.platform != 'win32':
- posix_mystat = rffi.llexternal(c_func_name,
- [ARG1, STAT_STRUCT], rffi.INT,
- compilation_info=compilation_info)
-
- register_external(
- getattr(os, name), [s_arg], s_StatResult,
- "ll_os.ll_os_%s" % (name,),
- llimpl=func_with_new_name(posix_stat_llimpl,
- 'os_%s_llimpl' % (name,)),
- llfakeimpl=func_with_new_name(posix_fakeimpl,
- 'os_%s_fake' % (name,)),
- )
- else:
- # See Win32 implementation below
- register_external(
- getattr(os, name), [s_arg], s_StatResult,
- "ll_os.ll_os_%s" % (name,),
- llimpl=func_with_new_name(globals()['win32_%s_llimpl' % (name,)],
- 'os_%s_llimpl' % (name,)),
- )
+def make_win32_stat_impl(name, traits):
+ from pypy.rlib import rwin32
+ from pypy.rpython.module.ll_win32file import make_win32_traits
+ win32traits = make_win32_traits(traits)
-# ____________________________________________________________
-if sys.platform == 'win32':
# The CRT of Windows has a number of flaws wrt. its stat() implementation:
- # - for when we implement subsecond resolution in RPython, time stamps
- # would be restricted to second resolution
+ # - time stamps are restricted to second resolution
# - file modification times suffer from forth-and-back conversions between
# UTC and local time
# Therefore, we implement our own stat, based on the Win32 API directly.
@@ -302,122 +298,18 @@
assert len(STAT_FIELDS) == 10 # no extra fields on Windows
- class CConfig:
- _compilation_info_ = ExternalCompilationInfo(
- includes = ['windows.h', 'winbase.h', 'sys/stat.h'],
- )
-
- GetFileExInfoStandard = platform.ConstantInteger(
- 'GetFileExInfoStandard')
- FILE_ATTRIBUTE_DIRECTORY = platform.ConstantInteger(
- 'FILE_ATTRIBUTE_DIRECTORY')
- FILE_ATTRIBUTE_READONLY = platform.ConstantInteger(
- 'FILE_ATTRIBUTE_READONLY')
- ERROR_SHARING_VIOLATION = platform.ConstantInteger(
- 'ERROR_SHARING_VIOLATION')
- _S_IFDIR = platform.ConstantInteger('_S_IFDIR')
- _S_IFREG = platform.ConstantInteger('_S_IFREG')
- _S_IFCHR = platform.ConstantInteger('_S_IFCHR')
- _S_IFIFO = platform.ConstantInteger('_S_IFIFO')
- FILE_TYPE_UNKNOWN = platform.ConstantInteger('FILE_TYPE_UNKNOWN')
- FILE_TYPE_CHAR = platform.ConstantInteger('FILE_TYPE_CHAR')
- FILE_TYPE_PIPE = platform.ConstantInteger('FILE_TYPE_PIPE')
-
- WIN32_FILE_ATTRIBUTE_DATA = platform.Struct(
- 'WIN32_FILE_ATTRIBUTE_DATA',
- [('dwFileAttributes', rwin32.DWORD),
- ('nFileSizeHigh', rwin32.DWORD),
- ('nFileSizeLow', rwin32.DWORD),
- ('ftCreationTime', rwin32.FILETIME),
- ('ftLastAccessTime', rwin32.FILETIME),
- ('ftLastWriteTime', rwin32.FILETIME)])
-
- BY_HANDLE_FILE_INFORMATION = platform.Struct(
- 'BY_HANDLE_FILE_INFORMATION',
- [('dwFileAttributes', 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)])
-
- WIN32_FIND_DATA = platform.Struct(
- 'WIN32_FIND_DATAA',
- # Only interesting fields
- [('dwFileAttributes', rwin32.DWORD),
- ('nFileSizeHigh', rwin32.DWORD),
- ('nFileSizeLow', rwin32.DWORD),
- ('ftCreationTime', rwin32.FILETIME),
- ('ftLastAccessTime', rwin32.FILETIME),
- ('ftLastWriteTime', rwin32.FILETIME)])
-
- globals().update(platform.configure(CConfig))
- GET_FILEEX_INFO_LEVELS = rffi.ULONG # an enumeration
-
- GetFileAttributesEx = rffi.llexternal(
- 'GetFileAttributesExA',
- [rffi.CCHARP, GET_FILEEX_INFO_LEVELS,
- lltype.Ptr(WIN32_FILE_ATTRIBUTE_DATA)],
- rwin32.BOOL,
- calling_conv='win')
-
- GetFileInformationByHandle = rffi.llexternal(
- 'GetFileInformationByHandle',
- [rwin32.HANDLE, lltype.Ptr(BY_HANDLE_FILE_INFORMATION)],
- rwin32.BOOL,
- calling_conv='win')
-
- GetFileType = rffi.llexternal(
- 'GetFileType',
- [rwin32.HANDLE],
- rwin32.DWORD,
- calling_conv='win')
-
- FindFirstFile = rffi.llexternal(
- 'FindFirstFileA',
- [rffi.CCHARP, lltype.Ptr(WIN32_FIND_DATA)],
- rwin32.HANDLE,
- calling_conv='win')
-
- FindClose = rffi.llexternal(
- 'FindClose',
- [rwin32.HANDLE],
- rwin32.BOOL,
- calling_conv='win')
-
def attributes_to_mode(attributes):
m = 0
- if attributes & FILE_ATTRIBUTE_DIRECTORY:
- m |= _S_IFDIR | 0111 # IFEXEC for user,group,other
+ if attributes & win32traits.FILE_ATTRIBUTE_DIRECTORY:
+ m |= win32traits._S_IFDIR | 0111 # IFEXEC for user,group,other
else:
- m |= _S_IFREG
- if attributes & FILE_ATTRIBUTE_READONLY:
+ m |= win32traits._S_IFREG
+ if attributes & win32traits.FILE_ATTRIBUTE_READONLY:
m |= 0444
else:
m |= 0666
return m
- def make_longlong(high, low):
- return (lltype.r_longlong(high) << 32) + lltype.r_longlong(low)
-
- # Seconds between 1.1.1601 and 1.1.1970
- secs_between_epochs = lltype.r_longlong(11644473600)
-
- def FILE_TIME_to_time_t_nsec(filetime):
- ft = make_longlong(filetime.c_dwHighDateTime, filetime.c_dwLowDateTime)
- # FILETIME is in units of 100 nsec
- nsec = (ft % 10000000) * 100
- time = (ft / 10000000) - secs_between_epochs
- return time, nsec
-
- def time_t_to_FILE_TIME(time, filetime):
- ft = lltype.r_longlong((time + secs_between_epochs) * 10000000)
- filetime.c_dwHighDateTime = lltype.r_uint(ft >> 32)
- filetime.c_dwLowDateTime = lltype.r_uint(ft & ((1 << 32) - 1))
-
def attribute_data_to_stat(info):
st_mode = attributes_to_mode(info.c_dwFileAttributes)
st_size = make_longlong(info.c_nFileSizeHigh, info.c_nFileSizeLow)
@@ -456,65 +348,94 @@
return make_stat_result(result)
def attributes_from_dir(l_path, data):
- filedata = lltype.malloc(WIN32_FIND_DATA, flavor='raw')
- hFindFile = FindFirstFile(l_path, filedata)
- if hFindFile == rwin32.INVALID_HANDLE_VALUE:
- return 0
- FindClose(hFindFile)
- data.c_dwFileAttributes = filedata.c_dwFileAttributes
- rffi.structcopy(data.c_ftCreationTime, filedata.c_ftCreationTime)
- rffi.structcopy(data.c_ftLastAccessTime, filedata.c_ftLastAccessTime)
- rffi.structcopy(data.c_ftLastWriteTime, filedata.c_ftLastWriteTime)
- data.c_nFileSizeHigh = filedata.c_nFileSizeHigh
- data.c_nFileSizeLow = filedata.c_nFileSizeLow
- return 1
+ filedata = lltype.malloc(win32traits.WIN32_FIND_DATA, flavor='raw')
+ try:
+ hFindFile = win32traits.FindFirstFile(l_path, filedata)
+ if hFindFile == rwin32.INVALID_HANDLE_VALUE:
+ return 0
+ win32traits.FindClose(hFindFile)
+ data.c_dwFileAttributes = filedata.c_dwFileAttributes
+ rffi.structcopy(data.c_ftCreationTime, filedata.c_ftCreationTime)
+ rffi.structcopy(data.c_ftLastAccessTime, filedata.c_ftLastAccessTime)
+ rffi.structcopy(data.c_ftLastWriteTime, filedata.c_ftLastWriteTime)
+ data.c_nFileSizeHigh = filedata.c_nFileSizeHigh
+ data.c_nFileSizeLow = filedata.c_nFileSizeLow
+ return 1
+ finally:
+ lltype.free(filedata, flavor='raw')
def win32_stat_llimpl(path):
- data = lltype.malloc(WIN32_FILE_ATTRIBUTE_DATA, flavor='raw')
+ data = lltype.malloc(win32traits.WIN32_FILE_ATTRIBUTE_DATA, flavor='raw')
try:
- l_path = rffi.str2charp(path)
- res = GetFileAttributesEx(l_path, GetFileExInfoStandard, data)
+ l_path = traits.str2charp(path)
+ res = win32traits.GetFileAttributesEx(l_path, win32traits.GetFileExInfoStandard, data)
errcode = rwin32.GetLastError()
if res == 0:
- if errcode == ERROR_SHARING_VIOLATION:
+ if errcode == win32traits.ERROR_SHARING_VIOLATION:
res = attributes_from_dir(l_path, data)
errcode = rwin32.GetLastError()
- rffi.free_charp(l_path)
+ traits.free_charp(l_path)
if res == 0:
raise WindowsError(errcode, "os_stat failed")
return attribute_data_to_stat(data)
finally:
lltype.free(data, flavor='raw')
- win32_lstat_llimpl = win32_stat_llimpl
def win32_fstat_llimpl(fd):
handle = rwin32._get_osfhandle(fd)
- filetype = GetFileType(handle)
- if filetype == FILE_TYPE_CHAR:
+ filetype = win32traits.GetFileType(handle)
+ if filetype == win32traits.FILE_TYPE_CHAR:
# console or LPT device
- return make_stat_result((_S_IFCHR,
+ return make_stat_result((win32traits._S_IFCHR,
0, 0, 0, 0, 0,
0, 0, 0, 0))
- elif filetype == FILE_TYPE_PIPE:
+ elif filetype == win32traits.FILE_TYPE_PIPE:
# socket or named pipe
- return make_stat_result((_S_IFIFO,
+ return make_stat_result((win32traits._S_IFIFO,
0, 0, 0, 0, 0,
0, 0, 0, 0))
- elif filetype == FILE_TYPE_UNKNOWN:
+ elif filetype == win32traits.FILE_TYPE_UNKNOWN:
error = rwin32.GetLastError()
if error != 0:
raise WindowsError(error, "os_fstat failed")
# else: unknown but valid file
# normal disk file (FILE_TYPE_DISK)
- info = lltype.malloc(BY_HANDLE_FILE_INFORMATION, flavor='raw',
- zero=True)
+ info = lltype.malloc(win32traits.BY_HANDLE_FILE_INFORMATION,
+ flavor='raw', zero=True)
try:
- res = GetFileInformationByHandle(handle, info)
+ res = win32traits.GetFileInformationByHandle(handle, info)
if res == 0:
raise WindowsError(rwin32.GetLastError(), "os_fstat failed")
return by_handle_info_to_stat(info)
finally:
lltype.free(info, flavor='raw')
+ if name == 'fstat':
+ return win32_fstat_llimpl
+ else:
+ return win32_stat_llimpl
+
+
+#__________________________________________________
+# Helper functions for win32
+
+def make_longlong(high, low):
+ return (lltype.r_longlong(high) << 32) + lltype.r_longlong(low)
+
+# Seconds between 1.1.1601 and 1.1.1970
+secs_between_epochs = lltype.r_longlong(11644473600)
+
+def FILE_TIME_to_time_t_nsec(filetime):
+ ft = make_longlong(filetime.c_dwHighDateTime, filetime.c_dwLowDateTime)
+ # FILETIME is in units of 100 nsec
+ nsec = (ft % 10000000) * 100
+ time = (ft / 10000000) - secs_between_epochs
+ return time, nsec
+
+def time_t_to_FILE_TIME(time, filetime):
+ ft = lltype.r_longlong((time + secs_between_epochs) * 10000000)
+ filetime.c_dwHighDateTime = lltype.r_uint(ft >> 32)
+ filetime.c_dwLowDateTime = lltype.r_uint(ft & ((1 << 32) - 1))
+
Modified: pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_termios.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_termios.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rpython/module/ll_termios.py Tue Jul 20 20:55:30 2010
@@ -85,7 +85,7 @@
c_struct.c_c_lflag, ispeed, ospeed, cc = attributes
try:
for i in range(NCCS):
- c_struct.c_c_cc[i] = rffi.r_uchar(ord(cc[i]))
+ c_struct.c_c_cc[i] = rffi.r_uchar(ord(cc[i][0]))
error = c_cfsetispeed(c_struct, ispeed)
if error == -1:
raise termios.error(error, 'tcsetattr failed')
Modified: pypy/branch/x86-64-jit-backend/pypy/rpython/module/test/test_ll_os_stat.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rpython/module/test/test_ll_os_stat.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rpython/module/test/test_ll_os_stat.py Tue Jul 20 20:55:30 2010
@@ -1,4 +1,4 @@
-from pypy.rpython.module import ll_os_stat
+from pypy.rpython.module import ll_os_stat, ll_os
import sys, os
import py
@@ -8,14 +8,18 @@
py.test.skip("win32 specific tests")
def test_stat(self):
- stat = ll_os_stat.win32_stat_llimpl
+ stat = ll_os_stat.make_win32_stat_impl('stat', ll_os.StringTraits())
+ wstat = ll_os_stat.make_win32_stat_impl('stat', ll_os.UnicodeTraits())
def check(f):
- assert stat(f).st_mtime == os.stat(f).st_mtime
+ expected = os.stat(f).st_mtime
+ assert stat(f).st_mtime == expected
+ assert wstat(unicode(f)).st_mtime == expected
check('c:/')
check('c:/temp')
check('c:/pagefile.sys')
def test_fstat(self):
- stat = ll_os_stat.win32_fstat_llimpl(0) # stdout
+ fstat = ll_os_stat.make_win32_stat_impl('fstat', ll_os.StringTraits())
+ stat = fstat(0) # stdout
assert stat.st_mode != 0
Modified: pypy/branch/x86-64-jit-backend/pypy/rpython/rstr.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rpython/rstr.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rpython/rstr.py Tue Jul 20 20:55:30 2010
@@ -80,17 +80,6 @@
# defaults to checking the length
return super(AbstractStringRepr, self).rtype_is_true(hop)
- def rtype_ord(self, hop):
- string_repr = hop.args_r[0].repr
- v_str, = hop.inputargs(string_repr)
- c_zero = inputconst(Signed, 0)
- v_chr = hop.gendirectcall(self.ll.ll_stritem_nonneg, v_str, c_zero)
- if string_repr is hop.rtyper.type_system.rstr.string_repr:
- return hop.genop('cast_char_to_int', [v_chr], resulttype=Signed)
- else:
- assert string_repr is hop.rtyper.type_system.rstr.unicode_repr
- return hop.genop('cast_unichar_to_int', [v_chr], resulttype=Signed)
-
def rtype_method_startswith(self, hop):
str1_repr, str2_repr = self._str_reprs(hop)
v_str, v_value = hop.inputargs(str1_repr, str2_repr)
@@ -299,7 +288,11 @@
if not hop.args_s[1].is_constant():
raise TyperError("encoding must be constant")
encoding = hop.args_s[1].const
- v_self = hop.inputarg(self.repr, 0)
+ if encoding == "ascii":
+ expect = self.lowleveltype # can be a UniChar
+ else:
+ expect = self.repr # must be a regular unicode string
+ v_self = hop.inputarg(expect, 0)
hop.exception_is_here()
if encoding == "ascii":
return hop.gendirectcall(self.ll_str, v_self)
@@ -426,7 +419,17 @@
sourcevars.append((v_item, r_arg))
return r_str.ll.do_stringformat(hop, sourcevars)
-
+
+
+class __extend__(AbstractCharRepr):
+ def ll_str(self, ch):
+ return self.ll.ll_chr2str(ch)
+
+class __extend__(AbstractUniCharRepr):
+ def ll_str(self, ch):
+ # xxx suboptimal, maybe
+ return str(unicode(ch))
+
class __extend__(AbstractCharRepr,
AbstractUniCharRepr):
@@ -444,9 +447,6 @@
get_ll_fasthash_function = get_ll_hash_function
- def ll_str(self, ch):
- return self.ll.ll_chr2str(ch)
-
def rtype_len(_, hop):
return hop.inputconst(Signed, 1)
Modified: pypy/branch/x86-64-jit-backend/pypy/rpython/test/test_extfunc.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rpython/test/test_extfunc.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rpython/test/test_extfunc.py Tue Jul 20 20:55:30 2010
@@ -6,150 +6,164 @@
from pypy.annotation.policy import AnnotatorPolicy
from pypy.rpython.test.test_llinterp import interpret
-def b(x):
- return eval("x+40")
+class TestExtFuncEntry:
-class BTestFuncEntry(ExtFuncEntry):
- _about_ = b
- name = 'b'
- signature_args = [annmodel.SomeInteger()]
- signature_result = annmodel.SomeInteger()
-
-def test_annotation_b():
- def f():
- return b(1)
-
- policy = AnnotatorPolicy()
- policy.allow_someobjects = False
- a = RPythonAnnotator(policy=policy)
- s = a.build_types(f, [])
- assert isinstance(s, annmodel.SomeInteger)
-
-def test_rtyping_b():
- def f():
- return b(2)
-
- res = interpret(f, [])
- assert res == 42
-
-def c(y, x):
- yyy
-
-class CTestFuncEntry(ExtFuncEntry):
- _about_ = c
- name = 'ccc'
- signature_args = [annmodel.SomeInteger()] * 2
- signature_result = annmodel.SomeInteger()
-
- def lltypeimpl(y, x):
- return y + x
- lltypeimpl = staticmethod(lltypeimpl)
-
-def test_interp_c():
- def f():
- return c(3, 4)
-
- res = interpret(f, [])
- assert res == 7
-
-def d(y):
- return eval("y()")
-
-class DTestFuncEntry(ExtFuncEntry):
- _about_ = d
- name = 'd'
- signature_args = [annmodel.SomeGenericCallable(args=[], result=
- annmodel.SomeFloat())]
- signature_result = annmodel.SomeFloat()
-
-def test_callback():
- def callback():
- return 2.5
-
- def f():
- return d(callback)
-
- policy = AnnotatorPolicy()
- policy.allow_someobjects = False
- a = RPythonAnnotator(policy=policy)
- s = a.build_types(f, [])
- assert isinstance(s, annmodel.SomeFloat)
- assert a.translator._graphof(callback)
-
-def dd():
- pass
-
-register_external(dd, [int], int)
-
-def test_register_external_signature():
- def f():
- return dd(3)
-
- policy = AnnotatorPolicy()
- policy.allow_someobjects = False
- a = RPythonAnnotator(policy=policy)
- s = a.build_types(f, [])
- assert isinstance(s, annmodel.SomeInteger)
-
-
-def function_with_tuple_arg():
- """
- Dummy function which is declared via register_external to take a tuple as
- an argument so that register_external's behavior for tuple-taking functions
- can be verified.
- """
-register_external(function_with_tuple_arg, [(int,)], int)
-
-def test_register_external_tuple_args():
- """
- Verify the annotation of a registered external function which takes a tuple
- argument.
- """
- def f():
- return function_with_tuple_arg((1,))
-
- policy = AnnotatorPolicy()
- policy.allow_someobjects = False
- a = RPythonAnnotator(policy=policy)
- s = a.build_types(f, [])
-
- # Not a very good assertion, but at least it means _something_ happened.
- assert isinstance(s, annmodel.SomeInteger)
-
-def function_with_list():
- pass
-register_external(function_with_list, [[int]], int)
-
-def function_returning_list():
- pass
-register_external(function_returning_list, [], [int])
-
-def test_register_external_return_goes_back():
- """
- Check whether it works to pass the same list from one external
- fun to another
- [bookkeeper and list joining issues]
- """
- def f():
- return function_with_list(function_returning_list())
-
- policy = AnnotatorPolicy()
- policy.allow_someobjects = False
- a = RPythonAnnotator(policy=policy)
- s = a.build_types(f, [])
- assert isinstance(s, annmodel.SomeInteger)
-
-def function_withspecialcase(arg):
- return repr(arg)
-register_external(function_withspecialcase, args=None, result=str)
-
-def test_register_external_specialcase():
- def f():
- x = function_withspecialcase
- return x(33) + x("aaa") + x([]) + "\n"
-
- policy = AnnotatorPolicy()
- policy.allow_someobjects = False
- a = RPythonAnnotator(policy=policy)
- s = a.build_types(f, [])
- assert isinstance(s, annmodel.SomeString)
+ def test_basic(self):
+ """
+ A ExtFuncEntry provides an annotation for a function, no need to flow
+ its graph.
+ """
+ def b(x):
+ "NOT_RPYTHON"
+ return eval("x+40")
+
+ class BTestFuncEntry(ExtFuncEntry):
+ _about_ = b
+ name = 'b'
+ signature_args = [annmodel.SomeInteger()]
+ signature_result = annmodel.SomeInteger()
+
+ def f():
+ return b(2)
+
+ policy = AnnotatorPolicy()
+ policy.allow_someobjects = False
+ a = RPythonAnnotator(policy=policy)
+ s = a.build_types(f, [])
+ assert isinstance(s, annmodel.SomeInteger)
+
+ res = interpret(f, [])
+ assert res == 42
+
+ def test_lltypeimpl(self):
+ """
+ interpret() calls lltypeimpl instead of of the function/
+ """
+ def c(y, x):
+ yyy
+
+ class CTestFuncEntry(ExtFuncEntry):
+ _about_ = c
+ name = 'ccc'
+ signature_args = [annmodel.SomeInteger()] * 2
+ signature_result = annmodel.SomeInteger()
+
+ def lltypeimpl(y, x):
+ return y + x
+ lltypeimpl = staticmethod(lltypeimpl)
+
+ def f():
+ return c(3, 4)
+
+ res = interpret(f, [])
+ assert res == 7
+
+ def test_callback(self):
+ """
+ Verify annotation when a callback function is in the arguments list.
+ """
+ def d(y):
+ return eval("y()")
+
+ class DTestFuncEntry(ExtFuncEntry):
+ _about_ = d
+ name = 'd'
+ signature_args = [annmodel.SomeGenericCallable(args=[], result=
+ annmodel.SomeFloat())]
+ signature_result = annmodel.SomeFloat()
+
+ def callback():
+ return 2.5
+
+ def f():
+ return d(callback)
+
+ policy = AnnotatorPolicy()
+ policy.allow_someobjects = False
+ a = RPythonAnnotator(policy=policy)
+ s = a.build_types(f, [])
+ assert isinstance(s, annmodel.SomeFloat)
+ assert a.translator._graphof(callback)
+
+ def test_register_external_signature(self):
+ """
+ Test the standard interface for external functions.
+ """
+ def dd():
+ pass
+ register_external(dd, [int], int)
+
+ def f():
+ return dd(3)
+
+ policy = AnnotatorPolicy()
+ policy.allow_someobjects = False
+ a = RPythonAnnotator(policy=policy)
+ s = a.build_types(f, [])
+ assert isinstance(s, annmodel.SomeInteger)
+
+ def test_register_external_tuple_args(self):
+ """
+ Verify the annotation of a registered external function which takes a
+ tuple argument.
+ """
+
+ def function_with_tuple_arg():
+ """
+ Dummy function which is declared via register_external to take a
+ tuple as an argument so that register_external's behavior for
+ tuple-taking functions can be verified.
+ """
+ register_external(function_with_tuple_arg, [(int,)], int)
+
+ def f():
+ return function_with_tuple_arg((1,))
+
+ policy = AnnotatorPolicy()
+ policy.allow_someobjects = False
+ a = RPythonAnnotator(policy=policy)
+ s = a.build_types(f, [])
+
+ # Not a very good assertion, but at least it means _something_ happened.
+ assert isinstance(s, annmodel.SomeInteger)
+
+ def test_register_external_return_goes_back(self):
+ """
+ Check whether it works to pass the same list from one external
+ fun to another
+ [bookkeeper and list joining issues]
+ """
+ def function_with_list():
+ pass
+ register_external(function_with_list, [[int]], int)
+
+ def function_returning_list():
+ pass
+ register_external(function_returning_list, [], [int])
+
+ def f():
+ return function_with_list(function_returning_list())
+
+ policy = AnnotatorPolicy()
+ policy.allow_someobjects = False
+ a = RPythonAnnotator(policy=policy)
+ s = a.build_types(f, [])
+ assert isinstance(s, annmodel.SomeInteger)
+
+ def test_register_external_specialcase(self):
+ """
+ When args=None, the external function accepts any arguments unmodified.
+ """
+ def function_withspecialcase(arg):
+ return repr(arg)
+ register_external(function_withspecialcase, args=None, result=str)
+
+ def f():
+ x = function_withspecialcase
+ return x(33) + x("aaa") + x([]) + "\n"
+
+ policy = AnnotatorPolicy()
+ policy.allow_someobjects = False
+ a = RPythonAnnotator(policy=policy)
+ s = a.build_types(f, [])
+ assert isinstance(s, annmodel.SomeString)
Modified: pypy/branch/x86-64-jit-backend/pypy/rpython/test/test_rstr.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/rpython/test/test_rstr.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/rpython/test/test_rstr.py Tue Jul 20 20:55:30 2010
@@ -131,7 +131,7 @@
s = c * mul
res = 0
for i in range(len(s)):
- res = res*10 + ord(const(s[i])) - ord(const('0'))
+ res = res*10 + ord(const(s[i])[0]) - ord(const('0')[0])
c2 = c
c2 *= mul
res = 10 * res + (c2 == s)
@@ -577,7 +577,7 @@
sum = 0
for num in l:
if len(num):
- sum += ord(num) - ord(const('0'))
+ sum += ord(num[0]) - ord(const('0')[0])
return sum + len(l) * 100
for i in range(5):
res = self.interpret(fn, [i])
@@ -863,6 +863,24 @@
res = self.interpret(f, [1])
assert self.ll_to_string(res) == "hello"
+ def test_str_unichar(self):
+ def f(i):
+ c = u"abc"
+ return str(c[i])[0]
+ assert self.interpret(f, [1]) == "b"
+
+ def test_encode_char(self):
+ def f(i):
+ c = u"abc"
+ return c[i].encode("ascii")
+ assert self.ll_to_string(self.interpret(f, [0])) == "a"
+
+ def test_encode_char_latin1(self):
+ def f(i):
+ c = u"abc"
+ return c[i].encode("latin-1")
+ assert self.ll_to_string(self.interpret(f, [0])) == "a"
+
def FIXME_test_str_to_pystringobj():
def f(n):
if n >= 0:
Modified: pypy/branch/x86-64-jit-backend/pypy/translator/c/test/test_typed.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/translator/c/test/test_typed.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/translator/c/test/test_typed.py Tue Jul 20 20:55:30 2010
@@ -789,3 +789,37 @@
return u'hello' + unichr(i)
f = self.getcompiled(func, [int])
assert f(0x1234) == u'hello\u1234'
+
+ def test_ovfcheck_float_to_int(self):
+ from pypy.rlib.rarithmetic import ovfcheck_float_to_int
+
+ def func(fl):
+ try:
+ return ovfcheck_float_to_int(fl)
+ except OverflowError:
+ return -666
+ f = self.getcompiled(func, [float])
+ assert f(-123.0) == -123
+
+ for frac in [0.0, 0.01, 0.99]:
+ # strange things happening for float to int on 64 bit:
+ # int(float(i)) != i because of rounding issues
+ x = sys.maxint
+ while int(x + frac) > sys.maxint:
+ x -= 1
+ assert f(x + frac) == int(x + frac)
+
+ x = sys.maxint
+ while int(x - frac) <= sys.maxint:
+ x += 1
+ assert f(x - frac) == -666
+
+ x = -sys.maxint-1
+ while int(x - frac) < -sys.maxint-1:
+ x += 1
+ assert f(x - frac) == int(x - frac)
+
+ x = -sys.maxint-1
+ while int(x + frac) >= -sys.maxint-1:
+ x -= 1
+ assert f(x + frac) == -666
Modified: pypy/branch/x86-64-jit-backend/pypy/translator/platform/__init__.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/translator/platform/__init__.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/translator/platform/__init__.py Tue Jul 20 20:55:30 2010
@@ -161,7 +161,7 @@
return (library_dirs + self.link_flags + export_flags +
link_files + list(eci.link_extra) + libraries)
- def _exportsymbols_link_flags(self, eci):
+ def _exportsymbols_link_flags(self, eci, relto=None):
if eci.export_symbols:
raise ValueError("This platform does not support export symbols")
return []
Modified: pypy/branch/x86-64-jit-backend/pypy/translator/platform/darwin.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/translator/platform/darwin.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/translator/platform/darwin.py Tue Jul 20 20:55:30 2010
@@ -56,7 +56,7 @@
include_dirs = self._includedirs(eci.include_dirs)
return (args + frameworks + include_dirs)
- def _exportsymbols_link_flags(self, eci):
+ def _exportsymbols_link_flags(self, eci, relto=None):
if not eci.export_symbols:
return []
@@ -65,6 +65,9 @@
for sym in eci.export_symbols:
f.write("_%s\n" % (sym,))
f.close()
+
+ if relto:
+ response_file = relto.bestrelpath(response_file)
return ["-Wl,-exported_symbols_list,%s" % (response_file,)]
class Darwin_i386(Darwin):
Modified: pypy/branch/x86-64-jit-backend/pypy/translator/platform/posix.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/translator/platform/posix.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/translator/platform/posix.py Tue Jul 20 20:55:30 2010
@@ -39,7 +39,7 @@
def _link_args_from_eci(self, eci, standalone):
return Platform._link_args_from_eci(self, eci, standalone)
- def _exportsymbols_link_flags(self, eci):
+ def _exportsymbols_link_flags(self, eci, relto=None):
if not eci.export_symbols:
return []
@@ -50,6 +50,9 @@
f.write("%s;\n" % (sym,))
f.write("};")
f.close()
+
+ if relto:
+ response_file = relto.bestrelpath(response_file)
return ["-Wl,--export-dynamic,--version-script=%s" % (response_file,)]
def _link(self, cc, ofiles, link_args, standalone, exe_name):
@@ -90,7 +93,7 @@
if shared:
linkflags = self._args_for_shared(linkflags)
- linkflags += self._exportsymbols_link_flags(eci)
+ linkflags += self._exportsymbols_link_flags(eci, relto=path)
if shared:
libname = exe_name.new(ext='').basename
Modified: pypy/branch/x86-64-jit-backend/pypy/translator/platform/windows.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/translator/platform/windows.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/translator/platform/windows.py Tue Jul 20 20:55:30 2010
@@ -141,7 +141,7 @@
# Windows needs to resolve all symbols even for DLLs
return super(MsvcPlatform, self)._link_args_from_eci(eci, standalone=True)
- def _exportsymbols_link_flags(self, eci):
+ def _exportsymbols_link_flags(self, eci, relto=None):
if not eci.export_symbols:
return []
@@ -150,6 +150,9 @@
for sym in eci.export_symbols:
f.write("/EXPORT:%s\n" % (sym,))
f.close()
+
+ if relto:
+ response_file = relto.bestrelpath(response_file)
return ["@%s" % (response_file,)]
def _compile_c_file(self, cc, cfile, compile_args):
@@ -219,7 +222,7 @@
if shared:
linkflags = self._args_for_shared(linkflags) + [
'/EXPORT:$(PYPY_MAIN_FUNCTION)']
- linkflags += self._exportsymbols_link_flags(eci)
+ linkflags += self._exportsymbols_link_flags(eci, relto=path)
if shared:
so_name = exe_name.new(purebasename='lib' + exe_name.purebasename,
More information about the Pypy-commit
mailing list