Fix fat pointers, object copying, magic double evals on JS (#9411) [backport]

* 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
This commit is contained in:
rec 2018-12-04 12:04:27 +01:00 • committed by Andreas Rumpf
commit e3e5ae287f
6 changed files with 745 additions and 83 deletions

View file

@ -2522,12 +2522,13 @@ proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} =
when not defined(JS):
proc seqToPtr[T](x: seq[T]): pointer {.inline, nosideeffect.} =
result = cast[pointer](x)
else:
proc seqToPtr[T](x: seq[T]): pointer {.asmNoStackFrame, nosideeffect.} =
asm """return `x`"""
if seqToPtr(x) == seqToPtr(y):
return true
if seqToPtr(x) == seqToPtr(y):
return true
else:
var sameObject = false
asm """`sameObject` = `x` === `y`"""
if sameObject: return true
when not defined(nimNoNil):
if x.isNil or y.isNil:

View file

@ -519,8 +519,11 @@ proc nimCopyAux(dest, src: JSRef, n: ptr TNimNode) {.compilerproc.} =
`dest`[`n`.offset] = nimCopy(`dest`[`n`.offset], `src`[`n`.offset], `n`.typ);
"""
of nkList:
for i in 0..n.len-1:
nimCopyAux(dest, src, n.sons[i])
asm """
for (var i = 0; i < `n`.sons.length; i++) {
nimCopyAux(`dest`, `src`, `n`.sons[i]);
}
"""
of nkCase:
asm """
`dest`[`n`.offset] = nimCopy(`dest`[`n`.offset], `src`[`n`.offset], `n`.typ);

View file

@ -64,7 +64,9 @@ proc reprStrAux(result: var string, s: cstring, len: int) =
proc reprStr(s: string): string {.compilerRtl.} =
result = ""
if cast[pointer](s).isNil:
var sIsNil = false
asm """`sIsNil` = `s` === null"""
if sIsNil: # cast[pointer](s).isNil:
# Handle nil strings here because they don't have a length field in js
# TODO: check for null/undefined before generating call to length in js?
# Also: c backend repr of a nil string is <pointer>"", but repr of an