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

let's assume littleEndian in JS backend #16886

Merged
merged 2 commits into from
Feb 1, 2021
Merged

let's assume littleEndian in JS backend #16886

merged 2 commits into from
Feb 1, 2021

Conversation

ringabout
Copy link
Member

@ringabout ringabout commented Jan 31, 2021

Most systems are little endians(especially for JS, it's more meaningful to assume little endians.

Ref https://hacks.mozilla.org/2017/01/typedarray-or-dataview-understanding-byte-order

So, in summary, here’s what we’ve learned:
It is safe to assume systems to be little-endian.

@ringabout
Copy link
Member Author

ringabout commented Jan 31, 2021

getEndians for C/JS/VM backend

when defined(js):
  import std/jsbigints

  type
    ArrayBuffer* = ref object of JsRoot
    Float64Array* = ref object of JsRoot
    Uint32Array* = ref object of JsRoot
    BigUint64Array* = 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 newBigUint64Array*(buffer: ArrayBuffer): BigUint64Array {.importjs: "new BigUint64Array(#)".}

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

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

when defined(js):
  type
    Uint8Array* = ref object of JsRoot

  func buffer(p: Uint32Array): ArrayBuffer {.importjs: "#.buffer".}


  func newUint32Array*(arr: openArray[uint32]): Uint32Array {.importjs: "new Uint32Array(#)".}

  func newUint8Array(p: ArrayBuffer): Uint8Array {.importjs: "new Uint8Array(#)".}

  func `[]`*(arr: Uint8Array, i: int): uint8 {.importjs: "#[#]".}


when defined(js):
  when defined(nodejs):
    {.emit: "const _nim_nodejs_os = require('os');".}

    proc endianness(): cstring {.importjs: "_nim_nodejs_os.endianness()".}

    template getEndiansImpl(): Endianness =
      if endianness() == "LE":
        littleEndian
      else:
        bigEndian
  else:
    template getEndiansImpl(): Endianness =
      let a = newUint32Array([0x12345678'u32])
      let b = newUint8Array(a.buffer)
      if b[0] == 0x78:
        littleEndian
      else:
        bigEndian

template getEndiansImpl(): Endianness =
  when defined(i386) or defined(alpha) or defined(powerpc64el) or
      defined(ia64) or defined(amd64) or defined(mipsel) or defined(arm) or
      defined(arm64) or defined(avr) or defined(msp430) or defined(riscv32) or
      defined(riscv64) or defined(esp) or defined(wasm32) or defined(mips64el):
    littleEndian
  elif defined(m68k) or defined(powerpc) or defined(powerpc64) or defined(sparc) or
      defined(hppa) or defined(mips) or defined(sparc64) or defined(mips64):
    bigEndian
  else:
    littleEndian

proc getEndians(): Endianness {.inline.} =
  when nimvm:
    getEndiansImpl()
  else:
    when defined(js):
      result = getEndiansImpl()
    else:
      result = cpuEndian

static: echo getEndians()
echo getEndians()

compiler/platform.nim Outdated Show resolved Hide resolved
@ringabout ringabout changed the title let's assume littleEndian in JS and VM backend let's assume littleEndian in JS backend Jan 31, 2021
@timotheecour
Copy link
Member

timotheecour commented Feb 1, 2021

LGTM.
future work:

@Araq Araq merged commit 74f8a8e into nim-lang:devel Feb 1, 2021
ardek66 pushed a commit to ardek66/Nim that referenced this pull request Mar 26, 2021
* let's assume littleEndian in JS and VM backend

* Update compiler/platform.nim
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants