PageRenderTime 78ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://github.com/pypy/pypy
Python | 906 lines | 870 code | 29 blank | 7 comment | 5 complexity | 93aae34713ef099af10157489dab36ae MD5 | raw file
  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 fielddescrof_dynamic(self, offset, fieldsize, is_pointer, is_float, is_signed):
  288. if is_pointer:
  289. typeinfo = REF
  290. elif is_float:
  291. typeinfo = FLOAT
  292. else:
  293. typeinfo = INT
  294. # we abuse the arg_types field to distinguish dynamic and static descrs
  295. return self.getdescr(offset, typeinfo, arg_types='dynamic', name='<dynamic field>')
  296. def interiorfielddescrof(self, A, fieldname):
  297. S = A.OF
  298. width = symbolic.get_size(A)
  299. ofs, size = symbolic.get_field_token(S, fieldname)
  300. token = history.getkind(getattr(S, fieldname))
  301. return self.getdescr(ofs, token[0], name=fieldname, width=width)
  302. def interiorfielddescrof_dynamic(self, offset, width, fieldsize,
  303. is_pointer, is_float, is_signed):
  304. if is_pointer:
  305. typeinfo = REF
  306. elif is_float:
  307. typeinfo = FLOAT
  308. else:
  309. typeinfo = INT
  310. # we abuse the arg_types field to distinguish dynamic and static descrs
  311. return Descr(offset, typeinfo, arg_types='dynamic', name='<dynamic interior field>', width=width)
  312. def calldescrof(self, FUNC, ARGS, RESULT, extrainfo):
  313. arg_types = []
  314. for ARG in ARGS:
  315. token = history.getkind(ARG)
  316. if token != 'void':
  317. if token == 'float' and longlong.is_longlong(ARG):
  318. token = 'L'
  319. arg_types.append(token[0])
  320. token = history.getkind(RESULT)
  321. if token == 'float' and longlong.is_longlong(RESULT):
  322. token = 'L'
  323. return self.getdescr(0, token[0], extrainfo=extrainfo,
  324. arg_types=''.join(arg_types))
  325. def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo, ffi_flags):
  326. from pypy.jit.backend.llsupport.ffisupport import get_ffi_type_kind
  327. from pypy.jit.backend.llsupport.ffisupport import UnsupportedKind
  328. arg_types = []
  329. try:
  330. for arg in ffi_args:
  331. kind = get_ffi_type_kind(self, arg)
  332. if kind != history.VOID:
  333. arg_types.append(kind)
  334. reskind = get_ffi_type_kind(self, ffi_result)
  335. except UnsupportedKind:
  336. return None
  337. return self.getdescr(0, reskind, extrainfo=extrainfo,
  338. arg_types=''.join(arg_types),
  339. ffi_flags=ffi_flags)
  340. def grab_exc_value(self):
  341. return llimpl.grab_exc_value()
  342. def arraydescrof(self, A):
  343. assert A.OF != lltype.Void
  344. assert isinstance(A, lltype.GcArray) or A._hints.get('nolength', False)
  345. size = symbolic.get_size(A)
  346. if isinstance(A.OF, lltype.Ptr) or isinstance(A.OF, lltype.Primitive):
  347. token = history.getkind(A.OF)[0]
  348. elif isinstance(A.OF, lltype.Struct):
  349. token = 's'
  350. else:
  351. token = '?'
  352. return self.getdescr(size, token)
  353. # ---------- the backend-dependent operations ----------
  354. def bh_strlen(self, string):
  355. return llimpl.do_strlen(string)
  356. def bh_strgetitem(self, string, index):
  357. return llimpl.do_strgetitem(string, index)
  358. def bh_unicodelen(self, string):
  359. return llimpl.do_unicodelen(string)
  360. def bh_unicodegetitem(self, string, index):
  361. return llimpl.do_unicodegetitem(string, index)
  362. def bh_getarrayitem_gc_i(self, arraydescr, array, index):
  363. assert isinstance(arraydescr, Descr)
  364. return llimpl.do_getarrayitem_gc_int(array, index)
  365. def bh_getarrayitem_raw_i(self, arraydescr, array, index):
  366. assert isinstance(arraydescr, Descr)
  367. return llimpl.do_getarrayitem_raw_int(array, index)
  368. def bh_getarrayitem_gc_r(self, arraydescr, array, index):
  369. assert isinstance(arraydescr, Descr)
  370. return llimpl.do_getarrayitem_gc_ptr(array, index)
  371. def bh_getarrayitem_gc_f(self, arraydescr, array, index):
  372. assert isinstance(arraydescr, Descr)
  373. return llimpl.do_getarrayitem_gc_float(array, index)
  374. def bh_getarrayitem_raw_f(self, arraydescr, array, index):
  375. assert isinstance(arraydescr, Descr)
  376. return llimpl.do_getarrayitem_raw_float(array, index)
  377. def bh_getfield_gc_i(self, struct, fielddescr):
  378. assert isinstance(fielddescr, Descr)
  379. return llimpl.do_getfield_gc_int(struct, fielddescr.ofs)
  380. def bh_getfield_gc_r(self, struct, fielddescr):
  381. assert isinstance(fielddescr, Descr)
  382. return llimpl.do_getfield_gc_ptr(struct, fielddescr.ofs)
  383. def bh_getfield_gc_f(self, struct, fielddescr):
  384. assert isinstance(fielddescr, Descr)
  385. return llimpl.do_getfield_gc_float(struct, fielddescr.ofs)
  386. def bh_getfield_raw_i(self, struct, fielddescr):
  387. assert isinstance(fielddescr, Descr)
  388. return llimpl.do_getfield_raw_int(struct, fielddescr.ofs)
  389. def bh_getfield_raw_r(self, struct, fielddescr):
  390. assert isinstance(fielddescr, Descr)
  391. return llimpl.do_getfield_raw_ptr(struct, fielddescr.ofs)
  392. def bh_getfield_raw_f(self, struct, fielddescr):
  393. assert isinstance(fielddescr, Descr)
  394. return llimpl.do_getfield_raw_float(struct, fielddescr.ofs)
  395. def bh_getinteriorfield_gc_i(self, array, index, descr):
  396. assert isinstance(descr, Descr)
  397. return llimpl.do_getinteriorfield_gc_int(array, index, descr.ofs)
  398. def bh_getinteriorfield_gc_r(self, array, index, descr):
  399. assert isinstance(descr, Descr)
  400. return llimpl.do_getinteriorfield_gc_ptr(array, index, descr.ofs)
  401. def bh_getinteriorfield_gc_f(self, array, index, descr):
  402. assert isinstance(descr, Descr)
  403. return llimpl.do_getinteriorfield_gc_float(array, index, descr.ofs)
  404. def bh_setinteriorfield_gc_i(self, array, index, descr, value):
  405. assert isinstance(descr, Descr)
  406. return llimpl.do_setinteriorfield_gc_int(array, index, descr.ofs,
  407. value)
  408. def bh_setinteriorfield_gc_r(self, array, index, descr, value):
  409. assert isinstance(descr, Descr)
  410. return llimpl.do_setinteriorfield_gc_ptr(array, index, descr.ofs,
  411. value)
  412. def bh_setinteriorfield_gc_f(self, array, index, descr, value):
  413. assert isinstance(descr, Descr)
  414. return llimpl.do_setinteriorfield_gc_float(array, index, descr.ofs,
  415. value)
  416. def bh_new(self, sizedescr):
  417. assert isinstance(sizedescr, Descr)
  418. return llimpl.do_new(sizedescr.ofs)
  419. def bh_new_with_vtable(self, sizedescr, vtable):
  420. assert isinstance(sizedescr, Descr)
  421. result = llimpl.do_new(sizedescr.ofs)
  422. llimpl.do_setfield_gc_int(result, self.fielddescrof_vtable.ofs, vtable)
  423. return result
  424. def bh_classof(self, struct):
  425. struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct)
  426. result_adr = llmemory.cast_ptr_to_adr(struct.typeptr)
  427. return heaptracker.adr2int(result_adr)
  428. def bh_new_array(self, arraydescr, length):
  429. assert isinstance(arraydescr, Descr)
  430. return llimpl.do_new_array(arraydescr.ofs, length)
  431. def bh_arraylen_gc(self, arraydescr, array):
  432. assert isinstance(arraydescr, Descr)
  433. return llimpl.do_arraylen_gc(arraydescr, array)
  434. def bh_setarrayitem_gc_i(self, arraydescr, array, index, newvalue):
  435. assert isinstance(arraydescr, Descr)
  436. llimpl.do_setarrayitem_gc_int(array, index, newvalue)
  437. def bh_setarrayitem_raw_i(self, arraydescr, array, index, newvalue):
  438. assert isinstance(arraydescr, Descr)
  439. llimpl.do_setarrayitem_raw_int(array, index, newvalue)
  440. def bh_setarrayitem_gc_r(self, arraydescr, array, index, newvalue):
  441. assert isinstance(arraydescr, Descr)
  442. llimpl.do_setarrayitem_gc_ptr(array, index, newvalue)
  443. def bh_setarrayitem_gc_f(self, arraydescr, array, index, newvalue):
  444. assert isinstance(arraydescr, Descr)
  445. llimpl.do_setarrayitem_gc_float(array, index, newvalue)
  446. def bh_setarrayitem_raw_f(self, arraydescr, array, index, newvalue):
  447. assert isinstance(arraydescr, Descr)
  448. llimpl.do_setarrayitem_raw_float(array, index, newvalue)
  449. def bh_setfield_gc_i(self, struct, fielddescr, newvalue):
  450. assert isinstance(fielddescr, Descr)
  451. llimpl.do_setfield_gc_int(struct, fielddescr.ofs, newvalue)
  452. def bh_setfield_gc_r(self, struct, fielddescr, newvalue):
  453. assert isinstance(fielddescr, Descr)
  454. llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue)
  455. def bh_setfield_gc_f(self, struct, fielddescr, newvalue):
  456. assert isinstance(fielddescr, Descr)
  457. llimpl.do_setfield_gc_float(struct, fielddescr.ofs, newvalue)
  458. def bh_setfield_raw_i(self, struct, fielddescr, newvalue):
  459. assert isinstance(fielddescr, Descr)
  460. llimpl.do_setfield_raw_int(struct, fielddescr.ofs, newvalue)
  461. def bh_setfield_raw_r(self, struct, fielddescr, newvalue):
  462. assert isinstance(fielddescr, Descr)
  463. llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue)
  464. def bh_setfield_raw_f(self, struct, fielddescr, newvalue):
  465. assert isinstance(fielddescr, Descr)
  466. llimpl.do_setfield_raw_float(struct, fielddescr.ofs, newvalue)
  467. def bh_newstr(self, length):
  468. return llimpl.do_newstr(length)
  469. def bh_newunicode(self, length):
  470. return llimpl.do_newunicode(length)
  471. def bh_strsetitem(self, string, index, newvalue):
  472. llimpl.do_strsetitem(string, index, newvalue)
  473. def bh_unicodesetitem(self, string, index, newvalue):
  474. llimpl.do_unicodesetitem(string, index, newvalue)
  475. def bh_call_i(self, func, calldescr, args_i, args_r, args_f):
  476. self._prepare_call(INT, calldescr, args_i, args_r, args_f)
  477. return llimpl.do_call_int(func)
  478. def bh_call_r(self, func, calldescr, args_i, args_r, args_f):
  479. self._prepare_call(REF, calldescr, args_i, args_r, args_f)
  480. return llimpl.do_call_ptr(func)
  481. def bh_call_f(self, func, calldescr, args_i, args_r, args_f):
  482. self._prepare_call(FLOAT + 'L', calldescr, args_i, args_r, args_f)
  483. return llimpl.do_call_float(func)
  484. def bh_call_v(self, func, calldescr, args_i, args_r, args_f):
  485. self._prepare_call('v', calldescr, args_i, args_r, args_f)
  486. llimpl.do_call_void(func)
  487. def _prepare_call(self, resulttypeinfo, calldescr, args_i, args_r, args_f):
  488. assert isinstance(calldescr, Descr)
  489. assert calldescr.typeinfo in resulttypeinfo
  490. if args_i is not None:
  491. for x in args_i:
  492. llimpl.do_call_pushint(x)
  493. if args_r is not None:
  494. for x in args_r:
  495. llimpl.do_call_pushptr(x)
  496. if args_f is not None:
  497. for x in args_f:
  498. llimpl.do_call_pushfloat(x)
  499. def force(self, force_token):
  500. token = llmemory.cast_int_to_adr(force_token)
  501. frame = llimpl.get_forced_token_frame(token)
  502. fail_index = llimpl.force(frame)
  503. self.latest_frame = frame
  504. return self.get_fail_descr_from_number(fail_index)
  505. class OOtypeCPU_xxx_disabled(BaseCPU):
  506. is_oo = True
  507. ts = oohelper
  508. @staticmethod
  509. def fielddescrof(T, fieldname):
  510. # use class where the field is really defined as a key
  511. T1, _ = T._lookup_field(fieldname)
  512. return FieldDescr.new(T1, fieldname)
  513. @staticmethod
  514. def calldescrof(FUNC, ARGS, RESULT, extrainfo):
  515. return StaticMethDescr.new(FUNC, ARGS, RESULT, extrainfo)
  516. @staticmethod
  517. def methdescrof(SELFTYPE, methname):
  518. return MethDescr.new(SELFTYPE, methname)
  519. @staticmethod
  520. def typedescrof(TYPE):
  521. return TypeDescr.new(TYPE)
  522. @staticmethod
  523. def arraydescrof(A):
  524. assert isinstance(A, ootype.Array)
  525. TYPE = A.ITEM
  526. return TypeDescr.new(TYPE)
  527. def typedescr2classbox(self, descr):
  528. assert isinstance(descr, TypeDescr)
  529. return history.ConstObj(ootype.cast_to_object(
  530. ootype.runtimeClass(descr.TYPE)))
  531. def get_exception(self):
  532. if llimpl._last_exception:
  533. e = llimpl._last_exception.args[0]
  534. return ootype.cast_to_object(e)
  535. else:
  536. return ootype.NULL
  537. def get_exc_value(self):
  538. if llimpl._last_exception:
  539. earg = llimpl._last_exception.args[1]
  540. return ootype.cast_to_object(earg)
  541. else:
  542. return ootype.NULL
  543. def get_overflow_error(self):
  544. ll_err = llimpl._get_error(OverflowError)
  545. return (ootype.cast_to_object(ll_err.args[0]),
  546. ootype.cast_to_object(ll_err.args[1]))
  547. def get_zero_division_error(self):
  548. ll_err = llimpl._get_error(ZeroDivisionError)
  549. return (ootype.cast_to_object(ll_err.args[0]),
  550. ootype.cast_to_object(ll_err.args[1]))
  551. def do_new_with_vtable(self, clsbox):
  552. cls = clsbox.getref_base()
  553. typedescr = self.class_sizes[cls]
  554. return typedescr.create()
  555. def do_new_array(self, lengthbox, typedescr):
  556. assert isinstance(typedescr, TypeDescr)
  557. return typedescr.create_array(lengthbox)
  558. def do_new(self, typedescr):
  559. assert isinstance(typedescr, TypeDescr)
  560. return typedescr.create()
  561. def do_runtimenew(self, classbox):
  562. "NOT_RPYTHON"
  563. classobj = classbox.getref(ootype.Class)
  564. res = ootype.runtimenew(classobj)
  565. return history.BoxObj(ootype.cast_to_object(res))
  566. def do_instanceof(self, box1, typedescr):
  567. assert isinstance(typedescr, TypeDescr)
  568. return typedescr.instanceof(box1)
  569. def do_getfield_gc(self, box1, fielddescr):
  570. assert isinstance(fielddescr, FieldDescr)
  571. return fielddescr.getfield(box1)
  572. def do_setfield_gc(self, box1, box2, fielddescr):
  573. assert isinstance(fielddescr, FieldDescr)
  574. return fielddescr.setfield(box1, box2)
  575. def do_getarrayitem_gc(self, box1, box2, typedescr):
  576. assert isinstance(typedescr, TypeDescr)
  577. return typedescr.getarrayitem(box1, box2)
  578. def do_setarrayitem_gc(self, box1, box2, box3, typedescr):
  579. assert isinstance(typedescr, TypeDescr)
  580. return typedescr.setarrayitem(box1, box2, box3)
  581. def do_arraylen_gc(self, box1, typedescr):
  582. assert isinstance(typedescr, TypeDescr)
  583. return typedescr.getarraylength(box1)
  584. def do_call_XXX(self, args, descr):
  585. assert isinstance(descr, StaticMethDescr)
  586. funcbox = args[0]
  587. argboxes = args[1:]
  588. x = descr.callfunc(funcbox, argboxes)
  589. # XXX: return None if RESULT is Void
  590. return x
  591. def do_oosend(self, args, descr):
  592. assert isinstance(descr, MethDescr)
  593. selfbox = args[0]
  594. argboxes = args[1:]
  595. x = descr.callmeth(selfbox, argboxes)
  596. # XXX: return None if METH.RESULT is Void
  597. return x
  598. def make_getargs(ARGS):
  599. argsiter = unrolling_iterable(ARGS)
  600. args_n = len([ARG for ARG in ARGS if ARG is not ootype.Void])
  601. def getargs(argboxes):
  602. funcargs = ()
  603. assert len(argboxes) == args_n
  604. i = 0
  605. for ARG in argsiter:
  606. if ARG is ootype.Void:
  607. funcargs += (None,)
  608. else:
  609. box = argboxes[i]
  610. i+=1
  611. funcargs += (unwrap(ARG, box),)
  612. return funcargs
  613. return getargs
  614. def boxresult(RESULT, result):
  615. if isinstance(RESULT, ootype.OOType):
  616. return history.BoxObj(ootype.cast_to_object(result))
  617. elif RESULT is lltype.Float:
  618. return history.BoxFloat(result)
  619. else:
  620. return history.BoxInt(lltype.cast_primitive(ootype.Signed, result))
  621. boxresult._annspecialcase_ = 'specialize:arg(0)'
  622. class KeyManager(object):
  623. """
  624. Helper class to convert arbitrary dictionary keys to integers.
  625. """
  626. def __init__(self):
  627. self.keys = {}
  628. def getkey(self, key):
  629. try:
  630. return self.keys[key]
  631. except KeyError:
  632. n = len(self.keys)
  633. self.keys[key] = n
  634. return n
  635. def _freeze_(self):
  636. raise Exception("KeyManager is not supposed to be turned into a pbc")
  637. descr_cache = {}
  638. class OODescr(history.AbstractDescr):
  639. @classmethod
  640. def new(cls, *args):
  641. 'NOT_RPYTHON'
  642. key = (cls, args)
  643. try:
  644. return descr_cache[key]
  645. except KeyError:
  646. res = cls(*args)
  647. descr_cache[key] = res
  648. return res
  649. class StaticMethDescr(OODescr):
  650. def __init__(self, FUNC, ARGS, RESULT, extrainfo=None):
  651. self.FUNC = FUNC
  652. getargs = make_getargs(FUNC.ARGS)
  653. def callfunc(funcbox, argboxes):
  654. funcobj = funcbox.getref(FUNC)
  655. funcargs = getargs(argboxes)
  656. res = llimpl.call_maybe_on_top_of_llinterp(funcobj, funcargs)
  657. if RESULT is not ootype.Void:
  658. return boxresult(RESULT, res)
  659. self.callfunc = callfunc
  660. self.extrainfo = extrainfo
  661. def get_extra_info(self):
  662. return self.extrainfo
  663. class MethDescr(history.AbstractMethDescr):
  664. callmeth = None
  665. new = classmethod(OODescr.new.im_func)
  666. def __init__(self, SELFTYPE, methname):
  667. _, meth = SELFTYPE._lookup(methname)
  668. METH = ootype.typeOf(meth)
  669. self.SELFTYPE = SELFTYPE
  670. self.METH = METH
  671. self.methname = methname
  672. RESULT = METH.RESULT
  673. getargs = make_getargs(METH.ARGS)
  674. def callmeth(selfbox, argboxes):
  675. selfobj = selfbox.getref(SELFTYPE)
  676. meth = getattr(selfobj, methname)
  677. methargs = getargs(argboxes)
  678. res = llimpl.call_maybe_on_top_of_llinterp(meth, methargs)
  679. if RESULT is not ootype.Void:
  680. return boxresult(RESULT, res)
  681. self.callmeth = callmeth
  682. def __repr__(self):
  683. return '<MethDescr %r>' % self.methname
  684. class TypeDescr(OODescr):
  685. create = None
  686. def __init__(self, TYPE):
  687. self.TYPE = TYPE
  688. self.ARRAY = ARRAY = ootype.Array(TYPE)
  689. def create():
  690. return boxresult(TYPE, ootype.new(TYPE))
  691. def create_array(lengthbox):
  692. n = lengthbox.getint()
  693. return boxresult(ARRAY, ootype.oonewarray(ARRAY, n))
  694. def getarrayitem(arraybox, ibox):
  695. array = arraybox.getref(ARRAY)
  696. i = ibox.getint()
  697. return boxresult(TYPE, array.ll_getitem_fast(i))
  698. def setarrayitem(arraybox, ibox, valuebox):
  699. array = arraybox.getref(ARRAY)
  700. i = ibox.getint()
  701. value = unwrap(TYPE, valuebox)
  702. array.ll_setitem_fast(i, value)
  703. def getarraylength(arraybox):
  704. array = arraybox.getref(ARRAY)
  705. return boxresult(ootype.Signed, array.ll_length())
  706. def instanceof(box):
  707. obj = box.getref(ootype.ROOT)
  708. return history.BoxInt(ootype.instanceof(obj, TYPE))
  709. self.create = create
  710. self.create_array = create_array
  711. self.getarrayitem = getarrayitem
  712. self.setarrayitem = setarrayitem
  713. self.getarraylength = getarraylength
  714. self.instanceof = instanceof
  715. self._is_array_of_pointers = (history.getkind(TYPE) == 'ref')
  716. self._is_array_of_floats = (history.getkind(TYPE) == 'float')
  717. def is_array_of_pointers(self):
  718. # for arrays, TYPE is the type of the array item.
  719. return self._is_array_of_pointers
  720. def is_array_of_floats(self):
  721. # for arrays, TYPE is the type of the array item.
  722. return self._is_array_of_floats
  723. def __repr__(self):
  724. return '<TypeDescr %s>' % self.TYPE._short_name()
  725. class FieldDescr(OODescr):
  726. getfield = None
  727. _keys = KeyManager()
  728. def __init__(self, TYPE, fieldname):
  729. self.TYPE = TYPE
  730. self.fieldname = fieldname
  731. _, T = TYPE._lookup_field(fieldname)
  732. def getfield(objbox):
  733. obj = objbox.getref(TYPE)
  734. value = getattr(obj, fieldname)
  735. return boxresult(T, value)
  736. def setfield(objbox, valuebox):
  737. obj = objbox.getref(TYPE)
  738. value = unwrap(T, valuebox)
  739. setattr(obj, fieldname, value)
  740. self.getfield = getfield
  741. self.setfield = setfield
  742. self._is_pointer_field = (history.getkind(T) == 'ref')
  743. self._is_float_field = (history.getkind(T) == 'float')
  744. def sort_key(self):
  745. return self._keys.getkey((self.TYPE, self.fieldname))
  746. def is_pointer_field(self):
  747. return self._is_pointer_field
  748. def is_float_field(self):
  749. return self._is_float_field
  750. def equals(self, other):
  751. return self.TYPE == other.TYPE and \
  752. self.fieldname == other.fieldname
  753. def __repr__(self):
  754. return '<FieldDescr %r>' % self.fieldname