PageRenderTime 215ms CodeModel.GetById 33ms app.highlight 163ms RepoModel.GetById 2ms app.codeStats 1ms

/pypy/jit/backend/test/runner_test.py

https://bitbucket.org/pypy/pypy/
Python | 1453 lines | 1302 code | 95 blank | 56 comment | 223 complexity | a2309fdf7fa36042244b69c00afba735 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1import py, sys, random, os, struct, operator
   2from pypy.jit.metainterp.history import (AbstractFailDescr,
   3                                         AbstractDescr,
   4                                         BasicFailDescr,
   5                                         BoxInt, Box, BoxPtr,
   6                                         JitCellToken, TargetToken,
   7                                         ConstInt, ConstPtr,
   8                                         BoxObj,
   9                                         ConstObj, BoxFloat, ConstFloat)
  10from pypy.jit.metainterp.resoperation import ResOperation, rop
  11from pypy.jit.metainterp.typesystem import deref
  12from pypy.jit.codewriter.effectinfo import EffectInfo
  13from pypy.jit.tool.oparser import parse
  14from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass
  15from pypy.rpython.ootypesystem import ootype
  16from pypy.rpython.annlowlevel import llhelper
  17from pypy.rpython.llinterp import LLException
  18from pypy.jit.codewriter import heaptracker, longlong
  19from pypy.rlib.rarithmetic import intmask
  20from pypy.jit.backend.detect_cpu import autodetect_main_model_and_size
  21
  22def boxfloat(x):
  23    return BoxFloat(longlong.getfloatstorage(x))
  24
  25def constfloat(x):
  26    return ConstFloat(longlong.getfloatstorage(x))
  27
  28
  29class Runner(object):
  30
  31    add_loop_instruction = ['overload for a specific cpu']
  32    bridge_loop_instruction = ['overload for a specific cpu']
  33
  34    def execute_operation(self, opname, valueboxes, result_type, descr=None):
  35        inputargs, operations = self._get_single_operation_list(opname,
  36                                                                result_type,
  37                                                                valueboxes,
  38                                                                descr)
  39        looptoken = JitCellToken()
  40        self.cpu.compile_loop(inputargs, operations, looptoken)
  41        args = []
  42        for box in inputargs:
  43            if isinstance(box, BoxInt):
  44                args.append(box.getint())
  45            elif isinstance(box, (BoxPtr, BoxObj)):
  46                args.append(box.getref_base())
  47            elif isinstance(box, BoxFloat):
  48                args.append(box.getfloatstorage())
  49            else:
  50                raise NotImplementedError(box)
  51        res = self.cpu.execute_token(looptoken, *args)
  52        if res is operations[-1].getdescr():
  53            self.guard_failed = False
  54        else:
  55            self.guard_failed = True
  56        if result_type == 'int':
  57            return BoxInt(self.cpu.get_latest_value_int(0))
  58        elif result_type == 'ref':
  59            return BoxPtr(self.cpu.get_latest_value_ref(0))
  60        elif result_type == 'float':
  61            return BoxFloat(self.cpu.get_latest_value_float(0))
  62        elif result_type == 'void':
  63            return None
  64        else:
  65            assert False
  66
  67    def _get_single_operation_list(self, opnum, result_type, valueboxes,
  68                                   descr):
  69        if result_type == 'void':
  70            result = None
  71        elif result_type == 'int':
  72            result = BoxInt()
  73        elif result_type == 'ref':
  74            result = BoxPtr()
  75        elif result_type == 'float':
  76            result = BoxFloat()
  77        else:
  78            raise ValueError(result_type)
  79        if result is None:
  80            results = []
  81        else:
  82            results = [result]
  83        operations = [ResOperation(opnum, valueboxes, result),
  84                      ResOperation(rop.FINISH, results, None,
  85                                   descr=BasicFailDescr(0))]
  86        if operations[0].is_guard():
  87            operations[0].setfailargs([])
  88            if not descr:
  89                descr = BasicFailDescr(1)
  90        if descr is not None:
  91            operations[0].setdescr(descr)
  92        inputargs = []
  93        for box in valueboxes:
  94            if isinstance(box, Box) and box not in inputargs:
  95                inputargs.append(box)
  96        return inputargs, operations
  97
  98class BaseBackendTest(Runner):
  99
 100    avoid_instances = False
 101
 102    def test_compile_linear_loop(self):
 103        i0 = BoxInt()
 104        i1 = BoxInt()
 105        operations = [
 106            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
 107            ResOperation(rop.FINISH, [i1], None, descr=BasicFailDescr(1))
 108            ]
 109        inputargs = [i0]
 110        looptoken = JitCellToken()
 111        self.cpu.compile_loop(inputargs, operations, looptoken)
 112        fail = self.cpu.execute_token(looptoken, 2)
 113        res = self.cpu.get_latest_value_int(0)
 114        assert res == 3
 115        assert fail.identifier == 1
 116
 117    def test_compile_loop(self):
 118        i0 = BoxInt()
 119        i1 = BoxInt()
 120        i2 = BoxInt()
 121        looptoken = JitCellToken()
 122        targettoken = TargetToken()
 123        operations = [
 124            ResOperation(rop.LABEL, [i0], None, descr=targettoken),
 125            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
 126            ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
 127            ResOperation(rop.GUARD_TRUE, [i2], None, descr=BasicFailDescr(2)),
 128            ResOperation(rop.JUMP, [i1], None, descr=targettoken),
 129            ]
 130        inputargs = [i0]
 131        operations[3].setfailargs([i1])
 132
 133        self.cpu.compile_loop(inputargs, operations, looptoken)
 134        fail = self.cpu.execute_token(looptoken, 2)
 135        assert fail.identifier == 2
 136        res = self.cpu.get_latest_value_int(0)
 137        assert res == 10
 138
 139    def test_compile_with_holes_in_fail_args(self):
 140        i0 = BoxInt()
 141        i1 = BoxInt()
 142        i2 = BoxInt()
 143        i3 = BoxInt()
 144        looptoken = JitCellToken()
 145        targettoken = TargetToken()
 146        operations = [
 147            ResOperation(rop.INT_SUB, [i3, ConstInt(42)], i0),
 148            ResOperation(rop.LABEL, [i0], None, descr=targettoken),
 149            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
 150            ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
 151            ResOperation(rop.GUARD_TRUE, [i2], None, descr=BasicFailDescr(2)),
 152            ResOperation(rop.JUMP, [i1], None, descr=targettoken),
 153            ]
 154        inputargs = [i3]
 155        operations[4].setfailargs([None, None, i1, None])
 156
 157        self.cpu.compile_loop(inputargs, operations, looptoken)
 158        fail = self.cpu.execute_token(looptoken, 44)
 159        assert fail.identifier == 2
 160        res = self.cpu.get_latest_value_int(2)
 161        assert res == 10
 162
 163    def test_backends_dont_keep_loops_alive(self):
 164        import weakref, gc
 165        self.cpu.dont_keepalive_stuff = True
 166        i0 = BoxInt()
 167        i1 = BoxInt()
 168        i2 = BoxInt()
 169        looptoken = JitCellToken()
 170        targettoken = TargetToken()
 171        operations = [
 172            ResOperation(rop.LABEL, [i0], None, descr=targettoken),
 173            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
 174            ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
 175            ResOperation(rop.GUARD_TRUE, [i2], None, descr=BasicFailDescr()),
 176            ResOperation(rop.JUMP, [i1], None, descr=targettoken),
 177            ]
 178        inputargs = [i0]
 179        operations[3].setfailargs([i1])
 180        wr_i1 = weakref.ref(i1)
 181        wr_guard = weakref.ref(operations[2])
 182        self.cpu.compile_loop(inputargs, operations, looptoken)
 183        if hasattr(looptoken, '_x86_ops_offset'):
 184            del looptoken._x86_ops_offset # else it's kept alive
 185        del i0, i1, i2
 186        del inputargs
 187        del operations
 188        gc.collect()
 189        assert not wr_i1() and not wr_guard()
 190
 191    def test_compile_bridge(self):
 192        self.cpu.total_compiled_loops = 0
 193        self.cpu.total_compiled_bridges = 0
 194        i0 = BoxInt()
 195        i1 = BoxInt()
 196        i2 = BoxInt()
 197        faildescr1 = BasicFailDescr(1)
 198        faildescr2 = BasicFailDescr(2)
 199        looptoken = JitCellToken()
 200        targettoken = TargetToken()
 201        operations = [
 202            ResOperation(rop.LABEL, [i0], None, descr=targettoken),
 203            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
 204            ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
 205            ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1),
 206            ResOperation(rop.JUMP, [i1], None, descr=targettoken),
 207            ]
 208        inputargs = [i0]
 209        operations[3].setfailargs([i1])
 210        self.cpu.compile_loop(inputargs, operations, looptoken)
 211
 212        i1b = BoxInt()
 213        i3 = BoxInt()
 214        bridge = [
 215            ResOperation(rop.INT_LE, [i1b, ConstInt(19)], i3),
 216            ResOperation(rop.GUARD_TRUE, [i3], None, descr=faildescr2),
 217            ResOperation(rop.JUMP, [i1b], None, descr=targettoken),
 218        ]
 219        bridge[1].setfailargs([i1b])
 220
 221        self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken)
 222
 223        fail = self.cpu.execute_token(looptoken, 2)
 224        assert fail.identifier == 2
 225        res = self.cpu.get_latest_value_int(0)
 226        assert res == 20
 227
 228        assert self.cpu.total_compiled_loops == 1
 229        assert self.cpu.total_compiled_bridges == 1
 230        return looptoken
 231
 232    def test_compile_bridge_with_holes(self):
 233        i0 = BoxInt()
 234        i1 = BoxInt()
 235        i2 = BoxInt()
 236        i3 = BoxInt()
 237        faildescr1 = BasicFailDescr(1)
 238        faildescr2 = BasicFailDescr(2)
 239        looptoken = JitCellToken()
 240        targettoken = TargetToken()
 241        operations = [
 242            ResOperation(rop.INT_SUB, [i3, ConstInt(42)], i0),
 243            ResOperation(rop.LABEL, [i0], None, descr=targettoken),
 244            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
 245            ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
 246            ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1),
 247            ResOperation(rop.JUMP, [i1], None, descr=targettoken),
 248            ]
 249        inputargs = [i3]
 250        operations[4].setfailargs([None, i1, None])
 251        self.cpu.compile_loop(inputargs, operations, looptoken)
 252
 253        i1b = BoxInt()
 254        i3 = BoxInt()
 255        bridge = [
 256            ResOperation(rop.INT_LE, [i1b, ConstInt(19)], i3),
 257            ResOperation(rop.GUARD_TRUE, [i3], None, descr=faildescr2),
 258            ResOperation(rop.JUMP, [i1b], None, descr=targettoken),
 259        ]
 260        bridge[1].setfailargs([i1b])
 261
 262        self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken)
 263
 264        fail = self.cpu.execute_token(looptoken, 2)
 265        assert fail.identifier == 2
 266        res = self.cpu.get_latest_value_int(0)
 267        assert res == 20
 268
 269    def test_get_latest_value_count(self):
 270        i0 = BoxInt()
 271        i1 = BoxInt()
 272        i2 = BoxInt()
 273        faildescr1 = BasicFailDescr(1)
 274        looptoken = JitCellToken()
 275        targettoken = TargetToken()
 276        operations = [
 277            ResOperation(rop.LABEL, [i0], None, descr=targettoken),
 278            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
 279            ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
 280            ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1),
 281            ResOperation(rop.JUMP, [i1], None, descr=targettoken),
 282            ]
 283        inputargs = [i0]
 284        operations[3].setfailargs([None, i1, None])
 285        self.cpu.compile_loop(inputargs, operations, looptoken)
 286
 287        fail = self.cpu.execute_token(looptoken, 2)
 288        assert fail is faildescr1
 289
 290        count = self.cpu.get_latest_value_count()
 291        assert count == 3
 292        assert self.cpu.get_latest_value_int(1) == 10
 293        assert self.cpu.get_latest_value_int(1) == 10   # multiple reads ok
 294        self.cpu.clear_latest_values(3)
 295
 296    def test_finish(self):
 297        i0 = BoxInt()
 298        class UntouchableFailDescr(AbstractFailDescr):
 299            def __setattr__(self, name, value):
 300                if name == 'index':
 301                    return AbstractFailDescr.__setattr__(self, name, value)
 302                py.test.fail("finish descrs should not be touched")
 303        faildescr = UntouchableFailDescr() # to check that is not touched
 304        looptoken = JitCellToken()
 305        operations = [
 306            ResOperation(rop.FINISH, [i0], None, descr=faildescr)
 307            ]
 308        self.cpu.compile_loop([i0], operations, looptoken)
 309        fail = self.cpu.execute_token(looptoken, 99)
 310        assert fail is faildescr
 311        res = self.cpu.get_latest_value_int(0)
 312        assert res == 99
 313
 314        looptoken = JitCellToken()
 315        operations = [
 316            ResOperation(rop.FINISH, [ConstInt(42)], None, descr=faildescr)
 317            ]
 318        self.cpu.compile_loop([], operations, looptoken)
 319        fail = self.cpu.execute_token(looptoken)
 320        assert fail is faildescr
 321        res = self.cpu.get_latest_value_int(0)
 322        assert res == 42
 323
 324        looptoken = JitCellToken()
 325        operations = [
 326            ResOperation(rop.FINISH, [], None, descr=faildescr)
 327            ]
 328        self.cpu.compile_loop([], operations, looptoken)
 329        fail = self.cpu.execute_token(looptoken)
 330        assert fail is faildescr
 331
 332        if self.cpu.supports_floats:
 333            looptoken = JitCellToken()
 334            f0 = BoxFloat()
 335            operations = [
 336                ResOperation(rop.FINISH, [f0], None, descr=faildescr)
 337                ]
 338            self.cpu.compile_loop([f0], operations, looptoken)
 339            value = longlong.getfloatstorage(-61.25)
 340            fail = self.cpu.execute_token(looptoken, value)
 341            assert fail is faildescr
 342            res = self.cpu.get_latest_value_float(0)
 343            assert longlong.getrealfloat(res) == -61.25
 344
 345            looptoken = JitCellToken()
 346            operations = [
 347                ResOperation(rop.FINISH, [constfloat(42.5)], None, descr=faildescr)
 348                ]
 349            self.cpu.compile_loop([], operations, looptoken)
 350            fail = self.cpu.execute_token(looptoken)
 351            assert fail is faildescr
 352            res = self.cpu.get_latest_value_float(0)
 353            assert longlong.getrealfloat(res) == 42.5
 354
 355    def test_execute_operations_in_env(self):
 356        cpu = self.cpu
 357        x = BoxInt(123)
 358        y = BoxInt(456)
 359        z = BoxInt(579)
 360        t = BoxInt(455)
 361        u = BoxInt(0)    # False
 362        looptoken = JitCellToken()
 363        targettoken = TargetToken()
 364        operations = [
 365            ResOperation(rop.LABEL, [y, x], None, descr=targettoken),
 366            ResOperation(rop.INT_ADD, [x, y], z),
 367            ResOperation(rop.INT_SUB, [y, ConstInt(1)], t),
 368            ResOperation(rop.INT_EQ, [t, ConstInt(0)], u),
 369            ResOperation(rop.GUARD_FALSE, [u], None,
 370                         descr=BasicFailDescr()),
 371            ResOperation(rop.JUMP, [t, z], None, descr=targettoken),
 372            ]
 373        operations[-2].setfailargs([t, z])
 374        cpu.compile_loop([x, y], operations, looptoken)
 375        res = self.cpu.execute_token(looptoken, 0, 10)
 376        assert self.cpu.get_latest_value_int(0) == 0
 377        assert self.cpu.get_latest_value_int(1) == 55
 378
 379    def test_int_operations(self):
 380        from pypy.jit.metainterp.test.test_executor import get_int_tests
 381        for opnum, boxargs, retvalue in get_int_tests():
 382            res = self.execute_operation(opnum, boxargs, 'int')
 383            assert res.value == retvalue
 384
 385    def test_float_operations(self):
 386        from pypy.jit.metainterp.test.test_executor import get_float_tests
 387        for opnum, boxargs, rettype, retvalue in get_float_tests(self.cpu):
 388            res = self.execute_operation(opnum, boxargs, rettype)
 389            if isinstance(res, BoxFloat):
 390                assert res.getfloat() == retvalue
 391            else:
 392                assert res.value == retvalue
 393
 394    def test_ovf_operations(self, reversed=False):
 395        minint = -sys.maxint-1
 396        boom = 'boom'
 397        for opnum, testcases in [
 398            (rop.INT_ADD_OVF, [(10, -2, 8),
 399                               (-1, minint, boom),
 400                               (sys.maxint//2, sys.maxint//2+2, boom)]),
 401            (rop.INT_SUB_OVF, [(-20, -23, 3),
 402                               (-2, sys.maxint, boom),
 403                               (sys.maxint//2, -(sys.maxint//2+2), boom)]),
 404            (rop.INT_MUL_OVF, [(minint/2, 2, minint),
 405                               (-2, -(minint/2), minint),
 406                               (minint/2, -2, boom)]),
 407            ]:
 408            v1 = BoxInt(testcases[0][0])
 409            v2 = BoxInt(testcases[0][1])
 410            v_res = BoxInt()
 411            #
 412            if not reversed:
 413                ops = [
 414                    ResOperation(opnum, [v1, v2], v_res),
 415                    ResOperation(rop.GUARD_NO_OVERFLOW, [], None,
 416                                 descr=BasicFailDescr(1)),
 417                    ResOperation(rop.FINISH, [v_res], None,
 418                                 descr=BasicFailDescr(2)),
 419                    ]
 420                ops[1].setfailargs([])
 421            else:
 422                v_exc = self.cpu.ts.BoxRef()
 423                ops = [
 424                    ResOperation(opnum, [v1, v2], v_res),
 425                    ResOperation(rop.GUARD_OVERFLOW, [], None,
 426                                 descr=BasicFailDescr(1)),
 427                    ResOperation(rop.FINISH, [], None, descr=BasicFailDescr(2)),
 428                    ]
 429                ops[1].setfailargs([v_res])
 430            #
 431            looptoken = JitCellToken()
 432            self.cpu.compile_loop([v1, v2], ops, looptoken)
 433            for x, y, z in testcases:
 434                excvalue = self.cpu.grab_exc_value()
 435                assert not excvalue
 436                fail = self.cpu.execute_token(looptoken, x, y)
 437                if (z == boom) ^ reversed:
 438                    assert fail.identifier == 1
 439                else:
 440                    assert fail.identifier == 2
 441                if z != boom:
 442                    assert self.cpu.get_latest_value_int(0) == z
 443                excvalue = self.cpu.grab_exc_value()
 444                assert not excvalue
 445
 446    def test_ovf_operations_reversed(self):
 447        self.test_ovf_operations(reversed=True)
 448
 449    def test_bh_call(self):
 450        cpu = self.cpu
 451        #
 452        def func(c):
 453            return chr(ord(c) + 1)
 454        FPTR = self.Ptr(self.FuncType([lltype.Char], lltype.Char))
 455        func_ptr = llhelper(FPTR, func)
 456        calldescr = cpu.calldescrof(deref(FPTR), (lltype.Char,), lltype.Char,
 457                                    EffectInfo.MOST_GENERAL)
 458        x = cpu.bh_call_i(self.get_funcbox(cpu, func_ptr).value,
 459                          calldescr, [ord('A')], None, None)
 460        assert x == ord('B')
 461        if cpu.supports_floats:
 462            def func(f, i):
 463                assert isinstance(f, float)
 464                assert isinstance(i, int)
 465                return f - float(i)
 466            FPTR = self.Ptr(self.FuncType([lltype.Float, lltype.Signed],
 467                                          lltype.Float))
 468            func_ptr = llhelper(FPTR, func)
 469            FTP = deref(FPTR)
 470            calldescr = cpu.calldescrof(FTP, FTP.ARGS, FTP.RESULT,
 471                                        EffectInfo.MOST_GENERAL)
 472            x = cpu.bh_call_f(self.get_funcbox(cpu, func_ptr).value,
 473                              calldescr,
 474                              [42], None, [longlong.getfloatstorage(3.5)])
 475            assert longlong.getrealfloat(x) == 3.5 - 42
 476
 477    def test_call(self):
 478        from pypy.rlib.libffi import types, FUNCFLAG_CDECL
 479
 480        def func_int(a, b):
 481            return a + b
 482        def func_char(c, c1):
 483            return chr(ord(c) + ord(c1))
 484
 485        functions = [
 486            (func_int, lltype.Signed, types.sint, 655360),
 487            (func_int, rffi.SHORT, types.sint16, 1213),
 488            (func_char, lltype.Char, types.uchar, 12)
 489            ]
 490
 491        for func, TP, ffi_type, num in functions:
 492            cpu = self.cpu
 493            #
 494            FPTR = self.Ptr(self.FuncType([TP, TP], TP))
 495            func_ptr = llhelper(FPTR, func)
 496            FUNC = deref(FPTR)
 497            funcbox = self.get_funcbox(cpu, func_ptr)
 498            # first, try it with the "normal" calldescr
 499            calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
 500                                        EffectInfo.MOST_GENERAL)
 501            res = self.execute_operation(rop.CALL,
 502                                         [funcbox, BoxInt(num), BoxInt(num)],
 503                                         'int', descr=calldescr)
 504            assert res.value == 2 * num
 505            # then, try it with the dynamic calldescr
 506            dyn_calldescr = cpu.calldescrof_dynamic([ffi_type, ffi_type], ffi_type,
 507                                                    EffectInfo.MOST_GENERAL,
 508                                                    ffi_flags=FUNCFLAG_CDECL)
 509            res = self.execute_operation(rop.CALL,
 510                                         [funcbox, BoxInt(num), BoxInt(num)],
 511                                         'int', descr=dyn_calldescr)
 512            assert res.value == 2 * num
 513
 514
 515        if cpu.supports_floats:
 516            def func(f0, f1, f2, f3, f4, f5, f6, i0, i1, f7, f8, f9):
 517                return f0 + f1 + f2 + f3 + f4 + f5 + f6 + float(i0 + i1) + f7 + f8 + f9
 518            F = lltype.Float
 519            I = lltype.Signed
 520            FUNC = self.FuncType([F] * 7 + [I] * 2 + [F] * 3, F)
 521            FPTR = self.Ptr(FUNC)
 522            func_ptr = llhelper(FPTR, func)
 523            calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
 524                                        EffectInfo.MOST_GENERAL)
 525            funcbox = self.get_funcbox(cpu, func_ptr)
 526            args = ([boxfloat(.1) for i in range(7)] +
 527                    [BoxInt(1), BoxInt(2), boxfloat(.2), boxfloat(.3),
 528                     boxfloat(.4)])
 529            res = self.execute_operation(rop.CALL,
 530                                         [funcbox] + args,
 531                                         'float', descr=calldescr)
 532            assert abs(res.getfloat() - 4.6) < 0.0001
 533
 534    def test_call_many_arguments(self):
 535        # Test calling a function with a large number of arguments (more than
 536        # 6, which will force passing some arguments on the stack on 64-bit)
 537
 538        def func(*args):
 539            assert len(args) == 16
 540            # Try to sum up args in a way that would probably detect a
 541            # transposed argument
 542            return sum(arg * (2**i) for i, arg in enumerate(args))
 543
 544        FUNC = self.FuncType([lltype.Signed]*16, lltype.Signed)
 545        FPTR = self.Ptr(FUNC)
 546        calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
 547                                         EffectInfo.MOST_GENERAL)
 548        func_ptr = llhelper(FPTR, func)
 549        args = range(16)
 550        funcbox = self.get_funcbox(self.cpu, func_ptr)
 551        res = self.execute_operation(rop.CALL, [funcbox] + map(BoxInt, args), 'int', descr=calldescr)
 552        assert res.value == func(*args)
 553
 554    def test_call_box_func(self):
 555        def a(a1, a2):
 556            return a1 + a2
 557        def b(b1, b2):
 558            return b1 * b2
 559
 560        arg1 = 40
 561        arg2 = 2
 562        for f in [a, b]:
 563            TP = lltype.Signed
 564            FPTR = self.Ptr(self.FuncType([TP, TP], TP))
 565            func_ptr = llhelper(FPTR, f)
 566            FUNC = deref(FPTR)
 567            funcconst = self.get_funcbox(self.cpu, func_ptr)
 568            funcbox = funcconst.clonebox()
 569            calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
 570                                        EffectInfo.MOST_GENERAL)
 571            res = self.execute_operation(rop.CALL,
 572                                         [funcbox, BoxInt(arg1), BoxInt(arg2)],
 573                                         'int', descr=calldescr)
 574            assert res.getint() == f(arg1, arg2)
 575        
 576    def test_call_stack_alignment(self):
 577        # test stack alignment issues, notably for Mac OS/X.
 578        # also test the ordering of the arguments.
 579
 580        def func_ints(*ints):
 581            s = str(ints) + '\n'
 582            os.write(1, s)   # don't remove -- crash if the stack is misaligned
 583            return sum([(10+i)*(5+j) for i, j in enumerate(ints)])
 584
 585        for nb_args in range(0, 35):
 586            cpu = self.cpu
 587            TP = lltype.Signed
 588            #
 589            FPTR = self.Ptr(self.FuncType([TP] * nb_args, TP))
 590            func_ptr = llhelper(FPTR, func_ints)
 591            FUNC = deref(FPTR)
 592            calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
 593                                        EffectInfo.MOST_GENERAL)
 594            funcbox = self.get_funcbox(cpu, func_ptr)
 595            args = [280-24*i for i in range(nb_args)]
 596            res = self.execute_operation(rop.CALL,
 597                                         [funcbox] + map(BoxInt, args),
 598                                         'int', descr=calldescr)
 599            assert res.value == func_ints(*args)
 600
 601    def test_call_with_const_floats(self):
 602        def func(f1, f2):
 603            return f1 + f2
 604
 605        FUNC = self.FuncType([lltype.Float, lltype.Float], lltype.Float)
 606        FPTR = self.Ptr(FUNC)
 607        calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
 608                                         EffectInfo.MOST_GENERAL)
 609        func_ptr = llhelper(FPTR, func)
 610        funcbox = self.get_funcbox(self.cpu, func_ptr)
 611        res = self.execute_operation(rop.CALL, [funcbox, constfloat(1.5),
 612                                                constfloat(2.5)], 'float',
 613                                     descr=calldescr)
 614        assert res.getfloat() == 4.0
 615
 616
 617    def test_field_basic(self):
 618        t_box, T_box = self.alloc_instance(self.T)
 619        fielddescr = self.cpu.fielddescrof(self.S, 'value')
 620        assert not fielddescr.is_pointer_field()
 621        #
 622        res = self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(39082)],
 623                                     'void', descr=fielddescr)
 624        assert res is None
 625        res = self.execute_operation(rop.GETFIELD_GC, [t_box],
 626                                     'int', descr=fielddescr)
 627        assert res.value == 39082
 628        #
 629        fielddescr1 = self.cpu.fielddescrof(self.S, 'chr1')
 630        fielddescr2 = self.cpu.fielddescrof(self.S, 'chr2')
 631        shortdescr = self.cpu.fielddescrof(self.S, 'short')
 632        self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(250)],
 633                               'void', descr=fielddescr2)
 634        self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(133)],
 635                               'void', descr=fielddescr1)
 636        self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(1331)],
 637                               'void', descr=shortdescr)
 638        res = self.execute_operation(rop.GETFIELD_GC, [t_box],
 639                                     'int', descr=fielddescr2)
 640        assert res.value == 250
 641        res = self.execute_operation(rop.GETFIELD_GC, [t_box],
 642                                     'int', descr=fielddescr1)
 643        assert res.value == 133
 644        res = self.execute_operation(rop.GETFIELD_GC, [t_box],
 645                                     'int', descr=shortdescr)
 646        assert res.value == 1331
 647
 648        #
 649        u_box, U_box = self.alloc_instance(self.U)
 650        fielddescr2 = self.cpu.fielddescrof(self.S, 'next')
 651        assert fielddescr2.is_pointer_field()
 652        res = self.execute_operation(rop.SETFIELD_GC, [t_box, u_box],
 653                                     'void', descr=fielddescr2)
 654        assert res is None
 655        res = self.execute_operation(rop.GETFIELD_GC, [t_box],
 656                                     'ref', descr=fielddescr2)
 657        assert res.value == u_box.value
 658        #
 659        null_const = self.null_instance().constbox()
 660        res = self.execute_operation(rop.SETFIELD_GC, [t_box, null_const],
 661                                     'void', descr=fielddescr2)
 662        assert res is None
 663        res = self.execute_operation(rop.GETFIELD_GC, [t_box],
 664                                     'ref', descr=fielddescr2)
 665        assert res.value == null_const.value
 666        if self.cpu.supports_floats:
 667            floatdescr = self.cpu.fielddescrof(self.S, 'float')
 668            self.execute_operation(rop.SETFIELD_GC, [t_box, boxfloat(3.4)],
 669                                   'void', descr=floatdescr)
 670            res = self.execute_operation(rop.GETFIELD_GC, [t_box],
 671                                         'float', descr=floatdescr)
 672            assert res.getfloat() == 3.4
 673            #
 674            self.execute_operation(rop.SETFIELD_GC, [t_box, constfloat(-3.6)],
 675                                   'void', descr=floatdescr)
 676            res = self.execute_operation(rop.GETFIELD_GC, [t_box],
 677                                         'float', descr=floatdescr)
 678            assert res.getfloat() == -3.6
 679
 680
 681    def test_passing_guards(self):
 682        t_box, T_box = self.alloc_instance(self.T)
 683        nullbox = self.null_instance()
 684        all = [(rop.GUARD_TRUE, [BoxInt(1)]),
 685               (rop.GUARD_FALSE, [BoxInt(0)]),
 686               (rop.GUARD_VALUE, [BoxInt(42), ConstInt(42)]),
 687               ]
 688        if not self.avoid_instances:
 689            all.extend([
 690               (rop.GUARD_NONNULL, [t_box]),
 691               (rop.GUARD_ISNULL, [nullbox])
 692               ])
 693        if self.cpu.supports_floats:
 694            all.append((rop.GUARD_VALUE, [boxfloat(3.5), constfloat(3.5)]))
 695        for (opname, args) in all:
 696            assert self.execute_operation(opname, args, 'void') == None
 697            assert not self.guard_failed
 698
 699
 700    def test_passing_guard_class(self):
 701        t_box, T_box = self.alloc_instance(self.T)
 702        #null_box = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(T)))
 703        self.execute_operation(rop.GUARD_CLASS, [t_box, T_box], 'void')
 704        assert not self.guard_failed
 705        self.execute_operation(rop.GUARD_NONNULL_CLASS, [t_box, T_box], 'void')
 706        assert not self.guard_failed
 707
 708    def test_failing_guards(self):
 709        t_box, T_box = self.alloc_instance(self.T)
 710        nullbox = self.null_instance()
 711        all = [(rop.GUARD_TRUE, [BoxInt(0)]),
 712               (rop.GUARD_FALSE, [BoxInt(1)]),
 713               (rop.GUARD_VALUE, [BoxInt(42), ConstInt(41)]),
 714               ]
 715        if not self.avoid_instances:
 716            all.extend([
 717               (rop.GUARD_NONNULL, [nullbox]),
 718               (rop.GUARD_ISNULL, [t_box])])
 719        if self.cpu.supports_floats:
 720            all.append((rop.GUARD_VALUE, [boxfloat(-1.0), constfloat(1.0)]))
 721        for opname, args in all:
 722            assert self.execute_operation(opname, args, 'void') == None
 723            assert self.guard_failed
 724
 725    def test_failing_guard_class(self):
 726        t_box, T_box = self.alloc_instance(self.T)
 727        u_box, U_box = self.alloc_instance(self.U)
 728        null_box = self.null_instance()
 729        for opname, args in [(rop.GUARD_CLASS, [t_box, U_box]),
 730                             (rop.GUARD_CLASS, [u_box, T_box]),
 731                             (rop.GUARD_NONNULL_CLASS, [t_box, U_box]),
 732                             (rop.GUARD_NONNULL_CLASS, [u_box, T_box]),
 733                             (rop.GUARD_NONNULL_CLASS, [null_box, T_box]),
 734                             ]:
 735            assert self.execute_operation(opname, args, 'void') == None
 736            assert self.guard_failed
 737
 738    def test_ooops(self):
 739        u1_box, U_box = self.alloc_instance(self.U)
 740        u2_box, U_box = self.alloc_instance(self.U)
 741        r = self.execute_operation(rop.PTR_EQ, [u1_box,
 742                                                u1_box.clonebox()], 'int')
 743        assert r.value == 1
 744        r = self.execute_operation(rop.PTR_NE, [u2_box,
 745                                                u2_box.clonebox()], 'int')
 746        assert r.value == 0
 747        r = self.execute_operation(rop.PTR_EQ, [u1_box, u2_box], 'int')
 748        assert r.value == 0
 749        r = self.execute_operation(rop.PTR_NE, [u2_box, u1_box], 'int')
 750        assert r.value == 1
 751        #
 752        null_box = self.null_instance()
 753        r = self.execute_operation(rop.PTR_EQ, [null_box,
 754                                                null_box.clonebox()], 'int')
 755        assert r.value == 1
 756        r = self.execute_operation(rop.PTR_EQ, [u1_box, null_box], 'int')
 757        assert r.value == 0
 758        r = self.execute_operation(rop.PTR_EQ, [null_box, u2_box], 'int')
 759        assert r.value == 0
 760        r = self.execute_operation(rop.PTR_NE, [null_box,
 761                                                null_box.clonebox()], 'int')
 762        assert r.value == 0
 763        r = self.execute_operation(rop.PTR_NE, [u2_box, null_box], 'int')
 764        assert r.value == 1
 765        r = self.execute_operation(rop.PTR_NE, [null_box, u1_box], 'int')
 766        assert r.value == 1
 767
 768    def test_array_basic(self):
 769        a_box, A = self.alloc_array_of(rffi.SHORT, 342)
 770        arraydescr = self.cpu.arraydescrof(A)
 771        assert not arraydescr.is_array_of_pointers()
 772        #
 773        r = self.execute_operation(rop.ARRAYLEN_GC, [a_box],
 774                                   'int', descr=arraydescr)
 775        assert r.value == 342
 776        r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(310),
 777                                                         BoxInt(744)],
 778                                   'void', descr=arraydescr)
 779        assert r is None
 780        r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(310)],
 781                                   'int', descr=arraydescr)
 782        assert r.value == 744
 783
 784        a_box, A = self.alloc_array_of(lltype.Signed, 342)
 785        arraydescr = self.cpu.arraydescrof(A)
 786        assert not arraydescr.is_array_of_pointers()
 787        #
 788        r = self.execute_operation(rop.ARRAYLEN_GC, [a_box],
 789                                   'int', descr=arraydescr)
 790        assert r.value == 342
 791        r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(310),
 792                                                         BoxInt(7441)],
 793                                   'void', descr=arraydescr)
 794        assert r is None
 795        r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(310)],
 796                                   'int', descr=arraydescr)
 797        assert r.value == 7441
 798        #
 799        a_box, A = self.alloc_array_of(lltype.Char, 11)
 800        arraydescr = self.cpu.arraydescrof(A)
 801        assert not arraydescr.is_array_of_pointers()
 802        r = self.execute_operation(rop.ARRAYLEN_GC, [a_box],
 803                                   'int', descr=arraydescr)
 804        assert r.value == 11
 805        r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(4),
 806                                                         BoxInt(150)],
 807                                   'void', descr=arraydescr)
 808        assert r is None
 809        r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(3),
 810                                                         BoxInt(160)],
 811                                   'void', descr=arraydescr)
 812        assert r is None
 813        r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(4)],
 814                                   'int', descr=arraydescr)
 815        assert r.value == 150
 816        r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(3)],
 817                                   'int', descr=arraydescr)
 818        assert r.value == 160
 819
 820        #
 821        if isinstance(A, lltype.GcArray):
 822            A = lltype.Ptr(A)
 823        b_box, B = self.alloc_array_of(A, 3)
 824        arraydescr = self.cpu.arraydescrof(B)
 825        assert arraydescr.is_array_of_pointers()
 826        r = self.execute_operation(rop.ARRAYLEN_GC, [b_box],
 827                                   'int', descr=arraydescr)
 828        assert r.value == 3
 829        r = self.execute_operation(rop.SETARRAYITEM_GC, [b_box, BoxInt(1),
 830                                                         a_box],
 831                                   'void', descr=arraydescr)
 832        assert r is None
 833        r = self.execute_operation(rop.GETARRAYITEM_GC, [b_box, BoxInt(1)],
 834                                   'ref', descr=arraydescr)
 835        assert r.value == a_box.value
 836        #
 837        # Unsigned should work the same as Signed
 838        a_box, A = self.alloc_array_of(lltype.Unsigned, 342)
 839        arraydescr = self.cpu.arraydescrof(A)
 840        assert not arraydescr.is_array_of_pointers()
 841        r = self.execute_operation(rop.ARRAYLEN_GC, [a_box],
 842                                   'int', descr=arraydescr)
 843        assert r.value == 342
 844        r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(310),
 845                                                         BoxInt(7441)],
 846                                   'void', descr=arraydescr)
 847        assert r is None
 848        r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(310)],
 849                                   'int', descr=arraydescr)
 850        assert r.value == 7441
 851        #
 852        # Bool should work the same as Char
 853        a_box, A = self.alloc_array_of(lltype.Bool, 311)
 854        arraydescr = self.cpu.arraydescrof(A)
 855        assert not arraydescr.is_array_of_pointers()
 856        r = self.execute_operation(rop.ARRAYLEN_GC, [a_box],
 857                                   'int', descr=arraydescr)
 858        assert r.value == 311
 859        r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(304),
 860                                                         BoxInt(1)],
 861                                   'void', descr=arraydescr)
 862        assert r is None
 863        r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(303),
 864                                                         BoxInt(0)],
 865                                   'void', descr=arraydescr)
 866        assert r is None
 867        r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(302),
 868                                                         BoxInt(1)],
 869                                   'void', descr=arraydescr)
 870        assert r is None
 871        r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(304)],
 872                                   'int', descr=arraydescr)
 873        assert r.value == 1
 874        r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(303)],
 875                                   'int', descr=arraydescr)
 876        assert r.value == 0
 877        r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(302)],
 878                                   'int', descr=arraydescr)
 879        assert r.value == 1
 880
 881        if self.cpu.supports_floats:
 882            a_box, A = self.alloc_array_of(lltype.Float, 31)
 883            arraydescr = self.cpu.arraydescrof(A)
 884            self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(1),
 885                                                         boxfloat(3.5)],
 886                                   'void', descr=arraydescr)
 887            self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(2),
 888                                                         constfloat(4.5)],
 889                                   'void', descr=arraydescr)
 890            r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(1)],
 891                                       'float', descr=arraydescr)
 892            assert r.getfloat() == 3.5
 893            r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(2)],
 894                                       'float', descr=arraydescr)
 895            assert r.getfloat() == 4.5
 896
 897        # For platforms where sizeof(INT) != sizeof(Signed) (ie, x86-64)
 898        a_box, A = self.alloc_array_of(rffi.INT, 342)
 899        arraydescr = self.cpu.arraydescrof(A)
 900        assert not arraydescr.is_array_of_pointers()
 901        r = self.execute_operation(rop.ARRAYLEN_GC, [a_box],
 902                                   'int', descr=arraydescr)
 903        assert r.value == 342
 904        r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(310),
 905                                                         BoxInt(7441)],
 906                                   'void', descr=arraydescr)
 907        assert r is None
 908        r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(310)],
 909                                   'int', descr=arraydescr)
 910        assert r.value == 7441
 911
 912    def test_array_of_structs(self):
 913        TP = lltype.GcStruct('x')
 914        ITEM = lltype.Struct('x',
 915                             ('vs', lltype.Signed),
 916                             ('vu', lltype.Unsigned),
 917                             ('vsc', rffi.SIGNEDCHAR),
 918                             ('vuc', rffi.UCHAR),
 919                             ('vss', rffi.SHORT),
 920                             ('vus', rffi.USHORT),
 921                             ('vsi', rffi.INT),
 922                             ('vui', rffi.UINT),
 923                             ('k', lltype.Float),
 924                             ('p', lltype.Ptr(TP)))
 925        a_box, A = self.alloc_array_of(ITEM, 15)
 926        s_box, S = self.alloc_instance(TP)
 927        kdescr = self.cpu.interiorfielddescrof(A, 'k')
 928        pdescr = self.cpu.interiorfielddescrof(A, 'p')
 929        self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, BoxInt(3),
 930                                                         boxfloat(1.5)],
 931                               'void', descr=kdescr)
 932        f = self.cpu.bh_getinteriorfield_gc_f(a_box.getref_base(), 3, kdescr)
 933        assert longlong.getrealfloat(f) == 1.5
 934        self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, kdescr, longlong.getfloatstorage(2.5))
 935        r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)],
 936                                   'float', descr=kdescr)
 937        assert r.getfloat() == 2.5
 938        #
 939        NUMBER_FIELDS = [('vs', lltype.Signed),
 940                         ('vu', lltype.Unsigned),
 941                         ('vsc', rffi.SIGNEDCHAR),
 942                         ('vuc', rffi.UCHAR),
 943                         ('vss', rffi.SHORT),
 944                         ('vus', rffi.USHORT),
 945                         ('vsi', rffi.INT),
 946                         ('vui', rffi.UINT)]
 947        for name, TYPE in NUMBER_FIELDS[::-1]:
 948            vdescr = self.cpu.interiorfielddescrof(A, name)
 949            self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, BoxInt(3),
 950                                                             BoxInt(-15)],
 951                                   'void', descr=vdescr)
 952        for name, TYPE in NUMBER_FIELDS:
 953            vdescr = self.cpu.interiorfielddescrof(A, name)
 954            i = self.cpu.bh_getinteriorfield_gc_i(a_box.getref_base(), 3,
 955                                                  vdescr)
 956            assert i == rffi.cast(lltype.Signed, rffi.cast(TYPE, -15))
 957        for name, TYPE in NUMBER_FIELDS[::-1]:
 958            vdescr = self.cpu.interiorfielddescrof(A, name)
 959            self.cpu.bh_setinteriorfield_gc_i(a_box.getref_base(), 3,
 960                                              vdescr, -25)
 961        for name, TYPE in NUMBER_FIELDS:
 962            vdescr = self.cpu.interiorfielddescrof(A, name)
 963            r = self.execute_operation(rop.GETINTERIORFIELD_GC,
 964                                       [a_box, BoxInt(3)],
 965                                       'int', descr=vdescr)
 966            assert r.getint() == rffi.cast(lltype.Signed, rffi.cast(TYPE, -25))
 967        #
 968        self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, BoxInt(4),
 969                                                         s_box],
 970                               'void', descr=pdescr)
 971        r = self.cpu.bh_getinteriorfield_gc_r(a_box.getref_base(), 4, pdescr)
 972        assert r == s_box.getref_base()
 973        self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, pdescr,
 974                                          s_box.getref_base())
 975        r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)],
 976                                   'ref', descr=pdescr)
 977        assert r.getref_base() == s_box.getref_base()
 978
 979    def test_string_basic(self):
 980        s_box = self.alloc_string("hello\xfe")
 981        r = self.execute_operation(rop.STRLEN, [s_box], 'int')
 982        assert r.value == 6
 983        r = self.execute_operation(rop.STRGETITEM, [s_box, BoxInt(5)], 'int')
 984        assert r.value == 254
 985        r = self.execute_operation(rop.STRSETITEM, [s_box, BoxInt(4),
 986                                                    BoxInt(153)], 'void')
 987        assert r is None
 988        r = self.execute_operation(rop.STRGETITEM, [s_box, BoxInt(5)], 'int')
 989        assert r.value == 254
 990        r = self.execute_operation(rop.STRGETITEM, [s_box, BoxInt(4)], 'int')
 991        assert r.value == 153
 992
 993    def test_copystrcontent(self):
 994        s_box = self.alloc_string("abcdef")
 995        for s_box in [s_box, s_box.constbox()]:
 996            for srcstart_box in [BoxInt(2), ConstInt(2)]:
 997                for dststart_box in [BoxInt(3), ConstInt(3)]:
 998                    for length_box in [BoxInt(4), ConstInt(4)]:
 999                        for r_box_is_const in [False, True]:
1000                            r_box = self.alloc_string("!???????!")
1001                            if r_box_is_const:
1002                                r_box = r_box.constbox()
1003                                self.execute_operation(rop.COPYSTRCONTENT,
1004                                                       [s_box, r_box,
1005                                                        srcstart_box,
1006                                                        dststart_box,
1007                                                        length_box], 'void')
1008                                assert self.look_string(r_box) == "!??cdef?!"
1009
1010    def test_copyunicodecontent(self):
1011        s_box = self.alloc_unicode(u"abcdef")
1012        for s_box in [s_box, s_box.constbox()]:
1013            for srcstart_box in [BoxInt(2), ConstInt(2)]:
1014                for dststart_box in [BoxInt(3), ConstInt(3)]:
1015                    for length_box in [BoxInt(4), ConstInt(4)]:
1016                        for r_box_is_const in [False, True]:
1017                            r_box = self.alloc_unicode(u"!???????!")
1018                            if r_box_is_const:
1019                                r_box = r_box.constbox()
1020                                self.execute_operation(rop.COPYUNICODECONTENT,
1021                                                       [s_box, r_box,
1022                                                        srcstart_box,
1023                                                        dststart_box,
1024                                                        length_box], 'void')
1025                                assert self.look_unicode(r_box) == u"!??cdef?!"
1026
1027    def test_do_unicode_basic(self):
1028        u = self.cpu.bh_newunicode(5)
1029        self.cpu.bh_unicodesetitem(u, 4, 123)
1030        r = self.cpu.bh_unicodegetitem(u, 4)
1031        assert r == 123
1032
1033    def test_unicode_basic(self):
1034        u_box = self.alloc_unicode(u"hello\u1234")
1035        r = self.execute_operation(rop.UNICODELEN, [u_box], 'int')
1036        assert r.value == 6
1037        r = self.execute_operation(rop.UNICODEGETITEM, [u_box, BoxInt(5)],
1038                                   'int')
1039        assert r.value == 0x1234
1040        r = self.execute_operation(rop.UNICODESETITEM, [u_box, BoxInt(4),
1041                                                        BoxInt(31313)], 'void')
1042        assert r is None
1043        r = self.execute_operation(rop.UNICODEGETITEM, [u_box, BoxInt(5)],
1044                                   'int')
1045        assert r.value == 0x1234
1046        r = self.execute_operation(rop.UNICODEGETITEM, [u_box, BoxInt(4)],
1047                                   'int')
1048        assert r.value == 31313
1049
1050    def test_same_as(self):
1051        r = self.execute_operation(rop.SAME_AS, [ConstInt(5)], 'int')
1052        assert r.value == 5
1053        r = self.execute_operation(rop.SAME_AS, [BoxInt(5)], 'int')
1054        assert r.value == 5
1055        u_box = self.alloc_unicode(u"hello\u1234")
1056        r = self.execute_operation(rop.SAME_AS, [u_box.constbox()], 'ref')
1057        assert r.value == u_box.value
1058        r = self.execute_operation(rop.SAME_AS, [u_box], 'ref')
1059        assert r.value == u_box.value
1060
1061        if self.cpu.supports_floats:
1062            r = self.execute_operation(rop.SAME_AS, [constfloat(5.5)], 'float')
1063            assert r.getfloat() == 5.5
1064            r = self.execute_operation(rop.SAME_AS, [boxfloat(5.5)], 'float')
1065            assert r.getfloat() == 5.5
1066
1067    def test_virtual_ref(self):
1068        pass   # VIRTUAL_REF must not reach the backend nowadays
1069
1070    def test_virtual_ref_finish(self):
1071        pass   # VIRTUAL_REF_FINISH must not reach the backend nowadays
1072
1073    def test_jump(self):
1074        # this test generates small loops where the JUMP passes many
1075        # arguments of various types, shuffling them around.
1076        if self.cpu.supports_floats:
1077            numkinds = 3
1078        else:
1079            numkinds = 2
1080        seed = random.randrange(0, 10000)
1081        print 'Seed is', seed    # or choose it by changing the previous line
1082        r = random.Random()
1083        r.seed(seed)
1084        for nb_args in range(50):
1085            print 'Passing %d arguments around...' % nb_args
1086            #
1087            inputargs = []
1088            for k in range(nb_args):
1089                kind = r.randrange(0, numkinds)
1090                if kind == 0:
1091                    inputargs.append(BoxInt())
1092                elif kind == 1:
1093                    inputargs.append(BoxPtr())
1094                else:
1095                    inputargs.append(BoxFloat())
1096            jumpargs = []
1097            remixing = []
1098            for srcbox in inputargs:
1099                n = r.randrange(0, len(inputargs))
1100                otherbox = inputargs[n]
1101                if otherbox.type == srcbox.type:
1102                    remixing.append((srcbox, otherbox))
1103                else:
1104                    otherbox = srcbox
1105                jumpargs.append(otherbox)
1106            #
1107            index_counter = r.randrange(0, len(inputargs)+1)
1108            i0 = BoxInt()
1109            i1 = BoxInt()
1110            i2 = BoxInt()
1111            inputargs.insert(index_counter, i0)
1112            jumpargs.insert(index_counter, i1)
1113            #
1114            looptoken = JitCellToken()
1115            targettoken = TargetToken()
1116            faildescr = BasicFailDescr(15)
1117            operations = [
1118                ResOperation(rop.LABEL, inputargs, None, descr=targettoken),
1119                ResOperation(rop.INT_SUB, [i0, ConstInt(1)], i1),
1120                ResOperation(rop.INT_GE, [i1,

Large files files are truncated, but you can click here to view the full file