Skip to content

[lua] Fix closure on string method causing runtime error#12676

Open
jdonaldson wants to merge 1 commit intoHaxeFoundation:developmentfrom
jdonaldson:fix-8068-string-closure
Open

[lua] Fix closure on string method causing runtime error#12676
jdonaldson wants to merge 1 commit intoHaxeFoundation:developmentfrom
jdonaldson:fix-8068-string-closure

Conversation

@jdonaldson
Copy link
Member

Summary

Fixes #8068 on the Lua target.

Extracting a method from a string as a closure (var o = {charAt: f.charAt}) crashes at runtime because:

  1. Native Lua strings don't have Haxe methods on their metatable. The generator emits _hx_bind(f, f.charAt), but f.charAt resolves to nil through Lua's default string metatable. Fixed by looking up the method from String.prototype instead when the expression is String-typed.

  2. _hx_bind crashes on non-table primitives. It calls rawset(o, '_hx__closures', {}) which fails on strings. Fixed by detecting non-table types and returning a fresh bound closure without caching. This covers the Dynamic/untyped case where the generator can't know the type at compile time.

Note: the JS target has the same $bind issue (tries to set hx__closures__ on a string primitive). This PR only addresses Lua.

Test plan

  • New regression test Issue8068 — extracts charAt from a string, calls it through an anonymous object
  • All Lua unit tests pass (11661 assertions, 0 failures)
  • Standalone repro from original issue returns correct result

@Simn
Copy link
Member

Simn commented Feb 26, 2026

I generally think this should be fixed in the run-time because whatever problem can occur with properly typed code can also occur when accessing it through Dynamic. I don't know if that's something we can do on lua though, so maybe this is alright. Let's double-check that!

@jdonaldson jdonaldson force-pushed the fix-8068-string-closure branch from 21910e9 to 0db2d52 Compare February 26, 2026 06:55
…ion#8068)

Two fixes for extracting string methods as closures (e.g. f.charAt):

1. Generator: when creating a closure on a String-typed expression,
   look up the method from String.prototype instead of from the native
   Lua string, which doesn't have Haxe methods on its metatable.

2. Runtime: guard _hx_bind against non-table values (strings, numbers)
   by skipping the closure cache (rawset crashes on primitives) and
   returning a fresh bound closure. Covers Dynamic/untyped access.
@jdonaldson jdonaldson force-pushed the fix-8068-string-closure branch from 0db2d52 to cc1ef26 Compare March 1, 2026 17:33
@skial skial mentioned this pull request Mar 4, 2026
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Closure on string

2 participants