summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-25 09:51:44 -0700
committerCliff Click <cliffc@acm.org>2026-10-25 09:51:44 -0700
commit4051ce7cd26314f01dc8c0237899a742e0ab2084 (patch)
tree29cb9b47e0461c34be1797ac36dd31e8f0b10c09 /docs
parent5cfb046c8306a81ec40be82a59015f16f654fa93 (diff)
downloadSimple-4051ce7cd26314f01dc8c0237899a742e0ab2084.tar.gz
Simple-4051ce7cd26314f01dc8c0237899a742e0ab2084.zip
Fix ++x in methods
Fix ideaj setups
Diffstat (limited to 'docs')
-rw-r--r--docs/chapter-backports.md34
-rw-r--r--docs/intellij.md43
-rw-r--r--docs/stage-audit.md35
3 files changed, 87 insertions, 25 deletions
diff --git a/docs/chapter-backports.md b/docs/chapter-backports.md
index 6e6d1d5c..1c2ffb85 100644
--- a/docs/chapter-backports.md
+++ b/docs/chapter-backports.md
@@ -111,32 +111,26 @@ language restriction into Chapters 10-24 or the named pre-module snapshots.
Establish an earlier-chapter failure before changing compiler behavior.
-### Prefix update of an enclosing class field
+### Narrow stores in the ideal evaluator
-The following returns 11 instead of 21 in numbered Chapter 25, Modules, and
-Separate Compilation:
+The prefix-update regression exposed an independent evaluator bug. In Chapter
+23, this postfix-only example returns 25710 in Eval2 instead of 110:
```simple
-int calls=0;
-val next_noInline={ -> ++calls; };
-return next_noInline()+10*next_noInline();
-```
-
-The prefix path updates an enclosing parser slot instead of class memory.
-Postfix `calls++; return calls;` works and is used in the new chapter example.
-This is independent of importing IR. The stage audit also reproduced the
-instance-method form in Chapter 23, where methods first appear:
-
-```simple
-struct C { int x=0; val inc={ -> ++x; }; };
+struct C { u8 x=255; val next_noInline={ -> x++; return x; }; };
var c=new C;
-return c.inc()+10*c.inc();
+val a=c.next_noInline();
+val b=c.next_noInline();
+return a+10*b+100*c.x;
```
-It returns 11 instead of 21 in Chapters 23 and 26. Prefix lookup bypasses the
-ordinary field-access path. A fix should share name resolution with other
-reads/updates while preserving constructor locals, and propagate from 23
-through 28b. No fix is included in the numbering change.
+`Eval2.store` copies the raw value into its Java object array. It does not
+truncate to the field width, even though Store optimization removes masks that
+machine stores perform implicitly. The native prefix-update regression checks
+that the stored byte wraps and the expression returns the converted value.
+Establish the first affected evaluator and check signed fields and floating
+rounding before propagating a fix. Do not change valid generated code to match
+an incorrect ideal evaluator.
### Constructor loop with break/continue: worklist assertion
diff --git a/docs/intellij.md b/docs/intellij.md
new file mode 100644
index 00000000..a488fca6
--- /dev/null
+++ b/docs/intellij.md
@@ -0,0 +1,43 @@
+# IntelliJ
+
+Open the repository folder as an existing IntelliJ project. Select JDK 21 in
+**File > Project Structure > Project SDK** if needed. The native `.iml` setup
+includes every numbered chapter and the shared Java code; no Maven import is
+needed. Each chapter has separate main and test output under `build/idea` and
+never depends on another chapter's compiler. Make's output stays separate.
+
+On a fresh checkout, run `make lib` to fetch JUnit, then close the project and run:
+
+```sh
+python build-support/idea.py
+```
+
+Reopen the repository folder. The script refreshes the module list and test
+configurations, and sets the JUnit template's working directory to
+`$MODULE_WORKING_DIR$`. It preserves the selected SDK and existing personal run
+configurations and breakpoints. Original settings are backed up in
+`build/idea-backup`. Run it again after adding or renaming chapters, with the
+project closed so IntelliJ cannot overwrite the new list with its old one.
+After a chapter move, use **Build > Rebuild Project** once to remove old compiled
+classes from reused chapter directories.
+
+Open a chapter's `src/test/java` file and use the gutter's **Debug** action on a
+test method. Its configuration should use that chapter's module. You can also
+select **chapter23 field write** to debug
+`PrefixUpdateTest.testMethodFieldWrites`, or **chapterXX tests** to run that
+chapter's suite. These shared configurations set the module, working directory,
+assertions and build step explicitly. Suite discovery is limited to that module.
+
+Old personal run configurations may still name the former combined chapter25.
+Recreate those from the intended chapter's test gutter, or change both their
+module and working directory in **Run > Edit Configurations**. The same Java
+class names occur in many chapters, so a class name alone cannot identify the
+intended snapshot.
+
+Tests that compile native code still need the C toolchain on IntelliJ's PATH.
+Tests using Chapter 28b's native runtime or saved `sys` library also need the
+Make prerequisites: run `make -C chapter28b release CTAGS=` before debugging
+those tests. IntelliJ's Java build does not build the native runtime or library.
+
+For the JUnit working directory and module classpath settings, see
+[JetBrains' JUnit configuration reference](https://www.jetbrains.com/help/idea/run-debug-configuration-junit.html).
diff --git a/docs/stage-audit.md b/docs/stage-audit.md
index c375d159..dac2dc77 100644
--- a/docs/stage-audit.md
+++ b/docs/stage-audit.md
@@ -22,13 +22,39 @@ regression identities; they do not identify current chapter boundaries.
and the former roadmap is now [docs/roadmap.md](roadmap.md).
- The recursive-return diagnostic already passed. It remains enabled in the
earlier snapshots and is enabled again in 28a/28b. The mutual-recursion test had an obsolete graph-string
- expectation; it now checks its existing four execution results in 24b–28b.
+ expectation; it now checks its existing four execution results in 24b–28b.
In 24a, local SCCP cannot infer the recursive return type; the same example
checks that conservative diagnostic instead. This makes the boundary explicit.
- Allocation/runtime measurement runs passed after the comparison correction;
the changed spill goldens record the resulting smaller graphs. Historical
published tables retain their original compiler labels and dates.
+## Prefix-update follow-up
+
+Prefix `++` and `--` now use the same name lookup as ordinary reads and postfix
+updates in Chapters 23 through 28b. A method's field goes through memory; a
+constructor-local field stays in SSA. Previously, the prefix path updated the
+field declaration's parser slot and silently lost the write. The two-call
+reproducer now returns 21 instead of 11. Narrow update results stay alive while
+Store folding drops a redundant conversion from its own input.
+
+`PrefixUpdateTest` covers increment/decrement, integer/float/byte fields,
+multiple worklist seeds, local shadowing, final-field errors, native byte
+wraparound, and module fields where supported. Existing final-constructor
+coverage includes prefix updates in loops.
+
+The focused Linux checks pass in all eight affected chapters, including native
+SystemV byte-wraparound execution and the existing final-constructor tests.
+The early final-field rejection is retained so an illegal prefix update never
+enters the optimizer as a Store; native data bindings still update their writable
+contents despite having a fixed address.
+
+The Windows full suites cover 4,169 tests plus eight fuzzer regression runs;
+shared printer and ISA checks pass. Focused reruns cover the final diagnostic
+and prefix-result lifetime adjustments. The full Chapter 27 suite was rerun
+after restricting the temporary keep to prefix results; its existing spill
+expectations remain unchanged. No allocator goldens were updated.
+
## Implemented, with narrower limits than earlier prose suggested
- Separate compilation imports types and optimized IR without source parsing;
@@ -47,10 +73,9 @@ regression identities; they do not identify current chapter boundaries.
## Existing failures and deferred validation
-- Prefix update of a field from a method can lose the write, starting in
- Chapter 23 (confirmed by two calls to `inc={ -> ++x; }`). The enclosing
- module-field reproducer and the worklist failure below are retained in the
- [queue](chapter-backports.md), rather than hidden by the split.
+- The ideal evaluator does not truncate narrow stores in Chapter 23. A byte
+ update can therefore disagree with generated code; the postfix-only
+ reproducer is retained in the [queue](chapter-backports.md).
- A constructor loop with both break and continue still reproduces a worklist
assertion in Chapter 26. It is not caused by final-field mutability.
- `testModule0` is an ignored historical incremental-build experiment. It