Skip to content

cgen,builtin: support for 64bit int 1#25236

Merged
spytheman merged 20 commits intovlang:masterfrom
kbkpbot:64bit-int-1
Sep 13, 2025
Merged

cgen,builtin: support for 64bit int 1#25236
spytheman merged 20 commits intovlang:masterfrom
kbkpbot:64bit-int-1

Conversation

@kbkpbot
Copy link
Contributor

@kbkpbot kbkpbot commented Sep 4, 2025

Feature required by #25206

This is the first PR to enable 64bit int on an 64bit system.

It can be use with -d new_int to enable this feature,

v self -d new_int

This will build a new V compiler with this feature enabled.

NOTE: Currently the V compiler itself is working, but some works needed to make vlib pass all tests.

When enable -d new_int, internal int will be replaced by a vint_t in the compiler.

@kbkpbot kbkpbot marked this pull request as draft September 4, 2025 14:06
@huly-for-github
Copy link

Connected to Huly®: V_0.6-24731

@kbkpbot
Copy link
Contributor Author

kbkpbot commented Sep 4, 2025

a simple test code:
b.v

module main

fn main() {
        x := []int{len: 4}

        for i in 0 .. x.len {
                dump(x[i])
        }

        dump(sizeof(int))
}
$ v run b.v
[b.v:7] x[i]: 0
[b.v:7] x[i]: 0
[b.v:7] x[i]: 0
[b.v:7] x[i]: 0
[b.v:10] sizeof(int): 8

note that the sizeof(int) is 8 now.

and the generated C code:

//================================== builtin types ================================*/
#if defined(__x86_64__) || defined(_M_AMD64) || defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || (defined(__riscv_xlen) && __riscv_xlen == 64) || defined(__s390x__) || (defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)) || defined(__loongarch64)
typedef int64_t vint_t;
#else
typedef int32_t vint_t;
#endif


VV_LOC void main__main(void) {
        Array_vint_t x = __new_array_with_default_noscan(4, 0, sizeof(vint_t), 0);
        for (vint_t i = 0; i < x.len; ++i) {
                 _v_dump_expr_vint_t(_S("b.v"), 7, _S("x[i]"), (*(vint_t*)array_get(x, i)));
        }
         _v_dump_expr_u32(_S("b.v"), 10, _S("sizeof(int)"), sizeof(vint_t));
}

@JalonSolov
Copy link
Contributor

Question: Would it be simpler to force int to be an alias to either i32 or i64? This could be done early, and inserted into the AST. You wouldn't need a max_int, as it would resolve to either max_i32 or max_i64, etc. - or simply force that as an alias, as well.

@kbkpbot
Copy link
Contributor Author

kbkpbot commented Sep 5, 2025

Question: Would it be simpler to force int to be an alias to either i32 or i64? This could be done early, and inserted into the AST. You wouldn't need a max_int, as it would resolve to either max_i32 or max_i64, etc. - or simply force that as an alias, as well.

That is my first option, but soon I found some problems:

  1. sumtype, which has both int and i64 in it, for example, type MySum = int | i64 will cause the compiler confuse, that it may generate two fields of _i64, which is wrong.
  2. All int methods , such as .str_l(), .hex_full(), must re-implement in with i64.
  3. something like json, orm implement in v compiler, they call vlib/json`` and vlib/orm` directly, this will cause some problems.

I am still working on find out a better solution for this.

@JalonSolov
Copy link
Contributor

JalonSolov commented Sep 5, 2025

  1. It would be the same as type MySum = string | string, just with a different error message.
error: sum type MySum cannot hold the type `string` more than once
    1 | type MySum = string | string
      |                       ~~~~~~

So something like

error: sum type MySum cannot hold the type `i64` more than once (`int` is an alias for `i64`)
    1 | type MySum = int | i64
      |                    ~~~
  1. Those methods should be on i64 and i32 already.

  2. That's the tougher one...

@kbkpbot
Copy link
Contributor Author

kbkpbot commented Sep 5, 2025

Yes, using int as an alias for i64 or i32 can ensure that the generated AST contains accurate information, so that even different backends can correctly handle the int type.

@kbkpbot
Copy link
Contributor Author

kbkpbot commented Sep 9, 2025

Fix issue #25269, it is a msvc bug.
827b0a8

@kbkpbot
Copy link
Contributor Author

kbkpbot commented Sep 10, 2025

After enabling 64-bit integers in v, do all the C interface function codes need to be adjusted? For example, does fn C.memset(str voidptr, c int, n usize) voidptr need to be changed to fn C.memset(str voidptr, c i32, n usize) voidptr? This seems like quite a substantial workload.

@spytheman
Copy link
Member

For example, does fn C.memset(str voidptr, c int, n usize) voidptr need to be changed to fn C.memset(str voidptr, c i32, n usize) voidptr?

I think that preferably yes.

int in the C side does not change its size between 32 and 64 bit machines, unlike in Go where it does.

I think that using i32 instead, will be less ambiguous in the C declarations.

@spytheman
Copy link
Member

@medvednikov what do you think?

@JalonSolov
Copy link
Contributor

JalonSolov commented Sep 10, 2025

That might be a separate PR.

Not only do the fn defs need to be changed, but we should have a checker error to not allow int in C. defs from now on.

@spytheman
Copy link
Member

That might be a separate PR.

Yes, definitely.

@spytheman
Copy link
Member

but we should have a checker error to not allow int in C. defs from now on.

perhaps a notice first; otherwise it will break a lot of projects

@spytheman
Copy link
Member

v fmt could also just change int into i32 just inside fn C. 🤔 .
I do not see downsides to that so far.

@JalonSolov
Copy link
Contributor

I'd say a warning rather than a notice.

The code will likely fail in unexpected ways if int is used. At least warning up front will let people know of the problem, and the warning turning to an error will block the "weird" failures in production code.

@spytheman
Copy link
Member

The usual escalation for such things is notice->warning->error with at least 1 week before each transition, preferably 1 month.

@spytheman
Copy link
Member

The code will likely fail in unexpected ways if int is used.

I do not see how, -d new_int is still not the default, and while that is not changed, a notice seems completely fine to me - it will give people time to upgrade.

@JalonSolov
Copy link
Contributor

Hmm... notice if new_int isn't defined, warning/error if it is?

Because if it's on, using int is fine as long as the int size matches what the C. def needs, but it can badly mess things up if it doesn't match. For example, using i64 where i32 was the requirement (which might just give bad answers), or using i32 where i64 was required (which can overwite stack), etc.

@kbkpbot
Copy link
Contributor Author

kbkpbot commented Sep 11, 2025

I believe that most of the conversions for 64-bit int inside cgen are already working.

TODO:

  1. Modify all int types in C.func to i32;
  2. Fix vlib to ensure it passes all tests with -d new_int enabled;
  3. Modify c2v and others to use i32 instead of int for generating function interfaces;
  4. Add notice/warning/error message for using int in a C.func.
  5. Maybe some other c2v projects, such as doom need to regenerate the code. :(

@kbkpbot kbkpbot marked this pull request as ready for review September 11, 2025 13:54
kbkpbot added a commit to vlang/c2v that referenced this pull request Sep 12, 2025
As vlang/v#25236 may change int a platform dependent 32/64 bit integer, all int from a C program should translate to i32 in v.
@kbkpbot
Copy link
Contributor Author

kbkpbot commented Sep 12, 2025

please wait for sometime, fixing...

@spytheman
Copy link
Member

I believe that most of the conversions for 64-bit int inside cgen are already working.
TODO:

Please do not expand the scope of the PR. It was already good as it is, and given its nature, it has to be done in stages.

Adding more stuff here, just complicates things a lot, both for you, for me, and for the users of c2v :-|

@kbkpbot
Copy link
Contributor Author

kbkpbot commented Sep 12, 2025

A bug found by 513030d, #25291
need another PR to fix this.

* master:
  cgen: fix option variadic arg passing (fix vlang#25261) (vlang#25273)
  x.crypto.ascon: improve ascon_generic_hash, cleanup (vlang#25288)
  cgen: fix generic cast to sumtype of empty struct (fix vlang#25263) (vlang#25290)
  cgen: fix fixed-array const initializer (fix vlang#25291) (vlang#25293)
@spytheman spytheman merged commit c221b32 into vlang:master Sep 13, 2025
83 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.

3 participants