Skip to content

Fix value conversions, Lua string coercion and stream reads - #394

Merged
akeit0 merged 2 commits into
mainfrom
codex/fix-value-and-stream-conversions
Oct 29, 2026
Merged

akeit0 merged 2 commits into
mainfrom
codex/fix-value-and-stream-conversions

Conversation

@akeit0

@akeit0 akeit0 commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator

Fix incorrect C# value conversions, memory-stream consumption and Lua library string arguments.

  • Reject out-of-range int, long, uint and ulong conversions before casting. TryRead returns false instead of clamping or throwing; generated bindings report Lua argument errors. Exclusive double upper bounds handle the rounded 64-bit maxima correctly.
  • Return boxed booleans from Read<object>(), preserving object-typed C# arguments and round trips.
  • Advance StringStream after reading all content, and preserve nonnumeric input after a failed memory-stream number read. Leading whitespace is scanned once.
  • Accept numeric arguments where Lua libraries expect strings, using the platform's number format. Coerce the argument slot as C Lua 5.2 does, including during reentrant debug inspection, while keeping typed C# string reads strict.
  • Read file:seek offsets as long, matching the stream API and supporting positions beyond 2 GiB.

For example, string.len(123) now returns 3, reading all of a string-backed stream leaves it at EOF, and reading a number from x12 leaves x12 available for the next read.

Validation

  • Release solution builds all four runtime targets without warnings.
  • Full runtime suite: 2,697 passed on each .NET 8/10, plus 73 generator tests. After the seek follow-up, all 77 focused conversion and I/O tests pass on each framework.
  • Regression cases fail against the original binary. Native Lua 5.2 confirms numeric string coercion and its visibility through debug.getlocal.
  • The large-offset seek regression uses a position-only stream, without allocating a large file or buffer.
  • CSharpier, diff checks and benchmark --verify pass.
  • Paired .NET 10 samples show string workloads about 6–10% faster, unchanged allocations and no host-call slowdown. Direct signed integer reads cost about 2% more for required range validation; unsigned reads improve after removing checked conversion helpers.

Reject out-of-range int, long, uint and ulong reads before casting, using
exclusive double upper bounds for 64-bit targets. TryRead returns false
instead of clamping or throwing, and generated argument errors remain Lua
errors. Read booleans as boxed bool values for object-typed interop.

Advance StringStream after its full-content fast path. Scan leading
whitespace once for memory-backed numeric reads and preserve nonnumeric
input when conversion fails.

Use a shared Lua-library string reader that accepts numeric arguments in
the selected platform format and updates the argument slot like Lua 5.2.
Keep public typed C# string reads strict and preserve caller values across
reentrant callbacks.

Add 54 regression cases for integer boundaries, boxing, generated bindings,
stream cursor sequences, numeric string arguments, format policies and
reentrant debug inspection. The original binary fails the regression cases
for all five bugs; native Lua 5.2 confirms the argument-slot behavior.

Validation: 2,697 runtime tests pass on each of .NET 8 and .NET 10, plus 73
generator tests. Release solution build passes for all four runtime targets
with no warnings. CSharpier, diff checks and benchmark --verify pass.

Paired .NET 10 samples show string workloads 6-10% faster, unchanged
allocations and no host-call slowdown. Direct signed integer reads add
about 2% for range validation; unsigned reads improve after eliminating
checked conversion helpers.
Read file:seek offsets as long to match ILuaStream.Seek and FileHandle.Seek.
This avoids a 32-bit restriction when the underlying .NET stream supports
larger offsets and keeps range validation at the existing conversion
boundary. Lua 5.2 likewise sizes offsets for its configured file backend.

Add a position-only regression covering a 3 GB absolute seek, querying the
position, and a negative relative offset beyond Int32 range. The original
binary fails this case; no large files or buffers are created by the test.

Validation: Release solution builds all runtime targets without warnings.
All 77 focused conversion, memory-stream, file-seek and I/O tests pass on
.NET 8 and .NET 10. CSharpier and diff checks pass.
@akeit0
akeit0 merged commit 3fbaaea into main Oct 29, 2026
2 checks passed
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.

1 participant