Commit Graph

566 Commits

Author SHA1 Message Date
Andreas Rumpf
cf388722db IC: massive cleanup, NIF26 support, docs about its inner workings (#25427) 2026-01-16 12:19:17 +01:00
Andreas Rumpf
234c73c58a refactoring for IC (#25395) 2025-12-29 13:52:22 +01:00
Andreas Rumpf
02893e2f4c IC: code generation progress (#25379) 2025-12-29 00:20:33 +01:00
ringabout
a41bbf6901 fixes #25387; embedsrc breaks with Line Continuation (#25388)
fixes #25387


https://stackoverflow.com/questions/30286253/how-to-escape-backslash-in-comment

- adding a whitespace or `\t` after `\` breaks the `goto` block
- `\* *\` doesn't support nesting, causing problems for using it in the
Nim comments
2025-12-25 21:02:54 +01:00
Andreas Rumpf
9bb57a64ba IC: keep package information (#25350) 2025-12-18 09:34:39 +01:00
Andreas Rumpf
cbb2fe0a63 IC: progress (#25344)
Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
2025-12-11 18:22:38 +01:00
Andreas Rumpf
a773178e2b IC: progress (#25314) 2025-12-01 22:59:12 +01:00
Andreas Rumpf
0486a2df51 IC progress (#25283)
bugfix: produce the required nimcache subdir
2025-11-25 12:49:23 +01:00
ringabout
9becd1453d fixes #25284; .global initialization inside method hoisted to preInitProc (#25285)
fixes #25284

```nim
proc m2()  =
  let v {.global, used.}: string = f2(f2("123"))
```

transform lifted `.global`statements in the top level scope
2025-11-14 16:20:42 +01:00
Andreas Rumpf
f608e109c9 massive refactoring for IC (#25282)
TODO:

- [ ] test writing of .nif files
- [x] implement loading of fields in PType/PSym that might not have been
loaded
- [ ] implement interface logic
- [ ] implement pragma "replays"
- [ ] implement special logic for `converter`
- [ ] implement special logic for `method`
- [ ] test the logic holds up for `export`
- [ ] implement logic to free the memory of PSym/PType if memory
pressure is high
- [ ] implement logic to close memory mapped files if too many are open.

---------

Co-authored-by: demotomohiro <gpuppur@gmail.com>
Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
Co-authored-by: Jacek Sieka <arnetheduck@gmail.com>
2025-11-13 21:31:24 +01:00
ringabout
7c65d9e747 fixes #25204; Uninitialized variable usage in resize__system_u... in @psystem.nim.c in ORC (#25209)
fixes #25204

```nim
  of mUnaryMinusI..mAbsI: unaryArithOverflow(p, e, d, op)
  of mAddI..mPred: binaryArithOverflow(p, e, d, op)
```
Arithmetic operations may raise exceptions. So we cannot entrust the
optimizer to skip `result` initialization in this situation, as
complained righteously by `gcc` and `clang`: `warning: ‘result’ may be
used uninitialized [-Wmaybe-uninitialize]`.

With this PR, `clang -c -Wuninitialized -O1 @psystem.nim.c` no longer
gives warnings
2025-10-08 19:10:09 +02:00
ringabout
3ce38f2959 fixes #24997; {.global.} variable in recursive function (#25016)
fixes #24997

handles functions in recursive order
2025-06-27 10:17:16 +02:00
ringabout
638a8bf84d fixes #24974; SIGSEGV when raising Defect/doAssert (#24985)
fixes #24974

requires `result` initializations when encountering unreachable code
(e.g. `quit`)
2025-06-10 14:12:12 +02:00
ringabout
ffb993d5bd fixes #24981; the length of the seq changed of procGloals (#24984)
fxies #24981

`m.g.graph.procGlobals` could change because the right side of `.global`
assignment (e.g. `let a {.global.} = g(T)`) may trigger injections for
unhandled procs
2025-06-09 20:53:40 +02:00
ringabout
3c0446b082 fixes #24940; fixes #17552; lifts {.global.} in injectDestructorCalls (#24962)
fixes #24940
fixes #17552

Collects `{.global.}` (i.e. if it was changed into a hook call: `=copy`,
`=sink`) in `injectDestructorCalls` and generates it in the init
sections in cgen
2025-05-23 16:15:55 +02:00
ringabout
e2d4791229 fixes move for getPotentialWrites (#24753)
`move` would modify parameters as well
2025-03-11 09:57:48 +01:00
ringabout
3bee04d9f3 prefix NimDestroyGlobals with nimMainPrefix (#24493)
ref https://github.com/nim-lang/Nim/issues/24471

---------

Co-authored-by: metagn <metagngn@gmail.com>
2024-12-03 13:05:14 +08:00
metagn
712f5be7eb cbuilder: use constants for type names, some cleanups (#24438)
As described in #24432
2024-11-18 17:34:37 +01:00
metagn
f053767132 make some trivial sizeof calls in codegen use types/literals (#24445)
Partial alternative to #24433 that should be harmless and is the minimal
amount of changes that #24438 depends on.
2024-11-17 20:37:34 +01:00
metagn
726195d784 cbuilder: second half of cgen (#24432)
Follows up #24423, needed more refactoring than I expected, sorry for
ugly diff.

With this pretty much all of the raw C code generating parts of the
codegen are abstracted into the cbuilder API (to my knowledge at least).
The current design of NIFC does not implement everything the codegen
generates, such things have mostly not been adapted, they are the
following along with how I'm guessing they could be implemented:

* C++ specific codegen: Maybe a dialect of NIFC for generating C++?
* `codegenDecl` pragma: Could be passed as a pragma to NIFC
* C macros, currently only used for line info IIRC i.e. `nimln_(123)`:
Just inline them when generating NIFC
* Other C defines & `#line`: Maybe as NIFC directives or line infos?
* There is also [this
`#ifndef`](21420d8b09/compiler/cgen.nim (L2249))
when generating headers but NIFC shouldn't need it
* `alignof`/`offsetof`: Is in `cbuilder` but not implemented in NIFC,
should be easy

For now we can disable C++ and the `codegenDecl` pragma when generating
NIFC but since cbuilder is mostly designed to generate NIFC as a flag
when booting the compiler, this hinders the ability to run the CI
against NIFC. Maybe we could also make cbuilder able to generate both C
and NIFC at runtime, this would be a large refactor but wouldn't be too
difficult.

Other missing abstractions before being able to generate NIFC are:

* Primitive types and symbols i.e. `int`, `void*`, `NI`, `NIM_NULL` are
currently still constant string literals, `NU8`, `NU16` etc are also
sometimes generated like `"NU" & $bits`.
* NIFC identifiers, i.e. adding `.c` to imported symbols and properly
mangling generated ones. Not sure how difficult this is going to be.
2024-11-14 16:28:13 +01:00
metagn
9d61f2cdd1 cbuilder: upper half of cgen, variable decls (#24423)
The lower half of cgen contains the main proc and HCR init code which
cause a large diff, so they are excluded from this PR. In general things
like generated defines, line directives, the stacktrace macros (`nimfr_`
etc) are also not done, since there are not exact equivalents for these
in NIFC (NIFC does generate line directives but based on the NIF line
info mechanism).
2024-11-10 19:58:48 +01:00
metagn
b3c1fbaf13 adapt blocks in ccgstmts to cbuilder (#24416)
This loses indents in codegen for now, another PR includes changes to
add indents to `Builder` itself rather than tracking `TBlock`: #24418
2024-11-08 14:28:52 +01:00
metagn
0bc3f5c74c use cbuilder for most of ccgcalls (#24407)
The only missing parts are Objective C named param calls and
`genThisArg` for C++ interop.
2024-11-05 09:31:35 +01:00
metagn
f5d80ede80 cbuilder: make Builder an object (#24401)
Doing this early is useful so we can move the indentation logic into
`Builder` itself rather than mix it with the block logic in `ccgstmts`
(the `if` statements in #24381 have not been indented properly either).
However it also means `Builder` is now used for code that still
generates raw C code, so the diff won't be as clean when these get
updated.
2024-11-03 14:59:50 +01:00
ringabout
8b88b5fdd8 fixes #24395; remove ndi (#24396)
fixes  #24395
2024-11-01 09:48:49 +01:00
metagn
0e3330ee96 use cbuilder for default proc generation (#24390)
C++ member procs are not implemented, and `codegenDecl` in general is
also not adapted, although it had to be included in the generation of
proc params for simplicity. Guessing `codegenDecl` and C++ stuff are
supposed to map to pragmas on NIFC, or are just not supported.
2024-10-31 23:02:14 +01:00
metagn
658c9da33e cbuilder: ccgexprs sweep part 1, basic if stmts (#24381)
Most of what ccgexprs uses is now ported to cbuilder, so this PR makes
around ~25% of ccgexprs use it, along with adding `if` stmts (no
`while`/`switch` and `for` which is only used as `for (tmp = a; tmp < b;
tmp++)`). The `if` builder does not add indents for blocks since we
can't make `Builder` an object yet rather than an alias to `string`,
this will likely be one of the last refactors.

Somewhat unrelated but `ccgtypes` is not ready yet because proc
signatures are not implemented.
2024-10-31 07:50:05 +01:00
metagn
820e2bee9c cbuilder: add assignments, fields, subscripts, deref (#24351)
This PR is somewhat large, worst case it can be split into one with just
assignments and one with just fields/derefs etc.

Assignments with calls as values have not been touched so they can be
done when calls are implemented. Similarly codegen with complex logic
i.e. `genEnumInfo`, `genTypeInfoV2`, `unaryExpr` is not completely
ported yet so they can be done in standalone PRs.
2024-10-25 14:16:39 +02:00
ringabout
68b2e9eb6a make PNode.typ a private field (#24326) 2024-10-18 16:52:07 +02:00
metagn
a2ee709199 use cbuilder for string literals, split into modules, document (#24237)
`cbuilder` is now split into `cbuilderbase`, `cbuilderexprs`,
`cbuilderdecls`, with all the struct builder code up to this point going
in `cbuilderdecls`.

Variable builders are added, with local, global and constant variables
implemented, but not threadvars.

A builder for struct (braced) initializers is added. The field names
have to be passed to build each field (so they can be used in `oconstr`
in nifc), but they're not used in the output code if a flag
`orderCompliant` is enabled, which means the initializer list is
generated in order of the built fields. The version which uses the names
on C is not implemented (C99 designated initializers), so this flag has
to be enabled for now.

The struct builders now generate the struct as an inline expression if a
name isn't provided rather than a statement. This means we can now use
`addSimpleStruct` etc for the type of fields, but we can't replace
`addFieldWithStructType` because of `#pragma pack(pop)`.

Doc comments are added to every usable proc but may still not be
sufficient.
2024-10-06 13:51:41 +02:00
metagn
2cdc0e913f use cbuilder for tuple/object generation (#24145)
based on #24127

Needs some tweaks to replace the other `struct` type generations, e.g.
seqs, maybe by exposing `BaseTypeKind` as a parameter. C++ and
codegenDecl etc seem like they are going to need attention.

Also `Builder` should really be `distinct string` that one has to call
`extract` on, but for this to be optimal in the current codegen, we
would need something like:

```nim
template buildInto(s: var string, builderName: untyped, body) =
  template `builderName`: untyped = Builder(s)
  body

buildInto(result, builder):
  builder.add ...
```

but this could be a separate PR since it might not work with the
compiler. The possibly-not-optimal alternative is to do:

```nim
template build(builderName: untyped, body): string =
  var `builderName` = Builder("")
  body
  extract(`builderName`)

result = build(builder):
  builder.add ...
```

where the compiler maybe copies the built string but shouldn't.

---------

Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
2024-09-27 11:12:39 +02:00
ringabout
21a161a535 remove nimfrs and varslot (#24126)
was introduced for debugger
b63f322a46 (diff-abd3a10386cf1ae32bfd3ffae82335a1938cc6c6d92be0ee492fcb44b9f2b552)


b63f322a46/lib/system/debugger.nim
2024-09-17 14:01:21 +02:00
ringabout
9ff15da426 fixes #23897; Useless empty C files with arc/orc (#24064)
fixes #23897

follow up https://github.com/nim-lang/Nim/pull/21288
follow up https://github.com/nim-lang/Nim/pull/22472

Since #22472 triggers `nimTestErrorFlag` in every module that isn't
empty, this PR removes unnecessary logic
2024-09-05 20:44:00 +02:00
ringabout
4bf323d6c4 fixes push warnings for sempass2 (#23603)
ref https://forum.nim-lang.org/t/11590
2024-09-03 09:19:52 +02:00
Juan M Gómez
2e4d344b43 Fixes #23962 resetLocdoenst produce any cgen code in importcpp types (#23964) 2024-08-18 13:21:17 +02:00
ringabout
02871c74de minor improvement on cgen (#23887) 2024-07-24 20:17:54 +02:00
ringabout
3a103669d1 fixes #23858; 2.2.0 rc1 regression with cdecl functions (#23859)
fixes #23858

We should not assign fields to fields for returns of function calls
because calls might have side effects.
2024-07-18 20:53:07 +02:00
Andreas Rumpf
6d7ab08dee refactor: The popular 'r' field is now named 'snippet' (#23829) 2024-07-12 15:23:09 +02:00
ringabout
56ed4e0bb9 fixes #23759; rework move for refc (#23764)
fixes #23759
2024-06-29 10:43:41 +02:00
ringabout
8f5ae28fab fixes #22672; Destructor not called for result when exception is thrown (#23267)
fixes #22672
2024-06-06 11:51:41 +02:00
Juan M Gómez
cb0ebecb20 #Fixes #23657 C++ compilation fails with: 'T1_' was not declared in t… (#23666)
…his scope
2024-06-02 15:15:03 +02:00
ringabout
c615828ccb fixes #22852; fixes #23435; fixes #23645; SIGSEGV when slicing string or seq[T] with index out of range (#23279)
follow up https://github.com/nim-lang/Nim/pull/23013

fixes #22852
fixes #23435
fixes #23645

reports rangeDefect correctly

```nim
/workspaces/Nim/test9.nim(1) test9
/workspaces/Nim/lib/system/indices.nim(116) []
/workspaces/Nim/lib/system/fatal.nim(53) sysFatal
Error: unhandled exception: value out of range: -2 notin 0 .. 9223372036854775807 [RangeDefect]
```
2024-05-27 14:13:18 +02:00
Nikolay Nikolov
7e3bac9235 * fix for the debug line info code generation (#23488)
Previously, in certain cases, the compiler would generate debug info for
the correct line number, but for the wrong .nim source file.
2024-04-22 13:55:14 +02:00
heterodoxic
318b2cfc5e allow having {.noinit.} on a complex type avoid memsets to 0 for its … (#23388)
…instantiations (C/C++ backend)

AFAIK, #22802 expanded `noinit`'s utility by allowing the pragma to be
attached to types (thanks @jmgomez !).
I suggest broadening the scope a bit further: try to avoid `nimZeroMem`s
on a type level beyond imported C/C++ types[^1], saving us from
annotating the type instantiations with `noinit`.

If this change is deemed acceptable, I will also adjust the docs, of
course.

Adding tests for this change seems a bit problematic, as the effect of
this type annotation will be to work with uninitialized memory, which
*might* match 0 patterns.

[^1]: "complex value types" as already defined here:
94c5996877/compiler/cgen.nim (L470-L471)
2024-04-18 21:58:01 +02:00
ringabout
fc48c7e615 apply the new mangle algorithm to JS backend for parameters and procs (#23476)
the function name extension encoded by paths could be useful for
debugging where the function is from

Before:
```js
function newSeq_33556909(len_33556911)
```

After:
```js
function newSeq__system_u2477(len_p0)
```
2024-04-05 08:54:48 +02:00
Juan M Gómez
33902d9dbb [Cpp] Fixes an issue when mixing hooks and calls (#23428) 2024-03-21 08:48:14 +01:00
ringabout
e217bb24a1 fixes #20945; fixes #18262; provides C API NimDestroyGlobals for static/dynlib libraries (#23357)
fixes #20945
fixes #18262

todo
- [ ] perhaps export with lib prefix when the option is enabled
2024-03-04 10:14:25 +01:00
heterodoxic
f4fe3af42a make use of C++11's auto type deduction for temporary variables (#23327)
This is just one of those tiny steps towards the goal of an "optimized"
C and C++ codegen I raised elsewhere before - what does me babbling
"optimized" mainly entail?

(not mutually-exclusive ascertainment proposals following:)

- less and simplified resulting code: easier to pick up/grasp for the
C/C++ compiler for to do its own optimization heuristics, less parsing
effort for us mere humans trying to debug, especially in the case of
interop
- build time reduction: less code emission I/O, runtime string
formatting for output...
- easier access for fresh contributors and better maintainability
- interop improvements
- further runtime optimizations

I am eagerly looking forward to the results of the LLVM-based
undertakings, but I also think we can do a bit better (as outlined
above) with our current C/C++ backends till those come to fruition.

**Long story short**: this PR here focuses on the C++ backend,
augmenting the current codegen method of establishing "temporary"
variables by using C++11's auto type deduction. The reasons for adopting
an "Almost Always Auto" style have been collected [here
](https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/)
for the C++ world. For those hopping between C++'s and Nim's realms,
this change also results in a bit less code and less work for the
codegen part (no redundant `getTypeDesc`s): no need to tell the C++
compiler the type it already knows of (in most cases).
2024-03-03 15:53:23 +01:00
ringabout
7d9721007c fixes regression #22909; don't optimize result init if statements can raise which corrupts the compiler (#23271)
fixes #22909
required by https://github.com/nim-lang/Nim/pull/23267

```nim
proc foo: string =
  assert false
  result = ""
```

In the function `foo`, `assert false` raises an exception, which can
cause `result` to be uninitialized if the default result initialization
is optimized out
2024-02-01 16:51:07 +01:00
ringabout
d44b0b1869 fixes #22597; avoid side effects for call returning openArray types (#23257)
fixes #22597

```nim
proc autoToOpenArray*[T](s: Slice[T]): openArray[T] =
  echo "here twice"
  result = toOpenArray(s.p, s.first, s.last)
```
For functions returning openarray types, `fixupCall` creates a temporary
variable to store the return value: `let tmp = autoToOpenArray()`. But
`genOpenArrayConv` cannot handle openarray assignements with side
effects. It should have stored the right part of the assignment first
instead of calling the right part twice.
2024-01-26 06:06:08 +01:00