jaseci 1.4.0.19__py3-none-any.whl → 1.4.0.20__py3-none-any.whl
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.
Potentially problematic release.
This version of jaseci might be problematic. Click here for more details.
- jaseci/VERSION +1 -1
- jaseci/cli_tools/jsctl.py +41 -2
- jaseci/cli_tools/tests/test_jsctl.py +11 -0
- jaseci/extens/act_lib/internal.py +2 -1
- jaseci/extens/act_lib/std.py +7 -0
- jaseci/extens/act_lib/tests/test_std_lib.py +3 -1
- jaseci/extens/api/jsorc_api.py +31 -0
- jaseci/extens/api/walker_api.py +8 -0
- jaseci/jac/interpreter/architype_interp.py +4 -7
- jaseci/jac/interpreter/sentinel_interp.py +4 -1
- jaseci/jac/interpreter/walker_interp.py +16 -8
- jaseci/jac/ir/ast.py +9 -1
- jaseci/jac/machine/jac_scope.py +5 -1
- jaseci/jac/machine/machine_state.py +69 -11
- jaseci/jsorc/jsorc.py +91 -78
- jaseci/jsorc/live_actions.py +1 -0
- jaseci/prim/ability.py +10 -2
- jaseci/prim/sentinel.py +3 -1
- jaseci/prim/walker.py +5 -3
- jaseci/tests/test_jac.py +1 -1
- jaseci/tests/test_stack.py +12 -0
- jaseci/utils/gprof2dot.py +3786 -0
- jaseci/utils/utils.py +52 -43
- {jaseci-1.4.0.19.dist-info → jaseci-1.4.0.20.dist-info}/METADATA +2 -2
- {jaseci-1.4.0.19.dist-info → jaseci-1.4.0.20.dist-info}/RECORD +29 -28
- {jaseci-1.4.0.19.dist-info → jaseci-1.4.0.20.dist-info}/LICENSE +0 -0
- {jaseci-1.4.0.19.dist-info → jaseci-1.4.0.20.dist-info}/WHEEL +0 -0
- {jaseci-1.4.0.19.dist-info → jaseci-1.4.0.20.dist-info}/entry_points.txt +0 -0
- {jaseci-1.4.0.19.dist-info → jaseci-1.4.0.20.dist-info}/top_level.txt +0 -0
jaseci/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.4.0.
|
|
1
|
+
1.4.0.20
|
jaseci/cli_tools/jsctl.py
CHANGED
|
@@ -17,6 +17,7 @@ from jaseci.utils.utils import copy_func
|
|
|
17
17
|
from .book_tools import Book, modifiedBook
|
|
18
18
|
from jaseci.utils.utils import logger, perf_test_start, perf_test_stop, find_first_api
|
|
19
19
|
from jaseci.jsorc.jsorc import JsOrc
|
|
20
|
+
from prettytable import PrettyTable
|
|
20
21
|
|
|
21
22
|
session = None
|
|
22
23
|
|
|
@@ -112,6 +113,39 @@ def resolve_none_type(kwargs):
|
|
|
112
113
|
kwargs[i] = None
|
|
113
114
|
|
|
114
115
|
|
|
116
|
+
def has_profile(output):
|
|
117
|
+
if isinstance(output, dict):
|
|
118
|
+
if "profile" in output.keys():
|
|
119
|
+
if "jac" in output["profile"].keys() and "perf" in output["profile"].keys():
|
|
120
|
+
return True
|
|
121
|
+
return False
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def gen_pretty_table(csv_str):
|
|
125
|
+
rows = csv_str.split("\n")
|
|
126
|
+
row_width = len(rows[0].split(","))
|
|
127
|
+
first_row = rows[0].split(",")
|
|
128
|
+
if first_row[2] == "percall":
|
|
129
|
+
first_row[2] = "percall_tot"
|
|
130
|
+
try:
|
|
131
|
+
table = PrettyTable(first_row)
|
|
132
|
+
for i in rows[1:]:
|
|
133
|
+
row = i.split(",")
|
|
134
|
+
if len(row) != row_width:
|
|
135
|
+
continue
|
|
136
|
+
table.add_row(row)
|
|
137
|
+
return table
|
|
138
|
+
except Exception as e:
|
|
139
|
+
click.echo(f"Something went wrong pretty printing profile: {e}")
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def pretty_profile(output):
|
|
143
|
+
click.echo("Jac Code Profile:")
|
|
144
|
+
click.echo(gen_pretty_table(output["profile"]["jac"]))
|
|
145
|
+
click.echo("\nInternal Jaseci Profile:")
|
|
146
|
+
click.echo(gen_pretty_table(output["profile"]["perf"]))
|
|
147
|
+
|
|
148
|
+
|
|
115
149
|
def interface_api(api_name, is_public, is_cli_only, **kwargs):
|
|
116
150
|
"""
|
|
117
151
|
Interfaces Master apis after processing arguments/parameters
|
|
@@ -137,6 +171,7 @@ def interface_api(api_name, is_public, is_cli_only, **kwargs):
|
|
|
137
171
|
out = session["master"].public_interface_to_api(kwargs, api_name)
|
|
138
172
|
else:
|
|
139
173
|
out = session["master"].general_interface_to_api(kwargs, api_name)
|
|
174
|
+
d_out = out
|
|
140
175
|
if (
|
|
141
176
|
isinstance(out, dict)
|
|
142
177
|
and "report_custom" in out.keys()
|
|
@@ -153,6 +188,8 @@ def interface_api(api_name, is_public, is_cli_only, **kwargs):
|
|
|
153
188
|
if not session["mem-only"]:
|
|
154
189
|
with open(session["filename"], "wb") as f:
|
|
155
190
|
pickle.dump(session, f)
|
|
191
|
+
if has_profile(d_out):
|
|
192
|
+
pretty_profile(d_out)
|
|
156
193
|
|
|
157
194
|
|
|
158
195
|
def extract_api_tree():
|
|
@@ -384,20 +421,22 @@ def script(filename, profile, output):
|
|
|
384
421
|
with open(output, "w") as f:
|
|
385
422
|
f.write("Multi Command Script Output:\n")
|
|
386
423
|
for i in cmds:
|
|
387
|
-
res = CliRunner(mix_stderr=False).invoke(jsctl, i
|
|
424
|
+
res = CliRunner(mix_stderr=False).invoke(jsctl, i)
|
|
388
425
|
click.echo(res.stdout)
|
|
389
426
|
if output:
|
|
390
427
|
with open(output, "a") as f:
|
|
391
428
|
f.write(f"Output for {i}:\n")
|
|
392
429
|
f.write(res.stdout)
|
|
393
430
|
if profile:
|
|
394
|
-
perf = perf_test_stop(prof)
|
|
431
|
+
perf, graph = perf_test_stop(prof)
|
|
395
432
|
click.echo(perf)
|
|
433
|
+
click.echo(graph)
|
|
396
434
|
if output:
|
|
397
435
|
with open(output, "a") as f:
|
|
398
436
|
if profile:
|
|
399
437
|
f.write(f"\nProfile:\n")
|
|
400
438
|
f.write(perf)
|
|
439
|
+
f.write(graph)
|
|
401
440
|
click.echo(f"[saved to {output}]")
|
|
402
441
|
|
|
403
442
|
|
|
@@ -506,6 +506,17 @@ class JsctlTest(TestCaseHelper, TestCase):
|
|
|
506
506
|
],
|
|
507
507
|
)
|
|
508
508
|
|
|
509
|
+
def test_jsctl_pretty_profiles(self):
|
|
510
|
+
self.call(f"actions load local {self.infer_loc}")
|
|
511
|
+
r = self.call(
|
|
512
|
+
f"sentinel register "
|
|
513
|
+
f"{os.path.dirname(__file__)}/graph_can.jac -name gc -set_active true"
|
|
514
|
+
)
|
|
515
|
+
r = self.call("walker run go -profiling true")
|
|
516
|
+
self.assertIn("walker::go", r)
|
|
517
|
+
self.assertIn("cumtime", r)
|
|
518
|
+
self.assertIn("cum_time", r)
|
|
519
|
+
|
|
509
520
|
|
|
510
521
|
class JsctlTestWithSession(TestCaseHelper, TestCase):
|
|
511
522
|
"""Unit tests for Jac language"""
|
|
@@ -14,4 +14,5 @@ def start_perf_test(name: str = "default"):
|
|
|
14
14
|
def stop_perf_test(name: str = "default"):
|
|
15
15
|
if name not in perf_tests.keys():
|
|
16
16
|
return
|
|
17
|
-
|
|
17
|
+
calls, graph = perf_test_stop(perf_tests[name])
|
|
18
|
+
return {"calls": calls, "graph": graph}
|
jaseci/extens/act_lib/std.py
CHANGED
|
@@ -11,6 +11,7 @@ from jaseci.extens.svc.elastic_svc import Elastic
|
|
|
11
11
|
|
|
12
12
|
import sys
|
|
13
13
|
import json
|
|
14
|
+
import time
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
@jaseci_action()
|
|
@@ -49,6 +50,12 @@ def err(*args):
|
|
|
49
50
|
print(*args, file=sys.stderr)
|
|
50
51
|
|
|
51
52
|
|
|
53
|
+
@jaseci_action()
|
|
54
|
+
def sleep(secs: float):
|
|
55
|
+
"""Standard built in for sleep"""
|
|
56
|
+
return time.sleep(secs)
|
|
57
|
+
|
|
58
|
+
|
|
52
59
|
@jaseci_action()
|
|
53
60
|
def sort_by_col(lst: list, col_num: int, reverse: bool = False):
|
|
54
61
|
"""
|
|
@@ -21,7 +21,9 @@ class StdLibTest(CoreTest):
|
|
|
21
21
|
ret = self.call(self.mast, ["walker_run", {"name": "internal_lib"}])
|
|
22
22
|
self.assertEqual(len(ret["report"]), 1)
|
|
23
23
|
self.assertTrue(
|
|
24
|
-
ret["report"][0].startswith(
|
|
24
|
+
ret["report"][0]["calls"].startswith(
|
|
25
|
+
"ncalls,tottime,percall,cumtime,percall,"
|
|
26
|
+
)
|
|
25
27
|
)
|
|
26
28
|
|
|
27
29
|
def test_rand_float_round(self):
|
jaseci/extens/api/jsorc_api.py
CHANGED
|
@@ -88,6 +88,37 @@ class JsOrcApi:
|
|
|
88
88
|
|
|
89
89
|
return new_config
|
|
90
90
|
|
|
91
|
+
@Interface.admin_api()
|
|
92
|
+
def jsorc_refresh(self):
|
|
93
|
+
"""
|
|
94
|
+
refreshing jsorc's config.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
JsOrc.configure()
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
"running_interval": JsOrc._running_interval,
|
|
101
|
+
"config": JsOrc._config,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@Interface.admin_api(cli_args=["name"])
|
|
105
|
+
def service_info(self, name: str):
|
|
106
|
+
"""
|
|
107
|
+
getting service's info.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
# will throw exception if not existing
|
|
111
|
+
svc = JsOrc.svc(name)
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
"enabled": svc.enabled,
|
|
115
|
+
"automated": svc.automated,
|
|
116
|
+
"quiet": svc.quiet,
|
|
117
|
+
"state": svc.state.name,
|
|
118
|
+
"config": svc.config,
|
|
119
|
+
"error": str(svc.error) if svc.error else None,
|
|
120
|
+
}
|
|
121
|
+
|
|
91
122
|
@Interface.admin_api(cli_args=["name"])
|
|
92
123
|
def service_refresh(self, name: str):
|
|
93
124
|
"""
|
jaseci/extens/api/walker_api.py
CHANGED
|
@@ -22,6 +22,11 @@ class WalkerApi:
|
|
|
22
22
|
def __init__(self):
|
|
23
23
|
self.spawned_walker_ids = IdList(self)
|
|
24
24
|
self.yielded_walkers_ids = IdList(self)
|
|
25
|
+
self.reset_profiling(False)
|
|
26
|
+
|
|
27
|
+
def reset_profiling(self, profiling):
|
|
28
|
+
self._profiling = profiling
|
|
29
|
+
self._jac_profile = {}
|
|
25
30
|
|
|
26
31
|
@Interface.private_api(cli_args=["wlk"])
|
|
27
32
|
def walker_get(self, wlk: Walker, mode: str = "default", detailed: bool = False):
|
|
@@ -166,6 +171,7 @@ class WalkerApi:
|
|
|
166
171
|
"""
|
|
167
172
|
Executes walker (assumes walker is primed)
|
|
168
173
|
"""
|
|
174
|
+
self.reset_profiling(profiling)
|
|
169
175
|
return wlk.run(
|
|
170
176
|
start_node=prime, prime_ctx=ctx, request_ctx=_req_ctx, profiling=profiling
|
|
171
177
|
)
|
|
@@ -200,6 +206,7 @@ class WalkerApi:
|
|
|
200
206
|
Creates walker instance, primes walker on node, executes walker,
|
|
201
207
|
reports results, and cleans up walker instance.
|
|
202
208
|
"""
|
|
209
|
+
self.reset_profiling(profiling)
|
|
203
210
|
wlk = self.yielded_walkers_ids.get_obj_by_name(name, silent=True)
|
|
204
211
|
if wlk is None:
|
|
205
212
|
wlk = snt.run_architype(
|
|
@@ -226,6 +233,7 @@ class WalkerApi:
|
|
|
226
233
|
"""
|
|
227
234
|
Walker individual APIs
|
|
228
235
|
"""
|
|
236
|
+
self.reset_profiling(profiling)
|
|
229
237
|
return self.walker_run(name, nd, ctx, _req_ctx, snt, profiling)
|
|
230
238
|
|
|
231
239
|
@Interface.public_api(cli_args=["wlk"])
|
|
@@ -44,7 +44,7 @@ class ArchitypeInterp(Interp):
|
|
|
44
44
|
|
|
45
45
|
kid = self.set_cur_ast(jac_ast)
|
|
46
46
|
|
|
47
|
-
self.push_scope(JacScope(parent=self))
|
|
47
|
+
self.push_scope(JacScope(parent=self, name=f"spawn:{jac_ast.loc_str()}"))
|
|
48
48
|
if kid[0].name == "KW_NODE":
|
|
49
49
|
item = Node(
|
|
50
50
|
m_id=self._m_id,
|
|
@@ -173,14 +173,11 @@ class ArchitypeInterp(Interp):
|
|
|
173
173
|
"""
|
|
174
174
|
kid = self.set_cur_ast(jac_ast)
|
|
175
175
|
root_name = self.run_has_root(kid[1])
|
|
176
|
-
m = Interp(parent_override=self.parent(), caller=self)
|
|
177
|
-
m.push_scope(JacScope(parent=self, here=self))
|
|
178
176
|
try:
|
|
179
|
-
|
|
177
|
+
self.run_code_block(kid[4])
|
|
180
178
|
except Exception as e:
|
|
181
|
-
self.rt_error(f"Internal Exception: {e}",
|
|
182
|
-
local_state =
|
|
183
|
-
self.report = self.report + m.report
|
|
179
|
+
self.rt_error(f"Internal Exception: {e}", self._cur_jac_ast)
|
|
180
|
+
local_state = self._jac_scope.local_scope
|
|
184
181
|
if root_name in local_state.keys():
|
|
185
182
|
obj = local_state[root_name]
|
|
186
183
|
if not isinstance(obj, Node):
|
|
@@ -125,7 +125,9 @@ class SentinelInterp(Interp):
|
|
|
125
125
|
def arch_can_compile(self, jac_ast, arch):
|
|
126
126
|
"""Helper function to statically compile can stmts for arch"""
|
|
127
127
|
kid = self.set_cur_ast(jac_ast)
|
|
128
|
-
self.push_scope(
|
|
128
|
+
self.push_scope(
|
|
129
|
+
JacScope(parent=self, name=f"a_cgen:{jac_ast.loc_str()}", has_obj=None)
|
|
130
|
+
)
|
|
129
131
|
if jac_ast.name in ["attr_block", "walker_block"]:
|
|
130
132
|
for i in kid:
|
|
131
133
|
if i.name == "attr_stmt" and i.kid[0].name == "can_stmt":
|
|
@@ -178,6 +180,7 @@ class SentinelInterp(Interp):
|
|
|
178
180
|
m_id=self._m_id,
|
|
179
181
|
h=self._h,
|
|
180
182
|
name=action_name,
|
|
183
|
+
kind="ability",
|
|
181
184
|
code_ir=ir,
|
|
182
185
|
preset_in_out=preset_in_out,
|
|
183
186
|
access_list=access_list,
|
|
@@ -24,6 +24,7 @@ class WalkerInterp(Interp):
|
|
|
24
24
|
self.scope_and_run(
|
|
25
25
|
jac_ast if jac_ast.name == "walker_block" else kid[-1],
|
|
26
26
|
self.run_walker_block,
|
|
27
|
+
scope_name=f"w_run:{jac_ast.loc_str()}",
|
|
27
28
|
)
|
|
28
29
|
|
|
29
30
|
def run_walker_block(self, jac_ast):
|
|
@@ -188,10 +189,10 @@ class WalkerInterp(Interp):
|
|
|
188
189
|
"""
|
|
189
190
|
kid = self.set_cur_ast(jac_ast)
|
|
190
191
|
param_list = {"args": [], "kwargs": []}
|
|
191
|
-
|
|
192
|
-
m.push_scope(
|
|
192
|
+
self.push_scope(
|
|
193
193
|
JacScope(
|
|
194
194
|
parent=self,
|
|
195
|
+
name=f"p_in_out:{jac_ast.loc_str()}",
|
|
195
196
|
has_obj=self.current_node,
|
|
196
197
|
here=self.current_node,
|
|
197
198
|
visitor=self,
|
|
@@ -199,17 +200,18 @@ class WalkerInterp(Interp):
|
|
|
199
200
|
)
|
|
200
201
|
|
|
201
202
|
if kid[1].name == "param_list":
|
|
202
|
-
param_list =
|
|
203
|
+
param_list = self.run_param_list(kid[1]).value
|
|
203
204
|
try:
|
|
204
205
|
result = act.run_action(param_list, self._jac_scope, self)
|
|
205
206
|
except Exception as e:
|
|
206
|
-
self.rt_error(f"Internal Exception: {e}",
|
|
207
|
+
self.rt_error(f"Internal Exception: {e}", self._cur_jac_ast)
|
|
207
208
|
result = None
|
|
208
209
|
if kid[-1].name == "expression":
|
|
209
|
-
|
|
210
|
-
dest =
|
|
210
|
+
self.run_expression(kid[-1])
|
|
211
|
+
dest = self.pop()
|
|
211
212
|
dest.value = result
|
|
212
213
|
dest.write(kid[-1])
|
|
214
|
+
self.pop_scope()
|
|
213
215
|
|
|
214
216
|
# Helper Functions ##################
|
|
215
217
|
def auto_trigger_node_actions(self, act_list):
|
|
@@ -229,13 +231,19 @@ class WalkerInterp(Interp):
|
|
|
229
231
|
if not i.preset_in_out: # All preset in and outs get executed
|
|
230
232
|
already_executed.append(i.name)
|
|
231
233
|
|
|
232
|
-
def scope_and_run(self, jac_ast, run_func):
|
|
234
|
+
def scope_and_run(self, jac_ast, run_func, scope_name):
|
|
233
235
|
"""
|
|
234
236
|
Helper to run ast elements with execution scope added
|
|
235
237
|
(Useful for running arbitrary code blocks as one-offs)
|
|
236
238
|
"""
|
|
237
239
|
self.push_scope(
|
|
238
|
-
JacScope(
|
|
240
|
+
JacScope(
|
|
241
|
+
parent=self,
|
|
242
|
+
name=scope_name,
|
|
243
|
+
has_obj=self,
|
|
244
|
+
here=self.current_node,
|
|
245
|
+
visitor=self,
|
|
246
|
+
)
|
|
239
247
|
)
|
|
240
248
|
run_func(jac_ast)
|
|
241
249
|
self.pop_scope()
|
jaseci/jac/ir/ast.py
CHANGED
|
@@ -16,7 +16,12 @@ class Ast:
|
|
|
16
16
|
):
|
|
17
17
|
self.name = "unparsed"
|
|
18
18
|
self.kid = []
|
|
19
|
-
self.loc = [
|
|
19
|
+
self.loc = [
|
|
20
|
+
0,
|
|
21
|
+
0,
|
|
22
|
+
mod_name if mod_name is not None else "@default",
|
|
23
|
+
{},
|
|
24
|
+
] # line, col, module, tokens
|
|
20
25
|
|
|
21
26
|
def is_terminal(self):
|
|
22
27
|
"""Returns true if node is a terminal"""
|
|
@@ -37,6 +42,9 @@ class Ast:
|
|
|
37
42
|
if self.is_terminal():
|
|
38
43
|
return self.token()["symbol"]
|
|
39
44
|
|
|
45
|
+
def loc_str(self):
|
|
46
|
+
return f"{self.loc[2]}:{self.loc[0]}"
|
|
47
|
+
|
|
40
48
|
def __str__(self):
|
|
41
49
|
res = f"{self.name}:{self.loc[2]}:{self.loc[0]}:{self.loc[1]}:"
|
|
42
50
|
if self.is_terminal():
|
jaseci/jac/machine/jac_scope.py
CHANGED
|
@@ -8,12 +8,16 @@ from jaseci.jsorc.live_actions import get_global_actions
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class JacScope:
|
|
11
|
-
def __init__(self, parent, has_obj=None, here=None, visitor=None):
|
|
11
|
+
def __init__(self, parent, name, has_obj=None, here=None, visitor=None):
|
|
12
12
|
self.parent = parent
|
|
13
|
+
self.name = name
|
|
13
14
|
self.local_scope = {}
|
|
14
15
|
self.has_obj = has_obj if has_obj else self
|
|
15
16
|
self.context = {}
|
|
16
17
|
self.action_sets = []
|
|
18
|
+
self._start_time = 0 # For profiling
|
|
19
|
+
self._total_time = 0 # For profiling
|
|
20
|
+
self._cum_start_time = None
|
|
17
21
|
self.set_refs(here, visitor)
|
|
18
22
|
self.setup_actions()
|
|
19
23
|
|
|
@@ -19,12 +19,16 @@ from jaseci.prim.edge import Edge
|
|
|
19
19
|
from jaseci.prim.node import Node
|
|
20
20
|
from jaseci.jac.machine.jac_value import JacValue
|
|
21
21
|
from jaseci.jac.jsci_vm.op_codes import JsCmp
|
|
22
|
+
import time
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
class MachineState:
|
|
25
26
|
"""Shared interpreter class across both sentinels and walkers"""
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
recur_detect_set = []
|
|
29
|
+
profile_stack = [None]
|
|
30
|
+
|
|
31
|
+
def __init__(self):
|
|
28
32
|
self.report = []
|
|
29
33
|
self.report_status = None
|
|
30
34
|
self.report_custom = None
|
|
@@ -32,10 +36,6 @@ class MachineState:
|
|
|
32
36
|
self.runtime_errors = []
|
|
33
37
|
self.yielded_walkers_ids = IdList(self)
|
|
34
38
|
self.ignore_node_ids = IdList(self)
|
|
35
|
-
self._parent_override = parent_override
|
|
36
|
-
if not isinstance(self, Element) and caller:
|
|
37
|
-
self._m_id = caller._m_id
|
|
38
|
-
self._h = caller._h
|
|
39
39
|
self._scope_stack = [None]
|
|
40
40
|
self._jac_scope = None
|
|
41
41
|
self._relevant_edges = []
|
|
@@ -46,18 +46,14 @@ class MachineState:
|
|
|
46
46
|
self._loop_limit = 10000
|
|
47
47
|
self._cur_jac_ast = Ast("none")
|
|
48
48
|
self._write_candidate = None
|
|
49
|
+
self._mast = self.get_master()
|
|
50
|
+
|
|
49
51
|
self.inform_hook()
|
|
50
52
|
|
|
51
53
|
def inform_hook(self):
|
|
52
54
|
if hasattr(self, "_h"):
|
|
53
55
|
self._h._machine = self
|
|
54
56
|
|
|
55
|
-
def parent(self): # parent here is always a sentinel
|
|
56
|
-
if self._parent_override:
|
|
57
|
-
return self._parent_override
|
|
58
|
-
else:
|
|
59
|
-
return Element.parent(self)
|
|
60
|
-
|
|
61
57
|
def reset(self):
|
|
62
58
|
self.report = []
|
|
63
59
|
self.report_status = None
|
|
@@ -69,12 +65,74 @@ class MachineState:
|
|
|
69
65
|
self._stopped = None
|
|
70
66
|
|
|
71
67
|
def push_scope(self, scope: JacScope):
|
|
68
|
+
self.profile_pause()
|
|
72
69
|
self._scope_stack.append(scope)
|
|
73
70
|
self._jac_scope = scope
|
|
71
|
+
MachineState.profile_stack.append(self._jac_scope)
|
|
72
|
+
self.profile_in()
|
|
73
|
+
MachineState.recur_detect_set.append(self.call_name())
|
|
74
74
|
|
|
75
75
|
def pop_scope(self):
|
|
76
|
+
MachineState.recur_detect_set.remove(self.call_name())
|
|
77
|
+
self.profile_out()
|
|
76
78
|
self._scope_stack.pop()
|
|
77
79
|
self._jac_scope = self._scope_stack[-1]
|
|
80
|
+
MachineState.profile_stack.pop()
|
|
81
|
+
self.profile_unpause()
|
|
82
|
+
|
|
83
|
+
def profile_in(self):
|
|
84
|
+
if self._mast and self._mast._profiling:
|
|
85
|
+
self._jac_scope._start_time = time.time()
|
|
86
|
+
self._jac_scope._cum_start_time = time.time()
|
|
87
|
+
|
|
88
|
+
def profile_out(self):
|
|
89
|
+
# profile_jac_scope = MachineState.profile_stack[-1] # refactor and clean
|
|
90
|
+
if self._mast and self._mast._profiling:
|
|
91
|
+
name = self.call_name()
|
|
92
|
+
if name not in self._mast._jac_profile:
|
|
93
|
+
self._mast._jac_profile[name] = {
|
|
94
|
+
"calls": 1,
|
|
95
|
+
"u_calls": 0 if name in MachineState.recur_detect_set else 1,
|
|
96
|
+
"tot_time": self._jac_scope._total_time
|
|
97
|
+
+ (time.time() - self._jac_scope._start_time),
|
|
98
|
+
"cum_time": 0
|
|
99
|
+
if name in MachineState.recur_detect_set
|
|
100
|
+
else time.time() - self._jac_scope._cum_start_time,
|
|
101
|
+
}
|
|
102
|
+
else:
|
|
103
|
+
c = self._mast._jac_profile[name]["calls"]
|
|
104
|
+
u = self._mast._jac_profile[name]["u_calls"]
|
|
105
|
+
t = self._mast._jac_profile[name]["tot_time"]
|
|
106
|
+
p = self._mast._jac_profile[name]["cum_time"]
|
|
107
|
+
self._mast._jac_profile[name]["calls"] = c + 1
|
|
108
|
+
self._mast._jac_profile[name]["u_calls"] = (
|
|
109
|
+
u if name in MachineState.recur_detect_set else u + 1
|
|
110
|
+
)
|
|
111
|
+
self._mast._jac_profile[name][
|
|
112
|
+
"tot_time"
|
|
113
|
+
] += self._jac_scope._total_time + (
|
|
114
|
+
time.time() - self._jac_scope._start_time
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
self._mast._jac_profile[name]["cum_time"] = (
|
|
118
|
+
p
|
|
119
|
+
if name in MachineState.recur_detect_set
|
|
120
|
+
else (p + time.time() - self._jac_scope._cum_start_time)
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
def call_name(self):
|
|
124
|
+
return f"{self.kind}::{self.name}:{self._jac_scope.name}"
|
|
125
|
+
|
|
126
|
+
def profile_pause(self):
|
|
127
|
+
_jac_scope = MachineState.profile_stack[-1] # refactor and clean
|
|
128
|
+
if self._mast and self._mast._profiling and _jac_scope:
|
|
129
|
+
_jac_scope._total_time += time.time() - _jac_scope._start_time
|
|
130
|
+
_jac_scope._start_time = 0
|
|
131
|
+
|
|
132
|
+
def profile_unpause(self):
|
|
133
|
+
_jac_scope = MachineState.profile_stack[-1] # refactor and clean
|
|
134
|
+
if self._mast and self._mast._profiling and _jac_scope:
|
|
135
|
+
_jac_scope._start_time = time.time()
|
|
78
136
|
|
|
79
137
|
def here(self):
|
|
80
138
|
return self._scope_stack[-1].here() if self._scope_stack[-1] else None
|