HaxeFoundation / HaxeFoundation/haxe
`@:hlNative` on extern function silently omits native registrations in HL target
- Dominant language
- Haxe
- Stars
- 6.9k
- Forks
- 715
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 11
Description
**Haxe version:** latest (reproduced on 4.x)
**Target:** HashLink (hl)
### Description
When using `@:hlNative` on an `extern` function inside a regular class, the compiler does not emit native function entries into the `.hl` bytecode. As a result, HashLink cannot resolve the functions at runtime and either crashes with `JIT ERROR -1` or `Failed to load function`.
The same binding works correctly when the function has a stub body (`{ return null; }`) without the `extern` keyword.
### Reproduction
**Working:**
```haxe
class SysNative {
@:hlNative("std", "sys_locale")
static public function sysLocale(): hl.Bytes { return null; }
}
```
**Not working (no compile-time error, runtime crash):**
```haxe
class SysNative {
@:hlNative("std", "sys_locale")
static extern public function sysLocale(): hl.Bytes;
}
```
### Investigation
Comparing the two compiled `.hl` files shows that in the `extern` function variant, the native function name (`sys_locale`) is completely absent from the bytecode string table. The native entry is never written, so `functions_indexes` for that findex remains `0xFFFFFFFF`, which triggers `ASSERT(fid)` in [`jit.c:1585`](https://github.com/HaxeFoundation/hashlink/blob/981e1a69a537943d7b2d1e8647cf14b0363a1f53/src/jit.c#L1585) (`op_call_fun`).
Attempting to compile with `--hl out.c` also throws `Invalid_argument("index out of bounds")` for the extern variant, further confirming the issue is in the compiler emit phase.
### Expected behavior
`@:hlNative` on an `extern` function should produce the same bytecode output as on a regular function with a stub body, consistent with how the feature works on other targets.
Contributor guide
Research direction
Reproduce the issue with the two `@:hlNative` examples and compare their `.hl` output, including the missing native name. Start with the compiler emit phase and `--hl out.c`; use HashLink `jit.c:1585` as the runtime failure reference. Done means the extern form emits the same native registration as the stub-body form.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100