V: cannot register struct `os.File` while using `-b wasm` option.
Describe the bug
I compiled my calculator code, which runs successfully in Ubuntu 20.04. (v calc.v)
However, when I use v -b wasm calc.v, it throws an error about os.File.
My code (calc.v):
import os
import calculator
fn main() {
mut parser := calculator.Parser{}
result := parser.evaluate(calculator.tokenize(os.input(''))) or {println(err) return}
println(result)
}
The calculator module only uses math, random, and datatypes.
It does not use any os function or struct.
calc.v is the only place that I use os module.
Expected Behavior
It should be compiled into WASI binary.
Current Behavior
It throws:
/home/<my-name>/hobby/v/vlib/os/file.js.v:3:12: error: cannot register struct `os.File`, another type with this name exists
1 | module os
2 |
3 | pub struct File {
| ~~~~
4 | pub:
5 | fd int
Reproduction Steps
I made a sample code to reproduce (echo.v):
import os
fn main() {
println(os.input(''))
}
Then run v -b wasm echo.v.
Possible Solution
I assume that -b wasm tries to compile both vlib/os/file.c.v and vlib/os/file.js.v.
I've searched all the files in the os module for struct File {, but vlib/os/file.c.v and vlib/os/file.js.v were only occurrences.
Also, if I try v -b js echo.v instead, it compiles into js.
I suspect that WASM backend tries to compile all the .v files.
I made an example to prove it:
my-app/
├─ sus/
│ ├─ sus.js.v
│ ├─ sus.c.v
├─ main.v
main.v:
module main
import sus
fn main() {
sus.printout()
}
sus.c.v:
module sus
pub fn printout() {
println("C!")
}
sus.js.v:
module sus
pub fn printout() {
println("JS!")
}
The result of v -b wasm main.v:
builder error: redefinition of function `sus.printout`
sus/sus.c.v:3:1: conflicting declaration: pub fn printout()
1 | module sus
2 |
3 | pub fn printout() {
| ~~~~~~~~~~~~~~~~~
4 | println("C!")
5 | }
sus/sus.js.v:3:1: conflicting declaration: pub fn printout()
1 | module sus
2 |
3 | pub fn printout() {
| ~~~~~~~~~~~~~~~~~
4 | println("JS!")
5 | }
Additional Information/Context
No response
V version
V 0.3.3 130f35c
Environment details (OS name and version, etc.)
V full version: V 0.3.3 130f35c OS: linux, Ubuntu 20.04.6 LTS (WSL 2) Processor: 8 cpus, 64bit, little endian, Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz
getwd: /mnt/c/Users/
vroot: OK, value: /home/
Git version: git version 2.25.1 Git vroot status: weekly.2023.12-35-g130f35c7 .git/config present: true
CC version: cc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0 thirdparty/tcc status: thirdparty-linux-amd64 12f392c3
The WebAssembly backend does not support importing the os module. .js.v and .c.v files are also not properly discriminated against. The backend is currently WIP right now, I will keep these in mind.
Then how can I read from stdin?
os.input is the only input function I know.
Is there any workaround?
@km19809 you can build for WASM via emscripten for now
-os wasm32-emscripten
I tried -os wasm32=emscripten which generates a JS file and a WASM.
The code compiles but prints <EOF> when it ran on node.js.
This behavior is the same as the result of -b js.
Somehow, a simple echo going tough...
I should try WASM.fd_read.
WASM.fd_read is currently not implemented in the standard library yet, only WASM.fd_write. You can find a reference implementation for WASM.fd_write to help you out inside vlib/builtin/wasm/wasi/wasi.v.