zexus 1.6.8 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/README.md +12 -5
  2. package/package.json +1 -1
  3. package/src/__init__.py +7 -0
  4. package/src/zexus/__init__.py +1 -1
  5. package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
  6. package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
  7. package/src/zexus/__pycache__/debug_sanitizer.cpython-312.pyc +0 -0
  8. package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
  9. package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
  10. package/src/zexus/__pycache__/input_validation.cpython-312.pyc +0 -0
  11. package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
  12. package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
  13. package/src/zexus/__pycache__/module_manager.cpython-312.pyc +0 -0
  14. package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
  15. package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
  16. package/src/zexus/__pycache__/security_enforcement.cpython-312.pyc +0 -0
  17. package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
  18. package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  19. package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
  20. package/src/zexus/access_control_system/__pycache__/__init__.cpython-312.pyc +0 -0
  21. package/src/zexus/access_control_system/__pycache__/access_control.cpython-312.pyc +0 -0
  22. package/src/zexus/advanced_types.py +17 -2
  23. package/src/zexus/blockchain/__init__.py +411 -0
  24. package/src/zexus/blockchain/accelerator.py +1160 -0
  25. package/src/zexus/blockchain/chain.py +660 -0
  26. package/src/zexus/blockchain/consensus.py +821 -0
  27. package/src/zexus/blockchain/contract_vm.py +1019 -0
  28. package/src/zexus/blockchain/crypto.py +79 -14
  29. package/src/zexus/blockchain/events.py +526 -0
  30. package/src/zexus/blockchain/loadtest.py +721 -0
  31. package/src/zexus/blockchain/monitoring.py +350 -0
  32. package/src/zexus/blockchain/mpt.py +716 -0
  33. package/src/zexus/blockchain/multichain.py +951 -0
  34. package/src/zexus/blockchain/multiprocess_executor.py +338 -0
  35. package/src/zexus/blockchain/network.py +886 -0
  36. package/src/zexus/blockchain/node.py +666 -0
  37. package/src/zexus/blockchain/rpc.py +1203 -0
  38. package/src/zexus/blockchain/rust_bridge.py +421 -0
  39. package/src/zexus/blockchain/storage.py +423 -0
  40. package/src/zexus/blockchain/tokens.py +750 -0
  41. package/src/zexus/blockchain/upgradeable.py +1004 -0
  42. package/src/zexus/blockchain/verification.py +1602 -0
  43. package/src/zexus/blockchain/wallet.py +621 -0
  44. package/src/zexus/capability_system.py +184 -9
  45. package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
  46. package/src/zexus/cli/main.py +383 -34
  47. package/src/zexus/cli/zpm.py +1 -1
  48. package/src/zexus/compiler/__pycache__/bytecode.cpython-312.pyc +0 -0
  49. package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
  50. package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
  51. package/src/zexus/compiler/__pycache__/semantic.cpython-312.pyc +0 -0
  52. package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  53. package/src/zexus/compiler/bytecode.py +124 -7
  54. package/src/zexus/compiler/compat_runtime.py +6 -2
  55. package/src/zexus/compiler/lexer.py +16 -5
  56. package/src/zexus/compiler/parser.py +108 -7
  57. package/src/zexus/compiler/semantic.py +18 -19
  58. package/src/zexus/compiler/zexus_ast.py +26 -1
  59. package/src/zexus/concurrency_system.py +79 -0
  60. package/src/zexus/config.py +54 -0
  61. package/src/zexus/crypto_bridge.py +244 -8
  62. package/src/zexus/dap/__init__.py +10 -0
  63. package/src/zexus/dap/__main__.py +4 -0
  64. package/src/zexus/dap/dap_server.py +391 -0
  65. package/src/zexus/dap/debug_engine.py +298 -0
  66. package/src/zexus/environment.py +112 -9
  67. package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
  68. package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
  69. package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
  70. package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
  71. package/src/zexus/evaluator/__pycache__/resource_limiter.cpython-312.pyc +0 -0
  72. package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
  73. package/src/zexus/evaluator/__pycache__/unified_execution.cpython-312.pyc +0 -0
  74. package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
  75. package/src/zexus/evaluator/bytecode_compiler.py +457 -37
  76. package/src/zexus/evaluator/core.py +644 -50
  77. package/src/zexus/evaluator/expressions.py +358 -62
  78. package/src/zexus/evaluator/functions.py +458 -20
  79. package/src/zexus/evaluator/resource_limiter.py +4 -4
  80. package/src/zexus/evaluator/statements.py +774 -122
  81. package/src/zexus/evaluator/unified_execution.py +573 -72
  82. package/src/zexus/evaluator/utils.py +14 -2
  83. package/src/zexus/evaluator_original.py +1 -1
  84. package/src/zexus/event_loop.py +186 -0
  85. package/src/zexus/lexer.py +742 -458
  86. package/src/zexus/lsp/__init__.py +1 -1
  87. package/src/zexus/lsp/definition_provider.py +163 -9
  88. package/src/zexus/lsp/server.py +22 -8
  89. package/src/zexus/lsp/symbol_provider.py +182 -9
  90. package/src/zexus/module_cache.py +239 -9
  91. package/src/zexus/module_manager.py +129 -1
  92. package/src/zexus/object.py +76 -6
  93. package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
  94. package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
  95. package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
  96. package/src/zexus/parser/parser.py +1349 -408
  97. package/src/zexus/parser/strategy_context.py +755 -58
  98. package/src/zexus/parser/strategy_structural.py +121 -21
  99. package/src/zexus/persistence.py +15 -1
  100. package/src/zexus/renderer/__init__.py +61 -0
  101. package/src/zexus/renderer/__pycache__/__init__.cpython-312.pyc +0 -0
  102. package/src/zexus/renderer/__pycache__/backend.cpython-312.pyc +0 -0
  103. package/src/zexus/renderer/__pycache__/canvas.cpython-312.pyc +0 -0
  104. package/src/zexus/renderer/__pycache__/color_system.cpython-312.pyc +0 -0
  105. package/src/zexus/renderer/__pycache__/layout.cpython-312.pyc +0 -0
  106. package/src/zexus/renderer/__pycache__/main_renderer.cpython-312.pyc +0 -0
  107. package/src/zexus/renderer/__pycache__/painter.cpython-312.pyc +0 -0
  108. package/src/zexus/renderer/backend.py +261 -0
  109. package/src/zexus/renderer/canvas.py +78 -0
  110. package/src/zexus/renderer/color_system.py +201 -0
  111. package/src/zexus/renderer/graphics.py +31 -0
  112. package/src/zexus/renderer/layout.py +222 -0
  113. package/src/zexus/renderer/main_renderer.py +66 -0
  114. package/src/zexus/renderer/painter.py +30 -0
  115. package/src/zexus/renderer/tk_backend.py +208 -0
  116. package/src/zexus/renderer/web_backend.py +260 -0
  117. package/src/zexus/runtime/__init__.py +10 -2
  118. package/src/zexus/runtime/__pycache__/__init__.cpython-312.pyc +0 -0
  119. package/src/zexus/runtime/__pycache__/async_runtime.cpython-312.pyc +0 -0
  120. package/src/zexus/runtime/__pycache__/load_manager.cpython-312.pyc +0 -0
  121. package/src/zexus/runtime/file_flags.py +137 -0
  122. package/src/zexus/runtime/load_manager.py +368 -0
  123. package/src/zexus/safety/__pycache__/__init__.cpython-312.pyc +0 -0
  124. package/src/zexus/safety/__pycache__/memory_safety.cpython-312.pyc +0 -0
  125. package/src/zexus/security.py +424 -34
  126. package/src/zexus/stdlib/fs.py +23 -18
  127. package/src/zexus/stdlib/http.py +289 -186
  128. package/src/zexus/stdlib/sockets.py +207 -163
  129. package/src/zexus/stdlib/websockets.py +282 -0
  130. package/src/zexus/stdlib_integration.py +369 -2
  131. package/src/zexus/strategy_recovery.py +6 -3
  132. package/src/zexus/type_checker.py +423 -0
  133. package/src/zexus/virtual_filesystem.py +189 -2
  134. package/src/zexus/vm/__init__.py +113 -3
  135. package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
  136. package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
  137. package/src/zexus/vm/__pycache__/bytecode_converter.cpython-312.pyc +0 -0
  138. package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
  139. package/src/zexus/vm/__pycache__/compiler.cpython-312.pyc +0 -0
  140. package/src/zexus/vm/__pycache__/gas_metering.cpython-312.pyc +0 -0
  141. package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
  142. package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
  143. package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
  144. package/src/zexus/vm/async_optimizer.py +80 -6
  145. package/src/zexus/vm/binary_bytecode.py +659 -0
  146. package/src/zexus/vm/bytecode.py +59 -11
  147. package/src/zexus/vm/bytecode_converter.py +26 -12
  148. package/src/zexus/vm/cabi.c +1985 -0
  149. package/src/zexus/vm/cabi.cpython-312-x86_64-linux-gnu.so +0 -0
  150. package/src/zexus/vm/cabi.h +127 -0
  151. package/src/zexus/vm/cache.py +561 -17
  152. package/src/zexus/vm/compiler.py +818 -51
  153. package/src/zexus/vm/fastops.c +15743 -0
  154. package/src/zexus/vm/fastops.cpython-312-x86_64-linux-gnu.so +0 -0
  155. package/src/zexus/vm/fastops.pyx +288 -0
  156. package/src/zexus/vm/gas_metering.py +50 -9
  157. package/src/zexus/vm/jit.py +364 -20
  158. package/src/zexus/vm/native_jit_backend.py +1816 -0
  159. package/src/zexus/vm/native_runtime.cpp +1388 -0
  160. package/src/zexus/vm/native_runtime.cpython-312-x86_64-linux-gnu.so +0 -0
  161. package/src/zexus/vm/optimizer.py +161 -11
  162. package/src/zexus/vm/parallel_vm.py +140 -45
  163. package/src/zexus/vm/peephole_optimizer.py +82 -4
  164. package/src/zexus/vm/profiler.py +38 -18
  165. package/src/zexus/vm/register_allocator.py +16 -5
  166. package/src/zexus/vm/register_vm.py +8 -5
  167. package/src/zexus/vm/vm.py +3581 -531
  168. package/src/zexus/vm/wasm_compiler.py +658 -0
  169. package/src/zexus/zexus_ast.py +137 -11
  170. package/src/zexus/zexus_token.py +16 -5
  171. package/src/zexus/zpm/installer.py +55 -15
  172. package/src/zexus/zpm/package_manager.py +1 -1
  173. package/src/zexus/zpm/registry.py +257 -28
  174. package/src/zexus.egg-info/PKG-INFO +16 -6
  175. package/src/zexus.egg-info/SOURCES.txt +129 -17
  176. package/src/zexus.egg-info/entry_points.txt +1 -0
  177. package/src/zexus.egg-info/requires.txt +4 -0
@@ -0,0 +1,1388 @@
1
+ #define PY_SSIZE_T_CLEAN
2
+ #include <Python.h>
3
+
4
+ typedef PyObject* ZxValue;
5
+
6
+ static PyObject *zx_get_attr(PyObject *obj, const char *name) {
7
+ if (!obj) return NULL;
8
+ return PyObject_GetAttrString(obj, name);
9
+ }
10
+
11
+ static int zx_is_awaitable(PyObject *obj) {
12
+ if (!obj) return 0;
13
+ int has = PyObject_HasAttrString(obj, "__await__");
14
+ return has > 0;
15
+ }
16
+
17
+ static PyObject *zx_to_bytes(PyObject *obj) {
18
+ if (!obj) return PyBytes_FromString("");
19
+ if (PyBytes_Check(obj)) { Py_INCREF(obj); return obj; }
20
+ if (PyUnicode_Check(obj)) return PyUnicode_AsEncodedString(obj, "utf-8", "strict");
21
+ if (PyDict_Check(obj)) {
22
+ PyObject *json = PyImport_ImportModule("json");
23
+ if (!json) { PyErr_Clear(); goto fallback; }
24
+ PyObject *dumps = PyObject_GetAttrString(json, "dumps");
25
+ Py_DECREF(json);
26
+ if (!dumps) { PyErr_Clear(); goto fallback; }
27
+ PyObject *kwargs = Py_BuildValue("{s:O}", "sort_keys", Py_True);
28
+ PyObject *args = PyTuple_Pack(1, obj);
29
+ PyObject *s = PyObject_Call(dumps, args, kwargs);
30
+ Py_DECREF(args);
31
+ Py_DECREF(kwargs);
32
+ Py_DECREF(dumps);
33
+ if (!s) { PyErr_Clear(); goto fallback; }
34
+ PyObject *bytes = PyUnicode_AsEncodedString(s, "utf-8", "strict");
35
+ Py_DECREF(s);
36
+ return bytes;
37
+ }
38
+ fallback:
39
+ {
40
+ PyObject *s = PyObject_Str(obj);
41
+ if (!s) { PyErr_Clear(); return PyBytes_FromString(""); }
42
+ PyObject *bytes = PyUnicode_AsEncodedString(s, "utf-8", "strict");
43
+ Py_DECREF(s);
44
+ return bytes;
45
+ }
46
+ }
47
+
48
+ static PyObject *zx_sha256_hex(PyObject *bytes_obj) {
49
+ PyObject *hashlib = PyImport_ImportModule("hashlib");
50
+ if (!hashlib) { PyErr_Clear(); Py_RETURN_NONE; }
51
+ PyObject *sha256 = PyObject_GetAttrString(hashlib, "sha256");
52
+ Py_DECREF(hashlib);
53
+ if (!sha256) { PyErr_Clear(); Py_RETURN_NONE; }
54
+ PyObject *empty = NULL;
55
+ PyObject *arg_obj = bytes_obj ? bytes_obj : (empty = PyBytes_FromString(""));
56
+ PyObject *args = PyTuple_Pack(1, arg_obj);
57
+ Py_XDECREF(empty);
58
+ PyObject *hash = PyObject_CallObject(sha256, args);
59
+ Py_DECREF(args);
60
+ Py_DECREF(sha256);
61
+ if (!hash) { PyErr_Clear(); Py_RETURN_NONE; }
62
+ PyObject *hex = PyObject_CallMethod(hash, "hexdigest", NULL);
63
+ Py_DECREF(hash);
64
+ if (!hex) { PyErr_Clear(); Py_RETURN_NONE; }
65
+ return hex;
66
+ }
67
+
68
+ static PyObject *zx_env_get_dict(PyObject *env, const char *key, int create) {
69
+ if (!env || !PyDict_Check(env)) return NULL;
70
+ PyObject *k = PyUnicode_FromString(key);
71
+ if (!k) return NULL;
72
+ PyObject *val = PyDict_GetItem(env, k);
73
+ if (!val && create) {
74
+ PyObject *d = PyDict_New();
75
+ if (d) {
76
+ PyDict_SetItem(env, k, d);
77
+ val = d;
78
+ Py_DECREF(d);
79
+ }
80
+ }
81
+ Py_DECREF(k);
82
+ return val;
83
+ }
84
+
85
+ static PyObject *zx_env_get_list(PyObject *env, const char *key, int create) {
86
+ if (!env || !PyDict_Check(env)) return NULL;
87
+ PyObject *k = PyUnicode_FromString(key);
88
+ if (!k) return NULL;
89
+ PyObject *val = PyDict_GetItem(env, k);
90
+ if (!val && create) {
91
+ PyObject *lst = PyList_New(0);
92
+ if (lst) {
93
+ PyDict_SetItem(env, k, lst);
94
+ val = lst;
95
+ Py_DECREF(lst);
96
+ }
97
+ }
98
+ Py_DECREF(k);
99
+ return val;
100
+ }
101
+
102
+ static PyObject *zx_env_get_bool(PyObject *env, const char *key) {
103
+ if (!env || !PyDict_Check(env)) return NULL;
104
+ PyObject *k = PyUnicode_FromString(key);
105
+ if (!k) return NULL;
106
+ PyObject *val = PyDict_GetItem(env, k);
107
+ Py_DECREF(k);
108
+ return val;
109
+ }
110
+
111
+ static void zx_env_set(PyObject *env, const char *key, PyObject *value) {
112
+ if (!env || !PyDict_Check(env)) return;
113
+ PyObject *k = PyUnicode_FromString(key);
114
+ if (!k) return;
115
+ PyDict_SetItem(env, k, value ? value : Py_None);
116
+ Py_DECREF(k);
117
+ }
118
+
119
+ static PyObject *zx_unwrap_value(PyObject *obj) {
120
+ if (!obj) {
121
+ Py_RETURN_NONE;
122
+ }
123
+ PyObject *attr = PyObject_GetAttrString(obj, "value");
124
+ if (attr) {
125
+ if (!PyCallable_Check(attr)) {
126
+ return attr;
127
+ }
128
+ Py_DECREF(attr);
129
+ } else {
130
+ PyErr_Clear();
131
+ }
132
+ Py_INCREF(obj);
133
+ return obj;
134
+ }
135
+
136
+ extern "C" {
137
+
138
+ ZxValue zexus_rt_call_callable(ZxValue callable, ZxValue args_tuple) {
139
+ if (!callable || !PyCallable_Check(callable)) {
140
+ Py_RETURN_NONE;
141
+ }
142
+ return PyObject_CallObject(callable, args_tuple);
143
+ }
144
+
145
+ ZxValue zexus_rt_call_method(ZxValue obj, ZxValue method_name, ZxValue args_tuple) {
146
+ if (!obj || !method_name) {
147
+ Py_RETURN_NONE;
148
+ }
149
+ PyObject *method = PyObject_GetAttr(obj, method_name);
150
+ if (!method) {
151
+ PyErr_Clear();
152
+ Py_RETURN_NONE;
153
+ }
154
+ if (!PyCallable_Check(method)) {
155
+ Py_DECREF(method);
156
+ Py_RETURN_NONE;
157
+ }
158
+ PyObject *result = PyObject_CallObject(method, args_tuple);
159
+ Py_DECREF(method);
160
+ return result;
161
+ }
162
+
163
+ ZxValue zexus_rt_call_name(ZxValue env, ZxValue builtins, ZxValue name, ZxValue args_tuple) {
164
+ PyObject *callable = NULL;
165
+ if (env && name) {
166
+ callable = PyObject_GetItem(env, name);
167
+ if (!callable) { PyErr_Clear(); }
168
+ }
169
+ if (!callable && builtins && name) {
170
+ callable = PyObject_GetItem(builtins, name);
171
+ if (!callable) { PyErr_Clear(); }
172
+ }
173
+ if (!callable || !PyCallable_Check(callable)) {
174
+ Py_XDECREF(callable);
175
+ Py_RETURN_NONE;
176
+ }
177
+ PyObject *result = PyObject_CallObject(callable, args_tuple);
178
+ Py_DECREF(callable);
179
+ return result;
180
+ }
181
+
182
+ ZxValue zexus_rt_env_get(ZxValue env, ZxValue name) {
183
+ if (!env || !name) {
184
+ Py_RETURN_NONE;
185
+ }
186
+ PyObject *val = PyObject_GetItem(env, name);
187
+ if (!val) { PyErr_Clear(); Py_RETURN_NONE; }
188
+ return val;
189
+ }
190
+
191
+ int zexus_rt_env_set(ZxValue env, ZxValue name, ZxValue value) {
192
+ if (!env || !name) return 0;
193
+ if (PyObject_SetItem(env, name, value) == 0) return 1;
194
+ PyErr_Clear();
195
+ return 0;
196
+ }
197
+
198
+ ZxValue zexus_rt_export(ZxValue env, ZxValue name, ZxValue value) {
199
+ if (!env || !name) { Py_RETURN_NONE; }
200
+ PyObject *val = value;
201
+ if (!val || val == Py_None) {
202
+ val = PyObject_GetItem(env, name);
203
+ if (!val) {
204
+ PyErr_Clear();
205
+ val = Py_None;
206
+ Py_INCREF(val);
207
+ }
208
+ } else {
209
+ Py_INCREF(val);
210
+ }
211
+
212
+ PyObject *export_fn = PyObject_GetAttrString(env, "export");
213
+ if (export_fn && PyCallable_Check(export_fn)) {
214
+ PyObject *args = PyTuple_Pack(2, name, val);
215
+ if (args) {
216
+ PyObject *res = PyObject_CallObject(export_fn, args);
217
+ Py_XDECREF(res);
218
+ Py_DECREF(args);
219
+ }
220
+ Py_DECREF(export_fn);
221
+ } else {
222
+ Py_XDECREF(export_fn);
223
+ if (PyObject_SetItem(env, name, val) != 0) {
224
+ PyErr_Clear();
225
+ }
226
+ }
227
+ Py_DECREF(val);
228
+ Py_RETURN_NONE;
229
+ }
230
+
231
+ ZxValue zexus_rt_build_list(ZxValue *items, Py_ssize_t count) {
232
+ PyObject *list = PyList_New(count);
233
+ if (!list) return NULL;
234
+ for (Py_ssize_t i = 0; i < count; i++) {
235
+ PyObject *item = items[i] ? items[i] : Py_None;
236
+ Py_INCREF(item);
237
+ PyList_SetItem(list, i, item);
238
+ }
239
+ return list;
240
+ }
241
+
242
+ ZxValue zexus_rt_build_map(ZxValue *items, Py_ssize_t count) {
243
+ PyObject *dict = PyDict_New();
244
+ if (!dict) return NULL;
245
+ for (Py_ssize_t i = 0; i + 1 < count; i += 2) {
246
+ PyObject *k = items[i] ? items[i] : Py_None;
247
+ PyObject *v = items[i + 1] ? items[i + 1] : Py_None;
248
+ PyDict_SetItem(dict, k, v);
249
+ }
250
+ return dict;
251
+ }
252
+
253
+ ZxValue zexus_rt_iter_next(ZxValue iterator) {
254
+ if (!iterator) { return NULL; }
255
+ PyObject *val = PyIter_Next(iterator);
256
+ if (!val) {
257
+ if (PyErr_Occurred()) {
258
+ PyErr_Clear();
259
+ }
260
+ return NULL;
261
+ }
262
+ return val;
263
+ }
264
+
265
+ ZxValue zexus_rt_build_set(ZxValue *items, Py_ssize_t count) {
266
+ PyObject *set = PySet_New(NULL);
267
+ if (!set) return NULL;
268
+ for (Py_ssize_t i = 0; i < count; i++) {
269
+ PyObject *item = items[i] ? items[i] : Py_None;
270
+ PySet_Add(set, item);
271
+ }
272
+ return set;
273
+ }
274
+
275
+ ZxValue zexus_rt_build_tuple(ZxValue *items, Py_ssize_t count) {
276
+ PyObject *tuple = PyTuple_New(count);
277
+ if (!tuple) return NULL;
278
+ for (Py_ssize_t i = 0; i < count; i++) {
279
+ PyObject *item = items[i] ? items[i] : Py_None;
280
+ Py_INCREF(item);
281
+ PyTuple_SetItem(tuple, i, item);
282
+ }
283
+ return tuple;
284
+ }
285
+
286
+ ZxValue zexus_rt_add(ZxValue a, ZxValue b) { return PyNumber_Add(a, b); }
287
+ ZxValue zexus_rt_sub(ZxValue a, ZxValue b) { return PyNumber_Subtract(a, b); }
288
+ ZxValue zexus_rt_mul(ZxValue a, ZxValue b) { return PyNumber_Multiply(a, b); }
289
+ ZxValue zexus_rt_div(ZxValue a, ZxValue b) { return PyNumber_TrueDivide(a, b); }
290
+ ZxValue zexus_rt_mod(ZxValue a, ZxValue b) { return PyNumber_Remainder(a, b); }
291
+ ZxValue zexus_rt_pow(ZxValue a, ZxValue b) { return PyNumber_Power(a, b, Py_None); }
292
+ ZxValue zexus_rt_neg(ZxValue a) { return PyNumber_Negative(a); }
293
+
294
+ ZxValue zexus_rt_eq(ZxValue a, ZxValue b) {
295
+ int r = PyObject_RichCompareBool(a, b, Py_EQ);
296
+ if (r < 0) { PyErr_Clear(); Py_RETURN_FALSE; }
297
+ if (r) Py_RETURN_TRUE; else Py_RETURN_FALSE;
298
+ }
299
+ ZxValue zexus_rt_neq(ZxValue a, ZxValue b) {
300
+ int r = PyObject_RichCompareBool(a, b, Py_NE);
301
+ if (r < 0) { PyErr_Clear(); Py_RETURN_FALSE; }
302
+ if (r) Py_RETURN_TRUE; else Py_RETURN_FALSE;
303
+ }
304
+ ZxValue zexus_rt_lt(ZxValue a, ZxValue b) {
305
+ int r = PyObject_RichCompareBool(a, b, Py_LT);
306
+ if (r < 0) { PyErr_Clear(); Py_RETURN_FALSE; }
307
+ if (r) Py_RETURN_TRUE; else Py_RETURN_FALSE;
308
+ }
309
+ ZxValue zexus_rt_gt(ZxValue a, ZxValue b) {
310
+ int r = PyObject_RichCompareBool(a, b, Py_GT);
311
+ if (r < 0) { PyErr_Clear(); Py_RETURN_FALSE; }
312
+ if (r) Py_RETURN_TRUE; else Py_RETURN_FALSE;
313
+ }
314
+ ZxValue zexus_rt_lte(ZxValue a, ZxValue b) {
315
+ int r = PyObject_RichCompareBool(a, b, Py_LE);
316
+ if (r < 0) { PyErr_Clear(); Py_RETURN_FALSE; }
317
+ if (r) Py_RETURN_TRUE; else Py_RETURN_FALSE;
318
+ }
319
+ ZxValue zexus_rt_gte(ZxValue a, ZxValue b) {
320
+ int r = PyObject_RichCompareBool(a, b, Py_GE);
321
+ if (r < 0) { PyErr_Clear(); Py_RETURN_FALSE; }
322
+ if (r) Py_RETURN_TRUE; else Py_RETURN_FALSE;
323
+ }
324
+
325
+ int zexus_rt_truthy(ZxValue a) {
326
+ int t = PyObject_IsTrue(a);
327
+ if (t < 0) { PyErr_Clear(); return 0; }
328
+ return t ? 1 : 0;
329
+ }
330
+ ZxValue zexus_rt_not(ZxValue a) {
331
+ int t = PyObject_IsTrue(a);
332
+ if (t < 0) { PyErr_Clear(); Py_RETURN_FALSE; }
333
+ if (!t) Py_RETURN_TRUE; else Py_RETURN_FALSE;
334
+ }
335
+ ZxValue zexus_rt_and(ZxValue a, ZxValue b) {
336
+ int ta = zexus_rt_truthy(a);
337
+ int tb = zexus_rt_truthy(b);
338
+ if (ta && tb) Py_RETURN_TRUE; else Py_RETURN_FALSE;
339
+ }
340
+ ZxValue zexus_rt_or(ZxValue a, ZxValue b) {
341
+ int ta = zexus_rt_truthy(a);
342
+ int tb = zexus_rt_truthy(b);
343
+ if (ta || tb) Py_RETURN_TRUE; else Py_RETURN_FALSE;
344
+ }
345
+
346
+ ZxValue zexus_rt_index(ZxValue obj, ZxValue idx) {
347
+ if (!obj || !idx) { Py_RETURN_NONE; }
348
+ PyObject *val = PyObject_GetItem(obj, idx);
349
+ if (!val) { PyErr_Clear(); Py_RETURN_NONE; }
350
+ return val;
351
+ }
352
+
353
+ ZxValue zexus_rt_slice(ZxValue obj, ZxValue start, ZxValue end) {
354
+ if (!obj) { Py_RETURN_NONE; }
355
+ PyObject *slice = PySlice_New(start ? start : Py_None, end ? end : Py_None, Py_None);
356
+ if (!slice) { PyErr_Clear(); Py_RETURN_NONE; }
357
+ PyObject *res = PyObject_GetItem(obj, slice);
358
+ Py_DECREF(slice);
359
+ if (res) {
360
+ return res;
361
+ }
362
+ PyErr_Clear();
363
+ PyObject *elements = PyObject_GetAttrString(obj, "elements");
364
+ if (!elements) {
365
+ PyErr_Clear();
366
+ Py_RETURN_NONE;
367
+ }
368
+ Py_ssize_t s = 0;
369
+ Py_ssize_t e = PyList_Check(elements) ? PyList_Size(elements) : PySequence_Size(elements);
370
+ if (start && start != Py_None) {
371
+ s = PyLong_AsSsize_t(start);
372
+ }
373
+ if (end && end != Py_None) {
374
+ e = PyLong_AsSsize_t(end);
375
+ }
376
+ if (PyErr_Occurred()) {
377
+ PyErr_Clear();
378
+ s = 0;
379
+ e = PySequence_Size(elements);
380
+ }
381
+ PyObject *slice_list = PySequence_GetSlice(elements, s, e);
382
+ Py_DECREF(elements);
383
+ if (!slice_list) { PyErr_Clear(); Py_RETURN_NONE; }
384
+ return slice_list;
385
+ }
386
+ ZxValue zexus_rt_get_attr(ZxValue obj, ZxValue attr) {
387
+ if (!obj || !attr) { Py_RETURN_NONE; }
388
+ PyObject *val = PyObject_GetAttr(obj, attr);
389
+ if (!val) { PyErr_Clear(); Py_RETURN_NONE; }
390
+ return val;
391
+ }
392
+ ZxValue zexus_rt_get_length(ZxValue obj) {
393
+ if (!obj) { Py_RETURN_NONE; }
394
+ Py_ssize_t len = PyObject_Length(obj);
395
+ if (len < 0) { PyErr_Clear(); Py_RETURN_NONE; }
396
+ return PyLong_FromSsize_t(len);
397
+ }
398
+
399
+ ZxValue zexus_rt_print(ZxValue obj) {
400
+ if (!obj) {
401
+ PySys_WriteStdout("%s", "null");
402
+ PySys_WriteStdout("\n");
403
+ Py_RETURN_NONE;
404
+ }
405
+ PyObject *str = PyObject_Str(obj);
406
+ if (str) {
407
+ const char *cstr = PyUnicode_AsUTF8(str);
408
+ if (cstr) {
409
+ PySys_WriteStdout("%s", cstr);
410
+ }
411
+ Py_DECREF(str);
412
+ }
413
+ PySys_WriteStdout("\n");
414
+ Py_RETURN_NONE;
415
+ }
416
+
417
+ ZxValue zexus_rt_read(ZxValue path) {
418
+ if (!path) { Py_RETURN_NONE; }
419
+ PyObject *io = PyImport_ImportModule("io");
420
+ if (!io) { PyErr_Clear(); Py_RETURN_NONE; }
421
+ PyObject *open_fn = PyObject_GetAttrString(io, "open");
422
+ Py_DECREF(io);
423
+ if (!open_fn) { PyErr_Clear(); Py_RETURN_NONE; }
424
+ PyObject *args = PyTuple_Pack(2, path, PyUnicode_FromString("r"));
425
+ PyObject *file = PyObject_CallObject(open_fn, args);
426
+ Py_DECREF(args);
427
+ Py_DECREF(open_fn);
428
+ if (!file) { PyErr_Clear(); Py_RETURN_NONE; }
429
+ PyObject *read_fn = PyObject_GetAttrString(file, "read");
430
+ if (!read_fn) { PyErr_Clear(); Py_DECREF(file); Py_RETURN_NONE; }
431
+ PyObject *content = PyObject_CallObject(read_fn, NULL);
432
+ Py_DECREF(read_fn);
433
+ PyObject *close_fn = PyObject_GetAttrString(file, "close");
434
+ if (close_fn) {
435
+ PyObject_CallObject(close_fn, NULL);
436
+ Py_DECREF(close_fn);
437
+ }
438
+ Py_DECREF(file);
439
+ if (!content) { PyErr_Clear(); Py_RETURN_NONE; }
440
+ return content;
441
+ }
442
+
443
+ ZxValue zexus_rt_write(ZxValue path, ZxValue content) {
444
+ if (!path) { Py_RETURN_NONE; }
445
+ PyObject *io = PyImport_ImportModule("io");
446
+ if (!io) { PyErr_Clear(); Py_RETURN_NONE; }
447
+ PyObject *open_fn = PyObject_GetAttrString(io, "open");
448
+ Py_DECREF(io);
449
+ if (!open_fn) { PyErr_Clear(); Py_RETURN_NONE; }
450
+ PyObject *args = PyTuple_Pack(2, path, PyUnicode_FromString("w"));
451
+ PyObject *file = PyObject_CallObject(open_fn, args);
452
+ Py_DECREF(args);
453
+ Py_DECREF(open_fn);
454
+ if (!file) { PyErr_Clear(); Py_RETURN_NONE; }
455
+ PyObject *write_fn = PyObject_GetAttrString(file, "write");
456
+ if (!write_fn) { PyErr_Clear(); Py_DECREF(file); Py_RETURN_NONE; }
457
+ PyObject *text = content ? PyObject_Str(content) : PyUnicode_FromString("null");
458
+ PyObject *write_args = PyTuple_Pack(1, text ? text : PyUnicode_FromString(""));
459
+ PyObject *write_res = PyObject_CallObject(write_fn, write_args);
460
+ Py_XDECREF(write_res);
461
+ Py_DECREF(write_args);
462
+ Py_XDECREF(text);
463
+ Py_DECREF(write_fn);
464
+ PyObject *close_fn = PyObject_GetAttrString(file, "close");
465
+ if (close_fn) {
466
+ PyObject_CallObject(close_fn, NULL);
467
+ Py_DECREF(close_fn);
468
+ }
469
+ Py_DECREF(file);
470
+ Py_RETURN_NONE;
471
+ }
472
+
473
+ ZxValue zexus_rt_import(ZxValue name) {
474
+ if (!name) { Py_RETURN_NONE; }
475
+ PyObject *module = PyImport_Import(name);
476
+ if (!module) { PyErr_Clear(); Py_RETURN_NONE; }
477
+ return module;
478
+ }
479
+
480
+ ZxValue zexus_rt_int_from_long(long long value) {
481
+ return PyLong_FromLongLong(value);
482
+ }
483
+
484
+ ZxValue zexus_rt_hash_block(ZxValue obj) {
485
+ PyObject *bytes = zx_to_bytes(obj);
486
+ if (!bytes) { PyErr_Clear(); Py_RETURN_NONE; }
487
+ PyObject *hex = zx_sha256_hex(bytes);
488
+ Py_DECREF(bytes);
489
+ return hex ? hex : Py_None;
490
+ }
491
+
492
+ ZxValue zexus_rt_merkle_root(ZxValue *items, Py_ssize_t count) {
493
+ if (count <= 0) {
494
+ return PyUnicode_FromString("");
495
+ }
496
+ PyObject *hashes = PyList_New(0);
497
+ if (!hashes) { Py_RETURN_NONE; }
498
+ for (Py_ssize_t i = 0; i < count; i++) {
499
+ PyObject *leaf = items[i] ? items[i] : Py_None;
500
+ PyObject *bytes = zx_to_bytes(leaf);
501
+ if (!bytes) { PyErr_Clear(); continue; }
502
+ PyObject *hex = zx_sha256_hex(bytes);
503
+ Py_DECREF(bytes);
504
+ if (!hex) { PyErr_Clear(); continue; }
505
+ PyList_Append(hashes, hex);
506
+ Py_DECREF(hex);
507
+ }
508
+ while (PyList_Size(hashes) > 1) {
509
+ Py_ssize_t n = PyList_Size(hashes);
510
+ if (n % 2 != 0) {
511
+ PyObject *last = PyList_GetItem(hashes, n - 1);
512
+ PyList_Append(hashes, last);
513
+ n += 1;
514
+ }
515
+ PyObject *new_hashes = PyList_New(0);
516
+ for (Py_ssize_t i = 0; i < n; i += 2) {
517
+ PyObject *h1 = PyList_GetItem(hashes, i);
518
+ PyObject *h2 = PyList_GetItem(hashes, i + 1);
519
+ PyObject *combined = PyUnicode_Concat(h1, h2);
520
+ if (!combined) { PyErr_Clear(); continue; }
521
+ PyObject *bytes = PyUnicode_AsEncodedString(combined, "utf-8", "strict");
522
+ Py_DECREF(combined);
523
+ if (!bytes) { PyErr_Clear(); continue; }
524
+ PyObject *hex = zx_sha256_hex(bytes);
525
+ Py_DECREF(bytes);
526
+ if (!hex) { PyErr_Clear(); continue; }
527
+ PyList_Append(new_hashes, hex);
528
+ Py_DECREF(hex);
529
+ }
530
+ Py_DECREF(hashes);
531
+ hashes = new_hashes;
532
+ }
533
+ PyObject *result = PyList_Size(hashes) > 0 ? PyList_GetItem(hashes, 0) : PyUnicode_FromString("");
534
+ Py_XINCREF(result);
535
+ Py_DECREF(hashes);
536
+ return result;
537
+ }
538
+
539
+ ZxValue zexus_rt_verify_signature(ZxValue env, ZxValue builtins, ZxValue sig, ZxValue msg, ZxValue pk) {
540
+ PyObject *verify = NULL;
541
+ if (builtins && PyDict_Check(builtins)) verify = PyDict_GetItemString(builtins, "verify_sig");
542
+ if (!verify && env && PyDict_Check(env)) verify = PyDict_GetItemString(env, "verify_sig");
543
+ if (verify && PyCallable_Check(verify)) {
544
+ PyObject *res = PyObject_CallFunctionObjArgs(verify, sig, msg, pk, NULL);
545
+ if (!res) { PyErr_Clear(); Py_RETURN_FALSE; }
546
+ return res;
547
+ }
548
+ PyObject *bytes = zx_to_bytes(msg);
549
+ if (!bytes) { PyErr_Clear(); Py_RETURN_FALSE; }
550
+ PyObject *expected = zx_sha256_hex(bytes);
551
+ Py_DECREF(bytes);
552
+ if (!expected) { PyErr_Clear(); Py_RETURN_FALSE; }
553
+ int eq = PyObject_RichCompareBool(sig, expected, Py_EQ);
554
+ Py_DECREF(expected);
555
+ if (eq < 0) { PyErr_Clear(); Py_RETURN_FALSE; }
556
+ if (eq) Py_RETURN_TRUE; else Py_RETURN_FALSE;
557
+ }
558
+
559
+ ZxValue zexus_rt_state_read(ZxValue env, ZxValue key) {
560
+ PyObject *state = zx_env_get_dict(env, "_blockchain_state", 1);
561
+ if (!state || !PyDict_Check(state) || !key) { Py_RETURN_NONE; }
562
+ PyObject *val = PyDict_GetItem(state, key);
563
+ if (!val) Py_RETURN_NONE;
564
+ Py_INCREF(val);
565
+ return val;
566
+ }
567
+
568
+ ZxValue zexus_rt_state_write(ZxValue env, ZxValue key, ZxValue value) {
569
+ if (!key) { Py_RETURN_NONE; }
570
+ PyObject *in_tx = zx_env_get_bool(env, "_in_transaction");
571
+ int in_transaction = in_tx ? PyObject_IsTrue(in_tx) : 0;
572
+ PyObject *target = in_transaction ? zx_env_get_dict(env, "_tx_pending_state", 1)
573
+ : zx_env_get_dict(env, "_blockchain_state", 1);
574
+ if (target && PyDict_Check(target)) {
575
+ PyDict_SetItem(target, key, value ? value : Py_None);
576
+ }
577
+ Py_RETURN_NONE;
578
+ }
579
+
580
+ ZxValue zexus_rt_tx_begin(ZxValue env) {
581
+ if (!env || !PyDict_Check(env)) { Py_RETURN_NONE; }
582
+ zx_env_set(env, "_in_transaction", Py_True);
583
+ PyObject *pending = PyDict_New();
584
+ if (pending) {
585
+ zx_env_set(env, "_tx_pending_state", pending);
586
+ Py_DECREF(pending);
587
+ }
588
+ PyObject *state = zx_env_get_dict(env, "_blockchain_state", 1);
589
+ if (state) {
590
+ PyObject *snapshot = PyDict_Copy(state);
591
+ if (snapshot) {
592
+ zx_env_set(env, "_tx_snapshot", snapshot);
593
+ Py_DECREF(snapshot);
594
+ }
595
+ }
596
+ Py_RETURN_NONE;
597
+ }
598
+
599
+ ZxValue zexus_rt_tx_commit(ZxValue env) {
600
+ if (!env || !PyDict_Check(env)) { Py_RETURN_NONE; }
601
+ PyObject *in_tx = zx_env_get_bool(env, "_in_transaction");
602
+ int in_transaction = in_tx ? PyObject_IsTrue(in_tx) : 0;
603
+ if (!in_transaction) { Py_RETURN_NONE; }
604
+ PyObject *state = zx_env_get_dict(env, "_blockchain_state", 1);
605
+ PyObject *pending = zx_env_get_dict(env, "_tx_pending_state", 0);
606
+ if (state && pending && PyDict_Check(state) && PyDict_Check(pending)) {
607
+ PyDict_Update(state, pending);
608
+ }
609
+ zx_env_set(env, "_in_transaction", Py_False);
610
+ PyObject *empty = PyDict_New();
611
+ if (empty) {
612
+ zx_env_set(env, "_tx_pending_state", empty);
613
+ Py_DECREF(empty);
614
+ }
615
+ Py_RETURN_NONE;
616
+ }
617
+
618
+ ZxValue zexus_rt_tx_revert(ZxValue env) {
619
+ if (!env || !PyDict_Check(env)) { Py_RETURN_NONE; }
620
+ PyObject *in_tx = zx_env_get_bool(env, "_in_transaction");
621
+ int in_transaction = in_tx ? PyObject_IsTrue(in_tx) : 0;
622
+ if (!in_transaction) { Py_RETURN_NONE; }
623
+ PyObject *snapshot = zx_env_get_dict(env, "_tx_snapshot", 0);
624
+ if (snapshot && PyDict_Check(snapshot)) {
625
+ zx_env_set(env, "_blockchain_state", snapshot);
626
+ }
627
+ zx_env_set(env, "_in_transaction", Py_False);
628
+ PyObject *empty = PyDict_New();
629
+ if (empty) {
630
+ zx_env_set(env, "_tx_pending_state", empty);
631
+ Py_DECREF(empty);
632
+ }
633
+ Py_RETURN_NONE;
634
+ }
635
+
636
+ ZxValue zexus_rt_gas_charge(ZxValue env, ZxValue amount) {
637
+ if (!env || !PyDict_Check(env)) return NULL;
638
+ PyObject *k = PyUnicode_FromString("_gas_remaining");
639
+ if (!k) return NULL;
640
+ PyObject *cur = PyDict_GetItem(env, k);
641
+ Py_DECREF(k);
642
+ if (!cur) return NULL;
643
+ if (!PyFloat_Check(cur) && !PyLong_Check(cur)) return NULL;
644
+ if (PyFloat_Check(cur) && PyFloat_AsDouble(cur) == Py_HUGE_VAL) return NULL;
645
+ PyObject *zero = PyLong_FromLong(0);
646
+ PyObject *subtrahend = amount ? amount : zero;
647
+ PyObject *new_gas = PyNumber_Subtract(cur, subtrahend);
648
+ Py_DECREF(zero);
649
+ if (!new_gas) { PyErr_Clear(); return NULL; }
650
+ PyObject *cmp_zero = PyLong_FromLong(0);
651
+ int neg = PyObject_RichCompareBool(new_gas, cmp_zero, Py_LT);
652
+ Py_DECREF(cmp_zero);
653
+ if (neg) {
654
+ Py_DECREF(new_gas);
655
+ PyObject *in_tx = zx_env_get_bool(env, "_in_transaction");
656
+ int in_transaction = in_tx ? PyObject_IsTrue(in_tx) : 0;
657
+ if (in_transaction) {
658
+ PyObject *snapshot = zx_env_get_dict(env, "_tx_snapshot", 0);
659
+ if (snapshot && PyDict_Check(snapshot)) {
660
+ zx_env_set(env, "_blockchain_state", snapshot);
661
+ }
662
+ zx_env_set(env, "_in_transaction", Py_False);
663
+ }
664
+ PyObject *err = PyDict_New();
665
+ if (!err) return NULL;
666
+ PyDict_SetItemString(err, "error", PyUnicode_FromString("OutOfGas"));
667
+ if (amount) {
668
+ PyDict_SetItemString(err, "required", amount);
669
+ } else {
670
+ PyObject *zero_req = PyLong_FromLong(0);
671
+ if (zero_req) {
672
+ PyDict_SetItemString(err, "required", zero_req);
673
+ Py_DECREF(zero_req);
674
+ }
675
+ }
676
+ PyDict_SetItemString(err, "remaining", cur);
677
+ return err;
678
+ }
679
+ PyObject *gas_key = PyUnicode_FromString("_gas_remaining");
680
+ if (gas_key) {
681
+ PyDict_SetItem(env, gas_key, new_gas);
682
+ Py_DECREF(gas_key);
683
+ }
684
+ Py_DECREF(new_gas);
685
+ return NULL;
686
+ }
687
+
688
+ ZxValue zexus_rt_require(ZxValue env, ZxValue condition, ZxValue message) {
689
+ int ok = condition ? PyObject_IsTrue(condition) : 0;
690
+ if (ok > 0) {
691
+ return NULL;
692
+ }
693
+ if (ok < 0) {
694
+ PyErr_Clear();
695
+ }
696
+
697
+ if (env && PyDict_Check(env)) {
698
+ PyObject *in_tx = zx_env_get_bool(env, "_in_transaction");
699
+ int in_transaction = in_tx ? PyObject_IsTrue(in_tx) : 0;
700
+ if (in_transaction) {
701
+ PyObject *snapshot = zx_env_get_dict(env, "_tx_snapshot", 0);
702
+ if (snapshot && PyDict_Check(snapshot)) {
703
+ zx_env_set(env, "_blockchain_state", snapshot);
704
+ }
705
+ zx_env_set(env, "_in_transaction", Py_False);
706
+ PyObject *empty = PyDict_New();
707
+ if (empty) {
708
+ zx_env_set(env, "_tx_pending_state", empty);
709
+ Py_DECREF(empty);
710
+ }
711
+ }
712
+ }
713
+
714
+ PyObject *err = PyDict_New();
715
+ if (!err) return NULL;
716
+ PyDict_SetItemString(err, "error", PyUnicode_FromString("RequirementFailed"));
717
+ PyObject *msg_obj = message && message != Py_None ? PyObject_Str(message) : PyUnicode_FromString("Requirement failed");
718
+ if (msg_obj) {
719
+ PyDict_SetItemString(err, "message", msg_obj);
720
+ Py_DECREF(msg_obj);
721
+ }
722
+ return err;
723
+ }
724
+
725
+ ZxValue zexus_rt_ledger_append(ZxValue env, ZxValue entry) {
726
+ PyObject *ledger = zx_env_get_list(env, "_ledger", 1);
727
+ if (!ledger || !PyList_Check(ledger)) { Py_RETURN_NONE; }
728
+ if (entry && PyDict_Check(entry)) {
729
+ PyObject *ts_key = PyUnicode_FromString("timestamp");
730
+ int has_ts = ts_key ? PyDict_Contains(entry, ts_key) : 0;
731
+ Py_XDECREF(ts_key);
732
+ if (!has_ts) {
733
+ PyObject *time_mod = PyImport_ImportModule("time");
734
+ if (time_mod) {
735
+ PyObject *time_fn = PyObject_GetAttrString(time_mod, "time");
736
+ Py_DECREF(time_mod);
737
+ if (time_fn) {
738
+ PyObject *ts = PyObject_CallObject(time_fn, NULL);
739
+ Py_DECREF(time_fn);
740
+ if (ts) {
741
+ PyDict_SetItemString(entry, "timestamp", ts);
742
+ Py_DECREF(ts);
743
+ }
744
+ }
745
+ }
746
+ }
747
+ }
748
+ PyList_Append(ledger, entry ? entry : Py_None);
749
+ Py_RETURN_NONE;
750
+ }
751
+
752
+ ZxValue zexus_rt_register_event(ZxValue vm, ZxValue name, ZxValue handler) {
753
+ if (!vm || !name) { Py_RETURN_NONE; }
754
+ PyObject *events = zx_get_attr(vm, "_events");
755
+ if (!events || !PyDict_Check(events)) { Py_XDECREF(events); Py_RETURN_NONE; }
756
+ PyObject *lst = PyDict_GetItem(events, name);
757
+ if (!lst) {
758
+ lst = PyList_New(0);
759
+ if (lst) {
760
+ PyDict_SetItem(events, name, lst);
761
+ Py_DECREF(lst);
762
+ }
763
+ }
764
+ if (handler && handler != Py_None && lst && PyList_Check(lst)) {
765
+ int contains = PySequence_Contains(lst, handler);
766
+ if (contains == 0) PyList_Append(lst, handler);
767
+ }
768
+ Py_DECREF(events);
769
+ Py_RETURN_NONE;
770
+ }
771
+
772
+ ZxValue zexus_rt_emit_event(ZxValue vm, ZxValue env, ZxValue builtins, ZxValue name, ZxValue payload) {
773
+ if (!vm || !name) { Py_RETURN_NONE; }
774
+ PyObject *events = zx_get_attr(vm, "_events");
775
+ if (!events || !PyDict_Check(events)) { Py_XDECREF(events); Py_RETURN_NONE; }
776
+ PyObject *handlers = PyDict_GetItem(events, name);
777
+ if (!handlers || !PyList_Check(handlers)) { Py_DECREF(events); Py_RETURN_NONE; }
778
+ PyObject *builtins_dict = builtins;
779
+ PyObject *env_dict = env;
780
+ Py_ssize_t n = PyList_Size(handlers);
781
+ for (Py_ssize_t i = 0; i < n; i++) {
782
+ PyObject *h = PyList_GetItem(handlers, i);
783
+ PyObject *fn = NULL;
784
+ if (h && PyUnicode_Check(h)) {
785
+ if (builtins_dict && PyDict_Check(builtins_dict)) fn = PyDict_GetItem(builtins_dict, h);
786
+ if (!fn && env_dict && PyDict_Check(env_dict)) fn = PyDict_GetItem(env_dict, h);
787
+ } else {
788
+ fn = h;
789
+ }
790
+ if (!fn) continue;
791
+ PyObject *args_list = PyList_New(1);
792
+ if (!args_list) continue;
793
+ PyObject *payload_obj = payload ? payload : Py_None;
794
+ Py_INCREF(payload_obj);
795
+ PyList_SetItem(args_list, 0, payload_obj);
796
+ PyObject *res = PyObject_CallMethod(vm, "_call_builtin_async_obj", "OOO", fn, args_list, Py_False);
797
+ Py_DECREF(args_list);
798
+ if (!res) { PyErr_Clear(); continue; }
799
+ if (zx_is_awaitable(res)) {
800
+ PyObject *awaited = PyObject_CallMethod(vm, "_run_coroutine_sync", "O", res);
801
+ Py_XDECREF(awaited);
802
+ }
803
+ Py_DECREF(res);
804
+ }
805
+ Py_DECREF(events);
806
+ Py_RETURN_NONE;
807
+ }
808
+
809
+ static PyObject *zx_spawn_task(PyObject *vm, PyObject *coro) {
810
+ if (!vm || !coro) return NULL;
811
+ PyObject *asyncio = PyImport_ImportModule("asyncio");
812
+ PyObject *task = NULL;
813
+ if (asyncio) {
814
+ PyObject *loop = PyObject_CallMethod(asyncio, "get_running_loop", NULL);
815
+ if (!loop) {
816
+ PyErr_Clear();
817
+ } else {
818
+ task = PyObject_CallMethod(loop, "create_task", "O", coro);
819
+ Py_DECREF(loop);
820
+ }
821
+ Py_DECREF(asyncio);
822
+ }
823
+ if (!task) {
824
+ PyObject *res = PyObject_CallMethod(vm, "_run_coroutine_sync", "O", coro);
825
+ task = res ? res : Py_None;
826
+ Py_XINCREF(task);
827
+ }
828
+ PyObject *tasks = zx_get_attr(vm, "_tasks");
829
+ PyObject *counter = zx_get_attr(vm, "_task_counter");
830
+ long next_id = 1;
831
+ if (counter && PyLong_Check(counter)) {
832
+ next_id = PyLong_AsLong(counter) + 1;
833
+ }
834
+ PyObject *new_counter = PyLong_FromLong(next_id);
835
+ if (new_counter) {
836
+ PyObject_SetAttrString(vm, "_task_counter", new_counter);
837
+ Py_DECREF(new_counter);
838
+ }
839
+ if (tasks && PyDict_Check(tasks)) {
840
+ PyObject *tid = PyUnicode_FromFormat("task_%ld", next_id);
841
+ if (tid) {
842
+ PyDict_SetItem(tasks, tid, task);
843
+ Py_DECREF(task);
844
+ Py_DECREF(tasks);
845
+ return tid;
846
+ }
847
+ }
848
+ Py_XDECREF(tasks);
849
+ Py_XDECREF(task);
850
+ Py_RETURN_NONE;
851
+ }
852
+
853
+ ZxValue zexus_rt_spawn_name(ZxValue vm, ZxValue env, ZxValue builtins, ZxValue name, ZxValue args_tuple) {
854
+ if (!vm || !name) { Py_RETURN_NONE; }
855
+ PyObject *callable = NULL;
856
+ if (env && PyDict_Check(env)) callable = PyDict_GetItem(env, name);
857
+ if (!callable && builtins && PyDict_Check(builtins)) callable = PyDict_GetItem(builtins, name);
858
+ if (!callable) { Py_RETURN_NONE; }
859
+ PyObject *empty = NULL;
860
+ PyObject *args_source = args_tuple ? args_tuple : (empty = PyTuple_New(0));
861
+ PyObject *args_list = PySequence_List(args_source);
862
+ Py_XDECREF(empty);
863
+ if (!args_list) { PyErr_Clear(); Py_RETURN_NONE; }
864
+ PyObject *coro = PyObject_CallMethod(vm, "_to_coro", "OO", callable, args_list);
865
+ Py_DECREF(args_list);
866
+ if (!coro) { PyErr_Clear(); Py_RETURN_NONE; }
867
+ PyObject *tid = zx_spawn_task(vm, coro);
868
+ Py_DECREF(coro);
869
+ return tid ? tid : Py_None;
870
+ }
871
+
872
+ ZxValue zexus_rt_spawn_call(ZxValue vm, ZxValue callable, ZxValue args_tuple) {
873
+ if (!vm || !callable) { Py_RETURN_NONE; }
874
+ PyObject *empty = NULL;
875
+ PyObject *args_source = args_tuple ? args_tuple : (empty = PyTuple_New(0));
876
+ PyObject *args_list = PySequence_List(args_source);
877
+ Py_XDECREF(empty);
878
+ if (!args_list) { PyErr_Clear(); Py_RETURN_NONE; }
879
+ PyObject *coro = PyObject_CallMethod(vm, "_to_coro", "OO", callable, args_list);
880
+ Py_DECREF(args_list);
881
+ if (!coro) { PyErr_Clear(); Py_RETURN_NONE; }
882
+ PyObject *tid = zx_spawn_task(vm, coro);
883
+ Py_DECREF(coro);
884
+ return tid ? tid : Py_None;
885
+ }
886
+
887
+ ZxValue zexus_rt_await(ZxValue vm, ZxValue task_or_coro) {
888
+ if (!vm || !task_or_coro) { Py_RETURN_NONE; }
889
+ PyObject *tasks = zx_get_attr(vm, "_tasks");
890
+ if (tasks && PyDict_Check(tasks) && PyUnicode_Check(task_or_coro)) {
891
+ PyObject *obj = PyDict_GetItem(tasks, task_or_coro);
892
+ if (obj) {
893
+ if (zx_is_awaitable(obj)) {
894
+ PyObject *res = PyObject_CallMethod(vm, "_run_coroutine_sync", "O", obj);
895
+ Py_DECREF(tasks);
896
+ return res ? res : Py_None;
897
+ }
898
+ Py_INCREF(obj);
899
+ Py_DECREF(tasks);
900
+ return obj;
901
+ }
902
+ }
903
+ Py_XDECREF(tasks);
904
+ if (zx_is_awaitable(task_or_coro)) {
905
+ PyObject *res = PyObject_CallMethod(vm, "_run_coroutine_sync", "O", task_or_coro);
906
+ return res ? res : Py_None;
907
+ }
908
+ Py_INCREF(task_or_coro);
909
+ return task_or_coro;
910
+ }
911
+
912
+ static PyObject *zx_get_or_create_lock(PyObject *env, PyObject *key) {
913
+ if (!env || !PyDict_Check(env) || !key) return NULL;
914
+ PyObject *locks = zx_env_get_dict(env, "_locks", 1);
915
+ if (!locks || !PyDict_Check(locks)) return NULL;
916
+ PyObject *lock = PyDict_GetItem(locks, key);
917
+ if (lock) return lock;
918
+
919
+ PyObject *threading = PyImport_ImportModule("threading");
920
+ if (!threading) { PyErr_Clear(); return NULL; }
921
+ PyObject *lock_cls = PyObject_GetAttrString(threading, "Lock");
922
+ Py_DECREF(threading);
923
+ if (!lock_cls) { PyErr_Clear(); return NULL; }
924
+ PyObject *new_lock = PyObject_CallObject(lock_cls, NULL);
925
+ Py_DECREF(lock_cls);
926
+ if (!new_lock) { PyErr_Clear(); return NULL; }
927
+ PyDict_SetItem(locks, key, new_lock);
928
+ Py_DECREF(new_lock);
929
+ return PyDict_GetItem(locks, key);
930
+ }
931
+
932
+ ZxValue zexus_rt_lock_acquire(ZxValue env, ZxValue key) {
933
+ if (!env || !key) { Py_RETURN_NONE; }
934
+ PyObject *lock = zx_get_or_create_lock(env, key);
935
+ if (!lock) { Py_RETURN_NONE; }
936
+ PyObject *res = PyObject_CallMethod(lock, "acquire", NULL);
937
+ if (!res) { PyErr_Clear(); Py_RETURN_NONE; }
938
+ Py_DECREF(res);
939
+ Py_RETURN_NONE;
940
+ }
941
+
942
+ ZxValue zexus_rt_lock_release(ZxValue env, ZxValue key) {
943
+ if (!env || !key) { Py_RETURN_NONE; }
944
+ PyObject *lock = zx_get_or_create_lock(env, key);
945
+ if (!lock) { Py_RETURN_NONE; }
946
+ PyObject *res = PyObject_CallMethod(lock, "release", NULL);
947
+ if (!res) { PyErr_Clear(); Py_RETURN_NONE; }
948
+ Py_DECREF(res);
949
+ Py_RETURN_NONE;
950
+ }
951
+
952
+ ZxValue zexus_rt_barrier_wait(ZxValue barrier, ZxValue timeout) {
953
+ if (!barrier) { Py_RETURN_NONE; }
954
+ PyObject *res = NULL;
955
+ if (timeout && timeout != Py_None) {
956
+ res = PyObject_CallMethod(barrier, "wait", "O", timeout);
957
+ } else {
958
+ res = PyObject_CallMethod(barrier, "wait", NULL);
959
+ }
960
+ if (!res) { PyErr_Clear(); Py_RETURN_NONE; }
961
+ return res;
962
+ }
963
+
964
+ static PyObject *zx_get_or_create_atomic_lock(PyObject *env) {
965
+ if (!env || !PyDict_Check(env)) return NULL;
966
+ PyObject *lock = PyDict_GetItemString(env, "_atomic_lock");
967
+ if (lock) return lock;
968
+ PyObject *threading = PyImport_ImportModule("threading");
969
+ if (!threading) { PyErr_Clear(); return NULL; }
970
+ PyObject *lock_cls = PyObject_GetAttrString(threading, "Lock");
971
+ Py_DECREF(threading);
972
+ if (!lock_cls) { PyErr_Clear(); return NULL; }
973
+ PyObject *new_lock = PyObject_CallObject(lock_cls, NULL);
974
+ Py_DECREF(lock_cls);
975
+ if (!new_lock) { PyErr_Clear(); return NULL; }
976
+ PyDict_SetItemString(env, "_atomic_lock", new_lock);
977
+ Py_DECREF(new_lock);
978
+ return PyDict_GetItemString(env, "_atomic_lock");
979
+ }
980
+
981
+ ZxValue zexus_rt_atomic_add(ZxValue env, ZxValue key, ZxValue delta) {
982
+ if (!env || !PyDict_Check(env) || !key) { Py_RETURN_NONE; }
983
+ PyObject *lock = zx_get_or_create_atomic_lock(env);
984
+ if (!lock) { Py_RETURN_NONE; }
985
+ PyObject *acq = PyObject_CallMethod(lock, "acquire", NULL);
986
+ Py_XDECREF(acq);
987
+ PyObject *state = zx_env_get_dict(env, "_atomic_state", 1);
988
+ PyObject *current = state ? PyDict_GetItem(state, key) : NULL;
989
+ if (!current) current = PyLong_FromLong(0);
990
+ else Py_INCREF(current);
991
+ PyObject *delta_val = delta ? delta : PyLong_FromLong(0);
992
+ if (!delta) Py_DECREF(delta_val);
993
+ PyObject *new_val = PyNumber_Add(current, delta_val);
994
+ if (new_val && state) {
995
+ PyDict_SetItem(state, key, new_val);
996
+ }
997
+ Py_DECREF(current);
998
+ PyObject *rel = PyObject_CallMethod(lock, "release", NULL);
999
+ Py_XDECREF(rel);
1000
+ if (!new_val) { PyErr_Clear(); Py_RETURN_NONE; }
1001
+ return new_val;
1002
+ }
1003
+
1004
+ ZxValue zexus_rt_atomic_cas(ZxValue env, ZxValue key, ZxValue expected, ZxValue new_value) {
1005
+ if (!env || !PyDict_Check(env) || !key) { Py_RETURN_FALSE; }
1006
+ PyObject *lock = zx_get_or_create_atomic_lock(env);
1007
+ if (!lock) { Py_RETURN_FALSE; }
1008
+ PyObject *acq = PyObject_CallMethod(lock, "acquire", NULL);
1009
+ Py_XDECREF(acq);
1010
+ PyObject *state = zx_env_get_dict(env, "_atomic_state", 1);
1011
+ PyObject *current = state ? PyDict_GetItem(state, key) : NULL;
1012
+ int eq = PyObject_RichCompareBool(current ? current : Py_None, expected ? expected : Py_None, Py_EQ);
1013
+ if (eq > 0 && state) {
1014
+ PyDict_SetItem(state, key, new_value ? new_value : Py_None);
1015
+ }
1016
+ PyObject *rel = PyObject_CallMethod(lock, "release", NULL);
1017
+ Py_XDECREF(rel);
1018
+ if (eq < 0) { PyErr_Clear(); Py_RETURN_FALSE; }
1019
+ if (eq) Py_RETURN_TRUE; else Py_RETURN_FALSE;
1020
+ }
1021
+
1022
+ ZxValue zexus_rt_get_iter(ZxValue obj) {
1023
+ if (!obj) { Py_RETURN_NONE; }
1024
+ PyObject *iter = PyObject_GetIter(obj);
1025
+ if (!iter) { PyErr_Clear(); Py_RETURN_NONE; }
1026
+ return iter;
1027
+ }
1028
+
1029
+ ZxValue zexus_rt_iter_next_pair(ZxValue iterator) {
1030
+ if (!iterator) { Py_RETURN_NONE; }
1031
+ PyObject *value = PyIter_Next(iterator);
1032
+ if (!value) {
1033
+ if (PyErr_Occurred()) { PyErr_Clear(); }
1034
+ PyObject *none = Py_None; Py_INCREF(none);
1035
+ PyObject *flag = Py_False; Py_INCREF(flag);
1036
+ PyObject *tpl = PyTuple_Pack(2, none, flag);
1037
+ Py_DECREF(none); Py_DECREF(flag);
1038
+ return tpl ? tpl : Py_None;
1039
+ }
1040
+ PyObject *flag = Py_True; Py_INCREF(flag);
1041
+ PyObject *tpl = PyTuple_Pack(2, value, flag);
1042
+ Py_DECREF(value);
1043
+ Py_DECREF(flag);
1044
+ return tpl ? tpl : Py_None;
1045
+ }
1046
+
1047
+ ZxValue zexus_rt_define_enum(ZxValue env, ZxValue name, ZxValue spec) {
1048
+ if (!env || !PyDict_Check(env) || !name) { Py_RETURN_NONE; }
1049
+ PyObject *enums = zx_env_get_dict(env, "enums", 1);
1050
+ if (enums && PyDict_Check(enums)) {
1051
+ PyDict_SetItem(enums, name, spec ? spec : Py_None);
1052
+ }
1053
+ PyDict_SetItem(env, name, spec ? spec : Py_None);
1054
+ Py_RETURN_NONE;
1055
+ }
1056
+
1057
+ ZxValue zexus_rt_define_protocol(ZxValue env, ZxValue name, ZxValue spec) {
1058
+ if (!env || !PyDict_Check(env) || !name) { Py_RETURN_NONE; }
1059
+ PyObject *protocols = zx_env_get_dict(env, "protocols", 1);
1060
+ if (protocols && PyDict_Check(protocols)) {
1061
+ PyDict_SetItem(protocols, name, spec ? spec : Py_None);
1062
+ }
1063
+ PyDict_SetItem(env, name, spec ? spec : Py_None);
1064
+ Py_RETURN_NONE;
1065
+ }
1066
+
1067
+ ZxValue zexus_rt_assert_protocol(ZxValue env, ZxValue name, ZxValue spec) {
1068
+ if (!env || !PyDict_Check(env) || !name || !spec) {
1069
+ PyObject *empty = PyList_New(0);
1070
+ return PyTuple_Pack(2, Py_False, empty ? empty : PyList_New(0));
1071
+ }
1072
+ PyObject *obj = PyDict_GetItem(env, name);
1073
+ PyObject *methods = PyDict_GetItemString(spec, "methods");
1074
+ PyObject *missing = PyList_New(0);
1075
+ int ok = 1;
1076
+ if (methods && PySequence_Check(methods)) {
1077
+ Py_ssize_t n = PySequence_Size(methods);
1078
+ for (Py_ssize_t i = 0; i < n; i++) {
1079
+ PyObject *m = PySequence_GetItem(methods, i);
1080
+ if (!m) { PyErr_Clear(); continue; }
1081
+ int has = obj ? PyObject_HasAttr(obj, m) : 0;
1082
+ if (has <= 0) {
1083
+ ok = 0;
1084
+ PyList_Append(missing, m);
1085
+ }
1086
+ Py_DECREF(m);
1087
+ }
1088
+ }
1089
+ PyObject *ok_obj = ok ? Py_True : Py_False;
1090
+ Py_INCREF(ok_obj);
1091
+ PyObject *result = PyTuple_Pack(2, ok_obj, missing ? missing : PyList_New(0));
1092
+ Py_DECREF(ok_obj);
1093
+ Py_XDECREF(missing);
1094
+ return result;
1095
+ }
1096
+
1097
+ ZxValue zexus_rt_define_capability(ZxValue env, ZxValue name, ZxValue definition) {
1098
+ if (!env || !PyDict_Check(env) || !name) { Py_RETURN_NONE; }
1099
+ PyObject *caps = zx_env_get_dict(env, "_capabilities", 1);
1100
+ PyObject *key = zx_unwrap_value(name);
1101
+ if (caps && PyDict_Check(caps)) {
1102
+ PyDict_SetItem(caps, key, definition ? definition : Py_None);
1103
+ }
1104
+ Py_DECREF(key);
1105
+ Py_RETURN_NONE;
1106
+ }
1107
+
1108
+ static PyObject *zx_to_string_key(PyObject *obj);
1109
+
1110
+ ZxValue zexus_rt_define_screen(ZxValue env, ZxValue name, ZxValue props) {
1111
+ if (!env || !PyDict_Check(env)) { Py_RETURN_NONE; }
1112
+ PyObject *screens = zx_env_get_dict(env, "screens", 1);
1113
+ if (!screens || !PyDict_Check(screens)) { Py_RETURN_NONE; }
1114
+ PyObject *key = zx_to_string_key(name ? name : Py_None);
1115
+ PyDict_SetItem(screens, key, props ? props : Py_None);
1116
+ Py_DECREF(key);
1117
+ Py_RETURN_NONE;
1118
+ }
1119
+
1120
+ ZxValue zexus_rt_define_component(ZxValue env, ZxValue name, ZxValue props) {
1121
+ if (!env || !PyDict_Check(env)) { Py_RETURN_NONE; }
1122
+ PyObject *components = zx_env_get_dict(env, "components", 1);
1123
+ if (!components || !PyDict_Check(components)) { Py_RETURN_NONE; }
1124
+ PyObject *key = zx_to_string_key(name ? name : Py_None);
1125
+ PyDict_SetItem(components, key, props ? props : Py_None);
1126
+ Py_DECREF(key);
1127
+ Py_RETURN_NONE;
1128
+ }
1129
+
1130
+ ZxValue zexus_rt_define_theme(ZxValue env, ZxValue name, ZxValue props) {
1131
+ if (!env || !PyDict_Check(env)) { Py_RETURN_NONE; }
1132
+ PyObject *themes = zx_env_get_dict(env, "themes", 1);
1133
+ if (!themes || !PyDict_Check(themes)) { Py_RETURN_NONE; }
1134
+ PyObject *key = zx_to_string_key(name ? name : Py_None);
1135
+ PyDict_SetItem(themes, key, props ? props : Py_None);
1136
+ Py_DECREF(key);
1137
+ Py_RETURN_NONE;
1138
+ }
1139
+
1140
+ static PyObject *zx_get_or_create_set(PyObject *mapping, PyObject *key) {
1141
+ if (!mapping || !PyDict_Check(mapping) || !key) return NULL;
1142
+ PyObject *val = PyDict_GetItem(mapping, key);
1143
+ if (val && PySet_Check(val)) {
1144
+ return val;
1145
+ }
1146
+ PyObject *set_obj = PySet_New(NULL);
1147
+ if (!set_obj) return NULL;
1148
+ PyDict_SetItem(mapping, key, set_obj);
1149
+ Py_DECREF(set_obj);
1150
+ return PyDict_GetItem(mapping, key);
1151
+ }
1152
+
1153
+ static PyObject *zx_to_string_key(PyObject *obj) {
1154
+ PyObject *val = zx_unwrap_value(obj);
1155
+ PyObject *s = PyObject_Str(val);
1156
+ Py_DECREF(val);
1157
+ if (!s) { PyErr_Clear(); return PyUnicode_FromString(""); }
1158
+ return s;
1159
+ }
1160
+
1161
+ ZxValue zexus_rt_grant_capability(ZxValue env, ZxValue entity, ZxValue *caps, Py_ssize_t count) {
1162
+ if (!env || !PyDict_Check(env) || !entity) { Py_RETURN_NONE; }
1163
+ PyObject *grants = zx_env_get_dict(env, "_grants", 1);
1164
+ PyObject *entity_key = zx_to_string_key(entity);
1165
+ PyObject *entity_grants = zx_get_or_create_set(grants, entity_key);
1166
+ Py_DECREF(entity_key);
1167
+ if (entity_grants && PySet_Check(entity_grants)) {
1168
+ for (Py_ssize_t i = 0; i < count; i++) {
1169
+ PyObject *cap_key = zx_to_string_key(caps[i] ? caps[i] : Py_None);
1170
+ PySet_Add(entity_grants, cap_key);
1171
+ Py_DECREF(cap_key);
1172
+ }
1173
+ }
1174
+ Py_RETURN_NONE;
1175
+ }
1176
+
1177
+ ZxValue zexus_rt_revoke_capability(ZxValue env, ZxValue entity, ZxValue *caps, Py_ssize_t count) {
1178
+ if (!env || !PyDict_Check(env) || !entity) { Py_RETURN_NONE; }
1179
+ PyObject *grants = zx_env_get_dict(env, "_grants", 0);
1180
+ PyObject *entity_key = zx_to_string_key(entity);
1181
+ PyObject *entity_grants = grants ? PyDict_GetItem(grants, entity_key) : NULL;
1182
+ Py_DECREF(entity_key);
1183
+ if (entity_grants && PySet_Check(entity_grants)) {
1184
+ for (Py_ssize_t i = 0; i < count; i++) {
1185
+ PyObject *cap_key = zx_to_string_key(caps[i] ? caps[i] : Py_None);
1186
+ PySet_Discard(entity_grants, cap_key);
1187
+ Py_DECREF(cap_key);
1188
+ }
1189
+ }
1190
+ Py_RETURN_NONE;
1191
+ }
1192
+
1193
+ ZxValue zexus_rt_audit_log(ZxValue env, ZxValue ts, ZxValue action, ZxValue data) {
1194
+ if (!env || !PyDict_Check(env)) { Py_RETURN_NONE; }
1195
+ PyObject *log_list = zx_env_get_list(env, "_audit_log", 1);
1196
+ if (!log_list || !PyList_Check(log_list)) { Py_RETURN_NONE; }
1197
+ PyObject *ts_val = zx_unwrap_value(ts ? ts : Py_None);
1198
+ PyObject *action_val = zx_unwrap_value(action ? action : Py_None);
1199
+ PyObject *data_val = zx_unwrap_value(data ? data : Py_None);
1200
+ PyObject *entry = PyDict_New();
1201
+ if (entry) {
1202
+ PyDict_SetItemString(entry, "timestamp", ts_val);
1203
+ PyDict_SetItemString(entry, "action", action_val);
1204
+ PyDict_SetItemString(entry, "data", data_val);
1205
+ PyList_Append(log_list, entry);
1206
+ Py_DECREF(entry);
1207
+ }
1208
+ Py_DECREF(ts_val);
1209
+ Py_DECREF(action_val);
1210
+ Py_DECREF(data_val);
1211
+ Py_RETURN_NONE;
1212
+ }
1213
+
1214
+ ZxValue zexus_rt_define_contract(ZxValue *items, Py_ssize_t count, ZxValue name) {
1215
+ PyObject *members = PyDict_New();
1216
+ if (!members) { Py_RETURN_NONE; }
1217
+ Py_ssize_t total = count * 2;
1218
+ for (Py_ssize_t i = 0; i < count; i++) {
1219
+ Py_ssize_t key_index = total - 1 - (i * 2);
1220
+ Py_ssize_t val_index = total - 2 - (i * 2);
1221
+ PyObject *key_obj = (key_index >= 0 && key_index < total) ? items[key_index] : Py_None;
1222
+ PyObject *val_obj = (val_index >= 0 && val_index < total) ? items[val_index] : Py_None;
1223
+ PyObject *key_val = zx_unwrap_value(key_obj ? key_obj : Py_None);
1224
+ PyObject *key_str = PyObject_Str(key_val);
1225
+ Py_DECREF(key_val);
1226
+ if (key_str) {
1227
+ PyDict_SetItem(members, key_str, val_obj ? val_obj : Py_None);
1228
+ Py_DECREF(key_str);
1229
+ } else {
1230
+ PyErr_Clear();
1231
+ }
1232
+ }
1233
+ return members;
1234
+ }
1235
+
1236
+ ZxValue zexus_rt_define_entity(ZxValue *items, Py_ssize_t count, ZxValue name) {
1237
+ PyObject *members = zexus_rt_define_contract(items, count, name);
1238
+ if (!members || !PyDict_Check(members)) {
1239
+ return members ? members : Py_None;
1240
+ }
1241
+ PyObject *name_val = zx_unwrap_value(name ? name : Py_None);
1242
+ PyObject *name_str = PyObject_Str(name_val);
1243
+ Py_DECREF(name_val);
1244
+ if (!name_str) { PyErr_Clear(); name_str = PyUnicode_FromString(""); }
1245
+ PyDict_SetItemString(members, "_type", PyUnicode_FromString("entity"));
1246
+ PyDict_SetItemString(members, "_name", name_str);
1247
+ Py_DECREF(name_str);
1248
+ return members;
1249
+ }
1250
+
1251
+ ZxValue zexus_rt_restrict_access(ZxValue env, ZxValue obj, ZxValue prop, ZxValue restriction) {
1252
+ if (!env || !PyDict_Check(env)) { Py_RETURN_NONE; }
1253
+ PyObject *restrictions = zx_env_get_dict(env, "_restrictions", 1);
1254
+ if (!restrictions || !PyDict_Check(restrictions)) { Py_RETURN_NONE; }
1255
+ PyObject *obj_str = zx_to_string_key(obj ? obj : Py_None);
1256
+ PyObject *prop_str = prop ? zx_to_string_key(prop) : NULL;
1257
+ PyObject *key = NULL;
1258
+ if (prop_str && PyUnicode_GetLength(prop_str) > 0) {
1259
+ PyObject *dot = PyUnicode_FromString(".");
1260
+ PyObject *tmp = PyUnicode_Concat(obj_str, dot);
1261
+ Py_DECREF(dot);
1262
+ if (tmp) {
1263
+ key = PyUnicode_Concat(tmp, prop_str);
1264
+ Py_DECREF(tmp);
1265
+ }
1266
+ } else {
1267
+ key = obj_str;
1268
+ Py_INCREF(key);
1269
+ }
1270
+ if (key) {
1271
+ PyDict_SetItem(restrictions, key, restriction ? restriction : Py_None);
1272
+ Py_DECREF(key);
1273
+ }
1274
+ Py_DECREF(obj_str);
1275
+ Py_XDECREF(prop_str);
1276
+ Py_RETURN_NONE;
1277
+ }
1278
+
1279
+ ZxValue zexus_rt_enable_error_mode(ZxValue env) {
1280
+ if (!env || !PyDict_Check(env)) { Py_RETURN_NONE; }
1281
+ zx_env_set(env, "_continue_on_error", Py_True);
1282
+ Py_RETURN_NONE;
1283
+ }
1284
+
1285
+ } // extern "C"
1286
+
1287
+ static PyObject *native_get_symbols(PyObject *self, PyObject *args) {
1288
+ PyObject *symbols = PyDict_New();
1289
+ if (!symbols) return NULL;
1290
+ PyDict_SetItemString(symbols, "zexus_call_callable", PyLong_FromVoidPtr((void *)&zexus_rt_call_callable));
1291
+ PyDict_SetItemString(symbols, "zexus_call_method", PyLong_FromVoidPtr((void *)&zexus_rt_call_method));
1292
+ PyDict_SetItemString(symbols, "zexus_call_name", PyLong_FromVoidPtr((void *)&zexus_rt_call_name));
1293
+ PyDict_SetItemString(symbols, "zexus_env_get", PyLong_FromVoidPtr((void *)&zexus_rt_env_get));
1294
+ PyDict_SetItemString(symbols, "zexus_env_set", PyLong_FromVoidPtr((void *)&zexus_rt_env_set));
1295
+ PyDict_SetItemString(symbols, "zexus_export", PyLong_FromVoidPtr((void *)&zexus_rt_export));
1296
+ PyDict_SetItemString(symbols, "zexus_build_list", PyLong_FromVoidPtr((void *)&zexus_rt_build_list));
1297
+ PyDict_SetItemString(symbols, "zexus_build_map", PyLong_FromVoidPtr((void *)&zexus_rt_build_map));
1298
+ PyDict_SetItemString(symbols, "zexus_build_set", PyLong_FromVoidPtr((void *)&zexus_rt_build_set));
1299
+ PyDict_SetItemString(symbols, "zexus_build_list_from_array", PyLong_FromVoidPtr((void *)&zexus_rt_build_list));
1300
+ PyDict_SetItemString(symbols, "zexus_build_map_from_array", PyLong_FromVoidPtr((void *)&zexus_rt_build_map));
1301
+ PyDict_SetItemString(symbols, "zexus_build_set_from_array", PyLong_FromVoidPtr((void *)&zexus_rt_build_set));
1302
+ PyDict_SetItemString(symbols, "zexus_iter_next", PyLong_FromVoidPtr((void *)&zexus_rt_iter_next));
1303
+ PyDict_SetItemString(symbols, "zexus_build_tuple_from_array", PyLong_FromVoidPtr((void *)&zexus_rt_build_tuple));
1304
+ PyDict_SetItemString(symbols, "zexus_number_add", PyLong_FromVoidPtr((void *)&zexus_rt_add));
1305
+ PyDict_SetItemString(symbols, "zexus_number_sub", PyLong_FromVoidPtr((void *)&zexus_rt_sub));
1306
+ PyDict_SetItemString(symbols, "zexus_number_mul", PyLong_FromVoidPtr((void *)&zexus_rt_mul));
1307
+ PyDict_SetItemString(symbols, "zexus_number_div", PyLong_FromVoidPtr((void *)&zexus_rt_div));
1308
+ PyDict_SetItemString(symbols, "zexus_number_mod", PyLong_FromVoidPtr((void *)&zexus_rt_mod));
1309
+ PyDict_SetItemString(symbols, "zexus_number_pow", PyLong_FromVoidPtr((void *)&zexus_rt_pow));
1310
+ PyDict_SetItemString(symbols, "zexus_number_neg", PyLong_FromVoidPtr((void *)&zexus_rt_neg));
1311
+ PyDict_SetItemString(symbols, "zexus_compare_eq", PyLong_FromVoidPtr((void *)&zexus_rt_eq));
1312
+ PyDict_SetItemString(symbols, "zexus_compare_ne", PyLong_FromVoidPtr((void *)&zexus_rt_neq));
1313
+ PyDict_SetItemString(symbols, "zexus_compare_lt", PyLong_FromVoidPtr((void *)&zexus_rt_lt));
1314
+ PyDict_SetItemString(symbols, "zexus_compare_gt", PyLong_FromVoidPtr((void *)&zexus_rt_gt));
1315
+ PyDict_SetItemString(symbols, "zexus_compare_lte", PyLong_FromVoidPtr((void *)&zexus_rt_lte));
1316
+ PyDict_SetItemString(symbols, "zexus_compare_gte", PyLong_FromVoidPtr((void *)&zexus_rt_gte));
1317
+ PyDict_SetItemString(symbols, "zexus_truthy_int", PyLong_FromVoidPtr((void *)&zexus_rt_truthy));
1318
+ PyDict_SetItemString(symbols, "zexus_not", PyLong_FromVoidPtr((void *)&zexus_rt_not));
1319
+ PyDict_SetItemString(symbols, "zexus_bool_and", PyLong_FromVoidPtr((void *)&zexus_rt_and));
1320
+ PyDict_SetItemString(symbols, "zexus_bool_or", PyLong_FromVoidPtr((void *)&zexus_rt_or));
1321
+ PyDict_SetItemString(symbols, "zexus_index", PyLong_FromVoidPtr((void *)&zexus_rt_index));
1322
+ PyDict_SetItemString(symbols, "zexus_slice", PyLong_FromVoidPtr((void *)&zexus_rt_slice));
1323
+ PyDict_SetItemString(symbols, "zexus_get_attr", PyLong_FromVoidPtr((void *)&zexus_rt_get_attr));
1324
+ PyDict_SetItemString(symbols, "zexus_get_length", PyLong_FromVoidPtr((void *)&zexus_rt_get_length));
1325
+ PyDict_SetItemString(symbols, "zexus_print", PyLong_FromVoidPtr((void *)&zexus_rt_print));
1326
+ PyDict_SetItemString(symbols, "zexus_read", PyLong_FromVoidPtr((void *)&zexus_rt_read));
1327
+ PyDict_SetItemString(symbols, "zexus_write", PyLong_FromVoidPtr((void *)&zexus_rt_write));
1328
+ PyDict_SetItemString(symbols, "zexus_import", PyLong_FromVoidPtr((void *)&zexus_rt_import));
1329
+ PyDict_SetItemString(symbols, "zexus_int_from_long", PyLong_FromVoidPtr((void *)&zexus_rt_int_from_long));
1330
+ PyDict_SetItemString(symbols, "zexus_hash_block", PyLong_FromVoidPtr((void *)&zexus_rt_hash_block));
1331
+ PyDict_SetItemString(symbols, "zexus_merkle_root", PyLong_FromVoidPtr((void *)&zexus_rt_merkle_root));
1332
+ PyDict_SetItemString(symbols, "zexus_verify_signature", PyLong_FromVoidPtr((void *)&zexus_rt_verify_signature));
1333
+ PyDict_SetItemString(symbols, "zexus_state_read", PyLong_FromVoidPtr((void *)&zexus_rt_state_read));
1334
+ PyDict_SetItemString(symbols, "zexus_state_write", PyLong_FromVoidPtr((void *)&zexus_rt_state_write));
1335
+ PyDict_SetItemString(symbols, "zexus_tx_begin", PyLong_FromVoidPtr((void *)&zexus_rt_tx_begin));
1336
+ PyDict_SetItemString(symbols, "zexus_tx_commit", PyLong_FromVoidPtr((void *)&zexus_rt_tx_commit));
1337
+ PyDict_SetItemString(symbols, "zexus_tx_revert", PyLong_FromVoidPtr((void *)&zexus_rt_tx_revert));
1338
+ PyDict_SetItemString(symbols, "zexus_gas_charge", PyLong_FromVoidPtr((void *)&zexus_rt_gas_charge));
1339
+ PyDict_SetItemString(symbols, "zexus_require", PyLong_FromVoidPtr((void *)&zexus_rt_require));
1340
+ PyDict_SetItemString(symbols, "zexus_ledger_append", PyLong_FromVoidPtr((void *)&zexus_rt_ledger_append));
1341
+ PyDict_SetItemString(symbols, "zexus_register_event", PyLong_FromVoidPtr((void *)&zexus_rt_register_event));
1342
+ PyDict_SetItemString(symbols, "zexus_emit_event", PyLong_FromVoidPtr((void *)&zexus_rt_emit_event));
1343
+ PyDict_SetItemString(symbols, "zexus_spawn_name", PyLong_FromVoidPtr((void *)&zexus_rt_spawn_name));
1344
+ PyDict_SetItemString(symbols, "zexus_spawn_call", PyLong_FromVoidPtr((void *)&zexus_rt_spawn_call));
1345
+ PyDict_SetItemString(symbols, "zexus_await", PyLong_FromVoidPtr((void *)&zexus_rt_await));
1346
+ PyDict_SetItemString(symbols, "zexus_lock_acquire", PyLong_FromVoidPtr((void *)&zexus_rt_lock_acquire));
1347
+ PyDict_SetItemString(symbols, "zexus_lock_release", PyLong_FromVoidPtr((void *)&zexus_rt_lock_release));
1348
+ PyDict_SetItemString(symbols, "zexus_barrier_wait", PyLong_FromVoidPtr((void *)&zexus_rt_barrier_wait));
1349
+ PyDict_SetItemString(symbols, "zexus_atomic_add", PyLong_FromVoidPtr((void *)&zexus_rt_atomic_add));
1350
+ PyDict_SetItemString(symbols, "zexus_atomic_cas", PyLong_FromVoidPtr((void *)&zexus_rt_atomic_cas));
1351
+ PyDict_SetItemString(symbols, "zexus_get_iter", PyLong_FromVoidPtr((void *)&zexus_rt_get_iter));
1352
+ PyDict_SetItemString(symbols, "zexus_iter_next_pair", PyLong_FromVoidPtr((void *)&zexus_rt_iter_next_pair));
1353
+ PyDict_SetItemString(symbols, "zexus_atomic_add", PyLong_FromVoidPtr((void *)&zexus_rt_atomic_add));
1354
+ PyDict_SetItemString(symbols, "zexus_atomic_cas", PyLong_FromVoidPtr((void *)&zexus_rt_atomic_cas));
1355
+ PyDict_SetItemString(symbols, "zexus_barrier_wait", PyLong_FromVoidPtr((void *)&zexus_rt_barrier_wait));
1356
+ PyDict_SetItemString(symbols, "zexus_define_enum", PyLong_FromVoidPtr((void *)&zexus_rt_define_enum));
1357
+ PyDict_SetItemString(symbols, "zexus_define_protocol", PyLong_FromVoidPtr((void *)&zexus_rt_define_protocol));
1358
+ PyDict_SetItemString(symbols, "zexus_assert_protocol", PyLong_FromVoidPtr((void *)&zexus_rt_assert_protocol));
1359
+ PyDict_SetItemString(symbols, "zexus_define_capability", PyLong_FromVoidPtr((void *)&zexus_rt_define_capability));
1360
+ PyDict_SetItemString(symbols, "zexus_define_screen", PyLong_FromVoidPtr((void *)&zexus_rt_define_screen));
1361
+ PyDict_SetItemString(symbols, "zexus_define_component", PyLong_FromVoidPtr((void *)&zexus_rt_define_component));
1362
+ PyDict_SetItemString(symbols, "zexus_define_theme", PyLong_FromVoidPtr((void *)&zexus_rt_define_theme));
1363
+ PyDict_SetItemString(symbols, "zexus_grant_capability", PyLong_FromVoidPtr((void *)&zexus_rt_grant_capability));
1364
+ PyDict_SetItemString(symbols, "zexus_revoke_capability", PyLong_FromVoidPtr((void *)&zexus_rt_revoke_capability));
1365
+ PyDict_SetItemString(symbols, "zexus_audit_log", PyLong_FromVoidPtr((void *)&zexus_rt_audit_log));
1366
+ PyDict_SetItemString(symbols, "zexus_define_contract", PyLong_FromVoidPtr((void *)&zexus_rt_define_contract));
1367
+ PyDict_SetItemString(symbols, "zexus_define_entity", PyLong_FromVoidPtr((void *)&zexus_rt_define_entity));
1368
+ PyDict_SetItemString(symbols, "zexus_restrict_access", PyLong_FromVoidPtr((void *)&zexus_rt_restrict_access));
1369
+ PyDict_SetItemString(symbols, "zexus_enable_error_mode", PyLong_FromVoidPtr((void *)&zexus_rt_enable_error_mode));
1370
+ return symbols;
1371
+ }
1372
+
1373
+ static PyMethodDef NativeRuntimeMethods[] = {
1374
+ {"get_symbols", native_get_symbols, METH_VARARGS, "Return symbol addresses for native runtime"},
1375
+ {NULL, NULL, 0, NULL}
1376
+ };
1377
+
1378
+ static struct PyModuleDef native_runtime_module = {
1379
+ PyModuleDef_HEAD_INIT,
1380
+ "native_runtime",
1381
+ "Zexus native runtime (C++)",
1382
+ -1,
1383
+ NativeRuntimeMethods
1384
+ };
1385
+
1386
+ PyMODINIT_FUNC PyInit_native_runtime(void) {
1387
+ return PyModule_Create(&native_runtime_module);
1388
+ }