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,1816 @@
1
+ g"""
2
+ Native JIT backend using LLVM (llvmlite).
3
+
4
+ Compiles a restricted subset of numeric bytecode into native machine code.
5
+ """
6
+
7
+ from typing import Optional, Callable, List, Tuple, Dict, Any
8
+ import os
9
+
10
+ try:
11
+ from llvmlite import ir
12
+ from llvmlite import binding as llvm
13
+ _LLVM_AVAILABLE = True
14
+ except Exception:
15
+ _LLVM_AVAILABLE = False
16
+ ir = None
17
+ llvm = None
18
+
19
+
20
+ class NativeJITBackend:
21
+ def __init__(self, debug: bool = False):
22
+ if not _LLVM_AVAILABLE:
23
+ raise ImportError("llvmlite is required for native JIT")
24
+ self.debug = debug
25
+ llvm.initialize()
26
+ llvm.initialize_native_target()
27
+ llvm.initialize_native_asmprinter()
28
+ self.target = llvm.Target.from_default_triple()
29
+ self.target_machine = self.target.create_target_machine()
30
+ self.engine = llvm.create_mcjit_compiler(llvm.parse_assembly(""), self.target_machine)
31
+ self._register_cabi_symbols()
32
+
33
+ def _register_cabi_symbols(self) -> None:
34
+ symbols = None
35
+ try:
36
+ from . import native_runtime
37
+ symbols = native_runtime.get_symbols()
38
+ except Exception:
39
+ symbols = None
40
+ if symbols is None:
41
+ try:
42
+ from . import cabi
43
+ symbols = cabi.get_symbols()
44
+ except Exception:
45
+ symbols = None
46
+
47
+ if isinstance(symbols, dict):
48
+ for name, addr in symbols.items():
49
+ try:
50
+ llvm.add_symbol(name, int(addr))
51
+ except Exception:
52
+ continue
53
+
54
+ def compile(self, bytecode) -> Optional[Callable]:
55
+ trace_enabled = self.debug or os.environ.get("ZEXUS_NATIVE_JIT_TRACE", "0") in ("1", "true", "yes")
56
+ instrs = list(getattr(bytecode, "instructions", []))
57
+ consts = list(getattr(bytecode, "constants", []))
58
+
59
+ normalized: List[Tuple[str, Any]] = []
60
+ names: List[str] = []
61
+ name_index: Dict[str, int] = {}
62
+
63
+ for instr in instrs:
64
+ if instr is None:
65
+ continue
66
+ if isinstance(instr, tuple) and len(instr) >= 2:
67
+ op = instr[0]
68
+ operand = instr[1] if len(instr) == 2 else tuple(instr[1:])
69
+ op_name = op.name if hasattr(op, "name") else op
70
+ normalized.append((op_name, operand))
71
+ if op_name in ("LOAD_NAME", "STORE_NAME"):
72
+ name = consts[operand] if isinstance(operand, int) and 0 <= operand < len(consts) else operand
73
+ if isinstance(name, str) and name not in name_index:
74
+ name_index[name] = len(names)
75
+ names.append(name)
76
+ else:
77
+ return None
78
+
79
+ supported = {
80
+ "LOAD_CONST",
81
+ "LOAD_NAME",
82
+ "STORE_NAME",
83
+ "POP",
84
+ "DUP",
85
+ "ADD",
86
+ "SUB",
87
+ "MUL",
88
+ "DIV",
89
+ "MOD",
90
+ "NEG",
91
+ "EQ",
92
+ "NEQ",
93
+ "LT",
94
+ "GT",
95
+ "LTE",
96
+ "GTE",
97
+ "AND",
98
+ "OR",
99
+ "NOT",
100
+ "RETURN",
101
+ "JUMP",
102
+ "JUMP_IF_FALSE",
103
+ "JUMP_IF_TRUE",
104
+ }
105
+ object_ops = {
106
+ "CALL_NAME",
107
+ "CALL_FUNC_CONST",
108
+ "CALL_METHOD",
109
+ "CALL_TOP",
110
+ "CALL_BUILTIN",
111
+ "LOAD_REG",
112
+ "LOAD_VAR_REG",
113
+ "STORE_REG",
114
+ "MOV_REG",
115
+ "ADD_REG",
116
+ "SUB_REG",
117
+ "MUL_REG",
118
+ "DIV_REG",
119
+ "MOD_REG",
120
+ "POW_REG",
121
+ "NEG_REG",
122
+ "EQ_REG",
123
+ "NEQ_REG",
124
+ "LT_REG",
125
+ "GT_REG",
126
+ "LTE_REG",
127
+ "GTE_REG",
128
+ "AND_REG",
129
+ "OR_REG",
130
+ "NOT_REG",
131
+ "PUSH_REG",
132
+ "POP_REG",
133
+ "BUILD_LIST",
134
+ "BUILD_MAP",
135
+ "BUILD_SET",
136
+ "INDEX",
137
+ "SLICE",
138
+ "GET_ATTR",
139
+ "GET_LENGTH",
140
+ "PRINT",
141
+ "READ",
142
+ "WRITE",
143
+ "IMPORT",
144
+ "EXPORT",
145
+ "STORE_FUNC",
146
+ "STORE_CONST",
147
+ "POW",
148
+ "SPAWN",
149
+ "AWAIT",
150
+ "SPAWN_CALL",
151
+ "REGISTER_EVENT",
152
+ "EMIT_EVENT",
153
+ "HASH_BLOCK",
154
+ "VERIFY_SIGNATURE",
155
+ "MERKLE_ROOT",
156
+ "STATE_READ",
157
+ "STATE_WRITE",
158
+ "TX_BEGIN",
159
+ "TX_COMMIT",
160
+ "TX_REVERT",
161
+ "GAS_CHARGE",
162
+ "REQUIRE",
163
+ "LEDGER_APPEND",
164
+ "DEFINE_ENUM",
165
+ "DEFINE_PROTOCOL",
166
+ "ASSERT_PROTOCOL",
167
+ "DEFINE_CAPABILITY",
168
+ "GRANT_CAPABILITY",
169
+ "REVOKE_CAPABILITY",
170
+ "AUDIT_LOG",
171
+ "DEFINE_SCREEN",
172
+ "DEFINE_COMPONENT",
173
+ "DEFINE_THEME",
174
+ "DEFINE_CONTRACT",
175
+ "DEFINE_ENTITY",
176
+ "RESTRICT_ACCESS",
177
+ "ENABLE_ERROR_MODE",
178
+ "NOP",
179
+ "PARALLEL_START",
180
+ "PARALLEL_END",
181
+ "SPAWN_TASK",
182
+ "TASK_JOIN",
183
+ "TASK_RESULT",
184
+ "LOCK_ACQUIRE",
185
+ "LOCK_RELEASE",
186
+ "ATOMIC_ADD",
187
+ "ATOMIC_CAS",
188
+ "BARRIER",
189
+ "SETUP_TRY",
190
+ "POP_TRY",
191
+ "THROW",
192
+ "FOR_ITER",
193
+ }
194
+ use_object_mode = False
195
+ for op_name, _ in normalized:
196
+ if op_name in object_ops:
197
+ use_object_mode = True
198
+ if op_name not in supported and op_name not in object_ops:
199
+ return None
200
+
201
+ if trace_enabled:
202
+ try:
203
+ mode = "object" if use_object_mode else "numeric"
204
+ print(f"[NATIVE JIT] compile mode={mode} instrs={len(normalized)} consts={len(consts)}")
205
+ except Exception:
206
+ pass
207
+
208
+ if use_object_mode:
209
+ func_ptr = self._build_object_function(normalized, consts)
210
+ else:
211
+ func_ptr = self._build_function(normalized, consts, names)
212
+ if func_ptr is None:
213
+ return None
214
+
215
+ from ctypes import CFUNCTYPE, c_double, POINTER, py_object
216
+
217
+ if use_object_mode:
218
+ cfunc = CFUNCTYPE(py_object, py_object, py_object, py_object, POINTER(py_object))(func_ptr)
219
+ const_objs = [c for c in consts]
220
+
221
+ def jit_execute(vm, stack, env):
222
+ try:
223
+ const_buf = (py_object * max(len(const_objs), 1))(*const_objs)
224
+ return cfunc(vm, env, vm.builtins, const_buf)
225
+ except Exception:
226
+ return None
227
+
228
+ return jit_execute
229
+ else:
230
+ cfunc = CFUNCTYPE(c_double, POINTER(c_double), POINTER(c_double))(func_ptr)
231
+ const_values = [float(c) if isinstance(c, (int, float)) else 0.0 for c in consts]
232
+
233
+ def jit_execute(vm, stack, env):
234
+ try:
235
+ locals_buf = (c_double * max(len(names), 1))()
236
+ for idx, name in enumerate(names):
237
+ val = env.get(name)
238
+ if isinstance(val, bool):
239
+ val = 1.0 if val else 0.0
240
+ if not isinstance(val, (int, float)):
241
+ return None
242
+ locals_buf[idx] = float(val)
243
+ const_buf = (c_double * max(len(const_values), 1))(*const_values)
244
+ result = cfunc(locals_buf, const_buf)
245
+ # write-back locals to env
246
+ for idx, name in enumerate(names):
247
+ env[name] = float(locals_buf[idx])
248
+ return result
249
+ except Exception:
250
+ return None
251
+
252
+ return jit_execute
253
+
254
+ def _build_function(self, instrs: List[Tuple[str, Any]], consts: List[Any], names: List[str]) -> Optional[int]:
255
+ module = ir.Module(name="zexus_native_jit")
256
+ double = ir.DoubleType()
257
+ double_ptr = double.as_pointer()
258
+ func_type = ir.FunctionType(double, [double_ptr, double_ptr])
259
+ func = ir.Function(module, func_type, name="jit_fn")
260
+
261
+ blocks = [func.append_basic_block(name=f"b{i}") for i in range(len(instrs) + 1)]
262
+ builder = ir.IRBuilder(blocks[0])
263
+
264
+ stack_size = max(8, len(instrs) + 4)
265
+ stack_arr = builder.alloca(ir.ArrayType(double, stack_size))
266
+ stack_base = builder.gep(stack_arr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)])
267
+ sp = builder.alloca(ir.IntType(32))
268
+ builder.store(ir.Constant(ir.IntType(32), 0), sp)
269
+
270
+ locals_ptr, const_ptr = func.args
271
+
272
+ def push(val):
273
+ cur_sp = builder.load(sp)
274
+ ptr = builder.gep(stack_base, [cur_sp])
275
+ builder.store(val, ptr)
276
+ builder.store(builder.add(cur_sp, ir.Constant(ir.IntType(32), 1)), sp)
277
+
278
+ def pop():
279
+ cur_sp = builder.load(sp)
280
+ new_sp = builder.sub(cur_sp, ir.Constant(ir.IntType(32), 1))
281
+ builder.store(new_sp, sp)
282
+ ptr = builder.gep(stack_base, [new_sp])
283
+ return builder.load(ptr)
284
+
285
+ name_to_idx = {}
286
+ try:
287
+ name_to_idx = {n: i for i, n in enumerate(names)}
288
+ except Exception:
289
+ name_to_idx = {}
290
+
291
+ for idx, (op_name, operand) in enumerate(instrs):
292
+ builder = ir.IRBuilder(blocks[idx])
293
+
294
+ if op_name == "LOAD_CONST":
295
+ if isinstance(operand, int) and 0 <= operand < len(consts):
296
+ val = consts[operand]
297
+ val = float(val) if isinstance(val, (int, float)) else 0.0
298
+ else:
299
+ val = float(operand) if isinstance(operand, (int, float)) else 0.0
300
+ push(ir.Constant(double, val))
301
+ builder.branch(blocks[idx + 1])
302
+ continue
303
+
304
+ if op_name == "LOAD_NAME":
305
+ if isinstance(operand, int) and 0 <= operand < len(consts):
306
+ name = consts[operand]
307
+ else:
308
+ name = operand
309
+ name_idx = name_to_idx.get(name)
310
+ if name_idx is not None:
311
+ ptr = builder.gep(locals_ptr, [ir.Constant(ir.IntType(32), name_idx)])
312
+ push(builder.load(ptr))
313
+ else:
314
+ push(ir.Constant(double, 0.0))
315
+ builder.branch(blocks[idx + 1])
316
+ continue
317
+
318
+ if op_name == "STORE_NAME":
319
+ if isinstance(operand, int) and 0 <= operand < len(consts):
320
+ name = consts[operand]
321
+ else:
322
+ name = operand
323
+ val = pop()
324
+ name_idx = name_to_idx.get(name)
325
+ if name_idx is not None:
326
+ ptr = builder.gep(locals_ptr, [ir.Constant(ir.IntType(32), name_idx)])
327
+ builder.store(val, ptr)
328
+ builder.branch(blocks[idx + 1])
329
+ continue
330
+
331
+ if op_name == "POP":
332
+ _ = pop()
333
+ builder.branch(blocks[idx + 1])
334
+ continue
335
+
336
+ if op_name == "DUP":
337
+ val = pop()
338
+ push(val)
339
+ push(val)
340
+ builder.branch(blocks[idx + 1])
341
+ continue
342
+
343
+ if op_name == "PUSH_REG":
344
+ reg_idx = int(operand) if not isinstance(operand, (list, tuple)) else int(operand[0])
345
+ reg_slot = reg_ptr(ir.Constant(ir.IntType(32), reg_idx))
346
+ val = builder.load(reg_slot)
347
+ push(val)
348
+ builder.branch(blocks[idx + 1])
349
+ continue
350
+
351
+ if op_name == "POP_REG":
352
+ reg_idx = int(operand) if not isinstance(operand, (list, tuple)) else int(operand[0])
353
+ val = pop()
354
+ reg_slot = reg_ptr(ir.Constant(ir.IntType(32), reg_idx))
355
+ builder.store(val, reg_slot)
356
+ builder.branch(blocks[idx + 1])
357
+ continue
358
+
359
+ if op_name in ("ADD", "SUB", "MUL", "DIV", "MOD"):
360
+ b = pop()
361
+ a = pop()
362
+ if op_name == "ADD":
363
+ res = builder.fadd(a, b)
364
+ elif op_name == "SUB":
365
+ res = builder.fsub(a, b)
366
+ elif op_name == "MUL":
367
+ res = builder.fmul(a, b)
368
+ elif op_name == "DIV":
369
+ res = builder.fdiv(a, b)
370
+ else:
371
+ res = builder.frem(a, b)
372
+ push(res)
373
+ builder.branch(blocks[idx + 1])
374
+ continue
375
+
376
+ if op_name == "NEG":
377
+ a = pop()
378
+ res = builder.fsub(ir.Constant(double, 0.0), a)
379
+ push(res)
380
+ builder.branch(blocks[idx + 1])
381
+ continue
382
+
383
+ if op_name in ("EQ", "NEQ", "LT", "GT", "LTE", "GTE"):
384
+ b = pop()
385
+ a = pop()
386
+ if op_name == "EQ":
387
+ cmp = builder.fcmp_ordered("==", a, b)
388
+ elif op_name == "NEQ":
389
+ cmp = builder.fcmp_ordered("!=", a, b)
390
+ elif op_name == "LT":
391
+ cmp = builder.fcmp_ordered("<", a, b)
392
+ elif op_name == "GT":
393
+ cmp = builder.fcmp_ordered(">", a, b)
394
+ elif op_name == "LTE":
395
+ cmp = builder.fcmp_ordered("<=", a, b)
396
+ else:
397
+ cmp = builder.fcmp_ordered(">=", a, b)
398
+ # bool -> double
399
+ res = builder.uitofp(cmp, double)
400
+ push(res)
401
+ builder.branch(blocks[idx + 1])
402
+ continue
403
+
404
+ if op_name in ("AND", "OR"):
405
+ b = pop()
406
+ a = pop()
407
+ zero = ir.Constant(double, 0.0)
408
+ a_true = builder.fcmp_ordered("!=", a, zero)
409
+ b_true = builder.fcmp_ordered("!=", b, zero)
410
+ if op_name == "AND":
411
+ res_bool = builder.and_(a_true, b_true)
412
+ else:
413
+ res_bool = builder.or_(a_true, b_true)
414
+ res = builder.uitofp(res_bool, double)
415
+ push(res)
416
+ builder.branch(blocks[idx + 1])
417
+ continue
418
+
419
+ if op_name == "NOT":
420
+ a = pop()
421
+ zero = ir.Constant(double, 0.0)
422
+ is_false = builder.fcmp_ordered("==", a, zero)
423
+ res = builder.uitofp(is_false, double)
424
+ push(res)
425
+ builder.branch(blocks[idx + 1])
426
+ continue
427
+
428
+ if op_name == "JUMP":
429
+ target = int(operand) if operand is not None else idx + 1
430
+ builder.branch(blocks[target])
431
+ continue
432
+
433
+ if op_name == "JUMP_IF_FALSE":
434
+ cond = pop()
435
+ zero = ir.Constant(double, 0.0)
436
+ is_false = builder.fcmp_ordered("==", cond, zero)
437
+ target = int(operand) if operand is not None else idx + 1
438
+ builder.cbranch(is_false, blocks[target], blocks[idx + 1])
439
+ continue
440
+
441
+ if op_name == "JUMP_IF_TRUE":
442
+ cond = pop()
443
+ zero = ir.Constant(double, 0.0)
444
+ is_true = builder.fcmp_ordered("!=", cond, zero)
445
+ target = int(operand) if operand is not None else idx + 1
446
+ builder.cbranch(is_true, blocks[target], blocks[idx + 1])
447
+ continue
448
+
449
+ if op_name == "RETURN":
450
+ res = pop()
451
+ builder.ret(res)
452
+ continue
453
+
454
+ builder.branch(blocks[idx + 1])
455
+
456
+ builder = ir.IRBuilder(blocks[-1])
457
+ builder.ret(ir.Constant(double, 0.0))
458
+
459
+ llvm_ir = str(module)
460
+ mod = llvm.parse_assembly(llvm_ir)
461
+ mod.verify()
462
+ self.engine.add_module(mod)
463
+ self.engine.finalize_object()
464
+ self.engine.run_static_constructors()
465
+
466
+ func_ptr = self.engine.get_function_address("jit_fn")
467
+ return func_ptr
468
+
469
+ def _build_object_function(self, instrs: List[Tuple[str, Any]], consts: List[Any]) -> Optional[int]:
470
+ ptr = ir.IntType(8).as_pointer() # PyObject*
471
+ ptr_ptr = ptr.as_pointer() # PyObject**
472
+
473
+ # Determine register file size for register ops
474
+ max_reg = -1
475
+ register_ops = {
476
+ "LOAD_REG", "LOAD_VAR_REG", "STORE_REG", "MOV_REG",
477
+ "ADD_REG", "SUB_REG", "MUL_REG", "DIV_REG", "MOD_REG", "POW_REG",
478
+ "NEG_REG", "EQ_REG", "NEQ_REG", "LT_REG", "GT_REG", "LTE_REG", "GTE_REG",
479
+ "AND_REG", "OR_REG", "NOT_REG", "PUSH_REG", "POP_REG",
480
+ }
481
+ for op_name, operand in instrs:
482
+ if op_name in register_ops:
483
+ if op_name in ("LOAD_REG", "LOAD_VAR_REG", "STORE_REG"):
484
+ if isinstance(operand, (list, tuple)) and operand and isinstance(operand[0], int):
485
+ max_reg = max(max_reg, operand[0])
486
+ elif op_name == "MOV_REG":
487
+ if isinstance(operand, (list, tuple)) and len(operand) >= 2:
488
+ if isinstance(operand[0], int):
489
+ max_reg = max(max_reg, operand[0])
490
+ if isinstance(operand[1], int):
491
+ max_reg = max(max_reg, operand[1])
492
+ elif op_name in ("NEG_REG", "NOT_REG"):
493
+ if isinstance(operand, (list, tuple)) and len(operand) >= 2:
494
+ if isinstance(operand[0], int):
495
+ max_reg = max(max_reg, operand[0])
496
+ if isinstance(operand[1], int):
497
+ max_reg = max(max_reg, operand[1])
498
+ elif op_name in ("PUSH_REG", "POP_REG"):
499
+ if isinstance(operand, int):
500
+ max_reg = max(max_reg, operand)
501
+ elif isinstance(operand, (list, tuple)) and operand and isinstance(operand[0], int):
502
+ max_reg = max(max_reg, operand[0])
503
+ else:
504
+ if isinstance(operand, (list, tuple)):
505
+ for item in operand:
506
+ if isinstance(item, int):
507
+ max_reg = max(max_reg, item)
508
+ reg_count = max(1, max_reg + 1)
509
+
510
+ func_type = ir.FunctionType(ptr, [ptr, ptr, ptr, ptr_ptr])
511
+ func = ir.Function(ir.Module(name="zexus_native_jit_obj"), func_type, name="jit_obj_fn")
512
+ vm_ptr, env_ptr, builtins_ptr, consts_ptr = func.args
513
+
514
+ module = func.module
515
+
516
+ # Declare C ABI functions
517
+ def decl(name, ret, args):
518
+ return ir.Function(module, ir.FunctionType(ret, args), name=name)
519
+
520
+ cabi_env_get = decl("zexus_env_get", ptr, [ptr, ptr])
521
+ cabi_env_set = decl("zexus_env_set", ir.IntType(32), [ptr, ptr, ptr])
522
+ cabi_call_name = decl("zexus_call_name", ptr, [ptr, ptr, ptr, ptr])
523
+ cabi_call_method = decl("zexus_call_method", ptr, [ptr, ptr, ptr])
524
+ cabi_call_callable = decl("zexus_call_callable", ptr, [ptr, ptr])
525
+ cabi_build_list = decl("zexus_build_list_from_array", ptr, [ptr, ir.IntType(64)])
526
+ cabi_build_map = decl("zexus_build_map_from_array", ptr, [ptr, ir.IntType(64)])
527
+ cabi_build_set = decl("zexus_build_set_from_array", ptr, [ptr, ir.IntType(64)])
528
+ cabi_build_tuple = decl("zexus_build_tuple_from_array", ptr, [ptr, ir.IntType(64)])
529
+ cabi_iter_next = decl("zexus_iter_next", ptr, [ptr])
530
+ cabi_add = decl("zexus_number_add", ptr, [ptr, ptr])
531
+ cabi_sub = decl("zexus_number_sub", ptr, [ptr, ptr])
532
+ cabi_mul = decl("zexus_number_mul", ptr, [ptr, ptr])
533
+ cabi_div = decl("zexus_number_div", ptr, [ptr, ptr])
534
+ cabi_mod = decl("zexus_number_mod", ptr, [ptr, ptr])
535
+ cabi_pow = decl("zexus_number_pow", ptr, [ptr, ptr])
536
+ cabi_neg = decl("zexus_number_neg", ptr, [ptr])
537
+ cabi_eq = decl("zexus_compare_eq", ptr, [ptr, ptr])
538
+ cabi_neq = decl("zexus_compare_ne", ptr, [ptr, ptr])
539
+ cabi_lt = decl("zexus_compare_lt", ptr, [ptr, ptr])
540
+ cabi_gt = decl("zexus_compare_gt", ptr, [ptr, ptr])
541
+ cabi_lte = decl("zexus_compare_lte", ptr, [ptr, ptr])
542
+ cabi_gte = decl("zexus_compare_gte", ptr, [ptr, ptr])
543
+ cabi_truthy = decl("zexus_truthy_int", ir.IntType(32), [ptr])
544
+ cabi_not = decl("zexus_not", ptr, [ptr])
545
+ cabi_bool_and = decl("zexus_bool_and", ptr, [ptr, ptr])
546
+ cabi_bool_or = decl("zexus_bool_or", ptr, [ptr, ptr])
547
+ cabi_index = decl("zexus_index", ptr, [ptr, ptr])
548
+ cabi_slice = decl("zexus_slice", ptr, [ptr, ptr, ptr])
549
+ cabi_get_attr = decl("zexus_get_attr", ptr, [ptr, ptr])
550
+ cabi_get_length = decl("zexus_get_length", ptr, [ptr])
551
+ cabi_print = decl("zexus_print", ptr, [ptr])
552
+ cabi_read = decl("zexus_read", ptr, [ptr])
553
+ cabi_write = decl("zexus_write", ptr, [ptr, ptr])
554
+ cabi_import = decl("zexus_import", ptr, [ptr])
555
+ cabi_export = decl("zexus_export", ptr, [ptr, ptr, ptr])
556
+ cabi_int_from_long = decl("zexus_int_from_long", ptr, [ir.IntType(64)])
557
+ cabi_hash_block = decl("zexus_hash_block", ptr, [ptr])
558
+ cabi_merkle_root = decl("zexus_merkle_root", ptr, [ptr, ir.IntType(64)])
559
+ cabi_verify_signature = decl("zexus_verify_signature", ptr, [ptr, ptr, ptr, ptr, ptr])
560
+ cabi_state_read = decl("zexus_state_read", ptr, [ptr, ptr])
561
+ cabi_state_write = decl("zexus_state_write", ptr, [ptr, ptr, ptr])
562
+ cabi_tx_begin = decl("zexus_tx_begin", ptr, [ptr])
563
+ cabi_tx_commit = decl("zexus_tx_commit", ptr, [ptr])
564
+ cabi_tx_revert = decl("zexus_tx_revert", ptr, [ptr])
565
+ cabi_gas_charge = decl("zexus_gas_charge", ptr, [ptr, ptr])
566
+ cabi_require = decl("zexus_require", ptr, [ptr, ptr, ptr])
567
+ cabi_ledger_append = decl("zexus_ledger_append", ptr, [ptr, ptr])
568
+ cabi_register_event = decl("zexus_register_event", ptr, [ptr, ptr, ptr])
569
+ cabi_emit_event = decl("zexus_emit_event", ptr, [ptr, ptr, ptr, ptr, ptr])
570
+ cabi_spawn_name = decl("zexus_spawn_name", ptr, [ptr, ptr, ptr, ptr, ptr])
571
+ cabi_spawn_call = decl("zexus_spawn_call", ptr, [ptr, ptr, ptr])
572
+ cabi_await = decl("zexus_await", ptr, [ptr, ptr])
573
+ cabi_lock_acquire = decl("zexus_lock_acquire", ptr, [ptr, ptr])
574
+ cabi_lock_release = decl("zexus_lock_release", ptr, [ptr, ptr])
575
+ cabi_barrier_wait = decl("zexus_barrier_wait", ptr, [ptr, ptr])
576
+ cabi_atomic_add = decl("zexus_atomic_add", ptr, [ptr, ptr, ptr])
577
+ cabi_atomic_cas = decl("zexus_atomic_cas", ptr, [ptr, ptr, ptr, ptr])
578
+ cabi_get_iter = decl("zexus_get_iter", ptr, [ptr])
579
+ cabi_iter_next_pair = decl("zexus_iter_next_pair", ptr, [ptr])
580
+ cabi_atomic_add = decl("zexus_atomic_add", ptr, [ptr, ptr, ptr])
581
+ cabi_atomic_cas = decl("zexus_atomic_cas", ptr, [ptr, ptr, ptr, ptr])
582
+ cabi_barrier_wait = decl("zexus_barrier_wait", ptr, [ptr, ptr])
583
+ cabi_define_enum = decl("zexus_define_enum", ptr, [ptr, ptr, ptr])
584
+ cabi_define_protocol = decl("zexus_define_protocol", ptr, [ptr, ptr, ptr])
585
+ cabi_assert_protocol = decl("zexus_assert_protocol", ptr, [ptr, ptr, ptr])
586
+ cabi_define_capability = decl("zexus_define_capability", ptr, [ptr, ptr, ptr])
587
+ cabi_define_screen = decl("zexus_define_screen", ptr, [ptr, ptr, ptr])
588
+ cabi_define_component = decl("zexus_define_component", ptr, [ptr, ptr, ptr])
589
+ cabi_define_theme = decl("zexus_define_theme", ptr, [ptr, ptr, ptr])
590
+ cabi_grant_capability = decl("zexus_grant_capability", ptr, [ptr, ptr, ptr, ir.IntType(64)])
591
+ cabi_revoke_capability = decl("zexus_revoke_capability", ptr, [ptr, ptr, ptr, ir.IntType(64)])
592
+ cabi_audit_log = decl("zexus_audit_log", ptr, [ptr, ptr, ptr, ptr])
593
+ cabi_define_contract = decl("zexus_define_contract", ptr, [ptr, ir.IntType(64), ptr])
594
+ cabi_define_entity = decl("zexus_define_entity", ptr, [ptr, ir.IntType(64), ptr])
595
+ cabi_restrict_access = decl("zexus_restrict_access", ptr, [ptr, ptr, ptr, ptr])
596
+ cabi_enable_error_mode = decl("zexus_enable_error_mode", ptr, [ptr])
597
+
598
+ blocks = [func.append_basic_block(name=f"b{i}") for i in range(len(instrs) + 1)]
599
+ builder = ir.IRBuilder(blocks[0])
600
+
601
+ stack_size = max(16, len(instrs) + 4)
602
+ stack_arr = builder.alloca(ir.ArrayType(ptr, stack_size))
603
+ stack_base = builder.gep(stack_arr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)])
604
+ sp = builder.alloca(ir.IntType(32))
605
+ builder.store(ir.Constant(ir.IntType(32), 0), sp)
606
+
607
+ try_stack_size = max(4, len(instrs) + 2)
608
+ try_stack_arr = builder.alloca(ir.ArrayType(ir.IntType(32), try_stack_size))
609
+ try_stack_base = builder.gep(try_stack_arr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)])
610
+ try_sp = builder.alloca(ir.IntType(32))
611
+ builder.store(ir.Constant(ir.IntType(32), 0), try_sp)
612
+
613
+ reg_arr = builder.alloca(ir.ArrayType(ptr, reg_count))
614
+ reg_base = builder.gep(reg_arr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)])
615
+ null_ptr = ir.Constant(ptr, 0)
616
+ for r in range(reg_count):
617
+ reg_slot = builder.gep(reg_base, [ir.Constant(ir.IntType(32), r)])
618
+ builder.store(null_ptr, reg_slot)
619
+
620
+ def push(val):
621
+ cur_sp = builder.load(sp)
622
+ ptr_slot = builder.gep(stack_base, [cur_sp])
623
+ builder.store(val, ptr_slot)
624
+ builder.store(builder.add(cur_sp, ir.Constant(ir.IntType(32), 1)), sp)
625
+
626
+ def push_with(bld, val):
627
+ cur_sp = bld.load(sp)
628
+ ptr_slot = bld.gep(stack_base, [cur_sp])
629
+ bld.store(val, ptr_slot)
630
+ bld.store(bld.add(cur_sp, ir.Constant(ir.IntType(32), 1)), sp)
631
+
632
+ def pop():
633
+ cur_sp = builder.load(sp)
634
+ new_sp = builder.sub(cur_sp, ir.Constant(ir.IntType(32), 1))
635
+ builder.store(new_sp, sp)
636
+ ptr_slot = builder.gep(stack_base, [new_sp])
637
+ return builder.load(ptr_slot)
638
+
639
+ def const_obj(idx):
640
+ return builder.load(builder.gep(consts_ptr, [ir.Constant(ir.IntType(32), idx)]))
641
+
642
+ def reg_ptr(idx_val):
643
+ return builder.gep(reg_base, [idx_val])
644
+
645
+ def try_push(handler_idx):
646
+ cur_sp = builder.load(try_sp)
647
+ slot = builder.gep(try_stack_base, [cur_sp])
648
+ builder.store(handler_idx, slot)
649
+ builder.store(builder.add(cur_sp, ir.Constant(ir.IntType(32), 1)), try_sp)
650
+
651
+ def try_pop():
652
+ cur_sp = builder.load(try_sp)
653
+ new_sp = builder.sub(cur_sp, ir.Constant(ir.IntType(32), 1))
654
+ builder.store(new_sp, try_sp)
655
+ slot = builder.gep(try_stack_base, [new_sp])
656
+ return builder.load(slot)
657
+
658
+ def try_pop_with(bld):
659
+ cur_sp = bld.load(try_sp)
660
+ new_sp = bld.sub(cur_sp, ir.Constant(ir.IntType(32), 1))
661
+ bld.store(new_sp, try_sp)
662
+ slot = bld.gep(try_stack_base, [new_sp])
663
+ return bld.load(slot)
664
+
665
+ for idx, (op_name, operand) in enumerate(instrs):
666
+ builder = ir.IRBuilder(blocks[idx])
667
+
668
+ if op_name == "LOAD_CONST":
669
+ if isinstance(operand, int):
670
+ push(const_obj(operand))
671
+ else:
672
+ push(ir.Constant(ptr, 0))
673
+ builder.branch(blocks[idx + 1])
674
+ continue
675
+
676
+ if op_name == "LOAD_NAME":
677
+ name_obj = const_obj(int(operand)) if isinstance(operand, int) else ir.Constant(ptr, 0)
678
+ val = builder.call(cabi_env_get, [env_ptr, name_obj])
679
+ push(val)
680
+ builder.branch(blocks[idx + 1])
681
+ continue
682
+
683
+ if op_name == "STORE_NAME":
684
+ name_obj = const_obj(int(operand)) if isinstance(operand, int) else ir.Constant(ptr, 0)
685
+ val = pop()
686
+ builder.call(cabi_env_set, [env_ptr, name_obj, val])
687
+ builder.branch(blocks[idx + 1])
688
+ continue
689
+
690
+ if op_name == "STORE_CONST":
691
+ if isinstance(operand, (tuple, list)) and len(operand) == 2:
692
+ name_idx = operand[0]
693
+ value_idx = operand[1]
694
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
695
+ value_obj = const_obj(int(value_idx)) if isinstance(value_idx, int) else ir.Constant(ptr, 0)
696
+ builder.call(cabi_env_set, [env_ptr, name_obj, value_obj])
697
+ builder.branch(blocks[idx + 1])
698
+ continue
699
+
700
+ if op_name == "STORE_FUNC":
701
+ name_idx, func_idx = operand
702
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
703
+ func_obj = const_obj(int(func_idx)) if isinstance(func_idx, int) else ir.Constant(ptr, 0)
704
+ builder.call(cabi_env_set, [env_ptr, name_obj, func_obj])
705
+ builder.branch(blocks[idx + 1])
706
+ continue
707
+
708
+ if op_name == "LOAD_REG":
709
+ reg_idx, const_idx = operand
710
+ reg_slot = reg_ptr(ir.Constant(ir.IntType(32), int(reg_idx)))
711
+ value_obj = const_obj(int(const_idx)) if isinstance(const_idx, int) else ir.Constant(ptr, 0)
712
+ builder.store(value_obj, reg_slot)
713
+ builder.branch(blocks[idx + 1])
714
+ continue
715
+
716
+ if op_name == "LOAD_VAR_REG":
717
+ reg_idx, name_idx = operand
718
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
719
+ val = builder.call(cabi_env_get, [env_ptr, name_obj])
720
+ reg_slot = reg_ptr(ir.Constant(ir.IntType(32), int(reg_idx)))
721
+ builder.store(val, reg_slot)
722
+ builder.branch(blocks[idx + 1])
723
+ continue
724
+
725
+ if op_name == "STORE_REG":
726
+ reg_idx, name_idx = operand
727
+ reg_slot = reg_ptr(ir.Constant(ir.IntType(32), int(reg_idx)))
728
+ val = builder.load(reg_slot)
729
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
730
+ builder.call(cabi_env_set, [env_ptr, name_obj, val])
731
+ builder.branch(blocks[idx + 1])
732
+ continue
733
+
734
+ if op_name == "MOV_REG":
735
+ dest_idx, src_idx = operand
736
+ src_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src_idx)))
737
+ dest_slot = reg_ptr(ir.Constant(ir.IntType(32), int(dest_idx)))
738
+ val = builder.load(src_slot)
739
+ builder.store(val, dest_slot)
740
+ builder.branch(blocks[idx + 1])
741
+ continue
742
+
743
+ if op_name in ("ADD_REG", "SUB_REG", "MUL_REG", "DIV_REG", "MOD_REG"):
744
+ dest_idx, src1_idx, src2_idx = operand
745
+ src1_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src1_idx)))
746
+ src2_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src2_idx)))
747
+ dest_slot = reg_ptr(ir.Constant(ir.IntType(32), int(dest_idx)))
748
+ v1 = builder.load(src1_slot)
749
+ v2 = builder.load(src2_slot)
750
+ if op_name == "ADD_REG":
751
+ res = builder.call(cabi_add, [v1, v2])
752
+ elif op_name == "SUB_REG":
753
+ res = builder.call(cabi_sub, [v1, v2])
754
+ elif op_name == "MUL_REG":
755
+ res = builder.call(cabi_mul, [v1, v2])
756
+ elif op_name == "DIV_REG":
757
+ res = builder.call(cabi_div, [v1, v2])
758
+ else:
759
+ res = builder.call(cabi_mod, [v1, v2])
760
+ builder.store(res, dest_slot)
761
+ builder.branch(blocks[idx + 1])
762
+ continue
763
+
764
+ if op_name == "POW_REG":
765
+ dest_idx, src1_idx, src2_idx = operand
766
+ src1_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src1_idx)))
767
+ src2_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src2_idx)))
768
+ dest_slot = reg_ptr(ir.Constant(ir.IntType(32), int(dest_idx)))
769
+ v1 = builder.load(src1_slot)
770
+ v2 = builder.load(src2_slot)
771
+ res = builder.call(cabi_pow, [v1, v2])
772
+ builder.store(res, dest_slot)
773
+ builder.branch(blocks[idx + 1])
774
+ continue
775
+
776
+ if op_name == "NEG_REG":
777
+ dest_idx, src_idx = operand
778
+ src_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src_idx)))
779
+ dest_slot = reg_ptr(ir.Constant(ir.IntType(32), int(dest_idx)))
780
+ v1 = builder.load(src_slot)
781
+ res = builder.call(cabi_neg, [v1])
782
+ builder.store(res, dest_slot)
783
+ builder.branch(blocks[idx + 1])
784
+ continue
785
+
786
+ if op_name in ("EQ_REG", "NEQ_REG", "LT_REG"):
787
+ dest_idx, src1_idx, src2_idx = operand
788
+ src1_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src1_idx)))
789
+ src2_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src2_idx)))
790
+ dest_slot = reg_ptr(ir.Constant(ir.IntType(32), int(dest_idx)))
791
+ v1 = builder.load(src1_slot)
792
+ v2 = builder.load(src2_slot)
793
+ if op_name == "EQ_REG":
794
+ res = builder.call(cabi_eq, [v1, v2])
795
+ elif op_name == "NEQ_REG":
796
+ res = builder.call(cabi_neq, [v1, v2])
797
+ else:
798
+ res = builder.call(cabi_lt, [v1, v2])
799
+ builder.store(res, dest_slot)
800
+ builder.branch(blocks[idx + 1])
801
+ continue
802
+
803
+ if op_name in ("GT_REG", "LTE_REG", "GTE_REG"):
804
+ dest_idx, src1_idx, src2_idx = operand
805
+ src1_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src1_idx)))
806
+ src2_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src2_idx)))
807
+ dest_slot = reg_ptr(ir.Constant(ir.IntType(32), int(dest_idx)))
808
+ v1 = builder.load(src1_slot)
809
+ v2 = builder.load(src2_slot)
810
+ if op_name == "GT_REG":
811
+ res = builder.call(cabi_gt, [v1, v2])
812
+ elif op_name == "LTE_REG":
813
+ res = builder.call(cabi_lte, [v1, v2])
814
+ else:
815
+ res = builder.call(cabi_gte, [v1, v2])
816
+ builder.store(res, dest_slot)
817
+ builder.branch(blocks[idx + 1])
818
+ continue
819
+
820
+ if op_name in ("AND_REG", "OR_REG"):
821
+ dest_idx, src1_idx, src2_idx = operand
822
+ src1_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src1_idx)))
823
+ src2_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src2_idx)))
824
+ dest_slot = reg_ptr(ir.Constant(ir.IntType(32), int(dest_idx)))
825
+ v1 = builder.load(src1_slot)
826
+ v2 = builder.load(src2_slot)
827
+ if op_name == "AND_REG":
828
+ res = builder.call(cabi_bool_and, [v1, v2])
829
+ else:
830
+ res = builder.call(cabi_bool_or, [v1, v2])
831
+ builder.store(res, dest_slot)
832
+ builder.branch(blocks[idx + 1])
833
+ continue
834
+
835
+ if op_name == "NOT_REG":
836
+ dest_idx, src_idx = operand
837
+ src_slot = reg_ptr(ir.Constant(ir.IntType(32), int(src_idx)))
838
+ dest_slot = reg_ptr(ir.Constant(ir.IntType(32), int(dest_idx)))
839
+ v1 = builder.load(src_slot)
840
+ res = builder.call(cabi_not, [v1])
841
+ builder.store(res, dest_slot)
842
+ builder.branch(blocks[idx + 1])
843
+ continue
844
+
845
+ if op_name == "POP":
846
+ _ = pop()
847
+ builder.branch(blocks[idx + 1])
848
+ continue
849
+
850
+ if op_name == "DUP":
851
+ val = pop()
852
+ push(val)
853
+ push(val)
854
+ builder.branch(blocks[idx + 1])
855
+ continue
856
+
857
+ if op_name in ("ADD", "SUB", "MUL", "DIV", "MOD"):
858
+ b = pop()
859
+ a = pop()
860
+ if op_name == "ADD":
861
+ res = builder.call(cabi_add, [a, b])
862
+ elif op_name == "SUB":
863
+ res = builder.call(cabi_sub, [a, b])
864
+ elif op_name == "MUL":
865
+ res = builder.call(cabi_mul, [a, b])
866
+ elif op_name == "DIV":
867
+ res = builder.call(cabi_div, [a, b])
868
+ else:
869
+ res = builder.call(cabi_mod, [a, b])
870
+ push(res)
871
+ builder.branch(blocks[idx + 1])
872
+ continue
873
+
874
+ if op_name == "POW":
875
+ b = pop()
876
+ a = pop()
877
+ res = builder.call(cabi_pow, [a, b])
878
+ push(res)
879
+ builder.branch(blocks[idx + 1])
880
+ continue
881
+
882
+ if op_name == "NEG":
883
+ a = pop()
884
+ res = builder.call(cabi_neg, [a])
885
+ push(res)
886
+ builder.branch(blocks[idx + 1])
887
+ continue
888
+
889
+ if op_name in ("EQ", "NEQ", "LT", "GT", "LTE", "GTE"):
890
+ b = pop()
891
+ a = pop()
892
+ if op_name == "EQ":
893
+ res = builder.call(cabi_eq, [a, b])
894
+ elif op_name == "NEQ":
895
+ res = builder.call(cabi_neq, [a, b])
896
+ elif op_name == "LT":
897
+ res = builder.call(cabi_lt, [a, b])
898
+ elif op_name == "GT":
899
+ res = builder.call(cabi_gt, [a, b])
900
+ elif op_name == "LTE":
901
+ res = builder.call(cabi_lte, [a, b])
902
+ else:
903
+ res = builder.call(cabi_gte, [a, b])
904
+ push(res)
905
+ builder.branch(blocks[idx + 1])
906
+ continue
907
+
908
+ if op_name == "AND":
909
+ b = pop()
910
+ a = pop()
911
+ res = builder.call(cabi_bool_and, [a, b])
912
+ push(res)
913
+ builder.branch(blocks[idx + 1])
914
+ continue
915
+
916
+ if op_name == "OR":
917
+ b = pop()
918
+ a = pop()
919
+ res = builder.call(cabi_bool_or, [a, b])
920
+ push(res)
921
+ builder.branch(blocks[idx + 1])
922
+ continue
923
+
924
+ if op_name == "NOT":
925
+ a = pop()
926
+ res = builder.call(cabi_not, [a])
927
+ push(res)
928
+ builder.branch(blocks[idx + 1])
929
+ continue
930
+
931
+ if op_name == "JUMP":
932
+ target = int(operand) if operand is not None else idx + 1
933
+ builder.branch(blocks[target])
934
+ continue
935
+
936
+ if op_name == "JUMP_IF_FALSE":
937
+ cond = pop()
938
+ truth = builder.call(cabi_truthy, [cond])
939
+ zero = ir.Constant(ir.IntType(32), 0)
940
+ is_false = builder.icmp_signed("==", truth, zero)
941
+ target = int(operand) if operand is not None else idx + 1
942
+ builder.cbranch(is_false, blocks[target], blocks[idx + 1])
943
+ continue
944
+
945
+ if op_name == "JUMP_IF_TRUE":
946
+ cond = pop()
947
+ truth = builder.call(cabi_truthy, [cond])
948
+ zero = ir.Constant(ir.IntType(32), 0)
949
+ is_true = builder.icmp_signed("!=", truth, zero)
950
+ target = int(operand) if operand is not None else idx + 1
951
+ builder.cbranch(is_true, blocks[target], blocks[idx + 1])
952
+ continue
953
+
954
+ if op_name == "CALL_NAME":
955
+ name_idx, arg_count = operand
956
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
957
+ # build args tuple from stack
958
+ count_val = ir.Constant(ir.IntType(64), int(arg_count))
959
+ cur_sp = builder.load(sp)
960
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), int(arg_count)))
961
+ args_ptr = builder.gep(stack_base, [base])
962
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
963
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
964
+ # pop args
965
+ builder.store(base, sp)
966
+ res = builder.call(cabi_call_name, [env_ptr, builtins_ptr, name_obj, args_tuple])
967
+ push(res)
968
+ builder.branch(blocks[idx + 1])
969
+ continue
970
+
971
+ if op_name == "CALL_FUNC_CONST":
972
+ func_idx, arg_count = operand
973
+ func_obj = const_obj(int(func_idx)) if isinstance(func_idx, int) else ir.Constant(ptr, 0)
974
+ count_val = ir.Constant(ir.IntType(64), int(arg_count))
975
+ cur_sp = builder.load(sp)
976
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), int(arg_count)))
977
+ args_ptr = builder.gep(stack_base, [base])
978
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
979
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
980
+ builder.store(base, sp)
981
+ res = builder.call(cabi_call_callable, [func_obj, args_tuple])
982
+ push(res)
983
+ builder.branch(blocks[idx + 1])
984
+ continue
985
+
986
+ if op_name == "CALL_BUILTIN":
987
+ name_idx, arg_count = operand
988
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
989
+ count_val = ir.Constant(ir.IntType(64), int(arg_count))
990
+ cur_sp = builder.load(sp)
991
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), int(arg_count)))
992
+ args_ptr = builder.gep(stack_base, [base])
993
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
994
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
995
+ builder.store(base, sp)
996
+ null_env = ir.Constant(ptr, 0)
997
+ res = builder.call(cabi_call_name, [null_env, builtins_ptr, name_obj, args_tuple])
998
+ push(res)
999
+ builder.branch(blocks[idx + 1])
1000
+ continue
1001
+
1002
+ if op_name == "CALL_METHOD":
1003
+ method_idx, arg_count = operand
1004
+ count_val = ir.Constant(ir.IntType(64), int(arg_count))
1005
+ cur_sp = builder.load(sp)
1006
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), int(arg_count)))
1007
+ args_ptr = builder.gep(stack_base, [base])
1008
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1009
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1010
+ builder.store(base, sp)
1011
+ target = pop()
1012
+ method_obj = const_obj(int(method_idx)) if isinstance(method_idx, int) else ir.Constant(ptr, 0)
1013
+ res = builder.call(cabi_call_method, [target, method_obj, args_tuple])
1014
+ push(res)
1015
+ builder.branch(blocks[idx + 1])
1016
+ continue
1017
+
1018
+ if op_name == "CALL_TOP":
1019
+ arg_count = int(operand) if operand is not None else 0
1020
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1021
+ cur_sp = builder.load(sp)
1022
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1023
+ args_ptr = builder.gep(stack_base, [base])
1024
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1025
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1026
+ builder.store(base, sp)
1027
+ callable_obj = pop()
1028
+ res = builder.call(cabi_call_callable, [callable_obj, args_tuple])
1029
+ push(res)
1030
+ builder.branch(blocks[idx + 1])
1031
+ continue
1032
+
1033
+ if op_name == "SETUP_TRY":
1034
+ handler = int(operand) if operand is not None else idx + 1
1035
+ try_push(ir.Constant(ir.IntType(32), handler))
1036
+ builder.branch(blocks[idx + 1])
1037
+ continue
1038
+
1039
+ if op_name == "POP_TRY":
1040
+ _ = try_pop()
1041
+ builder.branch(blocks[idx + 1])
1042
+ continue
1043
+
1044
+ if op_name == "THROW":
1045
+ exc = pop()
1046
+ cur_sp = builder.load(try_sp)
1047
+ has_handler = builder.icmp_unsigned("!=", cur_sp, ir.Constant(ir.IntType(32), 0))
1048
+ handler_block = func.append_basic_block(name=f"throw_handler_{idx}")
1049
+ no_handler_block = func.append_basic_block(name=f"throw_unhandled_{idx}")
1050
+ builder.cbranch(has_handler, handler_block, no_handler_block)
1051
+
1052
+ handler_builder = ir.IRBuilder(handler_block)
1053
+ handler_idx = try_pop_with(handler_builder)
1054
+ push_with(handler_builder, exc)
1055
+ switch_inst = handler_builder.switch(handler_idx, blocks[idx + 1])
1056
+ for case_idx, block in enumerate(blocks):
1057
+ switch_inst.add_case(ir.Constant(ir.IntType(32), case_idx), block)
1058
+
1059
+ no_handler_builder = ir.IRBuilder(no_handler_block)
1060
+ no_handler_builder.ret(exc)
1061
+ continue
1062
+
1063
+ if op_name == "FOR_ITER":
1064
+ target = int(operand) if operand is not None else idx + 1
1065
+ iter_obj = pop()
1066
+ iter_obj = builder.call(cabi_get_iter, [iter_obj])
1067
+ pair = builder.call(cabi_iter_next_pair, [iter_obj])
1068
+ one_obj = builder.call(cabi_int_from_long, [ir.Constant(ir.IntType(64), 1)])
1069
+ zero_obj = builder.call(cabi_int_from_long, [ir.Constant(ir.IntType(64), 0)])
1070
+ has_flag = builder.call(cabi_index, [pair, one_obj])
1071
+ truth = builder.call(cabi_truthy, [has_flag])
1072
+ is_true = builder.icmp_signed("!=", truth, ir.Constant(ir.IntType(32), 0))
1073
+ has_block = func.append_basic_block(name=f"for_has_{idx}")
1074
+ done_block = func.append_basic_block(name=f"for_done_{idx}")
1075
+ builder.cbranch(is_true, has_block, done_block)
1076
+
1077
+ has_builder = ir.IRBuilder(has_block)
1078
+ val = has_builder.call(cabi_index, [pair, zero_obj])
1079
+ push_with(has_builder, iter_obj)
1080
+ push_with(has_builder, val)
1081
+ has_builder.branch(blocks[idx + 1])
1082
+
1083
+ done_builder = ir.IRBuilder(done_block)
1084
+ done_builder.branch(blocks[target])
1085
+ continue
1086
+
1087
+ if op_name == "BUILD_LIST":
1088
+ count = int(operand) if operand is not None else 0
1089
+ count_val = ir.Constant(ir.IntType(64), count)
1090
+ cur_sp = builder.load(sp)
1091
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), count))
1092
+ items_ptr = builder.gep(stack_base, [base])
1093
+ items_ptr_cast = builder.bitcast(items_ptr, ptr)
1094
+ lst = builder.call(cabi_build_list, [items_ptr_cast, count_val])
1095
+ builder.store(base, sp)
1096
+ push(lst)
1097
+ builder.branch(blocks[idx + 1])
1098
+ continue
1099
+
1100
+ if op_name == "BUILD_MAP":
1101
+ count = int(operand) if operand is not None else 0
1102
+ count_val = ir.Constant(ir.IntType(64), count * 2)
1103
+ cur_sp = builder.load(sp)
1104
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), count * 2))
1105
+ items_ptr = builder.gep(stack_base, [base])
1106
+ items_ptr_cast = builder.bitcast(items_ptr, ptr)
1107
+ mp = builder.call(cabi_build_map, [items_ptr_cast, count_val])
1108
+ builder.store(base, sp)
1109
+ push(mp)
1110
+ builder.branch(blocks[idx + 1])
1111
+ continue
1112
+
1113
+ if op_name == "BUILD_SET":
1114
+ count = int(operand) if operand is not None else 0
1115
+ count_val = ir.Constant(ir.IntType(64), count)
1116
+ cur_sp = builder.load(sp)
1117
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), count))
1118
+ items_ptr = builder.gep(stack_base, [base])
1119
+ items_ptr_cast = builder.bitcast(items_ptr, ptr)
1120
+ st = builder.call(cabi_build_set, [items_ptr_cast, count_val])
1121
+ builder.store(base, sp)
1122
+ push(st)
1123
+ builder.branch(blocks[idx + 1])
1124
+ continue
1125
+
1126
+ if op_name == "INDEX":
1127
+ idx_val = pop()
1128
+ obj_val = pop()
1129
+ res = builder.call(cabi_index, [obj_val, idx_val])
1130
+ push(res)
1131
+ builder.branch(blocks[idx + 1])
1132
+ continue
1133
+
1134
+ if op_name == "SLICE":
1135
+ count = int(operand) if operand is not None else 2
1136
+ end_val = pop() if count >= 3 else ir.Constant(ptr, None)
1137
+ start_val = pop()
1138
+ obj_val = pop()
1139
+ res = builder.call(cabi_slice, [obj_val, start_val, end_val])
1140
+ push(res)
1141
+ builder.branch(blocks[idx + 1])
1142
+ continue
1143
+
1144
+ if op_name == "GET_ATTR":
1145
+ attr = pop()
1146
+ obj = pop()
1147
+ res = builder.call(cabi_get_attr, [obj, attr])
1148
+ push(res)
1149
+ builder.branch(blocks[idx + 1])
1150
+ continue
1151
+
1152
+ if op_name == "GET_LENGTH":
1153
+ obj = pop()
1154
+ res = builder.call(cabi_get_length, [obj])
1155
+ push(res)
1156
+ builder.branch(blocks[idx + 1])
1157
+ continue
1158
+
1159
+ if op_name == "PRINT":
1160
+ val = pop()
1161
+ _ = builder.call(cabi_print, [val])
1162
+ builder.branch(blocks[idx + 1])
1163
+ continue
1164
+
1165
+ if op_name == "READ":
1166
+ path = pop()
1167
+ res = builder.call(cabi_read, [path])
1168
+ push(res)
1169
+ builder.branch(blocks[idx + 1])
1170
+ continue
1171
+
1172
+ if op_name == "WRITE":
1173
+ content = pop()
1174
+ path = pop()
1175
+ _ = builder.call(cabi_write, [path, content])
1176
+ builder.branch(blocks[idx + 1])
1177
+ continue
1178
+
1179
+ if op_name == "IMPORT":
1180
+ if isinstance(operand, (list, tuple)) and operand:
1181
+ name_idx = operand[0]
1182
+ alias_idx = operand[1] if len(operand) > 1 else None
1183
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1184
+ alias_obj = const_obj(int(alias_idx)) if isinstance(alias_idx, int) else name_obj
1185
+ res = builder.call(cabi_import, [name_obj])
1186
+ builder.call(cabi_env_set, [env_ptr, alias_obj, res])
1187
+ else:
1188
+ name = pop()
1189
+ res = builder.call(cabi_import, [name])
1190
+ push(res)
1191
+ builder.branch(blocks[idx + 1])
1192
+ continue
1193
+
1194
+ if op_name == "EXPORT":
1195
+ if isinstance(operand, (list, tuple)) and operand:
1196
+ name_idx = operand[0]
1197
+ value_idx = operand[1] if len(operand) > 1 else None
1198
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1199
+ if isinstance(value_idx, int):
1200
+ value_obj = const_obj(int(value_idx))
1201
+ else:
1202
+ value_obj = pop()
1203
+ builder.call(cabi_export, [env_ptr, name_obj, value_obj])
1204
+ elif isinstance(operand, int):
1205
+ name_obj = const_obj(int(operand))
1206
+ builder.call(cabi_export, [env_ptr, name_obj, ir.Constant(ptr, 0)])
1207
+ else:
1208
+ value_obj = pop()
1209
+ name_obj = pop()
1210
+ builder.call(cabi_export, [env_ptr, name_obj, value_obj])
1211
+ builder.branch(blocks[idx + 1])
1212
+ continue
1213
+
1214
+ if op_name == "SPAWN":
1215
+ if isinstance(operand, tuple) and len(operand) >= 3 and operand[0] == "CALL":
1216
+ name_idx = operand[1]
1217
+ arg_count = int(operand[2])
1218
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1219
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1220
+ cur_sp = builder.load(sp)
1221
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1222
+ args_ptr = builder.gep(stack_base, [base])
1223
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1224
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1225
+ builder.store(base, sp)
1226
+ res = builder.call(cabi_spawn_name, [vm_ptr, env_ptr, builtins_ptr, name_obj, args_tuple])
1227
+ push(res)
1228
+ else:
1229
+ arg_count = int(operand) if operand is not None else 0
1230
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1231
+ cur_sp = builder.load(sp)
1232
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1233
+ args_ptr = builder.gep(stack_base, [base])
1234
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1235
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1236
+ builder.store(base, sp)
1237
+ callable_obj = pop()
1238
+ res = builder.call(cabi_spawn_call, [vm_ptr, callable_obj, args_tuple])
1239
+ push(res)
1240
+ builder.branch(blocks[idx + 1])
1241
+ continue
1242
+
1243
+ if op_name == "SPAWN_CALL":
1244
+ if isinstance(operand, tuple) and len(operand) >= 2 and operand[0] == "CALL_NAME":
1245
+ name_idx = operand[1]
1246
+ arg_count = int(operand[2]) if len(operand) > 2 else 0
1247
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1248
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1249
+ cur_sp = builder.load(sp)
1250
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1251
+ args_ptr = builder.gep(stack_base, [base])
1252
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1253
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1254
+ builder.store(base, sp)
1255
+ res = builder.call(cabi_spawn_name, [vm_ptr, env_ptr, builtins_ptr, name_obj, args_tuple])
1256
+ push(res)
1257
+ elif isinstance(operand, tuple) and len(operand) >= 2 and operand[0] == "CALL_BUILTIN":
1258
+ name_idx = operand[1]
1259
+ arg_count = int(operand[2]) if len(operand) > 2 else 0
1260
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1261
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1262
+ cur_sp = builder.load(sp)
1263
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1264
+ args_ptr = builder.gep(stack_base, [base])
1265
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1266
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1267
+ builder.store(base, sp)
1268
+ res = builder.call(cabi_spawn_name, [vm_ptr, env_ptr, builtins_ptr, name_obj, args_tuple])
1269
+ push(res)
1270
+ elif isinstance(operand, tuple) and len(operand) >= 2 and operand[0] == "CALL_FUNC_CONST":
1271
+ func_idx = operand[1]
1272
+ arg_count = int(operand[2]) if len(operand) > 2 else 0
1273
+ func_obj = const_obj(int(func_idx)) if isinstance(func_idx, int) else ir.Constant(ptr, 0)
1274
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1275
+ cur_sp = builder.load(sp)
1276
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1277
+ args_ptr = builder.gep(stack_base, [base])
1278
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1279
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1280
+ builder.store(base, sp)
1281
+ res = builder.call(cabi_spawn_call, [vm_ptr, func_obj, args_tuple])
1282
+ push(res)
1283
+ elif isinstance(operand, tuple) and len(operand) >= 2 and operand[0] == "CALL_TOP":
1284
+ arg_count = int(operand[1]) if len(operand) > 1 else 0
1285
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1286
+ cur_sp = builder.load(sp)
1287
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1288
+ args_ptr = builder.gep(stack_base, [base])
1289
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1290
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1291
+ builder.store(base, sp)
1292
+ callable_obj = pop()
1293
+ res = builder.call(cabi_spawn_call, [vm_ptr, callable_obj, args_tuple])
1294
+ push(res)
1295
+ else:
1296
+ arg_count = int(operand) if operand is not None else 0
1297
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1298
+ cur_sp = builder.load(sp)
1299
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1300
+ args_ptr = builder.gep(stack_base, [base])
1301
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1302
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1303
+ builder.store(base, sp)
1304
+ callable_obj = pop()
1305
+ res = builder.call(cabi_spawn_call, [vm_ptr, callable_obj, args_tuple])
1306
+ push(res)
1307
+ builder.branch(blocks[idx + 1])
1308
+ continue
1309
+
1310
+ if op_name == "SPAWN_TASK":
1311
+ if isinstance(operand, tuple) and len(operand) >= 2 and operand[0] == "CALL_NAME":
1312
+ name_idx = operand[1]
1313
+ arg_count = int(operand[2]) if len(operand) > 2 else 0
1314
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1315
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1316
+ cur_sp = builder.load(sp)
1317
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1318
+ args_ptr = builder.gep(stack_base, [base])
1319
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1320
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1321
+ builder.store(base, sp)
1322
+ res = builder.call(cabi_spawn_name, [vm_ptr, env_ptr, builtins_ptr, name_obj, args_tuple])
1323
+ push(res)
1324
+ elif isinstance(operand, tuple) and len(operand) >= 2 and operand[0] == "CALL_BUILTIN":
1325
+ name_idx = operand[1]
1326
+ arg_count = int(operand[2]) if len(operand) > 2 else 0
1327
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1328
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1329
+ cur_sp = builder.load(sp)
1330
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1331
+ args_ptr = builder.gep(stack_base, [base])
1332
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1333
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1334
+ builder.store(base, sp)
1335
+ res = builder.call(cabi_spawn_name, [vm_ptr, env_ptr, builtins_ptr, name_obj, args_tuple])
1336
+ push(res)
1337
+ elif isinstance(operand, tuple) and len(operand) >= 2 and operand[0] == "CALL_FUNC_CONST":
1338
+ func_idx = operand[1]
1339
+ arg_count = int(operand[2]) if len(operand) > 2 else 0
1340
+ func_obj = const_obj(int(func_idx)) if isinstance(func_idx, int) else ir.Constant(ptr, 0)
1341
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1342
+ cur_sp = builder.load(sp)
1343
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1344
+ args_ptr = builder.gep(stack_base, [base])
1345
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1346
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1347
+ builder.store(base, sp)
1348
+ res = builder.call(cabi_spawn_call, [vm_ptr, func_obj, args_tuple])
1349
+ push(res)
1350
+ elif isinstance(operand, tuple) and len(operand) >= 2 and operand[0] == "CALL_TOP":
1351
+ arg_count = int(operand[1]) if len(operand) > 1 else 0
1352
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1353
+ cur_sp = builder.load(sp)
1354
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1355
+ args_ptr = builder.gep(stack_base, [base])
1356
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1357
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1358
+ builder.store(base, sp)
1359
+ callable_obj = pop()
1360
+ res = builder.call(cabi_spawn_call, [vm_ptr, callable_obj, args_tuple])
1361
+ push(res)
1362
+ else:
1363
+ arg_count = int(operand) if operand is not None else 0
1364
+ count_val = ir.Constant(ir.IntType(64), arg_count)
1365
+ cur_sp = builder.load(sp)
1366
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), arg_count))
1367
+ args_ptr = builder.gep(stack_base, [base])
1368
+ args_ptr_cast = builder.bitcast(args_ptr, ptr)
1369
+ args_tuple = builder.call(cabi_build_tuple, [args_ptr_cast, count_val])
1370
+ builder.store(base, sp)
1371
+ callable_obj = pop()
1372
+ res = builder.call(cabi_spawn_call, [vm_ptr, callable_obj, args_tuple])
1373
+ push(res)
1374
+ builder.branch(blocks[idx + 1])
1375
+ continue
1376
+
1377
+ if op_name == "TASK_JOIN":
1378
+ task_obj = pop() if operand is None else (const_obj(int(operand)) if isinstance(operand, int) else pop())
1379
+ _ = builder.call(cabi_await, [vm_ptr, task_obj])
1380
+ builder.branch(blocks[idx + 1])
1381
+ continue
1382
+
1383
+ if op_name == "TASK_RESULT":
1384
+ task_obj = pop() if operand is None else (const_obj(int(operand)) if isinstance(operand, int) else pop())
1385
+ res = builder.call(cabi_await, [vm_ptr, task_obj])
1386
+ push(res)
1387
+ builder.branch(blocks[idx + 1])
1388
+ continue
1389
+
1390
+ if op_name == "AWAIT":
1391
+ obj = pop()
1392
+ res = builder.call(cabi_await, [vm_ptr, obj])
1393
+ push(res)
1394
+ builder.branch(blocks[idx + 1])
1395
+ continue
1396
+
1397
+ if op_name == "REGISTER_EVENT":
1398
+ if isinstance(operand, (list, tuple)):
1399
+ name_idx = operand[0] if len(operand) > 0 else None
1400
+ handler_idx = operand[1] if len(operand) > 1 else None
1401
+ else:
1402
+ name_idx = operand
1403
+ handler_idx = None
1404
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1405
+ handler_obj = const_obj(int(handler_idx)) if isinstance(handler_idx, int) else ir.Constant(ptr, 0)
1406
+ builder.call(cabi_register_event, [vm_ptr, name_obj, handler_obj])
1407
+ builder.branch(blocks[idx + 1])
1408
+ continue
1409
+
1410
+ if op_name == "EMIT_EVENT":
1411
+ if isinstance(operand, (list, tuple)):
1412
+ name_idx = operand[0] if len(operand) > 0 else None
1413
+ payload_idx = operand[1] if len(operand) > 1 else None
1414
+ else:
1415
+ name_idx = operand
1416
+ payload_idx = None
1417
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1418
+ if isinstance(payload_idx, int):
1419
+ payload_obj = const_obj(int(payload_idx))
1420
+ builder.call(cabi_emit_event, [vm_ptr, env_ptr, builtins_ptr, name_obj, payload_obj])
1421
+ builder.branch(blocks[idx + 1])
1422
+ continue
1423
+
1424
+ cur_sp = builder.load(sp)
1425
+ has_payload = builder.icmp_signed("!=", cur_sp, ir.Constant(ir.IntType(32), 0))
1426
+ has_block = func.append_basic_block(name=f"emit_has_payload_{idx}")
1427
+ none_block = func.append_basic_block(name=f"emit_no_payload_{idx}")
1428
+ merge_block = func.append_basic_block(name=f"emit_merge_{idx}")
1429
+ builder.cbranch(has_payload, has_block, none_block)
1430
+
1431
+ has_builder = ir.IRBuilder(has_block)
1432
+ payload_val = None
1433
+ # pop in has payload path
1434
+ has_cur_sp = has_builder.load(sp)
1435
+ has_new_sp = has_builder.sub(has_cur_sp, ir.Constant(ir.IntType(32), 1))
1436
+ has_builder.store(has_new_sp, sp)
1437
+ has_ptr_slot = has_builder.gep(stack_base, [has_new_sp])
1438
+ payload_val = has_builder.load(has_ptr_slot)
1439
+ has_builder.branch(merge_block)
1440
+
1441
+ none_builder = ir.IRBuilder(none_block)
1442
+ none_builder.branch(merge_block)
1443
+
1444
+ merge_builder = ir.IRBuilder(merge_block)
1445
+ payload_phi = merge_builder.phi(ptr)
1446
+ payload_phi.add_incoming(payload_val, has_block)
1447
+ payload_phi.add_incoming(ir.Constant(ptr, 0), none_block)
1448
+ merge_builder.call(cabi_emit_event, [vm_ptr, env_ptr, builtins_ptr, name_obj, payload_phi])
1449
+ merge_builder.branch(blocks[idx + 1])
1450
+ continue
1451
+
1452
+ if op_name == "HASH_BLOCK":
1453
+ obj = pop()
1454
+ res = builder.call(cabi_hash_block, [obj])
1455
+ push(res)
1456
+ builder.branch(blocks[idx + 1])
1457
+ continue
1458
+
1459
+ if op_name == "VERIFY_SIGNATURE":
1460
+ pk = pop()
1461
+ msg = pop()
1462
+ sig = pop()
1463
+ res = builder.call(cabi_verify_signature, [env_ptr, builtins_ptr, sig, msg, pk])
1464
+ push(res)
1465
+ builder.branch(blocks[idx + 1])
1466
+ continue
1467
+
1468
+ if op_name == "MERKLE_ROOT":
1469
+ count = int(operand) if operand is not None else 0
1470
+ count_val = ir.Constant(ir.IntType(64), count)
1471
+ cur_sp = builder.load(sp)
1472
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), count))
1473
+ items_ptr = builder.gep(stack_base, [base])
1474
+ items_ptr_cast = builder.bitcast(items_ptr, ptr)
1475
+ res = builder.call(cabi_merkle_root, [items_ptr_cast, count_val])
1476
+ builder.store(base, sp)
1477
+ push(res)
1478
+ builder.branch(blocks[idx + 1])
1479
+ continue
1480
+
1481
+ if op_name == "STATE_READ":
1482
+ key_obj = pop() if operand is None else (const_obj(int(operand)) if isinstance(operand, int) else ir.Constant(ptr, 0))
1483
+ res = builder.call(cabi_state_read, [env_ptr, key_obj])
1484
+ push(res)
1485
+ builder.branch(blocks[idx + 1])
1486
+ continue
1487
+
1488
+ if op_name == "STATE_WRITE":
1489
+ val = pop()
1490
+ key_obj = pop() if operand is None else (const_obj(int(operand)) if isinstance(operand, int) else ir.Constant(ptr, 0))
1491
+ builder.call(cabi_state_write, [env_ptr, key_obj, val])
1492
+ builder.branch(blocks[idx + 1])
1493
+ continue
1494
+
1495
+ if op_name == "TX_BEGIN":
1496
+ builder.call(cabi_tx_begin, [env_ptr])
1497
+ builder.branch(blocks[idx + 1])
1498
+ continue
1499
+
1500
+ if op_name == "TX_COMMIT":
1501
+ builder.call(cabi_tx_commit, [env_ptr])
1502
+ builder.branch(blocks[idx + 1])
1503
+ continue
1504
+
1505
+ if op_name == "TX_REVERT":
1506
+ builder.call(cabi_tx_revert, [env_ptr])
1507
+ builder.branch(blocks[idx + 1])
1508
+ continue
1509
+
1510
+ if op_name == "GAS_CHARGE":
1511
+ if isinstance(operand, int):
1512
+ amount_obj = builder.call(cabi_int_from_long, [ir.Constant(ir.IntType(64), int(operand))])
1513
+ else:
1514
+ amount_obj = pop()
1515
+ res = builder.call(cabi_gas_charge, [env_ptr, amount_obj])
1516
+ null_ptr = ir.Constant(ptr, None)
1517
+ has_err = builder.icmp_unsigned("!=", res, null_ptr)
1518
+ err_block = func.append_basic_block(name=f"gas_err_{idx}")
1519
+ builder.cbranch(has_err, err_block, blocks[idx + 1])
1520
+ err_builder = ir.IRBuilder(err_block)
1521
+ err_builder.ret(res)
1522
+ continue
1523
+
1524
+ if op_name == "REQUIRE":
1525
+ msg_obj = None
1526
+ if isinstance(operand, int):
1527
+ msg_obj = const_obj(int(operand))
1528
+ else:
1529
+ msg_obj = pop()
1530
+ cond_obj = pop()
1531
+ res = builder.call(cabi_require, [env_ptr, cond_obj, msg_obj])
1532
+ null_ptr = ir.Constant(ptr, None)
1533
+ has_err = builder.icmp_unsigned("!=", res, null_ptr)
1534
+ err_block = func.append_basic_block(name=f"req_err_{idx}")
1535
+ builder.cbranch(has_err, err_block, blocks[idx + 1])
1536
+ err_builder = ir.IRBuilder(err_block)
1537
+ err_builder.ret(res)
1538
+ continue
1539
+
1540
+ if op_name == "LEDGER_APPEND":
1541
+ entry = pop()
1542
+ builder.call(cabi_ledger_append, [env_ptr, entry])
1543
+ builder.branch(blocks[idx + 1])
1544
+ continue
1545
+
1546
+ if op_name == "DEFINE_ENUM":
1547
+ if isinstance(operand, (list, tuple)) and len(operand) >= 2:
1548
+ name_idx = operand[0]
1549
+ spec_idx = operand[1]
1550
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1551
+ spec_obj = const_obj(int(spec_idx)) if isinstance(spec_idx, int) else ir.Constant(ptr, 0)
1552
+ builder.call(cabi_define_enum, [env_ptr, name_obj, spec_obj])
1553
+ builder.branch(blocks[idx + 1])
1554
+ continue
1555
+
1556
+ if op_name == "DEFINE_SCREEN":
1557
+ if isinstance(operand, (list, tuple)) and len(operand) >= 2:
1558
+ name_idx = operand[0]
1559
+ props_idx = operand[1]
1560
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1561
+ props_obj = const_obj(int(props_idx)) if isinstance(props_idx, int) else ir.Constant(ptr, 0)
1562
+ else:
1563
+ props_obj = pop()
1564
+ name_obj = pop()
1565
+ builder.call(cabi_define_screen, [env_ptr, name_obj, props_obj])
1566
+ builder.branch(blocks[idx + 1])
1567
+ continue
1568
+
1569
+ if op_name == "DEFINE_COMPONENT":
1570
+ if isinstance(operand, (list, tuple)) and len(operand) >= 2:
1571
+ name_idx = operand[0]
1572
+ props_idx = operand[1]
1573
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1574
+ props_obj = const_obj(int(props_idx)) if isinstance(props_idx, int) else ir.Constant(ptr, 0)
1575
+ else:
1576
+ props_obj = pop()
1577
+ name_obj = pop()
1578
+ builder.call(cabi_define_component, [env_ptr, name_obj, props_obj])
1579
+ builder.branch(blocks[idx + 1])
1580
+ continue
1581
+
1582
+ if op_name == "DEFINE_THEME":
1583
+ if isinstance(operand, (list, tuple)) and len(operand) >= 2:
1584
+ name_idx = operand[0]
1585
+ props_idx = operand[1]
1586
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1587
+ props_obj = const_obj(int(props_idx)) if isinstance(props_idx, int) else ir.Constant(ptr, 0)
1588
+ else:
1589
+ props_obj = pop()
1590
+ name_obj = pop()
1591
+ builder.call(cabi_define_theme, [env_ptr, name_obj, props_obj])
1592
+ builder.branch(blocks[idx + 1])
1593
+ continue
1594
+
1595
+ if op_name == "DEFINE_PROTOCOL":
1596
+ if isinstance(operand, (list, tuple)) and len(operand) >= 2:
1597
+ name_idx = operand[0]
1598
+ spec_idx = operand[1]
1599
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1600
+ spec_obj = const_obj(int(spec_idx)) if isinstance(spec_idx, int) else ir.Constant(ptr, 0)
1601
+ builder.call(cabi_define_protocol, [env_ptr, name_obj, spec_obj])
1602
+ builder.branch(blocks[idx + 1])
1603
+ continue
1604
+
1605
+ if op_name == "ASSERT_PROTOCOL":
1606
+ if isinstance(operand, (list, tuple)) and len(operand) >= 2:
1607
+ name_idx = operand[0]
1608
+ spec_idx = operand[1]
1609
+ name_obj = const_obj(int(name_idx)) if isinstance(name_idx, int) else ir.Constant(ptr, 0)
1610
+ spec_obj = const_obj(int(spec_idx)) if isinstance(spec_idx, int) else ir.Constant(ptr, 0)
1611
+ res = builder.call(cabi_assert_protocol, [env_ptr, name_obj, spec_obj])
1612
+ push(res)
1613
+ else:
1614
+ push(ir.Constant(ptr, 0))
1615
+ builder.branch(blocks[idx + 1])
1616
+ continue
1617
+
1618
+ if op_name == "DEFINE_CAPABILITY":
1619
+ name_obj = pop()
1620
+ definition = pop()
1621
+ builder.call(cabi_define_capability, [env_ptr, name_obj, definition])
1622
+ builder.branch(blocks[idx + 1])
1623
+ continue
1624
+
1625
+ if op_name == "GRANT_CAPABILITY":
1626
+ count = int(operand) if operand is not None else 0
1627
+ count_val = ir.Constant(ir.IntType(64), count)
1628
+ cur_sp = builder.load(sp)
1629
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), count))
1630
+ items_ptr = builder.gep(stack_base, [base])
1631
+ items_ptr_cast = builder.bitcast(items_ptr, ptr)
1632
+ builder.store(base, sp)
1633
+ entity_name = pop()
1634
+ builder.call(cabi_grant_capability, [env_ptr, entity_name, items_ptr_cast, count_val])
1635
+ builder.branch(blocks[idx + 1])
1636
+ continue
1637
+
1638
+ if op_name == "REVOKE_CAPABILITY":
1639
+ count = int(operand) if operand is not None else 0
1640
+ count_val = ir.Constant(ir.IntType(64), count)
1641
+ cur_sp = builder.load(sp)
1642
+ base = builder.sub(cur_sp, ir.Constant(ir.IntType(32), count))
1643
+ items_ptr = builder.gep(stack_base, [base])
1644
+ items_ptr_cast = builder.bitcast(items_ptr, ptr)
1645
+ builder.store(base, sp)
1646
+ entity_name = pop()
1647
+ builder.call(cabi_revoke_capability, [env_ptr, entity_name, items_ptr_cast, count_val])
1648
+ builder.branch(blocks[idx + 1])
1649
+ continue
1650
+
1651
+ if op_name == "AUDIT_LOG":
1652
+ ts = pop()
1653
+ action = pop()
1654
+ data = pop()
1655
+ builder.call(cabi_audit_log, [env_ptr, ts, action, data])
1656
+ builder.branch(blocks[idx + 1])
1657
+ continue
1658
+
1659
+ if op_name == "DEFINE_CONTRACT":
1660
+ count = int(operand) if operand is not None else 0
1661
+ count_val = ir.Constant(ir.IntType(64), count)
1662
+ pair_count = ir.Constant(ir.IntType(32), count * 2)
1663
+ cur_sp = builder.load(sp)
1664
+ base = builder.sub(cur_sp, pair_count)
1665
+ items_ptr = builder.gep(stack_base, [base])
1666
+ items_ptr_cast = builder.bitcast(items_ptr, ptr)
1667
+ builder.store(base, sp)
1668
+ name_obj = pop()
1669
+ res = builder.call(cabi_define_contract, [items_ptr_cast, count_val, name_obj])
1670
+ push(res)
1671
+ builder.branch(blocks[idx + 1])
1672
+ continue
1673
+
1674
+ if op_name == "DEFINE_ENTITY":
1675
+ count = int(operand) if operand is not None else 0
1676
+ count_val = ir.Constant(ir.IntType(64), count)
1677
+ pair_count = ir.Constant(ir.IntType(32), count * 2)
1678
+ cur_sp = builder.load(sp)
1679
+ base = builder.sub(cur_sp, pair_count)
1680
+ items_ptr = builder.gep(stack_base, [base])
1681
+ items_ptr_cast = builder.bitcast(items_ptr, ptr)
1682
+ builder.store(base, sp)
1683
+ name_obj = pop()
1684
+ res = builder.call(cabi_define_entity, [items_ptr_cast, count_val, name_obj])
1685
+ push(res)
1686
+ builder.branch(blocks[idx + 1])
1687
+ continue
1688
+
1689
+ if op_name == "RESTRICT_ACCESS":
1690
+ restriction = pop()
1691
+ prop = pop()
1692
+ obj = pop()
1693
+ builder.call(cabi_restrict_access, [env_ptr, obj, prop, restriction])
1694
+ builder.branch(blocks[idx + 1])
1695
+ continue
1696
+
1697
+ if op_name == "ENABLE_ERROR_MODE":
1698
+ builder.call(cabi_enable_error_mode, [env_ptr])
1699
+ builder.branch(blocks[idx + 1])
1700
+ continue
1701
+
1702
+ if op_name == "NOP":
1703
+ builder.branch(blocks[idx + 1])
1704
+ continue
1705
+
1706
+ if op_name in ("PARALLEL_START", "PARALLEL_END"):
1707
+ builder.branch(blocks[idx + 1])
1708
+ continue
1709
+
1710
+ if op_name == "LOCK_ACQUIRE":
1711
+ key_obj = pop() if operand is None else (const_obj(int(operand)) if isinstance(operand, int) else pop())
1712
+ builder.call(cabi_lock_acquire, [env_ptr, key_obj])
1713
+ builder.branch(blocks[idx + 1])
1714
+ continue
1715
+
1716
+ if op_name == "LOCK_RELEASE":
1717
+ key_obj = pop() if operand is None else (const_obj(int(operand)) if isinstance(operand, int) else pop())
1718
+ builder.call(cabi_lock_release, [env_ptr, key_obj])
1719
+ builder.branch(blocks[idx + 1])
1720
+ continue
1721
+
1722
+ if op_name == "BARRIER":
1723
+ barrier_obj = pop()
1724
+ timeout_obj = None
1725
+ if operand is not None and isinstance(operand, int):
1726
+ timeout_obj = const_obj(int(operand))
1727
+ else:
1728
+ timeout_obj = ir.Constant(ptr, 0)
1729
+ res = builder.call(cabi_barrier_wait, [barrier_obj, timeout_obj])
1730
+ push(res)
1731
+ builder.branch(blocks[idx + 1])
1732
+ continue
1733
+
1734
+ if op_name == "ATOMIC_ADD":
1735
+ delta = pop()
1736
+ key_obj = pop() if operand is None else (const_obj(int(operand)) if isinstance(operand, int) else pop())
1737
+ res = builder.call(cabi_atomic_add, [env_ptr, key_obj, delta])
1738
+ push(res)
1739
+ builder.branch(blocks[idx + 1])
1740
+ continue
1741
+
1742
+ if op_name == "ATOMIC_CAS":
1743
+ new_val = pop()
1744
+ expected = pop()
1745
+ key_obj = pop() if operand is None else (const_obj(int(operand)) if isinstance(operand, int) else pop())
1746
+ res = builder.call(cabi_atomic_cas, [env_ptr, key_obj, expected, new_val])
1747
+ push(res)
1748
+ builder.branch(blocks[idx + 1])
1749
+ continue
1750
+
1751
+ if op_name == "ATOMIC_ADD":
1752
+ delta_obj = pop()
1753
+ key_obj = pop() if operand is None else (const_obj(int(operand)) if isinstance(operand, int) else pop())
1754
+ res = builder.call(cabi_atomic_add, [env_ptr, key_obj, delta_obj])
1755
+ push(res)
1756
+ builder.branch(blocks[idx + 1])
1757
+ continue
1758
+
1759
+ if op_name == "ATOMIC_CAS":
1760
+ new_obj = pop()
1761
+ expected_obj = pop()
1762
+ key_obj = pop() if operand is None else (const_obj(int(operand)) if isinstance(operand, int) else pop())
1763
+ res = builder.call(cabi_atomic_cas, [env_ptr, key_obj, expected_obj, new_obj])
1764
+ push(res)
1765
+ builder.branch(blocks[idx + 1])
1766
+ continue
1767
+
1768
+ if op_name == "BARRIER":
1769
+ timeout_obj = ir.Constant(ptr, 0)
1770
+ if operand is not None and isinstance(operand, int):
1771
+ timeout_obj = const_obj(int(operand))
1772
+ barrier_obj = pop()
1773
+ res = builder.call(cabi_barrier_wait, [barrier_obj, timeout_obj])
1774
+ push(res)
1775
+ builder.branch(blocks[idx + 1])
1776
+ continue
1777
+
1778
+ if op_name == "FOR_ITER":
1779
+ cur_sp = builder.load(sp)
1780
+ top_idx = builder.sub(cur_sp, ir.Constant(ir.IntType(32), 1))
1781
+ iter_ptr = builder.gep(stack_base, [top_idx])
1782
+ iter_obj = builder.load(iter_ptr)
1783
+ res = builder.call(cabi_iter_next, [iter_obj])
1784
+ null_ptr = ir.Constant(ptr, 0)
1785
+ is_done = builder.icmp_unsigned("==", res, null_ptr)
1786
+ done_block = func.append_basic_block(name=f"for_done_{idx}")
1787
+ cont_block = func.append_basic_block(name=f"for_cont_{idx}")
1788
+ builder.cbranch(is_done, done_block, cont_block)
1789
+
1790
+ done_builder = ir.IRBuilder(done_block)
1791
+ done_builder.store(top_idx, sp)
1792
+ target = int(operand) if operand is not None else idx + 1
1793
+ done_builder.branch(blocks[target])
1794
+
1795
+ cont_builder = ir.IRBuilder(cont_block)
1796
+ push_with(cont_builder, res)
1797
+ cont_builder.branch(blocks[idx + 1])
1798
+ continue
1799
+
1800
+ if op_name == "RETURN":
1801
+ res = pop()
1802
+ builder.ret(res)
1803
+ continue
1804
+
1805
+ builder.branch(blocks[idx + 1])
1806
+
1807
+ builder = ir.IRBuilder(blocks[-1])
1808
+ builder.ret(ir.Constant(ptr, 0))
1809
+
1810
+ llvm_ir = str(module)
1811
+ mod = llvm.parse_assembly(llvm_ir)
1812
+ mod.verify()
1813
+ self.engine.add_module(mod)
1814
+ self.engine.finalize_object()
1815
+ self.engine.run_static_constructors()
1816
+ return self.engine.get_function_address("jit_obj_fn")