Unify numeric types API across all targets#12825
Conversation
|
@copilot Please do a survey of the current situation for all our targets. Observe and summarize how they are represented for all of them, and then make a suggestion on how we could go about unifying this properly. Research how other language standard libraries handle this to get a sense for best practices. |
…a thin @:op wrapper (#12826) * Initial plan * Refactor Int64: extract Int64Native, disable platform overrides, fix JVM generator - Create std/haxe/numeric/Int64Native.hx with cross-platform emulation - Refactor std/haxe/Int64.hx to use haxe.numeric.Int64Native as underlying type - Disable platform-specific Int64 overrides (cpp, jvm, hl, eval) - Remove haxe.Int64 -> TLong mapping from JVM generator - Remove special Int64.make() optimization from JVM generator - Fix JVM stdlib Jvm.hx to work with emulated Int64 Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Refactor Int64: move implementation logic to Int64Native, make Int64 a thin @:op wrapper Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Address review: remove __Int64 typedef and IMPL, move Int64Helper to haxe.numeric, add JVM Int64Native abstract shadow Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Add HL Int64Native shadow, import cleanup, forward isInt64, re-add genjvm mapping, delete .disabled files Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Add C++ and Eval Int64Native shadows wrapping native platform types Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Fix C++ CPPIA inline requirement and docgen Int64 merge incompatibility - C++ Int64Native: Make set_high, set_low, and new unconditionally inline (they modify `this` which requires inline even in CPPIA mode) - Convert cross-platform Int64Native from class to abstract over Int64Data (fixes docgen "could not merge" error between macro/lua targets where Int64Native was abstract on native targets but class on emulation) - Create Int64Data.hx as backing class with standalone toString() - Update 6 platform-specific Type.hx files to reference Int64Data Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Add hxcpp bootstrapping to copilot setup and document C++ compilation in instructions Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Fix docgen merge: skip Int64Native in XmlParser merge, add @:dox(hide), remove differing doc comments The haxe.rtti.XmlParser merge logic already had a hardcoded skip for the old haxe._Int64.NativeInt64 path. Added haxe.numeric.Int64Native to the same skip since it's intentionally different per platform (abstract over different native types). Also added @:dox(hide) to all Int64Native implementations and removed platform-specific doc comments that caused "documentation is different" errors. Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Remove accidentally committed dox build artifacts, add to .gitignore Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * this should be better * Apply typedef pattern to JVM/HL/C++, fix CPPIA inline, fix Type.hx Int64Data refs, clean up eval @:op Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * what do you mean? * inline things * docgen is a nuisance * more CPPIA inlining * add the host class too while we're at it * close enough * remove bad inlining because this isn't going to work for CPPIA * Fix CPPIA: use extern abstract + #if !scriptable inline pattern, add getHigh/getLow static functions Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * CPPIA: use properties instead of getHigh/getLow workaround, remove #if cpp from Int64.hx Co-authored-by: Simn <634365+Simn@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Simn <634365+Simn@users.noreply.github.com> Co-authored-by: Simon Krajewski <simon@haxe.org>
|
@copilot In 1f84a42 we have reworked Int64 to a unified system. Let's now do the same for Int32 to verify that the system is flexible:
I'm not sure how well tested Int32 is in our unit tests, so let's also take this opportunity to add unit/src/unit/haxe/Int32.hx with a good test coverage. If you come across test failures on some targets, please just |
…#12828) * Initial plan * Refactor Int32 to use Int32Native pattern matching Int64 architecture - Create std/haxe/numeric/Int32Native.hx as cross-platform abstract(Int) with masking - Create JVM, HL, C++, Neko target overrides in _std directories - Refactor std/haxe/Int32.hx to thin @:op layer delegating to Int32Native - Add comprehensive TestInt32 unit test class - All tests passing on interp, JS, JVM, Neko, Python, PHP Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Address code review: add comments for Neko negation and C++ test skip Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Address PR review: fix test #if, remove Neko override, remove target docs and @:coreApi - Move #if !cpp to cover entire testArrayIndexWithInt32 function (avoids utest "no assertions") - Remove Neko-specific Int32Native override (cross-platform version works correctly via Float auto-promotion) - Remove doc comments from target-specific Int32Native files (docs belong on main Int32 type) - Remove unnecessary @:coreApi(check = Off) from private types (Implied check handles these) - Add platform representation docs to main Int32.hx Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Fix CPPIA neg overflow, deduplicate Int32Native with Int32Direct, remove @:coreApi from Int64Native, add issue regression tests Co-authored-by: Simn <634365+Simn@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
|
@copilot Before we work on more types we need to discuss what to do with the unsigned variants. We'll definitely need to define central haxe/UInt64.hx and such for each of them, but the question is if we can avoid the code duplication on the native side by working with a single implementation per integer size. I haven't given this much thought yet, so go ahead and see if we can implement UInt64 on top of NativeInt64 or if that comes with complications. |
|
|
||
| package haxe.numeric; | ||
|
|
||
| typedef Int64Native = Int64NativeImpl; |
There was a problem hiding this comment.
We can follow a similar pattern here like Int32Direct and Int32Native so that the class implementation of Int64 is available for hl-legacy32
There was a problem hiding this comment.
That hinges on whether or not we have to drag hl-legacy32 into Haxe 5 in the first place. But I would like to review this part again anyway because the code duplication between native targets annoys me and it's largely because they have different native underlying types.
| // Use ~x+1 (two's complement) rather than unary minus. | ||
| // On CPPIA, unary minus on Int can return a value wider than 32 bits, | ||
| // while bitwise NOT and addition stay within the native 32-bit int range. | ||
| return cast(~(x : Int) + 1); |
There was a problem hiding this comment.
If this bug is cppia only then it sounds like it should be fixed in the cppia runtime rather than something that should have a workaround here.
There was a problem hiding this comment.
Yes but my rate-limit on CPPIA patience has been reached for this week.
|
I think the missing piece of the puzzle here is that the cross-target implementation should also typedef to something else which has the actual implementation. That way even targets can use parts of that (like the string parsing) and we don't need to duplicate so much. That still doesn't solve the |
…gh native layer (#12834) * Initial plan * Implement UInt64 on top of Int64Native, sharing the same backing type Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Route UInt64 operations through Int64Native, remove toStr, fix increment style Co-authored-by: Simn <634365+Simn@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
|
Actually I suppose that's pretty much what we already have anyway because this shared code lives in the Int64Helper and UInt64Helper classes, and the native versions simply call that. So I guess the current state is fine and the only part left to discuss in that regard is the HL legacy situation. |
I don't think this is needed for now because arguably even
Yes! This has been missing for a long time and recently came up in another context. Let's add this while we're here and make sure to properly test it.
If we can get this to behave consistently with minimal overhead then we should do it. Our other numeric types don't throw on overflow (I think? Let's verify that), so I don't see why Int64 should. Also, the test discussion has reminded me of something else that I wanted to bring up, which is MIN/MAX constants for numeric data types. Please take a look if we can get away with simply adding |
…/Int32/UInt64 (#12836) * Initial plan * Add toFloat, fix toInt truncation, add MIN/MAX to Int64/Int32/UInt64 Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * it works for me like this --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Simn <634365+Simn@users.noreply.github.com> Co-authored-by: Simon Krajewski <simon@haxe.org>
|
@copilot I've noticed that Int32 has a bunch of |
…ds; add `compare()` (#12837) * Initial plan * Replace body-less @:op methods in Int32 with explicit implementations; add compare() Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Redesign Int32 operator overloads: use type-parameter bounds, auto-promotions; remove exhaustive mixed-type permutations Co-authored-by: Simn <634365+Simn@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
|
@copilot Let's take a step back to review the current state of the generated code so that we make sure to avoid introducing performance regressions here. I've made a very simple test case to focus on a single thing for now: @:analyzer(ignore)
@:keep
class NumericTests {
static final i = 0;
static final i32 = 0i32;
static final i64 = 0i64;
@:pure(false)
static function use<T>(v:T) {}
static function eqI64I32() {
use(i64 == i32);
}
}
function main() {}Here's the before/after of the generated and decompiled JVM output: And here the same for HL: Please do a deep investigation of this and what causes the differences. Look into how the compiler handles abstract casts and type conversions in general, and also check out the two generators in that regard. See where improvements can be made and optimizations need to be applied. Focus on the compiler sources for that, no the standard library changes here. You can use |
|
Here's a summary of the design that has emerged:
This gives us a dual-path design that keeps the existing flexibility of Int/Float, but allows strictly defined numeric conversions for Int32 and such in places where it matters. There will be a perceived loss of convenience in that area because values can no longer be arbitrarily converted, but I'm prepared to argue that this is a major improvement. |
…ng conversions for (U)Int32/64 (#12845) * Initial plan * Add Float comparison ops to Int32/Int64/UInt64; add @:to Float to Int64/UInt64 Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Remove @:to Float from Int64/UInt64; integer cross-type comparisons use integer semantics Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Changes before error encountered Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Implement strict numeric type design: remove implicit float casts, add widening conversions, guard breaking tests - Remove @:transitive from Int32, UInt32, Int64 (breaks implicit multi-step coercions) - Remove @:to Float and all Float @:op overloads from Int32 and UInt32 - Add @:to Int to Int32 for explicit widening to platform Int - Add @:from Int32, @:from UInt32 widening casts to Int64; @:from UInt32, @:from Int64 to UInt64 - Add same-size @:from casts (Int32↔UInt32, Int64↔UInt64) - Add explicit toFloat(), toInt32(), toUInt32(), toInt64(), toUInt64(), fromFloat() to all types - Fix stdlib that relied on removed implicit conversions: io/Bytes.hx, io/BytesBuffer.hx, io/Output.hx, io/UInt32Array.hx, js/_std/io/UInt32Array.hx, numeric/Int64Native.hx, numeric/UInt64Helper.hx, eval/_std/numeric/Int64Native.hx - Guard all breaking tests behind #if loose_numeric_casts with noAssert() fallback: Issue2718, 2735, 2736, 2871, 3543, 3852, 5362 and TestInt32/TestUInt32/TestUInt32Array Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Fix bigint stdlib: change Vector<Int32> to Vector<Int>, shift params Int32→Int, tolerance UInt→Int Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Fix bigint (Vector<Int32>, switch cast, public API) and bytes flash conversions (UInt.toInt()) Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * fixes * dance around HL problems again * avoid flash problems too * it's 2026 and I'm editing flash externs, send help * missed one * try to fix the actual problem instead of doing this nonsense * update hlcode tests * I'm told this was fixed * Add hlcode tests for all (U)Int32/64 ↔ Int conversions and mixed operations Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * delete more code * deal with some tests * remove flash @:transitive * another one * that one was needed * update bytes public interface * Fix _std overrides: update getInt32/setInt32/addInt32/i32ToFloat/floatToI32 to use Int32 Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Fix flash CI failure: remove untyped in BytesOutput.getBytes, use bytes.length.toInt() Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * fix * Add testStrictTypeChecking to TestInt32/UInt32/Int64/UInt64 asserting disallowed conversions cause type errors Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Remove @:to Int from Int32, update API functions to use Int32 (partial - more fixes needed) Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Fix Int64Native shift/toString after @:to Int removal, fix stdlib sites using readInt32/setInt32 Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Fix HL target: Int32→hl.I64 in Int64Native, setI32 calls need .toInt(), fix hl/Bytes.fromAddress Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Fix unit tests: use .toInt() for Int32→Int conversions in tests and issue regressions Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Fix HL-specific TestInt32 edge cases: use .toInt() for Int32→Int comparisons Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Reorganize @:to/@:from casts per Simn's design: add back @:to Int on Int32, use @:to on source types instead of @:from on target types Int32: @:to Int (public), @:to UInt32 (private), @:to Int64 (private) UInt32: @:to Int32 (private), @:to UInt64 (private), toInt() (public, no @:to) Int64: @:to UInt64 (private), toInt32() (public) UInt64: @:to Int64 (private), toUInt32() (public) Removed @:from fromInt32/fromUInt32/fromUInt64 from Int64 and UInt64. Removed @:from fromUInt32/fromInt32 from Int32/UInt32. Removed toUInt64() from Int32, toInt64() from UInt32 (long paths). Removed toUInt32() from Int64, toInt32() from UInt64 (use toInt32().toUInt32()). All tests pass: interp (11572), JS (11625), JVM (12340), HL (12003), flash compiles clean. Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * Fix formatting in Int64Native shr/ushr: consistent line breaks in ternary expressions Co-authored-by: Simn <634365+Simn@users.noreply.github.com> * avoid HL more * Re-apply Int32 API signatures for "32" suffix functions: readInt32():Int32, i64ToDouble(low:Int32,high:Int32) Since @:to Int is back on Int32, functions with "Int32" suffix should use haxe.Int32 in their signatures. The @:to Int handles implicit coercion where needed in function bodies. Restored: - Input.readInt32():Int32 and BytesInput override - FPHelper.i64ToDouble(low:Int32, high:Int32) in all target overrides (cpp, eval, hl, lua, php, python) - Python FileInput.readInt32():Int32 and IInput.readInt32():Int32 All tests pass: interp (11572), JS (11625), JVM (12340), HL (12003), Python (11715), flash compiles clean, hlcode (38 tests). Co-authored-by: Simn <634365+Simn@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Simn <634365+Simn@users.noreply.github.com> Co-authored-by: Simon Krajewski <simon@haxe.org>
# Conflicts: # src/generators/genhl.ml # std/haxe/UInt32.hx # std/hl/_std/haxe/UInt32.hx # tests/unit/src/unit/issues/Issue2990.hx
# Conflicts: # std/cpp/_std/haxe/Int64.hx # std/eval/_std/haxe/Int64.hx # std/haxe/Int64.hx # std/hl/_std/haxe/Int64.hx # std/jvm/_std/haxe/Int64.hx
|
Right, that test still fails on these targets because the expression is something like this: @:implicitCast {
var x = cast cast python.Syntax.code("{0} % {1}", -1756908916 + python.Syntax.opPow(2, 31), python.Syntax.opPow(2, 32)) - python.Syntax.opPow(2, 31);
var this;
this = x;
cast cast this;
}The analyzer manages to turn the expression into a constant on other targets, but this is a bit much. This is one of these cases that would need better internal constant typing. |
|
@copilot Something we still need to do here is change how the comparison operators are generated. It currently goes through the (u)compare functions, but on targets with native support we want to generate the native comparison operators. This means that these calls have to be dispatched to the Int32Native/Int64Native types instead. Make sure to check the hlcode tests after updating this because it should change the results there. |
…gen (#12855) * Initial plan * Dispatch comparison operators to Int32Native/Int64Native for native codegen Add lt/lte/gt/gte (signed) and ult/ulte/ugt/ugte (unsigned) comparison functions to Int32Native, Int32Direct, Int64Native, and all target-specific overrides (JVM, HL, C++, eval). Update Int32/Int64/UInt32/UInt64 abstract operators to call these native functions directly instead of going through compare()/ucompare(). On targets with native support (JVM, HL), signed comparisons now generate direct native comparison operators instead of the multi-branch compare-return-{-1,0,1}-then-check pattern. HL bytecode improvement for Int32 < Int: 19 → 11 instructions HL bytecode improvement for Int64 < Int: 20 → 12 instructions Updated hlcode test expectations accordingly. Co-authored-by: Simn <634365+Simn@users.noreply.github.com> Agent-Logs-Url: https://github.com/HaxeFoundation/haxe/sessions/00ae78d7-e1c3-49a6-8216-da0541560084 * Clarify hlcode test comment about unsigned comparison dispatch Co-authored-by: Simn <634365+Simn@users.noreply.github.com> Agent-Logs-Url: https://github.com/HaxeFoundation/haxe/sessions/00ae78d7-e1c3-49a6-8216-da0541560084 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
|
@copilot I just noticed that Let's also take this opportunity to align the order of functions on all four types. I think Int64 and UInt64 already match (double-check that), so let's align Int32 and UInt32 to that. Let's also add |
… fix HL opcode tests (#12857) * Initial plan * Change isZero/isNeg to instance methods, add copy() to Int32/UInt32, align API order, fix HL opcode tests Co-authored-by: Simn <634365+Simn@users.noreply.github.com> Agent-Logs-Url: https://github.com/HaxeFoundation/haxe/sessions/330c2464-c0e6-4f48-b8e5-899473797b40 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR advances the Haxe stdlib/compiler toward a unified, cross-target fixed-width numeric API by moving core numeric behavior behind haxe.numeric.* backends, adding haxe.UInt64, and updating tests/target stubs to match the new semantics.
Changes:
- Refactors
haxe.Int32,haxe.UInt32, andhaxe.Int64to delegate tohaxe.numeric.Int32Native/haxe.numeric.Int64Nativewith target-specific_stdoverrides (JVM/HL/Eval/CPP). - Introduces
haxe.UInt64plus unsigned helper utilities, and updates multiple targets’Typedetection and runtime support to recognize the new backing implementation. - Expands/updates unit + codegen tests to lock in operator semantics, strict-cast behavior, and JS/HL codegen expectations.
Reviewed changes
Copilot reviewed 70 out of 71 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/src/unit/teststd/haxe/io/TestUInt32Array.hx | Updates UInt32Array tests (formatting + toFloat() usage) to match new UInt32 API. |
| tests/unit/src/unit/teststd/haxe/TestUInt32.hx | Adds a comprehensive UInt32 behavior test suite (string/compare/ops/shifts/strict casts). |
| tests/unit/src/unit/teststd/haxe/TestInt32.hx | Reworks Int32 tests to cover constants/overflow/ops/shifts/strict casts under new backend. |
| tests/unit/src/unit/issues/misc/Issue12415Abstract.hx | Updates Int64 zero-check usage to new instance API style. |
| tests/unit/src/unit/issues/Issue6942.hx | Migrates enum abstract from UInt to haxe.UInt32 and adjusts expectations. |
| tests/unit/src/unit/issues/Issue5362.hx | Updates UInt mixing by using explicit toInt() conversion. |
| tests/unit/src/unit/issues/Issue4870.hx.disabled | Adds a disabled regression scaffold referencing UInt behavior. |
| tests/unit/src/unit/issues/Issue3852.hx | Gates UInt/Float mixed ops behind #if loose_numeric_casts. |
| tests/unit/src/unit/issues/Issue3543.hx | Makes UInt division explicitly float-based via toFloat(). |
| tests/unit/src/unit/issues/Issue2990.hx | Updates typeof expectations to enforce integer semantics for UInt32 division/modulo. |
| tests/unit/src/unit/issues/Issue2871.hx | Makes UInt-to-Int conversion explicit via toInt(). |
| tests/unit/src/unit/issues/Issue2736.hx | Gates UInt vs Float comparisons behind #if loose_numeric_casts. |
| tests/unit/src/unit/issues/Issue2735.hx | Makes UInt-to-Float conversion explicit via toFloat(). |
| tests/unit/src/unit/issues/Issue12415.hx | Updates Int64 zero-check on nullable abstract via instance API. |
| tests/unit/src/unit/issues/Issue11248.hx | Adjusts constants (UInt→Int) with comment about UInt32 typing friction. |
| tests/unit/src/unit/TestType.hx | Reorders imports and updates Flash UInt typing expectation to use toInt(). |
| tests/unit/src/unit/TestMain.hx | Adds TestUInt64 to the unit test suite run list. |
| tests/unit/src/unit/TestInt64.hx | Updates Int64 tests to new APIs (fromInt, toString, %), adds strict-cast tests. |
| tests/optimization/src/TestJs.hx | Adds JS output test ensuring UInt32 Std.string uses unsigned formatting logic. |
| tests/hlcode/src/cases/UInt32Types.hx | Adds HL bytecode “golden” tests documenting UInt32 compare/shift lowering. |
| tests/hlcode/src/cases/NumericTypes.hx | Adds HL bytecode tests ensuring numeric abstracts don’t introduce temporaries. |
| std/python/_std/Type.hx | Updates TInt64 runtime detection to use haxe.numeric.Int64Native. |
| std/php/_std/Type.hx | Updates TInt64 runtime detection to use haxe.numeric.Int64Native. |
| std/neko/_std/Type.hx | Updates TInt64 runtime detection to use haxe.numeric.Int64Native. |
| std/lua/_std/Type.hx | Updates TInt64 runtime detection to use haxe.numeric.Int64Native. |
| std/lua/_lua/_hx_bit_clamp.lua | Adjusts Lua int32 clamping logic by forcing integer conversion prior to bit ops. |
| std/jvm/_std/haxe/numeric/Int64Native.hx | Adds JVM-native Int64Native backend (wrapping jvm.Int64). |
| std/jvm/_std/haxe/numeric/Int32Native.hx | Adds JVM Int32Native override typedef to Int32Direct. |
| std/jvm/_std/haxe/Int64.hx | Removes JVM-specific haxe.Int64 implementation in favor of unified backend. |
| std/jvm/Jvm.hx | Changes toLong to return haxe.Int64 and adjusts incr/decr paths. |
| std/jvm/Int64.hx | Simplifies JVM core jvm.Int64 extern ops set (removes Int-mixed variants). |
| std/js/_std/haxe/io/UInt32Array.hx | Ensures JS UInt32Array set writes the underlying Int via toInt(). |
| std/js/_std/Type.hx | Updates TInt64 runtime detection to use haxe.numeric.Int64Native. |
| std/hl/types/ArrayObj.hx | Updates unsigned bounds checks to use haxe.UInt32 casts. |
| std/hl/types/ArrayBytes.hx | Updates unsigned bounds checks to use haxe.UInt32 casts. |
| std/hl/_std/haxe/numeric/Int64Native.hx | Adds HL-native Int64Native backend (wrapping hl.I64) under version guard. |
| std/hl/_std/haxe/numeric/Int32Native.hx | Adds HL Int32Native override typedef to Int32Direct. |
| std/hl/_std/haxe/UInt32.hx | Removes HL-specific haxe.UInt32 implementation in favor of unified backend. |
| std/hl/I64.hx | Adds @:from conversion from haxe.Int64 to hl.I64. |
| std/hl/GUID.hx | Adds @:from conversion from haxe.Int64 to hl.GUID. |
| std/haxe/rtti/XmlParser.hx | Updates private-impl path filtering to new Int64Native private type path. |
| std/haxe/numeric/UInt64Helper.hx | Introduces shared unsigned-64 helper algorithms (div/mod/parse/toString/toFloat). |
| std/haxe/numeric/Int64Native.hx | Adds default (emulated) Int64Native backend + unsigned helpers wiring. |
| std/haxe/numeric/Int64Helper.hx | Introduces shared Int64 parse/fromFloat helper for Int64Native backends. |
| std/haxe/numeric/Int32Native.hx | Adds default Int32Native backend with clamp + unsigned helpers (parse/udiv/utoString). |
| std/haxe/numeric/Int32Helper.hx | Introduces shared Int32 parsing/unsigned division helpers. |
| std/haxe/numeric/Int32Direct.hx | Adds no-masking Int32 backend for native-32-bit targets (C++/JVM/HL). |
| std/haxe/io/BytesOutput.hx | Fixes Flash ByteArray UInt→Int conversions for length and Bytes construction. |
| std/haxe/io/BytesInput.hx | Fixes Flash ByteArray UInt→Int conversions for position/length/read methods. |
| std/haxe/io/BytesBuffer.hx | Fixes Flash ByteArray UInt→Int conversions in size and Bytes creation. |
| std/haxe/io/Bytes.hx | Fixes Flash ByteArray UInt→Int conversions in compare/fromString/ofData. |
| std/haxe/UInt64.hx | Adds the public cross-platform haxe.UInt64 abstract API. |
| std/haxe/UInt32.hx | Refactors UInt32 to a cross-platform abstract over Int32Native with unsigned semantics. |
| std/haxe/Int64Helper.hx | Updates Int64Helper to use new instance-style APIs (fromInt, isNeg). |
| std/haxe/Int32.hx | Refactors Int32 to a cross-platform abstract over Int32Native with consistent ops. |
| std/flash/_std/Type.hx | Updates TInt64 runtime detection to use haxe.numeric.Int64Native. |
| std/flash/Boot.hx | Fixes Flash stage color UInt→Int conversion. |
| std/eval/integers/Int64.hx | Adjusts eval Int64 interface visibility/ops exposure. |
| std/eval/_std/haxe/numeric/Int64Native.hx | Adds eval-native Int64Native backend (wrapping eval.integers.Int64). |
| std/eval/_std/haxe/Int64.hx | Removes eval-specific haxe.Int64 implementation in favor of unified backend. |
| std/cpp/cppia/HostClasses.hx | Updates kept host class list to new Int64Native impl path; tidies extern set formatting. |
| std/cpp/_std/haxe/numeric/Int64Native.hx | Adds C++ Int64Native backend using hxcpp helper intrinsics (incl. cppia surface). |
| std/cpp/_std/haxe/numeric/Int32Native.hx | Adds C++ Int32Native override typedef to Int32Direct. |
| std/cpp/_std/haxe/Int64.hx | Removes C++-specific haxe.Int64 implementation in favor of unified backend. |
| src/optimization/inline.ml | Adds UInt32 case to Std.string inliner (noted as effectively unreachable). |
| src/generators/genjvm.ml | Removes JVM codegen special-case for haxe.Int64.make constant folding. |
| src/generators/genhl.ml | Disables UInt32-as-unsigned detection (commented out due to failures). |
|
@copilot Please take a look at the still unresolved review comments! |
…ation fix, test assertion fixes (#12859) * Initial plan * Address review comments: explain genhl.ml UInt32 design, fix Lua truncation, fix Int32/64 test assertions Co-authored-by: Simn <634365+Simn@users.noreply.github.com> Agent-Logs-Url: https://github.com/HaxeFoundation/haxe/sessions/01972f1a-bfdf-4e6b-94da-b1c2d5d377db --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
|
This is as good as it's gonna get. We still have the As a next step we should probably look into adding |
At the moment all targets mostly just do their own thing when it comes to numeric types. While some like
haxe.Int64are somewhat nicely abstracted in the user-facing code, others are really only available via their target-specific type. I'd like to look into cleaning this up to have a unified API.Initial analysis:
Numeric types are inconsistently available and named across Haxe targets. This PR documents the current state and proposes a unification path.
Current State
Intprecision varies per target: 31-bit (Neko), 32-bit (C++/JVM/HL), 53-bit (JS), unbounded (Python), platform-dependent (PHP)haxe.Int64is the only well-unified fixed-width type — 4 targets use native overrides, 6 use emulated high/low paircpp.Int8–cpp.UInt64,cpp.Float32/Float64), JVM has partial (jvm.Int8,jvm.Int16,jvm.Int64), HL uses different naming (hl.I64,hl.F32,hl.UI8), scripting targets have nothinghaxe.*: No cross-platformInt8,Int16,UInt8,UInt16,UInt64,Float32UIntis only truly unsigned on Flash; simulated elsewhereSingle(Float32) exists as@:coreTypeon only 3 targetsProposal
Follow the proven
haxe.Int64pattern (cross-platform abstract + native_stdoverrides) to add:haxe.Int8abstract(Int)+ maskinghaxe.Int16abstract(Int)+ maskinghaxe.UInt8abstract(Int)+ maskinghaxe.UInt16abstract(Int)+ maskinghaxe.UInt32UInthaxe.UInt64haxe.Float32abstract(Float)(lossy)haxe.Float64FloatOpen Questions
Intbe pinned to 32-bit or documented as "at least 32-bit"?cpp.Int8→haxe.Int8,hl.I64→haxe.Int64,Single→haxe.Float32)UInt8/UInt16(binary protocols) andFloat32(graphics/games)Research
Surveyed Rust, Go, Swift, Kotlin, C# — all provide complete fixed-width type sets consistent across platforms. Swift's protocol hierarchy (
Numeric→BinaryInteger→FixedWidthInteger) is the most sophisticated generic approach. Kotlin Multiplatform normalizes all numeric types in common code without needingexpect/actual.