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

[superseded] VM: allow importc var in some cases #12840

Conversation

timotheecour
Copy link
Member

@timotheecour timotheecour commented Dec 8, 2019

/cc @Araq

before PR:
importc var variables doesn't work at CT ( Error: cannot evaluate at compile time:), requiring user to compile a separate library to expose getters/setters instead of directly using importc var, which has its own issues (more complex, can't be inlined, etc). Eg: see example 2 in #12825 getStdout ; ditto with getErrno / setErrno to get/set errno;

after PR:
importc var now works at CT for stdin/stdout/stderr

example 1

print to stderr at CT: (requires building nim with -d:nimHasLibFFI and compiling with --experimental:compiletimeFFI for importc at CT)

import system/ansi_c
proc main()=
  c_fprintf(cstderr, "hello world stderr\n")
static: main()
main()

example 2

illustrates why if s.importcCondVar: return is also needed in the PR

import system/ansi_c

var
  cstderr2* {.importc: "stderr", header: "<stdio.h>".}: CFilePtr
  cstdout2* {.importc: "stdout", header: "<stdio.h>".}: CFilePtr
  errno* {.importc, header: "<errno.h>".}: cint

proc fopen(filename, mode: cstring): pointer {.importc: "fopen", nodecl.}

proc main()=
  c_fprintf(cstderr, "hello world stderr\n")
  c_fprintf(cstdout, "hello world stdout\n")
  c_fprintf(cstderr2, "hello world stderr\n")
  c_fprintf(cstdout2, "hello world stdout\n")
  echo ("errno: before", errno) # BUG: D20191207T175525 at CT prints address instead of value: 140735821540136 => fixed in https://github.com/nim-lang/Nim/pull/12877
  let a = fopen("nonexistant", "r")
  echo errno
  errno = 0
  echo errno

static: main()
main()

note 1

pre-existing BUG that can be fixed in future PR: as shown in snippet above, var variables at CT work for ptr types (eg cstderr) but for integral types (eg errno), they currently return the address instead of the value; help welcome to fix that; probably a bug inside compiler/evalffi.nim

note 2

(related to #12824 but different)
in future PR, it would be nice also to allow importc let and const at CT:

let foo* {.importc: "foo", header: "<stdio.h>".}: Foo
const val* {.importc: "MY_CONST_VALUE", header: "<stdio.h>".}: int

these can be worked around using an intermediate library exactly as shown in example2 in #12825:

let foo = getFoo()
const val = getVal()

but ideally would work directly, making interop simpler

@timotheecour timotheecour changed the title VM: allow importc var at CT VM: allow importc var Dec 8, 2019
@krux02
Copy link
Contributor

krux02 commented Dec 9, 2019

Well, I am totally on your side, fprintf, stdout and stderr should just work at compile time. But saying that importc var now works seamlessly at CT is also a pretty bold claim that I just don't believe. Please be more honest about the limitations. A var has mutability, how is that reflected here in your PR? You change the state at compile time, what will the value be after compilation at runtime? Will it be the value that you set the var during compilation? I honestly don't think so, but if it does, it would be worth to be mentioned.

Regarding your future plans with let and const, am totally on your side with let. But const? I have my doubts that your plan that you are suggesting will work. But that isn't criticism on this PR though.

@timotheecour timotheecour changed the title VM: allow importc var VM: allow importc var in some cases Dec 10, 2019
@timotheecour
Copy link
Member Author

right, on further inspection, importcSymbol hardcodes some symbols; this PR makes it work for those, so i've updated a bit the description;
i'm trying (in another PR) to make it work more generally but it's a bit tricky

@Araq
Copy link
Member

Araq commented Dec 10, 2019

requires building nim with -d:nimHasLibFFI and compiling with --experimental:compiletimeFFI for importc at CT

So only allow it for -d:nimHasLibFFI? The fact that we cannot run importc variables in the VM is currently a wise bug prevention tool.

@timotheecour
Copy link
Member Author

So only allow it for -d:nimHasLibFFI?

AFAIK that's already the case, the check is done inside importcSym

@timotheecour
Copy link
Member Author

superseded by #12877 which is a much more general fix; I'm keeping this PR opened since it's a simple/small patch that improves things a bit (as shown in top post); but #12877 is more general

@timotheecour
Copy link
Member Author

superseded by #12877 and its follow-up #13083

@timotheecour timotheecour deleted the exp_fix_D20191206T111826_vm_var branch January 9, 2020 02:44
@timotheecour timotheecour changed the title VM: allow importc var in some cases [superseded] VM: allow importc var in some cases Nov 12, 2020
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