123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- =========================
- Code generation with Rust
- =========================
- 53 tests currently passing (flag --rust):
- features/instate/test_instate.xml
- features/instate/test_instate_nested.xml
- features/event_params/test_internalparam.xml
- features/action_lang/test_closure.xml
- features/action_lang/test_cond.xml
- features/action_lang/test_expressions.xml
- features/action_lang/test_functions2.xml
- features/action_lang/test_guard_action.xml
- features/action_lang/test_guard_readonly.xml
- features/action_lang/test_nested.xml
- features/history/test_composite_shallow.xml
- features/history/test_deep.xml
- features/history/test_default.xml
- features/history/test_parallel_deep.xml
- features/history/test_shallow.xml
- features/after/test_after.xml
- features/after/test_after_reentry.xml
- features/parallel/test_parallel.xml
- day_atlee/test_01_dialer_takemany.xml
- day_atlee/test_01_dialer_takeone.xml
- day_atlee/test_02_counter_takeone.xml
- day_atlee/test_03_trafficlight_single.xml
- day_atlee/test_04_counter_single.xml
- day_atlee/test_06_counter_lifeline.xml
- day_atlee/test_13_invar_rhs_smallstep.xml
- day_atlee/test_21_counter_combo.xml
- semantics/priority/test_explicit_flat.xml
- semantics/priority/test_explicit_ortho.xml
- semantics/priority/test_source_child.xml
- semantics/priority/test_source_parent.xml
- semantics/memory_protocol/test_gcsmall.xml
- semantics/event_lifeline/test_flat_nextss_takemany.xml
- semantics/event_lifeline/test_flat_nextss_takeone.xml
- semantics/event_lifeline/test_flat_queue_first.xml
- semantics/event_lifeline/test_flat_queue_whole_takemany.xml
- semantics/event_lifeline/test_flat_remainder.xml
- semantics/event_lifeline/test_ortho_nextcs_takemany.xml
- semantics/event_lifeline/test_ortho_nextcs_takeone.xml
- semantics/event_lifeline/test_ortho_nextss.xml
- semantics/event_lifeline/test_ortho_queue.xml
- semantics/big_step_maximality/test_cross_region1.xml
- semantics/big_step_maximality/test_cross_region2.xml
- semantics/big_step_maximality/test_flat_syntactic.xml
- semantics/big_step_maximality/test_flat_takemany.xml
- semantics/big_step_maximality/test_flat_takeone.xml
- semantics/big_step_maximality/test_ortho_syntactic.xml
- semantics/big_step_maximality/test_ortho_takemany.xml
- semantics/big_step_maximality/test_ortho_takeone.xml
- xml_syntax/stateref/test_flat_absolute.xml
- xml_syntax/stateref/test_flat_relative.xml
- xml_syntax/stateref/test_nested_absolute.xml
- xml_syntax/stateref/test_nested_relative.xml
- Roadmap
- -------
- (DONE) Milestone 1: Initial compilation to Rust
-
- - (DONE) entering and exiting states correctly
- - (DONE) incoming event triggers the right transition
- - (DONE) a port of the Controller class to Rust
- - (DONE) one implemented action: raise output event
- - (DONE) fixed semantics (YAKINDU-like)
- - "Take One" big step maximality
- - parent-first
- - (DONE) goal: subset of SCCD tests passes:
- semantics/big_step_maximality/test_flat_takeone.xml
- semantics/big_step_maximality/test_ortho_takeone.xml
- semantics/priority/test_source_parent.xml
- semantics/priority/test_explicit_flat.xml
- semantics/priority/test_explicit_ortho.xml
- - no history
- - no action language
- - guards evals and action stmts are just logged to console
- - guards always true, actions no effect
- - no event parameters
- (DONE) Milestone 2: Minimal support for semantic variability:
- - (DONE) Priority: Child-first
- - (DONE) Big-Step Maximality: Take Many
- - (DONE) goal: following tests should pass:
- semantics/priority/test_source_child.xml
- semantics/big_step_maximality/test_flat_takemany.xml
- semantics/big_step_maximality/test_ortho_takemany.xml
- (DONE) Milestone 3: Support history
- (DONE) Milestone 4: Timers (should be easy)
- (DONE) Milestone 5: Internal Events
- (DONE) Milestone 6: Action language
- (DONE) Milestone 7: INSTATE-function -> INSTATE-macro
- - INVARIANT: Action lang must never depend on statechart lang!
- - Evaluation of action lang expression can only read/write to the expression's scope (and parent scopes, if expression occurs in a function)
- -> Action lang expression evaluation cannot take mut ref to "state configuration"
- - Background: Currently implemented in interpreter as a function in "builtin"-scope:
- - Builtin-scope instantiated when statechart is instantiated
- - INSTATE-function is a value in "builtin" scope, a function partially bound to the statechart's execution state (which contains the "state configuration")
- - INSTATE-function takes an array of strings of absolutate paths to states. At runtime, these strings are used as keys in a dictionary to convert them to state IDs.
- -> Better to statically convert the absolute state paths to state IDs by introducing *macros*.
- - Better implementation:
- 1) Support macros in action lang:
- - From the type system's point of view, a macro call is just a function call (depending on the macro called, takes typed parameters and returns a typed value)
- - Macro body is executed statically, and during type check (= right after constructing AST).
- -> For INSTATE-macro, the macro body converts every state path to its correct state object.
- - Action lang parser constructor gets a dict of supported macros, their types, and their "bodies"
- 2) Based on the insight that INSTATE cannot occur everywhere (e.g. cannot occur in datamodel block), in fact it can only occur during a transition's guard eval or actions, treat these as follows:
- - Wrap guard eval or action code in an implicit function with as parameter the "state configuration".
- - Expansion of the INSTATE-macro then reads this parameter.
- Milestone n+1: "TODO"
- - (DONE) Syntactic output events
- - (DONE) Event parameters
- - Memory Protocol semantics
- - Concurrency semantics
- Insights
- --------
- - Rust compiler warnings are actually useful for the modeler:
- - e.g. An unexecutable transition is detected as an unreachable statement
- - e.g. An unused event is detected as an unused variable or never-constructed enum variant.
- - Rust's product ("struct") and sum ("enum") types map perfectly onto And- and Or-states
- Performance over time
- ---------------------
- for test semantics/big_step_maximality/test_ortho_takemany.xml
- commit 91a048eedb6eaf224df3567b506cbda07d664781 - Dec 28, 2020 - implemented event parameters, use tuple structs for event types
- binary size, opt-level=3: 3244920 bytes
- instruction count (perf stat) (opt-level=3): 562.600 instructions:u
- commit 950fcc1e7eed1e3b3c5eda75b896078e53eb71c4 - Dec 26, 2020 - syntactic output events (enums instead of strings), re-implemented event queue (entries allocated on heap, 'canceled' flag)
- binary size, no opt: 3833544 bytes <- not sure what caused this sudden drop in unoptimized binary size
- binary size, opt-level=3: 3255368 bytes
- instruction count (perf stat) (opt-level=3): 569.488 instructions:u
- commit ae8a94e186ee972c0d3e0b229b77901352137c64 - Dec 23, 2020 - implement additional event lifeline semantics, pass input event by reference instead of by value
- binary size, no opt: 800592 bytes
- binary size, opt-level=3: 422200 bytes
- instruction count (perf stat) (opt-level=3): 570.824 instructions:u
- commit 39fc866428c595c7ed909569d998981d1d350059 - Dec 22, 2020 - various fixes, support INSTATE
- binary size, no opt: 800544 bytes
- binary size, opt-level=3: 422200 bytes
- instruction count (perf stat) (opt-level=3): 570.776 instructions:u
- commit ec39dd73ea42a9ccee6f1edc8863b36625e0721a - Dec 20, 2020 - put reusable stuff in library
- binary size, opt-level=3: 422192 bytes
- instruction count (perf stat) (opt-level=3): 571.641 instructions:u
- commit 354576dd47587fd8e6277539a26a4743b2167565 - Dec 17, 2020 - action lang working
- binary size, no opt: 513760 bytes
- binary size, opt-level=3: 421056 bytes
- binary size, opt-level=3 inline-threshold=1000: 421056 bytes
- binary size, opt-level=z: 429200 bytes
- instruction count (perf stat) (opt-level=3): 575.539 instructions:u
- commit aa6a734f7d900479de9be99a8cdf68af0d561481 - Dec 2, 2020 - implemented big-step maximality
- binary size, no opt: 478976 bytes
- binary size, opt-level=3 inline-threshold=1000: 410880 bytes
- binary size, opt-level=z: 413576 bytes
- instruction count (perf stat) (opt-level=3): 580.701 instructions:u
- Performance insights
- - non-optimized binary size increased as features were added, optimized binary size stayed pretty much the same. this assures that Rust is able to inline and optimize away the many unused parameters of enter and exit functions.
- - the same conclusion can be drawn from binary size being slightly worse when setting a lower inline threshold (opt-level=z). this means that inlining is actually reducing the binaries' size, as we would expect (lots of unused parameters can be eliminated)
- - passing input event by reference instead of by value did not change the optimized binary size. probably evidence of Rust inlining or passing by value anyway.
|