Refactor api code and doc

This commit is contained in:
Steve Akinyemi 2018-11-20 20:11:58 +01:00
parent 70e3262bf8
commit 771dae7feb
32 changed files with 796 additions and 2332 deletions

42
Cargo.lock generated
View File

@ -85,19 +85,17 @@ dependencies = [
[[package]]
name = "cranelift-bforest"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cranelift-entity 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-entity 0.23.0",
]
[[package]]
name = "cranelift-codegen"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cranelift-bforest 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen-meta 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-entity 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-bforest 0.23.0",
"cranelift-codegen-meta 0.23.0",
"cranelift-entity 0.23.0",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -107,22 +105,19 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cranelift-entity 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-entity 0.23.0",
]
[[package]]
name = "cranelift-entity"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cranelift-frontend"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cranelift-codegen 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen 0.23.0",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -130,9 +125,8 @@ dependencies = [
[[package]]
name = "cranelift-native"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cranelift-codegen 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen 0.23.0",
"raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -140,11 +134,10 @@ dependencies = [
[[package]]
name = "cranelift-wasm"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cranelift-codegen 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-entity 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-frontend 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen 0.23.0",
"cranelift-entity 0.23.0",
"cranelift-frontend 0.23.0",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -594,10 +587,10 @@ dependencies = [
name = "wasmer"
version = "0.1.0"
dependencies = [
"cranelift-codegen 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-entity 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-native 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-wasm 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen 0.23.0",
"cranelift-entity 0.23.0",
"cranelift-native 0.23.0",
"cranelift-wasm 0.23.0",
"docopt 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (git+https://github.com/rust-lang/libc)",
@ -654,13 +647,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
"checksum cranelift-bforest 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c5f8e1ab4f73b59a98531a8013d8ed3ca7edb4e36984cb301d9c06f6892787b"
"checksum cranelift-codegen 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437ec8212686e6cdacfea75aaedb4ab8b013869be1e8693a4cb97a60f135035"
"checksum cranelift-codegen-meta 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4eac16097b96e9f609df735555f2d1658531750fbc3805bca1daca7671aef9eb"
"checksum cranelift-entity 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9be3f82369346201c2e0cff720522e6eb55459e51c916b2199f25cff2058ca96"
"checksum cranelift-frontend 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d5d18ab2bc89a09b4275442a9559dc0f947b9a8ad9ae9ee89452a057df54ced"
"checksum cranelift-native 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d8d3b5951eefd89778dc59b0e33b556573a870538bc21982019bd4c4003b0a2d"
"checksum cranelift-wasm 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5906a111814d43d84002ef974eb0c023804fd4d1866b34f43c1bb588a759ad8"
"checksum docopt 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d60c92df70dfaaabecc14b409fd79f55ba0f247780529db1d73bfa601e1d3ac0"
"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e"
"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"

View File

@ -20,14 +20,14 @@ include = [
]
[dependencies]
cranelift-native = "0.23.0"
# cranelift-native = { path = "cranelift/lib/native" }
cranelift-codegen = "0.23.0"
# cranelift-codegen = { path = "cranelift/lib/codegen" }
cranelift-entity = "0.23.0"
# cranelift-entity = { path = "cranelift/lib/entity" }
cranelift-wasm = "0.23.0"
# cranelift-wasm = { path = "cranelift/lib/wasm" }
# cranelift-native = "0.23.0"
cranelift-native = { path = "cranelift/lib/native" }
# cranelift-codegen = "0.23.0"
cranelift-codegen = { path = "cranelift/lib/codegen" }
# cranelift-entity = "0.23.0"
cranelift-entity = { path = "cranelift/lib/entity" }
# cranelift-wasm = "0.23.0"
cranelift-wasm = { path = "cranelift/lib/wasm" }
docopt = "1.0.0"
serde = "1.0.55"
serde_derive = "1.0.55"

1
cranelift Submodule

@ -0,0 +1 @@
Subproject commit 3f6fdf952c5fe52381e8c16f5d1912972fc2d394

31
examples/em_abort.wat Normal file
View File

@ -0,0 +1,31 @@
(module
(type $t1 (func (param i32 i32) (result i32)))
(type $t2 (func (param i32)))
(type $t3 (func ))
(func $printf (import "env" "printf") (type $t1))
(func $abort (import "env" "abort") (type $t2))
(func $_abort (import "env" "_abort") (type $t3))
(func $abort_on_cannot_grow_memory (import "env" "abortOnCannotGrowMemory") (type $t3))
(memory 1)
(data (i32.const 0) ">>> First\00")
(data (i32.const 24) ">>> Second\00")
(data (i32.const 48) "Aborting abruptly!\00")
(func $main (export "main")
;; print ">>> First"
(call $printf (i32.const 0) (i32.const 0))
(drop)
;; aborts
(call $_abort) ;; ()
;; aborts
(call $abort_on_cannot_grow_memory) ;; ()
;; aborts
(call $abort (i32.const 48)) ;; (message: u32)
;; print ">>> Second"
(call $printf (i32.const 24) (i32.const 0))
(drop)
)
)

27
examples/em_exit.wat Normal file
View File

@ -0,0 +1,27 @@
(module
(type $t1 (func (param i32)))
(func $putchar (import "env" "putchar") (type $t1))
(func $sys_exit (import "env" "___syscall1") (type $t1))
(memory 1)
(func $main (export "main")
;; print "Hello"
(call $putchar (i32.const 72))
(call $putchar (i32.const 101))
(call $putchar (i32.const 108))
(call $putchar (i32.const 108))
(call $putchar (i32.const 111))
(call $putchar (i32.const 32))
;; exit abruptly
(call $sys_exit (i32.const 255)) ;; (status: c_int) -> c_int
;; print " World!"
(call $putchar (i32.const 87))
(call $putchar (i32.const 111))
(call $putchar (i32.const 114))
(call $putchar (i32.const 108))
(call $putchar (i32.const 100))
(call $putchar (i32.const 33))
(call $putchar (i32.const 10))
)
)

File diff suppressed because it is too large Load Diff

43
examples/em_read_file.wat Normal file
View File

@ -0,0 +1,43 @@
(module
(type $t1 (func (param i32)))
(type $t2 (func (param i32 i32 i32) (result i32)))
(type $t3 (func (param i32) (result i32)))
(type $t4 (func (param i32 i32) (result i32)))
(func $putchar (import "env" "putchar") (type $t1))
(func $printf (import "env" "printf") (type $t4))
(func $sys_open (import "env" "___syscall5") (type $t2))
(func $sys_read (import "env" "___syscall3") (type $t2))
(func $sys_close (import "env" "___syscall6") (type $t3))
(memory 1)
(data $filename (i32.const 0) "/Users/xxxx/Desktop/hello.txt\00")
(func $main (export "main")
;; declare variables
(local $string_buf_addr i32)
(local $string_buf_len i32)
(local $file_access_flag i32)
(local $file_permission_flag i32)
(local $file_descriptor i32)
;; set variables
(set_local $string_buf_addr (i32.const 72)) ;; string_buf_addr at offset 72
(set_local $string_buf_len (i32.const 10)) ;; string_buf_len is 5
(set_local $file_access_flag (i32.const 02)) ;; file_access_flag has O_RDWR permission
(set_local $file_permission_flag (i32.const 700)) ;; file_permission_flag has S_IRWXU permission
;; open file
(call $sys_open (i32.const 0) (get_local $file_access_flag) (get_local $file_permission_flag)) ;; (path: u32, flags: c_int, mode: c_int) -> c_int
(set_local $file_descriptor) ;; set file_descriptor to the value returned by sys_open
;; read file content
(call $sys_read (get_local $file_descriptor) (get_local $string_buf_addr) (get_local $string_buf_len)) ;; (fd: c_int, buf: u32, count: size_t) -> ssize_t
(drop) ;; ignoring errors
;; close file
(call $sys_close (get_local $file_descriptor)) ;; (fd: c_int) -> c_int
(drop) ;; ignoring errors
;; print file content
(call $printf (get_local $string_buf_addr) (i32.const 0))
(drop) ;; ignoring errors
)
)

View File

@ -0,0 +1,394 @@
## HOST APIS
#### EMSCRIPTEN APIS
###### PROCESS
- **_abort**    [:top:](#host-apis)
```rust
fn _abort()
```
- **abort** ✅ 🔥     [:top:](#host-apis)
```rust
fn abort(message: u32, instance: &mut Instance)
```
- **abort_on_cannot_grow_memory**    [:top:](#host-apis)
```rust
fn abort_on_cannot_grow_memory()
```
###### TIMING
- **_clock_gettime**     [:top:](#host-apis)
```rust
```
###### ENVIRONMENT
- **_getenv**     [:top:](#host-apis)
```rust
```
###### THREAD
- **_pthread_getspecific**     [:top:](#host-apis)
```rust
```
- **_pthread_key_create**     [:top:](#host-apis)
```rust
```
- **_pthread_setspecific**     [:top:](#host-apis)
```rust
```
- **_unsetenv**     [:top:](#host-apis)
```rust
```
- **___lock**     [:top:](#host-apis)
```rust
```
- **___unlock**     [:top:](#host-apis)
```rust
```
###### MEMORY
- **_emscripten_memcpy_big** ✅ 🔥     [:top:](#host-apis)
```rust
fn _emscripten_memcpy_big(dest: u32, src: u32, len: u32, instance: &mut Instance) -> u32
```
- **enlarge_memory**    [:top:](#host-apis)
```rust
fn enlarge_memory()
```
- **get_total_memory**    [:top:](#host-apis)
```rust
fn get_total_memory(instance: &mut Instance) -> u32
```
###### TIMING
- **_clock_gettime**     [:top:](#host-apis)
```rust
```
###### STATUS
- **___set_err_no**     [:top:](#host-apis)
```rust
```
-------------------------------------------------------------------
#### EMSCRIPTEN SYSCALLS
- **access** (___syscall33)     [:top:](#host-apis)
```rust
```
- **acct** (___syscall51)     [:top:](#host-apis)
```rust
```
- **chdir** (___syscall12)     [:top:](#host-apis)
```rust
```
- **chmod** (___syscall15)     [:top:](#host-apis)
```rust
```
- **chown** (___syscall212)     [:top:](#host-apis)
```rust
```
- **clock_nanosleep** (___syscall265)     [:top:](#host-apis)
```rust
```
- **close** (___syscall6) ✅ ❗️     [:top:](#host-apis)
```rust
fn close(fd: c_int) -> c_int
```
- **dup** (___syscall330)     [:top:](#host-apis)
```rust
```
- **dup** (___syscall41)     [:top:](#host-apis)
```rust
```
- **dup** (___syscall63)     [:top:](#host-apis)
```rust
```
- **exit** (___syscall1) ✅     [:top:](#host-apis)
```rust
fn exit(status: c_int)
```
- **faccessat** (___syscall307)     [:top:](#host-apis)
```rust
```
- **fadvise** (___syscall272)     [:top:](#host-apis)
```rust
```
- **fallocate** (___syscall324)     [:top:](#host-apis)
```rust
```
- **fchdir** (___syscall133)     [:top:](#host-apis)
```rust
```
- **fchmod** (___syscall94)     [:top:](#host-apis)
```rust
```
- **fchmodat** (___syscall306)     [:top:](#host-apis)
```rust
```
- **fchown** (___syscall207)     [:top:](#host-apis)
```rust
```
- **fchownat** (___syscall298)     [:top:](#host-apis)
```rust
```
- **fcntl** (___syscall221)     [:top:](#host-apis)
```rust
```
- **fdatasync** (___syscall148)     [:top:](#host-apis)
```rust
```
- **fstat** (___syscall197)     [:top:](#host-apis)
```rust
```
- **fstatat** (___syscall300)     [:top:](#host-apis)
```rust
```
- **fstatfs** (___syscall269)     [:top:](#host-apis)
```rust
```
- **fsync** (___syscall118)     [:top:](#host-apis)
```rust
```
- **ftruncate** (___syscall194)     [:top:](#host-apis)
```rust
```
- **futimesat** (___syscall299)     [:top:](#host-apis)
```rust
```
- **getcwd** (___syscall183)     [:top:](#host-apis)
```rust
```
- **getdents** (___syscall220)     [:top:](#host-apis)
```rust
```
- **getgid** (___syscall202)     [:top:](#host-apis)
```rust
```
- **getgroups** (___syscall205)     [:top:](#host-apis)
```rust
```
- **getpgid** (___syscall132)     [:top:](#host-apis)
```rust
```
- **getpgrp** (___syscall65)     [:top:](#host-apis)
```rust
```
- **getpid** (___syscall20)     [:top:](#host-apis)
```rust
```
- **getppid** (___syscall64)     [:top:](#host-apis)
```rust
```
- **getpriority** (___syscall96)     [:top:](#host-apis)
```rust
```
- **getresgid** (___syscall211)     [:top:](#host-apis)
```rust
```
- **getrusage** (___syscall77)     [:top:](#host-apis)
```rust
```
- **getsid** (___syscall147)     [:top:](#host-apis)
```rust
```
- **ioctl** (___syscall54)     [:top:](#host-apis)
```rust
```
- **lchown** (___syscall198)     [:top:](#host-apis)
```rust
```
- **link** (___syscall9)     [:top:](#host-apis)
```rust
```
- **linkat** (___syscall303)     [:top:](#host-apis)
```rust
```
- **llseek** (___syscall140)     [:top:](#host-apis)
```rust
```
- **lstat** (___syscall196)     [:top:](#host-apis)
```rust
```
- **madvise** (___syscall219)     [:top:](#host-apis)
```rust
```
- **mincore** (___syscall218)     [:top:](#host-apis)
```rust
```
- **mkdir** (___syscall39)     [:top:](#host-apis)
```rust
```
- **mkdirat** (___syscall296)     [:top:](#host-apis)
```rust
```
- **mknod** (___syscall14)     [:top:](#host-apis)
```rust
```
- **mknodat** (___syscall297)     [:top:](#host-apis)
```rust
```
- **mmap** (___syscall192)     [:top:](#host-apis)
```rust
```
- **mprotect** (___syscall125)     [:top:](#host-apis)
```rust
```
- **mremap** (___syscall163)     [:top:](#host-apis)
```rust
```
- **msync** (___syscall144)     [:top:](#host-apis)
```rust
```
- **munlockall** (___syscall153)     [:top:](#host-apis)
```rust
```
- **munmap** (___syscall91)     [:top:](#host-apis)
```rust
```
- **newselect** (___syscall142)     [:top:](#host-apis)
```rust
```
- **nice** (___syscall34)     [:top:](#host-apis)
```rust
```
- **open** (___syscall5) ✅ ❗️ 🔥     [:top:](#host-apis)
```rust
fn open(path: u32, flags: c_int, mode: c_int, instance: &mut Instance) -> c_int
```
- **openat** (___syscall295)     [:top:](#host-apis)
```rust
```
- **pause** (___syscall29)     [:top:](#host-apis)
```rust
```
- **pipe** (___syscall331)     [:top:](#host-apis)
```rust
```
- **pipe** (___syscall42)     [:top:](#host-apis)
```rust
```
- **poll** (___syscall168)     [:top:](#host-apis)
```rust
```
- **pread** (___syscall180)     [:top:](#host-apis)
```rust
```
- **preadv** (___syscall333)     [:top:](#host-apis)
```rust
```
- **prlimit** (___syscall340)     [:top:](#host-apis)
```rust
```
- **pselect** (___syscall308)     [:top:](#host-apis)
```rust
```
- **pwrite** (___syscall181)     [:top:](#host-apis)
```rust
```
- **pwritev** (___syscall334)     [:top:](#host-apis)
```rust
```
- **read** (___syscall3) ✅ ❗️     [:top:](#host-apis)
```rust
fn read(fd: c_int, buf: u32, count: size_t, instance: &mut Instance) -> ssize_t
```
- **readlink** (___syscall85)     [:top:](#host-apis)
```rust
```
- **readlinkat** (___syscall305)     [:top:](#host-apis)
```rust
```
- **readv** (___syscall145)     [:top:](#host-apis)
```rust
```
- **recvmmsg** (___syscall337)     [:top:](#host-apis)
```rust
```
- **rename** (___syscall38)     [:top:](#host-apis)
```rust
```
- **renameat** (___syscall302)     [:top:](#host-apis)
```rust
```
- **rmdir** (___syscall40)     [:top:](#host-apis)
```rust
```
- **rt_sigqueueinfo** (___syscall178)     [:top:](#host-apis)
```rust
```
- **sendmmsg** (___syscall345)     [:top:](#host-apis)
```rust
```
- **setdomainname** (___syscall121)     [:top:](#host-apis)
```rust
```
- **setgid** (___syscall214)     [:top:](#host-apis)
```rust
```
- **setitimer** (___syscall104)     [:top:](#host-apis)
```rust
```
- **setpgid** (___syscall57)     [:top:](#host-apis)
```rust
```
- **setpriority** (___syscall97)     [:top:](#host-apis)
```rust
```
- **setresgid** (___syscall210)     [:top:](#host-apis)
```rust
```
- **setrlimit** (___syscall75)     [:top:](#host-apis)
```rust
```
- **setsid** (___syscall66)     [:top:](#host-apis)
```rust
```
- **socketcall** (___syscall102)     [:top:](#host-apis)
```rust
```
- **stat** (___syscall195)     [:top:](#host-apis)
```rust
```
- **statfs** (___syscall268)     [:top:](#host-apis)
```rust
```
- **symlink** (___syscall83)     [:top:](#host-apis)
```rust
```
- **symlinkat** (___syscall304)     [:top:](#host-apis)
```rust
```
- **sync** (___syscall36)     [:top:](#host-apis)
```rust
```
- **truncate** (___syscall193)     [:top:](#host-apis)
```rust
```
- **ugetrlimit** (___syscall191)     [:top:](#host-apis)
```rust
```
- **umask** (___syscall60)     [:top:](#host-apis)
```rust
```
- **uname** (___syscall122)     [:top:](#host-apis)
```rust
```
- **unlink** (___syscall10)     [:top:](#host-apis)
```rust
```
- **unlinkat** (___syscall301)     [:top:](#host-apis)
```rust
```
- **utimensat** (___syscall320)     [:top:](#host-apis)
```rust
```
- **wait** (___syscall114)     [:top:](#host-apis)
```rust
```
- **write** (___syscall4)     [:top:](#host-apis)
```rust
```
- **writev** (___syscall146)     [:top:](#host-apis)
```rust
```

View File

@ -2,6 +2,10 @@ use libc::printf as _printf;
use crate::webassembly::Instance;
/// putchar
pub use libc::putchar;
/// printf
pub extern "C" fn printf(memory_offset: i32, extra: i32, instance: &Instance) -> i32 {
let mem = &instance.memories[0];
return unsafe {

View File

@ -0,0 +1,25 @@
use libc::{
c_void,
size_t,
memcpy,
};
use crate::webassembly::{Instance};
/// emscripten: _emscripten_memcpy_big
pub extern "C" fn _emscripten_memcpy_big(dest: u32, src: u32, len: u32, instance: &mut Instance) -> u32 {
let dest_addr = instance.memory_offset_addr(0, dest as usize) as *mut c_void;
let src_addr = instance.memory_offset_addr(0, src as usize) as *mut c_void;
unsafe { memcpy(dest_addr, src_addr, len as size_t); }
dest
}
/// emscripten: getTotalMemory
pub extern "C" fn get_total_memory(instance: &mut Instance) -> u32 {
instance.memories[0].current_size()
}
/// emscripten: enlargeMemory
pub extern "C" fn enlarge_memory() {
// stub
}

View File

@ -1,20 +1,29 @@
use crate::webassembly::{ImportObject, ImportValue};
mod abort;
mod printf;
mod putchar;
mod syscalls;
// EMSCRIPTEN APIS
mod memory;
mod process;
mod io;
// SYSCALLS
use super::host;
pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
let mut import_object = ImportObject::new();
import_object.set("env", "printf", ImportValue::Func(printf::printf as *const u8));
import_object.set("env", "putchar", ImportValue::Func(putchar::putchar as *const u8));
import_object.set("env", "abort", ImportValue::Func(abort::abort as *const u8));
import_object.set("env", "_abort", ImportValue::Func(abort::abort as *const u8));
// SYSCALLS
import_object.set("env", "__syscall1", ImportValue::Func(syscalls::__syscall1 as *const u8));
import_object.set("env", "__syscall3", ImportValue::Func(syscalls::__syscall3 as *const u8));
import_object.set("env", "__syscall5", ImportValue::Func(syscalls::__syscall5 as *const u8));
import_object.set("env", "printf", ImportValue::Func(io::printf as *const u8));
import_object.set("env", "putchar", ImportValue::Func(io::putchar as *const u8));
// EMSCRIPTEN SYSCALLS
import_object.set("env", "___syscall1", ImportValue::Func(host::sys_exit as *const u8));
import_object.set("env", "___syscall3", ImportValue::Func(host::sys_read as *const u8));
import_object.set("env", "___syscall5", ImportValue::Func(host::sys_open as *const u8));
import_object.set("env", "___syscall6", ImportValue::Func(host::sys_close as *const u8));
// EMSCRIPTEN APIS
import_object.set("env", "abort", ImportValue::Func(process::em_abort as *const u8));
import_object.set("env", "_abort", ImportValue::Func(process::_abort as *const u8));
import_object.set("env", "abortOnCannotGrowMemory", ImportValue::Func(process::abort_on_cannot_grow_memory as *const u8));
import_object.set("env", "_emscripten_memcpy_big", ImportValue::Func(memory::_emscripten_memcpy_big as *const u8));
import_object.set("env", "enlargeMemory", ImportValue::Func(memory::enlarge_memory as *const u8));
import_object.set("env", "getTotalMemory", ImportValue::Func(memory::get_total_memory as *const u8));
import_object
}

View File

@ -0,0 +1,39 @@
use libc::{
// c_int,
// c_void,
c_char,
// size_t,
// ssize_t,
abort,
};
use std::ffi::CStr;
use crate::webassembly::{Instance};
extern "C" fn abort_with_message(message: &str) {
println!("{}", message);
_abort();
}
/// emscripten: _abort
pub extern "C" fn _abort() {
unsafe { abort(); }
}
/// emscripten: abort
pub extern "C" fn em_abort(message: u32, instance: &mut Instance) {
let message_addr = instance.memory_offset_addr(0, message as usize) as *mut c_char;
unsafe {
let message = CStr::from_ptr(message_addr)
.to_str()
.unwrap_or("Unexpected abort");
abort_with_message(message);
}
}
/// emscripten: abortOnCannotGrowMemory
pub extern "C" fn abort_on_cannot_grow_memory() {
abort_with_message("Cannot enlarge memory arrays!");
}

0
src/apis/gcc/.gitignore vendored Normal file
View File

4
src/apis/host/mod.rs Normal file
View File

@ -0,0 +1,4 @@
mod posix;
// TODO: Make portable
pub use self::posix::*;

View File

@ -0,0 +1,3 @@
pub mod syscalls;
pub use self::syscalls::*;

View File

@ -0,0 +1,37 @@
/// NOTE: These syscalls only support wasm_32 for now because they take u32 offset
use libc::{
c_int,
c_void,
size_t,
ssize_t,
exit,
read,
open,
close,
};
use crate::webassembly::{Instance};
/// emscripten: ___syscall1
pub extern "C" fn sys_exit(status: c_int) {
unsafe { exit(status); }
}
/// emscripten: ___syscall3
pub extern "C" fn sys_read(fd: c_int, buf: u32, count: size_t, instance: &mut Instance) -> ssize_t {
let buf_addr = instance.memory_offset_addr(0, buf as usize) as *mut c_void;
unsafe { read(fd, buf_addr, count) }
}
/// emscripten: ___syscall5
pub extern "C" fn sys_open(path: u32, flags: c_int, mode: c_int, instance: &mut Instance) -> c_int {
let path_addr = instance.memory_offset_addr(0, path as usize) as *const i8;
unsafe { open(path_addr, flags, mode) }
}
/// emscripten: ___syscall6
pub extern "C" fn sys_close(fd: c_int) -> c_int {
unsafe { close(fd) }
}

0
src/apis/llvm/.gitignore vendored Normal file
View File

View File

@ -1,3 +1,5 @@
pub mod emscripten;
pub mod host;
pub use self::emscripten::generate_emscripten_env;

View File

@ -1,389 +0,0 @@
# HOST APIS
## EMSCRIPTEN APIS
#### PROCESS
- <a name="abort"></a>SYS_fstat (___syscall197) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="_abort"></a>abort &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
fn abort()
```
- <a name="_clock_gettime"></a>abort &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
fn abort()
```
- <a name="_emscripten_memcpy_big"></a>abort &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
fn abort()
```
- <a name="_getenv"></a>abort &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
fn abort()
```
#### THREAD
- <a name="_pthread_getspecific"></a>abort &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
fn abort()
```
- <a name="_pthread_key_create"></a>abort &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
fn abort()
```
- <a name="_pthread_setspecific"></a>abort &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
fn abort()
```
- <a name="_unsetenv"></a>abort &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
fn abort()
```
- <a name="___lock"></a>SYS_fstat (___syscall197) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="___unlock"></a>SYS_fstat (___syscall197) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
#### MEMORY
- <a name="abortOnCannotGrowMemory"></a>SYS_fstat (___syscall197) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="enlargeMemory"></a>SYS_fstat (___syscall197) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getTotalMemory"></a>SYS_fstat (___syscall197) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
#### TIMING
- <a name="_clock_gettime"></a>SYS_fstat (___syscall197) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
#### STATUS
- <a name="___setErrNo"></a>SYS_fstat (___syscall197) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
## EMSCRIPTEN SYSCALLS
- <a name="SYS_fstat"></a>SYS_fstat (___syscall197) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="SYS_getdents"></a>SYS_getdents (___syscall220) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="SYS_lstat"></a>SYS_lstat (___syscall196) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="SYS_stat"></a>SYS_stat (___syscall195) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="access"></a>access (___syscall33) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="acct"></a>acct (___syscall51) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="chdir"></a>chdir (___syscall12) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="chmod"></a>chmod (___syscall15) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="chown"></a>chown (___syscall212) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="clock_nanosleep"></a>clock_nanosleep (___syscall265) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="close"></a>close (___syscall6) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="dup"></a>dup (___syscall330) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="dup"></a>dup (___syscall41) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="dup"></a>dup (___syscall63) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="exit"></a>exit (___syscall1) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
fn exit(status: c_int)
```
- <a name="faccessat"></a>faccessat (___syscall307) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fadvise"></a>fadvise (___syscall272) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fallocate"></a>fallocate (___syscall324) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fchdir"></a>fchdir (___syscall133) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fchmod"></a>fchmod (___syscall94) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fchmodat"></a>fchmodat (___syscall306) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fchown"></a>fchown (___syscall207) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fchownat"></a>fchownat (___syscall298) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fcntl"></a>fcntl (___syscall221) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fdatasync"></a>fdatasync (___syscall148) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fstatat"></a>fstatat (___syscall300) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fstatfs"></a>fstatfs (___syscall269) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="fsync"></a>fsync (___syscall118) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="ftruncate"></a>ftruncate (___syscall194) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="futimesat"></a>futimesat (___syscall299) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getcwd"></a>getcwd (___syscall183) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getgid"></a>getgid (___syscall202) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getgroups"></a>getgroups (___syscall205) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getpgid"></a>getpgid (___syscall132) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getpgrp"></a>getpgrp (___syscall65) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getpid"></a>getpid (___syscall20) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getppid"></a>getppid (___syscall64) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getpriority"></a>getpriority (___syscall96) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getresgid"></a>getresgid (___syscall211) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getrusage"></a>getrusage (___syscall77) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="getsid"></a>getsid (___syscall147) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="ioctl"></a>ioctl (___syscall54) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="lchown"></a>lchown (___syscall198) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="link"></a>link (___syscall9) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="linkat"></a>linkat (___syscall303) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="llseek"></a>llseek (___syscall140) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="madvise"></a>madvise (___syscall219) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="mincore"></a>mincore (___syscall218) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="mkdir"></a>mkdir (___syscall39) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="mkdirat"></a>mkdirat (___syscall296) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="mknod"></a>mknod (___syscall14) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="mknodat"></a>mknodat (___syscall297) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="mmap"></a>mmap (___syscall192) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="mprotect"></a>mprotect (___syscall125) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="mremap"></a>mremap (___syscall163) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="msync"></a>msync (___syscall144) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="munlockall"></a>munlockall (___syscall153) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="munmap"></a>munmap (___syscall91) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="newselect"></a>newselect (___syscall142) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="nice"></a>nice (___syscall34) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="open"></a>open (___syscall5) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
fn open(path: *const c_char, oflag: c_int, ...) -> c_int
```
- <a name="openat"></a>openat (___syscall295) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="pause"></a>pause (___syscall29) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="pipe"></a>pipe (___syscall331) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="pipe"></a>pipe (___syscall42) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="poll"></a>poll (___syscall168) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="pread"></a>pread (___syscall180) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="preadv"></a>preadv (___syscall333) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="prlimit"></a>prlimit (___syscall340) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="pselect"></a>pselect (___syscall308) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="pwrite"></a>pwrite (___syscall181) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="pwritev"></a>pwritev (___syscall334) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="read"></a>read (___syscall3) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
fn read(fd: usize, buf: *mut c_void, count: usize) -> isize
```
- <a name="readlink"></a>readlink (___syscall85) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="readlinkat"></a>readlinkat (___syscall305) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="readv"></a>readv (___syscall145) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="recvmmsg"></a>recvmmsg (___syscall337) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="rename"></a>rename (___syscall38) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="renameat"></a>renameat (___syscall302) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="rmdir"></a>rmdir (___syscall40) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="rt_sigqueueinfo"></a>rt_sigqueueinfo (___syscall178) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="sendmmsg"></a>sendmmsg (___syscall345) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="setdomainname"></a>setdomainname (___syscall121) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="setgid"></a>setgid (___syscall214) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="setitimer"></a>setitimer (___syscall104) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="setpgid"></a>setpgid (___syscall57) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="setpriority"></a>setpriority (___syscall97) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="setresgid"></a>setresgid (___syscall210) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="setrlimit"></a>setrlimit (___syscall75) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="setsid"></a>setsid (___syscall66) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="socketcall"></a>socketcall (___syscall102) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="statfs"></a>statfs (___syscall268) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="symlink"></a>symlink (___syscall83) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="symlinkat"></a>symlinkat (___syscall304) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="sync"></a>sync (___syscall36) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="truncate"></a>truncate (___syscall193) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="ugetrlimit"></a>ugetrlimit (___syscall191) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="umask"></a>umask (___syscall60) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="uname"></a>uname (___syscall122) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="unlink"></a>unlink (___syscall10) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="unlinkat"></a>unlinkat (___syscall301) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="utimensat"></a>utimensat (___syscall320) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="wait"></a>wait (___syscall114) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="write"></a>write (___syscall4) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```
- <a name="writev"></a>writev (___syscall146) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust
```

View File

@ -1,7 +0,0 @@
use crate::webassembly::Instance;
use std::process;
pub extern "C" fn abort(_code: i32, _instance: &Instance) {
process::abort();
// abort!("Aborted")
}

View File

@ -1 +0,0 @@
pub use libc::putchar;

View File

@ -1 +0,0 @@
pub mod syscalls;

View File

@ -1,25 +0,0 @@
use libc::{
c_int,
c_void,
c_char,
size_t,
ssize_t,
open,
exit,
read,
};
/// exit
pub extern "C" fn __syscall1(status: c_int) {
unsafe { exit(status); }
}
/// read
pub extern "C" fn __syscall3(fd: c_int, buf: *mut c_void, count: size_t) -> ssize_t {
unsafe { read(fd, buf, count) }
}
/// open
pub extern "C" fn __syscall5(path: *const c_char, oflag: c_int) -> c_int {
unsafe { open(path, oflag) }
}

View File

@ -1,3 +0,0 @@
mod darwin;
pub use self::darwin::syscalls::*;

View File

@ -25,7 +25,7 @@ use structopt::StructOpt;
#[macro_use]
mod macros;
pub mod common;
pub mod linkers;
pub mod apis;
pub mod sighandler;
#[cfg(test)]
mod spectests;
@ -71,12 +71,12 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> {
.map_err(|err| format!("Can't convert from wast to wasm: {:?}", err))?;
}
let import_object = linkers::generate_emscripten_env();
let import_object = apis::generate_emscripten_env();
let webassembly::ResultObject { module, instance } =
webassembly::instantiate(wasm_binary, import_object)
.map_err(|err| format!("Can't instantiate the WebAssembly module: {}", err))?;
webassembly::utils::print_instance_offsets(&instance);
// webassembly::utils::print_instance_offsets(&instance);
let func_index = instance
.start_func

View File

@ -12,7 +12,7 @@ pub fn spectest_importobject<'a, 'b>() -> ImportObject<&'a str, &'b str> {
let mut import_object = ImportObject::new();
import_object.set("spectest", "print_i32", ImportValue::Func(print_i32 as *const u8));
import_object.set("spectest", "print", ImportValue::Func(print as *const u8));
import_object.set("spectest", "global_i32", ImportValue::Func(GLOBAL_I32 as *const u8));
import_object.set("spectest", "global_i32", ImportValue::Global(GLOBAL_I32 as _));
import_object.set("spectest", "table", ImportValue::Table(vec![0; 30]));
return import_object;
}

View File

@ -112,7 +112,7 @@ where
#[derive(PartialEq, Debug)]
pub enum ImportValue {
Func(*const u8),
Global(u8),
Global(i64),
Table(Vec<usize>),
Memory(LinearMemory),
}

View File

@ -9,7 +9,7 @@
use cranelift_codegen::ir::LibCall;
use cranelift_codegen::{binemit, Context};
use cranelift_entity::EntityRef;
use cranelift_wasm::{FuncIndex, GlobalInit};
use cranelift_wasm::{FuncIndex, GlobalInit, GlobalIndex};
use cranelift_codegen::isa::TargetIsa;
use region;
use std::iter::Iterator;
@ -22,8 +22,7 @@ use super::super::common::slice::{BoundedSlice, UncheckedSlice};
use super::errors::ErrorKind;
use super::import_object::{ImportObject, ImportValue};
use super::memory::LinearMemory;
use super::module::Export;
use super::module::Module;
use super::module::{Export, ImportableExportable, Module};
use super::relocation::{Reloc, RelocSink, RelocationType};
use super::math_intrinsics;
@ -121,9 +120,9 @@ pub struct InstanceOptions {
pub isa: Box<TargetIsa>,
}
// extern fn mock_fn() -> i32 {
// return 0;
// }
extern fn mock_fn() -> i32 {
return 0;
}
impl Instance {
pub const TABLES_OFFSET: usize = 0; // 0 on 64-bit | 0 on 32-bit
@ -145,9 +144,6 @@ impl Instance {
let mut functions: Vec<Vec<u8>> = Vec::new();
let mut import_functions: Vec<*const u8> = Vec::new();
let mut imported_memories: Vec<LinearMemory> = Vec::new();
let mut imported_tables: Vec<Vec<usize>> = Vec::new();
debug!("Instance - Instantiating functions");
// Instantiate functions
{
@ -165,19 +161,19 @@ impl Instance {
for (module, field) in module.info.imported_funcs.iter() {
let imported = import_object
.get(&module.as_str(), &field.as_str());
let function = match imported {
let function: &*const u8 = match imported {
Some(ImportValue::Func(f)) => f,
None => {
// if options.mock_missing_imports {
// debug!("The import {}.{} is not provided, therefore will be mocked.", module, field);
// mock_fn as *const u8
// }
// else {
return Err(ErrorKind::LinkError(format!(
"Imported function {}.{} was not provided in the import_functions",
module, field
)));
// }
if options.mock_missing_imports {
debug!("The import {}.{} is not provided, therefore will be mocked.", module, field);
&(mock_fn as *const u8)
}
else {
return Err(ErrorKind::LinkError(format!(
"Imported function {}.{} was not provided in the import_functions",
module, field
)));
}
},
other => panic!("Expected function import, received {:?}", other)
};
@ -295,45 +291,81 @@ impl Instance {
}
}
// Looping through and getting the imported objects
for (_key, value) in import_object.map {
match value {
ImportValue::Memory(value) =>
imported_memories.push(value),
ImportValue::Table(value) =>
imported_tables.push(value),
_ => (),
debug!("Instance - Instantiating globals");
// Instantiate Globals
let globals_data = {
let globals_count = module.info.globals.len();
// Allocate the underlying memory and initialize it to zeros
let globals_data_size = globals_count * 8;
globals.resize(globals_data_size, 0);
// cast the globals slice to a slice of i64.
let globals_data = unsafe {
slice::from_raw_parts_mut(globals.as_mut_ptr() as *mut i64, globals_count)
};
for (i, global) in module.info.globals.iter().enumerate() {
let ImportableExportable {entity, import_name, ..} = global;
let value: i64 = match entity.initializer {
GlobalInit::I32Const(n) => n as _,
GlobalInit::I64Const(n) => n,
GlobalInit::F32Const(f) => f as _, // unsafe { mem::transmute(f as f64) },
GlobalInit::F64Const(f) => f as _, // unsafe { mem::transmute(f) },
GlobalInit::GlobalRef(_global_index) => {
unimplemented!("GlobalInit::GlobalRef is not yet supported")
}
GlobalInit::Import() => {
let (module_name, field_name) = import_name.as_ref().expect("Expected a import name for the global import");
let imported = import_object.get(&module_name.as_str(), &field_name.as_str());
match imported {
Some(ImportValue::Global(value)) => {
*value
},
_ => panic!("Imported global value was not provided {:?} ({}.{})", imported, module_name, field_name)
}
}
};
globals_data[i] = value;
}
}
globals_data
};
debug!("Instance - Instantiating tables");
// Instantiate tables
{
// Reserve space for tables
tables.reserve_exact(imported_tables.len() + module.info.tables.len());
// Get imported tables
for table in imported_tables {
tables.push(table);
}
tables.reserve_exact(module.info.tables.len());
// Get tables in module
for table in &module.info.tables {
let len = table.entity.size;
let mut v = Vec::with_capacity(len);
v.resize(len, 0);
tables.push(v);
let table: Vec<usize> = match table.import_name.as_ref() {
Some((module_name, field_name)) => {
let imported = import_object.get(&module_name.as_str(), &field_name.as_str());
match imported {
Some(ImportValue::Table(t)) => {
t.to_vec()
},
_ => panic!("Imported table was not provided {:?} ({}.{})", imported, module_name, field_name)
}
},
None => {
let len = table.entity.size;
let mut v = Vec::with_capacity(len);
v.resize(len, 0);
v
}
};
tables.push(table);
}
// instantiate tables
for table_element in &module.info.table_elements {
// TODO: We shouldn't assert here since we are returning a Result<Instance, ErrorKind>
assert!(
table_element.base.is_none(),
"globalvalue base not supported yet."
);
let base = 0;
let base = match table_element.base {
Some(global_index) => {
globals_data[global_index.index()] as usize
},
None => 0
};
let table = &mut tables[table_element.table_index.index()];
for (i, func_index) in table_element.elements.iter().enumerate() {
@ -343,6 +375,7 @@ impl Instance {
// let func_index = *elem_index - module.info.imported_funcs.len() as u32;
// let func_addr = functions[func_index.index()].as_ptr();
println!("TABLE LENGTH: {}", table.len());
let func_addr = get_function_addr(&func_index, &import_functions, &functions);
table[base + table_element.offset + i] = func_addr as _;
}
@ -353,12 +386,7 @@ impl Instance {
// Instantiate memories
{
// Reserve space for memories
memories.reserve_exact(imported_memories.len() + module.info.memories.len());
// Get imported memories
for memory in imported_memories {
memories.push(memory);
}
memories.reserve_exact(module.info.memories.len());
// Get memories in module
for memory in &module.info.memories {
@ -379,41 +407,6 @@ impl Instance {
}
}
debug!("Instance - Instantiating globals");
// TODO: Fix globals import
// Instantiate Globals
{
let globals_count = module.info.globals.len();
// Allocate the underlying memory and initialize it to zeros
let globals_data_size = globals_count * 8;
globals.resize(globals_data_size, 0);
// cast the globals slice to a slice of i64.
let globals_data = unsafe {
slice::from_raw_parts_mut(globals.as_mut_ptr() as *mut i64, globals_count)
};
for (i, global) in module.info.globals.iter().enumerate() {
let value: i64 = match global.entity.initializer {
GlobalInit::I32Const(n) => n as _,
GlobalInit::I64Const(n) => n,
GlobalInit::F32Const(f) => f as _, // unsafe { mem::transmute(f as f64) },
GlobalInit::F64Const(f) => f as _, // unsafe { mem::transmute(f) },
GlobalInit::GlobalRef(_global_index) => {
unimplemented!("GlobalInit::GlobalRef is not yet supported")
}
GlobalInit::Import() => {
// Right now (because there is no module/field fields on the Import
// https://github.com/CraneStation/cranelift/blob/5cabce9b58ff960534d4017fad11f2e78c72ceab/lib/wasm/src/sections_translator.rs#L90-L99 )
// It's impossible to know where to take the global from.
// This should be fixed in Cranelift itself.
unimplemented!("GlobalInit::Import is not yet supported")
}
};
globals_data[i] = value;
}
}
let start_func: Option<FuncIndex> =
module
.info
@ -484,6 +477,13 @@ impl Instance {
.as_ref()[address..address + len]
}
pub fn memory_offset_addr(&self, index: usize, offset: usize) -> *const usize {
let mem = &self.memories[index];
unsafe {
mem.mmap.as_ptr().offset(offset as isize) as *const usize
}
}
// Shows the value of a global variable.
// pub fn inspect_global(&self, global_index: GlobalIndex, ty: ir::Type) -> &[u8] {
// let offset = global_index * 8;
@ -496,6 +496,7 @@ impl Instance {
// }
}
// TODO: Needs to be moved to more appropriate place
extern "C" fn grow_memory(size: u32, memory_index: u32, instance: &mut Instance) -> i32 {
// TODO: Support for only one LinearMemory for now.
debug_assert_eq!(

View File

@ -65,6 +65,11 @@ impl LinearMemory {
self.current
}
/// Returns the maximum number of wasm pages allowed.
pub fn maximum_size(&self) -> u32 {
self.maximum.unwrap_or(65536)
}
/// Grow memory by the specified amount of pages.
///
/// Returns `None` if memory can't be grown by the specified amount

View File

@ -71,21 +71,25 @@ fn get_func_name(func_index: FuncIndex) -> ir::ExternalName {
ir::ExternalName::user(0, func_index.index() as u32)
}
/// A collection of names under which a given entity is exported.
/// A collection of names under which a given entity is imported/exported.
#[derive(Debug)]
pub struct Exportable<T> {
pub struct ImportableExportable<T> {
/// An entity.
pub entity: T,
/// Names under which the entity is exported.
pub export_names: Vec<String>,
/// Names under which the entity is imported.
pub import_name: Option<(String, String)>,
}
impl<T> Exportable<T> {
pub fn new(entity: T) -> Self {
impl<T> ImportableExportable<T> {
pub fn new(entity: T, import_name: Option<(String, String)>) -> Self {
Self {
entity,
export_names: Vec::new(),
import_name: import_name
}
}
}
@ -120,7 +124,7 @@ pub struct ModuleInfo {
pub signatures: Vec<ir::Signature>,
/// Functions, imported and local.
pub functions: PrimaryMap<FuncIndex, Exportable<SignatureIndex>>,
pub functions: PrimaryMap<FuncIndex, ImportableExportable<SignatureIndex>>,
/// Function bodies.
pub function_bodies: PrimaryMap<DefinedFuncIndex, ir::Function>,
@ -129,7 +133,7 @@ pub struct ModuleInfo {
pub imported_funcs: Vec<(String, String)>,
/// Tables as provided by `declare_table`.
pub tables: Vec<Exportable<Table>>,
pub tables: Vec<ImportableExportable<Table>>,
/// WebAssembly table initializers.
pub table_elements: Vec<TableElements>,
@ -138,13 +142,13 @@ pub struct ModuleInfo {
pub tables_base: Option<ir::GlobalValue>,
/// Memories as provided by `declare_memory`.
pub memories: Vec<Exportable<Memory>>,
pub memories: Vec<ImportableExportable<Memory>>,
/// The Cranelift global holding the base address of the globals vector.
pub globals_base: Option<ir::GlobalValue>,
/// Globals as provided by `declare_global`.
pub globals: Vec<Exportable<Global>>,
pub globals: Vec<ImportableExportable<Global>>,
/// The start function.
pub start_func: Option<FuncIndex>,
@ -154,7 +158,7 @@ pub struct ModuleInfo {
/// Exported entities
/// We use this in order to have a O(1) allocation of the exports
/// rather than iterating through the Exportable elements.
/// rather than iterating through the ImportableExportable elements.
pub exports: HashMap<String, Export>,
/// The external function declaration for implementing wasm's `current_memory`.
@ -708,7 +712,7 @@ impl<'data> ModuleEnvironment<'data> for Module {
self.info.imported_funcs.len(),
"Imported functions must be declared first"
);
self.info.functions.push(Exportable::new(sig_index));
self.info.functions.push(ImportableExportable::new(sig_index, None));
self.info
.imported_funcs
.push((String::from(module), String::from(field)));
@ -719,7 +723,7 @@ impl<'data> ModuleEnvironment<'data> for Module {
}
fn declare_func_type(&mut self, sig_index: SignatureIndex) {
self.info.functions.push(Exportable::new(sig_index));
self.info.functions.push(ImportableExportable::new(sig_index, None));
}
fn get_func_type(&self, func_index: FuncIndex) -> SignatureIndex {
@ -727,7 +731,16 @@ impl<'data> ModuleEnvironment<'data> for Module {
}
fn declare_global(&mut self, global: Global) {
self.info.globals.push(Exportable::new(global));
self.info.globals.push(ImportableExportable::new(global, None));
}
fn declare_global_import(
&mut self,
global: Global,
module: &'data str,
field: &'data str,
) {
self.info.globals.push(ImportableExportable::new(global, Some((String::from(module), String::from(field)))));
}
fn get_global(&self, global_index: GlobalIndex) -> &Global {
@ -735,7 +748,16 @@ impl<'data> ModuleEnvironment<'data> for Module {
}
fn declare_table(&mut self, table: Table) {
self.info.tables.push(Exportable::new(table));
self.info.tables.push(ImportableExportable::new(table, None));
}
fn declare_table_import(
&mut self,
table: Table,
module: &'data str,
field: &'data str,
) {
self.info.tables.push(ImportableExportable::new(table, Some((String::from(module), String::from(field)))));
}
fn declare_table_elements(
@ -745,7 +767,6 @@ impl<'data> ModuleEnvironment<'data> for Module {
offset: usize,
elements: Vec<FuncIndex>,
) {
debug_assert!(base.is_none(), "global-value offsets not supported yet");
self.info.table_elements.push(TableElements {
table_index,
base,
@ -755,7 +776,16 @@ impl<'data> ModuleEnvironment<'data> for Module {
}
fn declare_memory(&mut self, memory: Memory) {
self.info.memories.push(Exportable::new(memory));
self.info.memories.push(ImportableExportable::new(memory, None));
}
fn declare_memory_import(
&mut self,
memory: Memory,
module: &'data str,
field: &'data str,
) {
self.info.memories.push(ImportableExportable::new(memory, Some((String::from(module), String::from(field)))));
}
fn declare_data_initialization(