@tracecode/harness 0.6.2 → 0.6.6
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.
- package/CHANGELOG.md +23 -0
- package/dist/browser.cjs +121 -28
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +121 -28
- package/dist/browser.js.map +1 -1
- package/dist/cli.cjs +4 -0
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/core.cjs +121 -27
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +5 -2
- package/dist/core.d.ts +5 -2
- package/dist/core.js +120 -27
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +124 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +123 -28
- package/dist/index.js.map +1 -1
- package/dist/python.cjs +1 -0
- package/dist/python.cjs.map +1 -1
- package/dist/python.js +1 -0
- package/dist/python.js.map +1 -1
- package/package.json +5 -3
- package/workers/java/java-source-augmentations.cjs +242 -0
- package/workers/java/java-worker.js +856 -34
- package/workers/java/src/spike/user/TraceHooks.java +619 -0
- package/workers/python/runtime-core.js +78 -16
- package/workers/vendor/java-browser-spike-helper.jar +0 -0
|
@@ -31,9 +31,12 @@ import sys
|
|
|
31
31
|
import json
|
|
32
32
|
import math
|
|
33
33
|
import ast
|
|
34
|
+
from typing import *
|
|
34
35
|
import builtins as _builtins
|
|
35
36
|
${deps.PYTHON_CLASS_DEFINITIONS_SNIPPET}
|
|
36
37
|
|
|
38
|
+
_TRACECODE_TYPING_GLOBALS = {name for name in globals().keys() if not name.startswith('_')}
|
|
39
|
+
|
|
37
40
|
_trace_data = []
|
|
38
41
|
_console_output = []
|
|
39
42
|
_original_print = _builtins.print
|
|
@@ -69,14 +72,16 @@ ${deps.PYTHON_TRACE_SERIALIZE_FUNCTION_SNIPPET}
|
|
|
69
72
|
|
|
70
73
|
_call_stack = []
|
|
71
74
|
_pending_accesses = {}
|
|
75
|
+
_last_trace_index_by_frame = {}
|
|
72
76
|
_prev_hashmap_snapshots = {}
|
|
73
77
|
_TRACE_MUTATING_METHODS = {'append', 'appendleft', 'pop', 'popleft', 'extend', 'insert'}
|
|
74
|
-
_internal_funcs = {'_serialize', '_tracer', '_custom_print', '_dict_to_tree', '_dict_to_list', '_is_structural_constructor_frame', '_snapshot_call_stack', '_snapshot_locals', '_stable_token', '_looks_like_adjacency_list', '_looks_like_indexed_adjacency_list', '_extract_hashmap_snapshot', '_classify_runtime_object_kind', '_infer_hashmap_delta', '_clear_frame_hashmap_snapshots', '_build_runtime_visualization', '_resolve_inplace_result', '__tracecode_record_access', '__tracecode_flush_accesses', '__tracecode_normalize_indices', '__tracecode_make_access_event', '__tracecode_read_value', '__tracecode_write_value', '__tracecode_apply_augmented_value', '_tracecode_read_index', '_tracecode_write_index', '_tracecode_augassign_index', '_tracecode_mutating_call', '_tracecode_is_pure_literal_scaffold', '_tracecode_collect_collapsed_literal_lines', '__tracecode_attach_parents', '_tracecode_extract_named_subscript', '__TracecodeAccessTransformer', '__tracecode_compile_user_code', '<listcomp>', '<dictcomp>', '<setcomp>', '<genexpr>'}
|
|
78
|
+
_internal_funcs = {'_serialize', '_tracer', '_custom_print', '_dict_to_tree', '_dict_to_list', '_is_structural_constructor_frame', '_snapshot_call_stack', '_snapshot_locals', '_stable_token', '_looks_like_adjacency_list', '_looks_like_indexed_adjacency_list', '_extract_hashmap_snapshot', '_classify_runtime_object_kind', '_infer_hashmap_delta', '_clear_frame_hashmap_snapshots', '_build_runtime_visualization', '_resolve_inplace_result', '__tracecode_record_access', '__tracecode_flush_accesses', '__tracecode_append_trace_step', '__tracecode_attach_accesses_to_previous_step', '__tracecode_normalize_indices', '__tracecode_make_access_event', '__tracecode_read_value', '__tracecode_write_value', '__tracecode_apply_augmented_value', '_tracecode_read_index', '_tracecode_write_index', '_tracecode_augassign_index', '_tracecode_mutating_call', '_tracecode_mutating_index_call', '_tracecode_is_pure_literal_scaffold', '_tracecode_collect_collapsed_literal_lines', '__tracecode_attach_parents', '_tracecode_extract_named_subscript', '__TracecodeAccessTransformer', '__tracecode_compile_user_code', '<listcomp>', '<dictcomp>', '<setcomp>', '<genexpr>'}
|
|
75
79
|
_internal_locals = {
|
|
76
80
|
'_trace_data', '_console_output', '_original_print', '_target_function',
|
|
77
81
|
'_MIRROR_PRINT_TO_WORKER_CONSOLE', '_MINIMAL_TRACE', '_SKIP_SENTINEL',
|
|
78
82
|
'_SCRIPT_MODE', '_TRACE_INPUT_NAMES', '_SCRIPT_PRE_USER_GLOBALS',
|
|
79
|
-
'
|
|
83
|
+
'_TRACECODE_TYPING_GLOBALS',
|
|
84
|
+
'_call_stack', '_pending_accesses', '_last_trace_index_by_frame', '_prev_hashmap_snapshots', '_TRACE_MUTATING_METHODS', '_internal_funcs', '_internal_locals', '_max_trace_steps',
|
|
80
85
|
'_trace_limit_exceeded', '_timeout_reason', '_total_line_events', '_max_line_events',
|
|
81
86
|
'_line_hit_count', '_max_single_line_hits', '_infinite_loop_line',
|
|
82
87
|
'_MAX_SERIALIZE_DEPTH', '_trace_failed', '_inplace',
|
|
@@ -84,10 +89,11 @@ _internal_locals = {
|
|
|
84
89
|
'_is_structural_constructor_frame', '_snapshot_call_stack', '_snapshot_locals', '_stable_token',
|
|
85
90
|
'_looks_like_adjacency_list', '_looks_like_indexed_adjacency_list', '_extract_hashmap_snapshot', '_classify_runtime_object_kind', '_infer_hashmap_delta',
|
|
86
91
|
'_clear_frame_hashmap_snapshots', '_build_runtime_visualization', '_resolve_inplace_result',
|
|
87
|
-
'__tracecode_record_access', '__tracecode_flush_accesses', '
|
|
92
|
+
'__tracecode_record_access', '__tracecode_flush_accesses', '__tracecode_append_trace_step',
|
|
93
|
+
'__tracecode_attach_accesses_to_previous_step', '__tracecode_normalize_indices',
|
|
88
94
|
'__tracecode_make_access_event', '__tracecode_read_value', '__tracecode_write_value',
|
|
89
95
|
'__tracecode_apply_augmented_value', '_tracecode_read_index', '_tracecode_write_index',
|
|
90
|
-
'_tracecode_augassign_index', '_tracecode_mutating_call', '_tracecode_collapsed_literal_lines',
|
|
96
|
+
'_tracecode_augassign_index', '_tracecode_mutating_call', '_tracecode_mutating_index_call', '_tracecode_collapsed_literal_lines',
|
|
91
97
|
'_tracecode_is_pure_literal_scaffold', '_tracecode_collect_collapsed_literal_lines', '__tracecode_attach_parents',
|
|
92
98
|
'_tracecode_extract_named_subscript', '__TracecodeAccessTransformer', '__tracecode_compile_user_code',
|
|
93
99
|
'_InfiniteLoopDetected', '_tb', '_result', '_exc_type', '_exc_msg', '_exc_tb',
|
|
@@ -381,6 +387,27 @@ def __tracecode_flush_accesses(frame):
|
|
|
381
387
|
return []
|
|
382
388
|
return _pending_accesses.pop(id(frame), [])
|
|
383
389
|
|
|
390
|
+
def __tracecode_append_trace_step(frame, step):
|
|
391
|
+
_trace_data.append(step)
|
|
392
|
+
if frame is not None:
|
|
393
|
+
_last_trace_index_by_frame[id(frame)] = len(_trace_data) - 1
|
|
394
|
+
|
|
395
|
+
def __tracecode_attach_accesses_to_previous_step(frame):
|
|
396
|
+
accesses = __tracecode_flush_accesses(frame)
|
|
397
|
+
if not accesses:
|
|
398
|
+
return []
|
|
399
|
+
frame_key = id(frame)
|
|
400
|
+
previous_index = _last_trace_index_by_frame.get(frame_key)
|
|
401
|
+
if previous_index is not None and 0 <= previous_index < len(_trace_data):
|
|
402
|
+
previous_step = _trace_data[previous_index]
|
|
403
|
+
existing_accesses = previous_step.get('accesses')
|
|
404
|
+
if isinstance(existing_accesses, list):
|
|
405
|
+
existing_accesses.extend(accesses)
|
|
406
|
+
else:
|
|
407
|
+
previous_step['accesses'] = accesses
|
|
408
|
+
return []
|
|
409
|
+
return accesses
|
|
410
|
+
|
|
384
411
|
def __tracecode_normalize_indices(indices, max_depth=2):
|
|
385
412
|
if not isinstance(indices, (list, tuple)) or len(indices) == 0 or len(indices) > max_depth:
|
|
386
413
|
return None
|
|
@@ -509,6 +536,18 @@ def _tracecode_mutating_call(var_name, container, method_name, *args, **kwargs):
|
|
|
509
536
|
)
|
|
510
537
|
return result
|
|
511
538
|
|
|
539
|
+
def _tracecode_mutating_index_call(var_name, container, indices, method_name, *args, **kwargs):
|
|
540
|
+
effective_indices = list(indices)
|
|
541
|
+
target = __tracecode_read_value(container, effective_indices)
|
|
542
|
+
result = getattr(target, method_name)(*args, **kwargs)
|
|
543
|
+
normalized = __tracecode_normalize_indices(effective_indices)
|
|
544
|
+
if method_name in _TRACE_MUTATING_METHODS:
|
|
545
|
+
__tracecode_record_access(
|
|
546
|
+
sys._getframe(1),
|
|
547
|
+
__tracecode_make_access_event(var_name, 'mutating-call', normalized, method_name),
|
|
548
|
+
)
|
|
549
|
+
return result
|
|
550
|
+
|
|
512
551
|
def __tracecode_attach_parents(node, parent=None):
|
|
513
552
|
for child in ast.iter_child_nodes(node):
|
|
514
553
|
setattr(child, '__trace_parent__', node)
|
|
@@ -609,6 +648,25 @@ class __TracecodeAccessTransformer(ast.NodeTransformer):
|
|
|
609
648
|
return ast.copy_location(ast.Expr(value=call), node)
|
|
610
649
|
|
|
611
650
|
def visit_Call(self, node):
|
|
651
|
+
if isinstance(node.func, ast.Attribute):
|
|
652
|
+
method_name = node.func.attr
|
|
653
|
+
if method_name in _TRACE_MUTATING_METHODS:
|
|
654
|
+
extracted = _tracecode_extract_named_subscript(node.func.value)
|
|
655
|
+
if extracted is not None:
|
|
656
|
+
var_name, indices = extracted
|
|
657
|
+
call = ast.Call(
|
|
658
|
+
func=ast.Name(id='_tracecode_mutating_index_call', ctx=ast.Load()),
|
|
659
|
+
args=[
|
|
660
|
+
ast.Constant(value=var_name),
|
|
661
|
+
ast.Name(id=var_name, ctx=ast.Load()),
|
|
662
|
+
ast.List(elts=[self.visit(index) for index in indices], ctx=ast.Load()),
|
|
663
|
+
ast.Constant(value=method_name),
|
|
664
|
+
*[self.visit(arg) for arg in node.args],
|
|
665
|
+
],
|
|
666
|
+
keywords=[self.visit(keyword) for keyword in node.keywords],
|
|
667
|
+
)
|
|
668
|
+
return ast.copy_location(call, node)
|
|
669
|
+
|
|
612
670
|
node = self.generic_visit(node)
|
|
613
671
|
if isinstance(node.func, ast.Attribute) and isinstance(node.func.value, ast.Name):
|
|
614
672
|
method_name = node.func.attr
|
|
@@ -919,6 +977,7 @@ def _tracer(frame, event, arg):
|
|
|
919
977
|
|
|
920
978
|
# Fast counter for any loops
|
|
921
979
|
if event == 'line':
|
|
980
|
+
__tracecode_attach_accesses_to_previous_step(frame)
|
|
922
981
|
if frame.f_code.co_filename == '<user_code>' and frame.f_lineno in _tracecode_collapsed_literal_lines:
|
|
923
982
|
return _tracer
|
|
924
983
|
_total_line_events += 1
|
|
@@ -929,14 +988,14 @@ def _tracer(frame, event, arg):
|
|
|
929
988
|
_trace_limit_exceeded = True
|
|
930
989
|
_timeout_reason = 'line-limit'
|
|
931
990
|
_infinite_loop_line = frame.f_lineno
|
|
932
|
-
|
|
991
|
+
__tracecode_append_trace_step(frame, {
|
|
933
992
|
'line': frame.f_lineno,
|
|
934
993
|
'event': 'timeout',
|
|
935
994
|
'variables': {'timeoutReason': _timeout_reason},
|
|
936
995
|
'function': func_name,
|
|
937
996
|
'callStack': _snapshot_call_stack(),
|
|
938
997
|
'stdoutLineCount': len(_console_output),
|
|
939
|
-
'accesses':
|
|
998
|
+
'accesses': [],
|
|
940
999
|
})
|
|
941
1000
|
sys.settrace(None)
|
|
942
1001
|
raise _InfiniteLoopDetected(f"Exceeded {_max_line_events} line events")
|
|
@@ -951,7 +1010,7 @@ def _tracer(frame, event, arg):
|
|
|
951
1010
|
_infinite_loop_line = frame.f_lineno
|
|
952
1011
|
local_vars, local_sources = _snapshot_locals(frame, with_sources=True)
|
|
953
1012
|
local_vars['timeoutReason'] = _timeout_reason
|
|
954
|
-
|
|
1013
|
+
__tracecode_append_trace_step(frame, {
|
|
955
1014
|
'line': frame.f_lineno,
|
|
956
1015
|
'event': 'timeout',
|
|
957
1016
|
'variables': local_vars,
|
|
@@ -959,7 +1018,7 @@ def _tracer(frame, event, arg):
|
|
|
959
1018
|
'function': func_name,
|
|
960
1019
|
'callStack': _snapshot_call_stack(),
|
|
961
1020
|
'stdoutLineCount': len(_console_output),
|
|
962
|
-
'accesses':
|
|
1021
|
+
'accesses': [],
|
|
963
1022
|
'visualization': _build_runtime_visualization(local_vars, frame)
|
|
964
1023
|
})
|
|
965
1024
|
sys.settrace(None)
|
|
@@ -971,14 +1030,15 @@ def _tracer(frame, event, arg):
|
|
|
971
1030
|
_trace_limit_exceeded = True
|
|
972
1031
|
_timeout_reason = 'trace-limit'
|
|
973
1032
|
_infinite_loop_line = frame.f_lineno
|
|
974
|
-
|
|
1033
|
+
__tracecode_attach_accesses_to_previous_step(frame)
|
|
1034
|
+
__tracecode_append_trace_step(frame, {
|
|
975
1035
|
'line': frame.f_lineno,
|
|
976
1036
|
'event': 'timeout',
|
|
977
1037
|
'variables': {'timeoutReason': _timeout_reason},
|
|
978
1038
|
'function': func_name,
|
|
979
1039
|
'callStack': _snapshot_call_stack(),
|
|
980
1040
|
'stdoutLineCount': len(_console_output),
|
|
981
|
-
'accesses':
|
|
1041
|
+
'accesses': [],
|
|
982
1042
|
})
|
|
983
1043
|
sys.settrace(None)
|
|
984
1044
|
raise _InfiniteLoopDetected(f"Exceeded {_max_trace_steps} trace steps")
|
|
@@ -993,7 +1053,7 @@ def _tracer(frame, event, arg):
|
|
|
993
1053
|
})
|
|
994
1054
|
if _MINIMAL_TRACE:
|
|
995
1055
|
return _tracer
|
|
996
|
-
|
|
1056
|
+
__tracecode_append_trace_step(frame, {
|
|
997
1057
|
'line': frame.f_lineno,
|
|
998
1058
|
'event': 'call',
|
|
999
1059
|
'variables': local_vars,
|
|
@@ -1008,7 +1068,7 @@ def _tracer(frame, event, arg):
|
|
|
1008
1068
|
if _MINIMAL_TRACE:
|
|
1009
1069
|
return _tracer
|
|
1010
1070
|
local_vars, local_sources = _snapshot_locals(frame, with_sources=True)
|
|
1011
|
-
|
|
1071
|
+
__tracecode_append_trace_step(frame, {
|
|
1012
1072
|
'line': frame.f_lineno,
|
|
1013
1073
|
'event': event,
|
|
1014
1074
|
'variables': local_vars,
|
|
@@ -1016,13 +1076,14 @@ def _tracer(frame, event, arg):
|
|
|
1016
1076
|
'function': func_name,
|
|
1017
1077
|
'callStack': _snapshot_call_stack(),
|
|
1018
1078
|
'stdoutLineCount': len(_console_output),
|
|
1019
|
-
'accesses':
|
|
1079
|
+
'accesses': [],
|
|
1020
1080
|
'visualization': _build_runtime_visualization(local_vars, frame)
|
|
1021
1081
|
})
|
|
1022
1082
|
elif event == 'return':
|
|
1083
|
+
__tracecode_attach_accesses_to_previous_step(frame)
|
|
1023
1084
|
if not _MINIMAL_TRACE:
|
|
1024
1085
|
local_vars, local_sources = _snapshot_locals(frame, with_sources=True)
|
|
1025
|
-
|
|
1086
|
+
__tracecode_append_trace_step(frame, {
|
|
1026
1087
|
'line': frame.f_lineno,
|
|
1027
1088
|
'event': 'return',
|
|
1028
1089
|
'variables': local_vars,
|
|
@@ -1031,11 +1092,12 @@ def _tracer(frame, event, arg):
|
|
|
1031
1092
|
'returnValue': _serialize(arg),
|
|
1032
1093
|
'callStack': _snapshot_call_stack(),
|
|
1033
1094
|
'stdoutLineCount': len(_console_output),
|
|
1034
|
-
'accesses':
|
|
1095
|
+
'accesses': [],
|
|
1035
1096
|
'visualization': _build_runtime_visualization(local_vars, frame)
|
|
1036
1097
|
})
|
|
1037
1098
|
_clear_frame_hashmap_snapshots(frame)
|
|
1038
1099
|
_pending_accesses.pop(id(frame), None)
|
|
1100
|
+
_last_trace_index_by_frame.pop(id(frame), None)
|
|
1039
1101
|
if _call_stack and _call_stack[-1]['function'] == func_name:
|
|
1040
1102
|
_call_stack.pop()
|
|
1041
1103
|
|
|
@@ -1046,7 +1108,7 @@ def _tracer(frame, event, arg):
|
|
|
1046
1108
|
_real_globals = __builtins__['globals'] if isinstance(__builtins__, dict) else getattr(__builtins__, 'globals')
|
|
1047
1109
|
_real_list = __builtins__['list'] if isinstance(__builtins__, dict) else getattr(__builtins__, 'list')
|
|
1048
1110
|
_globals_dict = _real_globals()
|
|
1049
|
-
_preserve = {"TreeNode", "ListNode", 'sys', 'json', 'math', 'ast', 'print', '__builtins__', '__name__', '__doc__', '__package__', '__loader__', '__spec__'}
|
|
1111
|
+
_preserve = {"TreeNode", "ListNode", 'sys', 'json', 'math', 'ast', 'print', '__builtins__', '__name__', '__doc__', '__package__', '__loader__', '__spec__'} | _TRACECODE_TYPING_GLOBALS
|
|
1050
1112
|
for _k in _real_list(_globals_dict.keys()):
|
|
1051
1113
|
if not _k.startswith('_') and _k not in _preserve:
|
|
1052
1114
|
_globals_dict.pop(_k, None)
|
|
Binary file
|