vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.76k stars 2.16k forks source link

V: cannot register struct `os.File` while using `-b wasm` option. #17786

Open km19809 opened 1 year ago

km19809 commented 1 year ago

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//Desktop/py&others/velegram vexe: /home//hobby/v/v vexe mtime: 2023-03-26 14:15:10

vroot: OK, value: /home//hobby/v VMODULES: OK, value: /home//.vmodules VTMP: OK, value: /tmp/v_1000

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

l1mey112 commented 1 year ago

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.

km19809 commented 1 year ago

Then how can I read from stdin? os.input is the only input function I know. Is there any workaround?

medvednikov commented 1 year ago

@km19809 you can build for WASM via emscripten for now

-os wasm32-emscripten

km19809 commented 1 year ago

I tried -os wasm32=emscripten which generates a JS file and a WASM. The code compiles but prints 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.

l1mey112 commented 1 year ago

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.