PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/rpython/rtyper/rbuiltin.py

https://bitbucket.org/pypy/pypy/
Python | 777 lines | 621 code | 116 blank | 40 comment | 80 complexity | db1328bd02d895c76bb73bc438a97a64 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from collections import OrderedDict
  2. from rpython.annotator import model as annmodel
  3. from rpython.flowspace.model import Constant
  4. from rpython.rlib import rarithmetic, objectmodel
  5. from rpython.rtyper import raddress, rptr, extregistry, rrange
  6. from rpython.rtyper.error import TyperError
  7. from rpython.rtyper.lltypesystem import lltype, llmemory, rstr
  8. from rpython.rtyper import rclass
  9. from rpython.rtyper.rmodel import Repr
  10. from rpython.tool.pairtype import pairtype
  11. BUILTIN_TYPER = {}
  12. def typer_for(func):
  13. def wrapped(rtyper_func):
  14. BUILTIN_TYPER[func] = rtyper_func
  15. return rtyper_func
  16. return wrapped
  17. class __extend__(annmodel.SomeBuiltin):
  18. def rtyper_makerepr(self, rtyper):
  19. if not self.is_constant():
  20. raise TyperError("non-constant built-in function!")
  21. return BuiltinFunctionRepr(self.const)
  22. def rtyper_makekey(self):
  23. const = getattr(self, 'const', None)
  24. if extregistry.is_registered(const):
  25. const = extregistry.lookup(const)
  26. return self.__class__, const
  27. class __extend__(annmodel.SomeBuiltinMethod):
  28. def rtyper_makerepr(self, rtyper):
  29. assert self.methodname is not None
  30. result = BuiltinMethodRepr(rtyper, self.s_self, self.methodname)
  31. return result
  32. def rtyper_makekey(self):
  33. # NOTE: we hash by id of self.s_self here. This appears to be
  34. # necessary because it ends up in hop.args_s[0] in the method call,
  35. # and there is no telling what information the called
  36. # rtype_method_xxx() will read from that hop.args_s[0].
  37. # See test_method_join in test_rbuiltin.
  38. # There is no problem with self.s_self being garbage-collected and
  39. # its id reused, because the BuiltinMethodRepr keeps a reference
  40. # to it.
  41. return (self.__class__, self.methodname, id(self.s_self))
  42. def call_args_expand(hop):
  43. hop = hop.copy()
  44. from rpython.annotator.argument import ArgumentsForTranslation
  45. arguments = ArgumentsForTranslation.fromshape(
  46. hop.args_s[1].const, # shape
  47. range(hop.nb_args-2))
  48. assert arguments.w_stararg is None
  49. keywords = arguments.keywords
  50. # prefix keyword arguments with 'i_'
  51. kwds_i = {}
  52. for key in keywords:
  53. kwds_i['i_' + key] = keywords[key]
  54. return hop, kwds_i
  55. class BuiltinFunctionRepr(Repr):
  56. lowleveltype = lltype.Void
  57. def __init__(self, builtinfunc):
  58. self.builtinfunc = builtinfunc
  59. def findbltintyper(self, rtyper):
  60. "Find the function to use to specialize calls to this built-in func."
  61. try:
  62. return BUILTIN_TYPER[self.builtinfunc]
  63. except (KeyError, TypeError):
  64. pass
  65. if extregistry.is_registered(self.builtinfunc):
  66. entry = extregistry.lookup(self.builtinfunc)
  67. return entry.specialize_call
  68. raise TyperError("don't know about built-in function %r" % (
  69. self.builtinfunc,))
  70. def _call(self, hop2, **kwds_i):
  71. bltintyper = self.findbltintyper(hop2.rtyper)
  72. hop2.llops._called_exception_is_here_or_cannot_occur = False
  73. v_result = bltintyper(hop2, **kwds_i)
  74. if not hop2.llops._called_exception_is_here_or_cannot_occur:
  75. raise TyperError("missing hop.exception_cannot_occur() or "
  76. "hop.exception_is_here() in %s" % bltintyper)
  77. return v_result
  78. def rtype_simple_call(self, hop):
  79. hop2 = hop.copy()
  80. hop2.r_s_popfirstarg()
  81. return self._call(hop2)
  82. def rtype_call_args(self, hop):
  83. # calling a built-in function with keyword arguments:
  84. # mostly for rpython.objectmodel.hint()
  85. hop, kwds_i = call_args_expand(hop)
  86. hop2 = hop.copy()
  87. hop2.r_s_popfirstarg()
  88. hop2.r_s_popfirstarg()
  89. # the RPython-level keyword args are passed with an 'i_' prefix and
  90. # the corresponding value is an *index* in the hop2 arguments,
  91. # to be used with hop.inputarg(arg=..)
  92. return self._call(hop2, **kwds_i)
  93. class BuiltinMethodRepr(Repr):
  94. def __init__(self, rtyper, s_self, methodname):
  95. self.s_self = s_self
  96. self.self_repr = rtyper.getrepr(s_self)
  97. self.methodname = methodname
  98. # methods of a known name are implemented as just their 'self'
  99. self.lowleveltype = self.self_repr.lowleveltype
  100. def convert_const(self, obj):
  101. return self.self_repr.convert_const(obj.__self__)
  102. def rtype_simple_call(self, hop):
  103. # methods: look up the rtype_method_xxx()
  104. name = 'rtype_method_' + self.methodname
  105. try:
  106. bltintyper = getattr(self.self_repr, name)
  107. except AttributeError:
  108. raise TyperError("missing %s.%s" % (
  109. self.self_repr.__class__.__name__, name))
  110. # hack based on the fact that 'lowleveltype == self_repr.lowleveltype'
  111. hop2 = hop.copy()
  112. assert hop2.args_r[0] is self
  113. if isinstance(hop2.args_v[0], Constant):
  114. c = hop2.args_v[0].value # get object from bound method
  115. c = c.__self__
  116. hop2.args_v[0] = Constant(c)
  117. hop2.args_s[0] = self.s_self
  118. hop2.args_r[0] = self.self_repr
  119. return bltintyper(hop2)
  120. class __extend__(pairtype(BuiltinMethodRepr, BuiltinMethodRepr)):
  121. def convert_from_to((r_from, r_to), v, llops):
  122. # convert between two MethodReprs only if they are about the same
  123. # methodname. (Useful for the case r_from.s_self == r_to.s_self but
  124. # r_from is not r_to.) See test_rbuiltin.test_method_repr.
  125. if r_from.methodname != r_to.methodname:
  126. return NotImplemented
  127. return llops.convertvar(v, r_from.self_repr, r_to.self_repr)
  128. def parse_kwds(hop, *argspec_i_r):
  129. lst = [i for (i, r) in argspec_i_r if i is not None]
  130. lst.sort()
  131. if lst != range(hop.nb_args - len(lst), hop.nb_args):
  132. raise TyperError("keyword args are expected to be at the end of "
  133. "the 'hop' arg list")
  134. result = []
  135. for i, r in argspec_i_r:
  136. if i is not None:
  137. if r is None:
  138. r = hop.args_r[i]
  139. result.append(hop.inputarg(r, arg=i))
  140. else:
  141. result.append(None)
  142. del hop.args_v[hop.nb_args - len(lst):]
  143. return result
  144. # ____________________________________________________________
  145. @typer_for(bool)
  146. def rtype_builtin_bool(hop):
  147. # not called any more?
  148. assert hop.nb_args == 1
  149. return hop.args_r[0].rtype_bool(hop)
  150. @typer_for(int)
  151. def rtype_builtin_int(hop):
  152. if isinstance(hop.args_s[0], annmodel.SomeString):
  153. assert 1 <= hop.nb_args <= 2
  154. return hop.args_r[0].rtype_int(hop)
  155. assert hop.nb_args == 1
  156. return hop.args_r[0].rtype_int(hop)
  157. @typer_for(float)
  158. def rtype_builtin_float(hop):
  159. assert hop.nb_args == 1
  160. return hop.args_r[0].rtype_float(hop)
  161. @typer_for(chr)
  162. def rtype_builtin_chr(hop):
  163. assert hop.nb_args == 1
  164. return hop.args_r[0].rtype_chr(hop)
  165. @typer_for(unichr)
  166. def rtype_builtin_unichr(hop):
  167. assert hop.nb_args == 1
  168. return hop.args_r[0].rtype_unichr(hop)
  169. @typer_for(unicode)
  170. def rtype_builtin_unicode(hop):
  171. return hop.args_r[0].rtype_unicode(hop)
  172. @typer_for(bytearray)
  173. def rtype_builtin_bytearray(hop):
  174. return hop.args_r[0].rtype_bytearray(hop)
  175. @typer_for(list)
  176. def rtype_builtin_list(hop):
  177. return hop.args_r[0].rtype_bltn_list(hop)
  178. #def rtype_builtin_range(hop): see rrange.py
  179. #def rtype_builtin_xrange(hop): see rrange.py
  180. #def rtype_builtin_enumerate(hop): see rrange.py
  181. #def rtype_r_dict(hop): see rdict.py
  182. @typer_for(rarithmetic.intmask)
  183. def rtype_intmask(hop):
  184. hop.exception_cannot_occur()
  185. vlist = hop.inputargs(lltype.Signed)
  186. return vlist[0]
  187. @typer_for(rarithmetic.longlongmask)
  188. def rtype_longlongmask(hop):
  189. hop.exception_cannot_occur()
  190. vlist = hop.inputargs(lltype.SignedLongLong)
  191. return vlist[0]
  192. @typer_for(min)
  193. def rtype_builtin_min(hop):
  194. v1, v2 = hop.inputargs(hop.r_result, hop.r_result)
  195. hop.exception_cannot_occur()
  196. return hop.gendirectcall(ll_min, v1, v2)
  197. def ll_min(i1, i2):
  198. if i1 < i2:
  199. return i1
  200. return i2
  201. @typer_for(max)
  202. def rtype_builtin_max(hop):
  203. v1, v2 = hop.inputargs(hop.r_result, hop.r_result)
  204. hop.exception_cannot_occur()
  205. return hop.gendirectcall(ll_max, v1, v2)
  206. def ll_max(i1, i2):
  207. if i1 > i2:
  208. return i1
  209. return i2
  210. @typer_for(reversed)
  211. def rtype_builtin_reversed(hop):
  212. hop.exception_cannot_occur()
  213. return hop.r_result.newiter(hop)
  214. @typer_for(getattr(object.__init__, 'im_func', object.__init__))
  215. def rtype_object__init__(hop):
  216. hop.exception_cannot_occur()
  217. @typer_for(getattr(EnvironmentError.__init__, 'im_func',
  218. EnvironmentError.__init__))
  219. def rtype_EnvironmentError__init__(hop):
  220. hop.exception_cannot_occur()
  221. v_self = hop.args_v[0]
  222. r_self = hop.args_r[0]
  223. if hop.nb_args <= 2:
  224. v_errno = hop.inputconst(lltype.Signed, 0)
  225. if hop.nb_args == 2:
  226. v_strerror = hop.inputarg(rstr.string_repr, arg=1)
  227. r_self.setfield(v_self, 'strerror', v_strerror, hop.llops)
  228. else:
  229. v_errno = hop.inputarg(lltype.Signed, arg=1)
  230. v_strerror = hop.inputarg(rstr.string_repr, arg=2)
  231. r_self.setfield(v_self, 'strerror', v_strerror, hop.llops)
  232. if hop.nb_args >= 4:
  233. v_filename = hop.inputarg(rstr.string_repr, arg=3)
  234. r_self.setfield(v_self, 'filename', v_filename, hop.llops)
  235. r_self.setfield(v_self, 'errno', v_errno, hop.llops)
  236. try:
  237. WindowsError
  238. except NameError:
  239. pass
  240. else:
  241. @typer_for(
  242. getattr(WindowsError.__init__, 'im_func', WindowsError.__init__))
  243. def rtype_WindowsError__init__(hop):
  244. hop.exception_cannot_occur()
  245. if hop.nb_args == 2:
  246. raise TyperError("WindowsError() should not be called with "
  247. "a single argument")
  248. if hop.nb_args >= 3:
  249. v_self = hop.args_v[0]
  250. r_self = hop.args_r[0]
  251. v_error = hop.inputarg(lltype.Signed, arg=1)
  252. r_self.setfield(v_self, 'winerror', v_error, hop.llops)
  253. @typer_for(objectmodel.hlinvoke)
  254. def rtype_hlinvoke(hop):
  255. _, s_repr = hop.r_s_popfirstarg()
  256. r_callable = s_repr.const
  257. r_func, nimplicitarg = r_callable.get_r_implfunc()
  258. s_callable = r_callable.get_s_callable()
  259. nbargs = len(hop.args_s) - 1 + nimplicitarg
  260. s_sigs = r_func.get_s_signatures((nbargs, (), False))
  261. if len(s_sigs) != 1:
  262. raise TyperError("cannot hlinvoke callable %r with not uniform"
  263. "annotations: %r" % (r_callable,
  264. s_sigs))
  265. args_s, s_ret = s_sigs[0]
  266. rinputs = [hop.rtyper.getrepr(s_obj) for s_obj in args_s]
  267. rresult = hop.rtyper.getrepr(s_ret)
  268. args_s = args_s[nimplicitarg:]
  269. rinputs = rinputs[nimplicitarg:]
  270. new_args_r = [r_callable] + rinputs
  271. for i in range(len(new_args_r)):
  272. assert hop.args_r[i].lowleveltype == new_args_r[i].lowleveltype
  273. hop.args_r = new_args_r
  274. hop.args_s = [s_callable] + args_s
  275. hop.s_result = s_ret
  276. assert hop.r_result.lowleveltype == rresult.lowleveltype
  277. hop.r_result = rresult
  278. return hop.dispatch()
  279. typer_for(range)(rrange.rtype_builtin_range)
  280. typer_for(xrange)(rrange.rtype_builtin_xrange)
  281. typer_for(enumerate)(rrange.rtype_builtin_enumerate)
  282. # annotation of low-level types
  283. @typer_for(lltype.malloc)
  284. def rtype_malloc(hop, i_flavor=None, i_zero=None, i_track_allocation=None,
  285. i_add_memory_pressure=None, i_nonmovable=None):
  286. assert hop.args_s[0].is_constant()
  287. vlist = [hop.inputarg(lltype.Void, arg=0)]
  288. opname = 'malloc'
  289. kwds_v = parse_kwds(
  290. hop,
  291. (i_flavor, lltype.Void),
  292. (i_zero, None),
  293. (i_track_allocation, None),
  294. (i_add_memory_pressure, None),
  295. (i_nonmovable, None))
  296. (v_flavor, v_zero, v_track_allocation,
  297. v_add_memory_pressure, v_nonmovable) = kwds_v
  298. flags = {'flavor': 'gc'}
  299. if v_flavor is not None:
  300. flags['flavor'] = v_flavor.value
  301. if i_zero is not None:
  302. flags['zero'] = v_zero.value
  303. if i_track_allocation is not None:
  304. flags['track_allocation'] = v_track_allocation.value
  305. if i_add_memory_pressure is not None:
  306. flags['add_memory_pressure'] = v_add_memory_pressure.value
  307. if i_nonmovable is not None:
  308. flags['nonmovable'] = v_nonmovable
  309. vlist.append(hop.inputconst(lltype.Void, flags))
  310. assert 1 <= hop.nb_args <= 2
  311. if hop.nb_args == 2:
  312. vlist.append(hop.inputarg(lltype.Signed, arg=1))
  313. opname += '_varsize'
  314. hop.has_implicit_exception(MemoryError) # record that we know about it
  315. hop.exception_is_here()
  316. return hop.genop(opname, vlist, resulttype=hop.r_result.lowleveltype)
  317. @typer_for(lltype.free)
  318. def rtype_free(hop, i_flavor, i_track_allocation=None):
  319. vlist = [hop.inputarg(hop.args_r[0], arg=0)]
  320. v_flavor, v_track_allocation = parse_kwds(hop,
  321. (i_flavor, lltype.Void),
  322. (i_track_allocation, None))
  323. #
  324. assert v_flavor is not None and v_flavor.value == 'raw'
  325. flags = {'flavor': 'raw'}
  326. if i_track_allocation is not None:
  327. flags['track_allocation'] = v_track_allocation.value
  328. vlist.append(hop.inputconst(lltype.Void, flags))
  329. #
  330. hop.exception_cannot_occur()
  331. hop.genop('free', vlist)
  332. @typer_for(lltype.render_immortal)
  333. def rtype_render_immortal(hop, i_track_allocation=None):
  334. vlist = [hop.inputarg(hop.args_r[0], arg=0)]
  335. v_track_allocation = parse_kwds(hop,
  336. (i_track_allocation, None))
  337. hop.exception_cannot_occur()
  338. if i_track_allocation is None or v_track_allocation.value:
  339. hop.genop('track_alloc_stop', vlist)
  340. @typer_for(lltype.typeOf)
  341. @typer_for(lltype.nullptr)
  342. @typer_for(lltype.getRuntimeTypeInfo)
  343. @typer_for(lltype.Ptr)
  344. def rtype_const_result(hop):
  345. hop.exception_cannot_occur()
  346. return hop.inputconst(hop.r_result.lowleveltype, hop.s_result.const)
  347. @typer_for(lltype.cast_pointer)
  348. def rtype_cast_pointer(hop):
  349. assert hop.args_s[0].is_constant()
  350. assert isinstance(hop.args_r[1], rptr.PtrRepr)
  351. v_type, v_input = hop.inputargs(lltype.Void, hop.args_r[1])
  352. hop.exception_cannot_occur()
  353. return hop.genop('cast_pointer', [v_input], # v_type implicit in r_result
  354. resulttype = hop.r_result.lowleveltype)
  355. @typer_for(lltype.cast_opaque_ptr)
  356. def rtype_cast_opaque_ptr(hop):
  357. assert hop.args_s[0].is_constant()
  358. assert isinstance(hop.args_r[1], rptr.PtrRepr)
  359. v_type, v_input = hop.inputargs(lltype.Void, hop.args_r[1])
  360. hop.exception_cannot_occur()
  361. return hop.genop('cast_opaque_ptr', [v_input], # v_type implicit in r_result
  362. resulttype = hop.r_result.lowleveltype)
  363. @typer_for(lltype.length_of_simple_gcarray_from_opaque)
  364. def rtype_length_of_simple_gcarray_from_opaque(hop):
  365. assert isinstance(hop.args_r[0], rptr.PtrRepr)
  366. v_opaque_ptr, = hop.inputargs(hop.args_r[0])
  367. hop.exception_cannot_occur()
  368. return hop.genop('length_of_simple_gcarray_from_opaque', [v_opaque_ptr],
  369. resulttype = hop.r_result.lowleveltype)
  370. @typer_for(lltype.direct_fieldptr)
  371. def rtype_direct_fieldptr(hop):
  372. assert isinstance(hop.args_r[0], rptr.PtrRepr)
  373. assert hop.args_s[1].is_constant()
  374. vlist = hop.inputargs(hop.args_r[0], lltype.Void)
  375. hop.exception_cannot_occur()
  376. return hop.genop('direct_fieldptr', vlist,
  377. resulttype=hop.r_result.lowleveltype)
  378. @typer_for(lltype.direct_arrayitems)
  379. def rtype_direct_arrayitems(hop):
  380. assert isinstance(hop.args_r[0], rptr.PtrRepr)
  381. vlist = hop.inputargs(hop.args_r[0])
  382. hop.exception_cannot_occur()
  383. return hop.genop('direct_arrayitems', vlist,
  384. resulttype=hop.r_result.lowleveltype)
  385. @typer_for(lltype.direct_ptradd)
  386. def rtype_direct_ptradd(hop):
  387. assert isinstance(hop.args_r[0], rptr.PtrRepr)
  388. vlist = hop.inputargs(hop.args_r[0], lltype.Signed)
  389. hop.exception_cannot_occur()
  390. return hop.genop('direct_ptradd', vlist,
  391. resulttype=hop.r_result.lowleveltype)
  392. @typer_for(lltype.cast_primitive)
  393. def rtype_cast_primitive(hop):
  394. assert hop.args_s[0].is_constant()
  395. TGT = hop.args_s[0].const
  396. v_type, v_value = hop.inputargs(lltype.Void, hop.args_r[1])
  397. hop.exception_cannot_occur()
  398. return gen_cast(hop.llops, TGT, v_value)
  399. _cast_to_Signed = {
  400. lltype.Signed: None,
  401. lltype.Bool: 'cast_bool_to_int',
  402. lltype.Char: 'cast_char_to_int',
  403. lltype.UniChar: 'cast_unichar_to_int',
  404. lltype.Float: 'cast_float_to_int',
  405. lltype.Unsigned: 'cast_uint_to_int',
  406. lltype.SignedLongLong: 'truncate_longlong_to_int',
  407. }
  408. _cast_from_Signed = {
  409. lltype.Signed: None,
  410. lltype.Char: 'cast_int_to_char',
  411. lltype.UniChar: 'cast_int_to_unichar',
  412. lltype.Float: 'cast_int_to_float',
  413. lltype.Unsigned: 'cast_int_to_uint',
  414. lltype.SignedLongLong: 'cast_int_to_longlong',
  415. }
  416. def gen_cast(llops, TGT, v_value):
  417. ORIG = v_value.concretetype
  418. if ORIG == TGT:
  419. return v_value
  420. if (isinstance(TGT, lltype.Primitive) and
  421. isinstance(ORIG, lltype.Primitive)):
  422. if ORIG in _cast_to_Signed and TGT in _cast_from_Signed:
  423. op = _cast_to_Signed[ORIG]
  424. if op:
  425. v_value = llops.genop(op, [v_value], resulttype=lltype.Signed)
  426. op = _cast_from_Signed[TGT]
  427. if op:
  428. v_value = llops.genop(op, [v_value], resulttype=TGT)
  429. return v_value
  430. elif ORIG is lltype.Signed and TGT is lltype.Bool:
  431. return llops.genop('int_is_true', [v_value], resulttype=lltype.Bool)
  432. else:
  433. # use the generic operation if there is no alternative
  434. return llops.genop('cast_primitive', [v_value], resulttype=TGT)
  435. elif isinstance(TGT, lltype.Ptr):
  436. if isinstance(ORIG, lltype.Ptr):
  437. if (isinstance(TGT.TO, lltype.OpaqueType) or
  438. isinstance(ORIG.TO, lltype.OpaqueType)):
  439. return llops.genop('cast_opaque_ptr', [v_value], resulttype=TGT)
  440. else:
  441. return llops.genop('cast_pointer', [v_value], resulttype=TGT)
  442. elif ORIG == llmemory.Address:
  443. return llops.genop('cast_adr_to_ptr', [v_value], resulttype=TGT)
  444. elif isinstance(ORIG, lltype.Primitive):
  445. v_value = gen_cast(llops, lltype.Signed, v_value)
  446. return llops.genop('cast_int_to_ptr', [v_value], resulttype=TGT)
  447. elif TGT == llmemory.Address and isinstance(ORIG, lltype.Ptr):
  448. return llops.genop('cast_ptr_to_adr', [v_value], resulttype=TGT)
  449. elif isinstance(TGT, lltype.Primitive):
  450. if isinstance(ORIG, lltype.Ptr):
  451. v_value = llops.genop('cast_ptr_to_int', [v_value],
  452. resulttype=lltype.Signed)
  453. elif ORIG == llmemory.Address:
  454. v_value = llops.genop('cast_adr_to_int', [v_value],
  455. resulttype=lltype.Signed)
  456. else:
  457. raise TypeError("don't know how to cast from %r to %r" % (ORIG,
  458. TGT))
  459. return gen_cast(llops, TGT, v_value)
  460. raise TypeError("don't know how to cast from %r to %r" % (ORIG, TGT))
  461. @typer_for(lltype.cast_ptr_to_int)
  462. def rtype_cast_ptr_to_int(hop):
  463. assert isinstance(hop.args_r[0], rptr.PtrRepr)
  464. vlist = hop.inputargs(hop.args_r[0])
  465. hop.exception_cannot_occur()
  466. return hop.genop('cast_ptr_to_int', vlist,
  467. resulttype=lltype.Signed)
  468. @typer_for(lltype.cast_int_to_ptr)
  469. def rtype_cast_int_to_ptr(hop):
  470. assert hop.args_s[0].is_constant()
  471. v_type, v_input = hop.inputargs(lltype.Void, lltype.Signed)
  472. hop.exception_cannot_occur()
  473. return hop.genop('cast_int_to_ptr', [v_input],
  474. resulttype=hop.r_result.lowleveltype)
  475. @typer_for(lltype.identityhash)
  476. def rtype_identity_hash(hop):
  477. vlist = hop.inputargs(hop.args_r[0])
  478. hop.exception_cannot_occur()
  479. return hop.genop('gc_identityhash', vlist, resulttype=lltype.Signed)
  480. @typer_for(lltype.runtime_type_info)
  481. def rtype_runtime_type_info(hop):
  482. assert isinstance(hop.args_r[0], rptr.PtrRepr)
  483. vlist = hop.inputargs(hop.args_r[0])
  484. hop.exception_cannot_occur()
  485. return hop.genop('runtime_type_info', vlist,
  486. resulttype=hop.r_result.lowleveltype)
  487. # _________________________________________________________________
  488. # memory addresses
  489. @typer_for(llmemory.raw_malloc)
  490. def rtype_raw_malloc(hop):
  491. v_size, = hop.inputargs(lltype.Signed)
  492. hop.exception_cannot_occur()
  493. return hop.genop('raw_malloc', [v_size], resulttype=llmemory.Address)
  494. @typer_for(llmemory.raw_malloc_usage)
  495. def rtype_raw_malloc_usage(hop):
  496. v_size, = hop.inputargs(lltype.Signed)
  497. hop.exception_cannot_occur()
  498. return hop.genop('raw_malloc_usage', [v_size], resulttype=lltype.Signed)
  499. @typer_for(llmemory.raw_free)
  500. def rtype_raw_free(hop):
  501. s_addr = hop.args_s[0]
  502. if s_addr.is_null_address():
  503. raise TyperError("raw_free(x) where x is the constant NULL")
  504. v_addr, = hop.inputargs(llmemory.Address)
  505. hop.exception_cannot_occur()
  506. return hop.genop('raw_free', [v_addr])
  507. @typer_for(llmemory.raw_memcopy)
  508. def rtype_raw_memcopy(hop):
  509. for s_addr in hop.args_s[:2]:
  510. if s_addr.is_null_address():
  511. raise TyperError("raw_memcopy() with a constant NULL")
  512. v_list = hop.inputargs(llmemory.Address, llmemory.Address, lltype.Signed)
  513. hop.exception_cannot_occur()
  514. return hop.genop('raw_memcopy', v_list)
  515. @typer_for(llmemory.raw_memclear)
  516. def rtype_raw_memclear(hop):
  517. s_addr = hop.args_s[0]
  518. if s_addr.is_null_address():
  519. raise TyperError("raw_memclear(x, n) where x is the constant NULL")
  520. v_list = hop.inputargs(llmemory.Address, lltype.Signed)
  521. hop.exception_cannot_occur()
  522. return hop.genop('raw_memclear', v_list)
  523. @typer_for(llmemory.offsetof)
  524. def rtype_offsetof(hop):
  525. TYPE, field = hop.inputargs(lltype.Void, lltype.Void)
  526. hop.exception_cannot_occur()
  527. return hop.inputconst(lltype.Signed,
  528. llmemory.offsetof(TYPE.value, field.value))
  529. # _________________________________________________________________
  530. # non-gc objects
  531. @typer_for(objectmodel.free_non_gc_object)
  532. def rtype_free_non_gc_object(hop):
  533. hop.exception_cannot_occur()
  534. vinst, = hop.inputargs(hop.args_r[0])
  535. flavor = hop.args_r[0].gcflavor
  536. assert flavor != 'gc'
  537. flags = {'flavor': flavor}
  538. cflags = hop.inputconst(lltype.Void, flags)
  539. return hop.genop('free', [vinst, cflags])
  540. @typer_for(objectmodel.keepalive_until_here)
  541. def rtype_keepalive_until_here(hop):
  542. hop.exception_cannot_occur()
  543. for v in hop.args_v:
  544. hop.genop('keepalive', [v], resulttype=lltype.Void)
  545. return hop.inputconst(lltype.Void, None)
  546. @typer_for(llmemory.cast_ptr_to_adr)
  547. def rtype_cast_ptr_to_adr(hop):
  548. vlist = hop.inputargs(hop.args_r[0])
  549. assert isinstance(vlist[0].concretetype, lltype.Ptr)
  550. hop.exception_cannot_occur()
  551. return hop.genop('cast_ptr_to_adr', vlist,
  552. resulttype=llmemory.Address)
  553. @typer_for(llmemory.cast_adr_to_ptr)
  554. def rtype_cast_adr_to_ptr(hop):
  555. assert isinstance(hop.args_r[0], raddress.AddressRepr)
  556. adr, TYPE = hop.inputargs(hop.args_r[0], lltype.Void)
  557. hop.exception_cannot_occur()
  558. return hop.genop('cast_adr_to_ptr', [adr],
  559. resulttype=TYPE.value)
  560. @typer_for(llmemory.cast_adr_to_int)
  561. def rtype_cast_adr_to_int(hop):
  562. assert isinstance(hop.args_r[0], raddress.AddressRepr)
  563. adr = hop.inputarg(hop.args_r[0], arg=0)
  564. if len(hop.args_s) == 1:
  565. mode = "emulated"
  566. else:
  567. mode = hop.args_s[1].const
  568. hop.exception_cannot_occur()
  569. return hop.genop('cast_adr_to_int',
  570. [adr, hop.inputconst(lltype.Void, mode)],
  571. resulttype=lltype.Signed)
  572. @typer_for(llmemory.cast_int_to_adr)
  573. def rtype_cast_int_to_adr(hop):
  574. v_input, = hop.inputargs(lltype.Signed)
  575. hop.exception_cannot_occur()
  576. return hop.genop('cast_int_to_adr', [v_input],
  577. resulttype=llmemory.Address)
  578. @typer_for(objectmodel.instantiate)
  579. def rtype_instantiate(hop, i_nonmovable=None):
  580. hop.exception_cannot_occur()
  581. s_class = hop.args_s[0]
  582. assert isinstance(s_class, annmodel.SomePBC)
  583. v_nonmovable, = parse_kwds(hop, (i_nonmovable, None))
  584. nonmovable = (i_nonmovable is not None and v_nonmovable.value)
  585. if len(s_class.descriptions) != 1:
  586. # instantiate() on a variable class
  587. if nonmovable:
  588. raise TyperError("instantiate(x, nonmovable=True) cannot be used "
  589. "if x is not a constant class")
  590. vtypeptr, = hop.inputargs(rclass.get_type_repr(hop.rtyper))
  591. r_class = hop.args_r[0]
  592. return r_class._instantiate_runtime_class(hop, vtypeptr,
  593. hop.r_result.lowleveltype)
  594. classdef = s_class.any_description().getuniqueclassdef()
  595. return rclass.rtype_new_instance(hop.rtyper, classdef, hop.llops,
  596. nonmovable=nonmovable)
  597. @typer_for(hasattr)
  598. def rtype_builtin_hasattr(hop):
  599. hop.exception_cannot_occur()
  600. if hop.s_result.is_constant():
  601. return hop.inputconst(lltype.Bool, hop.s_result.const)
  602. raise TyperError("hasattr is only suported on a constant")
  603. @typer_for(OrderedDict)
  604. @typer_for(objectmodel.r_dict)
  605. @typer_for(objectmodel.r_ordereddict)
  606. def rtype_dict_constructor(hop, i_force_non_null=None):
  607. # 'i_force_non_null' is ignored here; if it has any effect, it
  608. # has already been applied to 'hop.r_result'
  609. hop.exception_cannot_occur()
  610. r_dict = hop.r_result
  611. cDICT = hop.inputconst(lltype.Void, r_dict.DICT)
  612. v_result = hop.gendirectcall(r_dict.ll_newdict, cDICT)
  613. if r_dict.custom_eq_hash:
  614. v_eqfn = hop.inputarg(r_dict.r_rdict_eqfn, arg=0)
  615. v_hashfn = hop.inputarg(r_dict.r_rdict_hashfn, arg=1)
  616. if r_dict.r_rdict_eqfn.lowleveltype != lltype.Void:
  617. cname = hop.inputconst(lltype.Void, 'fnkeyeq')
  618. hop.genop('setfield', [v_result, cname, v_eqfn])
  619. if r_dict.r_rdict_hashfn.lowleveltype != lltype.Void:
  620. cname = hop.inputconst(lltype.Void, 'fnkeyhash')
  621. hop.genop('setfield', [v_result, cname, v_hashfn])
  622. return v_result
  623. # _________________________________________________________________
  624. # weakrefs
  625. import weakref
  626. from rpython.rtyper.lltypesystem import llmemory
  627. @typer_for(llmemory.weakref_create)
  628. @typer_for(weakref.ref)
  629. def rtype_weakref_create(hop):
  630. from rpython.rtyper.rweakref import BaseWeakRefRepr
  631. v_inst, = hop.inputargs(hop.args_r[0])
  632. hop.exception_cannot_occur()
  633. if isinstance(hop.r_result, BaseWeakRefRepr):
  634. return hop.r_result._weakref_create(hop, v_inst)
  635. else:
  636. # low-level <PtrRepr * WeakRef>
  637. assert hop.rtyper.getconfig().translation.rweakref
  638. return hop.genop('weakref_create', [v_inst],
  639. resulttype=llmemory.WeakRefPtr)
  640. @typer_for(llmemory.weakref_deref)
  641. def rtype_weakref_deref(hop):
  642. assert hop.rtyper.getconfig().translation.rweakref
  643. c_ptrtype, v_wref = hop.inputargs(lltype.Void, hop.args_r[1])
  644. assert v_wref.concretetype == llmemory.WeakRefPtr
  645. hop.exception_cannot_occur()
  646. return hop.genop('weakref_deref', [v_wref], resulttype=c_ptrtype.value)
  647. @typer_for(llmemory.cast_ptr_to_weakrefptr)
  648. def rtype_cast_ptr_to_weakrefptr(hop):
  649. assert hop.rtyper.getconfig().translation.rweakref
  650. vlist = hop.inputargs(hop.args_r[0])
  651. hop.exception_cannot_occur()
  652. return hop.genop('cast_ptr_to_weakrefptr', vlist,
  653. resulttype=llmemory.WeakRefPtr)
  654. @typer_for(llmemory.cast_weakrefptr_to_ptr)
  655. def rtype_cast_weakrefptr_to_ptr(hop):
  656. assert hop.rtyper.getconfig().translation.rweakref
  657. c_ptrtype, v_wref = hop.inputargs(lltype.Void, hop.args_r[1])
  658. assert v_wref.concretetype == llmemory.WeakRefPtr
  659. hop.exception_cannot_occur()
  660. return hop.genop('cast_weakrefptr_to_ptr', [v_wref],
  661. resulttype=c_ptrtype.value)