PageRenderTime 68ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

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

http://github.com/pypy/pypy
Python | 3299 lines | 3048 code | 145 blank | 106 comment | 194 complexity | 6a2f55e39c425e24ba25e3c9b6b599bb MD5 | raw file

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

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