@@ -145,21 +145,62 @@ cargo build --release --target wasm32-wasip1 --features="freeze-stdlib"
145145
146146### JIT (Just in time) compiler
147147
148- RustPython has a ** very** experimental JIT compiler that compile python functions into native code.
148+ RustPython has a ** very** experimental JIT compiler that compiles python functions into native code.
149+ It comes in two forms: an automatic one that tries every function once, as it is first called, and
150+ an explicit ` __jit__() ` that compiles the one function it is called on.
149151
150152#### Building
151153
152- By default the JIT compiler isn't enabled, it's enabled with the ` jit ` cargo feature .
154+ Neither is built by default .
153155
154156``` bash
155- cargo run --features jit
157+ cargo run --features aot # automatic, and the explicit one with it
158+ cargo run --features jit # explicit `__jit__()` alone
156159```
157160
158161This requires autoconf, automake, libtool, and clang to be installed.
159162
160- #### Using
163+ #### Using the automatic compiler
161164
162- To compile a function, call ` __jit__() ` on it.
165+ A build that has it still has to be switched on, with ` -X aot=1 ` , ` RUSTPYTHON_AOT=1 `
166+ or ` PYTHON_JIT=1 ` ; ` -X aot=0 ` and ` =0 ` switch it back off. Every function is then
167+ offered to the compiler the first time it is called. The attempt happens once,
168+ so a function it turns down costs that one attempt and is interpreted from then on.
169+
170+ ` sys._jit.is_available() ` reports whether the compiler was built in, ` is_enabled() `
171+ whether it is switched on, and ` _stats() ` returns ` (compiled, rejected, deoptimized) `
172+ for the functions it has looked at so far — a RustPython extension.
173+
174+ #### What it compiles
175+
176+ Annotated scalar functions, and nothing else. The argument and return types come
177+ from the annotations rather than from the values a call arrives with, so a function
178+ without them is turned down however it is called.
179+
180+ Taken: ` int ` , ` float ` and ` bool ` arguments, locals and return values; arithmetic,
181+ comparison and boolean operators; ` if ` , ` while ` , and the assignments between them.
182+
183+ Turned down: missing annotations, ` *args ` /` **kwargs ` , closures, generators and
184+ coroutines, ` try ` /` except ` , attributes and methods, containers, ` for ` , calls to
185+ anything but the function itself, and expressions that merge with an operand still
186+ on the stack, such as a conditional expression. A call a function makes to itself
187+ is compiled only by ` __jit__() ` ; the automatic path turns those down too, because
188+ the global it goes through can be rebound between one call and the next.
189+
190+ Where a machine word runs out — an overflow, a division by zero, a shift past the
191+ width, a power with no real answer — the compiled code hands the frame back at the
192+ instruction it could not do, with the values it had, and the interpreter carries on
193+ from there. The native code is dropped at that point, and the function is
194+ interpreted afterwards.
195+
196+ Compiled code runs with no python frame. That is why ` sys._jit.is_active() ` is
197+ always ` False ` , why such a call reports no line and no return to ` sys.settrace ` or
198+ ` sys.monitoring ` , and why a call is interpreted, and left uncompiled, while either
199+ of those is installed.
200+
201+ #### Using ` __jit__() `
202+
203+ To compile a single function, call ` __jit__() ` on it. This needs only the ` jit ` feature.
163204
164205``` python
165206def foo ():
0 commit comments