feat(es/plugin): Update wasmer to 3 (#5456)

This commit is contained in:
OJ Kwon 2022-08-16 00:12:37 -07:00 committed by GitHub
parent bd4e268a83
commit 92f006c9a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 654 additions and 708 deletions

366
Cargo.lock generated
View File

@ -137,7 +137,7 @@ dependencies = [
"cfg-if 1.0.0",
"libc",
"miniz_oxide",
"object 0.27.1",
"object",
"rustc-demangle",
]
@ -465,56 +465,57 @@ dependencies = [
[[package]]
name = "cranelift-bforest"
version = "0.82.3"
version = "0.86.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75"
checksum = "529ffacce2249ac60edba2941672dfedf3d96558b415d0d8083cd007456e0f55"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-codegen"
version = "0.82.3"
version = "0.86.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b"
checksum = "427d105f617efc8cb55f8d036a7fded2e227892d8780b4985e5551f8d27c4a92"
dependencies = [
"cranelift-bforest",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
"cranelift-entity",
"cranelift-isle",
"gimli",
"log",
"regalloc",
"regalloc2",
"smallvec",
"target-lexicon",
]
[[package]]
name = "cranelift-codegen-meta"
version = "0.82.3"
version = "0.86.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24"
checksum = "551674bed85b838d45358e3eab4f0ffaa6790c70dc08184204b9a54b41cdb7d1"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.82.3"
version = "0.86.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc"
checksum = "2b3a63ae57498c3eb495360944a33571754241e15e47e3bcae6082f40fec5866"
[[package]]
name = "cranelift-entity"
version = "0.82.3"
version = "0.86.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf"
checksum = "11aa8aa624c72cc1c94ea3d0739fa61248260b5b14d3646f51593a88d67f3e6e"
[[package]]
name = "cranelift-frontend"
version = "0.82.3"
version = "0.86.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce"
checksum = "544ee8f4d1c9559c9aa6d46e7aaeac4a13856d620561094f35527356c7d21bd0"
dependencies = [
"cranelift-codegen",
"log",
@ -522,6 +523,12 @@ dependencies = [
"target-lexicon",
]
[[package]]
name = "cranelift-isle"
version = "0.86.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed16b14363d929b8c37e3c557d0a7396791b383ecc302141643c054343170aad"
[[package]]
name = "crc"
version = "2.1.0"
@ -537,15 +544,6 @@ version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403"
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "criterion"
version = "0.3.5"
@ -759,6 +757,17 @@ dependencies = [
"unreachable",
]
[[package]]
name = "derivative"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "derive_arbitrary"
version = "1.0.2"
@ -978,6 +987,15 @@ dependencies = [
"slab",
]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]
[[package]]
name = "generational-arena"
version = "0.2.8"
@ -1392,27 +1410,6 @@ dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "loupe"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d"
dependencies = [
"indexmap",
"loupe-derive",
"rustversion",
]
[[package]]
name = "loupe-derive"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "lru"
version = "0.7.2"
@ -1765,18 +1762,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "object"
version = "0.28.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40bec70ba014595f99f7aa110b84331ffe1ee9aece7fe6f387cc7e3ecda4d456"
dependencies = [
"crc32fast",
"hashbrown 0.11.2",
"indexmap",
"memchr",
]
[[package]]
name = "once_cell"
version = "1.13.0"
@ -2241,13 +2226,14 @@ dependencies = [
]
[[package]]
name = "regalloc"
version = "0.0.34"
name = "regalloc2"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02"
checksum = "d43a209257d978ef079f3d446331d0f1794f5e0fc19b306a199983857833a779"
dependencies = [
"fxhash",
"log",
"rustc-hash",
"slice-group-by",
"smallvec",
]
@ -2362,6 +2348,7 @@ checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15"
dependencies = [
"bytecheck",
"hashbrown 0.12.0",
"indexmap",
"ptr_meta",
"rend",
"rkyv_derive",
@ -2409,12 +2396,6 @@ dependencies = [
"semver 1.0.4",
]
[[package]]
name = "rustversion"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
[[package]]
name = "ryu"
version = "1.0.9"
@ -2525,15 +2506,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "serde_bytes"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9"
dependencies = [
"serde",
]
[[package]]
name = "serde_cbor"
version = "0.11.2"
@ -2627,6 +2599,12 @@ version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
[[package]]
name = "slice-group-by"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec"
[[package]]
name = "smallvec"
version = "1.8.0"
@ -4027,14 +4005,14 @@ dependencies = [
[[package]]
name = "swc_plugin"
version = "0.89.0"
version = "0.89.1"
dependencies = [
"once_cell",
]
[[package]]
name = "swc_plugin_macro"
version = "0.9.5"
version = "0.9.6"
dependencies = [
"proc-macro2",
"quote",
@ -4043,7 +4021,7 @@ dependencies = [
[[package]]
name = "swc_plugin_proxy"
version = "0.18.8"
version = "0.18.9"
dependencies = [
"better_scoped_tls",
"bytecheck",
@ -4056,7 +4034,7 @@ dependencies = [
[[package]]
name = "swc_plugin_runner"
version = "0.71.10"
version = "0.71.11"
dependencies = [
"anyhow",
"criterion",
@ -4757,25 +4735,20 @@ checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
[[package]]
name = "wasmer"
version = "2.3.0"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf"
checksum = "4a7662db4ddb1ff29653e709924145a6a97e86034bbea820ca1b1b6279d5e0a2"
dependencies = [
"cfg-if 1.0.0",
"indexmap",
"js-sys",
"loupe",
"more-asserts",
"target-lexicon",
"thiserror",
"wasm-bindgen",
"wasmer-artifact",
"wasmer-compiler",
"wasmer-compiler-cranelift",
"wasmer-derive",
"wasmer-engine",
"wasmer-engine-dylib",
"wasmer-engine-universal",
"wasmer-types",
"wasmer-vm",
"wasmparser",
@ -4783,24 +4756,11 @@ dependencies = [
"winapi",
]
[[package]]
name = "wasmer-artifact"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325"
dependencies = [
"enumset",
"loupe",
"thiserror",
"wasmer-compiler",
"wasmer-types",
]
[[package]]
name = "wasmer-cache"
version = "2.3.0"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0def391ee1631deac5ac1e6ce919c07a5ccb936ad0fd44708cdc2365c49561a4"
checksum = "8ed6e5cd9a188836346b42c6fcaad25e69ff3f4e5ffb4b73c83ac1aa1642a82f"
dependencies = [
"blake3",
"hex",
@ -4810,33 +4770,38 @@ dependencies = [
[[package]]
name = "wasmer-compiler"
version = "2.3.0"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c"
checksum = "f32214d36c989b1c350a48a928865c4128ce31d3ba82c8799b9f844ad485d5f3"
dependencies = [
"backtrace",
"cfg-if 1.0.0",
"enum-iterator",
"enumset",
"loupe",
"rkyv",
"serde",
"serde_bytes",
"lazy_static",
"leb128",
"memmap2",
"more-asserts",
"region",
"rustc-demangle",
"smallvec",
"target-lexicon",
"thiserror",
"wasmer-types",
"wasmer-vm",
"wasmparser",
"winapi",
]
[[package]]
name = "wasmer-compiler-cranelift"
version = "2.3.0"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0"
checksum = "4492a4895c85955d83756b5970483991f93cd5fe1ddbef2fb86e9d97085f64c7"
dependencies = [
"cranelift-codegen",
"cranelift-entity",
"cranelift-frontend",
"gimli",
"loupe",
"more-asserts",
"rayon",
"smallvec",
@ -4848,9 +4813,9 @@ dependencies = [
[[package]]
name = "wasmer-derive"
version = "2.3.0"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51"
checksum = "96d7e0d489ec1583d7c0367bb7eccb71e9e3f827e9f7c32a4375f3de6e8aa5f2"
dependencies = [
"proc-macro-error",
"proc-macro2",
@ -4859,123 +4824,36 @@ dependencies = [
]
[[package]]
name = "wasmer-engine"
version = "2.3.0"
name = "wasmer-types"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45"
checksum = "810fcad9772ae820c2b474a65a064c9f4d23c76b923b130aa007b3995fc602db"
dependencies = [
"backtrace",
"enum-iterator",
"enumset",
"lazy_static",
"loupe",
"memmap2",
"indexmap",
"more-asserts",
"rustc-demangle",
"serde",
"serde_bytes",
"rkyv",
"target-lexicon",
"thiserror",
"wasmer-artifact",
"wasmer-compiler",
"wasmer-types",
"wasmer-vm",
]
[[package]]
name = "wasmer-engine-dylib"
version = "2.3.0"
name = "wasmer-vbus"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53"
checksum = "5556ca1f059385cbecb360561e2c15c60074a12d8fe42e0692fb53fa700f8bef"
dependencies = [
"cfg-if 1.0.0",
"enum-iterator",
"enumset",
"leb128",
"libloading",
"loupe",
"object 0.28.3",
"rkyv",
"serde",
"tempfile",
"thiserror",
"tracing",
"wasmer-artifact",
"wasmer-compiler",
"wasmer-engine",
"wasmer-object",
"wasmer-types",
"wasmer-vm",
"which",
]
[[package]]
name = "wasmer-engine-universal"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15"
dependencies = [
"cfg-if 1.0.0",
"enumset",
"leb128",
"loupe",
"region",
"rkyv",
"wasmer-compiler",
"wasmer-engine",
"wasmer-engine-universal-artifact",
"wasmer-types",
"wasmer-vm",
"winapi",
]
[[package]]
name = "wasmer-engine-universal-artifact"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41"
dependencies = [
"enum-iterator",
"enumset",
"loupe",
"rkyv",
"thiserror",
"wasmer-artifact",
"wasmer-compiler",
"wasmer-types",
]
[[package]]
name = "wasmer-object"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b"
dependencies = [
"object 0.28.3",
"thiserror",
"wasmer-compiler",
"wasmer-types",
]
[[package]]
name = "wasmer-types"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f"
dependencies = [
"backtrace",
"enum-iterator",
"indexmap",
"loupe",
"more-asserts",
"rkyv",
"serde",
"thiserror",
"wasmer-vfs",
]
[[package]]
name = "wasmer-vfs"
version = "2.3.0"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9302eae3edc53cb540c2d681e7f16d8274918c1ce207591f04fed351649e97c0"
checksum = "53be0690ef53117068c89c20440a04381bb6ee42c9573b8d5dada30559ea042d"
dependencies = [
"libc",
"slab",
@ -4985,9 +4863,9 @@ dependencies = [
[[package]]
name = "wasmer-vm"
version = "2.3.0"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd"
checksum = "a951ec45d81689304cc6a2c7fe7eb038ad92929a0f97704358a2af676a135cbb"
dependencies = [
"backtrace",
"cc",
@ -4997,27 +4875,38 @@ dependencies = [
"indexmap",
"lazy_static",
"libc",
"loupe",
"mach",
"memoffset",
"more-asserts",
"region",
"rkyv",
"scopeguard",
"serde",
"thiserror",
"wasmer-artifact",
"wasmer-types",
"winapi",
]
[[package]]
name = "wasmer-wasi"
version = "2.3.0"
name = "wasmer-vnet"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fadbe31e3c1b6f3e398ad172b169152ae1a743ae6efd5f9ffb34019983319d99"
checksum = "d11caaab8165f3290a1becc041d3226f468fb0a5fedde86251aef116481293c0"
dependencies = [
"bytes",
"thiserror",
"tracing",
"wasmer-vfs",
]
[[package]]
name = "wasmer-wasi"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a37eb23498f5ceabed59144c6b6707707b7ff8dc40ef70bd1d289a657816f729"
dependencies = [
"bytes",
"cfg-if 1.0.0",
"chrono",
"derivative",
"generational-arena",
"getrandom",
"libc",
@ -5025,19 +4914,35 @@ dependencies = [
"tracing",
"wasm-bindgen",
"wasmer",
"wasmer-vbus",
"wasmer-vfs",
"wasmer-vnet",
"wasmer-wasi-local-networking",
"wasmer-wasi-types",
"winapi",
]
[[package]]
name = "wasmer-wasi-types"
version = "2.3.0"
name = "wasmer-wasi-local-networking"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22dc83aadbdf97388de3211cb6f105374f245a3cf2a5c65a16776e7a087a8468"
checksum = "144b8c652f04c78795a72bb520e4214365cf89479777638b1eecec0d8c347977"
dependencies = [
"bytes",
"tracing",
"wasmer-vfs",
"wasmer-vnet",
]
[[package]]
name = "wasmer-wasi-types"
version = "3.0.0-beta"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e822dda0962a1af8e36922b56bbb105dd8c8e46cad1511b9e3da81addf47da0"
dependencies = [
"byteorder",
"time 0.2.27",
"wasmer-derive",
"wasmer-types",
]
@ -5077,17 +4982,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "which"
version = "4.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2"
dependencies = [
"either",
"lazy_static",
"libc",
]
[[package]]
name = "winapi"
version = "0.3.9"

View File

@ -220,8 +220,8 @@ __utils = ["swc_ecma_utils"]
[dependencies]
# 3rd party dependencies
once_cell = { optional = true, version = "1.13.0" }
wasmer = { optional = true, version = "2.3.0", default-features = false }
wasmer-wasi = { optional = true, version = "2.3.0", default-features = false }
wasmer = { optional = true, version = "3.0.0-beta", default-features = false }
wasmer-wasi = { optional = true, version = "3.0.0-beta", default-features = false }
# swc_* dependencies
binding_macros = { optional = true, version = "0.2.3", path = "../binding_macros" }
@ -240,12 +240,12 @@ swc_ecma_visit = { optional = true, version = "0.76.5", path = "../
swc_node_base = { optional = true, version = "0.5.5", path = "../swc_node_base" }
swc_node_bundler = { optional = true, version = "0.0.2", path = "../swc_node_bundler" }
swc_nodejs_common = { optional = true, version = "0.0.1", path = "../swc_nodejs_common" }
swc_plugin = { optional = true, version = "0.89.0", path = "../swc_plugin" }
swc_plugin_macro = { optional = true, version = "0.9.5", path = "../swc_plugin_macro" }
swc_plugin_proxy = { optional = true, version = "0.18.8", path = "../swc_plugin_proxy" }
swc_plugin = { optional = true, version = "0.89.1", path = "../swc_plugin" }
swc_plugin_macro = { optional = true, version = "0.9.6", path = "../swc_plugin_macro" }
swc_plugin_proxy = { optional = true, version = "0.18.9", path = "../swc_plugin_proxy" }
swc_trace_macro = { optional = true, version = "0.1.2", path = "../swc_trace_macro" }
# TODO: eventually swc_plugin_runner needs to remove default features
swc_plugin_runner = { optional = true, version = "0.71.10", path = "../swc_plugin_runner", default-features = false }
swc_plugin_runner = { optional = true, version = "0.71.11", path = "../swc_plugin_runner", default-features = false }
[dev-dependencies]
testing = { version = "0.29.4", path = "../testing" }

View File

@ -1,16 +1,16 @@
[package]
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
description = "SDK for authoring swc plugin"
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
description = "SDK for authoring swc plugin"
documentation = "https://rustdoc.swc.rs/swc_plugin/"
edition = "2018"
license = "Apache-2.0"
name = "swc_plugin"
repository = "https://github.com/swc-project/swc.git"
version = "0.89.0"
edition = "2018"
license = "Apache-2.0"
name = "swc_plugin"
repository = "https://github.com/swc-project/swc.git"
version = "0.89.1"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lib]
bench = false

View File

@ -8,9 +8,9 @@
#[cfg(target_arch = "wasm32")]
#[no_mangle]
#[inline(always)]
pub extern "C" fn __alloc(size: usize) -> *mut u8 {
pub extern "C" fn __alloc(size: i32) -> *mut u8 {
// create a new mutable buffer with specified capacity
let mut buf = Vec::with_capacity(size);
let mut buf = Vec::with_capacity(size as usize);
// take a mutable pointer to the buffer
let ptr = buf.as_mut_ptr();
// take ownership of the memory block and
@ -28,8 +28,8 @@ pub extern "C" fn __alloc(size: usize) -> *mut u8 {
#[cfg(target_arch = "wasm32")]
#[no_mangle]
#[inline(always)]
pub extern "C" fn __free(ptr: *mut u8, size: usize) -> i32 {
let data = unsafe { Vec::from_raw_parts(ptr, size, size) };
pub extern "C" fn __free(ptr: *mut u8, size: i32) -> i32 {
let data = unsafe { Vec::from_raw_parts(ptr, size as usize, size as usize) };
std::mem::drop(data);
0
}

View File

@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0"
name = "swc_plugin_macro"
repository = "https://github.com/swc-project/swc.git"
version = "0.9.5"
version = "0.9.6"
[lib]
bench = false

View File

@ -91,7 +91,7 @@ fn handle_func(func: ItemFn) -> TokenStream {
#[no_mangle]
pub fn #transform_process_impl_ident(
ast_ptr: *const u8, ast_ptr_len: i32,
unresolved_mark: u32, should_enable_comments_proxy: i32) -> i32 {
unresolved_mark: i32, should_enable_comments_proxy: i32) -> i32 {
// Reconstruct `Program` & config string from serialized program
// Host (SWC) should allocate memory, copy bytes and pass ptr to plugin.
let program = unsafe { swc_core::common::plugin::serialized::deserialize_from_ptr(ast_ptr, ast_ptr_len) };
@ -121,7 +121,7 @@ fn handle_func(func: ItemFn) -> TokenStream {
let mut metadata = swc_core::plugin::metadata::TransformPluginProgramMetadata {
comments: plugin_comments_proxy,
source_map: swc_core::plugin::proxies::PluginSourceMapProxy { source_file: swc_core::common::sync::OnceCell::new() },
unresolved_mark: swc_core::common::Mark::from_u32(unresolved_mark),
unresolved_mark: swc_core::common::Mark::from_u32(unresolved_mark as u32),
};
// Take original plugin fn ident, then call it with interop'ed args

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
name = "swc_plugin_proxy"
repository = "https://github.com/swc-project/swc.git"
version = "0.18.8"
version = "0.18.9"
[lib]
bench = false

View File

@ -6,7 +6,7 @@ edition = "2021"
license = "Apache-2.0"
name = "swc_plugin_runner"
repository = "https://github.com/swc-project/swc.git"
version = "0.71.10"
version = "0.71.11"
[lib]
bench = false
@ -39,11 +39,11 @@ swc_plugin_proxy = { version = "0.18.7", path = "../swc_plugin_proxy", features
"plugin-rt",
] }
tracing = "0.1.32"
wasmer = { version = "2.3.0", default-features = false }
wasmer-wasi = { version = "2.3.0", default-features = false }
wasmer = { version = "3.0.0-beta", default-features = false }
wasmer-wasi = { version = "3.0.0-beta", default-features = false }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
wasmer-cache = { version = "2.3.0", optional = true }
wasmer-cache = { version = "3.0.0-beta", optional = true }
[dev-dependencies]
criterion = "0.3"
@ -54,8 +54,8 @@ swc_ecma_visit = { version = "0.76.5", path = "../swc_ecma_visit" }
swc_node_base = { path = "../swc_node_base" }
testing = { version = "0.29.4", path = "../testing" }
# This allows we can run non-wasm32 target build command while some pkg select features for wasmer/js omits its transitive deps
wasmer = "2.3.0"
wasmer-wasi = "2.3.0"
wasmer = "3.0.0-beta"
wasmer-wasi = "3.0.0-beta"
[[bench]]
harness = false

View File

@ -30,7 +30,7 @@ compile_error!(
/// however it is not gauranteed to be compatible across wasmer's
/// internal changes.
/// https://github.com/wasmerio/wasmer/issues/2781
const MODULE_SERIALIZATION_VERSION: &str = "v3";
const MODULE_SERIALIZATION_VERSION: &str = "v4";
/// A shared instance to plugin's module bytecode cache.
pub static PLUGIN_MODULE_CACHE: Lazy<PluginModuleCache> = Lazy::new(Default::default);
@ -133,7 +133,7 @@ impl PluginModuleCache {
/// In actual transform, `plugins` is also being called per each transform.
#[cfg(feature = "filesystem_cache")]
#[tracing::instrument(level = "info", skip_all)]
pub fn load_module(&self, binary_path: &Path) -> Result<Module, Error> {
pub fn load_module(&self, wasmer_store: &Store, binary_path: &Path) -> Result<Module, Error> {
let binary_path = binary_path.to_path_buf();
let mut inner_cache = self.inner.get().expect("Cache should be available").lock();
@ -149,8 +149,6 @@ impl PluginModuleCache {
std::fs::read(&binary_path).context("Cannot read plugin from specified path")?;
let module_bytes_hash = Hash::generate(&module_bytes);
let wasmer_store = Store::default();
let load_cold_wasm_bytes = || {
let span = tracing::span!(
tracing::Level::INFO,
@ -160,7 +158,7 @@ impl PluginModuleCache {
let span_guard = span.enter();
let _lock = self.instantiation_lock.lock();
let ret =
Module::new(&wasmer_store, module_bytes).context("Cannot compile plugin binary");
Module::new(wasmer_store, module_bytes).context("Cannot compile plugin binary");
drop(span_guard);
ret
};
@ -168,7 +166,7 @@ impl PluginModuleCache {
// Try to load compiled bytes from filesystem cache if available.
// Otherwise, cold compile instead.
let module = if let Some(fs_cache) = &mut inner_cache.fs_cache {
let load_result = unsafe { fs_cache.load(&wasmer_store, module_bytes_hash) };
let load_result = unsafe { fs_cache.load(wasmer_store, module_bytes_hash) };
if let Ok(module) = load_result {
module
} else {
@ -189,7 +187,7 @@ impl PluginModuleCache {
#[cfg(feature = "memory_cache")]
#[tracing::instrument(level = "info", skip_all)]
pub fn load_module(&self, binary_path: &Path) -> Result<Module, Error> {
pub fn load_module(&self, wasmer_store: &Store, binary_path: &Path) -> Result<Module, Error> {
let binary_path = binary_path.to_path_buf();
let mut inner_cache = self.inner.get().expect("Cache should be available").lock();
@ -205,8 +203,7 @@ impl PluginModuleCache {
//TODO: In native runtime we have to reconstruct module using raw bytes in
// memory cache. requires https://github.com/wasmerio/wasmer/pull/2821
let wasmer_store = Store::default();
let module = Module::new(&wasmer_store, in_memory_module_bytes)?;
let module = Module::new(wasmer_store, in_memory_module_bytes)?;
Ok(module)
}

View File

@ -1,25 +1,22 @@
use wasmer::{LazyInit, Memory};
use wasmer::Memory;
/// An external environment state imported (declared in host, injected into
/// guest) fn can access. This'll allow host to read from updated state from
/// guest.
///
/// This is `base` environment exposes guest's memory space only. For other
/// This is `base` environment exposes nothing. For other
/// calls requires additional data to be set in the host, separate
/// hostenvironments are declared. Refer `CommentsHostEnvironment` for an
/// example.
///
/// ref: https://docs.wasmer.io/integrations/examples/host-functions#declaring-the-data
#[derive(wasmer::WasmerEnv, Clone)]
#[derive(Clone)]
pub struct BaseHostEnvironment {
#[wasmer(export)]
pub memory: wasmer::LazyInit<Memory>,
pub memory: Option<Memory>,
}
impl BaseHostEnvironment {
pub fn new() -> BaseHostEnvironment {
BaseHostEnvironment {
memory: LazyInit::new(),
}
BaseHostEnvironment { memory: None }
}
}

View File

@ -7,20 +7,18 @@ use swc_common::{
BytePos,
};
use swc_plugin_proxy::COMMENTS;
use wasmer::{LazyInit, Memory, NativeFunc};
use wasmer::{AsStoreMut, FunctionEnvMut, Memory, TypedFunction};
use crate::memory_interop::{allocate_return_values_into_guest, copy_bytes_into_host};
/// External environment state for imported (declared in host, injected into
/// guest) fn for comments proxy.
#[derive(wasmer::WasmerEnv, Clone)]
#[derive(Clone)]
pub struct CommentHostEnvironment {
#[wasmer(export)]
pub memory: wasmer::LazyInit<Memory>,
pub memory: Option<Memory>,
/// Attached imported fn `__alloc` to the hostenvironment to allow any other
/// imported fn can allocate guest's memory space from host runtime.
#[wasmer(export(name = "__alloc"))]
pub alloc_guest_memory: LazyInit<NativeFunc<u32, i32>>,
pub alloc_guest_memory: Option<TypedFunction<i32, i32>>,
/// A buffer to `Comment`, or `Vec<Comment>` plugin need to pass to the host
/// to perform mutable comment operations like `add_leading, or
/// add_leading_comments`. This is vec to serialized bytes, doesn't
@ -32,8 +30,8 @@ pub struct CommentHostEnvironment {
impl CommentHostEnvironment {
pub fn new(mutable_comment_buffer: &Arc<Mutex<Vec<u8>>>) -> CommentHostEnvironment {
CommentHostEnvironment {
memory: LazyInit::default(),
alloc_guest_memory: LazyInit::default(),
memory: None,
alloc_guest_memory: None,
mutable_comment_buffer: mutable_comment_buffer.clone(),
}
}
@ -42,10 +40,14 @@ impl CommentHostEnvironment {
/// Copy given serialized byte into host's comment buffer, subsequent proxy call
/// in the host can read it.
#[tracing::instrument(level = "info", skip_all)]
pub fn copy_comment_to_host_env(env: &CommentHostEnvironment, bytes_ptr: i32, bytes_ptr_len: i32) {
if let Some(memory) = env.memory_ref() {
(*env.mutable_comment_buffer.lock()) =
copy_bytes_into_host(memory, bytes_ptr, bytes_ptr_len);
pub fn copy_comment_to_host_env(
mut env: FunctionEnvMut<CommentHostEnvironment>,
bytes_ptr: i32,
bytes_ptr_len: i32,
) {
if let Some(memory) = env.data().memory.as_ref() {
(*env.data_mut().mutable_comment_buffer.lock()) =
copy_bytes_into_host(&memory.view(&env), bytes_ptr, bytes_ptr_len);
}
}
@ -88,12 +90,16 @@ where
/// Utility fn to unwrap necessary values for the comments, as well as host
/// environment's state.
#[tracing::instrument(level = "info", skip_all)]
fn unwrap_comments_storage_with_env<F, R>(env: &CommentHostEnvironment, f: F, default: R) -> R
fn unwrap_comments_storage_with_env<F, R>(
env: &FunctionEnvMut<CommentHostEnvironment>,
f: F,
default: R,
) -> R
where
F: FnOnce(&SingleThreadedComments, &Memory, &NativeFunc<u32, i32>) -> R,
F: FnOnce(&SingleThreadedComments, &Memory, &TypedFunction<i32, i32>) -> R,
{
if let Some(memory) = env.memory_ref() {
if let Some(alloc_guest_memory) = env.alloc_guest_memory_ref() {
if let Some(memory) = env.data().memory.as_ref() {
if let Some(alloc_guest_memory) = env.data().alloc_guest_memory.as_ref() {
return unwrap_comments_storage_or_default(
|comments| f(comments, memory, alloc_guest_memory),
default,
@ -105,14 +111,14 @@ where
/// Common logics for add_*_comment/comments.
#[tracing::instrument(level = "info", skip_all)]
fn add_comments_inner<F>(env: &CommentHostEnvironment, byte_pos: u32, f: F)
fn add_comments_inner<F>(mut env: FunctionEnvMut<CommentHostEnvironment>, byte_pos: u32, f: F)
where
F: FnOnce(&SingleThreadedComments, BytePos, PluginSerializedBytes),
{
unwrap_comments_storage(|comments| {
let byte_pos = BytePos(byte_pos);
// PluginCommentProxy in the guest should've copied buffer already
let comment_byte = &mut (*env.mutable_comment_buffer.lock());
let comment_byte = &mut (*env.data_mut().mutable_comment_buffer.lock());
let serialized = PluginSerializedBytes::from_slice(comment_byte);
f(comments, byte_pos, serialized);
@ -123,7 +129,7 @@ where
});
}
pub fn add_leading_comment_proxy(env: &CommentHostEnvironment, byte_pos: u32) {
pub fn add_leading_comment_proxy(env: FunctionEnvMut<CommentHostEnvironment>, byte_pos: u32) {
add_comments_inner(env, byte_pos, |comments, byte_pos, serialized| {
comments.add_leading(
byte_pos,
@ -135,7 +141,7 @@ pub fn add_leading_comment_proxy(env: &CommentHostEnvironment, byte_pos: u32) {
}
#[tracing::instrument(level = "info", skip_all)]
pub fn add_leading_comments_proxy(env: &CommentHostEnvironment, byte_pos: u32) {
pub fn add_leading_comments_proxy(env: FunctionEnvMut<CommentHostEnvironment>, byte_pos: u32) {
add_comments_inner(env, byte_pos, |comments, byte_pos, serialized| {
comments.add_leading_comments(
byte_pos,
@ -160,32 +166,37 @@ pub fn move_leading_comments_proxy(from_byte_pos: u32, to_byte_pos: u32) {
#[tracing::instrument(level = "info", skip_all)]
pub fn take_leading_comments_proxy(
env: &CommentHostEnvironment,
mut env: FunctionEnvMut<CommentHostEnvironment>,
byte_pos: u32,
allocated_ret_ptr: i32,
) -> i32 {
unwrap_comments_storage_with_env(
env,
|comments, memory, alloc_guest_memory| {
let leading_comments = comments.take_leading(BytePos(byte_pos));
if let Some(leading_comments) = leading_comments {
let serialized_leading_comments_vec_bytes =
PluginSerializedBytes::try_serialize(&leading_comments)
.expect("Should be serializable");
if let Some(memory) = env.data().memory.clone().as_ref() {
if let Some(alloc_guest_memory) = env.data().alloc_guest_memory.clone().as_ref() {
return unwrap_comments_storage_or_default(
|comments| {
let leading_comments = comments.take_leading(BytePos(byte_pos));
if let Some(leading_comments) = leading_comments {
let serialized_leading_comments_vec_bytes =
PluginSerializedBytes::try_serialize(&leading_comments)
.expect("Should be serializable");
allocate_return_values_into_guest(
memory,
alloc_guest_memory,
allocated_ret_ptr,
&serialized_leading_comments_vec_bytes,
);
1
} else {
0
}
},
0,
)
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized_leading_comments_vec_bytes,
);
1
} else {
0
}
},
0,
);
}
}
0
}
/// Ask to get leading_comments from currently scoped comments held by
@ -195,36 +206,41 @@ pub fn take_leading_comments_proxy(
/// Allocated results should be read through CommentsPtr.
#[tracing::instrument(level = "info", skip_all)]
pub fn get_leading_comments_proxy(
env: &CommentHostEnvironment,
mut env: FunctionEnvMut<CommentHostEnvironment>,
byte_pos: u32,
allocated_ret_ptr: i32,
) -> i32 {
unwrap_comments_storage_with_env(
env,
|comments, memory, alloc_guest_memory| {
let leading_comments = comments.get_leading(BytePos(byte_pos));
if let Some(leading_comments) = leading_comments {
let serialized_leading_comments_vec_bytes =
PluginSerializedBytes::try_serialize(&leading_comments)
.expect("Should be serializable");
if let Some(memory) = env.data().memory.clone().as_ref() {
if let Some(alloc_guest_memory) = env.data().alloc_guest_memory.clone().as_ref() {
return unwrap_comments_storage_or_default(
|comments| {
let leading_comments = comments.get_leading(BytePos(byte_pos));
if let Some(leading_comments) = leading_comments {
let serialized_leading_comments_vec_bytes =
PluginSerializedBytes::try_serialize(&leading_comments)
.expect("Should be serializable");
allocate_return_values_into_guest(
memory,
alloc_guest_memory,
allocated_ret_ptr,
&serialized_leading_comments_vec_bytes,
);
1
} else {
0
}
},
0,
)
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized_leading_comments_vec_bytes,
);
1
} else {
0
}
},
0,
);
}
}
0
}
#[tracing::instrument(level = "info", skip_all)]
pub fn add_trailing_comment_proxy(env: &CommentHostEnvironment, byte_pos: u32) {
pub fn add_trailing_comment_proxy(env: FunctionEnvMut<CommentHostEnvironment>, byte_pos: u32) {
add_comments_inner(env, byte_pos, |comments, byte_pos, serialized| {
comments.add_trailing(
byte_pos,
@ -236,7 +252,7 @@ pub fn add_trailing_comment_proxy(env: &CommentHostEnvironment, byte_pos: u32) {
}
#[tracing::instrument(level = "info", skip_all)]
pub fn add_trailing_comments_proxy(env: &CommentHostEnvironment, byte_pos: u32) {
pub fn add_trailing_comments_proxy(env: FunctionEnvMut<CommentHostEnvironment>, byte_pos: u32) {
add_comments_inner(env, byte_pos, |comments, byte_pos, serialized| {
comments.add_trailing_comments(
byte_pos,
@ -264,62 +280,72 @@ pub fn move_trailing_comments_proxy(from_byte_pos: u32, to_byte_pos: u32) {
#[tracing::instrument(level = "info", skip_all)]
pub fn take_trailing_comments_proxy(
env: &CommentHostEnvironment,
mut env: FunctionEnvMut<CommentHostEnvironment>,
byte_pos: u32,
allocated_ret_ptr: i32,
) -> i32 {
unwrap_comments_storage_with_env(
env,
|comments, memory, alloc_guest_memory| {
let trailing_comments = comments.take_trailing(BytePos(byte_pos));
if let Some(leading_comments) = trailing_comments {
let serialized_leading_comments_vec_bytes =
PluginSerializedBytes::try_serialize(&leading_comments)
.expect("Should be serializable");
if let Some(memory) = env.data().memory.clone().as_ref() {
if let Some(alloc_guest_memory) = env.data().alloc_guest_memory.clone().as_ref() {
return unwrap_comments_storage_or_default(
|comments| {
let trailing_comments = comments.take_trailing(BytePos(byte_pos));
if let Some(leading_comments) = trailing_comments {
let serialized_leading_comments_vec_bytes =
PluginSerializedBytes::try_serialize(&leading_comments)
.expect("Should be serializable");
allocate_return_values_into_guest(
memory,
alloc_guest_memory,
allocated_ret_ptr,
&serialized_leading_comments_vec_bytes,
);
1
} else {
0
}
},
0,
)
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized_leading_comments_vec_bytes,
);
1
} else {
0
}
},
0,
);
}
}
0
}
#[tracing::instrument(level = "info", skip_all)]
pub fn get_trailing_comments_proxy(
env: &CommentHostEnvironment,
mut env: FunctionEnvMut<CommentHostEnvironment>,
byte_pos: u32,
allocated_ret_ptr: i32,
) -> i32 {
unwrap_comments_storage_with_env(
env,
|comments, memory, alloc_guest_memory| {
let trailing_comments = comments.get_trailing(BytePos(byte_pos));
if let Some(leading_comments) = trailing_comments {
let serialized_leading_comments_vec_bytes =
PluginSerializedBytes::try_serialize(&leading_comments)
.expect("Should be serializable");
if let Some(memory) = env.data().memory.clone().as_ref() {
if let Some(alloc_guest_memory) = env.data().alloc_guest_memory.clone().as_ref() {
return unwrap_comments_storage_or_default(
|comments| {
let trailing_comments = comments.get_trailing(BytePos(byte_pos));
if let Some(leading_comments) = trailing_comments {
let serialized_leading_comments_vec_bytes =
PluginSerializedBytes::try_serialize(&leading_comments)
.expect("Should be serializable");
allocate_return_values_into_guest(
memory,
alloc_guest_memory,
allocated_ret_ptr,
&serialized_leading_comments_vec_bytes,
);
1
} else {
0
}
},
0,
)
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized_leading_comments_vec_bytes,
);
1
} else {
0
}
},
0,
);
}
}
0
}
#[tracing::instrument(level = "info", skip_all)]

View File

@ -2,15 +2,21 @@ use swc_common::{
errors::{Diagnostic, HANDLER},
plugin::serialized::PluginSerializedBytes,
};
use wasmer::FunctionEnvMut;
use crate::{host_environment::BaseHostEnvironment, memory_interop::copy_bytes_into_host};
#[tracing::instrument(level = "info", skip_all)]
pub fn emit_diagnostics(env: &BaseHostEnvironment, bytes_ptr: i32, bytes_ptr_len: i32) {
if let Some(memory) = env.memory_ref() {
pub fn emit_diagnostics(
env: FunctionEnvMut<BaseHostEnvironment>,
bytes_ptr: i32,
bytes_ptr_len: i32,
) {
if let Some(memory) = env.data().memory.as_ref() {
if HANDLER.is_set() {
HANDLER.with(|handler| {
let diagnostics_bytes = copy_bytes_into_host(memory, bytes_ptr, bytes_ptr_len);
let diagnostics_bytes =
copy_bytes_into_host(&memory.view(&env), bytes_ptr, bytes_ptr_len);
let serialized = PluginSerializedBytes::from_slice(&diagnostics_bytes[..]);
let diagnostic = PluginSerializedBytes::deserialize::<Diagnostic>(&serialized)
.expect("Should able to be deserialized into diagnostic");

View File

@ -1,6 +1,7 @@
use swc_common::{
hygiene::MutableMarkContext, plugin::serialized::PluginSerializedBytes, Mark, SyntaxContext,
};
use wasmer::{AsStoreMut, FunctionEnvMut};
use crate::{host_environment::BaseHostEnvironment, memory_interop::write_into_memory_view};
@ -30,7 +31,7 @@ pub fn mark_set_builtin_proxy(self_mark: u32, is_builtin: u32) {
/// with return value accordingly.
#[tracing::instrument(level = "info", skip_all)]
pub fn mark_is_descendant_of_proxy(
env: &BaseHostEnvironment,
mut env: FunctionEnvMut<BaseHostEnvironment>,
self_mark: u32,
ancestor: u32,
allocated_ptr: i32,
@ -40,28 +41,43 @@ pub fn mark_is_descendant_of_proxy(
let return_value = self_mark.is_descendant_of(ancestor);
if let Some(memory) = env.memory_ref() {
if let Some(memory) = env.data().memory.clone().as_ref() {
let context = MutableMarkContext(self_mark.as_u32(), 0, return_value as u32);
let serialized_bytes =
PluginSerializedBytes::try_serialize(&context).expect("Should be serializable");
write_into_memory_view(memory, &serialized_bytes, |_| allocated_ptr);
write_into_memory_view(
memory,
&mut env.as_store_mut(),
&serialized_bytes,
|_, _| allocated_ptr,
);
}
}
#[tracing::instrument(level = "info", skip_all)]
pub fn mark_least_ancestor_proxy(env: &BaseHostEnvironment, a: u32, b: u32, allocated_ptr: i32) {
pub fn mark_least_ancestor_proxy(
mut env: FunctionEnvMut<BaseHostEnvironment>,
a: u32,
b: u32,
allocated_ptr: i32,
) {
let a = Mark::from_u32(a);
let b = Mark::from_u32(b);
let return_value = Mark::least_ancestor(a, b).as_u32();
if let Some(memory) = env.memory_ref() {
if let Some(memory) = env.data().memory.clone().as_ref() {
let context = MutableMarkContext(a.as_u32(), b.as_u32(), return_value);
let serialized_bytes =
PluginSerializedBytes::try_serialize(&context).expect("Should be serializable");
write_into_memory_view(memory, &serialized_bytes, |_| allocated_ptr);
write_into_memory_view(
memory,
&mut env.as_store_mut(),
&serialized_bytes,
|_, _| allocated_ptr,
);
}
}
@ -74,7 +90,7 @@ pub fn syntax_context_apply_mark_proxy(self_syntax_context: u32, mark: u32) -> u
#[tracing::instrument(level = "info", skip_all)]
pub fn syntax_context_remove_mark_proxy(
env: &BaseHostEnvironment,
mut env: FunctionEnvMut<BaseHostEnvironment>,
self_mark: u32,
allocated_ptr: i32,
) {
@ -82,12 +98,17 @@ pub fn syntax_context_remove_mark_proxy(
let return_value = self_mark.remove_mark();
if let Some(memory) = env.memory_ref() {
if let Some(memory) = env.data().memory.clone().as_ref() {
let context = MutableMarkContext(self_mark.as_u32(), 0, return_value.as_u32());
let serialized_bytes =
PluginSerializedBytes::try_serialize(&context).expect("Should be serializable");
write_into_memory_view(memory, &serialized_bytes, |_| allocated_ptr);
write_into_memory_view(
memory,
&mut env.as_store_mut(),
&serialized_bytes,
|_, _| allocated_ptr,
);
}
}

View File

@ -5,18 +5,16 @@ use swc_common::plugin::{
metadata::{TransformPluginMetadataContext, TransformPluginMetadataContextKind},
serialized::PluginSerializedBytes,
};
use wasmer::{LazyInit, Memory, NativeFunc};
use wasmer::{AsStoreMut, FunctionEnvMut, Memory, TypedFunction};
use crate::memory_interop::{allocate_return_values_into_guest, copy_bytes_into_host};
#[derive(wasmer::WasmerEnv, Clone)]
#[derive(Clone)]
pub struct MetadataContextHostEnvironment {
#[wasmer(export)]
pub memory: wasmer::LazyInit<Memory>,
pub memory: Option<Memory>,
/// Attached imported fn `__alloc` to the hostenvironment to allow any other
/// imported fn can allocate guest's memory space from host runtime.
#[wasmer(export(name = "__alloc"))]
pub alloc_guest_memory: LazyInit<NativeFunc<u32, i32>>,
pub alloc_guest_memory: Option<TypedFunction<i32, i32>>,
pub metadata_context: Arc<TransformPluginMetadataContext>,
pub transform_plugin_config: Option<serde_json::Value>,
/// A buffer to string key to the context plugin need to pass to the host.
@ -30,8 +28,8 @@ impl MetadataContextHostEnvironment {
mutable_context_key_buffer: &Arc<Mutex<Vec<u8>>>,
) -> Self {
MetadataContextHostEnvironment {
memory: LazyInit::default(),
alloc_guest_memory: LazyInit::default(),
memory: None,
alloc_guest_memory: None,
metadata_context: metadata_context.clone(),
transform_plugin_config: plugin_config.clone(),
mutable_context_key_buffer: mutable_context_key_buffer.clone(),
@ -43,24 +41,24 @@ impl MetadataContextHostEnvironment {
/// in the host can read it.
#[tracing::instrument(level = "info", skip_all)]
pub fn copy_context_key_to_host_env(
env: &MetadataContextHostEnvironment,
mut env: FunctionEnvMut<MetadataContextHostEnvironment>,
bytes_ptr: i32,
bytes_ptr_len: i32,
) {
if let Some(memory) = env.memory_ref() {
(*env.mutable_context_key_buffer.lock()) =
copy_bytes_into_host(memory, bytes_ptr, bytes_ptr_len);
if let Some(memory) = env.data().memory.as_ref() {
(*env.data_mut().mutable_context_key_buffer.lock()) =
copy_bytes_into_host(&memory.view(&env), bytes_ptr, bytes_ptr_len);
}
}
#[tracing::instrument(level = "info", skip_all)]
pub fn get_transform_plugin_config(
env: &MetadataContextHostEnvironment,
mut env: FunctionEnvMut<MetadataContextHostEnvironment>,
allocated_ret_ptr: i32,
) -> i32 {
if let Some(memory) = env.memory_ref() {
if let Some(alloc_guest_memory) = env.alloc_guest_memory_ref() {
let config_value = &env.transform_plugin_config;
if let Some(memory) = env.data().memory.clone().as_ref() {
if let Some(alloc_guest_memory) = env.data().alloc_guest_memory.clone().as_ref() {
let config_value = &env.data().transform_plugin_config;
if let Some(config_value) = config_value {
// Lazy as possible as we can - only deserialize json value if transform plugin
// actually needs it.
@ -71,6 +69,7 @@ pub fn get_transform_plugin_config(
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized,
@ -86,13 +85,17 @@ pub fn get_transform_plugin_config(
#[tracing::instrument(level = "info", skip_all)]
pub fn get_transform_context(
env: &MetadataContextHostEnvironment,
mut env: FunctionEnvMut<MetadataContextHostEnvironment>,
key: u32,
allocated_ret_ptr: i32,
) -> i32 {
if let Some(memory) = env.memory_ref() {
if let Some(alloc_guest_memory) = env.alloc_guest_memory_ref() {
let memory = env.data().memory.clone();
let __alloc = env.data().alloc_guest_memory.clone();
if let Some(memory) = memory.as_ref() {
if let Some(alloc_guest_memory) = __alloc.as_ref() {
let value = env
.data()
.metadata_context
.get(&TransformPluginMetadataContextKind::from(key));
@ -102,6 +105,7 @@ pub fn get_transform_context(
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized,
@ -116,17 +120,18 @@ pub fn get_transform_context(
#[tracing::instrument(level = "info", skip_all)]
pub fn get_experimental_transform_context(
env: &MetadataContextHostEnvironment,
mut env: FunctionEnvMut<MetadataContextHostEnvironment>,
allocated_ret_ptr: i32,
) -> i32 {
if let Some(memory) = env.memory_ref() {
if let Some(alloc_guest_memory) = env.alloc_guest_memory_ref() {
let context_key_buffer = &*env.mutable_context_key_buffer.lock();
if let Some(memory) = env.data().memory.clone().as_ref() {
if let Some(alloc_guest_memory) = env.data().alloc_guest_memory.clone().as_ref() {
let context_key_buffer = env.data().mutable_context_key_buffer.lock().clone();
let key: String = PluginSerializedBytes::from_slice(&context_key_buffer[..])
.deserialize()
.expect("Should able to deserialize");
let value = env
.data()
.metadata_context
.experimental
.get(&key)
@ -138,6 +143,7 @@ pub fn get_experimental_transform_context(
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized,
@ -152,17 +158,18 @@ pub fn get_experimental_transform_context(
#[tracing::instrument(level = "info", skip_all)]
pub fn get_raw_experiemtal_transform_context(
env: &MetadataContextHostEnvironment,
mut env: FunctionEnvMut<MetadataContextHostEnvironment>,
allocated_ret_ptr: i32,
) -> i32 {
if let Some(memory) = env.memory_ref() {
let experimental_context = &env.metadata_context.experimental;
if let Some(memory) = env.data().memory.clone().as_ref() {
let experimental_context = env.data().metadata_context.experimental.clone();
let serialized_experimental_context_bytes =
PluginSerializedBytes::try_serialize(experimental_context)
PluginSerializedBytes::try_serialize(&experimental_context)
.expect("Should be serializable");
if let Some(alloc_guest_memory) = env.alloc_guest_memory_ref() {
if let Some(alloc_guest_memory) = env.data().alloc_guest_memory.clone().as_ref() {
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized_experimental_context_bytes,

View File

@ -41,11 +41,7 @@
* actual vec into guest it'll write pointer to the vec into the struct.
*/
use std::sync::Arc;
use parking_lot::Mutex;
use swc_common::{plugin::metadata::TransformPluginMetadataContext, SourceMap};
use wasmer::{imports, Function, ImportObject, Module};
use wasmer::{imports, Function, FunctionEnv, Imports, Store};
use crate::{
host_environment::BaseHostEnvironment,
@ -63,13 +59,13 @@ use crate::{
},
};
mod comments;
mod handler;
mod hygiene;
mod metadata_context;
mod set_transform_result;
mod source_map;
mod span;
pub(crate) mod comments;
pub(crate) mod handler;
pub(crate) mod hygiene;
pub(crate) mod metadata_context;
pub(crate) mod set_transform_result;
pub(crate) mod source_map;
pub(crate) mod span;
use handler::*;
use hygiene::*;
@ -89,207 +85,144 @@ use self::{
/// Create an ImportObject includes functions to be imported from host to the
/// plugins.
pub(crate) fn build_import_object(
module: &Module,
transform_result: &Arc<Mutex<Vec<u8>>>,
source_map: Arc<SourceMap>,
metadata_context: Arc<TransformPluginMetadataContext>,
plugin_config: Option<serde_json::Value>,
) -> ImportObject {
let wasmer_store = module.store();
wasmer_store: &mut Store,
metadata_env: &FunctionEnv<MetadataContextHostEnvironment>,
transform_env: &FunctionEnv<TransformResultHostEnvironment>,
base_env: &FunctionEnv<BaseHostEnvironment>,
comments_env: &FunctionEnv<CommentHostEnvironment>,
source_map_host_env: &FunctionEnv<SourceMapHostEnvironment>,
) -> Imports {
// metadata
let context_key_buffer = Arc::new(Mutex::new(vec![]));
let copy_context_key_to_host_env_fn_decl = Function::new_native_with_env(
let copy_context_key_to_host_env_fn_decl =
Function::new_typed_with_env(wasmer_store, metadata_env, copy_context_key_to_host_env);
let get_transform_plugin_config_fn_decl =
Function::new_typed_with_env(wasmer_store, metadata_env, get_transform_plugin_config);
let get_transform_context_fn_decl =
Function::new_typed_with_env(wasmer_store, metadata_env, get_transform_context);
let get_experimental_transform_context_fn_decl = Function::new_typed_with_env(
wasmer_store,
MetadataContextHostEnvironment::new(&metadata_context, &plugin_config, &context_key_buffer),
copy_context_key_to_host_env,
);
let get_transform_plugin_config_fn_decl = Function::new_native_with_env(
wasmer_store,
MetadataContextHostEnvironment::new(&metadata_context, &plugin_config, &context_key_buffer),
get_transform_plugin_config,
);
let get_transform_context_fn_decl = Function::new_native_with_env(
wasmer_store,
MetadataContextHostEnvironment::new(&metadata_context, &plugin_config, &context_key_buffer),
get_transform_context,
);
let get_experimental_transform_context_fn_decl = Function::new_native_with_env(
wasmer_store,
MetadataContextHostEnvironment::new(&metadata_context, &plugin_config, &context_key_buffer),
metadata_env,
get_experimental_transform_context,
);
let get_raw_experiemtal_transform_context_fn_decl = Function::new_native_with_env(
let get_raw_experiemtal_transform_context_fn_decl = Function::new_typed_with_env(
wasmer_store,
MetadataContextHostEnvironment::new(&metadata_context, &plugin_config, &context_key_buffer),
metadata_env,
get_raw_experiemtal_transform_context,
);
// transform_result
let set_transform_result_fn_decl = Function::new_native_with_env(
wasmer_store,
TransformResultHostEnvironment::new(transform_result),
set_transform_result,
);
let set_transform_result_fn_decl =
Function::new_typed_with_env(wasmer_store, transform_env, set_transform_result);
// handler
let emit_diagnostics_fn_decl =
Function::new_native_with_env(wasmer_store, BaseHostEnvironment::new(), emit_diagnostics);
Function::new_typed_with_env(wasmer_store, base_env, emit_diagnostics);
// hygiene
let mark_fresh_fn_decl = Function::new_native(wasmer_store, mark_fresh_proxy);
let mark_parent_fn_decl = Function::new_native(wasmer_store, mark_parent_proxy);
let mark_is_builtin_fn_decl = Function::new_native(wasmer_store, mark_is_builtin_proxy);
let mark_set_builtin_fn_decl = Function::new_native(wasmer_store, mark_set_builtin_proxy);
let mark_is_descendant_of_fn_decl = Function::new_native_with_env(
wasmer_store,
BaseHostEnvironment::new(),
mark_is_descendant_of_proxy,
);
let mark_fresh_fn_decl = Function::new_typed(wasmer_store, mark_fresh_proxy);
let mark_parent_fn_decl = Function::new_typed(wasmer_store, mark_parent_proxy);
let mark_is_builtin_fn_decl = Function::new_typed(wasmer_store, mark_is_builtin_proxy);
let mark_set_builtin_fn_decl = Function::new_typed(wasmer_store, mark_set_builtin_proxy);
let mark_is_descendant_of_fn_decl =
Function::new_typed_with_env(wasmer_store, base_env, mark_is_descendant_of_proxy);
let mark_least_ancestor_fn_decl = Function::new_native_with_env(
wasmer_store,
BaseHostEnvironment::new(),
mark_least_ancestor_proxy,
);
let mark_least_ancestor_fn_decl =
Function::new_typed_with_env(wasmer_store, base_env, mark_least_ancestor_proxy);
let syntax_context_apply_mark_fn_decl =
Function::new_native(wasmer_store, syntax_context_apply_mark_proxy);
let syntax_context_remove_mark_fn_decl = Function::new_native_with_env(
wasmer_store,
BaseHostEnvironment::new(),
syntax_context_remove_mark_proxy,
);
Function::new_typed(wasmer_store, syntax_context_apply_mark_proxy);
let syntax_context_remove_mark_fn_decl =
Function::new_typed_with_env(wasmer_store, base_env, syntax_context_remove_mark_proxy);
let syntax_context_outer_fn_decl =
Function::new_native(wasmer_store, syntax_context_outer_proxy);
Function::new_typed(wasmer_store, syntax_context_outer_proxy);
// Span
let span_dummy_with_cmt_fn_decl = Function::new_native(wasmer_store, span_dummy_with_cmt_proxy);
let span_dummy_with_cmt_fn_decl = Function::new_typed(wasmer_store, span_dummy_with_cmt_proxy);
// comments
let comment_buffer = Arc::new(Mutex::new(vec![]));
let copy_comment_to_host_env_fn_decl =
Function::new_typed_with_env(wasmer_store, comments_env, copy_comment_to_host_env);
let copy_comment_to_host_env_fn_decl = Function::new_native_with_env(
wasmer_store,
CommentHostEnvironment::new(&comment_buffer),
copy_comment_to_host_env,
);
let add_leading_comment_fn_decl =
Function::new_typed_with_env(wasmer_store, comments_env, add_leading_comment_proxy);
let add_leading_comment_fn_decl = Function::new_native_with_env(
wasmer_store,
CommentHostEnvironment::new(&comment_buffer),
add_leading_comment_proxy,
);
let add_leading_comments_fn_decl = Function::new_native_with_env(
wasmer_store,
CommentHostEnvironment::new(&comment_buffer),
add_leading_comments_proxy,
);
let add_leading_comments_fn_decl =
Function::new_typed_with_env(wasmer_store, comments_env, add_leading_comments_proxy);
let has_leading_comments_fn_decl =
Function::new_native(wasmer_store, has_leading_comments_proxy);
Function::new_typed(wasmer_store, has_leading_comments_proxy);
let move_leading_comments_fn_decl =
Function::new_native(wasmer_store, move_leading_comments_proxy);
Function::new_typed(wasmer_store, move_leading_comments_proxy);
let take_leading_comments_fn_decl = Function::new_native_with_env(
let take_leading_comments_fn_decl = Function::new_typed_with_env(
wasmer_store,
// take_* doesn't need to share buffer to pass values from plugin to the host - do not
// clone buffer here.
CommentHostEnvironment::new(&Default::default()),
comments_env,
take_leading_comments_proxy,
);
let get_leading_comments_fn_decl = Function::new_native_with_env(
let get_leading_comments_fn_decl = Function::new_typed_with_env(
wasmer_store,
// get_* doesn't need to share buffer to pass values from plugin to the host - do not clone
// buffer here.
CommentHostEnvironment::new(&Default::default()),
comments_env,
get_leading_comments_proxy,
);
let add_trailing_comment_fn_decl = Function::new_native_with_env(
wasmer_store,
CommentHostEnvironment::new(&comment_buffer),
add_trailing_comment_proxy,
);
let add_trailing_comment_fn_decl =
Function::new_typed_with_env(wasmer_store, comments_env, add_trailing_comment_proxy);
let add_trailing_comments_fn_decl = Function::new_native_with_env(
wasmer_store,
CommentHostEnvironment::new(&comment_buffer),
add_trailing_comments_proxy,
);
let add_trailing_comments_fn_decl =
Function::new_typed_with_env(wasmer_store, comments_env, add_trailing_comments_proxy);
let has_trailing_comments_fn_decl =
Function::new_native(wasmer_store, has_trailing_comments_proxy);
Function::new_typed(wasmer_store, has_trailing_comments_proxy);
let move_trailing_comments_fn_decl =
Function::new_native(wasmer_store, move_trailing_comments_proxy);
Function::new_typed(wasmer_store, move_trailing_comments_proxy);
let take_trailing_comments_fn_decl = Function::new_native_with_env(
let take_trailing_comments_fn_decl = Function::new_typed_with_env(
wasmer_store,
// take_* doesn't need to share buffer to pass values from plugin to the host - do not
// clone buffer here.
CommentHostEnvironment::new(&Default::default()),
comments_env,
take_trailing_comments_proxy,
);
let get_trailing_comments_fn_decl = Function::new_native_with_env(
let get_trailing_comments_fn_decl = Function::new_typed_with_env(
wasmer_store,
// get_* doesn't need to share buffer to pass values from plugin to the host - do not clone
// buffer here.
CommentHostEnvironment::new(&Default::default()),
comments_env,
get_trailing_comments_proxy,
);
let add_pure_comment_fn_decl = Function::new_native(wasmer_store, add_pure_comment_proxy);
let add_pure_comment_fn_decl = Function::new_typed(wasmer_store, add_pure_comment_proxy);
// source_map
let source_map_buffer = Arc::new(Mutex::new(vec![]));
let source_map = Arc::new(Mutex::new(source_map));
let lookup_char_pos_source_map_fn_decl =
Function::new_typed_with_env(wasmer_store, source_map_host_env, lookup_char_pos_proxy);
let lookup_char_pos_source_map_fn_decl = Function::new_native_with_env(
wasmer_store,
SourceMapHostEnvironment::new(&source_map, &source_map_buffer),
lookup_char_pos_proxy,
);
let doctest_offset_line_fn_decl =
Function::new_typed_with_env(wasmer_store, source_map_host_env, doctest_offset_line_proxy);
let doctest_offset_line_fn_decl = Function::new_native_with_env(
wasmer_store,
SourceMapHostEnvironment::new(&source_map, &source_map_buffer),
doctest_offset_line_proxy,
);
let merge_spans_fn_decl =
Function::new_typed_with_env(wasmer_store, source_map_host_env, merge_spans_proxy);
let merge_spans_fn_decl = Function::new_native_with_env(
wasmer_store,
SourceMapHostEnvironment::new(&source_map, &source_map_buffer),
merge_spans_proxy,
);
let span_to_string_fn_decl =
Function::new_typed_with_env(wasmer_store, source_map_host_env, span_to_string_proxy);
let span_to_string_fn_decl = Function::new_native_with_env(
wasmer_store,
SourceMapHostEnvironment::new(&source_map, &source_map_buffer),
span_to_string_proxy,
);
let span_to_filename_fn_decl =
Function::new_typed_with_env(wasmer_store, source_map_host_env, span_to_filename_proxy);
let span_to_filename_fn_decl = Function::new_native_with_env(
wasmer_store,
SourceMapHostEnvironment::new(&source_map, &source_map_buffer),
span_to_filename_proxy,
);
let span_to_lines_fn_decl =
Function::new_typed_with_env(wasmer_store, source_map_host_env, span_to_lines_proxy);
let span_to_lines_fn_decl = Function::new_native_with_env(
wasmer_store,
SourceMapHostEnvironment::new(&source_map, &source_map_buffer),
span_to_lines_proxy,
);
let lookup_byte_offset_fn_decl = Function::new_native_with_env(
wasmer_store,
SourceMapHostEnvironment::new(&source_map, &source_map_buffer),
lookup_byte_offset_proxy,
);
let lookup_byte_offset_fn_decl =
Function::new_typed_with_env(wasmer_store, source_map_host_env, lookup_byte_offset_proxy);
imports! {
"env" => {

View File

@ -1,7 +1,7 @@
use std::sync::Arc;
use parking_lot::Mutex;
use wasmer::{LazyInit, Memory};
use wasmer::{FunctionEnvMut, Memory};
use crate::memory_interop::copy_bytes_into_host;
@ -10,17 +10,16 @@ use crate::memory_interop::copy_bytes_into_host;
///
/// When plugin performs its transform it'll fill in `transform_result` with
/// serialized result. Host will reconstruct AST from those value.
#[derive(wasmer::WasmerEnv, Clone)]
#[derive(Clone)]
pub struct TransformResultHostEnvironment {
#[wasmer(export)]
pub memory: wasmer::LazyInit<Memory>,
pub memory: Option<Memory>,
pub transform_result: Arc<Mutex<Vec<u8>>>,
}
impl TransformResultHostEnvironment {
pub fn new(transform_result: &Arc<Mutex<Vec<u8>>>) -> TransformResultHostEnvironment {
TransformResultHostEnvironment {
memory: LazyInit::default(),
memory: None,
transform_result: transform_result.clone(),
}
}
@ -32,11 +31,12 @@ impl TransformResultHostEnvironment {
/// this to set its result back to host.
#[tracing::instrument(level = "info", skip_all)]
pub fn set_transform_result(
env: &TransformResultHostEnvironment,
mut env: FunctionEnvMut<TransformResultHostEnvironment>,
bytes_ptr: i32,
bytes_ptr_len: i32,
) {
if let Some(memory) = env.memory_ref() {
(*env.transform_result.lock()) = copy_bytes_into_host(memory, bytes_ptr, bytes_ptr_len);
if let Some(memory) = env.data().memory.as_ref() {
(*env.data_mut().transform_result.lock()) =
copy_bytes_into_host(&memory.view(&env), bytes_ptr, bytes_ptr_len);
}
}

View File

@ -6,20 +6,18 @@ use swc_common::{
source_map::{PartialFileLines, PartialLoc},
BytePos, SourceMap, Span, SyntaxContext,
};
use wasmer::{LazyInit, Memory, NativeFunc};
use wasmer::{AsStoreMut, FunctionEnvMut, Memory, TypedFunction};
use crate::memory_interop::{allocate_return_values_into_guest, write_into_memory_view};
/// External environment state for imported (declared in host, injected into
/// guest) fn for source map proxy.
#[derive(wasmer::WasmerEnv, Clone)]
#[derive(Clone)]
pub struct SourceMapHostEnvironment {
#[wasmer(export)]
pub memory: wasmer::LazyInit<Memory>,
pub memory: Option<Memory>,
/// Attached imported fn `__alloc` to the hostenvironment to allow any other
/// imported fn can allocate guest's memory space from host runtime.
#[wasmer(export(name = "__alloc"))]
pub alloc_guest_memory: LazyInit<NativeFunc<u32, i32>>,
pub allocate_guest_memory: Option<TypedFunction<i32, i32>>,
pub source_map: Arc<Mutex<Arc<SourceMap>>>,
/// A buffer to non-determined size of return value from the host.
pub mutable_source_map_buffer: Arc<Mutex<Vec<u8>>>,
@ -31,8 +29,8 @@ impl SourceMapHostEnvironment {
mutable_source_map_buffer: &Arc<Mutex<Vec<u8>>>,
) -> SourceMapHostEnvironment {
SourceMapHostEnvironment {
memory: LazyInit::default(),
alloc_guest_memory: LazyInit::default(),
memory: None,
allocate_guest_memory: None,
source_map: source_map.clone(),
mutable_source_map_buffer: mutable_source_map_buffer.clone(),
}
@ -47,13 +45,13 @@ impl SourceMapHostEnvironment {
/// `SourceFile` is needed.
#[tracing::instrument(level = "info", skip_all)]
pub fn lookup_char_pos_proxy(
env: &SourceMapHostEnvironment,
mut env: FunctionEnvMut<SourceMapHostEnvironment>,
byte_pos: u32,
should_include_source_file: i32,
allocated_ret_ptr: i32,
) -> i32 {
if let Some(memory) = env.memory_ref() {
let original_loc = (env.source_map.lock()).lookup_char_pos(BytePos(byte_pos));
if let Some(memory) = env.data().memory.clone().as_ref() {
let original_loc = (env.data().source_map.lock()).lookup_char_pos(BytePos(byte_pos));
let ret = PartialLoc {
source_file: if should_include_source_file == 0 {
None
@ -68,9 +66,10 @@ pub fn lookup_char_pos_proxy(
let serialized_loc_bytes =
PluginSerializedBytes::try_serialize(&ret).expect("Should be serializable");
if let Some(alloc_guest_memory) = env.alloc_guest_memory_ref() {
if let Some(alloc_guest_memory) = env.data().allocate_guest_memory.clone().as_ref() {
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized_loc_bytes,
@ -85,14 +84,14 @@ pub fn lookup_char_pos_proxy(
}
#[tracing::instrument(level = "info", skip_all)]
pub fn doctest_offset_line_proxy(env: &SourceMapHostEnvironment, orig: u32) -> u32 {
(env.source_map.lock()).doctest_offset_line(orig as usize) as u32
pub fn doctest_offset_line_proxy(env: FunctionEnvMut<SourceMapHostEnvironment>, orig: u32) -> u32 {
(env.data().source_map.lock()).doctest_offset_line(orig as usize) as u32
}
#[allow(clippy::too_many_arguments)]
#[tracing::instrument(level = "info", skip_all)]
pub fn merge_spans_proxy(
env: &SourceMapHostEnvironment,
mut env: FunctionEnvMut<SourceMapHostEnvironment>,
lhs_lo: u32,
lhs_hi: u32,
lhs_ctxt: u32,
@ -101,7 +100,7 @@ pub fn merge_spans_proxy(
rhs_ctxt: u32,
allocated_ptr: i32,
) -> i32 {
if let Some(memory) = env.memory_ref() {
if let Some(memory) = env.data().memory.clone().as_ref() {
let sp_lhs = Span {
lo: BytePos(lhs_lo),
hi: BytePos(lhs_hi),
@ -114,11 +113,16 @@ pub fn merge_spans_proxy(
ctxt: SyntaxContext::from_u32(rhs_ctxt),
};
let ret = (env.source_map.lock()).merge_spans(sp_lhs, sp_rhs);
let ret = (env.data().source_map.lock()).merge_spans(sp_lhs, sp_rhs);
if let Some(span) = ret {
let serialized_bytes =
PluginSerializedBytes::try_serialize(&span).expect("Should be serializable");
write_into_memory_view(memory, &serialized_bytes, |_| allocated_ptr);
write_into_memory_view(
memory,
&mut env.as_store_mut(),
&serialized_bytes,
|_, _| allocated_ptr,
);
1
} else {
0
@ -130,21 +134,21 @@ pub fn merge_spans_proxy(
#[tracing::instrument(level = "info", skip_all)]
pub fn span_to_lines_proxy(
env: &SourceMapHostEnvironment,
mut env: FunctionEnvMut<SourceMapHostEnvironment>,
span_lo: u32,
span_hi: u32,
span_ctxt: u32,
should_request_source_file: i32,
allocated_ret_ptr: i32,
) -> i32 {
if let Some(memory) = env.memory_ref() {
if let Some(memory) = env.data().memory.clone().as_ref() {
let span = Span {
lo: BytePos(span_lo),
hi: BytePos(span_hi),
ctxt: SyntaxContext::from_u32(span_ctxt),
};
let ret = (env.source_map.lock())
let ret = (env.data().source_map.lock())
.span_to_lines(span)
.map(|lines| PartialFileLines {
file: if should_request_source_file == 0 {
@ -158,9 +162,10 @@ pub fn span_to_lines_proxy(
let serialized_loc_bytes =
PluginSerializedBytes::try_serialize(&ret).expect("Should be serializable");
if let Some(alloc_guest_memory) = env.alloc_guest_memory_ref() {
if let Some(alloc_guest_memory) = env.data().allocate_guest_memory.clone().as_ref() {
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized_loc_bytes,
@ -176,20 +181,21 @@ pub fn span_to_lines_proxy(
#[tracing::instrument(level = "info", skip_all)]
pub fn lookup_byte_offset_proxy(
env: &SourceMapHostEnvironment,
mut env: FunctionEnvMut<SourceMapHostEnvironment>,
byte_pos: u32,
allocated_ret_ptr: i32,
) -> i32 {
if let Some(memory) = env.memory_ref() {
if let Some(memory) = env.data().memory.clone().as_ref() {
let byte_pos = BytePos(byte_pos);
let ret = (env.source_map.lock()).lookup_byte_offset(byte_pos);
let ret = (env.data().source_map.lock()).lookup_byte_offset(byte_pos);
let serialized_loc_bytes =
PluginSerializedBytes::try_serialize(&ret).expect("Should be serializable");
if let Some(alloc_guest_memory) = env.alloc_guest_memory_ref() {
if let Some(alloc_guest_memory) = env.data().allocate_guest_memory.clone().as_ref() {
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized_loc_bytes,
@ -205,25 +211,26 @@ pub fn lookup_byte_offset_proxy(
#[tracing::instrument(level = "info", skip_all)]
pub fn span_to_string_proxy(
env: &SourceMapHostEnvironment,
mut env: FunctionEnvMut<SourceMapHostEnvironment>,
span_lo: u32,
span_hi: u32,
span_ctxt: u32,
allocated_ret_ptr: i32,
) -> i32 {
if let Some(memory) = env.memory_ref() {
if let Some(memory) = env.data().memory.clone().as_ref() {
let span = Span {
lo: BytePos(span_lo),
hi: BytePos(span_hi),
ctxt: SyntaxContext::from_u32(span_ctxt),
};
let ret = (env.source_map.lock()).span_to_string(span);
let ret = (env.data().source_map.lock()).span_to_string(span);
let serialized_loc_bytes =
PluginSerializedBytes::try_serialize(&ret).expect("Should be serializable");
if let Some(alloc_guest_memory) = env.alloc_guest_memory_ref() {
if let Some(alloc_guest_memory) = env.data().allocate_guest_memory.clone().as_ref() {
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized_loc_bytes,
@ -239,25 +246,26 @@ pub fn span_to_string_proxy(
#[tracing::instrument(level = "info", skip_all)]
pub fn span_to_filename_proxy(
env: &SourceMapHostEnvironment,
mut env: FunctionEnvMut<SourceMapHostEnvironment>,
span_lo: u32,
span_hi: u32,
span_ctxt: u32,
allocated_ret_ptr: i32,
) -> i32 {
if let Some(memory) = env.memory_ref() {
if let Some(memory) = env.data().memory.clone().as_ref() {
let span = Span {
lo: BytePos(span_lo),
hi: BytePos(span_hi),
ctxt: SyntaxContext::from_u32(span_ctxt),
};
let ret = (env.source_map.lock()).span_to_filename(span);
let ret = (env.data().source_map.lock()).span_to_filename(span);
let serialized_loc_bytes =
PluginSerializedBytes::try_serialize(&ret).expect("Should be serializable");
if let Some(alloc_guest_memory) = env.alloc_guest_memory_ref() {
if let Some(alloc_guest_memory) = env.data().allocate_guest_memory.clone().as_ref() {
allocate_return_values_into_guest(
memory,
&mut env.as_store_mut(),
alloc_guest_memory,
allocated_ret_ptr,
&serialized_loc_bytes,

View File

@ -3,30 +3,69 @@ use std::{env, sync::Arc};
use anyhow::{Context, Error};
use parking_lot::Mutex;
use swc_common::{plugin::metadata::TransformPluginMetadataContext, SourceMap};
use wasmer::{ChainableNamedResolver, Instance};
use wasmer::{FunctionEnv, Instance, Store};
use wasmer_wasi::{is_wasi_module, WasiState};
use crate::imported_fn::build_import_object;
use crate::{
host_environment::BaseHostEnvironment,
imported_fn::{
build_import_object, comments::CommentHostEnvironment,
metadata_context::MetadataContextHostEnvironment,
set_transform_result::TransformResultHostEnvironment, source_map::SourceMapHostEnvironment,
},
};
#[tracing::instrument(level = "info", skip_all)]
pub fn load_plugin(
store: &mut Store,
plugin_path: &std::path::Path,
cache: &once_cell::sync::Lazy<crate::cache::PluginModuleCache>,
source_map: &Arc<SourceMap>,
metadata_context: &Arc<TransformPluginMetadataContext>,
plugin_config: Option<serde_json::Value>,
) -> Result<(Instance, Arc<Mutex<Vec<u8>>>), Error> {
let module = cache.load_module(plugin_path);
let module = cache.load_module(store, plugin_path);
return match module {
Ok(module) => {
let context_key_buffer = Arc::new(Mutex::new(vec![]));
let metadata_env = FunctionEnv::new(
store,
MetadataContextHostEnvironment::new(
metadata_context,
&plugin_config,
&context_key_buffer,
),
);
let transform_result: Arc<Mutex<Vec<u8>>> = Arc::new(Mutex::new(vec![]));
let import_object = build_import_object(
&module,
&transform_result,
source_map.clone(),
metadata_context.clone(),
plugin_config,
let transform_env = FunctionEnv::new(
store,
TransformResultHostEnvironment::new(&transform_result),
);
let base_env = FunctionEnv::new(store, BaseHostEnvironment::new());
let comment_buffer = Arc::new(Mutex::new(vec![]));
let comments_env =
FunctionEnv::new(store, CommentHostEnvironment::new(&comment_buffer));
let source_map_buffer = Arc::new(Mutex::new(vec![]));
let source_map = Arc::new(Mutex::new(source_map.clone()));
let source_map_host_env = FunctionEnv::new(
store,
SourceMapHostEnvironment::new(&source_map, &source_map_buffer),
);
let mut import_object = build_import_object(
store,
&metadata_env,
&transform_env,
&base_env,
&comments_env,
&source_map_host_env,
);
// Plugin binary can be either wasm32-wasi or wasm32-unknown-unknown.
@ -57,14 +96,39 @@ pub fn load_plugin(
&mut wasi_env
};
let mut wasi_env = wasi_env.finalize()?;
let wasi_env = wasi_env.finalize(store)?;
// Generate an `ImportObject` from wasi_env, overwrite into imported_object
let wasi_env_import_object = wasi_env.import_object(&module)?;
let chained_resolver = import_object.chain_front(wasi_env_import_object);
Instance::new(&module, &chained_resolver)
let wasi_env_import_object = wasi_env.import_object(store, &module)?;
import_object.extend(&wasi_env_import_object);
let instance = Instance::new(store, &module, &import_object);
if let Ok(instance) = instance {
// For WASI, don't forget to import memory to WasiEnv
let memory = instance.exports.get_memory("memory")?;
let alloc = instance.exports.get_typed_function(store, "__alloc")?;
wasi_env.data_mut(store).set_memory(memory.clone());
// Unlike wasmer@2, have to manually `import` memory / necessary functions from
// the guest into env.
metadata_env.as_mut(store).memory = Some(memory.clone());
metadata_env.as_mut(store).alloc_guest_memory = Some(alloc.clone());
transform_env.as_mut(store).memory = Some(memory.clone());
base_env.as_mut(store).memory = Some(memory.clone());
comments_env.as_mut(store).memory = Some(memory.clone());
comments_env.as_mut(store).alloc_guest_memory = Some(alloc);
source_map_host_env.as_mut(store).memory = Some(memory.clone());
Ok(instance)
} else {
instance
}
} else {
Instance::new(&module, &import_object)
Instance::new(store, &module, &import_object)
};
instance

View File

@ -1,58 +1,39 @@
use swc_common::plugin::serialized::PluginSerializedBytes;
use swc_plugin_proxy::AllocatedBytesPtr;
use wasmer::{Array, Memory, NativeFunc, WasmPtr};
use wasmer::{Memory, MemoryView, StoreMut, TypedFunction, WasmPtr};
#[tracing::instrument(level = "info", skip_all)]
pub fn copy_bytes_into_host(memory: &Memory, bytes_ptr: i32, bytes_ptr_len: i32) -> Vec<u8> {
let ptr: WasmPtr<u8, Array> = WasmPtr::new(bytes_ptr as _);
pub fn copy_bytes_into_host(memory: &MemoryView, bytes_ptr: i32, bytes_ptr_len: i32) -> Vec<u8> {
let ptr: WasmPtr<u8> = WasmPtr::new(bytes_ptr as _);
let values = ptr.slice(memory, bytes_ptr_len as u32).expect("xxx");
// Deref & read through plugin's wasm memory space via returned ptr
let derefed_ptr = ptr
.deref(memory, 0, bytes_ptr_len as u32)
.expect("Should able to deref from given ptr");
derefed_ptr
.iter()
.enumerate()
.take(bytes_ptr_len as usize)
.map(|(_size, cell)| cell.get())
.collect::<Vec<u8>>()
values
.read_to_vec()
.expect("Should able to read memory from given ptr")
}
/// Locate a view from given memory, write serialized bytes into.
#[tracing::instrument(level = "info", skip_all)]
pub fn write_into_memory_view<F>(
memory: &Memory,
store: &mut StoreMut,
serialized_bytes: &PluginSerializedBytes,
get_allocated_ptr: F,
) -> (i32, i32)
where
F: Fn(usize) -> i32,
F: Fn(&mut StoreMut, usize) -> i32,
{
let serialized_len = serialized_bytes.as_ptr().1;
let ptr_start = get_allocated_ptr(serialized_len);
let ptr_start = get_allocated_ptr(store, serialized_len);
let ptr_start_size = ptr_start
.try_into()
.expect("Should be able to convert to usize");
let serialized_len_size: u32 = serialized_len
.try_into()
.expect("Should be able to convert to u32");
// Note: it's important to get a view from memory _after_ alloc completes
let view = memory.view::<u8>();
// Get a subarray for current memoryview starting from ptr address we just
// allocated above, perform copying into specified ptr. Wasm's memory layout
// is linear and we have atomic guarantee by not having any thread access,
// so can safely get subarray from allocated ptr address.
//
// If we want safer operation instead, refer previous implementation
// https://github.com/swc-project/swc/blob/1ef8f3749b6454eb7d40a36a5f9366137fa97928/crates/swc_plugin_runner/src/lib.rs#L56-L61
unsafe {
view.subarray(ptr_start_size, ptr_start_size + serialized_len_size)
.copy_from(serialized_bytes.as_slice());
}
let view = memory.view(store);
view.write(ptr_start_size, serialized_bytes.as_slice())
.expect("Should able to write into memory view");
(
ptr_start,
@ -69,14 +50,15 @@ where
#[tracing::instrument(level = "info", skip_all)]
pub fn allocate_return_values_into_guest(
memory: &Memory,
alloc_guest_memory: &NativeFunc<u32, i32>,
store: &mut StoreMut,
alloc_guest_memory: &TypedFunction<i32, i32>,
allocated_ret_ptr: i32,
serialized_bytes: &PluginSerializedBytes,
) {
let serialized_bytes_len = serialized_bytes.as_ptr().1;
let (allocated_ptr, allocated_ptr_len) =
write_into_memory_view(memory, serialized_bytes, |_| {
write_into_memory_view(memory, store, serialized_bytes, |s, _| {
// In most cases our host-plugin trampoline works in a way that
// plugin pre-allocates
// memory before calling host imported fn. But in case of
@ -86,6 +68,7 @@ pub fn allocate_return_values_into_guest(
// hostenvironment.
alloc_guest_memory
.call(
s,
serialized_bytes_len
.try_into()
.expect("Should be able to convert size"),
@ -94,9 +77,12 @@ pub fn allocate_return_values_into_guest(
});
let allocated_bytes = AllocatedBytesPtr(allocated_ptr, allocated_ptr_len);
// Retuning (allocated_ptr, len) into caller (plugin)
let comment_ptr_serialized =
PluginSerializedBytes::try_serialize(&allocated_bytes).expect("Should be serializable");
write_into_memory_view(memory, &comment_ptr_serialized, |_| allocated_ret_ptr);
write_into_memory_view(memory, store, &comment_ptr_serialized, |_, _| {
allocated_ret_ptr
});
}

View File

@ -14,14 +14,14 @@ use swc_common::{
},
SourceMap,
};
use wasmer::Instance;
use wasmer::{AsStoreMut, Instance, Store, TypedFunction};
use crate::memory_interop::write_into_memory_view;
/// A struct encapsule executing a plugin's transform interop to its teardown
pub struct TransformExecutor {
// Main transform interface plugin exports
exported_plugin_transform: wasmer::NativeFunc<(i32, i32, u32, i32), i32>,
exported_plugin_transform: TypedFunction<(i32, i32, i32, i32), i32>,
// Schema version interface exports
#[cfg_attr(
not(any(
@ -30,14 +30,15 @@ pub struct TransformExecutor {
)),
allow(unused)
)]
exported_plugin_transform_schema_version: wasmer::NativeFunc<(), u32>,
exported_plugin_transform_schema_version: TypedFunction<(), u32>,
// `__free` function automatically exported via swc_plugin sdk to allow deallocation in guest
// memory space
exported_plugin_free: wasmer::NativeFunc<(i32, i32), i32>,
exported_plugin_free: TypedFunction<(i32, i32), i32>,
// `__alloc` function automatically exported via swc_plugin sdk to allow allocation in guest
// memory space
exported_plugin_alloc: wasmer::NativeFunc<u32, i32>,
exported_plugin_alloc: TypedFunction<i32, i32>,
instance: Instance,
store: Store,
// Reference to the pointers successfully allocated which'll be freed by Drop.
allocated_ptr_vec: Vec<(i32, i32)>,
transform_result: Arc<Mutex<Vec<u8>>>,
@ -55,7 +56,9 @@ impl TransformExecutor {
metadata_context: &Arc<TransformPluginMetadataContext>,
plugin_config: Option<serde_json::Value>,
) -> Result<TransformExecutor, Error> {
let mut store = Store::default();
let (instance, transform_result) = crate::load_plugin::load_plugin(
&mut store,
path,
cache,
source_map,
@ -63,27 +66,22 @@ impl TransformExecutor {
plugin_config,
)?;
let tracker = TransformExecutor {
let executor = TransformExecutor {
exported_plugin_transform: instance
.exports
.get_native_function::<(i32, i32, u32, i32), i32>(
"__transform_plugin_process_impl",
)?,
.get_typed_function(&store, "__transform_plugin_process_impl")?,
exported_plugin_transform_schema_version: instance
.exports
.get_native_function::<(), u32>("__get_transform_plugin_schema_version")?,
exported_plugin_free: instance
.exports
.get_native_function::<(i32, i32), i32>("__free")?,
exported_plugin_alloc: instance
.exports
.get_native_function::<u32, i32>("__alloc")?,
.get_typed_function(&store, "__get_transform_plugin_schema_version")?,
exported_plugin_free: instance.exports.get_typed_function(&store, "__free")?,
exported_plugin_alloc: instance.exports.get_typed_function(&store, "__alloc")?,
instance,
store,
allocated_ptr_vec: Vec::with_capacity(3),
transform_result,
};
Ok(tracker)
Ok(executor)
}
/// Copy host's serialized bytes into guest (plugin)'s allocated memory.
@ -94,11 +92,16 @@ impl TransformExecutor {
) -> Result<(i32, i32), Error> {
let memory = self.instance.exports.get_memory("memory")?;
let ptr = write_into_memory_view(memory, serialized_bytes, |serialized_len| {
self.exported_plugin_alloc
.call(serialized_len.try_into().expect(""))
.expect("")
});
let ptr = write_into_memory_view(
memory,
&mut self.store.as_store_mut(),
serialized_bytes,
|s, serialized_len| {
self.exported_plugin_alloc
.call(s, serialized_len.try_into().expect(""))
.expect("")
},
);
self.allocated_ptr_vec.push(ptr);
Ok(ptr)
@ -140,12 +143,15 @@ impl TransformExecutor {
* current runtime.
*/
#[allow(unreachable_code)]
pub fn is_transform_schema_compatible(&self) -> Result<bool, Error> {
pub fn is_transform_schema_compatible(&mut self) -> Result<bool, Error> {
#[cfg(any(
feature = "plugin_transform_schema_v1",
feature = "plugin_transform_schema_vtest"
))]
return match self.exported_plugin_transform_schema_version.call() {
return match self
.exported_plugin_transform_schema_version
.call(&mut self.store)
{
Ok(plugin_schema_version) => {
let host_schema_version = PLUGIN_TRANSFORM_AST_SCHEMA_VERSION;
@ -180,9 +186,10 @@ impl TransformExecutor {
let guest_program_ptr = self.write_bytes_into_guest(program)?;
let result = self.exported_plugin_transform.call(
&mut self.store,
guest_program_ptr.0,
guest_program_ptr.1,
unresolved_mark.as_u32(),
unresolved_mark.as_u32() as i32,
should_enable_comments_proxy,
)?;
@ -194,7 +201,7 @@ impl Drop for TransformExecutor {
fn drop(&mut self) {
for ptr in self.allocated_ptr_vec.iter() {
self.exported_plugin_free
.call(ptr.0, ptr.1)
.call(&mut self.store, ptr.0, ptr.1)
.expect("Failed to free memory allocated in the plugin");
}
}

View File

@ -928,9 +928,9 @@ dependencies = [
[[package]]
name = "rkyv"
version = "0.7.37"
version = "0.7.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f08c8062c1fe1253064043b8fc07bfea1b9702b71b4a86c11ea3588183b12e1"
checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15"
dependencies = [
"bytecheck",
"hashbrown",
@ -942,9 +942,9 @@ dependencies = [
[[package]]
name = "rkyv_derive"
version = "0.7.37"
version = "0.7.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e289706df51226e84814bf6ba1a9e1013112ae29bc7a9878f73fce360520c403"
checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4"
dependencies = [
"proc-macro2",
"quote",
@ -1175,7 +1175,7 @@ dependencies = [
[[package]]
name = "swc_atoms"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"bytecheck",
"once_cell",
@ -1188,7 +1188,7 @@ dependencies = [
[[package]]
name = "swc_common"
version = "0.27.6"
version = "0.27.9"
dependencies = [
"ahash",
"anyhow",
@ -1219,7 +1219,7 @@ dependencies = [
[[package]]
name = "swc_core"
version = "0.7.6"
version = "0.7.15"
dependencies = [
"once_cell",
"swc_atoms",
@ -1235,7 +1235,7 @@ dependencies = [
[[package]]
name = "swc_ecma_ast"
version = "0.90.7"
version = "0.90.8"
dependencies = [
"bitflags",
"bytecheck",
@ -1327,7 +1327,7 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_base"
version = "0.103.6"
version = "0.103.7"
dependencies = [
"better_scoped_tls",
"bitflags",
@ -1435,14 +1435,14 @@ dependencies = [
[[package]]
name = "swc_plugin"
version = "0.89.0"
version = "0.89.1"
dependencies = [
"once_cell",
]
[[package]]
name = "swc_plugin_macro"
version = "0.9.2"
version = "0.9.6"
dependencies = [
"proc-macro2",
"quote",
@ -1451,7 +1451,7 @@ dependencies = [
[[package]]
name = "swc_plugin_proxy"
version = "0.18.5"
version = "0.18.9"
dependencies = [
"better_scoped_tls",
"bytecheck",