While `a.push.apply(a, b)` is better for performance than the previous
`a = a.concat(b)` due to the fact that it doesn't create a new array,
there is a pretty big problem with it: depending on the JS engine, if
the second array is too long, it can [cause a
crash](https://tanaikech.github.io/2020/04/20/limitation-of-array.prototype.push.apply-under-v8-for-google-apps-script/)
due to the function `push` taking too many arguments. This has
unfortunately been what the codegen produces since 1.4.0 (commit
707367e1ca).
So string addition is now moved to a compilerproc that just uses a `for`
loop. From what I can tell this is the most compatible and the fastest.
Only potential problem compared to `concat` etc is with aliasing, i.e.
adding an array to itself, but I'm guessing it's enough that the length
from before the iteration is used, since it can only grow. The test
checks for aliased nim strings but I don't know if there's an extra
protection for them.
Reworked closureiter transformation.
- Convolutedly nested finallies should cause no problems now.
- CurrentException state now follows nim runtime rules (pushes and pops
appropriately), and mimics normal code, which is somewhat buggy, see
#25031
- Previously state optimization (removing empty states or extra jumps)
missed some opportunities, I've reimplemented it to do everything
possible to optimize the states. At this point any extra states or jumps
should be considered a bug.
The resulting codegen (compiled binaries) is also slightly smaller.
**BUT:**
- I had to change C++ reraising logic, see expt.nim. Because with
closure iters `currentException` is not always in sync with C++'s notion
of current exception. From my tests and understanding of C++ runtime
there should not be any problems, but I'm only 99% sure :)
- I've reused `nfNoRewrite` flag in one specific case during the
transformation. This flag is also used in term-rewriting logic. Again,
99% sure, these 2 scenarios will never intersect.
implements https://github.com/nim-lang/RFCs/issues/557
It inserts defect handing into a bare except branch
```nim
try:
raiseAssert "test"
except:
echo "nope"
```
=>
```nim
try:
raiseAssert "test"
except:
# New behaviov, now well-defined: **never** catches the assert, regardless of panic mode
raiseDefect()
echo "nope"
```
In this way, `except` still catches foreign exceptions, but panics on
`Defect`. Probably when Nim has `except {.foreign.}`, we can extend
`raiseDefect` to foreign exceptions as well. That's supposed to be a
small use case anyway.
`--legacy:noPanicOnExcept` is provided for a transition period.
closes https://github.com/nim-lang/RFCs/issues/554
Adds a symmetric difference operation to the language bitset type. This
maps to a simple `xor` operation on the backend and thus is likely
faster than the current alternatives, namely `(a - b) + (b - a)` or `a +
b - a * b`. The compiler VM implementation of bitsets already
implemented this via `symdiffSets` but it was never used.
The standalone binary operation is added to `setutils`, named
`symmetricDifference` in line with [hash
sets](https://nim-lang.org/docs/sets.html#symmetricDifference%2CHashSet%5BA%5D%2CHashSet%5BA%5D).
An operator version `-+-` and an in-place version like `toggle` as
described in the RFC are also added, implemented as trivial sugar.
`reset`, `wasMoved` and `move` doesn't support primitive types, which
generate `null` for these types. It is now produce `x = default(...)` in
the backend. Ideally it should be done by ast2ir in the future
fixes#4695
ref https://github.com/nim-lang/Nim/pull/15818
Since `nkState` is only for the main loop state labels and `nkGotoState`
is used only for dispatching the `:state` (since
https://github.com/nim-lang/Nim/pull/7770), it's feasible to rewrite the
loop body into a single case-based dispatcher, which enables support for
JS, VM backend. `nkState` Node is replaced by a label and Node pair and
`nkGotoState` is only used for intermediary processing. Backends only
need to implement `nkBreakState` and `closureIterSetupExc` to support
closure iterators.
pending https://github.com/nim-lang/Nim/pull/23484
<del> I also observed some performance boost for C backend in the
release mode (not in the danger mode though, I suppose the old
implementation is optimized into computed goto in the danger mode)
</del>
allPathsAsgnResult???
why ?
- We already have an emit that does the same thing
- The name asm itself is a bit confusing, you might think it's an alias
for asm.js or something else.
- The asm keyword is used differently on different compiler targets (it
makes it inexpressive).
- Does anyone (other than some compiler libraries) use asm instead of
emit ? If yes, it's a bit strange to use asm somewhere and emit
somewhere. By making the asm keyword for js target deprecated, there
would be even less use of the asm keyword for js target, reducing the
amount of confusion.
- New users might accidentally use a non-universal approach via the asm
keyword instead of emit, and then when they learn about asm, try to
figure out what the differences are.
see https://forum.nim-lang.org/t/10821
---------
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
```nim
echo newString(8)
```
results in:
```
D:\User\test.js:25
var code_33556944 = c_33556931.toString(16);
^
TypeError: Cannot read properties of undefined (reading 'toString')
at toJSStr (D:\User\test.js:25:50)
at rawEcho (D:\User\test.js:70:16)
at Object.<anonymous> (D:\User\test.js:101:1)
at Module._compile (node:internal/modules/cjs/loader:1095:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1147:10)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
Node.js v17.0.1
Error: execution of an external program failed: '"C:\Program Files\nodejs\node.exe" --unhandled-rejections=strict D:\User\test.js'
```
* Added 'openarray[char]' overloads to 'std/parseutils'
* Removed redundant `start` and `last` params from slice using procs
* Fixed type for parseIdent overload
* fixed one by off with 'substr'
* removed missed start parameters for procedures
* Added 'openarray[char]' overloads to 'std/parseutils'
* Removed redundant `start` and `last` params from slice using procs
* Fixed type for parseIdent overload
* fixed one by off with 'substr'
* removed missed start parameters for procedures
* Fixed VM op to work with new 'opcSlice'
* Corrected captureBetween's logic to work with openarray
* js sys's parsefloat logic now uses openarray
Co-authored-by: Clay Sweetser <Varriount@users.noreply.github.com>
* Assignments, which would accidentally create global
variables, instead throw an error in strict mode
* Assignment to a getter-only property
Co-authored-by: Sven Keller <s.keller@cortona.de>
* fix#10053 FieldError for vm
* fixup
* FieldError now also shows runtime value of discriminant
* fix field error reporting in vm
* also report culprit line info in err msg
* fix errors for newruntime 2
* fix for js
* fixup
* PRTEMP4
* works
* works
* works perfect
* refactor
* std/private/repr_impl
* suppport --gc:arc
* cleanup
* refactor
* simplify
* simplify
* simplify
* fixup
* move out compiler.vmgen.genCustom
* fixup
* fixup
* add tests
* revert compiler/debugutils.nim
* simplify reprDiscriminant
* fixup
* lib/std/private/repr_impl.nim -> lib/system/repr_impl.nim
* try to fix D20210812T165220
* honor --declaredlocs
* control toFileLineCol via --declaredlocs
* compiler/vmhooks: add getVar to allow vmops with var params
* addFloat vmops with var param
* cgen now renders float32 literals in c backend using roundtrip float to string
* many bugfixes for js
fixes#12672, fixes#14153, closes#14123, closes#11331, fixes#11783, fixes#13966, fixes#14087, fixes#14117, closes#12256.
mostly fixes the fact that it was allowed to assign to newly created temp variables. additionally attempts to get rid of null initialized seqs/strings (though they might pop up here and there); this simplifies a lot of things and makes code size smaller. even if null seqs/strings pop up here and there it's still better than all those bugs existing.
* formatting fixes
* CI fixes
* more CI fixes
* Error -> Defect for defects
The distinction between Error and Defect is subjective,
context-dependent and somewhat arbitrary, so when looking at an
exception, it's hard to guess what it is - this happens often when
looking at a `raises` list _without_ opening the corresponding
definition and digging through layers of inheritance.
With the help of a little consistency in naming, it's at least possible
to start disentangling the two error types and the standard lib can set
a good example here.
* fix https://github.com/timotheecour/Nim/issues/133; $(a: float) works in nim js like in other backends
* fix tests
* fix test for windows that prints 1.1e17 differently than other OS
* Make index out of bounds more useful by including the 'bounds'.
* fixes#9880 index out of bounds (remaining cases); revives #10228
* change err msg to: `index 3 not in 0 .. 1`
* Add a test for issue #9389
* Fixes#9389.
* Make object contructors copy objects properly by checking whether the expressions passed to them don't need to be copied.
* Make mArrToSeq implementation actually check if a copy needs to be made.
* Avoid unnecessary copy in mChr impl
* Assume set constructor elements need no copy
* Add a test for issue #9410
* Add a test
* fix passing fat pointers (#9410)
* Enhance tests
* More tests and fixes
* Add more (failing) tests [ci skip]
* Added equality operator for fat pointers, more tests and fixes
* Fix printing uninitialized strings
* Fix mInc, mDec double eval, add more tests
* Tests
* Refactored, fixed multiple evals, revamped the tests, added missing ops
* Fix ups
* Fix#9643 and #9644
* add pointer normalization