mirror of
https://github.com/Nexoniarz/Finch.git
synced 2026-11-03 00:44:27 +00:00
Warnings for big copies: a struct with 256+ bytes of plain data as a parameter or in for x in list
- on stderr (finch ir stays the IR), as yellow warnings in editors (@W in the index), once per place - str, arrays and maps inside a struct don't count: passing it copies only their handles - none in the compiler, the examples or the tests other than the new one - docs: the warning instead of "not planned"; what was and wasn't checked for Android Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016GzNP6r8dg6WDxUVZy8wjL
This commit is contained in:
parent
961ba951ec
commit
d557b5505e
15 changed files with 210 additions and 18 deletions
|
|
@ -327,7 +327,7 @@ Automatic only when nothing is lost: smaller → bigger number, any int → floa
|
|||
|
||||
- Arrays, text and structs free themselves at the end of their block. No `free` needed.
|
||||
- `b := a` copies; a call's result moves; `return x` moves.
|
||||
- Passing a struct: `fn f(Body b)` works on its own copy (the caller's stays as it was), `fn f(ptr[Body] b)` changes the caller's (`f(body)` or `f(addr(body))`), a method gets `self` by address, never a copy.
|
||||
- Passing a struct: `fn f(Body b)` works on its own copy (the caller's stays as it was), `fn f(ptr[Body] b)` changes the caller's (`f(body)` or `f(addr(body))`), a method gets `self` by address, never a copy. A struct with 256+ bytes of numbers passed by value or in `for x in list` gets a warning.
|
||||
- `new(...)` + `free(...)` (often with `defer`) for linked lists, trees, sharing.
|
||||
- C memory: C's own functions (`malloc` / `free`, `fclose`, …).
|
||||
|
||||
|
|
|
|||
|
|
@ -503,6 +503,13 @@ makes the C-callable thunk. `atomic_add/sub/swap` lower to `atomicrmw add/sub/xc
|
|||
take a `ptr[T]` to any integer type. Finch's arrays, text and maps are not synchronised; sharing one between threads
|
||||
needs a mutex.
|
||||
|
||||
### Warnings
|
||||
|
||||
`warn()` prints `file:line:col: warning: …` to stderr (so `finch ir` stays pure IR) or, with `index`, an `@W` record the
|
||||
language server publishes with severity 2. One per source position. Two are given: a struct parameter, and the element of
|
||||
`for x in list`, whose plain data (`byteSize()`: numbers, nested structs, C `[N]T`; `str`/arrays/maps count 0, as only
|
||||
their handle is copied) is 256 bytes or more.
|
||||
|
||||
### Struct arguments by address
|
||||
|
||||
`argWant()` (call arguments only, not assignments): when a parameter is `ptr[S]` and the argument is a plain variable
|
||||
|
|
|
|||
|
|
@ -1134,11 +1134,20 @@ Not there yet:
|
|||
- Interfaces.
|
||||
- Unicode-aware text: `.len`, `s[i]` and `upper()` work on bytes / ASCII.
|
||||
- Checks that stop two threads from changing the same array at once (use a mutex).
|
||||
- Windows on ARM64, 32-bit systems, WebAssembly. Android is built (`--target android`) but not yet tried on a device.
|
||||
- Windows on ARM64, 32-bit systems, WebAssembly. `--target android` makes code for Android, but linking with the NDK and running on a device are untried.
|
||||
|
||||
On purpose, not planned: a warning for every big struct that gets copied. A copy in Finch is always visible in the
|
||||
code (`b := a`, passing a struct to a `Body b` parameter), a method never copies `self`, and `ptr[Body]` (or passing
|
||||
the variable to a `ptr[Body]` parameter) shares instead. A warning that fires on ordinary code would be noise.
|
||||
### Warnings about big copies
|
||||
|
||||
A struct with 256 bytes or more of plain data (numbers, structs of numbers, C's `[N]T`) is copied byte by byte when it
|
||||
is a parameter (`fn f(Body b)`) and in `for x in bodies`. Finch says so, and still builds the program:
|
||||
|
||||
```
|
||||
game.fch:27:11: warning: 'b' is a Body (264 bytes), copied on every call to weight; take ptr[Body] to share it instead (callers can still pass the variable as it is)
|
||||
game.fch:45:5: warning: each Body (264 bytes) is copied into 'x'; for i in 0..bodies.len with bodies[i] works on it in place
|
||||
```
|
||||
|
||||
Text, arrays and maps inside a struct don't count: passing the struct copies only their handles, not what they hold.
|
||||
`b := a` is not warned about: it says "copy" in the code. A method never copies `self`. Editors show the warnings in yellow.
|
||||
|
||||
See the [roadmap in the README](../../README.md#roadmap).
|
||||
|
||||
|
|
@ -1283,5 +1292,6 @@ Write the header (`float path_len(float x, float y);`, or let `cbindgen` write i
|
|||
|
||||
**Android**: `finch build game.fch --target android --shared` makes `libgame.so` for 64-bit ARM Android (API 24 and
|
||||
up) with the NDK's clang, found through `ANDROID_NDK_HOME` (or `FINCH_CC`). Load it from an app, for example through
|
||||
SDL3's Android project (the library's `SDL_main` is an `export fn`). This is new: it is built and checked here, but not
|
||||
yet tried on a device.
|
||||
SDL3's Android project (the library's `SDL_main` is an `export fn`). This is new and only partly checked: Finch's
|
||||
output compiles for Android (thread-local data goes through the emulated TLS older Android needs), but linking with the
|
||||
NDK and running on a device have not been tried yet.
|
||||
|
|
|
|||
|
|
@ -496,6 +496,13 @@ thunk wołany z C. `atomic_add/sub/swap` to `atomicrmw add/sub/xchg … seq_cst`
|
|||
`ptr[T]` do dowolnej liczby całkowitej. Tablice, teksty i mapy Fincha nie są synchronizowane; dzielenie ich między
|
||||
wątkami wymaga mutexu.
|
||||
|
||||
### Ostrzeżenia
|
||||
|
||||
`warn()` wypisuje `plik:linia:kolumna: warning: …` na stderr (więc `finch ir` daje samo IR) albo, w trybie `index`,
|
||||
rekord `@W`, który serwer języka publikuje z ważnością 2. Jedno na miejsce w kodzie. Są dwa: parametr-struktura oraz
|
||||
element `for x in lista`, gdy ich zwykłe dane (`byteSize()`: liczby, zagnieżdżone struktury, `[N]T` z C; `str`, tablice
|
||||
i mapy liczą się jako 0, bo kopiowany jest tylko ich uchwyt) mają 256 bajtów lub więcej.
|
||||
|
||||
### Struktura jako argument przez adres
|
||||
|
||||
`argWant()` (tylko argumenty wywołań, nie przypisania): gdy parametr to `ptr[S]`, a argument to zwykła zmienna typu `S`,
|
||||
|
|
|
|||
|
|
@ -1138,12 +1138,22 @@ Jeszcze nie ma:
|
|||
- Interfejsów.
|
||||
- Tekstu świadomego Unicode: `.len`, `s[i]` i `upper()` działają na bajtach / ASCII.
|
||||
- Pilnowania, żeby dwa wątki nie zmieniały tej samej tablicy naraz (do tego mutex).
|
||||
- Windowsa na ARM64, systemów 32-bitowych, WebAssembly. Android jest budowany (`--target android`), ale jeszcze nie
|
||||
sprawdzony na urządzeniu.
|
||||
- Windowsa na ARM64, systemów 32-bitowych, WebAssembly. `--target android` robi kod dla Androida, ale linkowanie
|
||||
z NDK i uruchomienie na urządzeniu nie były jeszcze próbowane.
|
||||
|
||||
Celowo nie planowane: ostrzeżenie przy każdym kopiowaniu dużej struktury. Kopię w Finchu zawsze widać w kodzie
|
||||
(`b := a`, struktura podana do parametru `Cialo c`), metoda nigdy nie kopiuje `self`, a `ptr[Cialo]` (albo zmienna
|
||||
podana do parametru `ptr[Cialo]`) współdzieli zamiast kopiować. Ostrzeżenie przy zwykłym kodzie byłoby szumem.
|
||||
### Ostrzeżenia o dużych kopiach
|
||||
|
||||
Struktura z 256 lub więcej bajtami zwykłych danych (liczby, struktury z liczb, `[N]T` z C) jest kopiowana bajt po bajcie,
|
||||
gdy jest parametrem (`fn f(Cialo c)`) i w `for x in ciala`. Finch o tym mówi, a program i tak buduje:
|
||||
|
||||
```
|
||||
gra.fch:27:11: warning: 'c' is a Cialo (264 bytes), copied on every call to waga; take ptr[Cialo] to share it instead (callers can still pass the variable as it is)
|
||||
gra.fch:45:5: warning: each Cialo (264 bytes) is copied into 'x'; for i in 0..ciala.len with ciala[i] works on it in place
|
||||
```
|
||||
|
||||
Teksty, tablice i mapy w strukturze się nie liczą: przekazanie struktury kopiuje tylko ich uchwyty, nie zawartość.
|
||||
`b := a` nie dostaje ostrzeżenia: w kodzie widać, że to kopia. Metoda nigdy nie kopiuje `self`. Edytory pokazują
|
||||
ostrzeżenia na żółto.
|
||||
|
||||
Plan rozwoju jest w [README](../../README.pl.md#plan-rozwoju).
|
||||
|
||||
|
|
@ -1288,5 +1298,6 @@ Napisz nagłówek (`float path_len(float x, float y);` albo niech napisze go `cb
|
|||
|
||||
**Android**: `finch build gra.fch --target android --shared` robi `libgra.so` dla 64-bitowego Androida na ARM (API 24
|
||||
i wyżej) clangiem z NDK, znalezionym przez `ANDROID_NDK_HOME` (albo `FINCH_CC`). Wczytaj go z aplikacji, na przykład
|
||||
przez projekt Androida z SDL3 (`SDL_main` biblioteki to `export fn`). To nowość: jest budowane i sprawdzane tutaj, ale
|
||||
jeszcze nie na urządzeniu.
|
||||
przez projekt Androida z SDL3 (`SDL_main` biblioteki to `export fn`). To nowość, sprawdzona tylko częściowo: kod Fincha
|
||||
kompiluje się dla Androida (dane wątków idą przez emulowane TLS, którego wymaga starszy Android), ale linkowanie z NDK
|
||||
i uruchomienie na urządzeniu nie były jeszcze próbowane.
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ Automatycznie tylko wtedy, gdy nic nie ginie: mniejsza → większa liczba, dowo
|
|||
|
||||
- Tablice, teksty i struktury zwalniają się same na końcu swojego bloku. Bez `free`.
|
||||
- `b := a` kopiuje; wynik wywołania jest przenoszony; `return x` przenosi.
|
||||
- Przekazywanie struktury: `fn f(Cialo c)` pracuje na własnej kopii (ta u wywołującego się nie zmienia), `fn f(ptr[Cialo] c)` zmienia tę u wywołującego (`f(cialo)` albo `f(addr(cialo))`), metoda dostaje `self` przez adres, nigdy kopię.
|
||||
- Przekazywanie struktury: `fn f(Cialo c)` pracuje na własnej kopii (ta u wywołującego się nie zmienia), `fn f(ptr[Cialo] c)` zmienia tę u wywołującego (`f(cialo)` albo `f(addr(cialo))`), metoda dostaje `self` przez adres, nigdy kopię. Struktura z 256+ bajtami liczb przekazana przez wartość albo w `for x in lista` dostaje ostrzeżenie.
|
||||
- `new(...)` + `free(...)` (często z `defer`) do list wiązanych, drzew, współdzielenia.
|
||||
- Pamięć z C: funkcjami z C (`malloc` / `free`, `fclose`, …).
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue