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

Compiler crash: invalid kind for first(tyObject) #7675

Closed
mratsim opened this issue Apr 22, 2018 · 4 comments
Closed

Compiler crash: invalid kind for first(tyObject) #7675

mratsim opened this issue Apr 22, 2018 · 4 comments

Comments

@mratsim
Copy link
Collaborator

mratsim commented Apr 22, 2018

Test case:

type
  int128*{.importc: "__int128".} = object
    # Size missing https://github.com/nim-lang/Nim/issues/7674

  helper128 = object
    lo, hi: uint64

func `+`(x, y: int128): int128 {.magic: "AddI".}

var
  helperA = helper128(lo: 10)
  helperB = helper128(lo: 30)

let
  a = (cast[ptr int128](helperA.addr))[]
  b = (cast[ptr int128](helperB.addr))[]

var c = a + b
echo (cast[ptr helper128](c.addr))[]
@mratsim
Copy link
Collaborator Author

mratsim commented Apr 22, 2018

This works though:

type
  int128*{.importc: "__int128".} = object
    # Size missing https://github.com/nim-lang/Nim/issues/7674
    do_not_use1, do_not_use2: uint64

  helper128 = object
    lo, hi: uint64

func `+`(x, y: int128): int128 {.magic: "AddI".}

var
  helperA = helper128(lo: 10)
  helperB = helper128(lo: 30)

let
  a = (cast[ptr int128](helperA.addr))[]
  b = (cast[ptr int128](helperB.addr))[]

var c = a + b
echo (cast[ptr helper128](c.addr))[] # (lo: 40, hi: 0)

Tagging #7674 as setting the size would probably solve this.

@Araq
Copy link
Member

Araq commented Apr 22, 2018

Come on, these magics are not for others. :P

@mratsim
Copy link
Collaborator Author

mratsim commented Apr 22, 2018

Okay closing this. I can get by with emit. I'd like the size to work though.

Emit:

{.emit:"""
typedef unsigned __int128 NU128;
typedef          __int128 NI128;
""".}

type
  int128*{.importc: "NI128".} = object
    # Size missing https://github.com/nim-lang/Nim/issues/7674
    do_not_use1, do_not_use2: uint64

  helper128 = object
    lo, hi: uint64

func `+`(x, y: int128): int128 {.magic: "AddI".}
# func `shl`(x, y: int128): int128 {.magic: "ShlI".}
#   # Generates c_3kT3fyGcLUlO9cGAfoG5F0w = ()((NU128)(a_H4uaduhuKIzzvSo9a5XGckw) << (NU128)(b_s7Jde6jEzqXVu63vxBEZxg));
#   # Notice how the parenthesis is empty

func `shl`(x, y: int128): int128 =
  {.emit: "`result` = (NI128)((NU128)(`x`) << (NU128)(`y`));".}
  # Works

var
  helperA = helper128(lo: 10)
  helperB = helper128(lo: 3)

let
  a = (cast[ptr int128](helperA.addr))[]
  b = (cast[ptr int128](helperB.addr))[]

var c = a shl b
echo (cast[ptr helper128](c.addr))[] # (lo: 80, hi: 0)

@mratsim mratsim closed this as completed Apr 22, 2018
@zah
Copy link
Member

zah commented Apr 23, 2018

@mratsim, besides emit, you can also use the importcpp pragma in some situations to produce shorter code. Check out these examples from the "jsffi" module:

https://github.com/nim-lang/Nim/blob/devel/lib/js/jsffi.nim#L137

You can think of the importcpp pragma as something like a codegen macro.

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

No branches or pull requests

3 participants