diff --git a/Cargo.lock b/Cargo.lock
index 8e6da6342..51d7645f8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index 3c795b0aa..1e11d8f45 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"
diff --git a/cranelift b/cranelift
new file mode 160000
index 000000000..3f6fdf952
--- /dev/null
+++ b/cranelift
@@ -0,0 +1 @@
+Subproject commit 3f6fdf952c5fe52381e8c16f5d1912972fc2d394
diff --git a/examples/em_abort.wat b/examples/em_abort.wat
new file mode 100644
index 000000000..1eb282754
--- /dev/null
+++ b/examples/em_abort.wat
@@ -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)
+ )
+)
diff --git a/examples/em_exit.wat b/examples/em_exit.wat
new file mode 100644
index 000000000..507985f35
--- /dev/null
+++ b/examples/em_exit.wat
@@ -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))
+ )
+)
diff --git a/examples/em_printf.wat b/examples/em_printf.wat
deleted file mode 100644
index 7044b9c33..000000000
--- a/examples/em_printf.wat
+++ /dev/null
@@ -1,1751 +0,0 @@
-(module
- (type $t0 (func (param i32 i32 i32) (result i32)))
- (type $t1 (func (param i32 i32 i32 i32) (result i32)))
- (type $t2 (func (param i32 i32) (result i32)))
- (type $t3 (func (param i32 i32 i32 i32 i32 i32) (result i32)))
- (type $t4 (func (result i32)))
- (type $t5 (func (param i32) (result i32)))
- (type $t6 (func (param i32)))
- (type $t7 (func (param i32 i64 i32) (result i64)))
- (import "env" "__syscall3" (func $env.__syscall3 (type $t1)))
- (import "env" "__syscall1" (func $env.__syscall1 (type $t2)))
- (import "env" "__syscall5" (func $env.__syscall5 (type $t3)))
- (func $main (export "main") (type $t4) (result i32)
- i32.const 1024
- call $f9
- drop
- i32.const 0)
- (func $f4 (type $t5) (param $p0 i32) (result i32)
- (local $l0 i32) (local $l1 i32)
- get_local $p0
- i32.load offset=76
- i32.const -1073741825
- i32.and
- i32.const 27
- i32.load
- tee_local $l1
- i32.ne
- if $I0
- get_local $p0
- i32.const 76
- i32.add
- set_local $p0
- block $B1
- loop $L2
- get_local $p0
- i32.load
- tee_local $l0
- i32.eqz
- br_if $B1
- get_local $p0
- i32.load
- get_local $l0
- i32.ne
- br_if $L2
- end
- get_local $p0
- get_local $l0
- i32.const 1073741824
- i32.or
- i32.store
- get_local $p0
- i32.load
- tee_local $l0
- if $I3
- loop $L4
- i32.const 240
- get_local $p0
- i32.const 128
- get_local $l0
- call $env.__syscall3
- i32.const -38
- i32.eq
- if $I5
- i32.const 240
- get_local $p0
- i32.const 0
- get_local $l0
- call $env.__syscall3
- drop
- end
- get_local $p0
- i32.load
- tee_local $l0
- br_if $L4
- end
- end
- get_local $l1
- i32.const 1073741824
- i32.or
- set_local $l1
- end
- get_local $p0
- get_local $l1
- i32.store
- i32.const 1
- set_local $l0
- end
- get_local $l0)
- (func $f5 (type $t6) (param $p0 i32)
- (local $l0 i32)
- get_local $p0
- i32.const 76
- i32.add
- set_local $p0
- loop $L0
- get_local $p0
- i32.load
- tee_local $l0
- get_local $p0
- i32.load
- i32.ne
- br_if $L0
- end
- get_local $p0
- i32.const 0
- i32.store
- block $B1
- get_local $l0
- i32.const 1073741824
- i32.and
- i32.eqz
- br_if $B1
- i32.const 240
- get_local $p0
- i32.const 129
- i32.const 1
- call $env.__syscall3
- i32.const -38
- i32.ne
- br_if $B1
- i32.const 240
- get_local $p0
- i32.const 1
- i32.const 1
- call $env.__syscall3
- drop
- end)
- (func $f6 (type $t5) (param $p0 i32) (result i32)
- (local $l0 i32)
- get_local $p0
- get_local $p0
- i32.load8_u offset=74
- tee_local $l0
- i32.const -1
- i32.add
- get_local $l0
- i32.or
- i32.store8 offset=74
- get_local $p0
- i32.load
- tee_local $l0
- i32.const 8
- i32.and
- i32.eqz
- if $I0
- get_local $p0
- i64.const 0
- i64.store offset=4 align=4
- get_local $p0
- get_local $p0
- i32.load offset=44
- tee_local $l0
- i32.store offset=28
- get_local $p0
- get_local $l0
- i32.store offset=20
- get_local $p0
- get_local $l0
- get_local $p0
- i32.load offset=48
- i32.add
- i32.store offset=16
- i32.const 0
- return
- end
- get_local $p0
- get_local $l0
- i32.const 32
- i32.or
- i32.store
- i32.const -1)
- (func $f7 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (result i32)
- (local $l0 i32) (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32)
- get_local $p3
- i32.load offset=76
- i32.const 0
- i32.ge_s
- if $I0
- get_local $p3
- call $f4
- i32.const 0
- i32.ne
- set_local $l3
- end
- get_local $p2
- get_local $p1
- i32.mul
- set_local $l1
- block $B1
- block $B2
- block $B3
- block $B4
- block $B5
- get_local $p3
- i32.load offset=16
- tee_local $l0
- if $I6
- get_local $l0
- get_local $p3
- i32.load offset=20
- tee_local $l4
- i32.sub
- get_local $l1
- i32.ge_u
- br_if $B5
- br $B3
- end
- i32.const 0
- set_local $l0
- get_local $p3
- call $f6
- br_if $B2
- get_local $p3
- i32.const 16
- i32.add
- i32.load
- get_local $p3
- i32.load offset=20
- tee_local $l4
- i32.sub
- get_local $l1
- i32.lt_u
- br_if $B3
- end
- block $B7 (result i32)
- block $B8
- get_local $p3
- i32.load8_s offset=75
- i32.const 0
- i32.lt_s
- br_if $B8
- get_local $p0
- get_local $l1
- i32.add
- set_local $l7
- i32.const 0
- set_local $l0
- loop $L9
- get_local $l1
- get_local $l0
- i32.add
- i32.eqz
- br_if $B8
- get_local $l7
- get_local $l0
- i32.add
- set_local $l5
- get_local $l0
- i32.const -1
- i32.add
- tee_local $l6
- set_local $l0
- get_local $l5
- i32.const -1
- i32.add
- i32.load8_u
- i32.const 10
- i32.ne
- br_if $L9
- end
- get_local $p3
- get_local $p0
- get_local $l1
- get_local $l6
- i32.add
- i32.const 1
- i32.add
- tee_local $l2
- get_local $p3
- i32.load offset=36
- call_indirect (type $t0)
- tee_local $l0
- get_local $l2
- i32.lt_u
- br_if $B2
- get_local $l7
- get_local $l6
- i32.add
- i32.const 1
- i32.add
- set_local $p0
- get_local $p3
- i32.const 20
- i32.add
- i32.load
- set_local $l4
- get_local $l6
- i32.const -1
- i32.xor
- br $B7
- end
- get_local $l1
- end
- set_local $l0
- get_local $l4
- get_local $p0
- get_local $l0
- call $f15
- drop
- get_local $p3
- i32.const 20
- i32.add
- tee_local $l5
- get_local $l5
- i32.load
- get_local $l0
- i32.add
- i32.store
- get_local $l2
- get_local $l0
- i32.add
- set_local $l0
- end
- br $B2
- end
- get_local $p3
- get_local $p0
- get_local $l1
- get_local $p3
- i32.load offset=36
- call_indirect (type $t0)
- set_local $l0
- end
- get_local $l3
- i32.eqz
- br_if $B1
- get_local $p3
- call $f5
- end
- get_local $l0
- get_local $l1
- i32.eq
- if $I10
- get_local $p2
- i32.const 0
- get_local $p1
- select
- return
- end
- get_local $l0
- get_local $p1
- i32.div_u)
- (func $f8 (type $t2) (param $p0 i32) (param $p1 i32) (result i32)
- (local $l0 i32) (local $l1 i32) (local $l2 i32)
- get_global $g0
- i32.const 16
- i32.sub
- tee_local $l1
- set_global $g0
- get_local $l1
- get_local $p1
- i32.store8 offset=15
- block $B0 (result i32)
- block $B1
- block $B2
- get_local $p0
- i32.load offset=16
- tee_local $l0
- if $I3
- get_local $p0
- i32.load offset=20
- tee_local $l2
- get_local $l0
- i32.ge_u
- br_if $B1
- br $B2
- end
- i32.const -1
- tee_local $l0
- get_local $p0
- call $f6
- br_if $B0
- drop
- get_local $p0
- i32.load offset=20
- tee_local $l2
- get_local $p0
- i32.const 16
- i32.add
- i32.load
- i32.ge_u
- br_if $B1
- end
- get_local $p1
- i32.const 255
- i32.and
- tee_local $l0
- get_local $p0
- i32.load8_s offset=75
- i32.eq
- br_if $B1
- get_local $p0
- i32.const 20
- i32.add
- get_local $l2
- i32.const 1
- i32.add
- i32.store
- get_local $l2
- get_local $p1
- i32.store8
- get_local $l1
- i32.const 16
- i32.add
- set_global $g0
- get_local $l0
- return
- end
- i32.const -1
- tee_local $l0
- get_local $p0
- get_local $l1
- i32.const 15
- i32.add
- i32.const 1
- get_local $p0
- i32.load offset=36
- call_indirect (type $t0)
- i32.const 1
- i32.ne
- br_if $B0
- drop
- get_local $l1
- i32.load8_u offset=15
- end
- set_local $l0
- get_local $l1
- i32.const 16
- i32.add
- set_global $g0
- get_local $l0)
- (func $f9 (type $t5) (param $p0 i32) (result i32)
- (local $l0 i32) (local $l1 i32) (local $l2 i32)
- i32.const 1036
- i32.load
- tee_local $l0
- i32.load offset=76
- i32.const 0
- i32.ge_s
- if $I0
- get_local $l0
- call $f4
- set_local $l1
- end
- block $B1
- block $B2
- i32.const -1
- i32.const 0
- get_local $p0
- call $f16
- tee_local $l2
- get_local $p0
- i32.const 1
- get_local $l2
- get_local $l0
- call $f7
- i32.ne
- select
- i32.const 0
- i32.ge_s
- if $I3
- block $B4
- get_local $l0
- i32.load8_u offset=75
- i32.const 10
- i32.eq
- br_if $B4
- get_local $l0
- i32.load offset=20
- tee_local $p0
- get_local $l0
- i32.load offset=16
- i32.ge_u
- br_if $B4
- get_local $l0
- i32.const 20
- i32.add
- get_local $p0
- i32.const 1
- i32.add
- i32.store
- get_local $p0
- i32.const 10
- i32.store8
- i32.const 0
- set_local $p0
- get_local $l1
- br_if $B2
- br $B1
- end
- get_local $l0
- i32.const 10
- call $f8
- i32.const 31
- i32.shr_s
- set_local $p0
- get_local $l1
- i32.eqz
- br_if $B1
- br $B2
- end
- i32.const -1
- set_local $p0
- get_local $l1
- i32.eqz
- br_if $B1
- end
- get_local $l0
- call $f5
- end
- get_local $p0)
- (func $f10 (type $t5) (param $p0 i32) (result i32)
- get_local $p0
- i32.const -4095
- i32.ge_u
- if $I0
- i32.const 31
- i32.const 0
- get_local $p0
- i32.sub
- i32.store
- i32.const -1
- set_local $p0
- end
- get_local $p0)
- (func $f11 (type $t5) (param $p0 i32) (result i32)
- i32.const 6
- get_local $p0
- i32.load offset=60
- call $env.__syscall1
- call $f10)
- (func $f12 (type $t0) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32)
- (local $l0 i32) (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32)
- get_global $g0
- i32.const 16
- i32.sub
- tee_local $l0
- set_global $g0
- get_local $l0
- get_local $p1
- i32.store offset=8
- get_local $l0
- get_local $p2
- i32.store offset=12
- get_local $l0
- get_local $p0
- i32.load offset=28
- tee_local $p1
- i32.store
- get_local $l0
- get_local $p0
- i32.load offset=20
- get_local $p1
- i32.sub
- tee_local $p1
- i32.store offset=4
- i32.const 2
- set_local $l3
- block $B0
- block $B1
- get_local $p1
- get_local $p2
- i32.add
- tee_local $l4
- i32.const 146
- get_local $p0
- i32.load offset=60
- get_local $l0
- i32.const 2
- call $env.__syscall3
- call $f10
- tee_local $l1
- i32.ne
- if $I2
- get_local $l0
- set_local $p1
- get_local $p0
- i32.const 60
- i32.add
- set_local $l6
- loop $L3
- get_local $l1
- i32.const -1
- i32.le_s
- br_if $B1
- get_local $p1
- i32.const 8
- i32.add
- get_local $p1
- get_local $l1
- get_local $p1
- i32.load offset=4
- tee_local $l5
- i32.gt_u
- tee_local $l2
- select
- tee_local $p1
- get_local $p1
- i32.load
- get_local $l1
- get_local $l5
- i32.const 0
- get_local $l2
- select
- i32.sub
- tee_local $l5
- i32.add
- i32.store
- get_local $p1
- get_local $p1
- i32.load offset=4
- get_local $l5
- i32.sub
- i32.store offset=4
- get_local $l4
- get_local $l1
- i32.sub
- set_local $l4
- i32.const 146
- get_local $l6
- i32.load
- get_local $p1
- get_local $l3
- get_local $l2
- i32.sub
- tee_local $l3
- call $env.__syscall3
- call $f10
- tee_local $l2
- set_local $l1
- get_local $l4
- get_local $l2
- i32.ne
- br_if $L3
- end
- end
- get_local $p0
- i32.const 28
- i32.add
- get_local $p0
- i32.load offset=44
- tee_local $p1
- i32.store
- get_local $p0
- i32.const 20
- i32.add
- get_local $p1
- i32.store
- get_local $p0
- get_local $p1
- get_local $p0
- i32.load offset=48
- i32.add
- i32.store offset=16
- get_local $p2
- set_local $l1
- br $B0
- end
- get_local $p0
- i64.const 0
- i64.store offset=16
- i32.const 0
- set_local $l1
- get_local $p0
- i32.const 28
- i32.add
- i32.const 0
- i32.store
- get_local $p0
- get_local $p0
- i32.load
- i32.const 32
- i32.or
- i32.store
- get_local $l3
- i32.const 2
- i32.eq
- br_if $B0
- get_local $p1
- i32.load offset=4
- set_local $p1
- get_local $l0
- i32.const 16
- i32.add
- set_global $g0
- get_local $p2
- get_local $p1
- i32.sub
- return
- end
- get_local $l0
- i32.const 16
- i32.add
- set_global $g0
- get_local $l1)
- (func $f13 (type $t0) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32)
- (local $l0 i32)
- get_global $g0
- i32.const 16
- i32.sub
- tee_local $l0
- set_global $g0
- get_local $p0
- i32.const 1
- i32.store offset=36
- block $B0
- get_local $p0
- i32.load8_u
- i32.const 64
- i32.and
- br_if $B0
- i32.const 54
- get_local $p0
- i32.load offset=60
- i32.const 21523
- get_local $l0
- i32.const 8
- i32.add
- call $env.__syscall3
- i32.eqz
- br_if $B0
- get_local $p0
- i32.const 255
- i32.store8 offset=75
- end
- get_local $p0
- get_local $p1
- get_local $p2
- call $f12
- set_local $p0
- get_local $l0
- i32.const 16
- i32.add
- set_global $g0
- get_local $p0)
- (func $f14 (type $t7) (param $p0 i32) (param $p1 i64) (param $p2 i32) (result i64)
- (local $l0 i32)
- get_global $g0
- i32.const 16
- i32.sub
- tee_local $l0
- set_global $g0
- i32.const 140
- get_local $p0
- i32.load offset=60
- get_local $p1
- i64.const 32
- i64.shr_u
- i32.wrap/i64
- get_local $p1
- i32.wrap/i64
- get_local $l0
- i32.const 8
- i32.add
- get_local $p2
- call $env.__syscall5
- call $f10
- i32.const 0
- i32.ge_s
- if $I0
- get_local $l0
- i64.load offset=8
- set_local $p1
- get_local $l0
- i32.const 16
- i32.add
- set_global $g0
- get_local $p1
- return
- end
- get_local $l0
- i64.const -1
- i64.store offset=8
- get_local $l0
- i32.const 16
- i32.add
- set_global $g0
- i64.const -1)
- (func $f15 (type $t0) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32)
- (local $l0 i32) (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32)
- block $B0
- block $B1
- block $B2
- get_local $p2
- i32.eqz
- get_local $p1
- i32.const 3
- i32.and
- i32.eqz
- i32.or
- i32.eqz
- if $I3
- get_local $p0
- set_local $l0
- block $B4
- loop $L5
- get_local $l0
- get_local $p1
- i32.load8_u
- i32.store8
- get_local $p2
- i32.const -1
- i32.add
- set_local $l1
- get_local $l0
- i32.const 1
- i32.add
- set_local $l0
- get_local $p1
- i32.const 1
- i32.add
- set_local $p1
- get_local $p2
- i32.const 1
- i32.eq
- br_if $B4
- get_local $l1
- set_local $p2
- get_local $p1
- i32.const 3
- i32.and
- br_if $L5
- end
- end
- get_local $l0
- i32.const 3
- i32.and
- i32.eqz
- br_if $B2
- br $B1
- end
- get_local $p2
- set_local $l1
- get_local $p0
- tee_local $l0
- i32.const 3
- i32.and
- br_if $B1
- end
- block $B6
- block $B7
- get_local $l1
- i32.const 16
- i32.ge_u
- if $I8
- get_local $l0
- get_local $l1
- i32.const -16
- i32.add
- tee_local $l3
- i32.const -16
- i32.and
- tee_local $l4
- i32.const 16
- i32.add
- tee_local $l5
- i32.add
- set_local $l2
- get_local $p1
- set_local $p2
- loop $L9
- get_local $l0
- get_local $p2
- i32.load
- i32.store
- get_local $l0
- i32.const 4
- i32.add
- get_local $p2
- i32.const 4
- i32.add
- i32.load
- i32.store
- get_local $l0
- i32.const 8
- i32.add
- get_local $p2
- i32.const 8
- i32.add
- i32.load
- i32.store
- get_local $l0
- i32.const 12
- i32.add
- get_local $p2
- i32.const 12
- i32.add
- i32.load
- i32.store
- get_local $l0
- i32.const 16
- i32.add
- set_local $l0
- get_local $p2
- i32.const 16
- i32.add
- set_local $p2
- get_local $l1
- i32.const -16
- i32.add
- tee_local $l1
- i32.const 15
- i32.gt_u
- br_if $L9
- end
- get_local $p1
- get_local $l5
- i32.add
- set_local $p1
- i32.const 8
- set_local $l0
- get_local $l3
- get_local $l4
- i32.sub
- tee_local $l1
- i32.const 8
- i32.and
- br_if $B7
- br $B6
- end
- get_local $l0
- set_local $l2
- i32.const 8
- set_local $l0
- get_local $l1
- i32.const 8
- i32.and
- i32.eqz
- br_if $B6
- end
- get_local $l2
- get_local $p1
- i32.load
- i32.store
- get_local $l2
- get_local $p1
- i32.load offset=4
- i32.store offset=4
- get_local $p1
- get_local $l0
- i32.add
- set_local $p1
- get_local $l2
- get_local $l0
- i32.add
- set_local $l2
- end
- block $B10
- block $B11
- block $B12
- get_local $l1
- i32.const 4
- i32.and
- i32.eqz
- if $I13
- i32.const 2
- set_local $l0
- get_local $l1
- i32.const 2
- i32.and
- br_if $B12
- br $B11
- end
- get_local $l2
- get_local $p1
- i32.load
- i32.store
- get_local $p1
- i32.const 4
- i32.add
- set_local $p1
- get_local $l2
- i32.const 4
- i32.add
- set_local $l2
- i32.const 2
- set_local $l0
- get_local $l1
- i32.const 2
- i32.and
- i32.eqz
- br_if $B11
- end
- get_local $l2
- get_local $p1
- i32.load8_u
- i32.store8
- get_local $l2
- get_local $p1
- i32.load8_u offset=1
- i32.store8 offset=1
- get_local $l2
- get_local $l0
- i32.add
- set_local $l2
- get_local $p1
- get_local $l0
- i32.add
- set_local $p1
- get_local $l1
- i32.const 1
- i32.and
- br_if $B10
- br $B0
- end
- get_local $l1
- i32.const 1
- i32.and
- i32.eqz
- br_if $B0
- end
- get_local $l2
- get_local $p1
- i32.load8_u
- i32.store8
- get_local $p0
- return
- end
- block $B14
- block $B15
- block $B16
- block $B17
- block $B18
- block $B19
- block $B20
- block $B21
- block $B22
- block $B23
- block $B24
- block $B25
- get_local $l1
- i32.const 32
- i32.lt_u
- br_if $B25
- get_local $l0
- i32.const 3
- i32.and
- tee_local $p2
- i32.const 3
- i32.eq
- br_if $B24
- get_local $p2
- i32.const 2
- i32.eq
- br_if $B23
- get_local $p2
- i32.const 1
- i32.ne
- br_if $B25
- get_local $l0
- get_local $p1
- i32.load8_u offset=1
- i32.store8 offset=1
- get_local $l0
- get_local $p1
- i32.load
- tee_local $l3
- i32.store8
- get_local $l0
- get_local $p1
- i32.load8_u offset=2
- i32.store8 offset=2
- get_local $p1
- i32.const 16
- i32.add
- set_local $p2
- get_local $l1
- i32.const -19
- i32.add
- set_local $l5
- get_local $l1
- i32.const -3
- i32.add
- set_local $l4
- get_local $l0
- i32.const 3
- i32.add
- set_local $l2
- get_local $p1
- get_local $l1
- i32.const -20
- i32.add
- i32.const -16
- i32.and
- tee_local $l6
- i32.const 19
- i32.add
- tee_local $l7
- i32.add
- set_local $p1
- loop $L26
- get_local $l2
- get_local $p2
- i32.const -12
- i32.add
- i32.load
- tee_local $l1
- i32.const 8
- i32.shl
- get_local $l3
- i32.const 24
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 4
- i32.add
- get_local $p2
- i32.const -8
- i32.add
- i32.load
- tee_local $l3
- i32.const 8
- i32.shl
- get_local $l1
- i32.const 24
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 8
- i32.add
- get_local $p2
- i32.const -4
- i32.add
- i32.load
- tee_local $l1
- i32.const 8
- i32.shl
- get_local $l3
- i32.const 24
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 12
- i32.add
- get_local $p2
- i32.load
- tee_local $l3
- i32.const 8
- i32.shl
- get_local $l1
- i32.const 24
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 16
- i32.add
- set_local $l2
- get_local $p2
- i32.const 16
- i32.add
- set_local $p2
- get_local $l4
- i32.const -16
- i32.add
- tee_local $l4
- i32.const 16
- i32.gt_u
- br_if $L26
- end
- get_local $l5
- get_local $l6
- i32.sub
- set_local $l1
- get_local $l0
- get_local $l7
- i32.add
- set_local $l0
- end
- i32.const 16
- set_local $p2
- get_local $l1
- i32.const 16
- i32.and
- br_if $B22
- br $B21
- end
- get_local $l0
- get_local $p1
- i32.load
- tee_local $l3
- i32.store8
- get_local $p1
- i32.const 16
- i32.add
- set_local $p2
- get_local $l1
- i32.const -17
- i32.add
- set_local $l5
- get_local $l1
- i32.const -1
- i32.add
- set_local $l4
- get_local $l0
- i32.const 1
- i32.add
- set_local $l2
- get_local $p1
- get_local $l1
- i32.const -20
- i32.add
- i32.const -16
- i32.and
- tee_local $l6
- i32.const 17
- i32.add
- tee_local $l7
- i32.add
- set_local $p1
- loop $L27
- get_local $l2
- get_local $p2
- i32.const -12
- i32.add
- i32.load
- tee_local $l1
- i32.const 24
- i32.shl
- get_local $l3
- i32.const 8
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 4
- i32.add
- get_local $p2
- i32.const -8
- i32.add
- i32.load
- tee_local $l3
- i32.const 24
- i32.shl
- get_local $l1
- i32.const 8
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 8
- i32.add
- get_local $p2
- i32.const -4
- i32.add
- i32.load
- tee_local $l1
- i32.const 24
- i32.shl
- get_local $l3
- i32.const 8
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 12
- i32.add
- get_local $p2
- i32.load
- tee_local $l3
- i32.const 24
- i32.shl
- get_local $l1
- i32.const 8
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 16
- i32.add
- set_local $l2
- get_local $p2
- i32.const 16
- i32.add
- set_local $p2
- get_local $l4
- i32.const -16
- i32.add
- tee_local $l4
- i32.const 18
- i32.gt_u
- br_if $L27
- end
- get_local $l0
- get_local $l7
- i32.add
- set_local $l0
- i32.const 16
- set_local $p2
- get_local $l5
- get_local $l6
- i32.sub
- tee_local $l1
- i32.const 16
- i32.and
- i32.eqz
- br_if $B21
- br $B22
- end
- get_local $l0
- get_local $p1
- i32.load
- tee_local $l3
- i32.store8
- get_local $l0
- get_local $p1
- i32.load8_u offset=1
- i32.store8 offset=1
- get_local $p1
- i32.const 16
- i32.add
- set_local $p2
- get_local $l1
- i32.const -18
- i32.add
- set_local $l5
- get_local $l1
- i32.const -2
- i32.add
- set_local $l4
- get_local $l0
- i32.const 2
- i32.add
- set_local $l2
- get_local $p1
- get_local $l1
- i32.const -20
- i32.add
- i32.const -16
- i32.and
- tee_local $l6
- i32.const 18
- i32.add
- tee_local $l7
- i32.add
- set_local $p1
- loop $L28
- get_local $l2
- get_local $p2
- i32.const -12
- i32.add
- i32.load
- tee_local $l1
- i32.const 16
- i32.shl
- get_local $l3
- i32.const 16
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 4
- i32.add
- get_local $p2
- i32.const -8
- i32.add
- i32.load
- tee_local $l3
- i32.const 16
- i32.shl
- get_local $l1
- i32.const 16
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 8
- i32.add
- get_local $p2
- i32.const -4
- i32.add
- i32.load
- tee_local $l1
- i32.const 16
- i32.shl
- get_local $l3
- i32.const 16
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 12
- i32.add
- get_local $p2
- i32.load
- tee_local $l3
- i32.const 16
- i32.shl
- get_local $l1
- i32.const 16
- i32.shr_u
- i32.or
- i32.store
- get_local $l2
- i32.const 16
- i32.add
- set_local $l2
- get_local $p2
- i32.const 16
- i32.add
- set_local $p2
- get_local $l4
- i32.const -16
- i32.add
- tee_local $l4
- i32.const 17
- i32.gt_u
- br_if $L28
- end
- get_local $l0
- get_local $l7
- i32.add
- set_local $l0
- i32.const 16
- set_local $p2
- get_local $l5
- get_local $l6
- i32.sub
- tee_local $l1
- i32.const 16
- i32.and
- i32.eqz
- br_if $B21
- end
- get_local $l0
- get_local $p1
- i32.load8_u offset=1
- i32.store8 offset=1
- get_local $l0
- get_local $p1
- i32.load8_u offset=2
- i32.store8 offset=2
- get_local $l0
- get_local $p1
- i32.load8_u offset=3
- i32.store8 offset=3
- get_local $l0
- get_local $p1
- i32.load8_u offset=4
- i32.store8 offset=4
- get_local $l0
- get_local $p1
- i32.load8_u offset=5
- i32.store8 offset=5
- get_local $l0
- get_local $p1
- i32.load8_u offset=6
- i32.store8 offset=6
- get_local $l0
- get_local $p1
- i32.load8_u offset=7
- i32.store8 offset=7
- get_local $l0
- get_local $p1
- i32.load8_u offset=8
- i32.store8 offset=8
- get_local $l0
- get_local $p1
- i32.load8_u offset=9
- i32.store8 offset=9
- get_local $l0
- get_local $p1
- i32.load8_u offset=10
- i32.store8 offset=10
- get_local $l0
- get_local $p1
- i32.load8_u offset=11
- i32.store8 offset=11
- get_local $l0
- get_local $p1
- i32.load8_u offset=12
- i32.store8 offset=12
- get_local $l0
- get_local $p1
- i32.load8_u offset=13
- i32.store8 offset=13
- get_local $l0
- get_local $p1
- i32.load8_u offset=14
- i32.store8 offset=14
- get_local $l0
- get_local $p1
- i32.load8_u
- i32.store8
- get_local $l0
- get_local $p1
- i32.load8_u offset=15
- i32.store8 offset=15
- get_local $l0
- get_local $p2
- i32.add
- set_local $l0
- get_local $p1
- get_local $p2
- i32.add
- set_local $p1
- i32.const 8
- set_local $p2
- get_local $l1
- i32.const 8
- i32.and
- i32.eqz
- br_if $B20
- br $B19
- end
- i32.const 8
- set_local $p2
- get_local $l1
- i32.const 8
- i32.and
- br_if $B19
- end
- i32.const 4
- set_local $p2
- get_local $l1
- i32.const 4
- i32.and
- br_if $B18
- br $B17
- end
- get_local $l0
- get_local $p1
- i32.load8_u
- i32.store8
- get_local $l0
- get_local $p1
- i32.load8_u offset=1
- i32.store8 offset=1
- get_local $l0
- get_local $p1
- i32.load8_u offset=2
- i32.store8 offset=2
- get_local $l0
- get_local $p1
- i32.load8_u offset=3
- i32.store8 offset=3
- get_local $l0
- get_local $p1
- i32.load8_u offset=4
- i32.store8 offset=4
- get_local $l0
- get_local $p1
- i32.load8_u offset=5
- i32.store8 offset=5
- get_local $l0
- get_local $p1
- i32.load8_u offset=6
- i32.store8 offset=6
- get_local $l0
- get_local $p1
- i32.load8_u offset=7
- i32.store8 offset=7
- get_local $l0
- get_local $p2
- i32.add
- set_local $l0
- get_local $p1
- get_local $p2
- i32.add
- set_local $p1
- i32.const 4
- set_local $p2
- get_local $l1
- i32.const 4
- i32.and
- i32.eqz
- br_if $B17
- end
- get_local $l0
- get_local $p1
- i32.load8_u
- i32.store8
- get_local $l0
- get_local $p1
- i32.load8_u offset=1
- i32.store8 offset=1
- get_local $l0
- get_local $p1
- i32.load8_u offset=2
- i32.store8 offset=2
- get_local $l0
- get_local $p1
- i32.load8_u offset=3
- i32.store8 offset=3
- get_local $l0
- get_local $p2
- i32.add
- set_local $l0
- get_local $p1
- get_local $p2
- i32.add
- set_local $p1
- i32.const 2
- set_local $p2
- get_local $l1
- i32.const 2
- i32.and
- i32.eqz
- br_if $B16
- br $B15
- end
- i32.const 2
- set_local $p2
- get_local $l1
- i32.const 2
- i32.and
- br_if $B15
- end
- get_local $l1
- i32.const 1
- i32.and
- br_if $B14
- br $B0
- end
- get_local $l0
- get_local $p1
- i32.load8_u
- i32.store8
- get_local $l0
- get_local $p1
- i32.load8_u offset=1
- i32.store8 offset=1
- get_local $l0
- get_local $p2
- i32.add
- set_local $l0
- get_local $p1
- get_local $p2
- i32.add
- set_local $p1
- get_local $l1
- i32.const 1
- i32.and
- i32.eqz
- br_if $B0
- end
- get_local $l0
- get_local $p1
- i32.load8_u
- i32.store8
- end
- get_local $p0)
- (func $f16 (type $t5) (param $p0 i32) (result i32)
- (local $l0 i32) (local $l1 i32) (local $l2 i32)
- block $B0
- block $B1
- block $B2
- get_local $p0
- tee_local $l0
- i32.const 3
- i32.and
- i32.eqz
- br_if $B2
- get_local $p0
- i32.load8_u
- i32.eqz
- br_if $B1
- get_local $p0
- i32.const 1
- i32.add
- set_local $l0
- loop $L3
- get_local $l0
- i32.const 3
- i32.and
- i32.eqz
- br_if $B2
- get_local $l0
- i32.load8_u
- set_local $l1
- get_local $l0
- i32.const 1
- i32.add
- tee_local $l2
- set_local $l0
- get_local $l1
- br_if $L3
- end
- get_local $l2
- i32.const -1
- i32.add
- get_local $p0
- i32.sub
- return
- end
- get_local $l0
- i32.const -4
- i32.add
- set_local $l0
- loop $L4
- get_local $l0
- i32.const 4
- i32.add
- tee_local $l0
- i32.load
- tee_local $l1
- i32.const -1
- i32.xor
- get_local $l1
- i32.const -16843009
- i32.add
- i32.and
- i32.const -2139062144
- i32.and
- i32.eqz
- br_if $L4
- end
- get_local $l1
- i32.const 255
- i32.and
- i32.eqz
- br_if $B0
- loop $L5
- get_local $l0
- i32.load8_u offset=1
- set_local $l1
- get_local $l0
- i32.const 1
- i32.add
- tee_local $l2
- set_local $l0
- get_local $l1
- br_if $L5
- end
- get_local $l2
- get_local $p0
- i32.sub
- return
- end
- i32.const 0
- return
- end
- get_local $l0
- get_local $p0
- i32.sub)
- (table $T0 5 5 anyfunc)
- (memory $memory (export "memory") 2)
- (global $g0 (mut i32) (i32.const 67760))
- (global $__heap_base (export "__heap_base") i32 (i32.const 67760))
- (global $__data_end (export "__data_end") i32 (i32.const 2216))
- (elem (i32.const 1) $f12 $f11 $f13 $f14)
- (data (i32.const 1024) "Hello World\00\10\04")
- (data (i32.const 1040) "\05")
- (data (i32.const 1052) "\02")
- (data (i32.const 1076) "\03\00\00\00\04\00\00\00\a8\04\00\00\00\04")
- (data (i32.const 1100) "\01")
- (data (i32.const 1115) "\0a\ff\ff\ff\ff"))
-
diff --git a/examples/em_read_file.wat b/examples/em_read_file.wat
new file mode 100644
index 000000000..7678e2519
--- /dev/null
+++ b/examples/em_read_file.wat
@@ -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
+ )
+)
diff --git a/src/apis/emscripten/README.md b/src/apis/emscripten/README.md
new file mode 100644
index 000000000..218318cbe
--- /dev/null
+++ b/src/apis/emscripten/README.md
@@ -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
+ ```
diff --git a/src/linkers/emscripten/printf.rs b/src/apis/emscripten/io.rs
similarity index 88%
rename from src/linkers/emscripten/printf.rs
rename to src/apis/emscripten/io.rs
index e8f4d902c..8e3eb7ba5 100644
--- a/src/linkers/emscripten/printf.rs
+++ b/src/apis/emscripten/io.rs
@@ -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 {
diff --git a/src/apis/emscripten/memory.rs b/src/apis/emscripten/memory.rs
new file mode 100644
index 000000000..fb59496b8
--- /dev/null
+++ b/src/apis/emscripten/memory.rs
@@ -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
+}
diff --git a/src/linkers/emscripten/mod.rs b/src/apis/emscripten/mod.rs
similarity index 53%
rename from src/linkers/emscripten/mod.rs
rename to src/apis/emscripten/mod.rs
index b269a6300..41f53ca94 100644
--- a/src/linkers/emscripten/mod.rs
+++ b/src/apis/emscripten/mod.rs
@@ -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
}
diff --git a/src/apis/emscripten/process.rs b/src/apis/emscripten/process.rs
new file mode 100644
index 000000000..0ff0badd1
--- /dev/null
+++ b/src/apis/emscripten/process.rs
@@ -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!");
+}
+
diff --git a/src/linkers/emscripten/tests/printf.wast b/src/apis/emscripten/tests/printf.wast
similarity index 100%
rename from src/linkers/emscripten/tests/printf.wast
rename to src/apis/emscripten/tests/printf.wast
diff --git a/src/linkers/emscripten/tests/putchar.wast b/src/apis/emscripten/tests/putchar.wast
similarity index 100%
rename from src/linkers/emscripten/tests/putchar.wast
rename to src/apis/emscripten/tests/putchar.wast
diff --git a/src/apis/gcc/.gitignore b/src/apis/gcc/.gitignore
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/apis/host/mod.rs b/src/apis/host/mod.rs
new file mode 100644
index 000000000..d92dd7201
--- /dev/null
+++ b/src/apis/host/mod.rs
@@ -0,0 +1,4 @@
+mod posix;
+
+// TODO: Make portable
+pub use self::posix::*;
diff --git a/src/apis/host/posix/mod.rs b/src/apis/host/posix/mod.rs
new file mode 100644
index 000000000..18ed9d0bf
--- /dev/null
+++ b/src/apis/host/posix/mod.rs
@@ -0,0 +1,3 @@
+pub mod syscalls;
+
+pub use self::syscalls::*;
diff --git a/src/apis/host/posix/syscalls.rs b/src/apis/host/posix/syscalls.rs
new file mode 100644
index 000000000..42124201e
--- /dev/null
+++ b/src/apis/host/posix/syscalls.rs
@@ -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) }
+}
+
diff --git a/src/apis/llvm/.gitignore b/src/apis/llvm/.gitignore
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/linkers/mod.rs b/src/apis/mod.rs
similarity index 82%
rename from src/linkers/mod.rs
rename to src/apis/mod.rs
index ef78d9e06..0c83d3b3f 100644
--- a/src/linkers/mod.rs
+++ b/src/apis/mod.rs
@@ -1,3 +1,5 @@
pub mod emscripten;
+pub mod host;
pub use self::emscripten::generate_emscripten_env;
+
diff --git a/src/linkers/emscripten/README.md b/src/linkers/emscripten/README.md
deleted file mode 100644
index b19c4de6c..000000000
--- a/src/linkers/emscripten/README.md
+++ /dev/null
@@ -1,389 +0,0 @@
-# HOST APIS
-
-## EMSCRIPTEN APIS
-#### PROCESS
-- SYS_fstat (___syscall197) [:top:](#host-apis)
-```rust
-```
-- abort [:top:](#host-apis)
-```rust
-fn abort()
-```
-- abort [:top:](#host-apis)
-```rust
-fn abort()
-```
-- abort [:top:](#host-apis)
-```rust
-fn abort()
-```
-- abort [:top:](#host-apis)
-```rust
-fn abort()
-```
-
-#### THREAD
-- abort [:top:](#host-apis)
-```rust
-fn abort()
-```
-- abort [:top:](#host-apis)
-```rust
-fn abort()
-```
-- abort [:top:](#host-apis)
-```rust
-fn abort()
-```
-- abort [:top:](#host-apis)
-```rust
-fn abort()
-```
-- SYS_fstat (___syscall197) [:top:](#host-apis)
-```rust
-```
-- SYS_fstat (___syscall197) [:top:](#host-apis)
-```rust
-```
-
-#### MEMORY
-- SYS_fstat (___syscall197) [:top:](#host-apis)
-```rust
-```
-- SYS_fstat (___syscall197) [:top:](#host-apis)
-```rust
-```
-- SYS_fstat (___syscall197) [:top:](#host-apis)
-```rust
-```
-
-#### TIMING
-
-- SYS_fstat (___syscall197) [:top:](#host-apis)
-```rust
-```
-
-#### STATUS
-- SYS_fstat (___syscall197) [:top:](#host-apis)
-```rust
-```
-
-## EMSCRIPTEN SYSCALLS
-- SYS_fstat (___syscall197) [:top:](#host-apis)
-```rust
-```
-- SYS_getdents (___syscall220) [:top:](#host-apis)
-```rust
-```
-- SYS_lstat (___syscall196) [:top:](#host-apis)
-```rust
-```
-- SYS_stat (___syscall195) [:top:](#host-apis)
-```rust
-```
-- 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
-```
-- 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
-```
-- 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
-```
-- 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
-```
-- 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: *const c_char, oflag: c_int, ...) -> 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: usize, buf: *mut c_void, count: usize) -> isize
-```
-- 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
-```
-- 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
-```
diff --git a/src/linkers/emscripten/abort.rs b/src/linkers/emscripten/abort.rs
deleted file mode 100644
index e2662bd19..000000000
--- a/src/linkers/emscripten/abort.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-use crate::webassembly::Instance;
-use std::process;
-
-pub extern "C" fn abort(_code: i32, _instance: &Instance) {
- process::abort();
- // abort!("Aborted")
-}
diff --git a/src/linkers/emscripten/putchar.rs b/src/linkers/emscripten/putchar.rs
deleted file mode 100644
index 20309b020..000000000
--- a/src/linkers/emscripten/putchar.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub use libc::putchar;
diff --git a/src/linkers/emscripten/syscalls/darwin/mod.rs b/src/linkers/emscripten/syscalls/darwin/mod.rs
deleted file mode 100644
index 1d7397e2f..000000000
--- a/src/linkers/emscripten/syscalls/darwin/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod syscalls;
diff --git a/src/linkers/emscripten/syscalls/darwin/syscalls.rs b/src/linkers/emscripten/syscalls/darwin/syscalls.rs
deleted file mode 100644
index dc7a64ff4..000000000
--- a/src/linkers/emscripten/syscalls/darwin/syscalls.rs
+++ /dev/null
@@ -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) }
-}
diff --git a/src/linkers/emscripten/syscalls/mod.rs b/src/linkers/emscripten/syscalls/mod.rs
deleted file mode 100644
index 8b5a6894d..000000000
--- a/src/linkers/emscripten/syscalls/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-mod darwin;
-
-pub use self::darwin::syscalls::*;
diff --git a/src/main.rs b/src/main.rs
index bb181aecf..743556f34 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -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
diff --git a/src/spectests/_common.rs b/src/spectests/_common.rs
index 0920378b5..3511b5d9a 100644
--- a/src/spectests/_common.rs
+++ b/src/spectests/_common.rs
@@ -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;
}
diff --git a/src/webassembly/import_object.rs b/src/webassembly/import_object.rs
index 7e7411d29..7d78dab59 100644
--- a/src/webassembly/import_object.rs
+++ b/src/webassembly/import_object.rs
@@ -112,7 +112,7 @@ where
#[derive(PartialEq, Debug)]
pub enum ImportValue {
Func(*const u8),
- Global(u8),
+ Global(i64),
Table(Vec),
Memory(LinearMemory),
}
diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs
index 3901988aa..99393b7a1 100644
--- a/src/webassembly/instance.rs
+++ b/src/webassembly/instance.rs
@@ -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,
}
-// 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::new();
let mut import_functions: Vec<*const u8> = Vec::new();
- let mut imported_memories: Vec = Vec::new();
- let mut imported_tables: Vec> = 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 = 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
- 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 =
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!(
diff --git a/src/webassembly/memory.rs b/src/webassembly/memory.rs
index 32600fb3e..7c6910b4a 100644
--- a/src/webassembly/memory.rs
+++ b/src/webassembly/memory.rs
@@ -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
diff --git a/src/webassembly/module.rs b/src/webassembly/module.rs
index 1b8a76c66..bd31b060b 100644
--- a/src/webassembly/module.rs
+++ b/src/webassembly/module.rs
@@ -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 {
+pub struct ImportableExportable {
/// An entity.
pub entity: T,
/// Names under which the entity is exported.
pub export_names: Vec,
+
+ /// Names under which the entity is imported.
+ pub import_name: Option<(String, String)>,
}
-impl Exportable {
- pub fn new(entity: T) -> Self {
+impl ImportableExportable {
+ 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,
/// Functions, imported and local.
- pub functions: PrimaryMap>,
+ pub functions: PrimaryMap>,
/// Function bodies.
pub function_bodies: PrimaryMap,
@@ -129,7 +133,7 @@ pub struct ModuleInfo {
pub imported_funcs: Vec<(String, String)>,
/// Tables as provided by `declare_table`.
- pub tables: Vec>,
+ pub tables: Vec>,
/// WebAssembly table initializers.
pub table_elements: Vec,
@@ -138,13 +142,13 @@ pub struct ModuleInfo {
pub tables_base: Option,
/// Memories as provided by `declare_memory`.
- pub memories: Vec>,
+ pub memories: Vec>,
/// The Cranelift global holding the base address of the globals vector.
pub globals_base: Option,
/// Globals as provided by `declare_global`.
- pub globals: Vec>,
+ pub globals: Vec>,
/// The start function.
pub start_func: Option,
@@ -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,
/// 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,
) {
- 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(