import t, c from stdint import * from w32.win32process import TlsAlloc, TlsGetValue, TlsSetValue import stdlib import stdio import string # Maximum provider stack depth (compiler verifies sufficiency; increase if needed) _MAX_PROVIDER_DEPTH: t.CDefine = 32 @t.Object class _ProviderStack: """Provider stack, stores pairs of field names and pointers.""" names: t.CArray[VOIDPTR, 32] ptrs: t.CArray[VOIDPTR, 32] top: UINT64 # TLS index (global; all threads share the same index) _tls_index: ULONG = 0 @t.TLS def _init_tls(): """Initialize TLS index (executes once; subsequent calls are skipped).""" global _tls_index _tls_index = TlsAlloc() def _get_stack() -> _ProviderStack | t.CPtr: """Obtain current thread's provider stack. Allocate one if none exists.""" _init_tls() stack: _ProviderStack | t.CPtr = TlsGetValue(_tls_index) if stack == None: stack = stdlib.malloc(_ProviderStack.__sizeof__()) string.memset(stack, 0, _ProviderStack.__sizeof__()) TlsSetValue(_tls_index, stack) return stack def _push_provider(field_name: str, ptr: t.CPtr): """Push a provider (field_name, ptr) onto the stack.""" stack: _ProviderStack | t.CPtr = _get_stack() if stack.top >= _MAX_PROVIDER_DEPTH: stdio.printf("[with] ERROR: provider stack overflow (depth=%lu, max=%d), field '%s' not injected\n", stack.top, _MAX_PROVIDER_DEPTH, field_name) return stack.names[stack.top] = field_name stack.ptrs[stack.top] = ptr stack.top = stack.top + 1 def _pop_provider(): """Pop the top provider entry from the stack.""" stack: _ProviderStack | t.CPtr = _get_stack() if stack.top > 0: stack.top = stack.top - 1 def _find_provider(field_name: str) -> t.CPtr: """Search for matching field_name starting from stack top. Return associated pointer, or NULL if no match found.""" stack: _ProviderStack | t.CPtr = _get_stack() for i in range(stack.top - 1, -1, -1): if stack.names[i] == field_name: return stack.ptrs[i] return None