Skip to content

add new target like wasm32-unknown-unknown in rust #3068

@hunjixin

Description

@hunjixin

Simple Summary

Add new wasm32-unkonw-unkonw/unknow_wasm target in TinyGo. Use this target to generate clean wasm which have no dependecies on JS or WASI.

Abstract

In the current implementation, WASM target depends heavily on the JS execution environment, and the WASI target requires the corresponding execution platform to suppoprt the POSIX protocol or something like POSIX.

When demands come to generate an algorithm to run on a specific WASM VM, there is usually no JS execution environment and no posix support in these vm environment. For example, if one would like to run the WASM code generated by TinyGo, we have to introduce some JS/WASI compatibility layer code. However, when the execution environment of the VM is developed by a third party and not within control, the developer then cannot run the compatibility layer code. At this time, it is forced to use the WASI target which translates to mannual changes of many modules in its project causing much inconvenience and infeasibilities in some cases.

A functional target similar to Rust's wasm32-unknown-unknown is needed to generate clean WASM without changing the existing library code.

Change Motivation

When the WASM file is to be run in a foreign VM environment and this target relies heavily on the JS running environment, it becomes impossible to use the WASM target. When the target is WASI, the generated code will have dependency on the WASI protocol resulting in having some import that depends on the WASI protocol. Compared with the WASM target, there is a possibility of realizing the implementation which developer can make mannual changes to the code (user module, standard package) to remove the imports on WASI. However, this approach implies large amount of engineering efforts.

For the general user library code(include dependecy), there are various parts that use POSIX functions such as (file/os/net/time) etc, which can be patched by cherry picking the corresponding module, modifying the module, removing the code that have WASI dependency and then replacing them with edited modules throughout your project. Through this method, we can achieve the goal of running targets, but it will be very cumbersome. In practice, due to the depth of dependencies, it will be difficult to find the module with problems. In addition, replacement will also bring side effects, which will require the replacement of other libraries that references the edited library.

For the standard library, it is even more cumbersome. In practice, fmt standard library has been one of the most serious problems. fmt use the stdout and stdin objects, which means that the fmt standard library depends on the os standard library that comes with an init function...(shown below)

// Args hold the command-line arguments, starting with the program name.
var Args []string

func init() {
	Args = runtime_args()
}

Not only does args_size invokes dependency on WASI, but runtime_args function further includes...

  (import "wasi_snapshot_preview1" "args_sizes_get" (func $runtime.args_sizes_get (;0;) (type 3)))
  (import "wasi_snapshot_preview1" "args_get" (func $runtime.args_get (;1;) (type 3)))
  (import "wasi_snapshot_preview1" "clock_time_get" (func $runtime.clock_time_get (;2;) (type 6)))

Unfortunately the fmt library is widely used (Eg: fmt.Errorf), which brings great troubles,

  • Standard library cannot be replaced
  • There are too many user modules which use fmt package, making not realistic to replace all of them.

Therefore, we hope to refer to Rust's wasm32-unkonow-unkonwn, and use plateform specific code to handle these problems (io/file/net) when specifying the directive.

Implementation

  1. Similar to WASI, add a new directive wasm_unknow to isolate the specific implementation to make sure previous WASM/WASI behaviour stays the same.
  2. Add new target type wasm_unknow to generate cleaner WASM files through this kind of utility target.

The main idea is to refer to the implementation of rust wasm32-unknown-unknown https://github.com/rust-lang/rust/tree/master/library/std/src/sys/unsupported.

packages to be changed

  1. src/os
  2. src/syscall
  3. src/runtime add new target support

behavior change

  1. os.args/os.env always return empty slice
  2. file/net not support ,
  3. stdout. discard
  4. stdin return io.EOF
  5. time flow rust panic behavire (many people use time as rand seed, autoincrease nano time cause predicatable randomness
  6. syscall use xx_emulated.go, and no Signal support
  7. Signal remove signal (Signal always used in main file, less used in library, so remote it)

Maintainer

I am also very happy to maintain this target, and I also have a team member who can invest in the development of this target.

@dankegel @deadprogram @aykevl

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions