diff --git a/Cargo.lock b/Cargo.lock index a4da3f260c..b0ca905708 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,15 +92,6 @@ dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "base64" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "bencher" version = "0.1.5" @@ -284,35 +275,6 @@ dependencies = [ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "curl" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "curl-sys 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.32 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "curl-sys" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.32 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "debug_unreachable" version = "0.1.1" @@ -496,7 +458,6 @@ dependencies = [ "codespan-reporting 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "collect-mac 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "compiletest_rs 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -507,7 +468,8 @@ dependencies = [ "gluon_completion 0.8.1", "gluon_parser 0.8.1", "gluon_vm 0.8.1", - "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "little-skeptic 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -521,8 +483,9 @@ dependencies = [ "serde_derive_state 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_state 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tensile 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tensile 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-retry 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -687,7 +650,7 @@ dependencies = [ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-signal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -720,10 +683,26 @@ dependencies = [ "serde_json 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_state 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "typed-arena 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "h2" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "handlebars" version = "1.0.0-beta.4" @@ -740,6 +719,16 @@ dependencies = [ "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "http" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "httparse" version = "1.2.4" @@ -755,30 +744,34 @@ dependencies = [ [[package]] name = "hyper" -version = "0.11.27" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "indexmap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "iovec" version = "0.1.2" @@ -861,11 +854,6 @@ name = "lalrpop-util" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "lazy_static" version = "0.2.11" @@ -886,17 +874,6 @@ name = "libc" version = "0.2.42" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "libz-sys" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "little-skeptic" version = "0.15.0" @@ -914,14 +891,6 @@ dependencies = [ "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "log" version = "0.4.1" @@ -943,14 +912,6 @@ name = "memoffset" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "mime" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "mio" version = "0.6.14" @@ -1069,22 +1030,6 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "openssl-probe" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "openssl-sys" -version = "0.9.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ordered-float" version = "0.5.0" @@ -1099,11 +1044,6 @@ name = "ordermap" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "pest" version = "1.0.6" @@ -1145,11 +1085,6 @@ dependencies = [ "siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "pkg-config" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "precomputed-hash" version = "0.1.1" @@ -1301,14 +1236,6 @@ dependencies = [ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "relay" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "remove_dir_all" version = "0.5.1" @@ -1351,11 +1278,6 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "safemem" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "same-file" version = "0.1.3" @@ -1373,15 +1295,6 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "schannel" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "scoped-tls" version = "0.1.2" @@ -1483,21 +1396,11 @@ name = "siphasher" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "slab" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "slab" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "smallvec" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "smallvec" version = "0.6.1" @@ -1514,6 +1417,11 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "string" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "string_cache" version = "0.7.2" @@ -1638,11 +1546,6 @@ dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "take" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "tempdir" version = "0.3.7" @@ -1666,7 +1569,7 @@ dependencies = [ [[package]] name = "tensile" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1734,7 +1637,7 @@ dependencies = [ [[package]] name = "tokio" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1744,8 +1647,8 @@ dependencies = [ "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1760,11 +1663,11 @@ dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1782,7 +1685,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1795,23 +1698,6 @@ dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tokio-proto" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tokio-reactor" version = "0.1.1" @@ -1826,11 +1712,13 @@ dependencies = [ ] [[package]] -name = "tokio-service" -version = "0.1.0" +name = "tokio-retry" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1862,7 +1750,7 @@ dependencies = [ [[package]] name = "tokio-threadpool" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1875,7 +1763,7 @@ dependencies = [ [[package]] name = "tokio-timer" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1897,7 +1785,7 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.1.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1915,14 +1803,6 @@ name = "ucd-util" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "unicase" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "unicode-width" version = "0.1.5" @@ -1964,21 +1844,11 @@ name = "utf8-ranges" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "vcpkg" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "version_check" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "void" version = "1.0.2" @@ -2005,12 +1875,12 @@ dependencies = [ [[package]] name = "want" -version = "0.0.4" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2076,7 +1946,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" "checksum backtrace 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbdd17cd962b570302f5297aea8648d5923e22e555c2ed2d8b2e34eca646bf6d" "checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e" -"checksum base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "85415d2594767338a74a30c1d370b2f3262ec1b4ed2d7bba5b3faf4de40467d9" "checksum bencher 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7dfdb4953a096c551ce9ace855a604d702e6e62d77fac690575ae347571717f5" "checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0" "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" @@ -2100,8 +1969,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7" "checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81" "checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" -"checksum curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf20bbe084f285f215eef2165feed70d6b75ba29cad24469badb853a4a287d0" -"checksum curl-sys 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71c63a540a9ee4e15e56c3ed9b11a2f121239b9f6d7b7fe30f616e048148df9a" "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" @@ -2127,10 +1994,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum h2 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6229ac66d3392dd83288fe04defd4b353354b15bbe07820d53dda063a736afcc" "checksum handlebars 1.0.0-beta.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2703b90b4bdf8caa04f9643ff4411d0dca1be7429a48ffa2910d69362d27bcee" +"checksum http 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "4fbced8864b04c030eebcb7d0dc3a81ba5231ac559f5116a29a8ba83ecee22cd" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" -"checksum hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)" = "34a590ca09d341e94cddf8e5af0bbccde205d5fbc2fa3c09dd67c7f85cea59d7" +"checksum hyper 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bd2dbf44d0eb8b32ac0cb7b0d75c31313554dd04d6f5dd1085e150ec5383d9b8" +"checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" @@ -2138,18 +2008,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lalrpop 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ba451f7bd819b7afc99d4cf4bdcd5a4861e64955ba9680ac70df3a50625ad6cf" "checksum lalrpop-snap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "60013fd6be14317d43f47658b1440956a9ca48a9ed0257e0e0a59aac13e43a1f" "checksum lalrpop-util 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "60c6c48ba857cd700673ce88907cadcdd7e2cd7783ed02378537c5ffd4f6460c" -"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739" "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" -"checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16" "checksum little-skeptic 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d453efd0f8353af14e7f02c38f2f095764ee1cbeda7568186572aa7bbdc97005" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0b28683d0b09bbc20be1c9b3f6f24854efb1356ffcffee08ea3f6e65596e85fa" "checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe" "checksum mio-uds 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "84c7b5caa3a118a6e34dbac36504503b1e8dc5835e833306b9d6af0e05929f79" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" @@ -2163,17 +2029,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775393e285254d2f5004596d69bb8bc1149754570dcc08cf30cabeba67955e28" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" -"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.32 (registry+https://github.com/rust-lang/crates.io-index)" = "55ab11bb4f1874c116d57ff27d8bfe8252dafc567384334b7c58339ad57e0010" "checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f" "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" "checksum pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ab94faafeb93f4c5e3ce81ca0e5a779529a602ad5d09ae6d21996bfb8b6a52bf" "checksum petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8b30dc85588cd02b9b76f5e386535db546d21dc68506cff2abebee0b6445e8e4" "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998" "checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930" -"checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum pretty 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f60c0d9f6fc88ecdd245d90c1920ff76a430ab34303fc778d33b1d0a4c3bf6d3" "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" @@ -2193,16 +2055,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b" -"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum rexpect 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9f223820adfca83e60e8b577346a0f7122e313eade41d46794766d953029a9c" "checksum rpds 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d41235ae795ad106da2c4f3dbdd09537062b14a15ee4754d4c9f4eeb69b4ad8b" "checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649" "checksum rustyline 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00b06ac9c8e8e3e83b33d175d39a9f7b6c2c930c82990593719c8e48788ae2d9" -"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" -"checksum schannel 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "85fd9df495640643ad2d00443b3d78aae69802ad488debab4f1dd52fc1806ade" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee2bc909ab2d8d60dab26e8cad85b25d795b14603a0dcb627b78b9d30b6454b" @@ -2216,11 +2075,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" "checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" -"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" -"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" "checksum smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03dab98ab5ded3a8b43b2c80751194608d0b2aa0f1d46cf95d1c35e192844aa7" "checksum socket2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "06dc9f86ee48652b7c80f3d254e3b9accb67a928c562c64d10d7b016d3d98dab" +"checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970" "checksum string_cache 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8ae5fbdcafd8573e2bfc14acb54720e27bbf102376ed05d6052f7eb238b27" "checksum string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35293b05cf1494e8ddd042a7df6756bf18d07f42d234f32e71dce8a7aabb0191" "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" @@ -2235,34 +2093,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c67da57e61ebc7b7b6fff56bb34440ca3a83db037320b0507af4c10368deda7d" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" -"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11ce2fe9db64b842314052e2421ac61a73ce41b898dc8e3750398b219c5fc1e0" -"checksum tensile 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "955b462099d2a91c032803838be32ea15983ecf6e5fe43006d74dc5c2ba2871b" +"checksum tensile 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5266c43863d439bace8ad20826a141fab2d912108f5b4dfebc7c0b4f895eedc9" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" -"checksum tokio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d00555353b013e170ed8bc4e13f648a317d1fd12157dbcae13f7013f6cf29f5" +"checksum tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ee337e5f4e501fc32966fec6fe0ca0cc1c237b0b1b14a335f8bfe3c5f06e286" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" "checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" "checksum tokio-fs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76766830bbf9a2d5bfb50c95350d56a2e79e2c80f675967fff448bc615899708" "checksum tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af9eb326f64b2d6b68438e1953341e00ab3cf54de7e35d92bfc73af8555313a" -"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" "checksum tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3cedc8e5af5131dc3423ffa4f877cce78ad25259a9a62de0613735a13ebc64b" -"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" +"checksum tokio-retry 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c03755b956458582182941061def32b8123a26c98b08fc6ddcf49ae89d18f33" "checksum tokio-signal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f46863230f9a05cf52d173721ec391b9c5782a2465f593029922b8782b9ffe" "checksum tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec9b094851aadd2caf83ba3ad8e8c4ce65a42104f7b94d9e6550023f0407853f" -"checksum tokio-threadpool 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5783254b10c7c84a56f62c74766ef7e5b83d1f13053218c7cab8d3f2c826fa0e" -"checksum tokio-timer 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535fed0ccee189f3d48447587697ba3fd234b3dbbb091f0ec4613ddfec0a7c4c" +"checksum tokio-threadpool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "24ab84f574027b0e875378f31575cf175360891919e93a3490f07e76e00e4efb" +"checksum tokio-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "028b94314065b90f026a21826cffd62a4e40a92cda3e5c069cc7b02e5945f5e9" "checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a" -"checksum try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2aa4715743892880f70885373966c83d73ef1b0838a664ef0c76fffd35e7c2" +"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum typed-arena 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5934776c3ac1bea4a9d56620d6bf2d483b20d394e49581db40f187e1118ff667" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" -"checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" @@ -2270,13 +2125,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" -"checksum vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ed0f6789c8a85ca41bbc1c9d175422116a9869bd1cf31bb08e1493ecce60380" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" "checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369" -"checksum want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a05d9d966753fa4b5c8db73fcab5eed4549cfe0e1e4e66911e5564a0085c35d1" +"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/Cargo.toml b/Cargo.toml index bb1dc42702..e1c3c5bd8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,6 @@ regex = { version = "1", optional = true } compiletest_rs = { version = "0.3", optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -tokio-core = "0.1" rand = { version = "0.4", optional = true } [build-dependencies] @@ -56,14 +55,16 @@ walkdir = { version = "2", optional = true } [dev-dependencies] bencher = "0.1.2" -tensile = "0.1.0" +tensile = "0.2.0" collect-mac = "0.1.0" env_logger = "0.5.0" pretty_assertions = "0.5" futures-cpupool = "0.1.8" +tokio = "0.1.7" +tokio-retry = "0.2" -hyper = "0.11.0" -curl = "0.4.1" +hyper = "0.12.0" +http = "0.1.0" serde = "1.0.0" serde_derive = "1.0.0" @@ -115,8 +116,6 @@ name = "debug" [[test]] name = "error" [[test]] -name = "http" -[[test]] name = "io" [[test]] name = "limits" diff --git a/examples/http/http.glu b/examples/http/http.glu index 6b435f14d9..9bceac976f 100644 --- a/examples/http/http.glu +++ b/examples/http/http.glu @@ -19,6 +19,23 @@ let { HttpState } = import! examples.http.types let http_prim = import! http.prim +let status = + let code : Int -> StatusCode = id + { + ok = code 200, + bad_request = code 400, + not_found = code 404, + internal_server_error = code 500, + } + +let method = + let method : String -> Method = id + { + get = method "GET", + post = method "POST", + put = method "PUT", + } + /// Force the value to be a Handler. Necessary to make the the type inference work for /// higher-kinded types let make : Handler a -> Handler a = id @@ -73,17 +90,11 @@ let test predicate : (Request -> Bool) -> Handler () = /// Handles `Get` requests let get : Handler () = - test (\request -> - match request.method with - | Get -> True - | _ -> False) + test (\request -> request.method == method.get) /// Handles `Post` requests let post : Handler () = - test (\request -> - match request.method with - | Post -> True - | _ -> False) + test (\request -> request.method == method.post) /// Processes this handler if `uri` matches the request's uri let path uri : String -> Handler () = @@ -98,7 +109,7 @@ let get_response_body : Handler ResponseBody = make (\success failure state -> success state.response state) /// Returns `OK` with an empty body -let empty_response = { status = Ok } +let empty_response = { status = status.ok } /// Converts an `IO` into a `Handler` let io_handler action : IO a -> Handler a = @@ -125,7 +136,7 @@ let catch_error action catch : Handler a -> (String -> Handler a) -> Handler a = /// Takes a `Handler` and a `Request` tries to process the request let handle handler state : Handler Response -> HttpState -> IO Response = let not_found _ state : _ -> _ -> IO Response = - http_prim.write_response state.response (string.as_bytes "Page not found") *> wrap { status = NotFound } + http_prim.write_response state.response (string.as_bytes "Page not found") *> wrap { status = status.not_found } handler (\response _ -> wrap response) not_found state { @@ -141,6 +152,9 @@ let handle handler state : Handler Response -> HttpState -> IO Response = alternative, monad, + status, + method, + empty_response, get_request, handle, diff --git a/examples/http/main.rs b/examples/http/main.rs index d232f9026d..79cbde293c 100644 --- a/examples/http/main.rs +++ b/examples/http/main.rs @@ -14,48 +14,44 @@ extern crate gluon_vm as vm; extern crate collect_mac; extern crate env_logger; extern crate futures; +extern crate http; extern crate hyper; -extern crate tokio_core; +extern crate tokio; #[macro_use] extern crate log; -#[macro_use] -extern crate serde_derive; use std::env; use std::error::Error as StdError; use std::fmt; use std::fs::File; -use std::io::{stderr, Read, Write}; +use std::io::Read; use std::marker::PhantomData; use std::sync::{Arc, Mutex}; -use hyper::server::Service; -use hyper::{Chunk, Method, StatusCode}; +use hyper::service::Service; +use hyper::Chunk; +use hyper::Server; + +use http::StatusCode; use futures::future::Either; -use futures::sink::Sink; use futures::stream::Stream; -use futures::sync::mpsc::Sender; use futures::sync::oneshot; use futures::{future, Async, Future}; -use tokio_core::reactor::Core; - use base::types::{ArcType, Type}; use vm::{Error as VmError, ExternModule, Result as VmResult}; use gluon::import::add_extern_module; use vm::api::{ - Function, FutureResult, Getable, OpaqueValue, OwnedFunction, PushAsRef, Pushable, Userdata, - VmType, WithVM, IO, + Function, FutureResult, OpaqueValue, OwnedFunction, PushAsRef, Userdata, VmType, WithVM, IO, }; use vm::future::FutureValue; use vm::gc::{Gc, Traverseable}; -use vm::thread::{Context, RootedThread, Thread}; -use vm::Variants; +use vm::thread::{RootedThread, Thread}; -use gluon::{Compiler, VmBuilder}; +use gluon::{new_vm, Compiler}; // `Handler` is a type defined in http.glu but since we need to refer to it in the signature of // listen we define a phantom type which we can use with `OpaqueValue` to store a `Handler` in Rust @@ -72,149 +68,6 @@ impl VmType for Handler { } } -// Rust does not let us define traits on types defined in a different crate such as `hyper`. We can -// however work around this by defining a wrapper type which we are then able to define the traits -// on. -struct Wrap(T); - -macro_rules! define_vmtype { - ($name:ident, $wrapper:ident) => { - impl VmType for Wrap<$name> { - type Type = $name; - fn make_type(vm: &Thread) -> ArcType { - $wrapper::make_type(vm) - } - } - - impl VmType for $wrapper { - type Type = $name; - fn make_type(vm: &Thread) -> ArcType { - use gluon::base::types::Alias; - - // If we have already created $name then return it immediately - if let Some(typ) = vm.get_type::<$name>() { - return typ; - } - - // Otherwise construct the type using the `Deserialize` impl for the type - let (name, typ) = gluon::vm::api::typ::from_rust::(vm).unwrap(); - vm.register_type_as( - name.clone(), - Alias::new(name, typ), - ::std::any::TypeId::of::<$name>(), - ).unwrap() - } - } - }; -} - -// This type, and the `StatusCode` type below are defined in hyper so we can't implement any traits -// on them. Instead we use serde's remote derive support to workaround it. -#[derive(Serialize, Deserialize)] -#[serde(remote = "Method")] -#[serde(rename = "Method")] -pub enum RemoteMethod { - Options, - Get, - Post, - Put, - Delete, - Head, - Trace, - Connect, - Patch, - Extension(String), -} -#[derive(Serialize, Deserialize)] -struct RemoteMethodContainer(#[serde(with = "RemoteMethod")] Method); - -define_vmtype! { Method, RemoteMethodContainer } - -impl<'vm> Pushable<'vm> for Wrap { - fn push(self, vm: &'vm Thread, context: &mut Context) -> VmResult<()> { - use gluon::vm::api::ser::Ser; - Ser(RemoteMethodContainer(self.0)).push(vm, context) - } -} - -#[derive(Serialize, Deserialize)] -#[serde(remote = "StatusCode")] -#[serde(rename = "StatusCode")] -pub enum RemoteStatusCode { - Continue, - SwitchingProtocols, - Processing, - Ok, - Created, - Accepted, - NonAuthoritativeInformation, - NoContent, - ResetContent, - PartialContent, - MultiStatus, - AlreadyReported, - ImUsed, - MultipleChoices, - MovedPermanently, - Found, - SeeOther, - NotModified, - UseProxy, - TemporaryRedirect, - PermanentRedirect, - BadRequest, - Unauthorized, - PaymentRequired, - Forbidden, - NotFound, - MethodNotAllowed, - NotAcceptable, - ProxyAuthenticationRequired, - RequestTimeout, - Conflict, - Gone, - LengthRequired, - PreconditionFailed, - PayloadTooLarge, - UriTooLong, - UnsupportedMediaType, - RangeNotSatisfiable, - ExpectationFailed, - ImATeapot, - MisdirectedRequest, - UnprocessableEntity, - Locked, - FailedDependency, - UpgradeRequired, - PreconditionRequired, - TooManyRequests, - RequestHeaderFieldsTooLarge, - UnavailableForLegalReasons, - InternalServerError, - NotImplemented, - BadGateway, - ServiceUnavailable, - GatewayTimeout, - HttpVersionNotSupported, - VariantAlsoNegotiates, - InsufficientStorage, - LoopDetected, - NotExtended, - NetworkAuthenticationRequired, - Unregistered(u16), -} -#[derive(Serialize, Deserialize)] -struct StatusCodeContainer(#[serde(with = "RemoteStatusCode")] StatusCode); - -define_vmtype! { StatusCode, StatusCodeContainer } - -impl<'vm, 'value> Getable<'vm, 'value> for Wrap { - fn from_value(vm: &'vm Thread, value: Variants<'value>) -> Self { - use gluon::vm::api::de::De; - Wrap((De::::from_value(vm, value).0).0) - } -} - // Representation of a http body that is in the prograss of being read pub struct Body(Arc, Error = VmError> + Send>>>); @@ -264,7 +117,7 @@ fn read_chunk( } // A http body that is being written -pub struct ResponseBody(Arc>>>>); +pub struct ResponseBody(Arc>>); impl fmt::Debug for ResponseBody { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -287,10 +140,9 @@ fn write_response( bytes: &[u8], ) -> FutureResult, Error = VmError> + Send + 'static>> { use futures::future::poll_fn; - use futures::AsyncSink; // Turn `bytes´ into a `Chunk` which can be sent to the http body - let mut unsent_chunk = Some(Ok(bytes.to_owned().into())); + let mut unsent_chunk = Some(bytes.to_owned().into()); let response = response.0.clone(); FutureResult(Box::new(poll_fn(move || { info!("Starting response send"); @@ -298,24 +150,26 @@ fn write_response( let sender = sender .as_mut() .expect("Sender has been dropped while still in use"); - if let Some(chunk) = unsent_chunk.take() { - match sender.start_send(chunk) { - Ok(AsyncSink::NotReady(chunk)) => { - unsent_chunk = Some(chunk); - return Ok(Async::NotReady); - } - Ok(AsyncSink::Ready) => (), - Err(_) => { - info!("Could not send http response"); - return Ok(Async::Ready(IO::Value(()))); - } + let chunk = unsent_chunk + .take() + .expect("Attempt to poll after chunk is sent"); + match sender.poll_ready() { + Ok(Async::NotReady) => { + unsent_chunk = Some(chunk); + return Ok(Async::NotReady); } - } - match sender.poll_complete() { - Ok(async) => Ok(async.map(IO::Value)), + Ok(Async::Ready(_)) => (), Err(_) => { info!("Could not send http response"); - Ok(Async::Ready(IO::Value(()))) + return Ok(Async::Ready(IO::Value(()))); + } + } + match sender.send_data(chunk) { + Ok(()) => Ok(Async::Ready(IO::Value(()))), + Err(chunk) => { + info!("Could not send http response"); + unsent_chunk = Some(chunk); + Ok(Async::NotReady) } } }))) @@ -326,13 +180,13 @@ fn write_response( field_decl! { method, uri, status, body, request, response } type Request = record_type!{ - method => Wrap, + method => String, uri => String, body => Body }; type Response = record_type!{ - status => Wrap + status => u16 }; type HttpState = record_type!{ @@ -349,8 +203,6 @@ fn listen( vm: thread, } = value; - use hyper::server::{Http, Request as HyperRequest, Response as HyperResponse}; - let thread = match thread.new_thread() { Ok(thread) => thread, Err(err) => return FutureResult(Either::A(future::err(err))), @@ -369,25 +221,24 @@ fn listen( } impl Service for Listen { - type Request = HyperRequest; - type Response = HyperResponse; + type ReqBody = hyper::Body; + type ResBody = hyper::Body; type Error = hyper::Error; - type Future = Box + Send + 'static>; + type Future = + Box, Error = hyper::Error> + Send + 'static>; - fn call(&self, request: HyperRequest) -> Self::Future { + fn call(&mut self, request: http::Request) -> Self::Future { let gluon_request = record_no_decl! { - // Here we use to `Wrap` type to make `hyper::Request` into a type that can be - // pushed to gluon - method => Wrap(request.method().clone()), + method => request.method().as_str().to_owned(), uri => request.uri().to_string(), // Since `Body` implements `Userdata` it can be directly pushed to gluon - body => Body(Arc::new(Mutex::new(Box::new(request.body() + body => Body(Arc::new(Mutex::new(Box::new(request.into_body() .map_err(|err| VmError::Message(format!("{}", err))) // `PushAsRef` makes the `body` parameter act as a `&[u8]` which means it is // marshalled to `Array Byte` in gluon .map(PushAsRef::<_, [u8]>::new))))) }; - let (response_sender, response_body) = hyper::Body::pair(); + let (response_sender, response_body) = hyper::Body::channel(); let response_sender = Arc::new(Mutex::new(Some(response_sender))); let http_state = record_no_decl!{ request => gluon_request, @@ -405,24 +256,29 @@ fn listen( // Drop the sender to so that it the receiver stops waiting for // more chunks *response_sender.lock().unwrap() = None; + + let status = StatusCode::from_u16(status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR); Ok( - HyperResponse::new() - .with_status(status.0) - .with_body(response_body), + http::Response::builder() + .status(status) + .body(response_body).unwrap(), ) } IO::Exception(err) => { - let _ = stderr().write(err.as_bytes()); + eprintln!("{}", err); Ok( - HyperResponse::new() - .with_status(StatusCode::InternalServerError), + http::Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR).body("".into()).unwrap() ) } } } Err(err) => { - let _ = stderr().write(format!("{}", err).as_bytes()); - Ok(HyperResponse::new().with_status(StatusCode::InternalServerError)) + eprintln!("{}", err); + Ok(http::Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body("".into()) + .unwrap()) } }), ) @@ -432,26 +288,19 @@ fn listen( let addr = format!("127.0.0.1:{}", port).parse().unwrap(); let (sender, receiver) = oneshot::channel(); - thread - .get_event_loop() - .expect("event loop") - .spawn(move |h| { - let h = h.clone(); - future::result(Http::new().serve_addr_handle(&addr, &h, move || { + tokio::spawn( + Server::bind(&addr) + .serve(move || -> Result<_, hyper::Error> { Ok(Listen { handle: handle.clone(), handler: handler.clone(), }) - })).flatten_stream() - .for_each(move |con| { - h.spawn(con.map(|_| ()).map_err(|err| error!("{}", err))); - Ok(()) - }) - .map_err(|err| { - error!("{}", err); - }) - .and_then(|_| sender.send(IO::Value(())).map_err(|_| ())) - }); + }) + .map_err(|err| { + error!("{}", err); + }) + .and_then(|_| sender.send(IO::Value(())).map_err(|_| ())), + ); FutureResult(Either::B( receiver.map_err(|err| vm::Error::from(format!("Server error: {}", err))), )) @@ -469,8 +318,8 @@ pub fn load_types(vm: &Thread) -> VmResult { // Define the types so that they can be used from gluon type Body => Body, type ResponseBody => ResponseBody, - type Method => Wrap, - type StatusCode => Wrap, + type Method => String, + type StatusCode => u16, type Request => Request, type Response => Response, type HttpState => HttpState @@ -497,21 +346,19 @@ fn main() { .map(|port| port.parse::().expect("port")) .unwrap_or(80); - let mut core = Core::new().unwrap(); - - let thread = VmBuilder::new().event_loop(Some(core.remote())).build(); - let result = core.run(start(&thread, port)); - if let Err(err) = result { - panic!("{}", err) - } + let thread = new_vm(); + tokio::run(start(&thread, port).map_err(|err| panic!("{}", err))); } -fn start(thread: &Thread, port: u16) -> impl Future> { +fn start( + thread: &Thread, + port: u16, +) -> impl Future> { add_extern_module(&thread, "http.prim_types", load_types); add_extern_module(&thread, "http.prim", load); let thread = thread.root_thread(); - future::lazy(|| -> Result<_, Box> { + future::lazy(|| -> Result<_, Box> { // Last we run our `http_server.glu` module which returns a function which starts listening // on the port we passed from the command line let mut expr = String::new(); @@ -540,51 +387,69 @@ fn start(thread: &Thread, port: u16) -> impl Future (wrap { status = Ok }) + *> (wrap { status = status.ok }) let echo_body request : Request -> Handler () = do chunk = io_handler (read_chunk request.body) @@ -35,11 +39,11 @@ let echo_body request : Request -> Handler () = let echo : Handler Response = (get_request >>= echo_body) - *> wrap { status = Ok } + *> wrap { status = status.ok } let handler = (get *> path "/" *> hello_world) <|> (post *> path "/echo" *> echo) - <|> (get *> path "/error" *> (wrap { status = InternalServerError })) + <|> (get *> path "/error" *> (wrap { status = status.internal_server_error })) let print_error h = catch_error h (\msg -> io_handler (io.println msg)) diff --git a/repl/Cargo.toml b/repl/Cargo.toml index 4ec046c5c6..26d0c647ed 100644 --- a/repl/Cargo.toml +++ b/repl/Cargo.toml @@ -25,7 +25,7 @@ gluon_doc = { version = "0.8.1", path = "../doc" } # GLUON app_dirs = "1.0.0" futures = "0.1.11" futures-cpupool = "0.1" -tokio-core = "0.1" +tokio = "0.1" tokio-signal = "0.1" clap = "2.22.0" structopt = "0.2" diff --git a/repl/src/main.rs b/repl/src/main.rs index a05a2e81c4..e4af07ce90 100644 --- a/repl/src/main.rs +++ b/repl/src/main.rs @@ -15,7 +15,7 @@ extern crate log; extern crate serde_derive; #[macro_use] extern crate structopt; -extern crate tokio_core; +extern crate tokio; extern crate tokio_signal; extern crate walkdir; @@ -111,7 +111,11 @@ define_vmtype! { Color } #[derive(StructOpt)] #[structopt(about = "Formats gluon source code")] pub struct FmtOpt { - #[structopt(name = "FILE", parse(from_os_str), help = "Formats each file")] + #[structopt( + name = "FILE", + parse(from_os_str), + help = "Formats each file" + )] input: Vec, } @@ -126,15 +130,23 @@ pub enum SubOpt { const LONG_VERSION: &str = concat!(crate_version!(), "\n", "commit: ", env!("GIT_HASH")); #[derive(StructOpt)] -#[structopt(about = "executes gluon programs", raw(long_version = "LONG_VERSION"))] +#[structopt( + about = "executes gluon programs", + raw(long_version = "LONG_VERSION") +)] pub struct Opt { #[structopt(short = "i", long = "interactive", help = "Starts the repl")] interactive: bool, #[structopt( - long = "color", default_value = "auto", help = "Coloring: auto, always, always-ansi, never" + long = "color", + default_value = "auto", + help = "Coloring: auto, always, always-ansi, never" )] color: Color, - #[structopt(name = "FILE", help = "Executes each file as a gluon program")] + #[structopt( + name = "FILE", + help = "Executes each file as a gluon program" + )] input: Vec, #[structopt(subcommand)] subcommand_opt: Option, diff --git a/repl/src/repl.rs b/repl/src/repl.rs index 44ac9e5aed..dfb5f98ca6 100644 --- a/repl/src/repl.rs +++ b/repl/src/repl.rs @@ -15,9 +15,9 @@ use base::ast::{Expr, Pattern, SpannedPattern, Typed, TypedIdent}; use base::error::InFile; use base::kind::Kind; use base::pos; +use base::resolve; use base::symbol::{Symbol, SymbolModule}; use base::types::ArcType; -use base::resolve; use parser::{parse_partial_repl_line, ReplLine}; use vm::api::de::De; use vm::api::generic::A; @@ -39,6 +39,15 @@ use codespan_reporting::termcolor; use Color; +macro_rules! try_future { + ($e:expr, $f:expr) => { + match $e { + Ok(ok) => ok, + Err(err) => return $f(futures::future::err(err.into())), + } + }; +} + fn type_of_expr(args: WithVM) -> IO> { let WithVM { vm, value: args } = args; let mut compiler = Compiler::new(); @@ -157,17 +166,17 @@ impl rustyline::completion::Completer for Completer { macro_rules! impl_userdata { ($name:ident) => { impl ::gluon::vm::api::Userdata for $name {} - + impl ::std::fmt::Debug for $name { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, concat!(stringify!($name), "(..)")) } } - + impl ::gluon::vm::api::VmType for $name { type Type = Self; } - + impl ::gluon::vm::gc::Traverseable for $name { fn traverse(&self, _: &mut ::gluon::vm::gc::Gc) {} } @@ -307,12 +316,13 @@ fn eval_line_( // so rewrite `let f x y = ` into `let f x y = in f` // and `let { x } = ` into `let repl_temp @ { x } = in repl_temp` let id = match unpack_pattern.value { - Pattern::Ident(ref id) if !let_binding.args.is_empty() => { - id.clone() - } + Pattern::Ident(ref id) if !let_binding.args.is_empty() => id.clone(), _ => { let id = Symbol::from("repl_temp"); - let_binding.name = pos::spanned(let_binding.name.span, Pattern::As(id.clone(), Box::new(let_binding.name))); + let_binding.name = pos::spanned( + let_binding.name.span, + Pattern::As(id.clone(), Box::new(let_binding.name)), + ); TypedIdent::new(id) } }; @@ -325,7 +335,8 @@ fn eval_line_( FutureValue::sync({ // Hack to get around borrow-checker. Method-chaining didn't work, // even with #[feature(nll)]. Seems like a bug - let temp = set_globals(&vm, &unpack_pattern, &value.typ, &value.value.as_ref()); + let temp = + set_globals(&vm, &unpack_pattern, &value.typ, &value.value.as_ref()); temp.and(Ok(value)) }) }) @@ -377,16 +388,22 @@ fn set_globals( let field_name: &Symbol = &pattern_field.name.value; // if the record didn't have a field with this name, // there should have already been a type error. So we can just panic here - let field_value: RootedValue<&Thread> = - value.get_field(field_name.declared_name()) - .unwrap_or_else(|| panic!( - "record doesn't have field `{}`", field_name.declared_name() - )); - let field_type = resolved_type.row_iter() + let field_value: RootedValue<&Thread> = value + .get_field(field_name.declared_name()) + .unwrap_or_else(|| { + panic!("record doesn't have field `{}`", field_name.declared_name()) + }); + let field_type = resolved_type + .row_iter() .find(|f| f.name == *field_name) - .unwrap_or_else(|| panic!( - "record type doesn't have field `{}`", field_name.declared_name() - )).typ.clone(); + .unwrap_or_else(|| { + panic!( + "record type doesn't have field `{}`", + field_name.declared_name() + ) + }) + .typ + .clone(); match pattern_field.value { Some(ref sub_pattern) => { set_globals(vm, sub_pattern, &field_type, &field_value)? @@ -533,21 +550,20 @@ fn compile_repl(compiler: &mut Compiler, vm: &Thread) -> Result<(), GluonError> } #[allow(dead_code)] -pub fn run(color: Color) -> Result<(), Box> { - let mut core = ::tokio_core::reactor::Core::new()?; - - let vm = ::gluon::VmBuilder::new() - .event_loop(Some(core.remote())) - .build(); +pub fn run(color: Color) -> impl Future> { + let vm = ::gluon::VmBuilder::new().build(); let mut compiler = Compiler::new(); - compile_repl(&mut compiler, &vm).map_err(|err| err.emit_string(compiler.code_map()).unwrap())?; + try_future!( + compile_repl(&mut compiler, &vm) + .map_err(|err| err.emit_string(compiler.code_map()).unwrap()), + Either::A + ); - let mut repl: OwnedFunction) -> IO<()>> = vm.get_global("repl")?; + let mut repl: OwnedFunction) -> IO<()>> = + try_future!(vm.get_global("repl"), Either::A); debug!("Starting repl"); - core.run(repl.call_async(Ser(color)))?; - - Ok(()) + Either::B(repl.call_async(Ser(color))) } #[cfg(test)] @@ -592,11 +608,9 @@ mod tests { .wait() .map_err(|(_, err)| err) .expect("Error evaluating let binding"); - let x: String = vm.get_global("x") - .expect("Error getting x"); + let x: String = vm.get_global("x").expect("Error getting x"); assert_eq!(x, "x"); - let y: String = vm.get_global("y") - .expect("Error getting y"); + let y: String = vm.get_global("y").expect("Error getting y"); assert_eq!(y, "y"); // pattern with field names out of order and different field types @@ -604,8 +618,7 @@ mod tests { .wait() .map_err(|(_, err)| err) .expect("Error evaluating let binding 2"); - let () = vm.get_global("y") - .expect("Error getting y"); + let () = vm.get_global("y").expect("Error getting y"); } type QueryFn = fn(&'static str) -> IO>; diff --git a/src/lib.rs b/src/lib.rs index 513184c310..0aff38ac0d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,758 +1,739 @@ -//! This crate contains contains the implementation for the gluon programming language. -//! -//! Gluon is a programming language suitable for embedding in an existing application to extend its -//! behaviour. For information about how to use this library the best resource currently is the -//! [tutorial](https://github.com/gluon-lang/gluon/blob/master/TUTORIAL.md) which contains examples -//! on how to write gluon programs as well as how to run them using this library. -#![doc(html_root_url = "https://docs.rs/gluon/0.8.1")] // # GLUON - -#[cfg(test)] -extern crate env_logger; - -extern crate codespan; -extern crate codespan_reporting; -pub extern crate either; -extern crate futures; -extern crate itertools; -#[macro_use] -extern crate log; -#[macro_use] -extern crate quick_error; -#[cfg(not(target_arch = "wasm32"))] -extern crate tokio_core; - -#[cfg(feature = "serde_derive_state")] -#[macro_use] -extern crate serde_derive_state; -#[cfg(feature = "serde")] -extern crate serde_state as serde; - -#[macro_use] -pub extern crate gluon_base as base; -pub extern crate gluon_check as check; -pub extern crate gluon_parser as parser; -#[macro_use] -pub extern crate gluon_vm as vm; - -pub mod compiler_pipeline; -pub mod import; -pub mod io; -#[cfg(all(feature = "rand", not(target_arch = "wasm32")))] -pub mod rand_bind; -#[cfg(feature = "regex")] -pub mod regex_bind; - -pub use vm::thread::{RootedThread, Thread}; - -pub use futures::Future; - -use either::Either; - -use std::env; -use std::error::Error as StdError; -use std::path::PathBuf; -use std::result::Result as StdResult; -use std::sync::Arc; - -use base::ast::{self, SpannedExpr}; -use base::error::{Errors, InFile}; -use base::filename_to_module; -use base::fnv::FnvMap; -use base::metadata::Metadata; -use base::pos::{self, BytePos, Span, Spanned}; -use base::symbol::{Symbol, SymbolModule, Symbols}; -use base::types::{ArcType, TypeCache}; - -use compiler_pipeline::*; -use import::{add_extern_module, DefaultImporter, Import}; -use vm::api::{Getable, Hole, OpaqueValue, VmType}; -use vm::compiler::CompiledModule; -use vm::future::{BoxFutureValue, FutureValue}; -use vm::macros; -use vm::thread::ThreadInternal; -use vm::Variants; - -quick_error! { - /// Error type wrapping all possible errors that can be generated from gluon - #[derive(Debug)] - pub enum Error { - /// Error found when parsing gluon code - Parse(err: InFile) { - description(err.description()) - display("{}", err) - from() - } - /// Error found when typechecking gluon code - Typecheck(err: InFile>) { - description(err.description()) - display("{}", err) - from() - } - /// Error found when performing an IO action such as loading a file - IO(err: ::std::io::Error) { - description(err.description()) - display("{}", err) - from() - } - /// Error found when executing code in the virtual machine - VM(err: ::vm::Error) { - description(err.description()) - display("{}", err) - from() - } - /// Error found when expanding macros - Macro(err: InFile) { - description(err.description()) - display("{}", err) - from() - } - Other(err: Box) { - description(err.description()) - display("{}", err) - from() - } - /// Multiple errors where found - Multiple(err: Errors) { - description(err.description()) - display("{}", err) - } - } -} - -impl From for Error { - fn from(s: String) -> Self { - Error::VM(s.into()) - } -} - -impl From>> for Error { - fn from(mut errors: Errors>) -> Error { - if errors.len() == 1 { - let err = errors.pop().unwrap(); - match err.value.downcast::() { - Ok(err) => *err, - Err(err) => Error::Other(err), - } - } else { - Error::Multiple( - errors - .into_iter() - .map(|err| match err.value.downcast::() { - Ok(err) => *err, - Err(err) => Error::Other(err), - }) - .collect(), - ) - } - } -} - -impl From> for Error { - fn from(mut errors: Errors) -> Error { - if errors.len() == 1 { - errors.pop().unwrap() - } else { - errors = errors - .into_iter() - .flat_map(|err| match err { - Error::Multiple(errors) => Either::Left(errors.into_iter()), - err => Either::Right(Some(err).into_iter()), - }) - .collect(); - - Error::Multiple(errors) - } - } -} - -impl Error { - pub fn emit_string(&self, code_map: &::codespan::CodeMap) -> ::std::io::Result { - let mut output = Vec::new(); - self.emit( - &mut ::codespan_reporting::termcolor::NoColor::new(&mut output), - code_map, - )?; - Ok(String::from_utf8(output).unwrap()) - } - - pub fn emit(&self, writer: &mut W, code_map: &::codespan::CodeMap) -> ::std::io::Result<()> - where - W: ?Sized + ::codespan_reporting::termcolor::WriteColor, - { - match *self { - Error::Parse(ref err) => err.emit(writer, code_map), - Error::Typecheck(ref err) => err.emit(writer, code_map), - Error::IO(ref err) => write!(writer, "{}", err), - Error::VM(ref err) => write!(writer, "{}", err), - Error::Macro(ref err) => err.emit(writer, code_map), - Error::Other(ref err) => write!(writer, "{}", err), - Error::Multiple(ref errors) => { - for err in errors { - err.emit(writer, code_map)?; - } - Ok(()) - } - } - } -} - -/// Type alias for results returned by gluon -pub type Result = StdResult; - -/// Type which makes parsing, typechecking and compiling an AST into bytecode -pub struct Compiler { - symbols: Symbols, - code_map: codespan::CodeMap, - index_map: FnvMap, - implicit_prelude: bool, - emit_debug_info: bool, - run_io: bool, - full_metadata: bool, -} - -impl Default for Compiler { - fn default() -> Compiler { - Compiler::new() - } -} - -macro_rules! option { - ($(#[$attr:meta])* $name: ident $set_name: ident : $typ: ty) => { - $(#[$attr])* - pub fn $name(mut self, $name: $typ) -> Self { - self.$name = $name; - self - } - - pub fn $set_name(&mut self, $name: $typ) { - self.$name = $name; - } - }; -} - -impl Compiler { - /// Creates a new compiler with default settings - pub fn new() -> Compiler { - Compiler { - symbols: Symbols::new(), - code_map: codespan::CodeMap::new(), - index_map: FnvMap::default(), - implicit_prelude: true, - emit_debug_info: true, - run_io: false, - full_metadata: false, - } - } - - option!{ - /// Sets whether the implicit prelude should be include when compiling a file using this - /// compiler (default: true) - implicit_prelude set_implicit_prelude: bool - } - - option!{ - /// Sets whether the compiler should emit debug information such as source maps and variable - /// names. - /// (default: true) - emit_debug_info set_emit_debug_info: bool - } - - option!{ - /// Sets whether `IO` expressions are evaluated. - /// (default: false) - run_io set_run_io: bool - } - - option!{ - /// Sets whether full metadata is required - /// (default: false) - full_metadata set_full_metadata: bool - } - - pub fn code_map(&self) -> &codespan::CodeMap { - &self.code_map - } - - pub fn update_filemap(&mut self, file: &str, source: S) -> Option> - where - S: Into, - { - let index_map = &mut self.index_map; - let code_map = &mut self.code_map; - index_map - .get(file) - .cloned() - .and_then(|i| code_map.update(i, source.into())) - .map(|file_map| { - index_map.insert(file.into(), file_map.span().start()); - file_map - }) - } - - pub fn get_filemap(&self, file: &str) -> Option<&Arc> { - self.index_map - .get(file) - .and_then(move |i| self.code_map.find_file(*i)) - } - - #[doc(hidden)] - pub fn add_filemap(&mut self, file: &str, source: S) -> Arc - where - S: AsRef + Into, - { - match self.get_filemap(file) { - Some(file_map) if file_map.src() == source.as_ref() => return file_map.clone(), - _ => (), - } - let file_map = self.code_map.add_filemap( - codespan::FileName::virtual_(file.to_string()), - source.into(), - ); - self.index_map.insert(file.into(), file_map.span().start()); - file_map - } - - pub fn mut_symbols(&mut self) -> &mut Symbols { - &mut self.symbols - } - - /// Parse `expr_str`, returning an expression if successful - pub fn parse_expr( - &mut self, - type_cache: &TypeCache, - file: &str, - expr_str: &str, - ) -> StdResult, InFile> { - self.parse_partial_expr(type_cache, file, expr_str) - .map_err(|(_, err)| err) - } - - /// Parse `input`, returning an expression if successful - pub fn parse_partial_expr( - &mut self, - type_cache: &TypeCache, - file: &str, - expr_str: &str, - ) -> StdResult, (Option>, InFile)> { - let map = self.add_filemap(file, expr_str); - Ok(parser::parse_partial_expr( - &mut SymbolModule::new(file.into(), &mut self.symbols), - type_cache, - &*map, - ).map_err(|(expr, err)| { - info!("Parse error: {}", err); - (expr, InFile::new(self.code_map().clone(), err)) - })?) - } - - /// Parse and typecheck `expr_str` returning the typechecked expression and type of the - /// expression - pub fn typecheck_expr( - &mut self, - vm: &Thread, - file: &str, - expr_str: &str, - expr: &mut SpannedExpr, - ) -> Result { - expr.typecheck_expected(self, vm, file, expr_str, None) - .map(|result| result.typ) - } - - pub fn typecheck_str( - &mut self, - vm: &Thread, - file: &str, - expr_str: &str, - expected_type: Option<&ArcType>, - ) -> Result<(SpannedExpr, ArcType)> { - let TypecheckValue { expr, typ, .. } = - expr_str.typecheck_expected(self, vm, file, expr_str, expected_type)?; - Ok((expr, typ)) - } - - /// Compiles `expr` into a function which can be added and run by the `vm` - pub fn compile_script( - &mut self, - vm: &Thread, - filename: &str, - expr_str: &str, - expr: &SpannedExpr, - ) -> Result { - TypecheckValue { - expr, - typ: vm.global_env().type_cache().hole(), - metadata: Default::default(), - metadata_map: Default::default(), - }.compile(self, vm, filename, expr_str, ()) - .map(|result| result.module) - } - - /// Compiles the source code `expr_str` into bytecode serialized using `serializer` - #[cfg(feature = "serialization")] - pub fn compile_to_bytecode( - &mut self, - thread: &Thread, - name: &str, - expr_str: &str, - serializer: S, - ) -> StdResult> - where - S: serde::Serializer, - S::Error: 'static, - { - compile_to(expr_str, self, &thread, name, expr_str, None, serializer) - } - - /// Loads bytecode from a `Deserializer` and stores it into the module `name`. - /// - /// `load_script` is equivalent to `compile_to_bytecode` followed by `load_bytecode` - #[cfg(feature = "serialization")] - pub fn load_bytecode<'vm, D>( - &mut self, - thread: &'vm Thread, - name: &str, - deserializer: D, - ) -> BoxFutureValue<'vm, (), Error> - where - D: serde::Deserializer<'vm> + 'vm, - D::Error: Send + Sync, - { - Precompiled(deserializer).load_script(self, thread, name, "", ()) - } - - /// Parses and typechecks `expr_str` followed by extracting metadata from the created - /// expression - pub fn extract_metadata( - &mut self, - vm: &Thread, - file: &str, - expr_str: &str, - ) -> Result<(SpannedExpr, ArcType, Metadata)> { - use check::metadata; - let (mut expr, typ) = self.typecheck_str(vm, file, expr_str, None)?; - - let (metadata, _) = metadata::metadata(&*vm.get_env(), &mut expr); - Ok((expr, typ, metadata)) - } - - /// Compiles `input` and if it is successful runs the resulting code and stores the resulting - /// value in the vm. - /// - /// If at any point the function fails the resulting error is returned and nothing is added to - /// the VM. - pub fn load_script(&mut self, vm: &Thread, filename: &str, input: &str) -> Result<()> { - self.load_script_async(vm, filename, input).wait() - } - - pub fn load_script_async<'vm>( - &mut self, - vm: &'vm Thread, - filename: &str, - input: &str, - ) -> BoxFutureValue<'vm, (), Error> { - input.load_script(self, vm, filename, input, None) - } - - /// Loads `filename` and compiles and runs its input by calling `load_script` - pub fn load_file<'vm>(&mut self, vm: &'vm Thread, filename: &str) -> Result<()> { - self.load_file_async(vm, filename).wait() - } - - pub fn load_file_async<'vm>( - &mut self, - vm: &'vm Thread, - filename: &str, - ) -> BoxFutureValue<'vm, (), Error> { - use macros::MacroExpander; - - // Use the import macro's path resolution if it exists so that we mimick the import - // macro as close as possible - let opt_macro = vm.get_macros().get("import"); - let owned_import; - let import = match opt_macro - .as_ref() - .and_then(|mac| mac.downcast_ref::()) - { - Some(import) => import, - None => { - owned_import = Import::new(DefaultImporter); - &owned_import - } - }; - let module_name = Symbol::from(format!("@{}", filename_to_module(filename))); - let mut macros = MacroExpander::new(vm); - if let Err((_, err)) = - import.load_module(self, vm, &mut macros, &module_name, Span::default()) - { - macros.errors.push(pos::spanned(Span::default(), err)); - }; - FutureValue::from(macros.finish().map_err(|err| err.into())).boxed() - } - - /// Compiles and runs the expression in `expr_str`. If successful the value from running the - /// expression is returned - /// - /// # Examples - /// - /// Import from gluon's standard library and evaluate a string - /// - /// ``` - /// # extern crate gluon; - /// # use gluon::{new_vm,Compiler}; - /// # fn main() { - /// let vm = new_vm(); - /// let (result, _) = Compiler::new() - /// .run_expr::( - /// &vm, - /// "example", - /// " let string = import! \"std/string.glu\" in string.trim \" Hello world \t\" " - /// ) - /// .unwrap(); - /// assert_eq!(result, "Hello world"); - /// # } - /// ``` - /// - pub fn run_expr<'vm, T>( - &mut self, - vm: &'vm Thread, - name: &str, - expr_str: &str, - ) -> Result<(T, ArcType)> - where - T: for<'value> Getable<'vm, 'value> + VmType + Send + 'vm, - { - let expected = T::make_type(vm); - expr_str - .run_expr(self, vm, name, expr_str, Some(&expected)) - .and_then(move |execute_value| unsafe { - FutureValue::sync(Ok(( - T::from_value(vm, Variants::new(&execute_value.value.get_value())), - execute_value.typ, - ))) - }) - .wait() - } - - /// Compiles and runs the expression in `expr_str`. If successful the value from running the - /// expression is returned - /// - /// # Examples - /// - /// Import from gluon's standard library and evaluate a string - /// - /// ``` - /// # extern crate gluon; - /// # use gluon::{new_vm,Compiler}; - /// # use gluon::base::types::Type; - /// # fn main() { - /// let vm = new_vm(); - /// let result = Compiler::new() - /// .run_expr_async::(&vm, "example", - /// " let string = import! \"std/string.glu\" in string.trim \" Hello world \t\" ") - /// .sync_or_error() - /// .unwrap(); - /// let expected = ("Hello world".to_string(), Type::string()); - /// - /// assert_eq!(result, expected); - /// } - /// ``` - /// - pub fn run_expr_async( - &mut self, - vm: &Thread, - name: &str, - expr_str: &str, - ) -> BoxFutureValue<'static, (T, ArcType), Error> - where - T: for<'vm, 'value> Getable<'vm, 'value> + VmType + Send + 'static, - { - let expected = T::make_type(&vm); - let vm = vm.root_thread(); - expr_str - .run_expr(self, vm.clone(), name, expr_str, Some(&expected)) - .and_then(move |execute_value| unsafe { - FutureValue::sync(Ok(( - T::from_value(&vm, Variants::new(&execute_value.value.get_value())), - execute_value.typ, - ))) - }) - .boxed() - } - - fn include_implicit_prelude( - &mut self, - type_cache: &TypeCache, - name: &str, - expr: &mut SpannedExpr, - ) { - use std::mem; - if name == "std.prelude" { - return; - } - - let prelude_expr = self.parse_expr(type_cache, "", PRELUDE).unwrap(); - let original_expr = mem::replace(expr, prelude_expr); - - // Set all spans in the prelude expression to -1 so that completion requests always - // skips searching the implicit prelude - use base::ast::{walk_mut_expr, walk_mut_pattern, MutVisitor, SpannedPattern}; - struct ExpandedSpans; - - impl<'a> MutVisitor<'a> for ExpandedSpans { - type Ident = Symbol; - - fn visit_expr(&mut self, e: &mut SpannedExpr) { - e.span = Span::new(u32::max_value().into(), u32::max_value().into()); - walk_mut_expr(self, e); - } - - fn visit_pattern(&mut self, p: &mut SpannedPattern) { - p.span = Span::new(u32::max_value().into(), u32::max_value().into()); - walk_mut_pattern(self, &mut p.value); - } - } - ExpandedSpans.visit_expr(expr); - - // Replace the 0 in the prelude with the actual expression - fn assign_last_body(l: &mut SpannedExpr, original_expr: SpannedExpr) { - match l.value { - ast::Expr::LetBindings(_, ref mut e) => { - assign_last_body(e, original_expr); - } - _ => *l = original_expr, - } - } - assign_last_body(expr, original_expr); - } -} - -pub const PRELUDE: &'static str = r#" -let __implicit_prelude = import! std.prelude -and { Num, Eq, Ord, Show, Functor, Applicative, Monad, Option, Bool, ? } = __implicit_prelude - -let { (+), (-), (*), (/), (==), (/=), (<), (<=), (>=), (>), (++), show, not } = __implicit_prelude - -let __implicit_bool @ { ? } = import! std.bool - -let { ? } = import! std.option - -let __implicit_float @ { ? } = import! std.float - -let __implicit_int @ { ? } = import! std.int - -let __implicit_string @ { ? } = import! std.string - -let { error } = import! std.prim - -in () -"#; - -#[derive(Default)] -pub struct VmBuilder { - #[cfg(not(target_arch = "wasm32"))] - event_loop: Option<::tokio_core::reactor::Remote>, - import_paths: Option>, -} - -impl VmBuilder { - pub fn new() -> VmBuilder { - VmBuilder::default() - } - - #[cfg(not(target_arch = "wasm32"))] - option!{ - /// Sets then event loop which threads are run on - /// (default: None) - event_loop set_event_loop: Option<::tokio_core::reactor::Remote> - } - - option!{ - /// Sets then event loop which threads are run on - /// (default: ["."]) - import_paths set_import_paths: Option> - } - - pub fn build(self) -> RootedThread { - #[cfg(target_arch = "wasm32")] - let vm = RootedThread::new(); - - #[cfg(not(target_arch = "wasm32"))] - let vm = RootedThread::with_global_state( - ::vm::vm::GlobalVmStateBuilder::new() - .event_loop(self.event_loop) - .build(), - ); - - let import = Import::new(DefaultImporter); - if let Some(import_paths) = self.import_paths { - import.set_paths(import_paths); - } - - if let Ok(gluon_path) = env::var("GLUON_PATH") { - import.add_path(gluon_path); - } - vm.get_macros().insert(String::from("import"), import); - - Compiler::new() - .implicit_prelude(false) - .run_expr::>(&vm, "", r#" import! std.types "#) - .unwrap_or_else(|err| panic!("{}", err)); - - add_extern_module(&vm, "std.prim", ::vm::primitives::load); - add_extern_module(&vm, "std.byte.prim", ::vm::primitives::load_byte); - add_extern_module(&vm, "std.int.prim", ::vm::primitives::load_int); - add_extern_module(&vm, "std.float.prim", ::vm::primitives::load_float); - add_extern_module(&vm, "std.string.prim", ::vm::primitives::load_string); - add_extern_module(&vm, "std.char.prim", ::vm::primitives::load_char); - add_extern_module(&vm, "std.array.prim", ::vm::primitives::load_array); - - add_extern_module(&vm, "std.lazy.prim", ::vm::lazy::load); - add_extern_module(&vm, "std.reference.prim", ::vm::reference::load); - - add_extern_module(&vm, "std.channel.prim", ::vm::channel::load_channel); - add_extern_module(&vm, "std.thread.prim", ::vm::channel::load_thread); - add_extern_module(&vm, "std.debug.prim", ::vm::debug::load); - add_extern_module(&vm, "std.io.prim", ::io::load); - - load_regex(&vm); - load_random(&vm); - - vm - } -} - -/// Creates a new virtual machine with support for importing other modules and with all primitives -/// loaded. -pub fn new_vm() -> RootedThread { - VmBuilder::default().build() -} - -#[cfg(feature = "regex")] -fn load_regex(vm: &Thread) { - add_extern_module(&vm, "std.regex", ::regex_bind::load); -} -#[cfg(not(feature = "regex"))] -fn load_regex(_: &Thread) {} - -#[cfg(all(feature = "rand", not(target_arch = "wasm32")))] -fn load_random(vm: &Thread) { - add_extern_module(&vm, "std.random.prim", ::rand_bind::load); -} -#[cfg(any(not(feature = "rand"), target_arch = "wasm32"))] -fn load_random(_: &Thread) {} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn implicit_prelude() { - let _ = ::env_logger::try_init(); - - let thread = new_vm(); - Compiler::new() - .implicit_prelude(false) - .run_expr::<()>(&thread, "prelude", PRELUDE) - .unwrap_or_else(|err| panic!("{}", err)); - } -} +//! This crate contains contains the implementation for the gluon programming language. +//! +//! Gluon is a programming language suitable for embedding in an existing application to extend its +//! behaviour. For information about how to use this library the best resource currently is the +//! [tutorial](https://github.com/gluon-lang/gluon/blob/master/TUTORIAL.md) which contains examples +//! on how to write gluon programs as well as how to run them using this library. +#![doc(html_root_url = "https://docs.rs/gluon/0.8.1")] // # GLUON + +#[cfg(test)] +extern crate env_logger; + +extern crate codespan; +extern crate codespan_reporting; +pub extern crate either; +extern crate futures; +extern crate itertools; +#[macro_use] +extern crate log; +#[macro_use] +extern crate quick_error; + +#[cfg(feature = "serde_derive_state")] +#[macro_use] +extern crate serde_derive_state; +#[cfg(feature = "serde")] +extern crate serde_state as serde; + +#[macro_use] +pub extern crate gluon_base as base; +pub extern crate gluon_check as check; +pub extern crate gluon_parser as parser; +#[macro_use] +pub extern crate gluon_vm as vm; + +pub mod compiler_pipeline; +pub mod import; +pub mod io; +#[cfg(all(feature = "rand", not(target_arch = "wasm32")))] +pub mod rand_bind; +#[cfg(feature = "regex")] +pub mod regex_bind; + +pub use vm::thread::{RootedThread, Thread}; + +pub use futures::Future; + +use either::Either; + +use std::env; +use std::error::Error as StdError; +use std::path::PathBuf; +use std::result::Result as StdResult; +use std::sync::Arc; + +use base::ast::{self, SpannedExpr}; +use base::error::{Errors, InFile}; +use base::filename_to_module; +use base::fnv::FnvMap; +use base::metadata::Metadata; +use base::pos::{self, BytePos, Span, Spanned}; +use base::symbol::{Symbol, SymbolModule, Symbols}; +use base::types::{ArcType, TypeCache}; + +use compiler_pipeline::*; +use import::{add_extern_module, DefaultImporter, Import}; +use vm::api::{Getable, Hole, OpaqueValue, VmType}; +use vm::compiler::CompiledModule; +use vm::future::{BoxFutureValue, FutureValue}; +use vm::macros; +use vm::thread::ThreadInternal; +use vm::Variants; + +quick_error! { + /// Error type wrapping all possible errors that can be generated from gluon + #[derive(Debug)] + pub enum Error { + /// Error found when parsing gluon code + Parse(err: InFile) { + description(err.description()) + display("{}", err) + from() + } + /// Error found when typechecking gluon code + Typecheck(err: InFile>) { + description(err.description()) + display("{}", err) + from() + } + /// Error found when performing an IO action such as loading a file + IO(err: ::std::io::Error) { + description(err.description()) + display("{}", err) + from() + } + /// Error found when executing code in the virtual machine + VM(err: ::vm::Error) { + description(err.description()) + display("{}", err) + from() + } + /// Error found when expanding macros + Macro(err: InFile) { + description(err.description()) + display("{}", err) + from() + } + Other(err: Box) { + description(err.description()) + display("{}", err) + from() + } + /// Multiple errors where found + Multiple(err: Errors) { + description(err.description()) + display("{}", err) + } + } +} + +impl From for Error { + fn from(s: String) -> Self { + Error::VM(s.into()) + } +} + +impl From>> for Error { + fn from(mut errors: Errors>) -> Error { + if errors.len() == 1 { + let err = errors.pop().unwrap(); + match err.value.downcast::() { + Ok(err) => *err, + Err(err) => Error::Other(err), + } + } else { + Error::Multiple( + errors + .into_iter() + .map(|err| match err.value.downcast::() { + Ok(err) => *err, + Err(err) => Error::Other(err), + }) + .collect(), + ) + } + } +} + +impl From> for Error { + fn from(mut errors: Errors) -> Error { + if errors.len() == 1 { + errors.pop().unwrap() + } else { + errors = errors + .into_iter() + .flat_map(|err| match err { + Error::Multiple(errors) => Either::Left(errors.into_iter()), + err => Either::Right(Some(err).into_iter()), + }) + .collect(); + + Error::Multiple(errors) + } + } +} + +impl Error { + pub fn emit_string(&self, code_map: &::codespan::CodeMap) -> ::std::io::Result { + let mut output = Vec::new(); + self.emit( + &mut ::codespan_reporting::termcolor::NoColor::new(&mut output), + code_map, + )?; + Ok(String::from_utf8(output).unwrap()) + } + + pub fn emit(&self, writer: &mut W, code_map: &::codespan::CodeMap) -> ::std::io::Result<()> + where + W: ?Sized + ::codespan_reporting::termcolor::WriteColor, + { + match *self { + Error::Parse(ref err) => err.emit(writer, code_map), + Error::Typecheck(ref err) => err.emit(writer, code_map), + Error::IO(ref err) => write!(writer, "{}", err), + Error::VM(ref err) => write!(writer, "{}", err), + Error::Macro(ref err) => err.emit(writer, code_map), + Error::Other(ref err) => write!(writer, "{}", err), + Error::Multiple(ref errors) => { + for err in errors { + err.emit(writer, code_map)?; + } + Ok(()) + } + } + } +} + +/// Type alias for results returned by gluon +pub type Result = StdResult; + +/// Type which makes parsing, typechecking and compiling an AST into bytecode +pub struct Compiler { + symbols: Symbols, + code_map: codespan::CodeMap, + index_map: FnvMap, + implicit_prelude: bool, + emit_debug_info: bool, + run_io: bool, + full_metadata: bool, +} + +impl Default for Compiler { + fn default() -> Compiler { + Compiler::new() + } +} + +macro_rules! option { + ($(#[$attr:meta])* $name: ident $set_name: ident : $typ: ty) => { + $(#[$attr])* + pub fn $name(mut self, $name: $typ) -> Self { + self.$name = $name; + self + } + + pub fn $set_name(&mut self, $name: $typ) { + self.$name = $name; + } + }; +} + +impl Compiler { + /// Creates a new compiler with default settings + pub fn new() -> Compiler { + Compiler { + symbols: Symbols::new(), + code_map: codespan::CodeMap::new(), + index_map: FnvMap::default(), + implicit_prelude: true, + emit_debug_info: true, + run_io: false, + full_metadata: false, + } + } + + option!{ + /// Sets whether the implicit prelude should be include when compiling a file using this + /// compiler (default: true) + implicit_prelude set_implicit_prelude: bool + } + + option!{ + /// Sets whether the compiler should emit debug information such as source maps and variable + /// names. + /// (default: true) + emit_debug_info set_emit_debug_info: bool + } + + option!{ + /// Sets whether `IO` expressions are evaluated. + /// (default: false) + run_io set_run_io: bool + } + + option!{ + /// Sets whether full metadata is required + /// (default: false) + full_metadata set_full_metadata: bool + } + + pub fn code_map(&self) -> &codespan::CodeMap { + &self.code_map + } + + pub fn update_filemap(&mut self, file: &str, source: S) -> Option> + where + S: Into, + { + let index_map = &mut self.index_map; + let code_map = &mut self.code_map; + index_map + .get(file) + .cloned() + .and_then(|i| code_map.update(i, source.into())) + .map(|file_map| { + index_map.insert(file.into(), file_map.span().start()); + file_map + }) + } + + pub fn get_filemap(&self, file: &str) -> Option<&Arc> { + self.index_map + .get(file) + .and_then(move |i| self.code_map.find_file(*i)) + } + + #[doc(hidden)] + pub fn add_filemap(&mut self, file: &str, source: S) -> Arc + where + S: AsRef + Into, + { + match self.get_filemap(file) { + Some(file_map) if file_map.src() == source.as_ref() => return file_map.clone(), + _ => (), + } + let file_map = self.code_map.add_filemap( + codespan::FileName::virtual_(file.to_string()), + source.into(), + ); + self.index_map.insert(file.into(), file_map.span().start()); + file_map + } + + pub fn mut_symbols(&mut self) -> &mut Symbols { + &mut self.symbols + } + + /// Parse `expr_str`, returning an expression if successful + pub fn parse_expr( + &mut self, + type_cache: &TypeCache, + file: &str, + expr_str: &str, + ) -> StdResult, InFile> { + self.parse_partial_expr(type_cache, file, expr_str) + .map_err(|(_, err)| err) + } + + /// Parse `input`, returning an expression if successful + pub fn parse_partial_expr( + &mut self, + type_cache: &TypeCache, + file: &str, + expr_str: &str, + ) -> StdResult, (Option>, InFile)> { + let map = self.add_filemap(file, expr_str); + Ok(parser::parse_partial_expr( + &mut SymbolModule::new(file.into(), &mut self.symbols), + type_cache, + &*map, + ).map_err(|(expr, err)| { + info!("Parse error: {}", err); + (expr, InFile::new(self.code_map().clone(), err)) + })?) + } + + /// Parse and typecheck `expr_str` returning the typechecked expression and type of the + /// expression + pub fn typecheck_expr( + &mut self, + vm: &Thread, + file: &str, + expr_str: &str, + expr: &mut SpannedExpr, + ) -> Result { + expr.typecheck_expected(self, vm, file, expr_str, None) + .map(|result| result.typ) + } + + pub fn typecheck_str( + &mut self, + vm: &Thread, + file: &str, + expr_str: &str, + expected_type: Option<&ArcType>, + ) -> Result<(SpannedExpr, ArcType)> { + let TypecheckValue { expr, typ, .. } = + expr_str.typecheck_expected(self, vm, file, expr_str, expected_type)?; + Ok((expr, typ)) + } + + /// Compiles `expr` into a function which can be added and run by the `vm` + pub fn compile_script( + &mut self, + vm: &Thread, + filename: &str, + expr_str: &str, + expr: &SpannedExpr, + ) -> Result { + TypecheckValue { + expr, + typ: vm.global_env().type_cache().hole(), + metadata: Default::default(), + metadata_map: Default::default(), + }.compile(self, vm, filename, expr_str, ()) + .map(|result| result.module) + } + + /// Compiles the source code `expr_str` into bytecode serialized using `serializer` + #[cfg(feature = "serialization")] + pub fn compile_to_bytecode( + &mut self, + thread: &Thread, + name: &str, + expr_str: &str, + serializer: S, + ) -> StdResult> + where + S: serde::Serializer, + S::Error: 'static, + { + compile_to(expr_str, self, &thread, name, expr_str, None, serializer) + } + + /// Loads bytecode from a `Deserializer` and stores it into the module `name`. + /// + /// `load_script` is equivalent to `compile_to_bytecode` followed by `load_bytecode` + #[cfg(feature = "serialization")] + pub fn load_bytecode<'vm, D>( + &mut self, + thread: &'vm Thread, + name: &str, + deserializer: D, + ) -> BoxFutureValue<'vm, (), Error> + where + D: serde::Deserializer<'vm> + 'vm, + D::Error: Send + Sync, + { + Precompiled(deserializer).load_script(self, thread, name, "", ()) + } + + /// Parses and typechecks `expr_str` followed by extracting metadata from the created + /// expression + pub fn extract_metadata( + &mut self, + vm: &Thread, + file: &str, + expr_str: &str, + ) -> Result<(SpannedExpr, ArcType, Metadata)> { + use check::metadata; + let (mut expr, typ) = self.typecheck_str(vm, file, expr_str, None)?; + + let (metadata, _) = metadata::metadata(&*vm.get_env(), &mut expr); + Ok((expr, typ, metadata)) + } + + /// Compiles `input` and if it is successful runs the resulting code and stores the resulting + /// value in the vm. + /// + /// If at any point the function fails the resulting error is returned and nothing is added to + /// the VM. + pub fn load_script(&mut self, vm: &Thread, filename: &str, input: &str) -> Result<()> { + self.load_script_async(vm, filename, input).wait() + } + + pub fn load_script_async<'vm>( + &mut self, + vm: &'vm Thread, + filename: &str, + input: &str, + ) -> BoxFutureValue<'vm, (), Error> { + input.load_script(self, vm, filename, input, None) + } + + /// Loads `filename` and compiles and runs its input by calling `load_script` + pub fn load_file<'vm>(&mut self, vm: &'vm Thread, filename: &str) -> Result<()> { + self.load_file_async(vm, filename).wait() + } + + pub fn load_file_async<'vm>( + &mut self, + vm: &'vm Thread, + filename: &str, + ) -> BoxFutureValue<'vm, (), Error> { + use macros::MacroExpander; + + // Use the import macro's path resolution if it exists so that we mimick the import + // macro as close as possible + let opt_macro = vm.get_macros().get("import"); + let owned_import; + let import = match opt_macro + .as_ref() + .and_then(|mac| mac.downcast_ref::()) + { + Some(import) => import, + None => { + owned_import = Import::new(DefaultImporter); + &owned_import + } + }; + let module_name = Symbol::from(format!("@{}", filename_to_module(filename))); + let mut macros = MacroExpander::new(vm); + if let Err((_, err)) = + import.load_module(self, vm, &mut macros, &module_name, Span::default()) + { + macros.errors.push(pos::spanned(Span::default(), err)); + }; + FutureValue::from(macros.finish().map_err(|err| err.into())).boxed() + } + + /// Compiles and runs the expression in `expr_str`. If successful the value from running the + /// expression is returned + /// + /// # Examples + /// + /// Import from gluon's standard library and evaluate a string + /// + /// ``` + /// # extern crate gluon; + /// # use gluon::{new_vm,Compiler}; + /// # fn main() { + /// let vm = new_vm(); + /// let (result, _) = Compiler::new() + /// .run_expr::( + /// &vm, + /// "example", + /// " let string = import! \"std/string.glu\" in string.trim \" Hello world \t\" " + /// ) + /// .unwrap(); + /// assert_eq!(result, "Hello world"); + /// # } + /// ``` + /// + pub fn run_expr<'vm, T>( + &mut self, + vm: &'vm Thread, + name: &str, + expr_str: &str, + ) -> Result<(T, ArcType)> + where + T: for<'value> Getable<'vm, 'value> + VmType + Send + 'vm, + { + let expected = T::make_type(vm); + expr_str + .run_expr(self, vm, name, expr_str, Some(&expected)) + .and_then(move |execute_value| unsafe { + FutureValue::sync(Ok(( + T::from_value(vm, Variants::new(&execute_value.value.get_value())), + execute_value.typ, + ))) + }) + .wait() + } + + /// Compiles and runs the expression in `expr_str`. If successful the value from running the + /// expression is returned + /// + /// # Examples + /// + /// Import from gluon's standard library and evaluate a string + /// + /// ``` + /// # extern crate gluon; + /// # use gluon::{new_vm,Compiler}; + /// # use gluon::base::types::Type; + /// # fn main() { + /// let vm = new_vm(); + /// let result = Compiler::new() + /// .run_expr_async::(&vm, "example", + /// " let string = import! \"std/string.glu\" in string.trim \" Hello world \t\" ") + /// .sync_or_error() + /// .unwrap(); + /// let expected = ("Hello world".to_string(), Type::string()); + /// + /// assert_eq!(result, expected); + /// } + /// ``` + /// + pub fn run_expr_async( + &mut self, + vm: &Thread, + name: &str, + expr_str: &str, + ) -> BoxFutureValue<'static, (T, ArcType), Error> + where + T: for<'vm, 'value> Getable<'vm, 'value> + VmType + Send + 'static, + { + let expected = T::make_type(&vm); + let vm = vm.root_thread(); + expr_str + .run_expr(self, vm.clone(), name, expr_str, Some(&expected)) + .and_then(move |execute_value| unsafe { + FutureValue::sync(Ok(( + T::from_value(&vm, Variants::new(&execute_value.value.get_value())), + execute_value.typ, + ))) + }) + .boxed() + } + + fn include_implicit_prelude( + &mut self, + type_cache: &TypeCache, + name: &str, + expr: &mut SpannedExpr, + ) { + use std::mem; + if name == "std.prelude" { + return; + } + + let prelude_expr = self.parse_expr(type_cache, "", PRELUDE).unwrap(); + let original_expr = mem::replace(expr, prelude_expr); + + // Set all spans in the prelude expression to -1 so that completion requests always + // skips searching the implicit prelude + use base::ast::{walk_mut_expr, walk_mut_pattern, MutVisitor, SpannedPattern}; + struct ExpandedSpans; + + impl<'a> MutVisitor<'a> for ExpandedSpans { + type Ident = Symbol; + + fn visit_expr(&mut self, e: &mut SpannedExpr) { + e.span = Span::new(u32::max_value().into(), u32::max_value().into()); + walk_mut_expr(self, e); + } + + fn visit_pattern(&mut self, p: &mut SpannedPattern) { + p.span = Span::new(u32::max_value().into(), u32::max_value().into()); + walk_mut_pattern(self, &mut p.value); + } + } + ExpandedSpans.visit_expr(expr); + + // Replace the 0 in the prelude with the actual expression + fn assign_last_body(l: &mut SpannedExpr, original_expr: SpannedExpr) { + match l.value { + ast::Expr::LetBindings(_, ref mut e) => { + assign_last_body(e, original_expr); + } + _ => *l = original_expr, + } + } + assign_last_body(expr, original_expr); + } +} + +pub const PRELUDE: &'static str = r#" +let __implicit_prelude = import! std.prelude +and { Num, Eq, Ord, Show, Functor, Applicative, Monad, Option, Bool, ? } = __implicit_prelude + +let { (+), (-), (*), (/), (==), (/=), (<), (<=), (>=), (>), (++), show, not } = __implicit_prelude + +let __implicit_bool @ { ? } = import! std.bool + +let { ? } = import! std.option + +let __implicit_float @ { ? } = import! std.float + +let __implicit_int @ { ? } = import! std.int + +let __implicit_string @ { ? } = import! std.string + +let { error } = import! std.prim + +in () +"#; + +#[derive(Default)] +pub struct VmBuilder { + import_paths: Option>, +} + +impl VmBuilder { + pub fn new() -> VmBuilder { + VmBuilder::default() + } + + option!{ + /// Defines the paths used to lookup gluon files + /// (default: ["."]) + import_paths set_import_paths: Option> + } + + pub fn build(self) -> RootedThread { + let vm = RootedThread::with_global_state(::vm::vm::GlobalVmStateBuilder::new().build()); + + let import = Import::new(DefaultImporter); + if let Some(import_paths) = self.import_paths { + import.set_paths(import_paths); + } + + if let Ok(gluon_path) = env::var("GLUON_PATH") { + import.add_path(gluon_path); + } + vm.get_macros().insert(String::from("import"), import); + + Compiler::new() + .implicit_prelude(false) + .run_expr::>(&vm, "", r#" import! std.types "#) + .unwrap_or_else(|err| panic!("{}", err)); + + add_extern_module(&vm, "std.prim", ::vm::primitives::load); + add_extern_module(&vm, "std.byte.prim", ::vm::primitives::load_byte); + add_extern_module(&vm, "std.int.prim", ::vm::primitives::load_int); + add_extern_module(&vm, "std.float.prim", ::vm::primitives::load_float); + add_extern_module(&vm, "std.string.prim", ::vm::primitives::load_string); + add_extern_module(&vm, "std.char.prim", ::vm::primitives::load_char); + add_extern_module(&vm, "std.array.prim", ::vm::primitives::load_array); + + add_extern_module(&vm, "std.lazy.prim", ::vm::lazy::load); + add_extern_module(&vm, "std.reference.prim", ::vm::reference::load); + + add_extern_module(&vm, "std.channel.prim", ::vm::channel::load_channel); + add_extern_module(&vm, "std.thread.prim", ::vm::channel::load_thread); + add_extern_module(&vm, "std.debug.prim", ::vm::debug::load); + add_extern_module(&vm, "std.io.prim", ::io::load); + + load_regex(&vm); + load_random(&vm); + + vm + } +} + +/// Creates a new virtual machine with support for importing other modules and with all primitives +/// loaded. +pub fn new_vm() -> RootedThread { + VmBuilder::default().build() +} + +#[cfg(feature = "regex")] +fn load_regex(vm: &Thread) { + add_extern_module(&vm, "std.regex", ::regex_bind::load); +} +#[cfg(not(feature = "regex"))] +fn load_regex(_: &Thread) {} + +#[cfg(all(feature = "rand", not(target_arch = "wasm32")))] +fn load_random(vm: &Thread) { + add_extern_module(&vm, "std.random.prim", ::rand_bind::load); +} +#[cfg(any(not(feature = "rand"), target_arch = "wasm32"))] +fn load_random(_: &Thread) {} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn implicit_prelude() { + let _ = ::env_logger::try_init(); + + let thread = new_vm(); + Compiler::new() + .implicit_prelude(false) + .run_expr::<()>(&thread, "prelude", PRELUDE) + .unwrap_or_else(|err| panic!("{}", err)); + } +} diff --git a/tests/http.rs b/tests/http.rs deleted file mode 100644 index 64226e5b1b..0000000000 --- a/tests/http.rs +++ /dev/null @@ -1,73 +0,0 @@ -extern crate curl; - -use std::cmp; -use std::io::Write; -use std::process::Command; -use std::sync::{Arc, Mutex}; -use std::time::Instant; - -use curl::easy::Easy; -use curl::Error; - -fn test_server( - easy: &mut Easy, - port: &str, - path: &str, - mut message: &'static [u8], -) -> Result> { - let http_path = "./target/debug/examples/http"; - let mut child = Command::new(http_path).arg(port).spawn().unwrap(); - - let start = Instant::now(); - easy.url(&format!("localhost:{}{}", port, path)).unwrap(); - let out = Arc::new(Mutex::new(Vec::new())); - easy.read_function(move |buffer| { - let len = cmp::min(buffer.len(), message.len()); - buffer[..len].copy_from_slice(&message[..len]); - message = &message[len..]; - Ok(len) - })?; - { - let out = out.clone(); - easy.write_function(move |data| Ok(out.lock().unwrap().write(data).unwrap())) - .unwrap(); - } - - let mut result = None; - while start.elapsed().as_secs() < 7 { - result = Some(easy.perform()); - if let Some(Ok(())) = result { - break; - } - } - - child.kill().unwrap(); - match result { - None => Err(None), - Some(Err(err)) => return Err(Some(err)), - Some(Ok(())) => Ok(String::from_utf8(out.lock().unwrap().to_owned()).unwrap()), - } -} - -#[test] -#[ignore] -fn http() { - let mut easy = Easy::new(); - let result = test_server(&mut easy, "2345", "", b""); - - assert_eq!(easy.response_code(), Ok(200)); - assert_eq!(result, Ok("Hello World".to_string())); -} - -#[test] -#[ignore] -fn echo() { - let mut easy = Easy::new(); - easy.post(true).unwrap(); - let content = b"test message"; - easy.post_field_size(content.len() as u64).unwrap(); - let result = test_server(&mut easy, "2346", "/echo", content); - - assert_eq!(easy.response_code(), Ok(200)); - assert_eq!(result, Ok("test message".to_string())); -} diff --git a/tests/io.rs b/tests/io.rs index a9a74a3acd..31ae605ddc 100644 --- a/tests/io.rs +++ b/tests/io.rs @@ -1,6 +1,6 @@ extern crate env_logger; extern crate gluon; -extern crate tokio_core; +extern crate tokio; use gluon::vm::api::{Hole, OpaqueValue, ValueRef, IO}; use gluon::{new_vm, Compiler, Thread}; @@ -129,14 +129,15 @@ fn spawn_on_twice() { action "#; - let mut core = self::tokio_core::reactor::Core::new().unwrap(); - let vm = make_async_vm(Some(core.remote())); - let (result, _) = - core.run( + let mut runtime = self::tokio::runtime::Runtime::new().unwrap(); + let vm = make_vm(); + let (result, _) = runtime + .block_on( Compiler::new() .run_io(true) .run_expr_async::>(&vm, "", text), - ).unwrap_or_else(|err| panic!("{}", err)); + ) + .unwrap_or_else(|err| panic!("{}", err)); match result { IO::Value(result) => { assert_eq!(result, "abc"); @@ -144,12 +145,13 @@ fn spawn_on_twice() { IO::Exception(err) => panic!("{}", err), } - let (result, _) = - core.run( + let (result, _) = runtime + .block_on( Compiler::new() .run_io(true) .run_expr_async::>(&vm, "", text), - ).unwrap_or_else(|err| panic!("{}", err)); + ) + .unwrap_or_else(|err| panic!("{}", err)); match result { IO::Value(result) => { assert_eq!(result, "abc"); @@ -173,14 +175,15 @@ fn spawn_on_runexpr() { wrap x.value "#; - let mut core = self::tokio_core::reactor::Core::new().unwrap(); - let vm = make_async_vm(Some(core.remote())); - let (result, _) = - core.run( + let mut runtime = self::tokio::runtime::Runtime::new().unwrap(); + let vm = make_vm(); + let (result, _) = runtime + .block_on( Compiler::new() .run_io(true) .run_expr_async::>(&vm, "", text), - ).unwrap_or_else(|err| panic!("{}", err)); + ) + .unwrap_or_else(|err| panic!("{}", err)); match result { IO::Value(result) => { assert_eq!(result, "123"); @@ -209,14 +212,15 @@ fn spawn_on_runexpr_in_catch() { (io.catch action wrap >>= io.println) *> wrap "123" "#; - let mut core = self::tokio_core::reactor::Core::new().unwrap(); - let vm = make_async_vm(Some(core.remote())); - let (result, _) = - core.run( + let mut runtime = self::tokio::runtime::Runtime::new().unwrap(); + let vm = make_vm(); + let (result, _) = runtime + .block_on( Compiler::new() .run_io(true) .run_expr_async::>(&vm, "", text), - ).unwrap_or_else(|err| panic!("{}", err)); + ) + .unwrap_or_else(|err| panic!("{}", err)); match result { IO::Value(result) => { assert_eq!(result, "123"); @@ -224,12 +228,13 @@ fn spawn_on_runexpr_in_catch() { IO::Exception(err) => panic!("{}", err), } - let (result, _) = - core.run( + let (result, _) = runtime + .block_on( Compiler::new() .run_io(true) .run_expr_async::>(&vm, "", text), - ).unwrap_or_else(|err| panic!("{}", err)); + ) + .unwrap_or_else(|err| panic!("{}", err)); match result { IO::Value(result) => { assert_eq!(result, "123"); diff --git a/tests/main.rs b/tests/main.rs index 7d4d3c1f5e..50630132e3 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -10,7 +10,7 @@ extern crate futures; extern crate futures_cpupool; extern crate gluon; extern crate tensile; -extern crate tokio_core; +extern crate tokio; extern crate pulldown_cmark; @@ -306,7 +306,7 @@ fn main_() -> Result<(), Box> { let iter = test_files("tests/pass")?.into_iter(); let pool = futures_cpupool::CpuPool::new(1); - let mut core = tokio_core::reactor::Core::new()?; + let mut runtime = tokio::runtime::Runtime::new()?; let pass_tests_future = stream::futures_ordered( iter.filter_map(|filename| { let name = filename_to_module(filename.to_str().unwrap_or("")); @@ -328,7 +328,7 @@ fn main_() -> Result<(), Box> { }) }), ).collect(); - let pass_tests = core.run(pass_tests_future)?; + let pass_tests = runtime.block_on(pass_tests_future)?; let iter = test_files("tests/fail")?.into_iter(); diff --git a/tests/support/mod.rs b/tests/support/mod.rs index dadbaa292c..e608d50e75 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -3,7 +3,6 @@ extern crate env_logger; pub extern crate futures; #[allow(unused_extern_crates)] extern crate gluon; -extern crate tokio_core; use gluon::import::Import; use gluon::vm::api::{Getable, VmType}; @@ -40,11 +39,7 @@ where /// Creates a VM for testing which has the correct paths to import the std library properly pub fn make_vm() -> RootedThread { - make_async_vm(None) -} - -pub fn make_async_vm(remote: Option) -> RootedThread { - let vm = ::gluon::VmBuilder::new().event_loop(remote).build(); + let vm = ::gluon::VmBuilder::new().build(); let import = vm.get_macros().get("import"); import .as_ref() @@ -63,7 +58,7 @@ macro_rules! test_expr { let mut vm = $crate::support::make_vm(); let value = $crate::support::run_expr_(&mut vm, $expr, true); assert_eq!(value, $value); - + // Help out the type inference by forcing that left and right are the same types fn equiv(_: &T, _: &T) {} equiv(&value, &$value); @@ -73,7 +68,7 @@ macro_rules! test_expr { #[test] fn $name() { use gluon::vm::api::IO; - + let _ = ::env_logger::try_init(); let mut vm = $crate::support::make_vm(); let (value, _) = ::gluon::Compiler::new() @@ -84,7 +79,7 @@ macro_rules! test_expr { match value { IO::Value(value) => { assert_eq!(value, $value); - + // Help out the type inference by forcing that left and right are the same types fn equiv(_: &T, _: &T) {} equiv(&value, &$value); @@ -109,7 +104,7 @@ macro_rules! test_expr { let mut vm = $crate::support::make_vm(); let value = $crate::support::run_expr(&mut vm, $expr); assert_eq!(value, $value); - + // Help out the type inference by forcing that left and right are the same types fn equiv(_: &T, _: &T) {} equiv(&value, &$value); diff --git a/vm/Cargo.toml b/vm/Cargo.toml index a35b6c75cb..c114c65a3e 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -34,9 +34,6 @@ serde_derive_state = { version = "0.4.0", optional = true } gluon_base = { path = "../base", version = "0.8.1" } # GLUON gluon_check = { path = "../check", version = "0.8.1" } # GLUON -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -tokio-core = "0.1" - [build-dependencies] lalrpop = { version = "0.15.1", optional = true } diff --git a/vm/src/channel.rs b/vm/src/channel.rs index 935953fcf0..644b8e1771 100644 --- a/vm/src/channel.rs +++ b/vm/src/channel.rs @@ -3,8 +3,7 @@ use std::collections::VecDeque; use std::fmt; use std::sync::{Arc, Mutex}; -use futures::sync::oneshot; -use futures::Future; +use futures::{future, Future}; use base::types::{ArcType, Type}; @@ -28,11 +27,7 @@ pub struct Sender { queue: Arc>>, } -impl Userdata for Sender -where - T: Any + Send + Sync + fmt::Debug + Traverseable, -{ -} +impl Userdata for Sender where T: Any + Send + Sync + fmt::Debug + Traverseable {} impl fmt::Debug for Sender where @@ -65,11 +60,7 @@ pub struct Receiver { queue: Arc>>, } -impl Userdata for Receiver -where - T: Any + Send + Sync + fmt::Debug + Traverseable, -{ -} +impl Userdata for Receiver where T: Any + Send + Sync + fmt::Debug + Traverseable {} impl fmt::Debug for Receiver where @@ -223,7 +214,7 @@ fn spawn_on<'vm>( _thread: RootedThread, _action: WithVM<'vm, FunctionRef>, ) -> IO>>> { - IO::Exception("spawn_on requires the `tokio_core` crate".to_string()) + IO::Exception("spawn_on requires the `tokio` crate".to_string()) } #[cfg(not(target_arch = "wasm32"))] @@ -239,11 +230,7 @@ fn spawn_on<'vm>( } } - impl Userdata for SpawnFuture - where - F: Send + 'static, - { - } + impl Userdata for SpawnFuture where F: Send + 'static {} impl Traverseable for SpawnFuture { fn traverse(&self, _: &mut Gc) {} @@ -292,10 +279,7 @@ fn spawn_on<'vm>( let WithVM { vm, value: action } = action; let mut action = OwnedFunction::::from_value(&thread, action.get_variant()); - let future = oneshot::spawn_fn( - move || action.call_async(()), - &vm.global_env().get_event_loop().expect("event loop"), - ); + let future = future::lazy(move || action.call_async(())); let mut context = vm.context(); diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 3af11c7398..c4e0cc5dac 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -1,212 +1,210 @@ -//! Crate which contain the virtual machine which executes gluon programs -#![doc(html_root_url = "https://docs.rs/gluon_vm/0.5.0")] -// # GLUON -#![recursion_limit = "1024"] - -#[macro_use] -extern crate bitflags; -extern crate codespan; -#[macro_use] -extern crate collect_mac; -#[cfg(test)] -extern crate env_logger; -#[doc(hidden)] -pub extern crate frunk_core; -#[macro_use] -extern crate futures; -extern crate itertools; -#[macro_use] -extern crate log; -#[macro_use] -extern crate mopa; -extern crate pretty; -#[macro_use] -extern crate quick_error; -#[cfg(not(target_arch = "wasm32"))] -extern crate tokio_core; - -#[cfg(feature = "serde_derive")] -#[macro_use] -extern crate serde_derive; -#[cfg(feature = "serde_derive")] -#[macro_use] -extern crate serde_derive_state; -#[cfg(feature = "serde_state")] -#[macro_use] -extern crate serde_state as serde; - -#[macro_use] -extern crate gluon_base as base; -extern crate gluon_check as check; - -#[macro_use] -#[cfg(feature = "serde")] -pub mod serialization; - -#[macro_use] -pub mod api; -pub mod channel; -pub mod compiler; -pub mod core; -pub mod debug; -pub mod dynamic; -#[macro_use] -pub mod future; -pub mod gc; -pub mod lazy; -pub mod macros; -pub mod primitives; -pub mod reference; -pub mod stack; -pub mod thread; -pub mod types; -pub mod vm; - -mod array; -mod derive; -mod interner; -mod source_map; -mod value; - -use std::fmt; -use std::marker::PhantomData; - -use api::{ValueRef, VmType}; -use base::metadata::Metadata; -use base::symbol::Symbol; -use base::types::ArcType; -use stack::Stacktrace; -use thread::{RootedThread, RootedValue, Thread}; -use types::VmIndex; -use value::{Value, ValueRepr}; - -unsafe fn forget_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T { - ::std::mem::transmute(x) -} - -#[derive(Copy, Clone, Debug, PartialEq)] -pub struct Variants<'a>(ValueRepr, PhantomData<&'a Value>); - -impl<'a> Variants<'a> { - /// Creates a new `Variants` value which assumes that `value` is rooted for the lifetime of the - /// value - pub unsafe fn new(value: &Value) -> Variants { - Variants::with_root(value.get_repr(), value) - } - - pub(crate) unsafe fn with_root(value: ValueRepr, _root: &T) -> Variants { - Variants(value, PhantomData) - } - - #[doc(hidden)] - pub fn get_value(&self) -> Value { - self.0.into() - } - - /// Returns an instance of `ValueRef` which allows users to safely retrieve the interals of a - /// value - pub fn as_ref(&self) -> ValueRef<'a> { - unsafe { ValueRef::rooted_new(self.0) } - } -} - -/// Type returned from vm functions which may fail -pub type Result = ::std::result::Result; - -quick_error! { - /// Representation of all possible errors that can occur when interacting with the `vm` crate - #[derive(Debug, PartialEq)] - pub enum Error { - Dead { - } - UndefinedBinding(symbol: String) { - display("Binding `{}` is not defined", symbol) - } - UndefinedField(typ: ArcType, field: String) { - display("Type `{}` does not have the field `{}`", typ, field) - } - TypeAlreadyExists(symbol: String) { - display("Type `{}` already exists", symbol) - } - GlobalAlreadyExists(symbol: Symbol) { - display("Global `{}` already exists", symbol) - } - MetadataDoesNotExist(symbol: String) { - display("No metadata exists for `{}`", symbol) - } - WrongType(expected: ArcType, actual: ArcType) { - display("Expected a value of type `{}` but the returned type was `{}`", - expected, actual) - } - OutOfMemory { limit: usize, needed: usize } { - display("Thread is out of memory: Limit {}, needed {}", limit, needed) - } - StackOverflow(limit: VmIndex) { - display("The stack has overflowed: Limit `{}`", limit) - } - Message(err: String) { - display("{}", err) - from() - } - Interrupted { - display("Thread was interrupted") - } - Panic(err: String, stacktrace: Option) { - display("{}", Panic { err, stacktrace }) - } - } -} - -struct Panic<'a> { - err: &'a String, - stacktrace: &'a Option, -} - -impl<'a> fmt::Display for Panic<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let Panic { err, stacktrace } = *self; - write!(f, "{}", err)?; - if let Some(ref stacktrace) = *stacktrace { - write!(f, "\n\n{}", stacktrace)?; - } - Ok(()) - } -} - -pub type ExternLoader = fn(&Thread) -> Result; - -pub struct ExternModule { - pub metadata: Metadata, - pub value: RootedValue, - pub typ: ArcType, -} - -impl ExternModule { - pub fn new<'vm, T>(thread: &'vm Thread, value: T) -> Result - where - T: VmType + api::Pushable<'vm> + Send + Sync, - { - ExternModule::with_metadata(thread, value, Metadata::default()) - } - - pub fn with_metadata<'vm, T>( - thread: &'vm Thread, - value: T, - metadata: Metadata, - ) -> Result - where - T: VmType + api::Pushable<'vm> + Send + Sync, - { - Ok(ExternModule { - value: value.marshal(thread)?, - typ: T::make_forall_type(thread), - metadata, - }) - } -} - -/// Internal types and functions exposed to the main `gluon` crate -pub mod internal { - pub use value::{Value, ValuePrinter}; - pub use vm::Global; -} +//! Crate which contain the virtual machine which executes gluon programs +#![doc(html_root_url = "https://docs.rs/gluon_vm/0.5.0")] +// # GLUON +#![recursion_limit = "1024"] + +#[macro_use] +extern crate bitflags; +extern crate codespan; +#[macro_use] +extern crate collect_mac; +#[cfg(test)] +extern crate env_logger; +#[doc(hidden)] +pub extern crate frunk_core; +#[macro_use] +extern crate futures; +extern crate itertools; +#[macro_use] +extern crate log; +#[macro_use] +extern crate mopa; +extern crate pretty; +#[macro_use] +extern crate quick_error; + +#[cfg(feature = "serde_derive")] +#[macro_use] +extern crate serde_derive; +#[cfg(feature = "serde_derive")] +#[macro_use] +extern crate serde_derive_state; +#[cfg(feature = "serde_state")] +#[macro_use] +extern crate serde_state as serde; + +#[macro_use] +extern crate gluon_base as base; +extern crate gluon_check as check; + +#[macro_use] +#[cfg(feature = "serde")] +pub mod serialization; + +#[macro_use] +pub mod api; +pub mod channel; +pub mod compiler; +pub mod core; +pub mod debug; +pub mod dynamic; +#[macro_use] +pub mod future; +pub mod gc; +pub mod lazy; +pub mod macros; +pub mod primitives; +pub mod reference; +pub mod stack; +pub mod thread; +pub mod types; +pub mod vm; + +mod array; +mod derive; +mod interner; +mod source_map; +mod value; + +use std::fmt; +use std::marker::PhantomData; + +use api::{ValueRef, VmType}; +use base::metadata::Metadata; +use base::symbol::Symbol; +use base::types::ArcType; +use stack::Stacktrace; +use thread::{RootedThread, RootedValue, Thread}; +use types::VmIndex; +use value::{Value, ValueRepr}; + +unsafe fn forget_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T { + ::std::mem::transmute(x) +} + +#[derive(Copy, Clone, Debug, PartialEq)] +pub struct Variants<'a>(ValueRepr, PhantomData<&'a Value>); + +impl<'a> Variants<'a> { + /// Creates a new `Variants` value which assumes that `value` is rooted for the lifetime of the + /// value + pub unsafe fn new(value: &Value) -> Variants { + Variants::with_root(value.get_repr(), value) + } + + pub(crate) unsafe fn with_root(value: ValueRepr, _root: &T) -> Variants { + Variants(value, PhantomData) + } + + #[doc(hidden)] + pub fn get_value(&self) -> Value { + self.0.into() + } + + /// Returns an instance of `ValueRef` which allows users to safely retrieve the interals of a + /// value + pub fn as_ref(&self) -> ValueRef<'a> { + unsafe { ValueRef::rooted_new(self.0) } + } +} + +/// Type returned from vm functions which may fail +pub type Result = ::std::result::Result; + +quick_error! { + /// Representation of all possible errors that can occur when interacting with the `vm` crate + #[derive(Debug, PartialEq)] + pub enum Error { + Dead { + } + UndefinedBinding(symbol: String) { + display("Binding `{}` is not defined", symbol) + } + UndefinedField(typ: ArcType, field: String) { + display("Type `{}` does not have the field `{}`", typ, field) + } + TypeAlreadyExists(symbol: String) { + display("Type `{}` already exists", symbol) + } + GlobalAlreadyExists(symbol: Symbol) { + display("Global `{}` already exists", symbol) + } + MetadataDoesNotExist(symbol: String) { + display("No metadata exists for `{}`", symbol) + } + WrongType(expected: ArcType, actual: ArcType) { + display("Expected a value of type `{}` but the returned type was `{}`", + expected, actual) + } + OutOfMemory { limit: usize, needed: usize } { + display("Thread is out of memory: Limit {}, needed {}", limit, needed) + } + StackOverflow(limit: VmIndex) { + display("The stack has overflowed: Limit `{}`", limit) + } + Message(err: String) { + display("{}", err) + from() + } + Interrupted { + display("Thread was interrupted") + } + Panic(err: String, stacktrace: Option) { + display("{}", Panic { err, stacktrace }) + } + } +} + +struct Panic<'a> { + err: &'a String, + stacktrace: &'a Option, +} + +impl<'a> fmt::Display for Panic<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let Panic { err, stacktrace } = *self; + write!(f, "{}", err)?; + if let Some(ref stacktrace) = *stacktrace { + write!(f, "\n\n{}", stacktrace)?; + } + Ok(()) + } +} + +pub type ExternLoader = fn(&Thread) -> Result; + +pub struct ExternModule { + pub metadata: Metadata, + pub value: RootedValue, + pub typ: ArcType, +} + +impl ExternModule { + pub fn new<'vm, T>(thread: &'vm Thread, value: T) -> Result + where + T: VmType + api::Pushable<'vm> + Send + Sync, + { + ExternModule::with_metadata(thread, value, Metadata::default()) + } + + pub fn with_metadata<'vm, T>( + thread: &'vm Thread, + value: T, + metadata: Metadata, + ) -> Result + where + T: VmType + api::Pushable<'vm> + Send + Sync, + { + Ok(ExternModule { + value: value.marshal(thread)?, + typ: T::make_forall_type(thread), + metadata, + }) + } +} + +/// Internal types and functions exposed to the main `gluon` crate +pub mod internal { + pub use value::{Value, ValuePrinter}; + pub use vm::Global; +} diff --git a/vm/src/thread.rs b/vm/src/thread.rs index f56e51172d..dbd4bf835a 100644 --- a/vm/src/thread.rs +++ b/vm/src/thread.rs @@ -310,11 +310,23 @@ impl<'b> Roots<'b> { // knowing wheter it is or not. So the only way of allowing it to mark itself is to disallow it to // be allocated anywhere else. /// Representation of the virtual machine -#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))] -#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "::serialization::DeSeed"))] -#[cfg_attr(feature = "serde_derive", serde(serialize_state = "::serialization::SeSeed"))] +#[cfg_attr( + feature = "serde_derive", + derive(DeserializeState, SerializeState) +)] +#[cfg_attr( + feature = "serde_derive", + serde(deserialize_state = "::serialization::DeSeed") +)] +#[cfg_attr( + feature = "serde_derive", + serde(serialize_state = "::serialization::SeSeed") +)] pub struct Thread { - #[cfg_attr(feature = "serde_derive", serde(state_with = "::base::serialization::shared"))] + #[cfg_attr( + feature = "serde_derive", + serde(state_with = "::base::serialization::shared") + )] global_state: Arc, // The parent of this thread, if it exists must live at least as long as this thread as this // thread can refer to any value in the parent thread @@ -383,9 +395,18 @@ impl<'vm, 'value> Getable<'vm, 'value> for RootedThread { /// An instance of `Thread` which is rooted. See the `Thread` type for documentation on interacting /// with the type. #[derive(Debug)] -#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))] -#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "::serialization::DeSeed"))] -#[cfg_attr(feature = "serde_derive", serde(serialize_state = "::serialization::SeSeed"))] +#[cfg_attr( + feature = "serde_derive", + derive(DeserializeState, SerializeState) +)] +#[cfg_attr( + feature = "serde_derive", + serde(deserialize_state = "::serialization::DeSeed") +)] +#[cfg_attr( + feature = "serde_derive", + serde(serialize_state = "::serialization::SeSeed") +)] pub struct RootedThread(#[cfg_attr(feature = "serde_derive", serde(state))] GcPtr); impl Drop for RootedThread { @@ -547,7 +568,10 @@ impl Thread { /// # } /// ``` /// - #[deprecated(since = "0.7.0", note = "Use `gluon::import::add_extern_module` instead")] + #[deprecated( + since = "0.7.0", + note = "Use `gluon::import::add_extern_module` instead" + )] pub fn define_global<'vm, T>(&'vm self, name: &str, value: T) -> Result<()> where T: Pushable<'vm> + VmType, @@ -653,11 +677,6 @@ impl Thread { self.global_env().get_macros() } - #[cfg(not(target_arch = "wasm32"))] - pub fn get_event_loop(&self) -> Option<::tokio_core::reactor::Remote> { - self.global_env().get_event_loop() - } - /// Runs a garbage collection. pub fn collect(&self) { let mut context = self.current_context(); @@ -1093,9 +1112,18 @@ struct Hook { previous_instruction_index: usize, } -#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))] -#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "::serialization::DeSeed"))] -#[cfg_attr(feature = "serde_derive", serde(serialize_state = "::serialization::SeSeed"))] +#[cfg_attr( + feature = "serde_derive", + derive(DeserializeState, SerializeState) +)] +#[cfg_attr( + feature = "serde_derive", + serde(deserialize_state = "::serialization::DeSeed") +)] +#[cfg_attr( + feature = "serde_derive", + serde(serialize_state = "::serialization::SeSeed") +)] pub struct Context { // FIXME It is dangerous to write to gc and stack #[cfg_attr(feature = "serde_derive", serde(state))] diff --git a/vm/src/vm.rs b/vm/src/vm.rs index d694b0ea6e..b54db234e9 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -94,13 +94,28 @@ fn new_bytecode_function( } #[derive(Debug)] -#[cfg_attr(feature = "serde_derive_state", derive(SerializeState, DeserializeState))] -#[cfg_attr(feature = "serde_derive_state", serde(deserialize_state = "::serialization::DeSeed"))] -#[cfg_attr(feature = "serde_derive_state", serde(serialize_state = "::serialization::SeSeed"))] +#[cfg_attr( + feature = "serde_derive_state", + derive(SerializeState, DeserializeState) +)] +#[cfg_attr( + feature = "serde_derive_state", + serde(deserialize_state = "::serialization::DeSeed") +)] +#[cfg_attr( + feature = "serde_derive_state", + serde(serialize_state = "::serialization::SeSeed") +)] pub struct Global { - #[cfg_attr(feature = "serde_derive", serde(state_with = "::serialization::symbol"))] + #[cfg_attr( + feature = "serde_derive", + serde(state_with = "::serialization::symbol") + )] pub id: Symbol, - #[cfg_attr(feature = "serde_derive", serde(state_with = "::serialization::borrow"))] + #[cfg_attr( + feature = "serde_derive", + serde(state_with = "::serialization::borrow") + )] pub typ: ArcType, pub metadata: Metadata, #[cfg_attr(feature = "serde_derive_state", serde(state))] @@ -113,14 +128,26 @@ impl Traverseable for Global { } } -#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))] -#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "::serialization::DeSeed"))] -#[cfg_attr(feature = "serde_derive", serde(serialize_state = "::serialization::SeSeed"))] +#[cfg_attr( + feature = "serde_derive", + derive(DeserializeState, SerializeState) +)] +#[cfg_attr( + feature = "serde_derive", + serde(deserialize_state = "::serialization::DeSeed") +)] +#[cfg_attr( + feature = "serde_derive", + serde(serialize_state = "::serialization::SeSeed") +)] pub struct GlobalVmState { #[cfg_attr(feature = "serde_derive", serde(state))] env: RwLock, - #[cfg_attr(feature = "serde_derive", serde(state_with = "::serialization::borrow"))] + #[cfg_attr( + feature = "serde_derive", + serde(state_with = "::serialization::borrow") + )] generics: RwLock>, #[cfg_attr(feature = "serde_derive", serde(skip))] @@ -144,10 +171,6 @@ pub struct GlobalVmState { // thread #[cfg_attr(feature = "serde_derive", serde(state))] pub generation_0_threads: RwLock>>, - - #[cfg_attr(feature = "serde_derive", serde(skip))] - #[cfg(not(target_arch = "wasm32"))] - event_loop: Option<::std::panic::AssertUnwindSafe<::tokio_core::reactor::Remote>>, } impl Traverseable for GlobalVmState { @@ -164,9 +187,18 @@ impl Traverseable for GlobalVmState { /// A borrowed structure which implements `CompilerEnv`, `TypeEnv` and `KindEnv` allowing the /// typechecker and compiler to lookup things in the virtual machine. #[derive(Debug)] -#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))] -#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "::serialization::DeSeed"))] -#[cfg_attr(feature = "serde_derive", serde(serialize_state = "::serialization::SeSeed"))] +#[cfg_attr( + feature = "serde_derive", + derive(DeserializeState, SerializeState) +)] +#[cfg_attr( + feature = "serde_derive", + serde(deserialize_state = "::serialization::DeSeed") +)] +#[cfg_attr( + feature = "serde_derive", + serde(serialize_state = "::serialization::SeSeed") +)] pub struct VmEnv { #[cfg_attr(feature = "serde_derive", serde(state))] pub type_infos: TypeInfos, @@ -359,37 +391,14 @@ impl VmEnv { } } -macro_rules! option { - ($(#[$attr:meta])* $name: ident $set_name: ident : $typ: ty) => { - $(#[$attr])* - pub fn $name(mut self, $name: $typ) -> Self { - self.$name = $name; - self - } - - $(#[$attr])* - pub fn $set_name(&mut self, $name: $typ) { - self.$name = $name; - } - }; -} - #[derive(Default)] -pub struct GlobalVmStateBuilder { - #[cfg(not(target_arch = "wasm32"))] - event_loop: Option<::tokio_core::reactor::Remote>, -} +pub struct GlobalVmStateBuilder {} impl GlobalVmStateBuilder { pub fn new() -> Self { Self::default() } - option!( - #[cfg(not(target_arch = "wasm32"))] - event_loop set_event_loop: Option<::tokio_core::reactor::Remote> - ); - pub fn build(self) -> GlobalVmState { let mut vm = GlobalVmState { env: RwLock::new(VmEnv { @@ -403,9 +412,6 @@ impl GlobalVmStateBuilder { macros: MacroEnv::new(), type_cache: TypeCache::default(), generation_0_threads: RwLock::new(Vec::new()), - - #[cfg(not(target_arch = "wasm32"))] - event_loop: self.event_loop.map(::std::panic::AssertUnwindSafe), }; vm.add_types().unwrap(); vm @@ -455,11 +461,6 @@ impl GlobalVmState { Ok(()) } - #[cfg(not(target_arch = "wasm32"))] - pub fn get_event_loop(&self) -> Option<::tokio_core::reactor::Remote> { - self.event_loop.as_ref().map(|x| x.0.clone()) - } - pub fn type_cache(&self) -> &TypeCache { &self.type_cache }