| 1 | module builtin |
| 2 | |
| 3 | import strings |
| 4 | |
| 5 | const autostr_type_stack_max_depth = 64 |
| 6 | |
| 7 | __global g_autostr_type_stack = [autostr_type_stack_max_depth]int{} |
| 8 | __global g_autostr_type_stack_len = 0 |
| 9 | |
| 10 | @[markused] |
| 11 | fn autostr_type_in_stack(typ int) bool { |
| 12 | for i := 0; i < g_autostr_type_stack_len; i++ { |
| 13 | if g_autostr_type_stack[i] == typ { |
| 14 | return true |
| 15 | } |
| 16 | } |
| 17 | return false |
| 18 | } |
| 19 | |
| 20 | @[markused] |
| 21 | fn autostr_type_push(typ int) { |
| 22 | if g_autostr_type_stack_len >= autostr_type_stack_max_depth { |
| 23 | return |
| 24 | } |
| 25 | g_autostr_type_stack[g_autostr_type_stack_len] = typ |
| 26 | g_autostr_type_stack_len++ |
| 27 | } |
| 28 | |
| 29 | @[markused] |
| 30 | fn autostr_type_pop() { |
| 31 | if g_autostr_type_stack_len > 0 { |
| 32 | g_autostr_type_stack_len-- |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | // Address-based circular reference detection. |
| 37 | // Tracks visited struct addresses to detect actual circular references |
| 38 | // (same instance reached again) without false positives from same-type |
| 39 | // different instances. |
| 40 | |
| 41 | __global g_autostr_addr_stack = [autostr_type_stack_max_depth]voidptr{} |
| 42 | __global g_autostr_addr_stack_len = 0 |
| 43 | |
| 44 | @[markused] |
| 45 | fn autostr_addr_in_stack(addr voidptr) bool { |
| 46 | for i := 0; i < g_autostr_addr_stack_len; i++ { |
| 47 | if g_autostr_addr_stack[i] == addr { |
| 48 | return true |
| 49 | } |
| 50 | } |
| 51 | return false |
| 52 | } |
| 53 | |
| 54 | @[markused] |
| 55 | fn autostr_addr_push(addr voidptr) { |
| 56 | if g_autostr_addr_stack_len >= autostr_type_stack_max_depth { |
| 57 | return |
| 58 | } |
| 59 | g_autostr_addr_stack[g_autostr_addr_stack_len] = addr |
| 60 | g_autostr_addr_stack_len++ |
| 61 | } |
| 62 | |
| 63 | @[markused] |
| 64 | fn autostr_addr_pop() { |
| 65 | if g_autostr_addr_stack_len > 0 { |
| 66 | g_autostr_addr_stack_len-- |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | @[markused] |
| 71 | fn autostr_array_circular(len int) string { |
| 72 | if len <= 0 { |
| 73 | return '[]' |
| 74 | } |
| 75 | mut sb := strings.new_builder(2 + len * 12) |
| 76 | sb.write_string('[') |
| 77 | for i in 0 .. len { |
| 78 | if i > 0 { |
| 79 | sb.write_string(', ') |
| 80 | } |
| 81 | sb.write_string('<circular>') |
| 82 | } |
| 83 | sb.write_string(']') |
| 84 | res := sb.str() |
| 85 | unsafe { sb.free() } |
| 86 | return res |
| 87 | } |
| 88 | |