PageRenderTime 56ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/jit/backend/llgraph/runner.py

https://bitbucket.org/pypy/pypy/
Python | 896 lines | 860 code | 29 blank | 7 comment | 5 complexity | 52c762f86e7a52e02a0d4b1f0db8330b MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. """
  2. Minimal-API wrapper around the llinterpreter to run operations.
  3. """
  4. from pypy.rlib.unroll import unrolling_iterable
  5. from pypy.rlib.objectmodel import we_are_translated
  6. from pypy.rpython.lltypesystem import lltype, llmemory, rclass
  7. from pypy.rpython.ootypesystem import ootype
  8. from pypy.rpython.llinterp import LLInterpreter
  9. from pypy.jit.metainterp import history
  10. from pypy.jit.metainterp.history import REF, INT, FLOAT, STRUCT
  11. from pypy.jit.metainterp.warmstate import unwrap
  12. from pypy.jit.metainterp.resoperation import rop
  13. from pypy.jit.backend import model
  14. from pypy.jit.backend.llgraph import llimpl, symbolic
  15. from pypy.jit.metainterp.typesystem import llhelper, oohelper
  16. from pypy.jit.codewriter import heaptracker, longlong
  17. class MiniStats:
  18. pass
  19. class Descr(history.AbstractDescr):
  20. def __init__(self, ofs, typeinfo, extrainfo=None, name=None,
  21. arg_types=None, count_fields_if_immut=-1, ffi_flags=0, width=-1):
  22. self.ofs = ofs
  23. self.width = width
  24. self.typeinfo = typeinfo
  25. self.extrainfo = extrainfo
  26. self.name = name
  27. self.arg_types = arg_types
  28. self.count_fields_if_immut = count_fields_if_immut
  29. self.ffi_flags = ffi_flags
  30. def get_arg_types(self):
  31. return self.arg_types
  32. def get_result_type(self):
  33. return self.typeinfo
  34. def get_extra_info(self):
  35. return self.extrainfo
  36. def sort_key(self):
  37. """Returns an integer that can be used as a key when sorting the
  38. field descrs of a single structure. The property that this
  39. number has is simply that two different field descrs of the same
  40. structure give different numbers."""
  41. return self.ofs
  42. def is_pointer_field(self):
  43. return self.typeinfo == REF
  44. def is_float_field(self):
  45. return self.typeinfo == FLOAT
  46. def is_array_of_pointers(self):
  47. return self.typeinfo == REF
  48. def is_array_of_floats(self):
  49. return self.typeinfo == FLOAT
  50. def is_array_of_structs(self):
  51. return self.typeinfo == STRUCT
  52. def as_vtable_size_descr(self):
  53. return self
  54. def count_fields_if_immutable(self):
  55. return self.count_fields_if_immut
  56. def get_ffi_flags(self):
  57. return self.ffi_flags
  58. def __lt__(self, other):
  59. raise TypeError("cannot use comparison on Descrs")
  60. def __le__(self, other):
  61. raise TypeError("cannot use comparison on Descrs")
  62. def __gt__(self, other):
  63. raise TypeError("cannot use comparison on Descrs")
  64. def __ge__(self, other):
  65. raise TypeError("cannot use comparison on Descrs")
  66. def __repr__(self):
  67. args = [repr(self.ofs), repr(self.typeinfo)]
  68. if self.name is not None:
  69. args.append(repr(self.name))
  70. if self.extrainfo is not None:
  71. args.append('E')
  72. return '<Descr %r>' % (', '.join(args),)
  73. history.TreeLoop._compiled_version = lltype.nullptr(llimpl.COMPILEDLOOP.TO)
  74. class BaseCPU(model.AbstractCPU):
  75. supports_floats = True
  76. supports_longlong = llimpl.IS_32_BIT
  77. supports_singlefloats = True
  78. def __init__(self, rtyper, stats=None, opts=None,
  79. translate_support_code=False,
  80. annmixlevel=None, gcdescr=None):
  81. assert type(opts) is not bool
  82. model.AbstractCPU.__init__(self)
  83. self.rtyper = rtyper
  84. self.translate_support_code = translate_support_code
  85. self.stats = stats or MiniStats()
  86. self.stats.exec_counters = {}
  87. self.stats.exec_jumps = 0
  88. self.stats.exec_conditional_jumps = 0
  89. llimpl._stats = self.stats
  90. llimpl._llinterp = LLInterpreter(self.rtyper)
  91. self._future_values = []
  92. self._descrs = {}
  93. def _freeze_(self):
  94. assert self.translate_support_code
  95. return False
  96. def getdescr(self, ofs, typeinfo='?', extrainfo=None, name=None,
  97. arg_types=None, count_fields_if_immut=-1, ffi_flags=0, width=-1):
  98. key = (ofs, typeinfo, extrainfo, name, arg_types,
  99. count_fields_if_immut, ffi_flags, width)
  100. try:
  101. return self._descrs[key]
  102. except KeyError:
  103. descr = Descr(ofs, typeinfo, extrainfo, name, arg_types,
  104. count_fields_if_immut, ffi_flags, width)
  105. self._descrs[key] = descr
  106. return descr
  107. def compile_bridge(self, faildescr, inputargs, operations,
  108. original_loop_token, log=True):
  109. c = llimpl.compile_start()
  110. clt = original_loop_token.compiled_loop_token
  111. clt.loop_and_bridges.append(c)
  112. clt.compiling_a_bridge()
  113. self._compile_loop_or_bridge(c, inputargs, operations, clt)
  114. old, oldindex = faildescr._compiled_fail
  115. llimpl.compile_redirect_fail(old, oldindex, c)
  116. def compile_loop(self, inputargs, operations, jitcell_token,
  117. log=True, name=''):
  118. """In a real assembler backend, this should assemble the given
  119. list of operations. Here we just generate a similar CompiledLoop
  120. instance. The code here is RPython, whereas the code in llimpl
  121. is not.
  122. """
  123. c = llimpl.compile_start()
  124. clt = model.CompiledLoopToken(self, jitcell_token.number)
  125. clt.loop_and_bridges = [c]
  126. clt.compiled_version = c
  127. jitcell_token.compiled_loop_token = clt
  128. self._compile_loop_or_bridge(c, inputargs, operations, clt)
  129. def free_loop_and_bridges(self, compiled_loop_token):
  130. for c in compiled_loop_token.loop_and_bridges:
  131. llimpl.mark_as_free(c)
  132. model.AbstractCPU.free_loop_and_bridges(self, compiled_loop_token)
  133. def _compile_loop_or_bridge(self, c, inputargs, operations, clt):
  134. var2index = {}
  135. for box in inputargs:
  136. if isinstance(box, history.BoxInt):
  137. var2index[box] = llimpl.compile_start_int_var(c)
  138. elif isinstance(box, self.ts.BoxRef):
  139. TYPE = self.ts.BASETYPE
  140. var2index[box] = llimpl.compile_start_ref_var(c, TYPE)
  141. elif isinstance(box, history.BoxFloat):
  142. var2index[box] = llimpl.compile_start_float_var(c)
  143. else:
  144. raise Exception("box is: %r" % (box,))
  145. llimpl.compile_started_vars(clt)
  146. self._compile_operations(c, operations, var2index, clt)
  147. return c
  148. def _compile_operations(self, c, operations, var2index, clt):
  149. for op in operations:
  150. llimpl.compile_add(c, op.getopnum())
  151. descr = op.getdescr()
  152. if isinstance(descr, Descr):
  153. llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo,
  154. descr.arg_types, descr.extrainfo,
  155. descr.width)
  156. if isinstance(descr, history.JitCellToken):
  157. assert op.getopnum() != rop.JUMP
  158. llimpl.compile_add_loop_token(c, descr)
  159. if isinstance(descr, history.TargetToken) and op.getopnum() == rop.LABEL:
  160. llimpl.compile_add_target_token(c, descr, clt)
  161. if self.is_oo and isinstance(descr, (OODescr, MethDescr)):
  162. # hack hack, not rpython
  163. c._obj.externalobj.operations[-1].setdescr(descr)
  164. for i in range(op.numargs()):
  165. x = op.getarg(i)
  166. if isinstance(x, history.Box):
  167. llimpl.compile_add_var(c, var2index[x])
  168. elif isinstance(x, history.ConstInt):
  169. llimpl.compile_add_int_const(c, x.value)
  170. elif isinstance(x, self.ts.ConstRef):
  171. llimpl.compile_add_ref_const(c, x.value, self.ts.BASETYPE)
  172. elif isinstance(x, history.ConstFloat):
  173. llimpl.compile_add_float_const(c, x.value)
  174. elif isinstance(x, Descr):
  175. llimpl.compile_add_descr_arg(c, x.ofs, x.typeinfo,
  176. x.arg_types)
  177. else:
  178. raise Exception("'%s' args contain: %r" % (op.getopname(),
  179. x))
  180. if op.is_guard():
  181. faildescr = op.getdescr()
  182. assert isinstance(faildescr, history.AbstractFailDescr)
  183. faildescr._fail_args_types = []
  184. for box in op.getfailargs():
  185. if box is None:
  186. type = history.HOLE
  187. else:
  188. type = box.type
  189. faildescr._fail_args_types.append(type)
  190. fail_index = self.get_fail_descr_number(faildescr)
  191. index = llimpl.compile_add_fail(c, fail_index)
  192. faildescr._compiled_fail = c, index
  193. for box in op.getfailargs():
  194. if box is not None:
  195. llimpl.compile_add_fail_arg(c, var2index[box])
  196. else:
  197. llimpl.compile_add_fail_arg(c, -1)
  198. x = op.result
  199. if x is not None:
  200. if isinstance(x, history.BoxInt):
  201. var2index[x] = llimpl.compile_add_int_result(c)
  202. elif isinstance(x, self.ts.BoxRef):
  203. var2index[x] = llimpl.compile_add_ref_result(c, self.ts.BASETYPE)
  204. elif isinstance(x, history.BoxFloat):
  205. var2index[x] = llimpl.compile_add_float_result(c)
  206. else:
  207. raise Exception("%s.result contain: %r" % (op.getopname(),
  208. x))
  209. op = operations[-1]
  210. assert op.is_final()
  211. if op.getopnum() == rop.JUMP:
  212. targettoken = op.getdescr()
  213. llimpl.compile_add_jump_target(c, targettoken, clt)
  214. elif op.getopnum() == rop.FINISH:
  215. faildescr = op.getdescr()
  216. index = self.get_fail_descr_number(faildescr)
  217. llimpl.compile_add_fail(c, index)
  218. else:
  219. assert False, "unknown operation"
  220. def _execute_token(self, loop_token):
  221. compiled_version = loop_token.compiled_loop_token.compiled_version
  222. frame = llimpl.new_frame(self.is_oo, self)
  223. # setup the frame
  224. llimpl.frame_clear(frame, compiled_version)
  225. # run the loop
  226. fail_index = llimpl.frame_execute(frame)
  227. # we hit a FAIL operation.
  228. self.latest_frame = frame
  229. return fail_index
  230. def make_execute_token(self, *argtypes):
  231. nb_args = len(argtypes)
  232. unroll_argtypes = unrolling_iterable(list(enumerate(argtypes)))
  233. #
  234. def execute_token(loop_token, *args):
  235. assert len(args) == nb_args
  236. for index, TYPE in unroll_argtypes:
  237. x = args[index]
  238. assert TYPE == lltype.typeOf(x)
  239. if TYPE == lltype.Signed:
  240. llimpl.set_future_value_int(index, x)
  241. elif TYPE == llmemory.GCREF:
  242. llimpl.set_future_value_ref(index, x)
  243. elif TYPE == longlong.FLOATSTORAGE:
  244. llimpl.set_future_value_float(index, x)
  245. else:
  246. assert 0
  247. #
  248. fail_index = self._execute_token(loop_token)
  249. return self.get_fail_descr_from_number(fail_index)
  250. #
  251. return execute_token
  252. def get_latest_value_int(self, index):
  253. return llimpl.frame_int_getvalue(self.latest_frame, index)
  254. def get_latest_value_ref(self, index):
  255. return llimpl.frame_ptr_getvalue(self.latest_frame, index)
  256. def get_latest_value_float(self, index):
  257. return llimpl.frame_float_getvalue(self.latest_frame, index)
  258. def get_latest_value_count(self):
  259. return llimpl.frame_get_value_count(self.latest_frame)
  260. def get_latest_force_token(self):
  261. token = llimpl.get_frame_forced_token(self.latest_frame)
  262. return heaptracker.adr2int(token)
  263. def clear_latest_values(self, count):
  264. llimpl.frame_clear_latest_values(self.latest_frame, count)
  265. def redirect_call_assembler(self, oldlooptoken, newlooptoken):
  266. if we_are_translated():
  267. raise ValueError("CALL_ASSEMBLER not supported")
  268. llimpl.redirect_call_assembler(self, oldlooptoken, newlooptoken)
  269. def invalidate_loop(self, looptoken):
  270. for loop in looptoken.compiled_loop_token.loop_and_bridges:
  271. loop._obj.externalobj.invalid = True
  272. # ----------
  273. def sizeof(self, S):
  274. assert not isinstance(S, lltype.Ptr)
  275. count = heaptracker.count_fields_if_immutable(S)
  276. return self.getdescr(symbolic.get_size(S), count_fields_if_immut=count)
  277. class LLtypeCPU(BaseCPU):
  278. is_oo = False
  279. ts = llhelper
  280. def __init__(self, *args, **kwds):
  281. BaseCPU.__init__(self, *args, **kwds)
  282. self.fielddescrof_vtable = self.fielddescrof(rclass.OBJECT, 'typeptr')
  283. def fielddescrof(self, S, fieldname):
  284. ofs, size = symbolic.get_field_token(S, fieldname)
  285. token = history.getkind(getattr(S, fieldname))
  286. return self.getdescr(ofs, token[0], name=fieldname)
  287. def interiorfielddescrof(self, A, fieldname):
  288. S = A.OF
  289. width = symbolic.get_size(A)
  290. ofs, size = symbolic.get_field_token(S, fieldname)
  291. token = history.getkind(getattr(S, fieldname))
  292. return self.getdescr(ofs, token[0], name=fieldname, width=width)
  293. def interiorfielddescrof_dynamic(self, offset, width, fieldsize,
  294. is_pointer, is_float, is_signed):
  295. if is_pointer:
  296. typeinfo = REF
  297. elif is_float:
  298. typeinfo = FLOAT
  299. else:
  300. typeinfo = INT
  301. # we abuse the arg_types field to distinguish dynamic and static descrs
  302. return Descr(offset, typeinfo, arg_types='dynamic', name='<dynamic interior field>', width=width)
  303. def calldescrof(self, FUNC, ARGS, RESULT, extrainfo):
  304. arg_types = []
  305. for ARG in ARGS:
  306. token = history.getkind(ARG)
  307. if token != 'void':
  308. if token == 'float' and longlong.is_longlong(ARG):
  309. token = 'L'
  310. arg_types.append(token[0])
  311. token = history.getkind(RESULT)
  312. if token == 'float' and longlong.is_longlong(RESULT):
  313. token = 'L'
  314. return self.getdescr(0, token[0], extrainfo=extrainfo,
  315. arg_types=''.join(arg_types))
  316. def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo, ffi_flags):
  317. from pypy.jit.backend.llsupport.ffisupport import get_ffi_type_kind
  318. from pypy.jit.backend.llsupport.ffisupport import UnsupportedKind
  319. arg_types = []
  320. try:
  321. for arg in ffi_args:
  322. kind = get_ffi_type_kind(self, arg)
  323. if kind != history.VOID:
  324. arg_types.append(kind)
  325. reskind = get_ffi_type_kind(self, ffi_result)
  326. except UnsupportedKind:
  327. return None
  328. return self.getdescr(0, reskind, extrainfo=extrainfo,
  329. arg_types=''.join(arg_types),
  330. ffi_flags=ffi_flags)
  331. def grab_exc_value(self):
  332. return llimpl.grab_exc_value()
  333. def arraydescrof(self, A):
  334. assert A.OF != lltype.Void
  335. assert isinstance(A, lltype.GcArray) or A._hints.get('nolength', False)
  336. size = symbolic.get_size(A)
  337. if isinstance(A.OF, lltype.Ptr) or isinstance(A.OF, lltype.Primitive):
  338. token = history.getkind(A.OF)[0]
  339. elif isinstance(A.OF, lltype.Struct):
  340. token = 's'
  341. else:
  342. token = '?'
  343. return self.getdescr(size, token)
  344. # ---------- the backend-dependent operations ----------
  345. def bh_strlen(self, string):
  346. return llimpl.do_strlen(string)
  347. def bh_strgetitem(self, string, index):
  348. return llimpl.do_strgetitem(string, index)
  349. def bh_unicodelen(self, string):
  350. return llimpl.do_unicodelen(string)
  351. def bh_unicodegetitem(self, string, index):
  352. return llimpl.do_unicodegetitem(string, index)
  353. def bh_getarrayitem_gc_i(self, arraydescr, array, index):
  354. assert isinstance(arraydescr, Descr)
  355. return llimpl.do_getarrayitem_gc_int(array, index)
  356. def bh_getarrayitem_raw_i(self, arraydescr, array, index):
  357. assert isinstance(arraydescr, Descr)
  358. return llimpl.do_getarrayitem_raw_int(array, index)
  359. def bh_getarrayitem_gc_r(self, arraydescr, array, index):
  360. assert isinstance(arraydescr, Descr)
  361. return llimpl.do_getarrayitem_gc_ptr(array, index)
  362. def bh_getarrayitem_gc_f(self, arraydescr, array, index):
  363. assert isinstance(arraydescr, Descr)
  364. return llimpl.do_getarrayitem_gc_float(array, index)
  365. def bh_getarrayitem_raw_f(self, arraydescr, array, index):
  366. assert isinstance(arraydescr, Descr)
  367. return llimpl.do_getarrayitem_raw_float(array, index)
  368. def bh_getfield_gc_i(self, struct, fielddescr):
  369. assert isinstance(fielddescr, Descr)
  370. return llimpl.do_getfield_gc_int(struct, fielddescr.ofs)
  371. def bh_getfield_gc_r(self, struct, fielddescr):
  372. assert isinstance(fielddescr, Descr)
  373. return llimpl.do_getfield_gc_ptr(struct, fielddescr.ofs)
  374. def bh_getfield_gc_f(self, struct, fielddescr):
  375. assert isinstance(fielddescr, Descr)
  376. return llimpl.do_getfield_gc_float(struct, fielddescr.ofs)
  377. def bh_getfield_raw_i(self, struct, fielddescr):
  378. assert isinstance(fielddescr, Descr)
  379. return llimpl.do_getfield_raw_int(struct, fielddescr.ofs)
  380. def bh_getfield_raw_r(self, struct, fielddescr):
  381. assert isinstance(fielddescr, Descr)
  382. return llimpl.do_getfield_raw_ptr(struct, fielddescr.ofs)
  383. def bh_getfield_raw_f(self, struct, fielddescr):
  384. assert isinstance(fielddescr, Descr)
  385. return llimpl.do_getfield_raw_float(struct, fielddescr.ofs)
  386. def bh_getinteriorfield_gc_i(self, array, index, descr):
  387. assert isinstance(descr, Descr)
  388. return llimpl.do_getinteriorfield_gc_int(array, index, descr.ofs)
  389. def bh_getinteriorfield_gc_r(self, array, index, descr):
  390. assert isinstance(descr, Descr)
  391. return llimpl.do_getinteriorfield_gc_ptr(array, index, descr.ofs)
  392. def bh_getinteriorfield_gc_f(self, array, index, descr):
  393. assert isinstance(descr, Descr)
  394. return llimpl.do_getinteriorfield_gc_float(array, index, descr.ofs)
  395. def bh_setinteriorfield_gc_i(self, array, index, descr, value):
  396. assert isinstance(descr, Descr)
  397. return llimpl.do_setinteriorfield_gc_int(array, index, descr.ofs,
  398. value)
  399. def bh_setinteriorfield_gc_r(self, array, index, descr, value):
  400. assert isinstance(descr, Descr)
  401. return llimpl.do_setinteriorfield_gc_ptr(array, index, descr.ofs,
  402. value)
  403. def bh_setinteriorfield_gc_f(self, array, index, descr, value):
  404. assert isinstance(descr, Descr)
  405. return llimpl.do_setinteriorfield_gc_float(array, index, descr.ofs,
  406. value)
  407. def bh_new(self, sizedescr):
  408. assert isinstance(sizedescr, Descr)
  409. return llimpl.do_new(sizedescr.ofs)
  410. def bh_new_with_vtable(self, sizedescr, vtable):
  411. assert isinstance(sizedescr, Descr)
  412. result = llimpl.do_new(sizedescr.ofs)
  413. llimpl.do_setfield_gc_int(result, self.fielddescrof_vtable.ofs, vtable)
  414. return result
  415. def bh_classof(self, struct):
  416. struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct)
  417. result_adr = llmemory.cast_ptr_to_adr(struct.typeptr)
  418. return heaptracker.adr2int(result_adr)
  419. def bh_new_array(self, arraydescr, length):
  420. assert isinstance(arraydescr, Descr)
  421. return llimpl.do_new_array(arraydescr.ofs, length)
  422. def bh_arraylen_gc(self, arraydescr, array):
  423. assert isinstance(arraydescr, Descr)
  424. return llimpl.do_arraylen_gc(arraydescr, array)
  425. def bh_setarrayitem_gc_i(self, arraydescr, array, index, newvalue):
  426. assert isinstance(arraydescr, Descr)
  427. llimpl.do_setarrayitem_gc_int(array, index, newvalue)
  428. def bh_setarrayitem_raw_i(self, arraydescr, array, index, newvalue):
  429. assert isinstance(arraydescr, Descr)
  430. llimpl.do_setarrayitem_raw_int(array, index, newvalue)
  431. def bh_setarrayitem_gc_r(self, arraydescr, array, index, newvalue):
  432. assert isinstance(arraydescr, Descr)
  433. llimpl.do_setarrayitem_gc_ptr(array, index, newvalue)
  434. def bh_setarrayitem_gc_f(self, arraydescr, array, index, newvalue):
  435. assert isinstance(arraydescr, Descr)
  436. llimpl.do_setarrayitem_gc_float(array, index, newvalue)
  437. def bh_setarrayitem_raw_f(self, arraydescr, array, index, newvalue):
  438. assert isinstance(arraydescr, Descr)
  439. llimpl.do_setarrayitem_raw_float(array, index, newvalue)
  440. def bh_setfield_gc_i(self, struct, fielddescr, newvalue):
  441. assert isinstance(fielddescr, Descr)
  442. llimpl.do_setfield_gc_int(struct, fielddescr.ofs, newvalue)
  443. def bh_setfield_gc_r(self, struct, fielddescr, newvalue):
  444. assert isinstance(fielddescr, Descr)
  445. llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue)
  446. def bh_setfield_gc_f(self, struct, fielddescr, newvalue):
  447. assert isinstance(fielddescr, Descr)
  448. llimpl.do_setfield_gc_float(struct, fielddescr.ofs, newvalue)
  449. def bh_setfield_raw_i(self, struct, fielddescr, newvalue):
  450. assert isinstance(fielddescr, Descr)
  451. llimpl.do_setfield_raw_int(struct, fielddescr.ofs, newvalue)
  452. def bh_setfield_raw_r(self, struct, fielddescr, newvalue):
  453. assert isinstance(fielddescr, Descr)
  454. llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue)
  455. def bh_setfield_raw_f(self, struct, fielddescr, newvalue):
  456. assert isinstance(fielddescr, Descr)
  457. llimpl.do_setfield_raw_float(struct, fielddescr.ofs, newvalue)
  458. def bh_newstr(self, length):
  459. return llimpl.do_newstr(length)
  460. def bh_newunicode(self, length):
  461. return llimpl.do_newunicode(length)
  462. def bh_strsetitem(self, string, index, newvalue):
  463. llimpl.do_strsetitem(string, index, newvalue)
  464. def bh_unicodesetitem(self, string, index, newvalue):
  465. llimpl.do_unicodesetitem(string, index, newvalue)
  466. def bh_call_i(self, func, calldescr, args_i, args_r, args_f):
  467. self._prepare_call(INT, calldescr, args_i, args_r, args_f)
  468. return llimpl.do_call_int(func)
  469. def bh_call_r(self, func, calldescr, args_i, args_r, args_f):
  470. self._prepare_call(REF, calldescr, args_i, args_r, args_f)
  471. return llimpl.do_call_ptr(func)
  472. def bh_call_f(self, func, calldescr, args_i, args_r, args_f):
  473. self._prepare_call(FLOAT + 'L', calldescr, args_i, args_r, args_f)
  474. return llimpl.do_call_float(func)
  475. def bh_call_v(self, func, calldescr, args_i, args_r, args_f):
  476. self._prepare_call('v', calldescr, args_i, args_r, args_f)
  477. llimpl.do_call_void(func)
  478. def _prepare_call(self, resulttypeinfo, calldescr, args_i, args_r, args_f):
  479. assert isinstance(calldescr, Descr)
  480. assert calldescr.typeinfo in resulttypeinfo
  481. if args_i is not None:
  482. for x in args_i:
  483. llimpl.do_call_pushint(x)
  484. if args_r is not None:
  485. for x in args_r:
  486. llimpl.do_call_pushptr(x)
  487. if args_f is not None:
  488. for x in args_f:
  489. llimpl.do_call_pushfloat(x)
  490. def force(self, force_token):
  491. token = llmemory.cast_int_to_adr(force_token)
  492. frame = llimpl.get_forced_token_frame(token)
  493. fail_index = llimpl.force(frame)
  494. self.latest_frame = frame
  495. return self.get_fail_descr_from_number(fail_index)
  496. class OOtypeCPU_xxx_disabled(BaseCPU):
  497. is_oo = True
  498. ts = oohelper
  499. @staticmethod
  500. def fielddescrof(T, fieldname):
  501. # use class where the field is really defined as a key
  502. T1, _ = T._lookup_field(fieldname)
  503. return FieldDescr.new(T1, fieldname)
  504. @staticmethod
  505. def calldescrof(FUNC, ARGS, RESULT, extrainfo):
  506. return StaticMethDescr.new(FUNC, ARGS, RESULT, extrainfo)
  507. @staticmethod
  508. def methdescrof(SELFTYPE, methname):
  509. return MethDescr.new(SELFTYPE, methname)
  510. @staticmethod
  511. def typedescrof(TYPE):
  512. return TypeDescr.new(TYPE)
  513. @staticmethod
  514. def arraydescrof(A):
  515. assert isinstance(A, ootype.Array)
  516. TYPE = A.ITEM
  517. return TypeDescr.new(TYPE)
  518. def typedescr2classbox(self, descr):
  519. assert isinstance(descr, TypeDescr)
  520. return history.ConstObj(ootype.cast_to_object(
  521. ootype.runtimeClass(descr.TYPE)))
  522. def get_exception(self):
  523. if llimpl._last_exception:
  524. e = llimpl._last_exception.args[0]
  525. return ootype.cast_to_object(e)
  526. else:
  527. return ootype.NULL
  528. def get_exc_value(self):
  529. if llimpl._last_exception:
  530. earg = llimpl._last_exception.args[1]
  531. return ootype.cast_to_object(earg)
  532. else:
  533. return ootype.NULL
  534. def get_overflow_error(self):
  535. ll_err = llimpl._get_error(OverflowError)
  536. return (ootype.cast_to_object(ll_err.args[0]),
  537. ootype.cast_to_object(ll_err.args[1]))
  538. def get_zero_division_error(self):
  539. ll_err = llimpl._get_error(ZeroDivisionError)
  540. return (ootype.cast_to_object(ll_err.args[0]),
  541. ootype.cast_to_object(ll_err.args[1]))
  542. def do_new_with_vtable(self, clsbox):
  543. cls = clsbox.getref_base()
  544. typedescr = self.class_sizes[cls]
  545. return typedescr.create()
  546. def do_new_array(self, lengthbox, typedescr):
  547. assert isinstance(typedescr, TypeDescr)
  548. return typedescr.create_array(lengthbox)
  549. def do_new(self, typedescr):
  550. assert isinstance(typedescr, TypeDescr)
  551. return typedescr.create()
  552. def do_runtimenew(self, classbox):
  553. "NOT_RPYTHON"
  554. classobj = classbox.getref(ootype.Class)
  555. res = ootype.runtimenew(classobj)
  556. return history.BoxObj(ootype.cast_to_object(res))
  557. def do_instanceof(self, box1, typedescr):
  558. assert isinstance(typedescr, TypeDescr)
  559. return typedescr.instanceof(box1)
  560. def do_getfield_gc(self, box1, fielddescr):
  561. assert isinstance(fielddescr, FieldDescr)
  562. return fielddescr.getfield(box1)
  563. def do_setfield_gc(self, box1, box2, fielddescr):
  564. assert isinstance(fielddescr, FieldDescr)
  565. return fielddescr.setfield(box1, box2)
  566. def do_getarrayitem_gc(self, box1, box2, typedescr):
  567. assert isinstance(typedescr, TypeDescr)
  568. return typedescr.getarrayitem(box1, box2)
  569. def do_setarrayitem_gc(self, box1, box2, box3, typedescr):
  570. assert isinstance(typedescr, TypeDescr)
  571. return typedescr.setarrayitem(box1, box2, box3)
  572. def do_arraylen_gc(self, box1, typedescr):
  573. assert isinstance(typedescr, TypeDescr)
  574. return typedescr.getarraylength(box1)
  575. def do_call_XXX(self, args, descr):
  576. assert isinstance(descr, StaticMethDescr)
  577. funcbox = args[0]
  578. argboxes = args[1:]
  579. x = descr.callfunc(funcbox, argboxes)
  580. # XXX: return None if RESULT is Void
  581. return x
  582. def do_oosend(self, args, descr):
  583. assert isinstance(descr, MethDescr)
  584. selfbox = args[0]
  585. argboxes = args[1:]
  586. x = descr.callmeth(selfbox, argboxes)
  587. # XXX: return None if METH.RESULT is Void
  588. return x
  589. def make_getargs(ARGS):
  590. argsiter = unrolling_iterable(ARGS)
  591. args_n = len([ARG for ARG in ARGS if ARG is not ootype.Void])
  592. def getargs(argboxes):
  593. funcargs = ()
  594. assert len(argboxes) == args_n
  595. i = 0
  596. for ARG in argsiter:
  597. if ARG is ootype.Void:
  598. funcargs += (None,)
  599. else:
  600. box = argboxes[i]
  601. i+=1
  602. funcargs += (unwrap(ARG, box),)
  603. return funcargs
  604. return getargs
  605. def boxresult(RESULT, result):
  606. if isinstance(RESULT, ootype.OOType):
  607. return history.BoxObj(ootype.cast_to_object(result))
  608. elif RESULT is lltype.Float:
  609. return history.BoxFloat(result)
  610. else:
  611. return history.BoxInt(lltype.cast_primitive(ootype.Signed, result))
  612. boxresult._annspecialcase_ = 'specialize:arg(0)'
  613. class KeyManager(object):
  614. """
  615. Helper class to convert arbitrary dictionary keys to integers.
  616. """
  617. def __init__(self):
  618. self.keys = {}
  619. def getkey(self, key):
  620. try:
  621. return self.keys[key]
  622. except KeyError:
  623. n = len(self.keys)
  624. self.keys[key] = n
  625. return n
  626. def _freeze_(self):
  627. raise Exception("KeyManager is not supposed to be turned into a pbc")
  628. descr_cache = {}
  629. class OODescr(history.AbstractDescr):
  630. @classmethod
  631. def new(cls, *args):
  632. 'NOT_RPYTHON'
  633. key = (cls, args)
  634. try:
  635. return descr_cache[key]
  636. except KeyError:
  637. res = cls(*args)
  638. descr_cache[key] = res
  639. return res
  640. class StaticMethDescr(OODescr):
  641. def __init__(self, FUNC, ARGS, RESULT, extrainfo=None):
  642. self.FUNC = FUNC
  643. getargs = make_getargs(FUNC.ARGS)
  644. def callfunc(funcbox, argboxes):
  645. funcobj = funcbox.getref(FUNC)
  646. funcargs = getargs(argboxes)
  647. res = llimpl.call_maybe_on_top_of_llinterp(funcobj, funcargs)
  648. if RESULT is not ootype.Void:
  649. return boxresult(RESULT, res)
  650. self.callfunc = callfunc
  651. self.extrainfo = extrainfo
  652. def get_extra_info(self):
  653. return self.extrainfo
  654. class MethDescr(history.AbstractMethDescr):
  655. callmeth = None
  656. new = classmethod(OODescr.new.im_func)
  657. def __init__(self, SELFTYPE, methname):
  658. _, meth = SELFTYPE._lookup(methname)
  659. METH = ootype.typeOf(meth)
  660. self.SELFTYPE = SELFTYPE
  661. self.METH = METH
  662. self.methname = methname
  663. RESULT = METH.RESULT
  664. getargs = make_getargs(METH.ARGS)
  665. def callmeth(selfbox, argboxes):
  666. selfobj = selfbox.getref(SELFTYPE)
  667. meth = getattr(selfobj, methname)
  668. methargs = getargs(argboxes)
  669. res = llimpl.call_maybe_on_top_of_llinterp(meth, methargs)
  670. if RESULT is not ootype.Void:
  671. return boxresult(RESULT, res)
  672. self.callmeth = callmeth
  673. def __repr__(self):
  674. return '<MethDescr %r>' % self.methname
  675. class TypeDescr(OODescr):
  676. create = None
  677. def __init__(self, TYPE):
  678. self.TYPE = TYPE
  679. self.ARRAY = ARRAY = ootype.Array(TYPE)
  680. def create():
  681. return boxresult(TYPE, ootype.new(TYPE))
  682. def create_array(lengthbox):
  683. n = lengthbox.getint()
  684. return boxresult(ARRAY, ootype.oonewarray(ARRAY, n))
  685. def getarrayitem(arraybox, ibox):
  686. array = arraybox.getref(ARRAY)
  687. i = ibox.getint()
  688. return boxresult(TYPE, array.ll_getitem_fast(i))
  689. def setarrayitem(arraybox, ibox, valuebox):
  690. array = arraybox.getref(ARRAY)
  691. i = ibox.getint()
  692. value = unwrap(TYPE, valuebox)
  693. array.ll_setitem_fast(i, value)
  694. def getarraylength(arraybox):
  695. array = arraybox.getref(ARRAY)
  696. return boxresult(ootype.Signed, array.ll_length())
  697. def instanceof(box):
  698. obj = box.getref(ootype.ROOT)
  699. return history.BoxInt(ootype.instanceof(obj, TYPE))
  700. self.create = create
  701. self.create_array = create_array
  702. self.getarrayitem = getarrayitem
  703. self.setarrayitem = setarrayitem
  704. self.getarraylength = getarraylength
  705. self.instanceof = instanceof
  706. self._is_array_of_pointers = (history.getkind(TYPE) == 'ref')
  707. self._is_array_of_floats = (history.getkind(TYPE) == 'float')
  708. def is_array_of_pointers(self):
  709. # for arrays, TYPE is the type of the array item.
  710. return self._is_array_of_pointers
  711. def is_array_of_floats(self):
  712. # for arrays, TYPE is the type of the array item.
  713. return self._is_array_of_floats
  714. def __repr__(self):
  715. return '<TypeDescr %s>' % self.TYPE._short_name()
  716. class FieldDescr(OODescr):
  717. getfield = None
  718. _keys = KeyManager()
  719. def __init__(self, TYPE, fieldname):
  720. self.TYPE = TYPE
  721. self.fieldname = fieldname
  722. _, T = TYPE._lookup_field(fieldname)
  723. def getfield(objbox):
  724. obj = objbox.getref(TYPE)
  725. value = getattr(obj, fieldname)
  726. return boxresult(T, value)
  727. def setfield(objbox, valuebox):
  728. obj = objbox.getref(TYPE)
  729. value = unwrap(T, valuebox)
  730. setattr(obj, fieldname, value)
  731. self.getfield = getfield
  732. self.setfield = setfield
  733. self._is_pointer_field = (history.getkind(T) == 'ref')
  734. self._is_float_field = (history.getkind(T) == 'float')
  735. def sort_key(self):
  736. return self._keys.getkey((self.TYPE, self.fieldname))
  737. def is_pointer_field(self):
  738. return self._is_pointer_field
  739. def is_float_field(self):
  740. return self._is_float_field
  741. def equals(self, other):
  742. return self.TYPE == other.TYPE and \
  743. self.fieldname == other.fieldname
  744. def __repr__(self):
  745. return '<FieldDescr %r>' % self.fieldname