Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS: make hash float support IE/Safari(follow up #16863) #16872

Merged
merged 1 commit into from
Feb 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions lib/pure/hashes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,18 @@ when defined(js):
res = hiXorLoJs(hiXorLoJs(P0, x xor P1), P58)
cast[Hash](toNumber(wrapToInt(res, 32)))

template asBigInt(num: float): JsBigInt =
template toBits(num: float): JsBigInt =
let
x = newArrayBuffer(8)
y = newFloat64Array(x)
z = newBigUint64Array(x)
y[0] = num
z[0]
if hasBigUint64Array():
let z = newBigUint64Array(x)
y[0] = num
z[0]
else:
let z = newUint32Array(x)
y[0] = num
big(z[0]) + big(z[1]) shl big(32)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
big(z[0]) + big(z[1]) shl big(32)
big(z[0]) + big(z[1]) shl big(32) # xxx support `bigEndian`

Copy link
Member Author

@ringabout ringabout Jan 31, 2021

Choose a reason for hiding this comment

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

endians is totally wrong in nodejs backend. For Nim JS, endians is always bigEndian.

echo cpuEndian.

Copy link
Member Author

Choose a reason for hiding this comment

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

but we could check endians by means of typed array

{.emit: """
let endianNess = () => {
  let uInt32 = new Uint32Array([0x11223344]);
  let uInt8 = new Uint8Array(uInt32.buffer);

  if(uInt8[0] === 0x44) {
      return 'Little Endian';
  } else if (uInt8[0] === 0x11) {
      return 'Big Endian';
  } else {
      return 'Maybe mixed-endian?';
  }
};

console.log(endianNess());
"""
.}

Copy link
Member

@timotheecour timotheecour Jan 31, 2021

Choose a reason for hiding this comment

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

For Nim JS, endians is always bigEndian.

endianness for js (say in browser or on node) depends on the host machine where the code runs
see also timotheecour#515

endians is totally wrong in nodejs backend.

possibly
EDIT: yikes, indeed:
nim r -b:js --eval:'echo cpuEndian' # both with or without -d:nodejs
bigEndian
=> we should file/fix
this possibly also impacts js non-nodejs

Copy link
Member

Choose a reason for hiding this comment

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

IMO for starters we should fix these:

    (name: "js", intSize: 32, endian: bigEndian,floatSize: 64,bit: 32),
    (name: "nimvm", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),

to littleEndian
in platform.nim

Copy link
Member

Choose a reason for hiding this comment

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

=> #16886

Copy link
Member Author

@ringabout ringabout Feb 1, 2021

Choose a reason for hiding this comment

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

@timotheecour
in platform.nim
there is vm and nimvm, I don't whether they are different?


proc hashWangYi1*(x: int64|uint64|Hash): Hash {.inline.} =
## Wang Yi's hash_v1 for 64-bit ints (see https://github.com/rurban/smhasher for
Expand Down Expand Up @@ -237,7 +242,7 @@ proc hash*(x: float): Hash {.inline.} =
when not defined(js):
result = hashWangYi1(cast[Hash](y))
else:
result = hashWangYiJS(asBigInt(y))
result = hashWangYiJS(toBits(y))

# Forward declarations before methods that hash containers. This allows
# containers to contain other containers
Expand Down
4 changes: 4 additions & 0 deletions lib/std/private/jsutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,9 @@ when defined(js):
func `[]`*(arr: BigUint64Array, i: int): JsBigInt {.importjs: "#[#]".}
func `[]=`*(arr: Float64Array, i: int, v: float) {.importjs: "#[#] = #".}


proc hasJsBigInt*(): bool =
asm """`result` = typeof BigInt != 'undefined'"""

proc hasBigUint64Array*(): bool =
asm """`result` = typeof BigUint64Array != 'undefined'"""