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

nim js prevents valid compile time functionality #11988

Closed
timotheecour opened this issue Aug 20, 2019 · 0 comments
Closed

nim js prevents valid compile time functionality #11988

timotheecour opened this issue Aug 20, 2019 · 0 comments

Comments

@timotheecour
Copy link
Member

timotheecour commented Aug 20, 2019

nim js prevents valid compile time functionality, see example below.
I'd like to be able to call code at CT with nim js, and it should works just like it does with nim c

Example

import std/json
const jsonNode = parseJson("12") # in my application, use case is to read/process at CT a config file
# note that getEnv and readFile do work at compile time with `nim js`

Current Output

json.nim(939, 12) Error: cannot 'importc' variable at compile time; parseNativeJson
      return parseNativeJson(buffer).convertObject()

Expected Output

should compile

Possible Solution

here's the relevant snippet from std/json

when not defined(js):
  proc parseJson*(buffer: string): JsonNode = ...
else:
  proc parseNativeJson(x: cstring): JSObject {.importc: "JSON.parse".}
  proc parseJson*(buffer: string): JsonNode = return parseNativeJson(buffer).convertObject()

the tricky part is when defined(js) doesn't care whether the procs are used at CT or RT, as the symbol table is defined once.
A workaround could be to use vm callbacks, but that's not a general solution (would require 1 callback per proc that needs to be usable at CT)
An actual solution could be a CT import:

# both RT and CT imports can coexist
{.push undef:js.}
# `when defined(js)` become false when the import is processed
import std/json as jsonCT
{.pop.}
# or: import std/json {.undef:js.} as jsonCT
import std/json # `when defined(js)` true for `nim js` when import is processed
const a = jsonCT.parseJson("12") # would use the non-js version
let a = json.parseJson("12") # would use the js version
# no magic implied, the symbol is dictated by visibility of fully qualified identifier
let a = jsonCT.parseJson("12") # CT error: jsonCT.parseJson only usable at CT
const a = json.parseJson("12") # CT error: same as in this issue report

implementation wise: checkModuleName would assign a distinct suffix to a module imported via {.undef:js.} (see processUndef), to make sure it's treated as a different module (similar to how we can now import 2 modules with same name but different paths); likewise with all modules recursively imported by it.

There may be other applications of this idea, eg to test a given windows proc on posix (can be useful in some cases, but won't always work, eg when there are system dependencies involved)

aditional examples

same root cause:

  • DynlibFormat at CT with nim js returns lib$1.so even if we're on OSX
  • Hash uses 4 bytes instead of 8 bytes with nim js at CT, like nim js, and unlike with nim c
    these are expected with current implementation, but the point is the limitations of nim js platform port over to CT code, which could be avoided.

Additional Information

  • Was it working in the previous Nim releases?
    no
$ nim -v
latest devel 4264e9576d0f3753dcff206fcff06217f2e70833
krux02 added a commit to krux02/Nim that referenced this issue Oct 9, 2019
@Araq Araq closed this as completed in 21cbfd7 Oct 17, 2019
alehander92 pushed a commit to alehander92/Nim that referenced this issue Dec 2, 2019
* closes nim-lang#12316
* make tjsonmacro work at js target
* closes nim-lang#12289
* closes nim-lang#11988
* also fixed gdb related stuff
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 a pull request may close this issue.

1 participant