From 0f50b85007f34cc4b0bf38be620e25cc387913f4 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Fri, 15 Nov 2024 17:32:14 -0500 Subject: [PATCH] tracing in exec --- jac/examples/ginsScripts/simple.jac | 6 +++ jac/jaclang/runtimelib/importer.py | 57 ++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/jac/examples/ginsScripts/simple.jac b/jac/examples/ginsScripts/simple.jac index 20e38ee1db..3575887f03 100644 --- a/jac/examples/ginsScripts/simple.jac +++ b/jac/examples/ginsScripts/simple.jac @@ -1,8 +1,14 @@ +can foo() { + return 1; +} + with entry { + foo(); a=0; x=0; if x >= 0{ a=1; } a=-1; + print("hello"); } \ No newline at end of file diff --git a/jac/jaclang/runtimelib/importer.py b/jac/jaclang/runtimelib/importer.py index c865da6603..2e72d6aac0 100644 --- a/jac/jaclang/runtimelib/importer.py +++ b/jac/jaclang/runtimelib/importer.py @@ -63,7 +63,56 @@ def get_caller_dir(self) -> str: chomp_target = chomp_target[1:] return path.join(caller_dir, self.dir_path) - +class CFGTracker: + def __init__(self): + self.count = 0 + def start_tracking(self): + """Start tracking branch coverage""" + sys.settrace(self.trace_callback) + def stop_tracking(self): + """Stop tracking branch coverage""" + sys.settrace(None) + + def trace_callback(self, frame: types.FrameType, event: str, arg: Any) -> Optional[types.TraceFunction]: + """Trace function to track executed branches""" + if event != 'line': + return self.trace_callback + code = frame.f_code + print(f"{frame.f_lineno}") + # print(f"Function Name: {code.co_name}") + # print(f"Filename: {code.co_filename}") + # print(f"First Line Number: {code.co_firstlineno}") + # print(f"Argument Count: {code.co_argcount}") + # print(f"Constants: {code.co_consts}") + # print(f"Local Variables: {code.co_varnames}") + self.count += 1 + + # if event != 'line': + # return self.trace_callback + + # code = frame.f_code + # if code not in self.cfg_cache: + # self.build_cfg(code) + + # # Find current basic block + # blocks = self.cfg_cache[code] + # current_offset = frame.f_lasti + + # # Find the block containing this offset + # current_block = None + # for block in blocks.values(): + # if block.offset <= current_offset <= block.offset + sum(inst.size for inst in block.instructions): + # current_block = block + # break + + # if current_block: + # current_block.hits += 1 + # # Record taken branches + # for next_block in current_block.next: + # self.coverage_data[code].add( + # (current_block.offset, next_block.offset)) + + # return self.trace_callback class ImportReturn: """Import Return Object.""" @@ -153,7 +202,6 @@ def load_jac_mod_as_item( ) if not codeobj: raise ImportError(f"No bytecode found for {jac_file_path}") - exec(codeobj, new_module.__dict__) return getattr(new_module, name, new_module) except ImportError as e: @@ -351,7 +399,12 @@ def run_import( try: with sys_path_context(spec.caller_dir): + tracker = CFGTracker() + tracker.start_tracking() + print("here") exec(codeobj, module.__dict__) + tracker.stop_tracking() + print(f"count={tracker.count}") except Exception as e: logger.error(e) logger.error(dump_traceback(e))