Skip to content

Commit ff0b551

Browse files
committed
[aexprs]_started_war_plan_for_new_rewriting_implementation
SQUASHED: aexprs-started-war-plan-for-new-rewriting-implementation,Merge-branch-gh-pages-of-https-github.com-LivelyKernel-lively4-core-into-gh-pages,
1 parent ff0025a commit ff0b551

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# New Rewriting Implementation
2+
3+
Goal: **2nd rewriting implementation along the first** (for performance comparison)
4+
5+
## Setup
6+
7+
- find a name
8+
- copy the system
9+
- copy *reactive* folder (including *test*) -> copy only *test*?
10+
- strip obviously irrelevant files/folders
11+
- adjust *system config*
12+
- copy aliases
13+
- adapt rewriting settings (babel configs)
14+
- adapt rewritings (with parts are rewritten in what manner)
15+
- adjust import paths (non local ones)
16+
- replace directive `"enable aexpr";` -> `"ae";`
17+
- also in rewriting files (tests & plugins)
18+
- add preference *"rewriting or new"*
19+
- tests deaktivieren
20+
- remove all irrelevant tests
21+
- `const xxit = xit;`
22+
- go through each `xit`: do we want this behavior in the new implementation?
23+
- if not: remove else: replace `xit` with `xxit`
24+
- `it` -> `xit`
25+
- some `before`/`afterEach` might throw
26+
- which tests test all implementations?
27+
- find them, add the new implementation
28+
29+
--> have **all tests passing** all the way until here
30+
31+
## Actual Implementation
32+
33+
### 1. Introduce EAM at body level
34+
35+
insight: a first-class piece of behavior can run completely either in EAM or outside EAM.
36+
37+
Thus, we can check if we are in EAM at the start of a FunctionBody, rather than on each member and variable access. Our initial function
38+
39+
```javascript
40+
function foo() {
41+
obj.prop
42+
}
43+
```
44+
45+
has its body duplicated for each mode of operation:
46+
47+
```javascript
48+
function foo() {
49+
if (self.__expressionAnalysisMode__) {
50+
_getMember(obj, "prop")
51+
} else {
52+
obj.prop
53+
}
54+
}
55+
```
56+
57+
thus, while analysing an expression, dependencies are still gathered, but outside the analysis, we only need to check one global boolean (which requires not only less redundant computation but also ).
58+
59+
#### caveats
60+
61+
1. arrow functionExpressions may need to be rewritten to have a block as body
62+
2. setters must be present in both
63+
3. the global `self` or `__expressionAnalysisMode__` might be shadowed, we have to take care of this case (initially skip this downside with a non-colliding import: )
64+
65+
#### downsides
66+
67+
- space for src code increases exponentially with nesting of functions (we have to measure this impact, e.g. by transforming all of lively and compare)
68+
69+
### 2. Localize Read/Write Accesses for Local Variables
70+
71+
idea: instead of a central data structutr, keep refereces to aexprs for locals in the `_scope` objects.
72+
73+
### 3. Localize Member Write Accesses (in favor of SourceCodeHooks)
74+
75+
#### caveats
76+
77+
1. `.length` (browser-dependent behavior for Arrays) and `obj[computedPropertyAccess]` still need to be using `setMember`
78+
2. other special hooks still need to be there (e.g. value hook or mutation hooks)
79+
80+
### 4. Minimize tracking of local variables
81+
82+
idea: local variables only need to be tracked, if
83+
- they leave their initial scope of declaration (= there is at least one read (#TODO: not sure if a read requires tracking) or write access to that variable in a different first-class functions' scope, i.e. it can be passed around)
84+
- they are not constant (there is a write operations somewhere for them)

0 commit comments

Comments
 (0)