jolicode / jolicode/rphp

JIT miscompiles untyped function parameters as zero after RECV elision

Open
#32 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
13
Forks
0
PR merge metrics
No merged PRs in 30d

Description

## Summary

The whole-function JIT can compile functions with untyped integer arguments, but their parameter CV slots are initialized to zero instead of receiving the runtime arguments.

This produces silently incorrect results.

Tested at commit `67ef61e68048a2a508cae3bb0834cfe69863fe46` on Linux x86_64 with Rust 1.96.0.

## Current JIT build blocker

At this commit, `cargo build --release --features jit` first fails because `jit_loop_hook()` uses `ctx` without receiving it.

For runtime testing, I applied only the mechanical wiring fix:

```diff
-pub(crate) fn jit_loop_hook(&mut self, idx: usize, header: usize, end: usize)
+pub(crate) fn jit_loop_hook(&mut self, ctx: &mut RunCtx, idx: usize, header: usize, end: usize)
```

and:

```diff
-vm.jit_loop_hook(idx, cur, end);
+vm.jit_loop_hook(ctx, idx, cur, end);
```

No JIT logic was otherwise changed.

## Reproducer

```php
add1(0) => 1
double($x) => double(0) => 0
```

Each `combine()` call therefore returns `1`, explaining the observed total of exactly `5000000`.

The existing parameter JIT test uses a typed parameter:

```php
function kern(int $n): int
```

That form retains `RECV`, so it does not exercise the compiler/JIT mismatch for untyped parameters.

## Possible fixes

A conservative short-term fix would be to reject whole-function JIT compilation when a parameter has no corresponding `RECV`.

A more complete fix would initialize parameter CV slots from `args_ptr` using the op-array parameter/CV metadata, independently of whether the interpreter bytecode retained `RECV`.

It would also be useful to add an integration test that goes through the normal compiler and VM call path with an untyped function receiving runtime integer arguments.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by running cargo build --release --features jit and inspect is_int_only(), translate(), jit_loop_hook(), and Opcode::Recv handling. Trace how untyped parameters reach JIT CV slots, then add an integration test through the normal compiler and VM call path using the reproducer's runtime integer arguments. Done means the JIT result matches the non-JIT expected total.

Written by the indexing model from the issue text.

Assessment

Tech stack
php, rust
Domain
compilers, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.