[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