import time from typing import Dict, Any from xic_extensions.gsz3_decompressor import GSZ3Decompressor, GSZ3DecompressionError from xic_extensions.execution_tracer import ExecutionTracer from xic_extensions.profiler import SegmentProfiler from .gx_loader import load_gx, GXLoaderError from .execution_plan import build_execution_plan from .context import ExecutionContext, new_context class ExecutionError(Exception): pass class GXRunner: @staticmethod def execute_gx( path: str, trace: bool = False, profile: bool = False ) -> ExecutionContext: try: manifest, compressed_payload = load_gx(path) try: decompressed = GSZ3Decompressor.decompress(compressed_payload) except GSZ3DecompressionError as e: raise ExecutionError(f"Decompression failed: {e}") plan = build_execution_plan(manifest) tracer = ExecutionTracer(verbose=False) if trace else None profiler = SegmentProfiler() if profile else None context = new_context(manifest, plan, tracer, profiler) if profiler: profiler.start("execution") try: if tracer: with tracer.trace_segment( "full_execution", 0, len(decompressed.encode('utf-8')) ): exec(compile(decompressed, "", "exec"), context.globals) else: exec(compile(decompressed, "", "exec"), context.globals) except ExecutionError: raise except Exception as e: raise ExecutionError(f"Execution failed: {e}") finally: if profiler: profiler.stop("execution") return context except (GXLoaderError, ExecutionError): raise except Exception as e: raise ExecutionError(f"Execution failed: {e}") def execute_gx(path: str, trace: bool = False, profile: bool = False) -> ExecutionContext: return GXRunner.execute_gx(path, trace, profile)