| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- -- Test cases for calls using the vectorcall API (Python 3.8+)
- --
- -- Vectorcalls are faster than the legacy API, especially with keyword arguments,
- -- since there is no need to allocate a temporary dictionary for keyword args.
- [case testeVectorcallBasic_python3_8]
- from typing import Any
- def f(c: Any) -> None:
- c()
- c('x', 'y')
- [out]
- def f(c):
- c, r0 :: object
- r1, r2 :: str
- r3 :: object[2]
- r4 :: object_ptr
- r5 :: object
- L0:
- r0 = _PyObject_Vectorcall(c, 0, 0, 0)
- r1 = 'x'
- r2 = 'y'
- r3 = [r1, r2]
- r4 = load_address r3
- r5 = _PyObject_Vectorcall(c, r4, 2, 0)
- keep_alive r1, r2
- return 1
- [case testVectorcallKeywords_python3_8]
- from typing import Any
- def f(c: Any) -> None:
- c(x='a')
- c('x', a='y', b='z')
- [out]
- def f(c):
- c :: object
- r0 :: str
- r1 :: object[1]
- r2 :: object_ptr
- r3, r4 :: object
- r5, r6, r7 :: str
- r8 :: object[3]
- r9 :: object_ptr
- r10, r11 :: object
- L0:
- r0 = 'a'
- r1 = [r0]
- r2 = load_address r1
- r3 = ('x',)
- r4 = _PyObject_Vectorcall(c, r2, 0, r3)
- keep_alive r0
- r5 = 'x'
- r6 = 'y'
- r7 = 'z'
- r8 = [r5, r6, r7]
- r9 = load_address r8
- r10 = ('a', 'b')
- r11 = _PyObject_Vectorcall(c, r9, 1, r10)
- keep_alive r5, r6, r7
- return 1
- [case testVectorcallMethod_python3_8]
- from typing import Any
- def f(o: Any) -> None:
- # On Python 3.8 vectorcalls are only faster with keyword args
- o.m('x')
- o.m('x', a='y')
- [out]
- def f(o):
- o :: object
- r0, r1 :: str
- r2 :: object
- r3, r4, r5 :: str
- r6 :: object
- r7 :: object[2]
- r8 :: object_ptr
- r9, r10 :: object
- L0:
- r0 = 'x'
- r1 = 'm'
- r2 = CPyObject_CallMethodObjArgs(o, r1, r0, 0)
- r3 = 'x'
- r4 = 'y'
- r5 = 'm'
- r6 = CPyObject_GetAttr(o, r5)
- r7 = [r3, r4]
- r8 = load_address r7
- r9 = ('a',)
- r10 = _PyObject_Vectorcall(r6, r8, 1, r9)
- keep_alive r3, r4
- return 1
- [case testVectorcallMethod_python3_9_64bit]
- from typing import Any
- def f(o: Any) -> None:
- # Python 3.9 has a new API for calling methods
- o.m('x')
- o.m('x', 'y', a='z')
- [out]
- def f(o):
- o :: object
- r0, r1 :: str
- r2 :: object[2]
- r3 :: object_ptr
- r4 :: object
- r5, r6, r7, r8 :: str
- r9 :: object[4]
- r10 :: object_ptr
- r11, r12 :: object
- L0:
- r0 = 'x'
- r1 = 'm'
- r2 = [o, r0]
- r3 = load_address r2
- r4 = PyObject_VectorcallMethod(r1, r3, 9223372036854775810, 0)
- keep_alive o, r0
- r5 = 'x'
- r6 = 'y'
- r7 = 'z'
- r8 = 'm'
- r9 = [o, r5, r6, r7]
- r10 = load_address r9
- r11 = ('a',)
- r12 = PyObject_VectorcallMethod(r8, r10, 9223372036854775811, r11)
- keep_alive o, r5, r6, r7
- return 1
- [case testVectorcallMethod_python3_9_32bit]
- from typing import Any
- def f(o: Any) -> None:
- # The IR is slightly different on 32-bit platforms
- o.m('x', a='y')
- [out]
- def f(o):
- o :: object
- r0, r1, r2 :: str
- r3 :: object[3]
- r4 :: object_ptr
- r5, r6 :: object
- L0:
- r0 = 'x'
- r1 = 'y'
- r2 = 'm'
- r3 = [o, r0, r1]
- r4 = load_address r3
- r5 = ('a',)
- r6 = PyObject_VectorcallMethod(r2, r4, 2147483650, r5)
- keep_alive o, r0, r1
- return 1
|