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

perpare for more compact bit operations in JS #16728

Merged
merged 1 commit into from
Jan 19, 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: 8 additions & 7 deletions lib/pure/math.nim
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,15 @@ func isNaN*(x: SomeFloat): bool {.inline, since: (1,5,1).} =
else: result = c_isnan(x)

when defined(js):
import std/private/jsutils

proc toBitsImpl(x: float): array[2, uint32] =
asm """
const buffer = new ArrayBuffer(8);
const floatBuffer = new Float64Array(buffer);
const uintBuffer = new Uint32Array(buffer);
floatBuffer[0] = `x`;
`result` = uintBuffer
"""
let buffer = newArrayBuffer(8)
let floatBuffer = newFloat64Array(buffer)
let uintBuffer = newUint32Array(buffer)
floatBuffer[0] = x
{.emit: "`result` = `uintBuffer`;".}
# result = cast[array[2, uint32]](uintBuffer)
alaviss marked this conversation as resolved.
Show resolved Hide resolved

proc signbit*(x: SomeFloat): bool {.inline, since: (1, 5, 1).} =
## Returns true if `x` is negative, false otherwise.
Expand Down
12 changes: 12 additions & 0 deletions lib/std/private/jsutils.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
when defined(js):
type
ArrayBuffer* = ref object of JsRoot
Float64Array* = ref object of JsRoot
Uint32Array* = ref object of JsRoot

func newArrayBuffer*(n: int): ArrayBuffer {.importjs: "new ArrayBuffer(#)".}
func newFloat64Array*(buffer: ArrayBuffer): Float64Array {.importjs: "new Float64Array(#)".}
func newUint32Array*(buffer: ArrayBuffer): Uint32Array {.importjs: "new Uint32Array(#)".}

func `[]`*(arr: Uint32Array, i: int): uint32 {.importjs: "#[#]".}
func `[]=`*(arr: Float64Array, i: int, v: float) {.importjs: "#[#] = #".}
Copy link
Member

@timotheecour timotheecour Jan 15, 2021

Choose a reason for hiding this comment

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

should this be arr: Float64Array or arr: var Float64Array ? I'm really not sure here since the type is ref, but really, Float64Array + friends act like seq, so var seems to make more sense here.

what are downsides of using var here?

Copy link
Member Author

Choose a reason for hiding this comment

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

var will generates array of typed array

Copy link
Member

Choose a reason for hiding this comment

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

yes, this is generally true of var in nim js; the question is whether this has a performance impact in this case or whether v8 can optimize this (I'm not sure how to check other than performance timing)

Copy link
Member Author

@ringabout ringabout Jan 29, 2021

Choose a reason for hiding this comment

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

It seems to cause some errors in some situations, but I forgot the example.

Copy link
Member

Choose a reason for hiding this comment

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

note that for var you need the awkard syntax like this: [#][0][0]

# eg: jsbigints:
func inc*(this: var JsBigInt; amount: JsBigInt) {.importjs: "([#][0][0] += #)".} =

(until nim-lang/RFCs#315 is resolved)