PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://bitbucket.org/pypy/pypy/
Python | 1453 lines | 1302 code | 95 blank | 56 comment | 171 complexity | a2309fdf7fa36042244b69c00afba735 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0

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

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

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