| -- 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] | |
| 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] | |
| 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_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_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 |