Skip to main content
JustJIT Logo

JustJIT

A Just-In-Time compiler for Python that compiles Python bytecode to native machine code using LLVM.

License: MIT Python 3.13 LLVM 18+


Installation

pip install justjit

Quick Start

from justjit import jit

@jit
def fibonacci(n):
    if n <= 1:
        return n
    a, b = 0, 1
    for _ in range(n - 1):
        a, b = b, a + b
    return b

result = fibonacci(40)  # Compiled to native code

Generator Functions

@jit
def count_up(n):
    i = 0
    while i < n:
        yield i
        i += 1

for value in count_up(10):
    print(value)

Async/Await

import asyncio
from justjit import jit

@jit
async def fetch_data():
    await asyncio.sleep(0.1)
    return "data"

result = asyncio.run(fetch_data())

Exception Handling

@jit
def safe_divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        return 0

print(safe_divide(10, 2))  # 5.0
print(safe_divide(10, 0))  # 0

Float Mode

@jit(mode='float')
def distance(x1, y1, x2, y2):
    dx = x2 - x1
    dy = y2 - y1
    return (dx * dx + dy * dy) ** 0.5

print(distance(0.0, 0.0, 3.0, 4.0))  # 5.0

List Comprehensions

@jit
def squares(n):
    return [x * x for x in range(n)]

print(squares(5))  # [0, 1, 4, 9, 16]

Features

  • Object Mode (default): Full Python semantics via C API calls
  • Native Modes: int, float, bool, complex128, vec4f, vec8i for specialized workloads
  • Generators: State machine compilation with yield support
  • Coroutines: Async/await with awaitable protocol
  • Exception Handling: Try/except/finally with stack unwinding
  • Inline C/C++: Compile C code at runtime (requires Clang)

Compilation Modes

Mode Type Use Case
auto PyObject* Default, full Python compatibility
int i64 Pure integer loops
float f64 Floating-point math
complex128 {f64, f64} Complex number operations
vec4f <4 x f32> SSE SIMD (4 floats)
vec8i <8 x i32> AVX SIMD (8 ints)
@jit(mode='int')
def sum_range(n):
    total = 0
    for i in range(n):
        total += i
    return total

Inline C Compiler

from justjit import inline_c

result = inline_c("""
double square(double x) {
    return x * x;
}
""")

print(result['square'](4.0))  # 16.0

How It Works

Compilation Pipeline

Python Function → Bytecode → CFG Analysis → LLVM IR → Native Code
  1. Bytecode Extraction: Uses Python's dis module to extract bytecode instructions
  2. CFG Construction: Builds control flow graph, identifies basic blocks and jump targets
  3. Stack Depth Analysis: Dataflow analysis to compute stack depth at each instruction
  4. IR Generation: Translates each opcode to LLVM IR
  5. Optimization: Applies LLVM optimization passes (O0-O3)
  6. JIT Compilation: LLVM ORC JIT compiles to native machine code

Object Mode Internals

In object mode, Python operations are compiled to C API calls:

# Python code
result = a + b
; Generated LLVM IR
%result = call ptr @PyNumber_Add(ptr %a, ptr %b)
call void @Py_DECREF(ptr %a)
call void @Py_DECREF(ptr %b)

Every API call is wrapped with NULL-checking for exception handling.

Native Mode Internals

Native modes bypass Python objects entirely:

@jit(mode='int')
def add(a, b):
    return a + b
; Generated LLVM IR - pure LLVM i64
define i64 @add(i64 %a, i64 %b) {
  %result = add i64 %a, %b
  ret i64 %result
}

Generator State Machine

Generators compile to step functions with explicit state:

// Step function signature
PyObject* step(int32_t* state, PyObject** locals, PyObject* sent);

// States: 0=initial, 1..N=resume points, -1=done, -2=error

At each yield:

  1. Stack values spill to persistent locals array
  2. State advances to next resume point
  3. Function returns yielded value

On resume:

  1. Switch dispatches to correct state
  2. Stack restores from locals array
  3. Execution continues after yield

Coroutine Internals

Coroutines extend generators with awaitable protocol:

struct JITCoroutineObject {
    int32_t state;           // Suspension state
    PyObject** locals;       // Persistent variables
    PyObject* awaiting;      // Currently awaited object
    GeneratorStepFunc step;  // Compiled step function
};

await compiles to:

  1. GET_AWAITABLE - validate and get iterator
  2. SEND - delegate to awaited object
  3. END_SEND - extract return value

Inline C Compiler

Uses embedded Clang to compile C/C++ at runtime:

C Code → Clang Frontend → LLVM IR → Same JIT as Python

Python variables are captured as C declarations:

// Python: x = 42, arr = numpy.array([1,2,3])
// Generated C preamble:
long long x = 42LL;
double* arr = (double*)0x7fff12345678ULL;
long long arr_len = 3LL;

Current Status

Working

  • Basic control flow (if/else, for, while)
  • Arithmetic and comparison operations
  • Function calls
  • List/dict/set operations
  • Try/except handling
  • Simple generators

Known Limitations

  • Native modes (int, float) only support scalar operations, not array indexing
  • Nested list comprehensions in generators may have issues
  • Some complex async patterns not fully tested

Building from Source

Requires: Python 3.10+, LLVM 18+, CMake 3.20+, C++17 compiler

# Set LLVM path
export LLVM_DIR=/path/to/llvm/lib/cmake/llvm  # Linux/macOS
$env:LLVM_DIR = "C:\path\to\llvm\lib\cmake\llvm"  # Windows

# Build
pip install -e . --no-build-isolation

License

MIT License - see LICENSE

Metadata

Release files for justjit 0.1.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for justjit 0.1.7
File Size Uploaded Provenance Actions
justjit-0.1.7.tar.gz 1.9 MB Without provenance Details for justjit-0.1.7.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for justjit 0.1.7
File Interpreter ABI Platform Actions
justjit-0.1.7-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details for justjit-0.1.7-cp313-cp313-win_amd64.whl
justjit-0.1.7-cp313-cp313-manylinux_2_35_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.35+ x86-64 Details for justjit-0.1.7-cp313-cp313-manylinux_2_35_x86_64.whl
justjit-0.1.7-cp313-cp313-macosx_12_0_arm64.whl CPython 3.13 CPython 3.13 macOS 12.0+ ARM64 Details for justjit-0.1.7-cp313-cp313-macosx_12_0_arm64.whl

Total release size: 186.0 MB

Release files / justjit-0.1.7.tar.gz

Download URL justjit-0.1.7.tar.gz
Size 1.9 MB
Tags Source
SHA-256 checksum
How to use checksums
9ed8722bf33504403fac3def0826a2d6338b8b56f0cc01b4b019a71390846b50
BLAKE2b-256 checksum
How to use checksums
ed3544f6ea5431aafa6b47e1820013df052a0a83991cd862b249dd4963a8ce46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / justjit-0.1.7-cp313-cp313-win_amd64.whl

Download URL justjit-0.1.7-cp313-cp313-win_amd64.whl
Size 28.0 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
d57ed00c4e35f7c44cc89ba55a0f2162ee3bdfa7ed2ecc0172b86a273d89f45d
BLAKE2b-256 checksum
How to use checksums
425c2c530c7bac5a1b645a702b556db7b323143407d0e20bdb265b310c307c77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / justjit-0.1.7-cp313-cp313-manylinux_2_35_x86_64.whl

Download URL justjit-0.1.7-cp313-cp313-manylinux_2_35_x86_64.whl
Size 83.6 MB
Tags CPython 3.13 Linux glibc 2.35+ x86-64
SHA-256 checksum
How to use checksums
9ee57b672b4991aa968b6a418867c8e43d9879a1936384eea510aeeb29296743
BLAKE2b-256 checksum
How to use checksums
10b71a8da1ac4411e8b01b9c0350614888eb0be889f1c66c154a7034422b96cc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / justjit-0.1.7-cp313-cp313-macosx_12_0_arm64.whl

Download URL justjit-0.1.7-cp313-cp313-macosx_12_0_arm64.whl
Size 72.6 MB
Tags CPython 3.13 macOS 12.0+ ARM64
SHA-256 checksum
How to use checksums
0fd8dc941ff88036ae7fd70ba4a4d86c0f7e382b3697b57e0cc1f2e2a6497011
BLAKE2b-256 checksum
How to use checksums
0b9222e6477287273099900cee00af2ef065992230fca018f07c52e689135393
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for justjit 0.1.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page