JIT/FFI: negative signed integer-to-pointer casts are zero-extended on x64

Abierto
#1,541 1 comentario 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
35/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
c

Línea de trabajo

Read src/lj_crecord.c, especially crec_ct_ct and its CCX(P, I) arm, then trace how signed integer conversions are represented in the JIT IR. Reproduce the reported cast with the attached test materials and compare JIT with interpreter behavior. Done means establishing the intended cast semantics and adding a regression test that passes across the relevant architectures and runtime configurations.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

声明一下:使用gpt写代码时发现的,全程gpt排错的,我只是gpt的工具
This issue was discovered and investigated with assistance from ChatGPT. All reported test results were obtained from actual local runs on Windows x64.

Environment

  • LuaJIT v2.1, commit ea9eb7edb5eac4a9d175d74523db34fac0fa5180
  • Windows x64, MSVC v143 (cl 19.44.35229)
  • Legacy 2.1.0-beta2 was also observed with the same minimal reproducer.
    Observed behavior
    In standalone FFI calls, direct conversion of a signed negative integer to a pointer can yield 0x00000000ffffffff on JIT traces rather than 0xffffffffffffffff. Interpreter execution and explicit 64-bit signed cdata conversion both yield full-width bit patterns.

Example of a triggering operation, inside a hot loop:
local ffi = require('ffi')
local p = ffi.cast('void*', -1)
-- Pass p to a native C helper that inspects the pointer BIT PATTERN,
-- without dereferencing it.
A native C helper is necessary to inspect the actual argument at the FFI call boundary. The reproducer must not dereference the pointer.
Evidence

  • Unpatched JIT minimal probe: 1188 wrong calls out of 1200, first observed at JIT trace activation.
  • Earlier x64 machine code: mov esi, 0xffffffff; upper 32 bits are cleared.
  • Experimental sign-extension patch: mov rsi, -0x1; 1200/1200 correct in the corresponding test.
  • 21-case dynamic matrix: BASE JIT ON = 5880 bad; candidate patch JIT ON = 0 bad; interpretation-mode tests pass.
  • Real SQLite sqlite3_bind_text() in-memory regression on candidate: 1200 unique rows, no recorded errors. Production runtime was not modified.
    Suspected source location
    src/lj_crecord.c, inside crec_ct_ct in the case CCX(P, I) arm. The candidate patch adds a signed 32/16/8-bit to 64-bit sign-extension conversion using IRCONV_SEXT.
    Proposed patch under review
    The attached ZIP contains the reproduction and experimental patch test materials.
    The candidate patch is provided for maintainer review, not as a validated upstream fix.

candidate.zip

The proposed patch requires maintainer review of C type semantics, 32-bit paths, and possible correctness or security implications.
Limitations / questions for maintainers

  • Are integer-to-pointer cast semantics intentionally different between Lua number and signed cdata? Current interpreter/JIT mismatch suggests unintended behavior in this reproducer.
  • Is sign extension needed for all source signed integer sizes below 8 bytes on 64-bit targets?
  • Please advise on preferred source placement, narrower IR construction, and regression-test style.
  • Cross-architecture and runtime-configuration tests have NOT been conducted.

LuaJIT-Phase54I-Test-Package.zip

Lenguaje dominante
C
Estrellas
5.8k
Forks
1.2k
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de LuaJIT/LuaJIT

Todos los issues de LuaJIT/LuaJIT

Issues similares

Más issues de C

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.