| -- Test cases for reference count insertion. | |
| [case testReturnLiteral] | |
| def f() -> int: | |
| return 1 | |
| [out] | |
| def f(): | |
| r0 :: short_int | |
| L0: | |
| r0 = 1 | |
| return r0 | |
| [case testReturnLocal] | |
| def f() -> int: | |
| x = 1 | |
| return x | |
| [out] | |
| def f(): | |
| r0 :: short_int | |
| x :: int | |
| L0: | |
| r0 = 1 | |
| x = r0 | |
| return x | |
| [case testLocalVars] | |
| def f() -> int: | |
| x = 1 | |
| y = x | |
| x = y | |
| return x | |
| [out] | |
| def f(): | |
| r0 :: short_int | |
| x, y :: int | |
| L0: | |
| r0 = 1 | |
| x = r0 | |
| y = x | |
| x = y | |
| return x | |
| [case testLocalVars2] | |
| def f() -> int: | |
| x = 1 | |
| y = x | |
| z = x | |
| return y + z | |
| [out] | |
| def f(): | |
| r0 :: short_int | |
| x, y, z, r1 :: int | |
| L0: | |
| r0 = 1 | |
| x = r0 | |
| inc_ref x :: int | |
| y = x | |
| z = x | |
| r1 = CPyTagged_Add(y, z) | |
| dec_ref y :: int | |
| dec_ref z :: int | |
| return r1 | |
| [case testFreeAtReturn] | |
| def f() -> int: | |
| x = 1 | |
| y = 2 | |
| if x == 1: | |
| return x | |
| return y | |
| [out] | |
| def f(): | |
| r0 :: short_int | |
| x :: int | |
| r1 :: short_int | |
| y :: int | |
| r2 :: short_int | |
| r3 :: bool | |
| L0: | |
| r0 = 1 | |
| x = r0 | |
| r1 = 2 | |
| y = r1 | |
| r2 = 1 | |
| r3 = CPyTagged_IsEq(x, r2) | |
| if r3 goto L3 else goto L4 :: bool | |
| L1: | |
| return x | |
| L2: | |
| return y | |
| L3: | |
| dec_ref y :: int | |
| goto L1 | |
| L4: | |
| dec_ref x :: int | |
| goto L2 | |
| [case testArgumentsInOps] | |
| def f(a: int, b: int) -> int: | |
| x = a + 1 | |
| y = x + a | |
| return y | |
| [out] | |
| def f(a, b): | |
| a, b :: int | |
| r0 :: short_int | |
| r1, x, r2, y :: int | |
| L0: | |
| r0 = 1 | |
| r1 = CPyTagged_Add(a, r0) | |
| x = r1 | |
| r2 = CPyTagged_Add(x, a) | |
| dec_ref x :: int | |
| y = r2 | |
| return y | |
| [case testArgumentsInAssign] | |
| def f(a: int) -> int: | |
| x = a | |
| y = a | |
| x = 1 | |
| return x + y | |
| [out] | |
| def f(a): | |
| a, x, y :: int | |
| r0 :: short_int | |
| r1 :: int | |
| L0: | |
| inc_ref a :: int | |
| x = a | |
| dec_ref x :: int | |
| inc_ref a :: int | |
| y = a | |
| r0 = 1 | |
| x = r0 | |
| r1 = CPyTagged_Add(x, y) | |
| dec_ref x :: int | |
| dec_ref y :: int | |
| return r1 | |
| [case testAssignToArgument1] | |
| def f(a: int) -> int: | |
| a = 1 | |
| y = a | |
| return y | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: short_int | |
| y :: int | |
| L0: | |
| r0 = 1 | |
| a = r0 | |
| y = a | |
| return y | |
| [case testAssignToArgument2] | |
| def f(a: int) -> int: | |
| a = 1 | |
| a = 2 | |
| a = 3 | |
| return a | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0, r1, r2 :: short_int | |
| L0: | |
| r0 = 1 | |
| a = r0 | |
| dec_ref a :: int | |
| r1 = 2 | |
| a = r1 | |
| dec_ref a :: int | |
| r2 = 3 | |
| a = r2 | |
| return a | |
| [case testAssignToArgument3] | |
| def f(a: int) -> int: | |
| x = 1 | |
| a = x | |
| y = x | |
| return a | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: short_int | |
| x, y :: int | |
| L0: | |
| r0 = 1 | |
| x = r0 | |
| inc_ref x :: int | |
| a = x | |
| y = x | |
| dec_ref y :: int | |
| return a | |
| [case testReturnArgument] | |
| def f(a: int) -> int: | |
| return a | |
| [out] | |
| def f(a): | |
| a :: int | |
| L0: | |
| inc_ref a :: int | |
| return a | |
| [case testConditionalAssignToArgument1] | |
| def f(a: int) -> int: | |
| if a == a: | |
| a = 1 | |
| else: | |
| x = 2 | |
| y = a + 1 | |
| return y | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: bool | |
| r1, r2 :: short_int | |
| x :: int | |
| r3 :: short_int | |
| r4, y :: int | |
| L0: | |
| r0 = CPyTagged_IsEq(a, a) | |
| if r0 goto L1 else goto L2 :: bool | |
| L1: | |
| r1 = 1 | |
| a = r1 | |
| goto L3 | |
| L2: | |
| r2 = 2 | |
| x = r2 | |
| dec_ref x :: int | |
| goto L4 | |
| L3: | |
| r3 = 1 | |
| r4 = CPyTagged_Add(a, r3) | |
| dec_ref a :: int | |
| y = r4 | |
| return y | |
| L4: | |
| inc_ref a :: int | |
| goto L3 | |
| [case testConditionalAssignToArgument2] | |
| def f(a: int) -> int: | |
| if a == a: | |
| x = 2 | |
| else: | |
| a = 1 | |
| y = a + 1 | |
| return y | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: bool | |
| r1 :: short_int | |
| x :: int | |
| r2, r3 :: short_int | |
| r4, y :: int | |
| L0: | |
| r0 = CPyTagged_IsEq(a, a) | |
| if r0 goto L1 else goto L2 :: bool | |
| L1: | |
| r1 = 2 | |
| x = r1 | |
| dec_ref x :: int | |
| goto L4 | |
| L2: | |
| r2 = 1 | |
| a = r2 | |
| L3: | |
| r3 = 1 | |
| r4 = CPyTagged_Add(a, r3) | |
| dec_ref a :: int | |
| y = r4 | |
| return y | |
| L4: | |
| inc_ref a :: int | |
| goto L3 | |
| [case testConditionalAssignToArgument3] | |
| def f(a: int) -> int: | |
| if a == a: | |
| a = 1 | |
| return a | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: bool | |
| r1 :: short_int | |
| L0: | |
| r0 = CPyTagged_IsEq(a, a) | |
| if r0 goto L1 else goto L3 :: bool | |
| L1: | |
| r1 = 1 | |
| a = r1 | |
| L2: | |
| return a | |
| L3: | |
| inc_ref a :: int | |
| goto L2 | |
| [case testAssignRegisterToItself] | |
| def f(a: int) -> int: | |
| a = a | |
| x = 1 | |
| x = x | |
| return x + a | |
| -- This is correct but bad code | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: short_int | |
| x, r1 :: int | |
| L0: | |
| inc_ref a :: int | |
| a = a | |
| r0 = 1 | |
| x = r0 | |
| inc_ref x :: int | |
| dec_ref x :: int | |
| x = x | |
| r1 = CPyTagged_Add(x, a) | |
| dec_ref x :: int | |
| dec_ref a :: int | |
| return r1 | |
| [case testIncrement1] | |
| def f(a: int) -> int: | |
| a = a + 1 | |
| x = 1 | |
| x = x + 1 | |
| return a + x | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: short_int | |
| r1 :: int | |
| r2 :: short_int | |
| x :: int | |
| r3 :: short_int | |
| r4, r5 :: int | |
| L0: | |
| r0 = 1 | |
| r1 = CPyTagged_Add(a, r0) | |
| a = r1 | |
| r2 = 1 | |
| x = r2 | |
| r3 = 1 | |
| r4 = CPyTagged_Add(x, r3) | |
| dec_ref x :: int | |
| x = r4 | |
| r5 = CPyTagged_Add(a, x) | |
| dec_ref a :: int | |
| dec_ref x :: int | |
| return r5 | |
| [case testIncrement2] | |
| def f() -> None: | |
| x = 1 | |
| x = x + 1 | |
| [out] | |
| def f(): | |
| r0 :: short_int | |
| x :: int | |
| r1 :: short_int | |
| r2 :: int | |
| r3 :: None | |
| L0: | |
| r0 = 1 | |
| x = r0 | |
| r1 = 1 | |
| r2 = CPyTagged_Add(x, r1) | |
| dec_ref x :: int | |
| x = r2 | |
| dec_ref x :: int | |
| r3 = None | |
| return r3 | |
| [case testAdd1] | |
| def f() -> None: | |
| y = 1 | |
| x = y + 1 | |
| [out] | |
| def f(): | |
| r0 :: short_int | |
| y :: int | |
| r1 :: short_int | |
| r2, x :: int | |
| r3 :: None | |
| L0: | |
| r0 = 1 | |
| y = r0 | |
| r1 = 1 | |
| r2 = CPyTagged_Add(y, r1) | |
| dec_ref y :: int | |
| x = r2 | |
| dec_ref x :: int | |
| r3 = None | |
| return r3 | |
| [case testAdd2] | |
| def f(a: int) -> int: | |
| a = a + a | |
| x = a | |
| x = x + x | |
| return x | |
| [out] | |
| def f(a): | |
| a, r0, x, r1 :: int | |
| L0: | |
| r0 = CPyTagged_Add(a, a) | |
| a = r0 | |
| x = a | |
| r1 = CPyTagged_Add(x, x) | |
| dec_ref x :: int | |
| x = r1 | |
| return x | |
| [case testAdd3] | |
| def f(a: int) -> int: | |
| x = a + a | |
| y = x + x | |
| return y | |
| [out] | |
| def f(a): | |
| a, r0, x, r1, y :: int | |
| L0: | |
| r0 = CPyTagged_Add(a, a) | |
| x = r0 | |
| r1 = CPyTagged_Add(x, x) | |
| dec_ref x :: int | |
| y = r1 | |
| return y | |
| [case testAdd4] | |
| def f(a: int) -> None: | |
| x = a + a | |
| y = 1 | |
| z = y + y | |
| [out] | |
| def f(a): | |
| a, r0, x :: int | |
| r1 :: short_int | |
| y, r2, z :: int | |
| r3 :: None | |
| L0: | |
| r0 = CPyTagged_Add(a, a) | |
| x = r0 | |
| dec_ref x :: int | |
| r1 = 1 | |
| y = r1 | |
| r2 = CPyTagged_Add(y, y) | |
| dec_ref y :: int | |
| z = r2 | |
| dec_ref z :: int | |
| r3 = None | |
| return r3 | |
| [case testAdd5] | |
| def f(a: int) -> None: | |
| a = a + a | |
| x = 1 | |
| x = x + x | |
| [out] | |
| def f(a): | |
| a, r0 :: int | |
| r1 :: short_int | |
| x, r2 :: int | |
| r3 :: None | |
| L0: | |
| r0 = CPyTagged_Add(a, a) | |
| a = r0 | |
| dec_ref a :: int | |
| r1 = 1 | |
| x = r1 | |
| r2 = CPyTagged_Add(x, x) | |
| dec_ref x :: int | |
| x = r2 | |
| dec_ref x :: int | |
| r3 = None | |
| return r3 | |
| [case testReturnInMiddleOfFunction] | |
| def f() -> int: | |
| x = 1 | |
| y = 2 | |
| z = 3 | |
| if z == z: | |
| return z | |
| a = 1 | |
| return x + y - a | |
| [out] | |
| def f(): | |
| r0 :: short_int | |
| x :: int | |
| r1 :: short_int | |
| y :: int | |
| r2 :: short_int | |
| z :: int | |
| r3 :: bool | |
| r4 :: short_int | |
| a, r5, r6 :: int | |
| L0: | |
| r0 = 1 | |
| x = r0 | |
| r1 = 2 | |
| y = r1 | |
| r2 = 3 | |
| z = r2 | |
| r3 = CPyTagged_IsEq(z, z) | |
| if r3 goto L3 else goto L4 :: bool | |
| L1: | |
| return z | |
| L2: | |
| r4 = 1 | |
| a = r4 | |
| r5 = CPyTagged_Add(x, y) | |
| dec_ref x :: int | |
| dec_ref y :: int | |
| r6 = CPyTagged_Subtract(r5, a) | |
| dec_ref r5 :: int | |
| dec_ref a :: int | |
| return r6 | |
| L3: | |
| dec_ref x :: int | |
| dec_ref y :: int | |
| goto L1 | |
| L4: | |
| dec_ref z :: int | |
| goto L2 | |
| [case testLoop] | |
| def f(a: int) -> int: | |
| sum = 0 | |
| i = 0 | |
| while i <= a: | |
| sum = sum + i | |
| i = i + 1 | |
| return sum | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: short_int | |
| sum :: int | |
| r1 :: short_int | |
| i :: int | |
| r2 :: bool | |
| r3 :: int | |
| r4 :: short_int | |
| r5 :: int | |
| L0: | |
| r0 = 0 | |
| sum = r0 | |
| r1 = 0 | |
| i = r1 | |
| L1: | |
| r2 = CPyTagged_IsLe(i, a) | |
| if r2 goto L2 else goto L4 :: bool | |
| L2: | |
| r3 = CPyTagged_Add(sum, i) | |
| dec_ref sum :: int | |
| sum = r3 | |
| r4 = 1 | |
| r5 = CPyTagged_Add(i, r4) | |
| dec_ref i :: int | |
| i = r5 | |
| goto L1 | |
| L3: | |
| return sum | |
| L4: | |
| dec_ref i :: int | |
| goto L3 | |
| [case testCall] | |
| def f(a: int) -> int: | |
| return f(a + 1) | |
| [out] | |
| def f(a): | |
| a :: int | |
| r0 :: short_int | |
| r1, r2 :: int | |
| L0: | |
| r0 = 1 | |
| r1 = CPyTagged_Add(a, r0) | |
| r2 = f(r1) | |
| dec_ref r1 :: int | |
| return r2 | |
| [case testError] | |
| def f(x: List[int]) -> None: pass # E: Name 'List' is not defined \ | |
| # N: Did you forget to import it from "typing"? (Suggestion: "from typing import List") | |
| [case testNewList] | |
| def f() -> int: | |
| a = [0, 1] | |
| return 0 | |
| [out] | |
| def f(): | |
| r0, r1 :: short_int | |
| r2, r3 :: object | |
| r4, a :: list | |
| r5 :: short_int | |
| L0: | |
| r0 = 0 | |
| r1 = 1 | |
| r2 = box(short_int, r0) | |
| r3 = box(short_int, r1) | |
| r4 = [r2, r3] | |
| a = r4 | |
| dec_ref a | |
| r5 = 0 | |
| return r5 | |
| [case testListSet] | |
| from typing import List | |
| def f(a: List[int], b: List[int]) -> None: | |
| a[0] = b[0] | |
| [out] | |
| def f(a, b): | |
| a, b :: list | |
| r0 :: short_int | |
| r1 :: object | |
| r2 :: int | |
| r3 :: short_int | |
| r4 :: object | |
| r5 :: bool | |
| r6 :: None | |
| L0: | |
| r0 = 0 | |
| r1 = CPyList_GetItemShort(b, r0) | |
| r2 = unbox(int, r1) | |
| dec_ref r1 | |
| r3 = 0 | |
| r4 = box(int, r2) | |
| r5 = CPyList_SetItem(a, r3, r4) | |
| r6 = None | |
| return r6 | |
| [case testTupleRefcount] | |
| from typing import Tuple | |
| def f(x: Tuple[Tuple[int, bool], bool]) -> int: | |
| return x[0][0] | |
| [out] | |
| def f(x): | |
| x :: tuple[tuple[int, bool], bool] | |
| r0 :: tuple[int, bool] | |
| r1 :: int | |
| L0: | |
| r0 = x[0] | |
| r1 = r0[0] | |
| dec_ref r0 | |
| return r1 | |
| [case testUserClassRefCount] | |
| class C: | |
| x: 'C' | |
| def f() -> None: | |
| c = C() | |
| c.x = C() | |
| [out] | |
| def f(): | |
| r0, c, r1 :: __main__.C | |
| r2 :: bool | |
| r3 :: None | |
| L0: | |
| r0 = C() | |
| c = r0 | |
| r1 = C() | |
| c.x = r1; r2 = is_error | |
| dec_ref c | |
| r3 = None | |
| return r3 | |
| [case testCastRefCount] | |
| class C: pass | |
| def f() -> None: | |
| a = [C()] | |
| d = a[0] | |
| [out] | |
| def f(): | |
| r0 :: __main__.C | |
| r1, a :: list | |
| r2 :: short_int | |
| r3 :: object | |
| r4, d :: __main__.C | |
| r5 :: None | |
| L0: | |
| r0 = C() | |
| r1 = [r0] | |
| a = r1 | |
| r2 = 0 | |
| r3 = CPyList_GetItemShort(a, r2) | |
| dec_ref a | |
| r4 = cast(__main__.C, r3) | |
| d = r4 | |
| dec_ref d | |
| r5 = None | |
| return r5 | |
| [case testUnaryBranchSpecialCase] | |
| def f(x: bool) -> int: | |
| if x: | |
| return 1 | |
| return 2 | |
| [out] | |
| def f(x): | |
| x :: bool | |
| r0, r1 :: short_int | |
| L0: | |
| if x goto L1 else goto L2 :: bool | |
| L1: | |
| r0 = 1 | |
| return r0 | |
| L2: | |
| r1 = 2 | |
| return r1 | |
| [case testUnicodeLiteral] | |
| def f() -> str: | |
| return "some string" | |
| [out] | |
| def f(): | |
| r0 :: str | |
| L0: | |
| r0 = unicode_1 :: static ('some string') | |
| inc_ref r0 | |
| return r0 | |
| [case testPyMethodCall] | |
| def g(x: str) -> int: | |
| return int(x, base=2) | |
| [out] | |
| def g(x): | |
| x :: str | |
| r0 :: short_int | |
| r1 :: object | |
| r2 :: str | |
| r3 :: tuple | |
| r4 :: native_int | |
| r5 :: object | |
| r6 :: dict | |
| r7 :: object | |
| r8 :: int | |
| L0: | |
| r0 = 2 | |
| r1 = int | |
| r2 = unicode_1 :: static ('base') | |
| r3 = (x) :: tuple | |
| r4 = 1 | |
| r5 = box(short_int, r0) | |
| r6 = CPyDict_Build(r4, r2, r5) | |
| dec_ref r5 | |
| r7 = py_call_with_kwargs(r1, r3, r6) | |
| dec_ref r3 | |
| dec_ref r6 | |
| r8 = unbox(int, r7) | |
| dec_ref r7 | |
| return r8 | |
| [case testListAppend] | |
| from typing import List | |
| def f(a: List[int], x: int) -> None: | |
| a.append(x) | |
| [out] | |
| def f(a, x): | |
| a :: list | |
| x :: int | |
| r0 :: object | |
| r1 :: bool | |
| r2, r3 :: None | |
| L0: | |
| inc_ref x :: int | |
| r0 = box(int, x) | |
| r1 = a.append(r0) :: list | |
| dec_ref r0 | |
| r2 = None | |
| r3 = None | |
| return r3 | |
| [case testForDict] | |
| from typing import Dict | |
| def f(d: Dict[int, int]) -> None: | |
| for key in d: | |
| d[key] | |
| [out] | |
| def f(d): | |
| d :: dict | |
| r0, r1 :: short_int | |
| r2 :: int | |
| r3 :: object | |
| r4 :: tuple[bool, int, object] | |
| r5 :: int | |
| r6 :: bool | |
| r7 :: object | |
| key, r8 :: int | |
| r9, r10 :: object | |
| r11 :: int | |
| r12, r13 :: bool | |
| r14 :: None | |
| L0: | |
| r0 = 0 | |
| r1 = r0 | |
| r2 = len d :: dict | |
| r3 = key_iter d :: dict | |
| L1: | |
| r4 = next_key r3, offset=r1 | |
| r5 = r4[1] | |
| r1 = r5 | |
| r6 = r4[0] | |
| if r6 goto L2 else goto L6 :: bool | |
| L2: | |
| r7 = r4[2] | |
| dec_ref r4 | |
| r8 = unbox(int, r7) | |
| dec_ref r7 | |
| key = r8 | |
| r9 = box(int, key) | |
| r10 = d[r9] :: dict | |
| dec_ref r9 | |
| r11 = unbox(int, r10) | |
| dec_ref r10 | |
| dec_ref r11 :: int | |
| L3: | |
| r12 = assert size(d) == r2 | |
| goto L1 | |
| L4: | |
| r13 = no_err_occurred | |
| L5: | |
| r14 = None | |
| return r14 | |
| L6: | |
| dec_ref r2 :: int | |
| dec_ref r3 | |
| dec_ref r4 | |
| goto L4 | |
| [case testBorrowRefs] | |
| def make_garbage(arg: object) -> None: | |
| b = True | |
| while b: | |
| arg = None | |
| b = False | |
| [out] | |
| def make_garbage(arg): | |
| arg :: object | |
| r0, b :: bool | |
| r1 :: None | |
| r2 :: object | |
| r3 :: bool | |
| r4 :: None | |
| L0: | |
| r0 = True | |
| b = r0 | |
| L1: | |
| if b goto L2 else goto L3 :: bool | |
| L2: | |
| r1 = None | |
| r2 = box(None, r1) | |
| inc_ref r2 | |
| arg = r2 | |
| dec_ref arg | |
| r3 = False | |
| b = r3 | |
| goto L1 | |
| L3: | |
| r4 = None | |
| return r4 |