Commits

Armin Rigo committed 11a6f13 Merge

hg merge default

Comments (0)

Files changed (39)

lib_pypy/datetime.py

             converter = _time.localtime
         else:
             converter = _time.gmtime
-        if 1 - (t % 1.0) < 0.000001:
-            t = float(int(t)) + 1
-        if t < 0:
-            t -= 1
+        if t < 0.0:
+            us = int(round(((-t) % 1.0) * 1000000))
+            if us > 0:
+                us = 1000000 - us
+                t -= 1.0
+        else:
+            us = int(round((t % 1.0) * 1000000))
+            if us == 1000000:
+                us = 0
+                t += 1.0
         y, m, d, hh, mm, ss, weekday, jday, dst = converter(t)
-        us = int((t % 1.0) * 1000000)
         ss = min(ss, 59)    # clamp out leap seconds if the platform has them
         result = cls(y, m, d, hh, mm, ss, us, tz)
         if tz is not None:

lib_pypy/msvcrt.py

         e = get_errno()
         raise IOError(e, errno.errorcode[e])
 
+# Console I/O routines
+
+kbhit = _c._kbhit
+kbhit.argtypes = []
+kbhit.restype = ctypes.c_int
+
+getch = _c._getch
+getch.argtypes = []
+getch.restype = ctypes.c_char
+
+getwch = _c._getwch
+getwch.argtypes = []
+getwch.restype = ctypes.c_wchar
+
+getche = _c._getche
+getche.argtypes = []
+getche.restype = ctypes.c_char
+
+getwche = _c._getwche
+getwche.argtypes = []
+getwche.restype = ctypes.c_wchar
+
+putch = _c._putch
+putch.argtypes = [ctypes.c_char]
+putch.restype = None
+
+putwch = _c._putwch
+putwch.argtypes = [ctypes.c_wchar]
+putwch.restype = None
+
+ungetch = _c._ungetch
+ungetch.argtypes = [ctypes.c_char]
+ungetch.restype = None
+
+ungetwch = _c._ungetwch
+ungetwch.argtypes = [ctypes.c_wchar]
+ungetwch.restype = None
+
 del ctypes

lib_pypy/pypy_test/test_datetime.py

     assert datetime.datetime.utcfromtimestamp(a).microsecond == 0
     assert datetime.datetime.utcfromtimestamp(a).second == 1
 
-    
+def test_more_datetime_rounding():
+    # this test verified on top of CPython 2.7 (using a plain
+    # "import datetime" above)
+    expected_results = {
+        -1000.0: 'datetime.datetime(1970, 1, 1, 0, 43, 20)',
+        -999.9999996: 'datetime.datetime(1970, 1, 1, 0, 43, 20)',
+        -999.4: 'datetime.datetime(1970, 1, 1, 0, 43, 20, 600000)',
+        -999.0000004: 'datetime.datetime(1970, 1, 1, 0, 43, 21)',
+        -1.0: 'datetime.datetime(1970, 1, 1, 0, 59, 59)',
+        -0.9999996: 'datetime.datetime(1970, 1, 1, 0, 59, 59)',
+        -0.4: 'datetime.datetime(1970, 1, 1, 0, 59, 59, 600000)',
+        -0.0000004: 'datetime.datetime(1970, 1, 1, 1, 0)',
+        0.0: 'datetime.datetime(1970, 1, 1, 1, 0)',
+        0.0000004: 'datetime.datetime(1970, 1, 1, 1, 0)',
+        0.4: 'datetime.datetime(1970, 1, 1, 1, 0, 0, 400000)',
+        0.9999996: 'datetime.datetime(1970, 1, 1, 1, 0, 1)',
+        1000.0: 'datetime.datetime(1970, 1, 1, 1, 16, 40)',
+        1000.0000004: 'datetime.datetime(1970, 1, 1, 1, 16, 40)',
+        1000.4: 'datetime.datetime(1970, 1, 1, 1, 16, 40, 400000)',
+        1000.9999996: 'datetime.datetime(1970, 1, 1, 1, 16, 41)',
+        1293843661.191: 'datetime.datetime(2011, 1, 1, 2, 1, 1, 191000)',
+        }
+    for t in sorted(expected_results):
+        dt = datetime.datetime.fromtimestamp(t)
+        assert repr(dt) == expected_results[t]

pypy/config/pypyoption.py

     "_rawffi": [("objspace.usemodules.struct", True)],
     "cpyext": [("translation.secondaryentrypoints", "cpyext"),
                ("translation.shared", sys.platform == "win32")],
+    "_ffi":    [("translation.jit_ffi", True)],
 }
 
 module_import_dependencies = {

pypy/config/test/test_pypyoption.py

             fn = prefix + "." + path + ".txt"
             yield check_file_exists, fn
 
+def test__ffi_opt():
+    config = get_pypy_config(translating=True)
+    config.objspace.usemodules._ffi = True
+    assert config.translation.jit_ffi

pypy/config/translationoption.py

     ChoiceOption("jit_profiler", "integrate profiler support into the JIT",
                  ["off", "oprofile"],
                  default="off"),
+    # jit_ffi is automatically turned on by withmod-_ffi (which is enabled by default)
+    BoolOption("jit_ffi", "optimize libffi calls", default=False, cmdline=None),
 
     # misc
     BoolOption("verbose", "Print extra information", default=False),

pypy/jit/backend/llsupport/descr.py

 import py
 from pypy.rpython.lltypesystem import lltype, rffi, llmemory, rclass
+from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.jit.backend.llsupport import symbolic, support
 from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr
 from pypy.jit.metainterp.history import BasicFailDescr, LoopToken, BoxFloat
     size = 0      # help translation
     is_immutable = False
 
+    tid = llop.combine_ushort(lltype.Signed, 0, 0)
+
     def __init__(self, size, count_fields_if_immut=-1):
         self.size = size
         self.count_fields_if_immut = count_fields_if_immut
 
 class BaseArrayDescr(AbstractDescr):
     _clsname = ''
+    tid = llop.combine_ushort(lltype.Signed, 0, 0)
 
     def get_base_size(self, translate_support_code):
         basesize, _, _ = symbolic.get_array_token(_A, translate_support_code)

pypy/jit/backend/llsupport/gc.py

         self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
             [llmemory.Address, llmemory.Address], lltype.Void))
         self.WB_ARRAY_FUNCPTR = lltype.Ptr(lltype.FuncType(
-            [llmemory.Address, lltype.Signed], lltype.Void))
+            [llmemory.Address, lltype.Signed, llmemory.Address], lltype.Void))
         self.write_barrier_descr = WriteBarrierDescr(self)
         #
         def malloc_array(itemsize, tid, num_elem):
             newops.append(op)
         return newops
 
-    def _gen_write_barrier(self, newops, v_base, v_value_or_index):
-        # NB. the 2nd argument of COND_CALL_GC_WB is either a pointer
-        # (regular case), or an index (case of write_barrier_from_array)
-        args = [v_base, v_value_or_index]
+    def _gen_write_barrier(self, newops, v_base, v_value):
+        args = [v_base, v_value]
         newops.append(ResOperation(rop.COND_CALL_GC_WB, args, None,
                                    descr=self.write_barrier_descr))
 
             length = known_lengths.get(v_base, LARGE)
             if length >= LARGE:
                 # unknown or too big: produce a write_barrier_from_array
-                self._gen_write_barrier(newops, v_base, v_index)
+                args = [v_base, v_value, v_index]
+                newops.append(ResOperation(rop.COND_CALL_GC_WB_ARRAY, args,
+                                           None,
+                                           descr=self.write_barrier_descr))
                 return
         # fall-back case: produce a write_barrier
         self._gen_write_barrier(newops, v_base, v_value)

pypy/jit/backend/llsupport/test/test_gc.py

                 del operations[:2]
             assert len(operations) == 2
             #
-            assert operations[0].getopnum() == rop.COND_CALL_GC_WB
-            assert operations[0].getarg(0) == v_base
             if isinstance(v_new_length, ConstInt) and v_new_length.value < 130:
+                assert operations[0].getopnum() == rop.COND_CALL_GC_WB
+                assert operations[0].getarg(0) == v_base
                 assert operations[0].getarg(1) == v_value
             else:
-                assert operations[0].getarg(1) == v_index
+                assert operations[0].getopnum() == rop.COND_CALL_GC_WB_ARRAY
+                assert operations[0].getarg(0) == v_base
+                assert operations[0].getarg(1) == v_value
+                assert operations[0].getarg(2) == v_index
             assert operations[0].result is None
             #
             assert operations[1].getopnum() == rop.SETARRAYITEM_RAW

pypy/jit/backend/x86/assembler.py

     def genop_discard_cond_call_gc_wb(self, op, arglocs):
         # Write code equivalent to write_barrier() in the GC: it checks
         # a flag in the object at arglocs[0], and if set, it calls the
-        # function remember_young_pointer() from the GC.  The two arguments
-        # to the call are in arglocs[:2].  The rest, arglocs[2:], contains
+        # function remember_young_pointer() from the GC.  The arguments
+        # to the call are in arglocs[:N].  The rest, arglocs[N:], contains
         # registers that need to be saved and restored across the call.
-        # If op.getarg(1) is a int, it is an array index and we must call
-        # instead remember_young_pointer_from_array().
+        # N is either 2 (regular write barrier) or 3 (array write barrier).
         descr = op.getdescr()
         if we_are_translated():
             cls = self.cpu.gc_ll_descr.has_write_barrier_class()
             assert cls is not None and isinstance(descr, cls)
+        #
+        opnum = op.getopnum()
+        if opnum == rop.COND_CALL_GC_WB:
+            N = 2
+            func = descr.get_write_barrier_fn(self.cpu)
+        elif opnum == rop.COND_CALL_GC_WB_ARRAY:
+            N = 3
+            func = descr.get_write_barrier_from_array_fn(self.cpu)
+            assert func != 0
+        else:
+            raise AssertionError(opnum)
+        #
         loc_base = arglocs[0]
         self.mc.TEST8(addr_add_const(loc_base, descr.jit_wb_if_flag_byteofs),
                       imm(descr.jit_wb_if_flag_singlebyte))
         if IS_X86_32:
             limit = -1      # push all arglocs on the stack
         elif IS_X86_64:
-            limit = 1       # push only arglocs[2:] on the stack
+            limit = N - 1   # push only arglocs[N:] on the stack
         for i in range(len(arglocs)-1, limit, -1):
             loc = arglocs[i]
             if isinstance(loc, RegLoc):
                 self.mc.PUSH_r(loc.value)
             else:
-                assert not IS_X86_64 # there should only be regs in arglocs[2:]
+                assert not IS_X86_64 # there should only be regs in arglocs[N:]
                 self.mc.PUSH_i32(loc.getint())
         if IS_X86_64:
             # We clobber these registers to pass the arguments, but that's
             # okay, because consider_cond_call_gc_wb makes sure that any
             # caller-save registers with values in them are present in
-            # arglocs[2:] too, so they are saved on the stack above and
+            # arglocs[N:] too, so they are saved on the stack above and
             # restored below.
-            remap_frame_layout(self, arglocs[:2], [edi, esi],
+            if N == 2:
+                callargs = [edi, esi]
+            else:
+                callargs = [edi, esi, edx]
+            remap_frame_layout(self, arglocs[:N], callargs,
                                X86_64_SCRATCH_REG)
-
-        if op.getarg(1).type == INT:
-            func = descr.get_write_barrier_from_array_fn(self.cpu)
-            assert func != 0
-        else:
-            func = descr.get_write_barrier_fn(self.cpu)
-
+        #
         # misaligned stack in the call, but it's ok because the write barrier
         # is not going to call anything more.  Also, this assumes that the
         # write barrier does not touch the xmm registers.  (Slightly delicate
         # be done properly)
         self.mc.CALL(imm(func))
         if IS_X86_32:
-            self.mc.ADD_ri(esp.value, 2*WORD)
-        for i in range(2, len(arglocs)):
+            self.mc.ADD_ri(esp.value, N*WORD)
+        for i in range(N, len(arglocs)):
             loc = arglocs[i]
             assert isinstance(loc, RegLoc)
             self.mc.POP_r(loc.value)
         assert 0 < offset <= 127
         self.mc.overwrite(jz_location-1, chr(offset))
 
+    genop_discard_cond_call_gc_wb_array = genop_discard_cond_call_gc_wb
+
     def genop_force_token(self, op, arglocs, resloc):
         # RegAlloc.consider_force_token ensures this:
         assert isinstance(resloc, RegLoc)

pypy/jit/backend/x86/regalloc.py

     def consider_cond_call_gc_wb(self, op):
         assert op.result is None
         args = op.getarglist()
-        loc_newvalue_or_index= self.rm.make_sure_var_in_reg(op.getarg(1), args)
-        # ^^^ we force loc_newvalue_or_index in a reg (unless it's a Const),
+        loc_newvalue = self.rm.make_sure_var_in_reg(op.getarg(1), args)
+        # ^^^ we force loc_newvalue in a reg (unless it's a Const),
         # because it will be needed anyway by the following setfield_gc.
         # It avoids loading it twice from the memory.
         loc_base = self.rm.make_sure_var_in_reg(op.getarg(0), args)
-        arglocs = [loc_base, loc_newvalue_or_index]
+        #
+        if len(args) == 2:
+            arglocs = [loc_base, loc_newvalue]    # cond_call_gc_wb
+        else:
+            # cond_call_gc_wb_array
+            loc_arrayindex = self.rm.make_sure_var_in_reg(op.getarg(2), args)
+            arglocs = [loc_base, loc_newvalue, loc_arrayindex]
         # add eax, ecx and edx as extra "arguments" to ensure they are
         # saved and restored.  Fish in self.rm to know which of these
         # registers really need to be saved (a bit of a hack).  Moreover,
         self.PerformDiscard(op, arglocs)
         self.rm.possibly_free_vars_for_op(op)
 
+    consider_cond_call_gc_wb_array = consider_cond_call_gc_wb
+
     def fastpath_malloc_fixedsize(self, op, descr):
         assert isinstance(descr, BaseSizeDescr)
         self._do_fastpath_malloc(op, descr.size, descr.tid)

pypy/jit/metainterp/executor.py

             if value in (rop.FORCE_TOKEN,
                          rop.CALL_ASSEMBLER,
                          rop.COND_CALL_GC_WB,
+                         rop.COND_CALL_GC_WB_ARRAY,
                          rop.DEBUG_MERGE_POINT,
                          rop.JIT_DEBUG,
                          rop.SETARRAYITEM_RAW,

pypy/jit/metainterp/history.py

     Explodes if the annotator only thinks it is an instance of AbstractValue.
     """
     if x is not None:
-        if not we_are_translated() and getattr(x, 'I_am_a_descr', False):
-            return # needed for the mock case in oparser_model
         assert isinstance(x, AbstractDescr)
 
 class Entry(ExtRegistryEntry):

pypy/jit/metainterp/optimizeopt/__init__.py

             ('virtualize', OptVirtualize),
             ('string', OptString),
             ('heap', OptHeap),
-            ('ffi', OptFfiCall),
+            ('ffi', None),
             ('unroll', None)]
 # no direct instantiation of unroll
 unroll_all_opts = unrolling_iterable(ALL_OPTS)
 ALL_OPTS_NAMES = ':'.join([name for name, _ in ALL_OPTS])
 PARAMETERS['enable_opts'] = ALL_OPTS_NAMES
 
-def optimize_loop_1(metainterp_sd, loop, enable_opts,
+def build_opt_chain(metainterp_sd, enable_opts,
                     inline_short_preamble=True, retraced=False):
-    """Optimize loop.operations to remove internal overheadish operations.
-    """
+    config = metainterp_sd.config
     optimizations = []
     unroll = 'unroll' in enable_opts
     for name, opt in unroll_all_opts:
                 # FIXME: Workaround to disable string optimisation
                 # during preamble but to keep it during the loop
                 optimizations.append(o)
+            elif name == 'ffi' and config.translation.jit_ffi:
+                # we cannot put the class directly in the unrolling_iterable,
+                # because we do not want it to be seen at all (to avoid to
+                # introduce a dependency on libffi in case we do not need it)
+                optimizations.append(OptFfiCall())
 
     if ('rewrite' not in enable_opts or 'virtualize' not in enable_opts
         or 'heap' not in enable_opts):
     if inline_short_preamble:
         optimizations = [OptInlineShortPreamble(retraced)] + optimizations
 
+    return optimizations, unroll
+
+
+def optimize_loop_1(metainterp_sd, loop, enable_opts,
+                    inline_short_preamble=True, retraced=False):
+    """Optimize loop.operations to remove internal overheadish operations.
+    """
+
+    optimizations, unroll = build_opt_chain(metainterp_sd, enable_opts,
+                                            inline_short_preamble, retraced)
+
     if unroll:
         optimize_unroll(metainterp_sd, loop, optimizations)
     else:

pypy/jit/metainterp/pyjitpl.py

     logger_ops = None
 
     def __init__(self, cpu, options,
-                 ProfilerClass=EmptyProfiler, warmrunnerdesc=None,
-                 jit_ffi=True):
+                 ProfilerClass=EmptyProfiler, warmrunnerdesc=None):
         self.cpu = cpu
         self.stats = self.cpu.stats
         self.options = options
         self.profiler = ProfilerClass()
         self.profiler.cpu = cpu
         self.warmrunnerdesc = warmrunnerdesc
-        self.jit_ffi = jit_ffi
+        if warmrunnerdesc:
+            self.config = warmrunnerdesc.translator.config
+        else:
+            from pypy.config.pypyoption import get_pypy_config
+            self.config = get_pypy_config(translating=True)
 
         backendmodule = self.cpu.__module__
         backendmodule = backendmodule.split('.')[-2]

pypy/jit/metainterp/resoperation.py

         # of the operation.  It must inherit from AbstractDescr.  The
         # backend provides it with cpu.fielddescrof(), cpu.arraydescrof(),
         # cpu.calldescrof(), and cpu.typedescrof().
+        self._check_descr(descr)
+        self._descr = descr
+
+    def _check_descr(self, descr):
+        if not we_are_translated() and getattr(descr, 'I_am_a_descr', False):
+            return # needed for the mock case in oparser_model
         from pypy.jit.metainterp.history import check_descr
         check_descr(descr)
-        self._descr = descr
+
 
 class GuardResOp(ResOpWithDescr):
 
     'STRSETITEM/3',
     'UNICODESETITEM/3',
     #'RUNTIMENEW/1',     # ootype operation
-    'COND_CALL_GC_WB/2d', # [objptr, newvalue] or [arrayptr, index]
-                          # (for the write barrier, latter is in an array)
+    'COND_CALL_GC_WB/2d', # [objptr, newvalue] (for the write barrier)
+    'COND_CALL_GC_WB_ARRAY/3d', # [objptr, newvalue, arrayindex] (write barr.)
     'DEBUG_MERGE_POINT/*',      # debugging only
     'JIT_DEBUG/*',              # debugging only
     'VIRTUAL_REF_FINISH/2',   # removed before it's passed to the backend

pypy/jit/metainterp/test/test_compile.py

     stats = Stats()
     profiler = jitprof.EmptyProfiler()
     warmrunnerdesc = None
-    jit_ffi = False
     def log(self, msg, event_kind=None):
         pass
 

pypy/jit/metainterp/test/test_optimizebasic.py

 
 class BaseTestBasic(BaseTest):
 
-    def invent_fail_descr(self, fail_args):
+    def invent_fail_descr(self, model, fail_args):
         if fail_args is None:
             return None
         descr = Storage()

pypy/jit/metainterp/test/test_optimizefficall.py

 
 
 class TestFfiCall(BaseTestBasic, LLtypeMixin):
-    jit_ffi = True
 
     class namespace:
         cpu = LLtypeMixin.cpu

pypy/jit/metainterp/test/test_optimizeopt.py

                                                         BaseTest)
 import pypy.jit.metainterp.optimizeopt.optimizer as optimizeopt
 import pypy.jit.metainterp.optimizeopt.virtualize as virtualize
-from pypy.jit.metainterp.optimizeopt import optimize_loop_1, ALL_OPTS_DICT
+from pypy.jit.metainterp.optimizeopt import optimize_loop_1, ALL_OPTS_DICT, build_opt_chain
 from pypy.jit.metainterp.optimizeutil import InvalidLoop
 from pypy.jit.metainterp.history import AbstractDescr, ConstInt, BoxInt
 from pypy.jit.metainterp.history import TreeLoop, LoopToken
 from pypy.jit.tool.oparser import pure_parse
 from pypy.jit.metainterp.test.test_optimizebasic import equaloplists
 from pypy.jit.metainterp.optimizeutil import args_dict
+from pypy.config.pypyoption import get_pypy_config
 
 class Fake(object):
     failargs_limit = 1000
 
 class FakeMetaInterpStaticData(object):
 
-    def __init__(self, cpu, jit_ffi=False):
+    def __init__(self, cpu):
         self.cpu = cpu
         self.profiler = EmptyProfiler()
         self.options = Fake()
         self.globaldata = Fake()
-        self.jit_ffi = jit_ffi
+        self.config = get_pypy_config(translating=True)
+        self.config.translation.jit_ffi = True
+
+
+def test_build_opt_chain():
+    def check(chain, expected_names):
+        names = [opt.__class__.__name__ for opt in chain]
+        assert names == expected_names
+    #
+    metainterp_sd = FakeMetaInterpStaticData(None)
+    chain, _ = build_opt_chain(metainterp_sd, "", inline_short_preamble=False)
+    check(chain, ["OptSimplify"])
+    #
+    chain, _ = build_opt_chain(metainterp_sd, "")
+    check(chain, ["OptInlineShortPreamble", "OptSimplify"])
+    #
+    chain, _ = build_opt_chain(metainterp_sd, "")
+    check(chain, ["OptInlineShortPreamble", "OptSimplify"])
+    #
+    chain, _ = build_opt_chain(metainterp_sd, "heap:intbounds")
+    check(chain, ["OptInlineShortPreamble", "OptIntBounds", "OptHeap", "OptSimplify"])
+    #
+    chain, unroll = build_opt_chain(metainterp_sd, "unroll")
+    check(chain, ["OptInlineShortPreamble", "OptSimplify"])
+    assert unroll
+    #
+    chain, _ = build_opt_chain(metainterp_sd, "aaa:bbb", inline_short_preamble=False)
+    check(chain, ["OptSimplify"])
+    #
+    chain, _ = build_opt_chain(metainterp_sd, "ffi", inline_short_preamble=False)
+    check(chain, ["OptFfiCall", "OptSimplify"])
+    #
+    metainterp_sd.config = get_pypy_config(translating=True)
+    assert not metainterp_sd.config.translation.jit_ffi
+    chain, _ = build_opt_chain(metainterp_sd, "ffi", inline_short_preamble=False)
+    check(chain, ["OptSimplify"])
+
 
 def test_store_final_boxes_in_guard():
     from pypy.jit.metainterp.compile import ResumeGuardDescr
     return sorted(boxes, key=lambda box: _kind2count[box.type])
 
 class BaseTestOptimizeOpt(BaseTest):
-    jit_ffi = False
-
-    def invent_fail_descr(self, fail_args):
+
+    def invent_fail_descr(self, model, fail_args):
         if fail_args is None:
             return None
         descr = Storage()
         loop.preamble = TreeLoop('preamble')
         loop.preamble.inputargs = loop.inputargs
         loop.preamble.token = LoopToken()
-        metainterp_sd = FakeMetaInterpStaticData(self.cpu, self.jit_ffi)
+        metainterp_sd = FakeMetaInterpStaticData(self.cpu)
         if hasattr(self, 'vrefinfo'):
             metainterp_sd.virtualref_info = self.vrefinfo
         if hasattr(self, 'callinfocollection'):

pypy/jit/tool/oparser.py

         return FORCE_SPILL(self.OPNUM, self.getarglist()[:])
 
 
-def default_fail_descr(fail_args=None):
-    from pypy.jit.metainterp.history import BasicFailDescr
-    return BasicFailDescr()
+def default_fail_descr(model, fail_args=None):
+    return model.BasicFailDescr()
 
 
 class OpParser(object):
                                 "Unknown var in fail_args: %s" % arg)
                     fail_args.append(fail_arg)
             if descr is None and self.invent_fail_descr:
-                descr = self.invent_fail_descr(fail_args)
+                descr = self.invent_fail_descr(self.model, fail_args)
             if hasattr(descr, '_oparser_uses_descr_of_guard'):
                 descr._oparser_uses_descr_of_guard(self, fail_args)
         else:
             fail_args = None
             if opnum == rop.FINISH:
                 if descr is None and self.invent_fail_descr:
-                    descr = self.invent_fail_descr()
+                    descr = self.invent_fail_descr(self.model)
             elif opnum == rop.JUMP:
                 if descr is None and self.invent_fail_descr:
                     descr = self.looptoken

pypy/jit/tool/oparser_model.py

         from pypy.jit.metainterp.history import TreeLoop, LoopToken
         from pypy.jit.metainterp.history import Box, BoxInt, BoxFloat
         from pypy.jit.metainterp.history import ConstInt, ConstObj, ConstPtr, ConstFloat
+        from pypy.jit.metainterp.history import BasicFailDescr
         from pypy.jit.metainterp.typesystem import llhelper
 
         from pypy.jit.metainterp.history import get_const_ptr_for_string
         class LoopToken(object):
             I_am_a_descr = True
 
+        class BasicFailDescr(object):
+            I_am_a_descr = True
+
         class Box(object):
             _counter = 0
             type = 'b'

pypy/jit/tool/test/test_oparser.py

 import py
+import sys
 from pypy.rpython.lltypesystem import lltype, llmemory
 
 from pypy.jit.tool.oparser import parse, OpParser
 
     def test_descr(self):
         class Xyz(AbstractDescr):
-            pass
+            I_am_a_descr = True # for the mock case
 
         x = """
         [p0]
 
     def test_descr_setfield(self):
         class Xyz(AbstractDescr):
-            pass
+            I_am_a_descr = True # for the mock case
 
         x = """
         [p0]
 
     def test_jump_target_other(self):
         looptoken = LoopToken()
+        looptoken.I_am_a_descr = True # for the mock case
         x = '''
         []
         jump(descr=looptoken)
         assert isinstance(b.sum0, BoxInt)
 
 
+class ForbiddenModule(object):
+    def __init__(self, name, old_mod):
+        self.name = name
+        self.old_mod = old_mod
+
+    def __getattr__(self, attr):
+        assert False, "You should not import module %s" % self.name
+
 
 class TestOpParserWithMock(BaseTestOparser):
 
     class OpParser(OpParser):
         use_mock_model = True
+
+    def setup_class(cls):
+        forbidden_mods = [
+            'pypy.jit.metainterp.history',
+            'pypy.rpython.lltypesystem.lltype',
+            ]
+        for modname in forbidden_mods:
+            if modname in sys.modules:
+                newmod = ForbiddenModule(modname, sys.modules[modname])
+                sys.modules[modname] = newmod
+
+    def teardown_class(cls):
+        for modname, mod in sys.modules.iteritems():
+            if isinstance(mod, ForbiddenModule):
+                sys.modules[modname] = mod.old_mod

pypy/module/array/interp_array.py

 
     def array_tostring__Array(space, self):
         cbuf = self.charbuf()
-        s = ''.join([cbuf[i] for i in xrange(self.len * mytype.bytes)])
-        return self.space.wrap(s)
-##
-##         s = ''
-##         i = 0
-##         while i < self.len * mytype.bytes:
-##             s += cbuf[i]
-##             i += 1
-##         return self.space.wrap(s)
+        return self.space.wrap(rffi.charpsize2str(cbuf, self.len * mytype.bytes))
 
     def array_fromfile__Array_ANY_ANY(space, self, w_f, w_n):
         if not isinstance(w_f, W_File):

pypy/module/micronumpy/__init__.py

     interpleveldefs = {
         'array': 'interp_numarray.SingleDimArray',
         'zeros': 'interp_numarray.zeros',
+        'empty': 'interp_numarray.zeros',
 
         # ufuncs
         'absolute': 'interp_ufuncs.absolute',

pypy/module/micronumpy/compile.py

+
+""" This is a set of tools for standalone compiling of numpy expressions.
+It should not be imported by the module itself
+"""
+
+from pypy.module.micronumpy.interp_numarray import FloatWrapper, SingleDimArray
+
+class BogusBytecode(Exception):
+    pass
+
+def create_array(size):
+    a = SingleDimArray(size)
+    for i in range(size):
+        a.storage[i] = float(i % 10)
+    return a
+
+class TrivialSpace(object):
+    def wrap(self, x):
+        return x
+
+def numpy_compile(bytecode, array_size):
+    space = TrivialSpace()
+    stack = []
+    i = 0
+    for b in bytecode:
+        if b == 'a':
+            stack.append(create_array(array_size))
+            i += 1
+        elif b == 'f':
+            stack.append(FloatWrapper(1.2))
+        elif b == '+':
+            right = stack.pop()
+            stack.append(stack.pop().descr_add(space, right))
+        elif b == '-':
+            right = stack.pop()
+            stack.append(stack.pop().descr_sub(space, right))
+        elif b == '*':
+            right = stack.pop()
+            stack.append(stack.pop().descr_mul(space, right))
+        elif b == '/':
+            right = stack.pop()
+            stack.append(stack.pop().descr_div(space, right))
+        else:
+            print "Unknown opcode: %s" % b
+            raise BogusBytecode()
+    if len(stack) != 1:
+        print "Bogus bytecode, uneven stack length"
+        raise BogusBytecode()
+    return stack[0]

pypy/module/micronumpy/interp_numarray.py

     def invalidated(self):
         for arr in self.invalidates:
             arr.force_if_needed()
-        self.invalidates = []
+        del self.invalidates[:]
 
     def _binop_impl(function):
         signature = Signature()
     def descr_len(self, space):
         return self.get_concrete().descr_len(space)
 
-    @unwrap_spec(item=int)
-    def descr_getitem(self, space, item):
-        return self.get_concrete().descr_getitem(space, item)
+    def descr_getitem(self, space, w_idx):
+        # TODO: indexing by tuples
+        start, stop, step, slice_length = space.decode_index4(w_idx, self.find_size())
+        if step == 0:
+            # Single index
+            return space.wrap(self.get_concrete().getitem(start))
+        else:
+            # Slice
+            res = SingleDimSlice(start, stop, step, slice_length, self, self.signature.transition(SingleDimSlice.static_signature))
+            return space.wrap(res)
 
     @unwrap_spec(item=int, value=float)
     def descr_setitem(self, space, item, value):
         self.invalidated()
         return self.get_concrete().descr_setitem(space, item, value)
 
-
 class FloatWrapper(BaseArray):
     """
     Intermediate class representing a float literal.
         self.forced_result = None
         self.signature = signature
 
+    def _del_sources(self):
+        # Function for deleting references to source arrays, to allow garbage-collecting them
+        raise NotImplementedError
+
     def compute(self):
         i = 0
         signature = self.signature
     def force_if_needed(self):
         if self.forced_result is None:
             self.forced_result = self.compute()
+            self._del_sources()
 
     def get_concrete(self):
         self.force_if_needed()
             return self.forced_result.eval(i)
         return self._eval(i)
 
+    def find_size(self):
+        if self.forced_result is not None:
+            # The result has been computed and sources may be unavailable
+            return self.forced_result.find_size()
+        return self._find_size()
+
+
 class Call1(VirtualArray):
     _immutable_fields_ = ["function", "values"]
 
         self.function = function
         self.values = values
 
-    def find_size(self):
+    def _del_sources(self):
+        self.values = None
+
+    def _find_size(self):
         return self.values.find_size()
 
     def _eval(self, i):
         self.left = left
         self.right = right
 
-    def find_size(self):
+    def _del_sources(self):
+        self.left = None
+        self.right = None
+
+    def _find_size(self):
         try:
             return self.left.find_size()
         except ValueError:
         lhs, rhs = self.left.eval(i), self.right.eval(i)
         return self.function(lhs, rhs)
 
+class ViewArray(BaseArray):
+    """
+    Class for representing views of arrays, they will reflect changes of parrent arrays. Example: slices
+    """
+    _immutable_fields_ = ["parent"]
+    def __init__(self, parent, signature):
+        BaseArray.__init__(self)
+        self.signature = signature
+        self.parent = parent
+        self.invalidates = parent.invalidates
+
+    def get_concrete(self):
+        return self # in fact, ViewArray never gets "concrete" as it never stores data. This implementation is needed for BaseArray getitem/setitem to work, can be refactored.
+
+    def eval(self, i):
+        return self.parent.eval(self.calc_index(i))
+
+    def getitem(self, item):
+        return self.parent.getitem(self.calc_index(item))
+
+    @unwrap_spec(item=int, value=float)
+    def descr_setitem(self, space, item, value):
+        return self.parent.descr_setitem(space, self.calc_index(item), value)
+
+    def descr_len(self, space):
+        return space.wrap(self.find_size())
+
+    def calc_index(self, item):
+        raise NotImplementedError
+
+class SingleDimSlice(ViewArray):
+    _immutable_fields_ = ["start", "stop", "step", "size"]
+    static_signature = Signature()
+
+    def __init__(self, start, stop, step, slice_length, parent, signature):
+        ViewArray.__init__(self, parent, signature)
+        self.start = start
+        self.stop = stop
+        self.step = step
+        self.size = slice_length
+
+    def find_size(self):
+        return self.size
+
+    def calc_index(self, item):
+        return (self.start + item * self.step)
+
 
 class SingleDimArray(BaseArray):
     signature = Signature()
     def descr_len(self, space):
         return space.wrap(self.size)
 
-    @unwrap_spec(item=int)
-    def descr_getitem(self, space, item):
-        item = self.getindex(space, item)
-        return space.wrap(self.storage[item])
+    def getitem(self, item):
+        return self.storage[item]
 
     @unwrap_spec(item=int, value=float)
     def descr_setitem(self, space, item, value):
     __sub__ = interp2app(BaseArray.descr_sub),
     __mul__ = interp2app(BaseArray.descr_mul),
     __div__ = interp2app(BaseArray.descr_div),
-)
+)

pypy/module/micronumpy/test/test_base.py

         v3 = ar.descr_add(space, FloatWrapper(1.0))
         assert v2.signature is v3.signature
         v4 = ar.descr_add(space, ar)
-        assert v1.signature is v4.signature
+        assert v1.signature is v4.signature
+
+    def test_slice_signature(self, space):
+        ar = SingleDimArray(10)
+        v1 = ar.descr_getitem(space, space.wrap(slice(1, 5, 1)))
+        v2 = ar.descr_getitem(space, space.wrap(slice(4, 6, 1)))
+        assert v1.signature is v2.signature
+
+        v3 = ar.descr_add(space, v1)
+        v4 = ar.descr_add(space, v2)
+        assert v3.signature is v4.signature

pypy/module/micronumpy/test/test_numarray.py

         a[13] = 5.3
         assert a[13] == 5.3
 
+    def test_empty(self):
+        """
+        Test that empty() works.
+        """
+
+        from numpy import empty
+        a = empty(2)
+        a[1] = 1.0
+        assert a[1] == 1.0
+
     def test_iterator_init(self):
         from numpy import array
         a = array(range(5))
         b = a + a
         c = b + b
         b[1] = 5
-        assert c[1] == 4
+        assert c[1] == 4
+
+    def test_getslice(self):
+        from numpy import array
+        a = array(range(5))
+        s = a[1:5]
+        assert len(s) == 4
+        for i in range(4):
+            assert s[i] == a[i+1]
+
+    def test_getslice_step(self):
+        from numpy import array
+        a = array(range(10))
+        s = a[1:9:2]
+        assert len(s) == 4
+        for i in range(4):
+            assert s[i] == a[2*i+1]
+        
+    def test_slice_update(self):
+        from numpy import array
+        a = array(range(5))
+        s = a[0:3]
+        s[1] = 10
+        assert a[1] == 10
+        a[2] = 20
+        assert s[2] == 20
+
+
+    def test_slice_invaidate(self):
+        # check that slice shares invalidation list with 
+        from numpy import array
+        a = array(range(5))
+        s = a[0:2]
+        b = array([10,11])
+        c = s + b
+        a[0]=100
+        assert c[0] == 10
+        assert c[1] == 12
+        d = s + b
+        a[1]=101
+        assert d[0] == 110
+        assert d[1] == 12
+

pypy/module/micronumpy/test/test_zjit.py

 from pypy.jit.metainterp.test.support import LLJitMixin
+from pypy.rpython.test.test_llinterp import interpret
 from pypy.module.micronumpy.interp_numarray import (SingleDimArray, Signature,
-    FloatWrapper, Call1, Call2, add, mul)
+    FloatWrapper, Call1, Call2, SingleDimSlice, add, mul)
 from pypy.module.micronumpy.interp_ufuncs import negative
-
+from pypy.module.micronumpy.compile import numpy_compile
 
 class FakeSpace(object):
     pass
 
         self.meta_interp(f, [5], listops=True, backendopt=True)
         # This is 3, not 2 because there is a bridge for the exit.
-        self.check_loop_count(3)
+        self.check_loop_count(3)
+
+    def test_slice(self):
+        space = self.space
+
+        def f(i):
+            step = 3
+            ar = SingleDimArray(step*i)
+            s = SingleDimSlice(0, step*i, step, i, ar, ar.signature.transition(SingleDimSlice.static_signature))
+            v = Call2(add, s, s, Signature())
+            return v.get_concrete().storage[3]
+
+        result = self.meta_interp(f, [5], listops=True, backendopt=True)
+        self.check_loops({'int_mul': 1, 'getarrayitem_raw': 2, 'float_add': 1,
+                          'setarrayitem_raw': 1, 'int_add': 1,
+                          'int_lt': 1, 'guard_true': 1, 'jump': 1})
+        assert result == f(5)
+
+    def test_slice2(self):
+        space = self.space
+
+        def f(i):
+            step1 = 2
+            step2 = 3
+            ar = SingleDimArray(step2*i)
+            s1 = SingleDimSlice(0, step1*i, step1, i, ar, ar.signature.transition(SingleDimSlice.static_signature))
+            s2 = SingleDimSlice(0, step2*i, step2, i, ar, ar.signature.transition(SingleDimSlice.static_signature))
+            v = Call2(add, s1, s2, Signature())
+            return v.get_concrete().storage[3]
+
+        result = self.meta_interp(f, [5], listops=True, backendopt=True)
+        self.check_loops({'int_mul': 2, 'getarrayitem_raw': 2, 'float_add': 1,
+                          'setarrayitem_raw': 1, 'int_add': 1,
+                          'int_lt': 1, 'guard_true': 1, 'jump': 1})
+        assert result == f(5)
+
+class TestTranslation(object):
+    def test_compile(self):
+        x = numpy_compile('aa+f*f/a-', 10)
+        x = x.compute()
+        assert isinstance(x, SingleDimArray)
+        assert x.size == 10
+        assert x.storage[0] == 0
+        assert x.storage[1] == ((1 + 1) * 1.2) / 1.2 - 1
+    
+    def test_translation(self):
+        # we import main to check if the target compiles
+        from pypy.translator.goal.targetnumpystandalone import main
+        from pypy.rpython.annlowlevel import llstr
+        
+        interpret(main, [llstr('af+'), 100])

pypy/rlib/clibffi.py

 import sys
 import ctypes.util
 
+from pypy.tool.ansi_print import ansi_log
+log = py.log.Producer("libffi")
+py.log.setconsumer("libffi", ansi_log)
+
 # maaaybe isinstance here would be better. Think
 _MSVC = platform.name == "msvc"
 _MINGW = platform.name == "mingw32"
             result = os.path.join(dir, 'libffi.a')
             if os.path.exists(result):
                 return result
-        raise ImportError("'libffi.a' not found in %s" % (dirlist,))
+        log.WARNING("'libffi.a' not found in %s" % (dirlist,))
+        log.WARNING("trying to use the dynamic library instead...")
+        return None
 
+    path_libffi_a = None
     if hasattr(platform, 'library_dirs_for_libffi_a'):
+        path_libffi_a = find_libffi_a()
+    if path_libffi_a is not None:
         # platforms on which we want static linking
         libraries = []
-        link_files = [find_libffi_a()]
+        link_files = [path_libffi_a]
     else:
         # platforms on which we want dynamic linking
         libraries = ['ffi']

pypy/rlib/ropenssl.py

 
 def external(name, argtypes, restype, **kw):
     kw['compilation_info'] = eci
-    eci.export_symbols += (name,)
+    if not kw.get('macro', False):
+        eci.export_symbols += (name,)
     return rffi.llexternal(
         name, argtypes, restype, **kw)
 

pypy/rpython/lltypesystem/rffi.py

         source = py.code.Source("""
             def call_external_function(%(argnames)s):
                 before = aroundstate.before
-                after = aroundstate.after
                 if before: before()
                 # NB. it is essential that no exception checking occurs here!
                 res = funcptr(%(argnames)s)
+                after = aroundstate.after
                 if after: after()
                 return res
         """ % locals())
         def wrapper(%s):    # no *args - no GIL for mallocing the tuple
             llop.gc_stack_bottom(lltype.Void)   # marker for trackgcroot.py
             if aroundstate is not None:
-                before = aroundstate.before
                 after = aroundstate.after
-            else:
-                before = None
-                after = None
-            if after:
-                after()
+                if after:
+                    after()
             # from now on we hold the GIL
             stackcounter.stacks_counter += 1
             try:
                     traceback.print_exc()
                 result = errorcode
             stackcounter.stacks_counter -= 1
-            if before:
-                before()
+            if aroundstate is not None:
+                before = aroundstate.before
+                if before:
+                    before()
             # here we don't hold the GIL any more. As in the wrapper() produced
             # by llexternal, it is essential that no exception checking occurs
             # after the call to before().

pypy/rpython/memory/gc/minimark.py

     def write_barrier_from_array(self, newvalue, addr_array, index):
         if self.header(addr_array).tid & GCFLAG_NO_YOUNG_PTRS:
             if self.card_page_indices > 0:     # <- constant-folded
-                self.remember_young_pointer_from_array(addr_array, index)
+                self.remember_young_pointer_from_array2(addr_array, index)
             else:
                 self.remember_young_pointer(addr_array, newvalue)
 
 
     def _init_writebarrier_with_card_marker(self):
         DEBUG = self.DEBUG
-        def remember_young_pointer_from_array(addr_array, index):
+        def remember_young_pointer_from_array2(addr_array, index):
             # 'addr_array' is the address of the object in which we write,
             # which must have an array part;  'index' is the index of the
             # item that is (or contains) the pointer that we write.
             #
             # We set the flag (even if the newly written address does not
             # actually point to the nursery, which seems to be ok -- actually
-            # it seems more important that remember_young_pointer_from_array()
+            # it seems more important that remember_young_pointer_from_array2()
             # does not take 3 arguments).
             addr_byte.char[0] = chr(byte | bitmask)
             #
                 self.old_objects_with_cards_set.append(addr_array)
                 objhdr.tid |= GCFLAG_CARDS_SET
 
-        remember_young_pointer_from_array._dont_inline_ = True
+        remember_young_pointer_from_array2._dont_inline_ = True
         assert self.card_page_indices > 0
-        self.remember_young_pointer_from_array = (
-            remember_young_pointer_from_array)
+        self.remember_young_pointer_from_array2 = (
+            remember_young_pointer_from_array2)
+
+        # xxx trying it out for the JIT: a 3-arguments version of the above
+        def remember_young_pointer_from_array3(addr_array, index, newvalue):
+            if DEBUG:   # note: PYPY_GC_DEBUG=1 does not enable this
+                ll_assert(self.debug_is_old_object(addr_array),
+                          "young array with GCFLAG_NO_YOUNG_PTRS")
+            objhdr = self.header(addr_array)
+            #
+            # a single check for the common case of neither GCFLAG_HAS_CARDS
+            # nor GCFLAG_NO_HEAP_PTRS
+            if objhdr.tid & (GCFLAG_HAS_CARDS | GCFLAG_NO_HEAP_PTRS) == 0:
+                # common case: fast path, jump to the end of the function
+                pass
+            elif objhdr.tid & GCFLAG_HAS_CARDS == 0:
+                # no cards, but GCFLAG_NO_HEAP_PTRS is set.
+                objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
+                self.prebuilt_root_objects.append(addr_array)
+                # jump to the end of the function
+            else:
+                # case with cards.
+                #
+                # If the newly written address does not actually point to the
+                # nursery, leave now.
+                if not self.appears_to_be_young(newvalue):
+                    return
+                #
+                # 'addr_array' is a raw_malloc'ed array with card markers
+                # in front.  Compute the index of the bit to set:
+                bitindex = index >> self.card_page_shift
+                byteindex = bitindex >> 3
+                bitmask = 1 << (bitindex & 7)
+                #
+                # If the bit is already set, leave now.
+                size_gc_header = self.gcheaderbuilder.size_gc_header
+                addr_byte = addr_array - size_gc_header
+                addr_byte = llarena.getfakearenaaddress(addr_byte) + \
+                            (~byteindex)
+                byte = ord(addr_byte.char[0])
+                if byte & bitmask:
+                    return
+                addr_byte.char[0] = chr(byte | bitmask)
+                #
+                if objhdr.tid & GCFLAG_CARDS_SET == 0:
+                    self.old_objects_with_cards_set.append(addr_array)
+                    objhdr.tid |= GCFLAG_CARDS_SET
+                return
+            #
+            # Logic for the no-cards case, put here to minimize the number
+            # of checks done at the start of the function
+            if self.appears_to_be_young(newvalue):
+                self.old_objects_pointing_to_young.append(addr_array)
+                objhdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
+
+        remember_young_pointer_from_array3._dont_inline_ = True
+        assert self.card_page_indices > 0
+        self.remember_young_pointer_from_array3 = (
+            remember_young_pointer_from_array3)
 
 
     def assume_young_pointers(self, addr_struct):

pypy/rpython/memory/gctransform/framework.py

                                             annmodel.SomeInteger()],
                                            annmodel.s_None,
                                            inline=True)
-                func = getattr(gcdata.gc, 'remember_young_pointer_from_array',
+                func = getattr(gcdata.gc, 'remember_young_pointer_from_array3',
                                None)
                 if func is not None:
                     # func should not be a bound method, but a real function
                     self.write_barrier_from_array_failing_case_ptr = \
                                              getfn(func,
                                                    [annmodel.SomeAddress(),
-                                                    annmodel.SomeInteger()],
+                                                    annmodel.SomeInteger(),
+                                                    annmodel.SomeAddress()],
                                                    annmodel.s_None)
         self.statistics_ptr = getfn(GCClass.statistics.im_func,
                                     [s_gc, annmodel.SomeInteger()],

pypy/tool/gcc_cache.py

                 platform.log_errors = False
                 platform.compile(c_files, eci)
             finally:
-                platform.log_errors = _previous
+                del platform.log_errors
+                # ^^^remove from the instance --- needed so that it can
+                # compare equal to another instance without it
+                if platform.log_errors != _previous:
+                    platform.log_errors = _previous
             data = 'True'
             path.write(data)
         except CompilationError, e:

pypy/tool/release/package.py

 It uses 'pypy/translator/goal/pypy-c' and parts of the rest of the working
 copy.  Usage:
 
-    package.py root-pypy-dir [name-of-archive] [name-of-pypy-c]
+    package.py root-pypy-dir [name-of-archive] [name-of-pypy-c] [destination-for-tarball] [pypy-c-path]
 
-Usually you would do:   package.py ../../.. pypy-VER-PLATFORM.
+Usually you would do:   package.py ../../.. pypy-VER-PLATFORM
 The output is found in the directory /tmp/usession-YOURNAME/build/.
 """
 
             zf.close()
         else:
             archive = str(builddir.join(name + '.tar.bz2'))
-            e = os.system('tar --owner=root --group=root --numeric-owner -cvjf ' + archive + " " + name)
+            if sys.platform == 'darwin':
+                e = os.system('tar --numeric-owner -cvjf ' + archive + " " + name)
+            else:
+                e = os.system('tar --owner=root --group=root --numeric-owner -cvjf ' + archive + " " + name)
             if e:
                 raise OSError('"tar" returned exit status %r' % e)
     finally:

pypy/translator/c/gcc/test/msvc/track_and_esp.s

+PUBLIC	??_C@_0BN@BIPHFGBC@pypy_g_ll_math_ll_math_frexp?$AA@ ; `string'
+PUBLIC	_pypy_g_ll_math_ll_math_frexp
+;	COMDAT ??_C@_0BN@BIPHFGBC@pypy_g_ll_math_ll_math_frexp?$AA@
+CONST	SEGMENT
+??_C@_0BN@BIPHFGBC@pypy_g_ll_math_ll_math_frexp?$AA@ DB 'pypy_g_ll_math_l'
+	DB	'l_math_frexp', 00H				; `string'
+; Function compile flags: /Ogtpy
+CONST	ENDS
+;	COMDAT _pypy_g_ll_math_ll_math_frexp
+_TEXT	SEGMENT
+_l_mantissa_0$ = -8					; size = 8
+_l_v21638$ = -8						; size = 8
+_l_x_14$ = 8						; size = 8
+_pypy_g_ll_math_ll_math_frexp PROC			; COMDAT
+
+; 58245: struct pypy_tuple2_0 *pypy_g_ll_math_ll_math_frexp(double l_x_14) {
+
+	push	ebp
+	mov	ebp, esp
+	and	esp, -64				; ffffffc0H
+
+; 58246: 	long *l_exp_p_0; double l_mantissa_0; bool_t l_v21641;
+; 58247: 	bool_t l_v21643; bool_t l_v21644; bool_t l_v21646; bool_t l_v21647;
+; 58248: 	bool_t l_v21652; bool_t l_v21653; bool_t l_v21660; bool_t l_v21666;
+; 58249: 	bool_t l_v21670; bool_t l_v21674; bool_t l_v21676; double l_v21638;
+; 58250: 	long l_v21637; long l_v21649; long l_v21651; long l_v21677;
+; 58251: 	long l_v21678; struct pypy_exceptions_Exception0 *l_v21687;
+; 58252: 	struct pypy_header0 *l_v21654; struct pypy_object0 *l_v21682;
+; 58253: 	struct pypy_object0 *l_v21691; struct pypy_object_vtable0 *l_v21665;
+; 58254: 	struct pypy_object_vtable0 *l_v21669;
+; 58255: 	struct pypy_object_vtable0 *l_v21675;
+; 58256: 	struct pypy_object_vtable0 *l_v21683; struct pypy_tuple2_0 *l_v21640;
+; 58257: 	struct pypy_tuple2_0 *l_v21695; void* l_v21639; void* l_v21648;
+; 58258: 	void* l_v21650; void* l_v21656; void* l_v21658; void* l_v21659;
+; 58259: 	void* l_v21668; void* l_v21672; void* l_v21679; void* l_v21688;
+; 58260: 	void* l_v21696;
+; 58261: 	goto block0;
+; 58262: 
+; 58263:     block0:
+; 58264: 	l_v21641 = pypy_g_ll_math_ll_math_isnan(l_x_14);
+
+	fld	QWORD PTR _l_x_14$[ebp]
+	sub	esp, 52					; 00000034H
+	push	ebx
+	push	esi
+	push	edi
+	sub	esp, 8
+	fstp	QWORD PTR [esp]
+$block0$88239:
+	call	_pypy_g_ll_math_ll_math_isnan
+
+; 58265: 	pypy_asm_gc_nocollect(pypy_g_ll_math_ll_math_isnan);
+; 58266: 	l_v21643 = l_v21641;
+; 58267: 	if (l_v21643) {
+; 58268: 		l_v21637 = 0L;
+; 58269: 		l_v21638 = l_x_14;
+
+	fld	QWORD PTR _l_x_14$[ebp]
+	add	esp, 8
+	test	al, al
+
+; 58270: 		goto block3;
+
+	jne	SHORT $LN10@pypy_g_ll_@159
+
+; 58271: 	}
+; 58272: 	goto block1;
+; 58273: 
+; 58274:     block1:
+; 58275: 	l_v21644 = pypy_g_ll_math_ll_math_isinf(l_x_14);
+
+	sub	esp, 8
+	fstp	QWORD PTR [esp]
+$block1$88243:
+	call	_pypy_g_ll_math_ll_math_isinf
+	add	esp, 8
+
+; 58276: 	pypy_asm_gc_nocollect(pypy_g_ll_math_ll_math_isinf);
+; 58277: 	l_v21646 = l_v21644;
+; 58278: 	if (l_v21646) {
+
+	test	al, al
+	je	SHORT $block2$88245
+
+; 58279: 		l_v21637 = 0L;
+; 58280: 		l_v21638 = l_x_14;
+
+	fld	QWORD PTR _l_x_14$[ebp]
+$LN10@pypy_g_ll_@159:
+
+; 58288: 		goto block14;
+; 58289: 	}
+; 58290: 	l_v21637 = 0L;
+
+	xor	edi, edi
+$LN30@pypy_g_ll_@159:
+
+; 58291: 	l_v21638 = l_x_14;
+; 58292: 	goto block3;
+; 58293: 
+; 58294:     block3:
+; 58295: 	l_v21648 = (&pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC)->ssgc_inst_free;
+
+	mov	esi, DWORD PTR _pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC+4
+	fstp	QWORD PTR _l_v21638$[esp+64]
+
+; 58296: 	OP_RAW_MALLOC_USAGE((0 + ROUND_UP_FOR_ALLOCATION(sizeof(struct pypy_tuple2_0), sizeof(struct pypy_forwarding_stub0))), l_v21649);
+; 58297: 	l_v21650 = (&pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC)->ssgc_inst_top_of_space;
+; 58298: 	OP_ADR_DELTA(l_v21650, l_v21648, l_v21651);
+
+	mov	eax, DWORD PTR _pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC+12
+	sub	eax, esi
+
+; 58299: 	OP_INT_GT(l_v21649, l_v21651, l_v21652);
+
+	cmp	eax, 24					; 00000018H
+$block3$88242:
+
+; 58300: 	if (l_v21652) {
+
+	jge	$block4$88260
+
+; 58334: 	l_v21695 = l_v21640;
+; 58335: 	goto block8;
+; 58336: 
+; 58337:     block8:
+; 58338: 	RPY_DEBUG_RETURN();
+; 58339: 	return l_v21695;
+; 58340: 
+; 58341:     block9:
+; 58342: 	PYPY_DEBUG_RECORD_TRACEBACK("ll_math_ll_math_frexp");
+; 58343: 	l_v21695 = ((struct pypy_tuple2_0 *) NULL);
+; 58344: 	goto block8;
+; 58345: 
+; 58346:     block10:
+; 58347: 	abort();  /* debug_llinterpcall should be unreachable */
+; 58348: 	l_v21665 = (&pypy_g_ExcData)->ed_exc_type;
+; 58349: 	l_v21666 = (l_v21665 == NULL);
+; 58350: 	if (!l_v21666) {
+; 58351: 		goto block11;
+; 58352: 	}
+; 58353: 	goto block5;
+; 58354: 
+; 58355:     block11:
+; 58356: 	PYPY_DEBUG_RECORD_TRACEBACK("ll_math_ll_math_frexp");
+; 58357: 	l_v21696 = NULL;
+; 58358: 	goto block6;
+; 58359: 
+; 58360:     block12:
+; 58361: 	l_v21668 = pypy_g_SemiSpaceGC_obtain_free_space((&pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC), (0 + ROUND_UP_FOR_ALLOCATION(sizeof(struct pypy_tuple2_0), sizeof(struct pypy_forwarding_stub0))));
+
+	push	24					; 00000018H
+	push	OFFSET _pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC
+$block12$88259:
+	call	_pypy_g_SemiSpaceGC_obtain_free_space
+
+; 58362: 	l_v21669 = (&pypy_g_ExcData)->ed_exc_type;
+; 58363: 	l_v21670 = (l_v21669 == NULL);
+
+	xor	ecx, ecx
+	add	esp, 8
+	cmp	DWORD PTR _pypy_g_ExcData, ecx
+
+; 58364: 	if (!l_v21670) {
+
+	je	$LN5@pypy_g_ll_@159
+
+; 58368: 	goto block4;
+; 58369: 
+; 58370:     block13:
+; 58371: 	PYPY_DEBUG_RECORD_TRACEBACK("ll_math_ll_math_frexp");
+
+	mov	eax, DWORD PTR _pypydtcount
+	mov	DWORD PTR _pypy_debug_tracebacks[eax*8], OFFSET ?loc@?N@??pypy_g_ll_math_ll_math_frexp@@9@9
+	mov	DWORD PTR _pypy_debug_tracebacks[eax*8+4], ecx
+	inc	eax
+	and	eax, 8191				; 00001fffH
+	mov	DWORD PTR _pypy_debug_tracebacks[eax*8], OFFSET ?loc@?8??pypy_g_ll_math_ll_math_frexp@@9@9
+	mov	DWORD PTR _pypy_debug_tracebacks[eax*8+4], ecx
+	inc	eax
+	and	eax, 8191				; 00001fffH
+	mov	DWORD PTR _pypydtcount, eax
+$block13$88313:
+$block9$88285:
+	xor	eax, eax
+
+; 58423: 	goto block8;
+; 58424: }
+
+	pop	edi
+	pop	esi
+	pop	ebx
+	mov	esp, ebp
+	pop	ebp
+	ret	0
+$block2$88245:
+
+; 58281: 		goto block3;
+; 58282: 	}
+; 58283: 	goto block2;
+; 58284: 
+; 58285:     block2:
+; 58286: 	OP_FLOAT_IS_TRUE(l_x_14, l_v21647);
+
+	fldz
+	fld	QWORD PTR _l_x_14$[ebp]
+	fucom	ST(1)
+	fnstsw	ax
+	fstp	ST(1)
+	test	ah, 68					; 00000044H
+
+; 58287: 	if (l_v21647) {
+
+	jnp	$LN10@pypy_g_ll_@159
+
+; 58372: 	l_v21696 = NULL;
+; 58373: 	goto block6;
+; 58374: 
+; 58375:     block14:
+; 58376: 	l_v21672 = pypy_g__ll_malloc_varsize_no_length__Signed_Signed_Sign(1L, (0 + 0), sizeof(long));
+
+	push	4
+	fstp	ST(0)
+	push	0
+	push	1
+$block14$88247:
+	call	_pypy_g__ll_malloc_varsize_no_length__Signed_Signed_Sign
+	mov	esi, eax
+
+; 58377: 	OP_TRACK_ALLOC_START(l_v21672, /* nothing */);
+
+	push	OFFSET ??_C@_0BN@BIPHFGBC@pypy_g_ll_math_ll_math_frexp?$AA@
+	push	esi
+	call	_pypy_debug_alloc_start
+	add	esp, 20					; 00000014H
+
+; 58378: 	l_exp_p_0 = (long *)l_v21672;
+; 58379: 	l_v21674 = (l_exp_p_0 != NULL);
+
+	test	esi, esi
+
+; 58380: 	if (!l_v21674) {
+
+	jne	SHORT $block15$88324
+
+; 58418: 	goto block8;
+; 58419: 
+; 58420:     block18:
+; 58421: 	PYPY_DEBUG_RECORD_TRACEBACK("ll_math_ll_math_frexp");
+
+	mov	eax, DWORD PTR _pypydtcount
+	mov	DWORD PTR _pypy_debug_tracebacks[eax*8], OFFSET ?loc@?BB@??pypy_g_ll_math_ll_math_frexp@@9@9
+	mov	DWORD PTR _pypy_debug_tracebacks[eax*8+4], esi
+	inc	eax
+	and	eax, 8191				; 00001fffH
+	mov	DWORD PTR _pypydtcount, eax
+$block18$88323:
+
+; 58422: 	l_v21695 = ((struct pypy_tuple2_0 *) NULL);
+
+	xor	eax, eax
+
+; 58423: 	goto block8;
+; 58424: }
+
+	pop	edi
+	pop	esi
+	pop	ebx
+	mov	esp, ebp
+	pop	ebp
+	ret	0
+$block15$88324:
+
+; 58381: 		goto block18;
+; 58382: 	}
+; 58383: 	goto block15;
+; 58384: 
+; 58385:     block15:
+; 58386: 	l_mantissa_0 = pypy_g_frexp__Float_arrayPtr_star_2(l_x_14, l_exp_p_0);
+
+	fld	QWORD PTR _l_x_14$[ebp]
+	push	esi
+	sub	esp, 8
+	fstp	QWORD PTR [esp]
+	call	_pypy_g_frexp__Float_arrayPtr_star_2
+
+; 58387: 	l_v21675 = (&pypy_g_ExcData)->ed_exc_type;
+; 58388: 	l_v21676 = (l_v21675 == NULL);
+
+	mov	edi, DWORD PTR _pypy_g_ExcData
+	fstp	QWORD PTR _l_mantissa_0$[esp+76]
+	add	esp, 12					; 0000000cH
+	test	edi, edi
+
+; 58389: 	if (!l_v21676) {
+
+	je	SHORT $block16$88328
+
+; 58403: 
+; 58404:     block17:
+; 58405: 	l_v21682 = (&pypy_g_ExcData)->ed_exc_value;
+; 58406: 	l_v21683 = (&pypy_g_ExcData)->ed_exc_type;
+; 58407: 	PYPY_DEBUG_CATCH_EXCEPTION("ll_math_ll_math_frexp", l_v21683, l_v21683 == (&pypy_g_py__code_assertion_AssertionError_vtable.ae_super.ae_super.se_super.e_super) || l_v21683 == (&pypy_g_exceptions_NotImplementedError_vtable.nie_super.re_super.se_super.e_super));
+
+	mov	eax, DWORD PTR _pypydtcount
+	mov	ebx, DWORD PTR _pypy_g_ExcData+4
+	mov	DWORD PTR _pypy_debug_tracebacks[eax*8], OFFSET ?loc@?BA@??pypy_g_ll_math_ll_math_frexp@@9@9
+	mov	DWORD PTR _pypy_debug_tracebacks[eax*8+4], edi
+	inc	eax
+	and	eax, 8191				; 00001fffH
+$block17$88327:
+	mov	DWORD PTR _pypydtcount, eax
+	cmp	edi, OFFSET _pypy_g_py__code_assertion_AssertionError_vtable
+	je	SHORT $LN1@pypy_g_ll_@159
+	cmp	edi, OFFSET _pypy_g_exceptions_NotImplementedError_vtable
+	jne	SHORT $LN2@pypy_g_ll_@159
+$LN1@pypy_g_ll_@159:
+	call	_pypy_debug_catch_fatal_exception
+$LN2@pypy_g_ll_@159:
+
+; 58408: 	(&pypy_g_ExcData)->ed_exc_value = ((struct pypy_object0 *) NULL);
+
+	xor	eax, eax
+
+; 58409: 	(&pypy_g_ExcData)->ed_exc_type = ((struct pypy_object_vtable0 *) NULL);
+; 58410: 	l_v21687 = (struct pypy_exceptions_Exception0 *)l_v21682;
+; 58411: 	l_v21688 = (void*)l_exp_p_0;
+; 58412: 	OP_TRACK_ALLOC_STOP(l_v21688, /* nothing */);
+
+	push	esi
+	mov	DWORD PTR _pypy_g_ExcData+4, eax
+	mov	DWORD PTR _pypy_g_ExcData, eax
+	call	_pypy_debug_alloc_stop
+
+; 58413: 	OP_RAW_FREE(l_v21688, /* nothing */);
+
+	push	esi
+	call	_PyObject_Free
+
+; 58414: 	l_v21691 = (struct pypy_object0 *)l_v21687;
+; 58415: 	pypy_g_RPyReRaiseException(l_v21683, l_v21691);
+
+	push	ebx
+	push	edi
+	call	_pypy_g_RPyReRaiseException
+	add	esp, 16					; 00000010H
+
+; 58416: 	pypy_asm_gc_nocollect(pypy_g_RPyReRaiseException);
+; 58417: 	l_v21695 = ((struct pypy_tuple2_0 *) NULL);
+
+	xor	eax, eax
+
+; 58423: 	goto block8;
+; 58424: }
+
+	pop	edi
+	pop	esi
+	pop	ebx
+	mov	esp, ebp
+	pop	ebp
+	ret	0
+$block16$88328:
+
+; 58390: 		goto block17;
+; 58391: 	}
+; 58392: 	goto block16;
+; 58393: 
+; 58394:     block16:
+; 58395: 	l_v21677 = RPyBareItem(l_exp_p_0, 0L);
+; 58396: 	l_v21678 = (long)(l_v21677);
+
+	mov	edi, DWORD PTR [esi]
+
+; 58397: 	l_v21679 = (void*)l_exp_p_0;
+; 58398: 	OP_TRACK_ALLOC_STOP(l_v21679, /* nothing */);
+
+	push	esi
+	call	_pypy_debug_alloc_stop
+
+; 58399: 	OP_RAW_FREE(l_v21679, /* nothing */);
+
+	push	esi
+	call	_PyObject_Free
+
+; 58400: 	l_v21637 = l_v21678;
+; 58401: 	l_v21638 = l_mantissa_0;
+
+	fld	QWORD PTR _l_mantissa_0$[esp+72]
+	add	esp, 8
+
+; 58402: 	goto block3;
+
+	jmp	$LN30@pypy_g_ll_@159
+$LN5@pypy_g_ll_@159:
+
+; 58365: 		goto block13;
+; 58366: 	}
+; 58367: 	l_v21639 = l_v21668;
+
+	mov	esi, eax
+$block4$88260:
+$block5$88263:
+
+; 58301: 		goto block12;
+; 58302: 	}
+; 58303: 	l_v21639 = l_v21648;
+; 58304: 	goto block4;
+; 58305: 
+; 58306:     block4:
+; 58307: 	OP_INT_IS_TRUE(RUNNING_ON_LLINTERP, l_v21653);
+; 58308: 	if (l_v21653) {
+; 58309: 		goto block10;
+; 58310: 	}
+; 58311: 	goto block5;
+; 58312: 
+; 58313:     block5:
+; 58314: 	l_v21654 = (struct pypy_header0 *)l_v21639;
+; 58315: 	RPyField(l_v21654, h_tid) = (GROUP_MEMBER_OFFSET(struct group_pypy_g_typeinfo_s, member20)+0L);
+
+	test	esi, esi
+	jne	SHORT $LN18@pypy_g_ll_@159
+	call	_RPyAbort
+$LN18@pypy_g_ll_@159:
+
+; 58316: 	OP_ADR_ADD(l_v21639, (0 + ROUND_UP_FOR_ALLOCATION(sizeof(struct pypy_tuple2_0), sizeof(struct pypy_forwarding_stub0))), l_v21656);
+; 58317: 	(&pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC)->ssgc_inst_free = l_v21656;
+; 58318: 	OP_ADR_ADD(l_v21639, 0, l_v21658);
+; 58319: 	l_v21659 = (void*)l_v21658;
+; 58320: 	l_v21696 = l_v21659;
+; 58321: 	goto block6;
+; 58322: 
+; 58323:     block6:
+; 58324: 	l_v21640 = (struct pypy_tuple2_0 *)l_v21696;
+; 58325: 	l_v21660 = (l_v21640 != NULL);
+; 58326: 	if (!l_v21660) {
+; 58327: 		goto block9;
+; 58328: 	}
+; 58329: 	goto block7;
+; 58330: 
+; 58331:     block7:
+; 58332: 	RPyField(l_v21640, t_item0) = l_v21638;
+
+	fld	QWORD PTR _l_v21638$[esp+64]
+	mov	DWORD PTR [esi], 81			; 00000051H
+	lea	ecx, DWORD PTR [esi+24]
+	mov	DWORD PTR _pypy_g_pypy_rpython_memory_gc_semispace_SemiSpaceGC+4, ecx
+	fstp	QWORD PTR [esi+8]
+
+; 58333: 	RPyField(l_v21640, t_item1) = l_v21637;
+
+	mov	DWORD PTR [esi+16], edi
+
+; 58423: 	goto block8;
+; 58424: }
+
+	pop	edi
+	mov	eax, esi
+	pop	esi
+$block6$88281:
+$block8$88289:
+	pop	ebx
+	mov	esp, ebp
+	pop	ebp
+	ret	0
+_pypy_g_ll_math_ll_math_frexp ENDP
+_TEXT	ENDS

pypy/translator/goal/targetnumpystandalone.py

 """
 
 import time
-from pypy.module.micronumpy.numarray import SingleDimArray, Code, compute
+from pypy.module.micronumpy.compile import numpy_compile
 from pypy.jit.codewriter.policy import JitPolicy
-
-def create_array(size):
-    a = SingleDimArray(size)
-    for i in range(size):
-        a.storage[i] = float(i % 10)
-    return a
+from pypy.rpython.annlowlevel import hlstr
 
 def entry_point(argv):
     if len(argv) != 3:
         print __doc__
         return 1
-    bytecode = argv[1]
-    for b in bytecode:
-        if b not in 'alf':
-            print "WRONG BYTECODE"
-            print __doc__
-            return 2
     try:
         size = int(argv[2])
     except ValueError:
         print "INVALID LITERAL FOR INT:", argv[2]
         print __doc__
         return 3
-    no_arrays = bytecode.count('l')
-    no_floats = bytecode.count('f')
-    arrays = []
-    floats = []
-    for i in range(no_arrays):
-        arrays.append(create_array(size))
-    for i in range(no_floats):
-        floats.append(float(i + 1))
-    code = Code(bytecode, arrays, floats)
     t0 = time.time()
-    compute(code)
-    print "bytecode:", bytecode, "size:", size
+    main(argv[0], size)
+    print "bytecode:", argv[0], "size:", size
     print "took:", time.time() - t0
     return 0
 
+def main(bc, size):
+    if not isinstance(bc, str):
+        bc = hlstr(bc) # for tests
+    a = numpy_compile(bc, size)
+    a = a.compute()
+
 def target(*args):
     return entry_point, None