Build N synthetic class/call pairs into an arena-backed buffer. */
| 16 | |
| 17 | /* Build N synthetic class/call pairs into an arena-backed buffer. */ |
| 18 | static char *build_fixture(int n_classes, int *out_len) { |
| 19 | /* Per class: ~140 chars (5-line def). Per call: ~50 chars. Overhead |
| 20 | * for the class number digits scales with log10(n) but the constant |
| 21 | * 256 covers up to 9-digit indices comfortably. */ |
| 22 | int approx = n_classes * 256 + 1024; |
| 23 | char *buf = (char *)malloc((size_t)approx); |
| 24 | if (!buf) |
| 25 | return NULL; |
| 26 | int pos = 0; |
| 27 | pos += snprintf(buf + pos, (size_t)(approx - pos), "from typing import Self\n"); |
| 28 | for (int i = 0; i < n_classes; i++) { |
| 29 | int n = snprintf(buf + pos, (size_t)(approx - pos), |
| 30 | "class Cls%d:\n" |
| 31 | " def method(self) -> int:\n" |
| 32 | " return %d\n" |
| 33 | " def chain(self) -> Self:\n" |
| 34 | " return self\n", |
| 35 | i, i); |
| 36 | if (n < 0 || pos + n >= approx) |
| 37 | break; |
| 38 | pos += n; |
| 39 | } |
| 40 | int n = snprintf(buf + pos, (size_t)(approx - pos), "def use():\n"); |
| 41 | pos += n; |
| 42 | for (int i = 0; i < n_classes; i++) { |
| 43 | int m = snprintf(buf + pos, (size_t)(approx - pos), |
| 44 | " Cls%d().chain().chain().method()\n", i); |
| 45 | if (m < 0 || pos + m >= approx) |
| 46 | break; |
| 47 | pos += m; |
| 48 | } |
| 49 | *out_len = pos; |
| 50 | return buf; |
| 51 | } |
| 52 | |
| 53 | static double measure(int n_classes, int *out_calls, int *out_resolved) { |
| 54 | int slen = 0; |