Skip to content

cgen: prefix builtin methods with builtin__#25264

Merged
spytheman merged 1 commit into
vlang:masterfrom
dy-tea:master
Sep 10, 2025
Merged

cgen: prefix builtin methods with builtin__#25264
spytheman merged 1 commit into
vlang:masterfrom
dy-tea:master

Conversation

@dy-tea

@dy-tea dy-tea commented Sep 8, 2025

Copy link
Copy Markdown
Member

We would like to prevent user-defined variable names from being able to conflict with c functions generated by the compiler.

Most simple thing in most cases is prefixing with _ but we need to specifically check for builtin types in some places as we don't want to add this to user-defined functions which will then reintroduce the issue (maybe we want a separate prefix for user-defined variables as well so they don't conflict with c functions?).

I have some commented out lines in the test at the moment for array and map initialization. Wasn't sure how to handle this.

I handle int_literal and float_literal separately but there might be a more elegant way to do this?

There are some places where I only prefix an underscore and was wondering if it's more efficient to use the string plus operator or string formatting, I currently mostly use string formatting but it can be changed.

This does not handle name collisions with included c functions like printf. Maybe have a per-module c_reserved array with the included function names? Not sure about the best solution for this.

Since this adds quite a few is_builtin() checks it likely will have some performance impact. It didn't seem too bad but I didn't do any extensive tests.

@huly-for-github

Copy link
Copy Markdown

Connected to Huly®: V_0.6-25002

@dy-tea dy-tea marked this pull request as draft September 8, 2025 22:03
@JalonSolov

Copy link
Copy Markdown
Collaborator

A scheme discussed in the past would be to simply prefix builtin names with the module name, the same way every other module in V prefixes the names with the module name.

For example, if you call os.dir(), the name of the routine comes out as os__dir in the output. fn main() comes out as main__main.

So why not builtin__println instead of println? It removes the name collisions with normal C routines, and makes it far less likely that such will happen in the future.

@dy-tea

dy-tea commented Sep 8, 2025

Copy link
Copy Markdown
Member Author

Yes this would be good. I don't actually have handling for stuff like println specifically (so it is not prefixed with _) because I thought the v compiler would treat is as a keyword but you can actually do this which surprised me:

fn main() {
  println := 'a'
  print(println)
}

The methods that I currently handle are methods on a type such as string_str() or string__eq()as these specifically cause invalid c to be generated but we could expand it to simply all builtin methods, giving them a consistent prefix.

@JalonSolov

JalonSolov commented Sep 9, 2025

Copy link
Copy Markdown
Collaborator

Allowing keywords to be used as variable names is a relatively recent change in V. Not everyone agrees with it, but enough wanted it for it to be added.

@spytheman

spytheman commented Sep 9, 2025

Copy link
Copy Markdown
Contributor

If we are going for prefixing builtin APIs, I do prefer builtin__ not just _, for consistency with the normal V modules.

@spytheman

Copy link
Copy Markdown
Contributor

println is not a keyword, it is a function implemented in vlib/builtin/builtin.c.v:327:pub fn println(s string) { for the C backend.

@spytheman

spytheman commented Sep 9, 2025

Copy link
Copy Markdown
Contributor

The failing CI job about ui is not easily avoidable directly, since it has webview/webview_darwin.m, containing g_vui_webview_js_val = string_clone(tos2([message.body UTF8String])); .

We can however add a separate API, something like:

@[export: 'builtin__ctovstring']
pub fn ctovstring_impl(s &u8) string {
    return tos2(s).clone()
}

as 1 commit on master, then change ui to use the explicitly exported builtin__ctovstring name, instead of relying on the hardcoded string_clone and tos2, and then continue on this draft, just rebasing/merging it over the master branch.

I'll take care of it asap.

edit: done in 69e80ba .
The PR here can be rebased to pick up the change.

@dy-tea

dy-tea commented Sep 9, 2025

Copy link
Copy Markdown
Member Author

Did a quick prefix change from _ to builtin__ and a rebase. I made a mostly comprehensive list of what I'm missing below, some of these might need an @export or some change in a code path I missed.

Missing stuff so I don't forget later:

  • option / result methods such as _option_ok
  • fast_string_eq
  • cstring_to_vstring
  • print and flush methods
  • map and array init methods
  • map_eq_*, map_clone_* and map_free_* methods
  • tos methods
  • abs methods
  • misc methods copy, arguments, isnil, vstrlen, vstrlen_char, vmemcpy, vmemmove, vmemcmp, vmemset, error_with_code, ptr_str, str_intpr (there may be more)
  • impl methods?

@dy-tea

dy-tea commented Sep 9, 2025

Copy link
Copy Markdown
Member Author

Huh that's weird, it's failing on clang and musl specifically?

@JalonSolov

Copy link
Copy Markdown
Collaborator

musl is just... weird, in general, compared to libc.

@dy-tea dy-tea force-pushed the master branch 3 times, most recently from b1c6283 to a359822 Compare September 10, 2025 00:17
@dy-tea

dy-tea commented Sep 10, 2025

Copy link
Copy Markdown
Member Author

Seems to handle everything now? Will go to sleep now and check if the CI worked tomorrow.

@spytheman spytheman marked this pull request as ready for review September 10, 2025 06:48
@spytheman

Copy link
Copy Markdown
Contributor

(rebased over current master (which solved the unrelated CI failure))

@medvednikov

Copy link
Copy Markdown
Member

If we are going for prefixing builtin APIs, I do prefer builtin__ not just _, for consistency with the normal V modules.

I agree

@medvednikov

Copy link
Copy Markdown
Member

Although it will increase the size of generated C code significantly

@spytheman

Copy link
Copy Markdown
Contributor

Although it will increase the size of generated C code significantly

#0 11:54:22 ^ master ~/v>gh pr checkout 25264
From github.com:vlang/v
 * [new ref]               refs/pull/25264/head -> dy-tea/master
Switched to branch 'dy-tea/master'
#0 11:54:30 ^ dy-tea/master ~/v>./v self
V self compiling ...
V built successfully as executable "v".
#0 11:54:35 ^ dy-tea/master ~/v>v -o hw.c examples/hello_world.v
#0 11:54:43 ^ dy-tea/master ~/v>git co master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
#0 11:54:52 ^ master ~/v>./v self
V self compiling ...
V built successfully as executable "v".
#0 11:54:56 ^ master ~/v>v -o old_hw.c examples/hello_world.v
#0 11:55:02 ^ master ~/v>wc old_hw.c hw.c
 1196  3296 28363 old_hw.c
 1196  3296 29497 hw.c
 2392  6592 57860 total
#0 11:55:08 ^ master ~/v>bc
29497 - 28363
1134
#0 11:55:21 ^ master ~/v>
#0 11:55:57 ^ master ~/v>./v -o old_v.c cmd/v
#0 11:56:08 ^ master ~/v>git switch -
Switched to branch 'dy-tea/master'
#0 11:56:10 ^ dy-tea/master ~/v>./v self
V self compiling ...
V built successfully as executable "v".
#0 11:56:17 ^ dy-tea/master ~/v>./v -o new_v.c cmd/v
#0 11:56:24 ^ dy-tea/master ~/v>wc old_v.c new_v.c
  123536   576758  6468517 old_v.c
  123640   577557  6663384 new_v.c
  247176  1154315 13131901 total
#0 11:56:30 ^ dy-tea/master ~/v>bc
6663384 - 6468517
194867

The overhead is 1134 bytes for a small program like examples/hello_world.v (~3.8%).
The overhead for v itself is 194867 bytes (~3%), as expected, since most of the compiler code calls other compiler code, not directly builtin APIs. Other larger programs will be similar.

The compiler overhead is also a bit bigger than that for other larger programs, since it also includes the new compiler code, not just the increase from the longer method names.

i.e. I expect the overhead for most code to be between 2.5% and 3.8% in terms for generated C code bytesize.

@spytheman

Copy link
Copy Markdown
Contributor

I could not measure a significant performance drop, by running v run .github/workflows/compare_pr_to_master.v .
I suspect that the elimination of the edge cases, pretty much balances out the new checks/logic.

@spytheman

Copy link
Copy Markdown
Contributor

Running v run .github/workflows/compare_pr_to_master.v -prod, showed
that it is even sometimes faster,
compared to the current master:

#0 12:23:44 ^ dy-tea/master ~/v>v run .github/workflows/compare_pr_to_master.v -prod
==================================================================================================
Current git branch: dy-tea/master, commit: f2951fd
    Compiling new V executables from PR branch: dy-tea/master, commit: f2951fd ...
CPU: 2.78s      Real: 3.02s     Elapsed: 0:03.02        RAM: 429452KB   ./v -o vnew1 cmd/v
CPU: 2.77s      Real: 3.01s     Elapsed: 0:03.01        RAM: 429448KB   ./vnew1 -o vnew2 cmd/v
CPU: 2.76s      Real: 3.00s     Elapsed: 0:03.00        RAM: 429456KB   ./vnew2 -no-parallel -o vnew cmd/v
CPU: 0.18s      Real: 0.19s     Elapsed: 0:00.19        RAM: 47592KB    ./vnew -no-parallel -o nhw_current.c examples/hello_world.v
CPU: 0.18s      Real: 0.20s     Elapsed: 0:00.20        RAM: 47888KB    ./vnew -no-parallel -o nhw_current_gcc.c -cc gcc examples/hello_world.v
CPU: 2.35s      Real: 2.59s     Elapsed: 0:02.59        RAM: 429476KB   ./vnew -no-parallel -o nv_current.c cmd/v
CPU: 105.65s    Real: 108.74s   Elapsed: 1:48.74        RAM: 430760KB   ./vnew -no-parallel -prod -o vnew_prod cmd/v
>Size of        nhw_current.c:      29497
>Size of    nhw_current_gcc.c:      44506
>Size of         nv_current.c:    6663384
>Size of                 vnew:   10131663
>Size of            vnew_prod:    4233984
Switched to branch 'v_repo_master'
Your branch is up to date with 'V_REPO/master'.
==================================================================================================
    Compiling old V executables from branch: v_repo_master, commit: f073169 ...
CPU: 2.74s      Real: 3.00s     Elapsed: 0:03.00        RAM: 429096KB   ./v -o vold1 cmd/v
CPU: 2.78s      Real: 3.00s     Elapsed: 0:03.00        RAM: 428256KB   ./vold1 -o vold2 cmd/v
CPU: 2.76s      Real: 3.01s     Elapsed: 0:03.01        RAM: 428304KB   ./vold2 -no-parallel -o vold cmd/v
CPU: 0.17s      Real: 0.19s     Elapsed: 0:00.19        RAM: 47584KB    ./vold -no-parallel -o ohw_master.c examples/hello_world.v
CPU: 0.18s      Real: 0.20s     Elapsed: 0:00.20        RAM: 47860KB    ./vold -no-parallel -o ohw_master_gcc.c -cc gcc examples/hello_world.v
CPU: 2.33s      Real: 2.57s     Elapsed: 0:02.57        RAM: 428256KB   ./vold -no-parallel -o ov_master.c cmd/v
CPU: 105.61s    Real: 108.58s   Elapsed: 1:48.58        RAM: 429340KB   ./vold -no-parallel -prod -o vold_prod cmd/v
>Size of            vold_prod:    4211912
>Size of         ohw_master.c:      28363
>Size of     ohw_master_gcc.c:      41988
>Size of          ov_master.c:    6468517
>Size of                 vold:   10100902
>Size of            vold_prod:    4211912
==================================================================================================
File sizes so far ...
>>>>>> size("    nhw_current.c") - size("     ohw_master.c") =      29497 -      28363 =       1134
>>>>>> size("nhw_current_gcc.c") - size(" ohw_master_gcc.c") =      44506 -      41988 =       2518
>>>>>> size("     nv_current.c") - size("      ov_master.c") =    6663384 -    6468517 =     194867
>>>>>> size("             vnew") - size("             vold") =   10131663 -   10100902 =      30761
Switched to branch 'dy-tea/master'
==================================================================================================
    Measuring at PR branch: dy-tea/master, commit: f2951fd ...
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 1086.787 ms                                                              
    1     -0.3%   1.00x faster   44.6ms ± σ:    0.1ms,   44.4ms…  44.7ms `./vnew_prod -check-syntax           examples/hello_world.v`
 >  2           base             44.7ms ± σ:    0.1ms,   44.7ms…  44.8ms `./vold_prod -check-syntax           examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 1081.462 ms                                                              
    1     -0.6%   1.01x faster   44.4ms ± σ:    0.1ms,   44.2ms…  44.4ms `./vnew_prod -check-syntax           examples/hello_world.v`
 >  2           base             44.6ms ± σ:    0.0ms,   44.6ms…  44.6ms `./vold_prod -check-syntax           examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 1081.198 ms                                                              
    1     -0.7%   1.01x faster   44.3ms ± σ:    0.1ms,   44.2ms…  44.4ms `./vnew_prod -check-syntax           examples/hello_world.v`
 >  2           base             44.6ms ± σ:    0.0ms,   44.6ms…  44.7ms `./vold_prod -check-syntax           examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 1580.933 ms                                                              
    1     -0.7%   1.01x faster   65.2ms ± σ:    0.2ms,   64.9ms…  65.3ms `./vnew_prod -check                  examples/hello_world.v`
 >  2           base             65.6ms ± σ:    0.2ms,   65.4ms…  65.9ms `./vold_prod -check                  examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 1573.948 ms                                                              
 >  1           base             65.2ms ± σ:    0.1ms,   65.1ms…  65.2ms `./vold_prod -check                  examples/hello_world.v`
    2     +0.1%   1.00x ~same~   65.2ms ± σ:    0.1ms,   65.1ms…  65.3ms `./vnew_prod -check                  examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 1574.267 ms                                                              
    1     -0.1%   1.00x ~same~   65.2ms ± σ:    0.0ms,   65.1ms…  65.2ms `./vnew_prod -check                  examples/hello_world.v`
 >  2           base             65.2ms ± σ:    0.0ms,   65.1ms…  65.2ms `./vold_prod -check                  examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 1823.214 ms                                                              
 >  1           base             75.4ms ± σ:    0.1ms,   75.2ms…  75.5ms `./vold_prod -no-parallel -o ohw.c   examples/hello_world.v`
    2     +0.1%   1.00x ~same~   75.5ms ± σ:    0.0ms,   75.4ms…  75.5ms `./vnew_prod -no-parallel -o nhw.c   examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 1825.084 ms                                                              
    1     -0.3%   1.00x faster   75.4ms ± σ:    0.1ms,   75.3ms…  75.5ms `./vnew_prod -no-parallel -o nhw.c   examples/hello_world.v`
 >  2           base             75.6ms ± σ:    0.1ms,   75.6ms…  75.7ms `./vold_prod -no-parallel -o ohw.c   examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 1840.917 ms                                                              
    1     -1.5%   1.02x faster   75.4ms ± σ:    0.1ms,   75.3ms…  75.5ms `./vnew_prod -no-parallel -o nhw.c   examples/hello_world.v`
 >  2           base             76.6ms ± σ:    0.1ms,   76.4ms…  76.8ms `./vold_prod -no-parallel -o ohw.c   examples/hello_world.v`
>>>>>> size("            nhw.c") - size("            ohw.c") =      29497 -      28363 =       1134
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 2102.016 ms                                                              
    1     -0.1%   1.00x ~same~   86.9ms ± σ:    0.0ms,   86.8ms…  86.9ms `./vnew_prod -no-parallel -o nhw.exe examples/hello_world.v`
 >  2           base             86.9ms ± σ:    0.1ms,   86.8ms…  87.1ms `./vold_prod -no-parallel -o ohw.exe examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 2110.651 ms                                                              
    1     -0.6%   1.01x faster   87.0ms ± σ:    0.1ms,   86.9ms…  87.1ms `./vnew_prod -no-parallel -o nhw.exe examples/hello_world.v`
 >  2           base             87.6ms ± σ:    0.5ms,   86.9ms…  88.0ms `./vold_prod -no-parallel -o ohw.exe examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 2122.613 ms                                                              
    1     -0.4%   1.00x faster   87.4ms ± σ:    0.2ms,   87.1ms…  87.6ms `./vnew_prod -no-parallel -o nhw.exe examples/hello_world.v`
 >  2           base             87.8ms ± σ:    0.1ms,   87.6ms…  87.9ms `./vold_prod -no-parallel -o ohw.exe examples/hello_world.v`
>>>>>> size("          nhw.exe") - size("          ohw.exe") =     242429 -     241853 =        576
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 8622.615 ms                                                              
    1     -0.6%   1.01x faster  352.9ms ± σ:    0.3ms,  352.5ms… 353.3ms `./vnew_prod -check-syntax           cmd/v`
 >  2           base            354.9ms ± σ:    0.7ms,  353.9ms… 355.4ms `./vold_prod -check-syntax           cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 8597.809 ms                                                              
    1     -0.9%   1.01x faster  352.7ms ± σ:    0.4ms,  352.2ms… 353.1ms `./vnew_prod -check-syntax           cmd/v`
 >  2           base            356.0ms ± σ:    0.3ms,  355.6ms… 356.3ms `./vold_prod -check-syntax           cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 8533.875 ms                                                              
    1     -0.6%   1.01x faster  352.9ms ± σ:    0.3ms,  352.4ms… 353.3ms `./vnew_prod -check-syntax           cmd/v`
 >  2           base            355.0ms ± σ:    0.8ms,  353.9ms… 355.8ms `./vold_prod -check-syntax           cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 14336.985 ms
    1     -0.4%   1.00x faster  593.9ms ± σ:    1.1ms,  592.8ms… 595.4ms `./vnew_prod -check                  cmd/v`
 >  2           base            596.0ms ± σ:    0.8ms,  595.2ms… 597.1ms `./vold_prod -check                  cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 14342.719 ms
    1     -0.1%   1.00x ~same~  594.6ms ± σ:    0.8ms,  593.6ms… 595.4ms `./vnew_prod -check                  cmd/v`
 >  2           base            595.5ms ± σ:    0.3ms,  595.1ms… 595.9ms `./vold_prod -check                  cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 14343.698 ms
    1     -0.4%   1.00x faster  593.8ms ± σ:    0.3ms,  593.4ms… 594.1ms `./vnew_prod -check                  cmd/v`
 >  2           base            596.4ms ± σ:    0.6ms,  596.0ms… 597.2ms `./vold_prod -check                  cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 24537.334 ms
    1     -0.1%   1.00x ~same~ 1019.5ms ± σ:    0.8ms, 1018.4ms…1020.2ms `./vnew_prod -no-parallel -o nv.c    cmd/v`
 >  2           base           1020.4ms ± σ:    2.0ms, 1017.6ms…1022.1ms `./vold_prod -no-parallel -o ov.c    cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 24529.957 ms
 >  1           base           1019.4ms ± σ:    0.9ms, 1018.5ms…1020.6ms `./vold_prod -no-parallel -o ov.c    cmd/v`
    2     +0.2%   1.00x slower 1021.1ms ± σ:    0.2ms, 1020.8ms…1021.2ms `./vnew_prod -no-parallel -o nv.c    cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 24532.430 ms
    1     -0.1%   1.00x ~same~ 1019.7ms ± σ:    0.4ms, 1019.4ms…1020.2ms `./vnew_prod -no-parallel -o nv.c    cmd/v`
 >  2           base           1020.6ms ± σ:    0.9ms, 1019.5ms…1021.6ms `./vold_prod -no-parallel -o ov.c    cmd/v`
>>>>>> size("             nv.c") - size("             ov.c") =    6663384 -    6480835 =     182549
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 34716.431 ms
 >  1           base           1443.5ms ± σ:    1.7ms, 1441.3ms…1445.5ms `./vold_prod -no-parallel -o ov.exe  cmd/v`
    2     +0.1%   1.00x ~same~ 1444.3ms ± σ:    0.8ms, 1443.1ms…1445.0ms `./vnew_prod -no-parallel -o nv.exe  cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 34698.929 ms
 >  1           base           1442.6ms ± σ:    0.4ms, 1442.1ms…1443.1ms `./vold_prod -no-parallel -o ov.exe  cmd/v`
    2     +0.1%   1.00x ~same~ 1443.8ms ± σ:    0.6ms, 1443.1ms…1444.5ms `./vnew_prod -no-parallel -o nv.exe  cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 34731.970 ms
    1     -0.2%   1.00x faster 1443.1ms ± σ:    0.4ms, 1442.5ms…1443.4ms `./vnew_prod -no-parallel -o nv.exe  cmd/v`
 >  2           base           1446.1ms ± σ:    0.6ms, 1445.4ms…1446.7ms `./vold_prod -no-parallel -o ov.exe  cmd/v`
>>>>>> size("           nv.exe") - size("           ov.exe") =   10131681 -   10125549 =       6132
Done. Total time: 508.560245219 s.
==================================================================================================
Final summary for file diff sizes on their own branches:
>>>>>> size("    nhw_current.c") - size("     ohw_master.c") =      29497 -      28363 =       1134
>>>>>> size("nhw_current_gcc.c") - size(" ohw_master_gcc.c") =      44506 -      41988 =       2518
>>>>>> size("     nv_current.c") - size("      ov_master.c") =    6663384 -    6468517 =     194867
>>>>>> size("             vnew") - size("             vold") =   10131663 -   10100902 =      30761
>>>>>> size("        vnew_prod") - size("        vold_prod") =    4233984 -    4211912 =      22072
==================================================================================================
Final summary for file diff sizes for generated files on the *current* branch:
>>>>>> size("            nhw.c") - size("            ohw.c") =      29497 -      28363 =       1134
>>>>>> size("             nv.c") - size("             ov.c") =    6663384 -    6480835 =     182549
>>>>>> size("          nhw.exe") - size("          ohw.exe") =     242429 -     241853 =        576
>>>>>> size("           nv.exe") - size("           ov.exe") =   10131681 -   10125549 =       6132
#0 12:32:18 ^ dy-tea/master ~/v>

@dy-tea dy-tea changed the title cgen: prefix builtin methods with _ cgen: prefix builtin methods with builtin__ Sep 10, 2025
Comment thread vlib/v/gen/c/assign.v

@spytheman spytheman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work!
Thank you very much @dy-tea .

This PR will enable a lot of future cleanups and removing of edge cases.

@dy-tea

dy-tea commented Sep 10, 2025

Copy link
Copy Markdown
Member Author

Oh that's good that performance doesn't seem to be impacted. The only thing missing now is some check to prevent people from naming variables with the builtin__ prefix or a variable renaming system.

For example:

fn main() {
	builtin__string__eq := 'a' == 'b'
	println(builtin__string__eq)
}

Produces:

void main__main(void) {
	bool builtin__string__eq = builtin__string__eq(_S("a"), _S("b"));
	builtin__println(builtin__string__eq ? _S("true") : _S("false"));
}

Which will fail c compilation.

Might want a seperate pr for this.

Now that I'm thinking about it, this would apply to all modules.

@spytheman

spytheman commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

The only thing missing now is some check to prevent people from naming variables with the builtin__ prefix or a variable renaming system.

The new collision is much less likely to happen for arbitrary code, compared to before, and preventing it is very easy to arrange, by banning the builtin__ prefix for local identifiers in the parser, and yes, it should be done in another separate PR.

@spytheman

Copy link
Copy Markdown
Contributor

this would apply to all modules

collisions with them are already unlikely too

@dy-tea

dy-tea commented Sep 10, 2025

Copy link
Copy Markdown
Member Author

Yeah something like:

import time

fn main() {
	time__now := time.now()
}

Will also fail to compile. Will think about a way to approach this.

@JalonSolov

JalonSolov commented Sep 10, 2025

Copy link
Copy Markdown
Collaborator

Reasonably simple... if prefix before __ matches any import, reject it. So having

fn main() {
	time__now := 5
}

would still work fine, since there is no import time in the code. It's only a problem if the prefix matches an import (and builtin is always an import, just never explicitly listed).

@spytheman spytheman merged commit e317c63 into vlang:master Sep 10, 2025
83 checks passed
@smalltalkman

Copy link
Copy Markdown
Contributor

This is truly beautiful work.
I attempted to address this issue a year ago, but it stalled after I couldn't get the commit IDs in the v and vc repositories to strictly match.
I have the impression there's a way to reduce the hard-coded builtin__ prefix, and I should be able to find a patch from a year ago if needed.

@JalonSolov

Copy link
Copy Markdown
Collaborator

I think having the prefix match the module name is a good thing - you don't have to guess where it came from, it's right there in the name.

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.

5 participants