Merge remote-tracking branch 'origin/master' into wasix

This commit is contained in:
Christoph Herzog
2023-01-28 08:30:02 +01:00
27 changed files with 463 additions and 709 deletions

View File

@ -129,7 +129,7 @@ jobs:
build-what: [
{
key: capi,
build-cmd: 'make build-capi',
build-cmd: 'make build-capi && make package-capi',
name: 'Build C-API'
},
{
@ -159,6 +159,26 @@ jobs:
PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig
PKG_CONFIG_ALLOW_CROSS: true
ENABLE_LLVM: 0
- name: Dist
if: ${{ matrix.build-what.key == 'capi' }}
run: |
make distribution
env:
CARGO_BINARY: docker run -v /var/run/docker.sock:/var/run/docker.sock -v ${GITHUB_WORKSPACE}:/project -w /project wasmer/aarch64 cross
CROSS_DOCKER_IN_DOCKER: true
CARGO_TARGET: aarch64-unknown-linux-gnu
PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig
PKG_CONFIG_ALLOW_CROSS: true
TARGET: aarch64-unknown-linux-gnu
TARGET_DIR: target/aarch64-unknown-linux-gnu/release
- name: Upload Artifacts
if: ${{ matrix.build-what.key == 'capi' }}
uses: actions/upload-artifact@v2
with:
name: capi-linux-aarch64
path: dist
if-no-files-found: error
retention-days: 2
build:
name: ${{ matrix.build-what.name }} on ${{ matrix.metadata.build }}
@ -575,6 +595,73 @@ jobs:
aws-endpoint: https://storage.googleapis.com
aws-s3-bucket-endpoint: false
aws-s3-force-path-style: true
- name: Prepare package directory
shell: bash
run: |
mkdir -p package
mkdir -p package/cache
- uses: actions/download-artifact@v3
with:
name: capi-linux-aarch64
path: package/cache/wasmercache1
- uses: actions/download-artifact@v3
with:
name: capi-windows-gnu
path: package/cache/wasmercache2
- uses: actions/download-artifact@v3
with:
name: capi-macos-arm
path: package/cache/wasmercache3
- uses: actions/download-artifact@v3
with:
name: capi-macos-x64
path: package/cache/wasmercache4
- uses: actions/download-artifact@v3
with:
name: capi-linux-x64
path: package/cache/wasmercache5
- name: Copy .tar.gz files to proper location
shell: bash
run: |
ls package/cache/wasmercache1
ls package/cache/wasmercache2
ls package/cache/wasmercache3
ls package/cache/wasmercache4
ls package/cache/wasmercache5
cp package/cache/wasmercache1/wasmer.tar.gz package/cache/wasmer-linux-aarch64.tar.gz
cp package/cache/wasmercache2/build-capi.tar.gz package/cache/wasmer-windows-gnu64.tar.gz
cp package/cache/wasmercache3/build-capi.tar.gz package/cache/wasmer-darwin-arm64.tar.gz
cp package/cache/wasmercache4/build-capi.tar.gz package/cache/wasmer-darwin-amd64.tar.gz
cp package/cache/wasmercache5/build-capi.tar.gz package/cache/wasmer-linux-amd64.tar.gz
- uses: actions/download-artifact@v3
if: ${{ matrix.build == 'windows-x64' }}
with:
name: capi-windows-gnu
path: download_link
- uses: actions/download-artifact@v3
if: ${{ matrix.build == 'linux-musl' }}
with:
name: capi-linux-musl
path: download_link
- uses: actions/download-artifact@v3
if: ${{ matrix.build == 'macos-arm' }}
with:
name: capi-macos-arm
path: download_link
- uses: actions/download-artifact@v3
if: ${{ matrix.build == 'macos-x64' }}
with:
name: capi-macos-x64
path: download_link
- uses: actions/download-artifact@v3
if: ${{ matrix.build == 'linux-x64' }}
with:
name: capi-linux-x64
path: download_link
- name: Copy build-capi.tar.gz to link.tar.gz
shell: bash
run: |
cp download_link/build-capi.tar.gz link.tar.gz
- name: Unzip Artifacts
shell: bash
run: |

4
.gitignore vendored
View File

@ -23,4 +23,6 @@ out.txt
wapm.toml
build-capi.tar.gz
build-wasmer.tar.gz
lcov.info
lcov.info
link/
link.tar.gz

View File

@ -562,10 +562,12 @@ test-wasi-unit:
test-wasi:
$(CARGO_BINARY) test $(CARGO_TARGET_FLAG) --release --tests $(compiler_features) -- wasi::wasitests
test-integration-cli:
test-integration-cli: build-wasmer build-capi package dist
cp ./dist/wasmer.tar.gz ./link.tar.gz
rustup target add wasm32-wasi
$(CARGO_BINARY) test $(CARGO_TARGET_FLAG) --features webc_runner --no-fail-fast -p wasmer-integration-tests-cli -- --nocapture --test-threads=1
# Before running this in the CI, we need to set up link.tar.gz and /cache/wasmer-[target].tar.gz
test-integration-cli-ci:
rustup target add wasm32-wasi
$(CARGO_BINARY) test $(CARGO_TARGET_FLAG) --features webc_runner -p wasmer-integration-tests-cli -- --nocapture --test-threads=1 || $(CARGO_BINARY) test $(CARGO_TARGET_FLAG) --features webc_runner --no-fail-fast -p wasmer-integration-tests-cli -- --nocapture --test-threads=1
@ -619,6 +621,7 @@ endif
package-capi:
mkdir -p "package/include"
mkdir -p "package/lib"
mkdir -p "package/winsdk"
cp lib/c-api/wasmer.h* package/include
cp lib/c-api/wasmer_wasm.h* package/include
cp lib/c-api/tests/wasm-c-api/include/wasm.h* package/include
@ -729,7 +732,7 @@ package: package-wasmer package-minimal-headless-wasmer package-capi
tar-capi:
ls -R package
tar -C package -zcvf build-capi.tar.gz lib include
tar -C package -zcvf build-capi.tar.gz lib include winsdk
untar-capi:
mkdir -p package

View File

@ -83,7 +83,7 @@ qjs >
## 他の言語とのインテグレーション
📦 Wasmer ランタイムは**他の言語に組み込んで**使用できるため、WebAssembly は_どんな場所でも_利用できます。
📦 Wasmer ランタイムは**他の言語に組み込んで**使用できるため、WebAssembly は*どんな場所でも*利用できます。
|   | Language | Package | Docs |
|-|-|-|-|

View File

@ -1,9 +1,10 @@
pub use self::inner::{FromToNativeWasmType, HostFunction, WasmTypeList, WithEnv, WithoutEnv};
use crate::js::exports::{ExportError, Exportable};
use crate::js::externals::{Extern, VMExtern};
use crate::js::externals::Extern;
use crate::js::function_env::FunctionEnvMut;
use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle, StoreMut};
use crate::js::store::{AsStoreMut, AsStoreRef, StoreMut};
use crate::js::types::{param_from_js, AsJs}; /* ValFuncRef */
use crate::js::vm::VMExtern;
use crate::js::RuntimeError;
use crate::js::TypedFunction;
use crate::js::Value;
@ -13,7 +14,7 @@ use std::iter::FromIterator;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use crate::js::export::VMFunction;
use crate::js::vm::VMFunction;
use std::fmt;
#[repr(C)]
@ -58,11 +59,11 @@ fn results_to_js_array(values: &[Value]) -> Array {
/// [Closures as host functions tracking issue](https://github.com/wasmerio/wasmer/issues/1840)
#[derive(Clone, PartialEq)]
pub struct Function {
pub(crate) handle: StoreHandle<VMFunction>,
pub(crate) handle: VMFunction,
}
impl From<StoreHandle<VMFunction>> for Function {
fn from(handle: StoreHandle<VMFunction>) -> Self {
impl From<VMFunction> for Function {
fn from(handle: VMFunction) -> Self {
Self { handle }
}
}
@ -86,7 +87,7 @@ impl Function {
/// To `VMExtern`.
pub fn to_vm_extern(&self) -> VMExtern {
VMExtern::Function(self.handle.internal_handle())
VMExtern::Function(self.handle.clone())
}
/// Creates a new host `Function` (dynamic) with the provided signature.
@ -190,7 +191,7 @@ impl Function {
JSFunction::new_with_args("f", "return f(Array.prototype.slice.call(arguments, 1))");
let binded_func = dyn_func.bind1(&JsValue::UNDEFINED, &wrapped_func);
let vm_function = VMFunction::new(binded_func, func_ty);
Self::from_vm_export(&mut store, vm_function)
Self::from_vm_extern(&mut store, vm_function)
}
#[deprecated(
@ -214,7 +215,7 @@ impl Function {
Args: WasmTypeList,
Rets: WasmTypeList,
{
let mut store = store.as_store_mut();
let store = store.as_store_mut();
if std::mem::size_of::<F>() != 0 {
Self::closures_unsupported_panic();
}
@ -232,7 +233,7 @@ impl Function {
let ty = function.ty();
let vm_function = VMFunction::new(binded_func, ty);
Self {
handle: StoreHandle::new(store.objects_mut(), vm_function),
handle: vm_function,
}
}
@ -281,7 +282,7 @@ impl Function {
Args: WasmTypeList,
Rets: WasmTypeList,
{
let mut store = store.as_store_mut();
let store = store.as_store_mut();
if std::mem::size_of::<F>() != 0 {
Self::closures_unsupported_panic();
}
@ -300,7 +301,7 @@ impl Function {
let ty = function.ty();
let vm_function = VMFunction::new(binded_func, ty);
Self {
handle: StoreHandle::new(store.objects_mut(), vm_function),
handle: vm_function,
}
}
@ -321,8 +322,8 @@ impl Function {
/// assert_eq!(f.ty().params(), vec![Type::I32, Type::I32]);
/// assert_eq!(f.ty().results(), vec![Type::I32]);
/// ```
pub fn ty(&self, store: &impl AsStoreRef) -> FunctionType {
self.handle.get(store.as_store_ref().objects()).ty.clone()
pub fn ty(&self, _store: &impl AsStoreRef) -> FunctionType {
self.handle.ty.clone()
}
/// Returns the number of parameters that this function takes.
@ -422,7 +423,7 @@ impl Function {
// TODO: This loop is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451
loop {
r = js_sys::Reflect::apply(
&self.handle.get(store.as_store_ref().objects()).function,
&self.handle.function,
&wasm_bindgen::JsValue::NULL,
&arr,
);
@ -446,7 +447,7 @@ impl Function {
r?
};
let result_types = self.handle.get(store.as_store_ref().objects()).ty.results();
let result_types = self.handle.ty.results();
match result_types.len() {
0 => Ok(Box::new([])),
1 => {
@ -465,21 +466,8 @@ impl Function {
}
}
pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self {
Self {
handle: StoreHandle::new(store.objects_mut(), vm_function),
}
}
pub(crate) fn from_vm_extern(
store: &mut impl AsStoreMut,
internal: InternalStoreHandle<VMFunction>,
) -> Self {
Self {
handle: unsafe {
StoreHandle::from_internal(store.as_store_ref().objects().id(), internal)
},
}
pub(crate) fn from_vm_extern(_store: &mut impl AsStoreMut, internal: VMFunction) -> Self {
Self { handle: internal }
}
#[deprecated(since = "3.0.0", note = "native() has been renamed to typed().")]
@ -616,8 +604,8 @@ impl Function {
}
/// Checks whether this `Function` can be used with the given context.
pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
self.handle.store_id() == store.as_store_ref().objects().id()
pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
true
}
}

View File

@ -1,8 +1,8 @@
use crate::js::export::VMGlobal;
use crate::js::exports::{ExportError, Exportable};
use crate::js::externals::{Extern, VMExtern};
use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle};
use crate::js::externals::Extern;
use crate::js::store::{AsStoreMut, AsStoreRef};
use crate::js::value::Value;
use crate::js::vm::{VMExtern, VMGlobal};
use crate::js::wasm_bindgen_polyfill::Global as JSGlobal;
use crate::js::GlobalType;
use crate::js::Mutability;
@ -17,7 +17,7 @@ use wasm_bindgen::JsValue;
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#global-instances>
#[derive(Debug, Clone, PartialEq)]
pub struct Global {
pub(crate) handle: StoreHandle<VMGlobal>,
pub(crate) handle: VMGlobal,
}
impl Global {
@ -57,7 +57,7 @@ impl Global {
/// To `VMExtern`.
pub(crate) fn to_vm_extern(&self) -> VMExtern {
VMExtern::Global(self.handle.internal_handle())
VMExtern::Global(self.handle.clone())
}
/// Create a `Global` with the initial value [`Value`] and the provided [`Mutability`].
@ -95,7 +95,7 @@ impl Global {
let js_global = JSGlobal::new(&descriptor, &value).unwrap();
let vm_global = VMGlobal::new(js_global, global_ty);
Ok(Self::from_vm_export(store, vm_global))
Ok(Self::from_vm_extern(store, vm_global))
}
/// Returns the [`GlobalType`] of the `Global`.
@ -112,8 +112,8 @@ impl Global {
/// assert_eq!(c.ty(), &GlobalType::new(Type::I32, Mutability::Const));
/// assert_eq!(v.ty(), &GlobalType::new(Type::I64, Mutability::Var));
/// ```
pub fn ty(&self, store: &impl AsStoreRef) -> GlobalType {
self.handle.get(store.as_store_ref().objects()).ty
pub fn ty(&self, _store: &impl AsStoreRef) -> GlobalType {
self.handle.ty
}
/// Retrieves the current value [`Value`] that the Global has.
@ -130,14 +130,8 @@ impl Global {
/// ```
pub fn get(&self, store: &impl AsStoreRef) -> Value {
unsafe {
let raw = self
.handle
.get(store.as_store_ref().objects())
.global
.value()
.as_f64()
.unwrap();
let ty = self.handle.get(store.as_store_ref().objects()).ty;
let raw = self.handle.global.value().as_f64().unwrap();
let ty = self.handle.ty;
Value::from_raw(store, ty.ty, raw)
}
}
@ -207,33 +201,19 @@ impl Global {
))
}
};
self.handle
.get_mut(store.objects_mut())
.global
.set_value(&new_value);
self.handle.global.set_value(&new_value);
Ok(())
}
pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_global: VMGlobal) -> Self {
Self {
handle: StoreHandle::new(store.objects_mut(), vm_global),
}
}
pub(crate) fn from_vm_extern(
store: &mut impl AsStoreMut,
internal: InternalStoreHandle<VMGlobal>,
) -> Self {
Self {
handle: unsafe {
StoreHandle::from_internal(store.as_store_ref().objects().id(), internal)
},
}
pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, vm_global: VMGlobal) -> Self {
use crate::js::store::StoreObject;
VMGlobal::list_mut(store.objects_mut()).push(vm_global.clone());
Self { handle: vm_global }
}
/// Checks whether this `Global` can be used with the given store.
pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
self.handle.store_id() == store.as_store_ref().objects().id()
pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
true
}
}

View File

@ -1,7 +1,7 @@
use crate::js::export::VMMemory;
use crate::js::exports::{ExportError, Exportable};
use crate::js::externals::{Extern, VMExtern};
use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle, StoreObjects};
use crate::js::externals::Extern;
use crate::js::store::{AsStoreMut, AsStoreRef, StoreObjects};
use crate::js::vm::{VMExtern, VMMemory};
use crate::js::{MemoryAccessError, MemoryType};
use std::marker::PhantomData;
use std::mem::MaybeUninit;
@ -65,7 +65,7 @@ extern "C" {
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances>
#[derive(Debug, Clone)]
pub struct Memory {
pub(crate) handle: StoreHandle<VMMemory>,
pub(crate) handle: VMMemory,
}
unsafe impl Send for Memory {}
@ -87,7 +87,7 @@ impl Memory {
/// ```
pub fn new(store: &mut impl AsStoreMut, ty: MemoryType) -> Result<Self, MemoryError> {
let vm_memory = VMMemory::new(Self::new_internal(ty.clone())?, ty);
Ok(Self::from_vm_export(store, vm_memory))
Ok(Self::from_vm_extern(store, vm_memory))
}
pub(crate) fn new_internal(ty: MemoryType) -> Result<js_sys::WebAssembly::Memory, MemoryError> {
@ -115,19 +115,17 @@ impl Memory {
ty: MemoryType,
) -> Result<Self, MemoryError> {
let vm_memory = VMMemory::new(js_memory, ty);
let handle = StoreHandle::new(store.objects_mut(), vm_memory);
Ok(Self::from_vm_extern(store, handle.internal_handle()))
Ok(Self::from_vm_extern(store, vm_memory))
}
/// Create a memory object from an existing memory and attaches it to the store
pub fn new_from_existing(new_store: &mut impl AsStoreMut, memory: VMMemory) -> Self {
let handle = StoreHandle::new(new_store.objects_mut(), memory);
Self::from_vm_extern(new_store, handle.internal_handle())
Self::from_vm_extern(new_store, memory)
}
/// To `VMExtern`.
pub(crate) fn to_vm_extern(&self) -> VMExtern {
VMExtern::Memory(self.handle.internal_handle())
VMExtern::Memory(self.handle.clone())
}
/// Returns the [`MemoryType`] of the `Memory`.
@ -143,8 +141,8 @@ impl Memory {
///
/// assert_eq!(m.ty(), mt);
/// ```
pub fn ty(&self, store: &impl AsStoreRef) -> MemoryType {
self.handle.get(store.as_store_ref().objects()).ty
pub fn ty(&self, _store: &impl AsStoreRef) -> MemoryType {
self.handle.ty
}
/// Creates a view into the memory that then allows for
@ -192,7 +190,7 @@ impl Memory {
IntoPages: Into<Pages>,
{
let pages = delta.into();
let js_memory = &self.handle.get_mut(store.objects_mut()).memory;
let js_memory = &self.handle.memory;
let our_js_memory: &JSMemory = JsCast::unchecked_from_js_ref(js_memory);
let new_pages = our_js_memory.grow(pages.0).map_err(|err| {
if err.is_instance_of::<js_sys::RangeError>() {
@ -236,38 +234,23 @@ impl Memory {
Ok(new_memory)
}
pub(crate) fn from_vm_export(store: &mut impl AsStoreMut, vm_memory: VMMemory) -> Self {
Self {
handle: StoreHandle::new(store.objects_mut(), vm_memory),
}
}
pub(crate) fn from_vm_extern(
store: &mut impl AsStoreMut,
internal: InternalStoreHandle<VMMemory>,
) -> Self {
Self {
handle: unsafe {
StoreHandle::from_internal(store.as_store_ref().objects().id(), internal)
},
}
pub(crate) fn from_vm_extern(_store: &mut impl AsStoreMut, internal: VMMemory) -> Self {
Self { handle: internal }
}
/// Attempts to clone this memory (if its clonable)
pub fn try_clone(&self, store: &impl AsStoreRef) -> Option<VMMemory> {
let mem = self.handle.get(store.as_store_ref().objects());
mem.try_clone()
pub fn try_clone(&self, _store: &impl AsStoreRef) -> Option<VMMemory> {
self.handle.try_clone()
}
/// Checks whether this `Global` can be used with the given context.
pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
self.handle.store_id() == store.as_store_ref().objects().id()
pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
true
}
/// Copies this memory to a new memory
pub fn duplicate(&mut self, store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
let mem = self.handle.get(store.as_store_ref().objects());
mem.duplicate()
pub fn duplicate(&mut self, _store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
self.handle.duplicate()
}
}

View File

@ -26,9 +26,8 @@ pub struct MemoryView<'a> {
}
impl<'a> MemoryView<'a> {
pub(crate) fn new(memory: &Memory, store: &impl AsStoreRef) -> Self {
let memory = memory.handle.get(store.as_store_ref().objects());
Self::new_raw(&memory.memory)
pub(crate) fn new(memory: &Memory, _store: &impl AsStoreRef) -> Self {
Self::new_raw(&memory.handle.memory)
}
pub(crate) fn new_raw(memory: &js_sys::WebAssembly::Memory) -> Self {

View File

@ -10,123 +10,13 @@ pub use self::memory::{Memory, MemoryError};
pub use self::memory_view::MemoryView;
pub use self::table::Table;
use crate::js::export::{Export, VMFunction, VMGlobal, VMMemory, VMTable};
use crate::js::exports::{ExportError, Exportable};
use crate::js::store::StoreObject;
use crate::js::types::AsJs;
/*
use crate::js::store::InternalStoreHandle;
use crate::js::store::{AsStoreMut, AsStoreRef};
use crate::js::ExternType;
use crate::js::types::AsJs;
use crate::js::vm::VMExtern;
use std::fmt;
*/
use crate::js::error::WasmError;
use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle};
use crate::js::wasm_bindgen_polyfill::Global as JsGlobal;
use js_sys::Function as JsFunction;
use js_sys::WebAssembly::{Memory as JsMemory, Table as JsTable};
use std::fmt;
use wasm_bindgen::{JsCast, JsValue};
use wasmer_types::ExternType;
/// The value of an export passed from one instance to another.
pub enum VMExtern {
/// A function export value.
Function(InternalStoreHandle<VMFunction>),
/// A table export value.
Table(InternalStoreHandle<VMTable>),
/// A memory export value.
Memory(InternalStoreHandle<VMMemory>),
/// A global export value.
Global(InternalStoreHandle<VMGlobal>),
}
impl VMExtern {
/// Return the export as a `JSValue`.
pub fn as_jsvalue<'context>(&self, store: &'context impl AsStoreRef) -> &'context JsValue {
match self {
Self::Memory(js_wasm_memory) => js_wasm_memory
.get(store.as_store_ref().objects())
.memory
.as_ref(),
Self::Function(js_func) => js_func
.get(store.as_store_ref().objects())
.function
.as_ref(),
Self::Table(js_wasm_table) => js_wasm_table
.get(store.as_store_ref().objects())
.table
.as_ref(),
Self::Global(js_wasm_global) => js_wasm_global
.get(store.as_store_ref().objects())
.global
.as_ref(),
}
}
/// Convert a `JsValue` into an `Export` within a given `Context`.
pub fn from_js_value(
val: JsValue,
store: &mut impl AsStoreMut,
extern_type: ExternType,
) -> Result<Self, WasmError> {
match extern_type {
ExternType::Memory(memory_type) => {
if val.is_instance_of::<JsMemory>() {
Ok(Self::Memory(InternalStoreHandle::new(
&mut store.objects_mut(),
VMMemory::new(val.unchecked_into::<JsMemory>(), memory_type),
)))
} else {
Err(WasmError::TypeMismatch(
val.js_typeof()
.as_string()
.map(Into::into)
.unwrap_or("unknown".into()),
"Memory".into(),
))
}
}
ExternType::Global(global_type) => {
if val.is_instance_of::<JsGlobal>() {
Ok(Self::Global(InternalStoreHandle::new(
&mut store.objects_mut(),
VMGlobal::new(val.unchecked_into::<JsGlobal>(), global_type),
)))
} else {
panic!("Extern type doesn't match js value type");
}
}
ExternType::Function(function_type) => {
if val.is_instance_of::<JsFunction>() {
Ok(Self::Function(InternalStoreHandle::new(
&mut store.objects_mut(),
VMFunction::new(val.unchecked_into::<JsFunction>(), function_type),
)))
} else {
panic!("Extern type doesn't match js value type");
}
}
ExternType::Table(table_type) => {
if val.is_instance_of::<JsTable>() {
Ok(Self::Table(InternalStoreHandle::new(
&mut store.objects_mut(),
VMTable::new(val.unchecked_into::<JsTable>(), table_type),
)))
} else {
panic!("Extern type doesn't match js value type");
}
}
}
}
}
/// An `Extern` is the runtime representation of an entity that
/// can be imported or exported.
///
@ -183,24 +73,15 @@ impl Extern {
Self::Table(val) => val.is_from_store(store),
}
}
fn to_export(&self) -> Export {
match self {
Self::Function(val) => Export::Function(val.handle.internal_handle()),
Self::Memory(val) => Export::Memory(val.handle.internal_handle()),
Self::Global(val) => Export::Global(val.handle.internal_handle()),
Self::Table(val) => Export::Table(val.handle.internal_handle()),
}
}
}
impl AsJs for Extern {
fn as_jsvalue(&self, store: &impl AsStoreRef) -> wasm_bindgen::JsValue {
match self {
Self::Function(_) => self.to_export().as_jsvalue(store),
Self::Global(_) => self.to_export().as_jsvalue(store),
Self::Table(_) => self.to_export().as_jsvalue(store),
Self::Memory(_) => self.to_export().as_jsvalue(store),
Self::Function(_) => self.to_vm_extern().as_jsvalue(store),
Self::Global(_) => self.to_vm_extern().as_jsvalue(store),
Self::Table(_) => self.to_vm_extern().as_jsvalue(store),
Self::Memory(_) => self.to_vm_extern().as_jsvalue(store),
}
.clone()
}
@ -213,8 +94,6 @@ impl<'a> Exportable<'a> for Extern {
}
}
impl StoreObject for Extern {}
impl fmt::Debug for Extern {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(

View File

@ -1,8 +1,8 @@
use crate::js::export::{VMFunction, VMTable};
use crate::js::exports::{ExportError, Exportable};
use crate::js::externals::{Extern, VMExtern};
use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle, StoreHandle};
use crate::js::externals::Extern;
use crate::js::store::{AsStoreMut, AsStoreRef};
use crate::js::value::Value;
use crate::js::vm::{VMExtern, VMFunction, VMTable};
use crate::js::RuntimeError;
use crate::js::{FunctionType, TableType};
use js_sys::Function;
@ -18,7 +18,7 @@ use js_sys::Function;
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#table-instances>
#[derive(Debug, Clone, PartialEq)]
pub struct Table {
pub(crate) handle: StoreHandle<VMTable>,
pub(crate) handle: VMTable,
}
fn set_table_item(table: &VMTable, item_index: u32, item: &Function) -> Result<(), RuntimeError> {
@ -30,12 +30,7 @@ fn get_function(store: &mut impl AsStoreMut, val: Value) -> Result<Function, Run
return Err(RuntimeError::new("cannot pass Value across contexts"));
}
match val {
Value::FuncRef(Some(ref func)) => Ok(func
.handle
.get(&store.as_store_ref().objects())
.function
.clone()
.into()),
Value::FuncRef(Some(ref func)) => Ok(func.handle.function.clone().into()),
// Only funcrefs is supported by the spec atm
_ => unimplemented!(),
}
@ -70,33 +65,25 @@ impl Table {
set_table_item(&table, i, &func)?;
}
Ok(Self {
handle: StoreHandle::new(store.objects_mut(), table),
})
Ok(Self { handle: table })
}
/// To `VMExtern`.
pub fn to_vm_extern(&self) -> VMExtern {
VMExtern::Table(self.handle.internal_handle())
VMExtern::Table(self.handle.clone())
}
/// Returns the [`TableType`] of the `Table`.
pub fn ty(&self, store: &impl AsStoreRef) -> TableType {
self.handle.get(store.as_store_ref().objects()).ty
pub fn ty(&self, _store: &impl AsStoreRef) -> TableType {
self.handle.ty
}
/// Retrieves an element of the table at the provided `index`.
pub fn get(&self, store: &mut impl AsStoreMut, index: u32) -> Option<Value> {
if let Some(func) = self
.handle
.get(store.as_store_ref().objects())
.table
.get(index)
.ok()
{
if let Some(func) = self.handle.table.get(index).ok() {
let ty = FunctionType::new(vec![], vec![]);
let vm_function = VMFunction::new(func, ty);
let function = crate::js::externals::Function::from_vm_export(store, vm_function);
let function = crate::js::externals::Function::from_vm_extern(store, vm_function);
Some(Value::FuncRef(Some(function)))
} else {
None
@ -111,15 +98,12 @@ impl Table {
val: Value,
) -> Result<(), RuntimeError> {
let item = get_function(store, val)?;
set_table_item(self.handle.get_mut(store.objects_mut()), index, &item)
set_table_item(&self.handle, index, &item)
}
/// Retrieves the size of the `Table` (in elements)
pub fn size(&self, store: &impl AsStoreRef) -> u32 {
self.handle
.get(store.as_store_ref().objects())
.table
.length()
pub fn size(&self, _store: &impl AsStoreRef) -> u32 {
self.handle.table.length()
}
/// Grows the size of the `Table` by `delta`, initializating
@ -158,20 +142,13 @@ impl Table {
unimplemented!("Table.copy is not natively supported in Javascript");
}
pub(crate) fn from_vm_extern(
store: &mut impl AsStoreMut,
internal: InternalStoreHandle<VMTable>,
) -> Self {
Self {
handle: unsafe {
StoreHandle::from_internal(store.as_store_ref().objects().id(), internal)
},
}
pub(crate) fn from_vm_extern(_store: &mut impl AsStoreMut, internal: VMTable) -> Self {
Self { handle: internal }
}
/// Checks whether this `Table` can be used with the given context.
pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
self.handle.store_id() == store.as_store_ref().objects().id()
pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
true
}
/// Get access to the backing VM value for this extern. This function is for
@ -183,10 +160,10 @@ impl Table {
/// make breaking changes to it at any time or remove this method.
#[doc(hidden)]
pub unsafe fn get_vm_table<'context>(
&self,
store: &'context impl AsStoreRef,
&'context self,
_store: &'context impl AsStoreRef,
) -> &'context VMTable {
self.handle.get(store.as_store_ref().objects())
&self.handle
}
}

View File

@ -6,6 +6,7 @@ use crate::js::exports::Exports;
use crate::js::module::Module;
use crate::js::store::{AsStoreMut, AsStoreRef};
use crate::js::types::AsJs;
use crate::js::vm::VMExtern;
use crate::js::ExternType;
use crate::Extern;
use std::collections::HashMap;
@ -206,7 +207,6 @@ impl Imports {
module: &Module,
object: js_sys::Object,
) -> Result<Self, WasmError> {
use crate::js::externals::VMExtern;
let module_imports: HashMap<(String, String), ExternType> = module
.imports()
.map(|import| {
@ -457,162 +457,4 @@ mod test {
assert!(happy.is_some());
assert!(small.is_some());
}
// fn namespace() {
// let mut store = Store::default();
// let g1 = Global::new(&store, Val::I32(0));
// let namespace = namespace! {
// "happy" => g1
// };
// let imports1 = imports! {
// "dog" => namespace
// };
// let happy_dog_entry = imports1.get_export("dog", "happy").unwrap();
// assert!(
// if let Export::Global(happy_dog_global) = happy_dog_entry.to_export() {
// happy_dog_global.ty.ty == Type::I32
// } else {
// false
// }
// );
// }
// fn imports_macro_allows_trailing_comma_and_none() {
// use crate::js::Function;
// let mut store = Default::default();
// fn func(arg: i32) -> i32 {
// arg + 1
// }
// let _ = imports! {
// "env" => {
// "func" => Function::new_typed(&store, func),
// },
// };
// let _ = imports! {
// "env" => {
// "func" => Function::new_typed(&store, func),
// }
// };
// let _ = imports! {
// "env" => {
// "func" => Function::new_typed(&store, func),
// },
// "abc" => {
// "def" => Function::new_typed(&store, func),
// }
// };
// let _ = imports! {
// "env" => {
// "func" => Function::new_typed(&store, func)
// },
// };
// let _ = imports! {
// "env" => {
// "func" => Function::new_typed(&store, func)
// }
// };
// let _ = imports! {
// "env" => {
// "func1" => Function::new_typed(&store, func),
// "func2" => Function::new_typed(&store, func)
// }
// };
// let _ = imports! {
// "env" => {
// "func1" => Function::new_typed(&store, func),
// "func2" => Function::new_typed(&store, func),
// }
// };
// }
// fn chaining_works() {
// let mut store = Store::default();
// let g = Global::new(&store, Val::I32(0));
// let mut imports1 = imports! {
// "dog" => {
// "happy" => g.clone()
// }
// };
// let imports2 = imports! {
// "dog" => {
// "small" => g.clone()
// },
// "cat" => {
// "small" => g.clone()
// }
// };
// imports1.extend(&imports2);
// let small_cat_export = imports1.get_export("cat", "small");
// assert!(small_cat_export.is_some());
// let happy = imports1.get_export("dog", "happy");
// let small = imports1.get_export("dog", "small");
// assert!(happy.is_some());
// assert!(small.is_some());
// }
// fn extending_conflict_overwrites() {
// let mut store = Store::default();
// let g1 = Global::new(&store, Val::I32(0));
// let g2 = Global::new(&store, Val::F32(0.));
// let mut imports1 = imports! {
// "dog" => {
// "happy" => g1,
// },
// };
// let imports2 = imports! {
// "dog" => {
// "happy" => g2,
// },
// };
// imports1.extend(&imports2);
// let happy_dog_entry = imports1.get_export("dog", "happy").unwrap();
// assert!(
// if let Export::Global(happy_dog_global) = happy_dog_entry.to_export() {
// happy_dog_global.ty.ty == Type::F32
// } else {
// false
// }
// );
// // now test it in reverse
// let mut store = Store::default();
// let g1 = Global::new(&store, Val::I32(0));
// let g2 = Global::new(&store, Val::F32(0.));
// let imports1 = imports! {
// "dog" => {
// "happy" => g1,
// },
// };
// let mut imports2 = imports! {
// "dog" => {
// "happy" => g2,
// },
// };
// imports2.extend(&imports1);
// let happy_dog_entry = imports2.get_export("dog", "happy").unwrap();
// assert!(
// if let Export::Global(happy_dog_global) = happy_dog_entry.to_export() {
// happy_dog_global.ty.ty == Type::I32
// } else {
// false
// }
// );
// }
}

View File

@ -3,7 +3,8 @@ use crate::js::exports::Exports;
use crate::js::externals::Extern;
use crate::js::imports::Imports;
use crate::js::module::Module;
use crate::js::store::{AsStoreMut, AsStoreRef, StoreHandle};
use crate::js::store::{AsStoreMut, AsStoreRef};
use crate::js::vm::{VMExtern, VMInstance};
use js_sys::WebAssembly;
use std::fmt;
@ -17,7 +18,7 @@ use std::fmt;
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#module-instances>
#[derive(Clone)]
pub struct Instance {
_handle: StoreHandle<WebAssembly::Instance>,
handle: VMInstance,
module: Module,
/// The exports for an instance.
pub exports: Exports,
@ -62,14 +63,11 @@ impl Instance {
module: &Module,
imports: &Imports,
) -> Result<Self, InstantiationError> {
let (instance, externs) = module
let instance = module
.instantiate(&mut store, imports)
.map_err(|e| InstantiationError::Start(e))?;
let instance = instance.get(store.objects_mut()).clone();
let mut self_instance = Self::from_module_and_instance(store, module, instance)?;
self_instance.ensure_memory_export(store, externs);
//self_instance.init_envs(&imports.iter().map(Extern::to_export).collect::<Vec<_>>())?;
let self_instance = Self::from_module_and_instance(store, module, instance)?;
Ok(self_instance)
}
@ -109,8 +107,6 @@ impl Instance {
module: &Module,
instance: WebAssembly::Instance,
) -> Result<Self, InstantiationError> {
use crate::js::externals::VMExtern;
let instance_exports = instance.exports();
let exports = module
@ -131,29 +127,13 @@ impl Instance {
})
.collect::<Result<Exports, InstantiationError>>()?;
let handle = StoreHandle::new(store.as_store_mut().objects_mut(), instance);
Ok(Self {
_handle: handle,
handle: instance,
module: module.clone(),
exports,
})
}
/// This will check the memory is correctly setup
/// If the memory is imported then also export it for backwards compatibility reasons
/// (many will assume the memory is always exported) - later we can remove this
pub fn ensure_memory_export(&mut self, store: &mut impl AsStoreMut, externs: Vec<Extern>) {
if self.exports.get_memory("memory").is_err() {
if let Some(memory) = externs
.iter()
.filter(|a| a.ty(store).memory().is_some())
.next()
{
self.exports.insert("memory", memory.clone());
}
}
}
/// Gets the [`Module`] associated with this instance.
pub fn module(&self) -> &Module {
&self.module
@ -162,10 +142,10 @@ impl Instance {
/// Returns the inner WebAssembly Instance
#[doc(hidden)]
pub fn raw<'context>(
&self,
store: &'context impl AsStoreRef,
&'context self,
_store: &'context impl AsStoreRef,
) -> &'context WebAssembly::Instance {
&self._handle.get(store.as_store_ref().objects())
&self.handle
}
}

View File

@ -24,7 +24,6 @@ mod lib {
}
pub(crate) mod error;
mod export;
mod exports;
mod externals;
mod function_env;
@ -41,10 +40,10 @@ mod store;
mod trap;
mod types;
mod value;
mod vm;
mod wasm_bindgen_polyfill;
pub use crate::js::error::{DeserializeError, InstantiationError, SerializeError};
pub use crate::js::export::Export;
pub use crate::js::exports::{ExportError, Exportable, Exports, ExportsIterator};
pub use crate::js::externals::{
Extern, FromToNativeWasmType, Function, Global, HostFunction, Memory, MemoryError, MemoryView,
@ -61,7 +60,7 @@ pub use crate::js::ptr::{Memory32, Memory64, MemorySize, WasmPtr, WasmPtr64};
pub use crate::js::trap::RuntimeError;
pub use crate::js::store::{
AsStoreMut, AsStoreRef, Store, StoreHandle, StoreMut, StoreObject, StoreObjects, StoreRef,
AsStoreMut, AsStoreRef, Store, StoreHandle, StoreMut, StoreObjects, StoreRef,
};
pub use crate::js::types::ValType as Type;
pub use crate::js::types::{
@ -71,11 +70,6 @@ pub use crate::js::types::{
pub use crate::js::value::Value;
pub use crate::js::value::Value as Val;
pub mod vm {
//! The `vm` module re-exports wasmer-vm types.
pub use crate::js::export::VMMemory;
}
pub use wasmer_types::is_wasm;
// TODO: OnCalledAction is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451
pub use wasmer_types::{

View File

@ -7,6 +7,7 @@ use crate::js::externals::Extern;
use crate::js::imports::Imports;
use crate::js::store::AsStoreMut;
use crate::js::types::{AsJs, ExportType, ImportType};
use crate::js::vm::VMInstance;
use crate::js::RuntimeError;
use crate::AsStoreRef;
use crate::IntoBytes;
@ -246,7 +247,7 @@ impl Module {
&self,
store: &mut impl AsStoreMut,
imports: &Imports,
) -> Result<(crate::StoreHandle<WebAssembly::Instance>, Vec<Extern>), RuntimeError> {
) -> Result<VMInstance, RuntimeError> {
// Ensure all imports come from the same store.
if imports
.into_iter()
@ -323,14 +324,8 @@ impl Module {
// in case the import is not found, the JS Wasm VM will handle
// the error for us, so we don't need to handle it
}
Ok((
crate::StoreHandle::new(
store.as_store_mut().objects_mut(),
WebAssembly::Instance::new(&self.module, &imports_object)
.map_err(|e: JsValue| -> RuntimeError { e.into() })?,
),
import_externs,
))
Ok(WebAssembly::Instance::new(&self.module, &imports_object)
.map_err(|e: JsValue| -> RuntimeError { e.into() })?)
}
/// Returns the name of the current module.

View File

@ -10,12 +10,12 @@
use std::marker::PhantomData;
use crate::js::externals::Function;
use crate::js::store::{AsStoreMut, AsStoreRef, StoreHandle};
use crate::js::store::{AsStoreMut, AsStoreRef};
use crate::js::{FromToNativeWasmType, RuntimeError, WasmTypeList};
// use std::panic::{catch_unwind, AssertUnwindSafe};
use crate::js::export::VMFunction;
use crate::js::types::param_from_js;
use crate::js::types::AsJs;
use crate::js::vm::VMFunction;
use js_sys::Array;
use std::iter::FromIterator;
use wasm_bindgen::JsValue;
@ -25,7 +25,7 @@ use wasmer_types::RawValue;
/// (using the Native ABI).
#[derive(Clone)]
pub struct TypedFunction<Args = (), Rets = ()> {
pub(crate) handle: StoreHandle<VMFunction>,
pub(crate) handle: VMFunction,
_phantom: PhantomData<(Args, Rets)>,
}
@ -38,9 +38,9 @@ where
Rets: WasmTypeList,
{
#[allow(dead_code)]
pub(crate) fn new<T>(store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self {
pub(crate) fn new<T>(_store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self {
Self {
handle: StoreHandle::new(store.as_store_mut().objects_mut(), vm_function),
handle: vm_function,
_phantom: PhantomData,
}
}
@ -78,7 +78,7 @@ macro_rules! impl_native_traits {
let mut r;
// TODO: This loop is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451
loop {
r = self.handle.get(store.as_store_ref().objects()).function.apply(
r = self.handle.function.apply(
&JsValue::UNDEFINED,
&Array::from_iter(params_list.iter())
);

View File

@ -78,14 +78,6 @@ impl fmt::Debug for Store {
}
}
/// A trait represinting any object that lives in the `Store`.
pub trait StoreObject {
/// Return true if the object `Store` is the same as the provided `Store`.
fn comes_from_same_store(&self, _store: &Store) -> bool {
true
}
}
impl AsStoreRef for Store {
fn as_store_ref(&self) -> StoreRef<'_> {
StoreRef { inner: &self.inner }
@ -207,21 +199,17 @@ impl<T: AsStoreMut> AsStoreMut for &'_ mut T {
}
}
pub use objects::*;
pub(crate) use objects::{InternalStoreHandle, StoreObject};
pub use objects::{StoreHandle, StoreId, StoreObjects};
mod objects {
use wasm_bindgen::JsValue;
use crate::js::{
export::{VMFunction, VMGlobal, VMMemory, VMTable},
function_env::VMFunctionEnvironment,
};
use crate::js::{function_env::VMFunctionEnvironment, vm::VMGlobal};
use std::{
cell::UnsafeCell,
fmt,
marker::PhantomData,
num::{NonZeroU64, NonZeroUsize},
ptr::NonNull,
sync::atomic::{AtomicU64, Ordering},
};
@ -266,11 +254,15 @@ mod objects {
}
impl_store_object! {
functions => VMFunction,
tables => VMTable,
// Note: we store the globals in order to be able to access them later via
// `StoreObjects::iter_globals`.
globals => VMGlobal,
memories => VMMemory,
instances => js_sys::WebAssembly::Instance,
// functions => VMFunction,
// tables => VMTable,
// memories => VMMemory,
// The function environments are the only things attached to a store,
// since the other JS objects (table, globals, memory and functions)
// live in the JS VM Store by default
function_environments => VMFunctionEnvironment,
}
@ -278,11 +270,7 @@ mod objects {
#[derive(Default)]
pub struct StoreObjects {
id: StoreId,
memories: Vec<VMMemory>,
tables: Vec<VMTable>,
globals: Vec<VMGlobal>,
functions: Vec<VMFunction>,
instances: Vec<js_sys::WebAssembly::Instance>,
function_environments: Vec<VMFunctionEnvironment>,
}
@ -482,28 +470,4 @@ mod objects {
})
}
}
/// Data used by the generated code is generally located inline within the
/// `VMContext` for items defined in an instance. Host-defined objects are
/// allocated separately and owned directly by the context.
#[allow(dead_code)]
pub enum MaybeInstanceOwned<T> {
/// The data is owned here.
Host(Box<UnsafeCell<T>>),
/// The data is stored inline in the `VMContext` of an instance.
Instance(NonNull<T>),
}
#[allow(dead_code)]
impl<T> MaybeInstanceOwned<T> {
/// Returns underlying pointer to the VM data.
#[allow(dead_code)]
pub fn as_ptr(&self) -> NonNull<T> {
match self {
MaybeInstanceOwned::Host(p) => unsafe { NonNull::new_unchecked(p.get()) },
MaybeInstanceOwned::Instance(p) => *p,
}
}
}
}

View File

@ -37,19 +37,14 @@ pub fn param_from_js(ty: &ValType, js_val: &JsValue) -> Value {
}
impl AsJs for Value {
fn as_jsvalue(&self, store: &impl AsStoreRef) -> JsValue {
fn as_jsvalue(&self, _store: &impl AsStoreRef) -> JsValue {
match self {
Self::I32(i) => JsValue::from_f64(*i as f64),
Self::I64(i) => JsValue::from_f64(*i as f64),
Self::F32(f) => JsValue::from_f64(*f as f64),
Self::F64(f) => JsValue::from_f64(*f),
Self::V128(f) => JsValue::from_f64(*f as f64),
Self::FuncRef(Some(func)) => func
.handle
.get(store.as_store_ref().objects())
.function
.clone()
.into(),
Self::FuncRef(Some(func)) => func.handle.function.clone().into(),
Self::FuncRef(None) => JsValue::null(),
}
}

View File

@ -87,19 +87,14 @@ impl Value {
}
/// Converts the `Value` into a `f64`.
pub fn as_raw(&self, store: &impl AsStoreRef) -> f64 {
pub fn as_raw(&self, _store: &impl AsStoreRef) -> f64 {
match *self {
Self::I32(v) => v as f64,
Self::I64(v) => v as f64,
Self::F32(v) => v as f64,
Self::F64(v) => v,
Self::V128(v) => v as f64,
Self::FuncRef(Some(ref f)) => f
.handle
.get(store.as_store_ref().objects())
.function
.as_f64()
.unwrap_or(0_f64), //TODO is this correct?
Self::FuncRef(Some(ref f)) => f.handle.function.as_f64().unwrap_or(0_f64), //TODO is this correct?
Self::FuncRef(None) => 0_f64,
//Self::ExternRef(Some(ref e)) => unsafe { *e.address().0 } as .into_raw(),

View File

@ -1,9 +1,19 @@
/// This module is mainly used to create the `VM` types that will hold both
/// the JS values of the `Memory`, `Table`, `Global` and `Function` and also
/// it's types.
/// This module should not be needed any longer (with the exception of the memory)
/// once the type reflection is added to the WebAssembly JS API.
/// https://github.com/WebAssembly/js-types/
use crate::js::error::WasmError;
use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle};
use crate::js::store::{AsStoreMut, AsStoreRef};
use crate::js::wasm_bindgen_polyfill::Global;
use crate::js::wasm_bindgen_polyfill::Global as JsGlobal;
use crate::MemoryView;
use js_sys::Function;
use js_sys::Function as JsFunction;
use js_sys::WebAssembly;
use js_sys::WebAssembly::{Memory, Table};
use js_sys::WebAssembly::{Memory as JsMemory, Table as JsTable};
use serde::{Deserialize, Serialize};
use std::fmt;
#[cfg(feature = "tracing")]
@ -162,56 +172,43 @@ impl fmt::Debug for VMFunction {
}
/// The value of an export passed from one instance to another.
#[derive(Debug, Clone)]
pub enum Export {
pub enum VMExtern {
/// A function export value.
Function(InternalStoreHandle<VMFunction>),
Function(VMFunction),
/// A table export value.
Table(InternalStoreHandle<VMTable>),
Table(VMTable),
/// A memory export value.
Memory(InternalStoreHandle<VMMemory>),
Memory(VMMemory),
/// A global export value.
Global(InternalStoreHandle<VMGlobal>),
Global(VMGlobal),
}
impl Export {
impl VMExtern {
/// Return the export as a `JSValue`.
pub fn as_jsvalue<'context>(&self, store: &'context impl AsStoreRef) -> &'context JsValue {
pub fn as_jsvalue<'context>(&self, _store: &'context impl AsStoreRef) -> JsValue {
match self {
Self::Memory(js_wasm_memory) => js_wasm_memory
.get(store.as_store_ref().objects())
.memory
.as_ref(),
Self::Function(js_func) => js_func
.get(store.as_store_ref().objects())
.function
.as_ref(),
Self::Table(js_wasm_table) => js_wasm_table
.get(store.as_store_ref().objects())
.table
.as_ref(),
Self::Global(js_wasm_global) => js_wasm_global
.get(store.as_store_ref().objects())
.global
.as_ref(),
Self::Memory(js_wasm_memory) => js_wasm_memory.memory.clone().into(),
Self::Function(js_func) => js_func.function.clone().into(),
Self::Table(js_wasm_table) => js_wasm_table.table.clone().into(),
Self::Global(js_wasm_global) => js_wasm_global.global.clone().into(),
}
}
/// Convert a `JsValue` into an `Export` within a given `Context`.
pub fn from_js_value(
val: JsValue,
store: &mut impl AsStoreMut,
_store: &mut impl AsStoreMut,
extern_type: ExternType,
) -> Result<Self, WasmError> {
match extern_type {
ExternType::Memory(memory_type) => {
if val.is_instance_of::<Memory>() {
Ok(Self::Memory(InternalStoreHandle::new(
&mut store.objects_mut(),
VMMemory::new(val.unchecked_into::<Memory>(), memory_type),
if val.is_instance_of::<JsMemory>() {
Ok(Self::Memory(VMMemory::new(
val.unchecked_into::<JsMemory>(),
memory_type,
)))
} else {
Err(WasmError::TypeMismatch(
@ -224,30 +221,30 @@ impl Export {
}
}
ExternType::Global(global_type) => {
if val.is_instance_of::<Global>() {
Ok(Self::Global(InternalStoreHandle::new(
&mut store.objects_mut(),
VMGlobal::new(val.unchecked_into::<Global>(), global_type),
if val.is_instance_of::<JsGlobal>() {
Ok(Self::Global(VMGlobal::new(
val.unchecked_into::<JsGlobal>(),
global_type,
)))
} else {
panic!("Extern type doesn't match js value type");
}
}
ExternType::Function(function_type) => {
if val.is_instance_of::<Function>() {
Ok(Self::Function(InternalStoreHandle::new(
&mut store.objects_mut(),
VMFunction::new(val.unchecked_into::<Function>(), function_type),
if val.is_instance_of::<JsFunction>() {
Ok(Self::Function(VMFunction::new(
val.unchecked_into::<JsFunction>(),
function_type,
)))
} else {
panic!("Extern type doesn't match js value type");
}
}
ExternType::Table(table_type) => {
if val.is_instance_of::<Table>() {
Ok(Self::Table(InternalStoreHandle::new(
&mut store.objects_mut(),
VMTable::new(val.unchecked_into::<Table>(), table_type),
if val.is_instance_of::<JsTable>() {
Ok(Self::Table(VMTable::new(
val.unchecked_into::<JsTable>(),
table_type,
)))
} else {
panic!("Extern type doesn't match js value type");
@ -256,3 +253,5 @@ impl Export {
}
}
}
pub type VMInstance = WebAssembly::Instance;

View File

@ -368,6 +368,9 @@
//! to compile it with [`wasm-pack`] and [`wasm-bindgen`]:
//!
//! ```ignore
//! use wasm_bindgen::prelude::*;
//! use wasmer::{imports, Instance, Module, Store, Value};
//!
//! #[wasm_bindgen]
//! pub extern fn do_add_one_in_wasmer() -> i32 {
//! let module_wat = r#"
@ -382,10 +385,10 @@
//! let module = Module::new(&store, &module_wat).unwrap();
//! // The module doesn't import anything, so we create an empty import object.
//! let import_object = imports! {};
//! let instance = Instance::new(&module, &import_object).unwrap();
//! let instance = Instance::new(&mut store, &module, &import_object).unwrap();
//!
//! let add_one = instance.exports.get_function("add_one").unwrap();
//! let result = add_one.call(&[Value::I32(42)]).unwrap();
//! let result = add_one.call(&mut store, &[Value::I32(42)]).unwrap();
//! assert_eq!(result[0], Value::I32(43));
//!
//! result[0].unwrap_i32()

View File

@ -14,10 +14,10 @@ pub fn main() {
if git_hash.len() > 5 {
println!(
"cargo:rustc-env=WASMER_BUILD_GIT_HASH_SHORT={}",
&git_hash[..5]
&git_hash[..7]
);
} else {
println!("cargo:rustc-env=WASMER_BUILD_GIT_HASH_SHORT=??????");
println!("cargo:rustc-env=WASMER_BUILD_GIT_HASH_SHORT=???????");
}
let utc: DateTime<Utc> = Utc::now();

View File

@ -53,5 +53,5 @@ pub fn get_cache_dir() -> PathBuf {
}
pub(crate) fn normalize_path(s: &str) -> String {
s.strip_prefix(r"\\?\").unwrap_or(s).to_string()
wasmer_registry::utils::normalize_path(s)
}

View File

@ -15,6 +15,7 @@ use std::fmt;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::time::Duration;
use tar::EntryType;
use url::Url;
pub mod config;
@ -26,6 +27,7 @@ pub mod publish;
pub mod queries;
pub mod utils;
use crate::utils::normalize_path;
pub use crate::{
config::{format_graphql, WasmerConfig},
package::Package,
@ -415,8 +417,14 @@ pub fn try_unpack_targz<P: AsRef<Path>>(
target_path: P,
strip_toplevel: bool,
) -> Result<PathBuf, anyhow::Error> {
let target_targz_path = target_targz_path.as_ref();
let target_path = target_path.as_ref();
let target_targz_path = target_targz_path.as_ref().to_string_lossy().to_string();
let target_targz_path = crate::utils::normalize_path(&target_targz_path);
let target_targz_path = Path::new(&target_targz_path);
let target_path = target_path.as_ref().to_string_lossy().to_string();
let target_path = crate::utils::normalize_path(&target_path);
let target_path = Path::new(&target_path);
let open_file = || {
std::fs::File::open(target_targz_path)
.map_err(|e| anyhow::anyhow!("failed to open {}: {e}", target_targz_path.display()))
@ -425,14 +433,20 @@ pub fn try_unpack_targz<P: AsRef<Path>>(
let try_decode_gz = || {
let file = open_file()?;
let gz_decoded = flate2::read::GzDecoder::new(&file);
let mut ar = tar::Archive::new(gz_decoded);
let ar = tar::Archive::new(gz_decoded);
if strip_toplevel {
unpack_sans_parent(ar, target_path).map_err(|e| {
anyhow::anyhow!("failed to unpack {}: {e}", target_targz_path.display())
anyhow::anyhow!(
"failed to unpack (gz_ar_unpack_sans_parent) {}: {e}",
target_targz_path.display()
)
})
} else {
ar.unpack(target_path).map_err(|e| {
anyhow::anyhow!("failed to unpack {}: {e}", target_targz_path.display())
unpack_with_parent(ar, target_path).map_err(|e| {
anyhow::anyhow!(
"failed to unpack (gz_ar_unpack) {}: {e}",
target_targz_path.display()
)
})
}
};
@ -442,25 +456,37 @@ pub fn try_unpack_targz<P: AsRef<Path>>(
let mut decomp: Vec<u8> = Vec::new();
let mut bufread = std::io::BufReader::new(&file);
lzma_rs::xz_decompress(&mut bufread, &mut decomp).map_err(|e| {
anyhow::anyhow!("failed to unpack {}: {e}", target_targz_path.display())
anyhow::anyhow!(
"failed to unpack (try_decode_xz) {}: {e}",
target_targz_path.display()
)
})?;
let cursor = std::io::Cursor::new(decomp);
let mut ar = tar::Archive::new(cursor);
if strip_toplevel {
unpack_sans_parent(ar, target_path).map_err(|e| {
anyhow::anyhow!("failed to unpack {}: {e}", target_targz_path.display())
anyhow::anyhow!(
"failed to unpack (sans parent) {}: {e}",
target_targz_path.display()
)
})
} else {
ar.unpack(target_path).map_err(|e| {
anyhow::anyhow!("failed to unpack {}: {e}", target_targz_path.display())
ar.unpack(&target_path).map_err(|e| {
anyhow::anyhow!(
"failed to unpack (with parent) {}: {e}",
target_targz_path.display()
)
})
}
};
try_decode_gz().or_else(|_| try_decode_xz())?;
try_decode_gz().or_else(|e1| {
try_decode_xz()
.map_err(|e2| anyhow::anyhow!("could not decode gz: {e1}, could not decode xz: {e2}"))
})?;
Ok(target_targz_path.to_path_buf())
Ok(Path::new(&target_targz_path).to_path_buf())
}
/// Whether the top-level directory should be stripped
@ -494,12 +520,14 @@ pub fn download_and_unpack_targz(
Ok(target_path.to_path_buf())
}
pub fn unpack_sans_parent<R>(mut archive: tar::Archive<R>, dst: &Path) -> std::io::Result<()>
pub fn unpack_with_parent<R>(mut archive: tar::Archive<R>, dst: &Path) -> Result<(), anyhow::Error>
where
R: std::io::Read,
{
use std::path::Component::Normal;
let dst_normalized = normalize_path(dst.to_string_lossy().as_ref());
for entry in archive.entries()? {
let mut entry = entry?;
let path: PathBuf = entry
@ -508,7 +536,32 @@ where
.skip(1) // strip top-level directory
.filter(|c| matches!(c, Normal(_))) // prevent traversal attacks
.collect();
entry.unpack(dst.join(path))?;
if entry.header().entry_type().is_file() {
entry.unpack_in(&dst_normalized)?;
} else if entry.header().entry_type() == EntryType::Directory {
std::fs::create_dir_all(&Path::new(&dst_normalized).join(&path))?;
}
}
Ok(())
}
pub fn unpack_sans_parent<R>(mut archive: tar::Archive<R>, dst: &Path) -> std::io::Result<()>
where
R: std::io::Read,
{
use std::path::Component::Normal;
let dst_normalized = normalize_path(dst.to_string_lossy().as_ref());
for entry in archive.entries()? {
let mut entry = entry?;
let path: PathBuf = entry
.path()?
.components()
.skip(1) // strip top-level directory
.filter(|c| matches!(c, Normal(_))) // prevent traversal attacks
.collect();
entry.unpack(Path::new(&dst_normalized).join(path))?;
}
Ok(())
}
@ -538,7 +591,7 @@ pub fn install_package(wasmer_dir: &Path, url: &Url) -> Result<PathBuf, anyhow::
unpacked_targz_path.as_path(),
false,
)
.with_context(|| anyhow::anyhow!("Could not unpack file downloaded from {url}"))?;
.map_err(|e| anyhow::anyhow!("Could not unpack file downloaded from {url}: {e}"))?;
// read {unpacked}/wasmer.toml to get the name + version number
let toml_parsed = LocalPackage::read_toml(&unpacked_targz_path)

View File

@ -20,3 +20,7 @@ pub fn get_username_registry_token(registry: &str, token: &str) -> anyhow::Resul
let response: who_am_i_query::ResponseData = execute_query(registry, token, &q)?;
Ok(response.viewer.map(|viewer| viewer.username))
}
pub fn normalize_path(s: &str) -> String {
s.strip_prefix(r"\\?\").unwrap_or(s).to_string()
}

View File

@ -9,8 +9,6 @@ publish = false
[dev-dependencies]
rand = "0.8.5"
tar = "0.4.38"
flate2 = "1.0.24"
target-lexicon = "0.12.4"
serde = { version = "1.0.147", features = ["derive"] }
insta = { version = "1.21.1", features = ["json"] }
@ -23,6 +21,8 @@ object = "0.30.0"
anyhow = "1"
tempfile = "3"
target-lexicon = "0.12.5"
tar = "0.4.38"
flate2 = "1.0.24"
[features]
default = ["webc_runner"]

View File

@ -66,6 +66,12 @@ impl WasmerCreateExe {
output.args(self.extra_cli_flags.iter());
output.arg("-o");
output.arg(&self.native_executable_path);
if !self.extra_cli_flags.contains(&"--target".to_string()) {
let tarball_path = get_repo_root_path().unwrap().join("link.tar.gz");
assert!(tarball_path.exists(), "link.tar.gz does not exist");
output.arg("--tarball");
output.arg(&tarball_path);
}
let cmd = format!("{:?}", output);
println!("(integration-test) running create-exe: {cmd}");
@ -257,14 +263,8 @@ fn test_create_exe_with_precompiled_works_1() {
// Ignored because of -lunwind linker issue on Windows
// see https://github.com/wasmerio/wasmer/issues/3459
// #[cfg_attr(target_os = "windows", ignore)]
#[cfg_attr(target_os = "windows", ignore)]
#[test]
// Test temporarily ignored during the release of 3.2.0-alpha
// because create-exe links to the old libwasmer.a which expects
// MetadataHeader::VERSION == 1, but we want to upgrade to version 2.
//
// https://github.com/wasmerio/wasmer/issues/3513
#[ignore]
fn create_exe_works() -> anyhow::Result<()> {
let temp_dir = tempfile::tempdir()?;
let operating_dir: PathBuf = temp_dir.path().to_owned();
@ -301,14 +301,8 @@ fn create_exe_works() -> anyhow::Result<()> {
/// Tests that "-c" and "-- -c" are treated differently
// Ignored because of -lunwind linker issue on Windows
// see https://github.com/wasmerio/wasmer/issues/3459
// #[cfg_attr(target_os = "windows", ignore)]
#[cfg_attr(target_os = "windows", ignore)]
#[test]
// Test temporarily ignored during the release of 3.2.0-alpha
// because create-exe links to the old libwasmer.a which expects
// MetadataHeader::VERSION == 1, but we want to upgrade to version 2.
//
// https://github.com/wasmerio/wasmer/issues/3513
#[ignore]
fn create_exe_works_multi_command_args_handling() -> anyhow::Result<()> {
let temp_dir = tempfile::tempdir()?;
let operating_dir: PathBuf = temp_dir.path().to_owned();
@ -373,14 +367,8 @@ fn create_exe_works_multi_command_args_handling() -> anyhow::Result<()> {
// Ignored because of -lunwind linker issue on Windows
// see https://github.com/wasmerio/wasmer/issues/3459
// #[cfg_attr(target_os = "windows", ignore)]
#[cfg_attr(target_os = "windows", ignore)]
#[test]
// Test temporarily ignored during the release of 3.2.0-alpha
// because create-exe links to the old libwasmer.a which expects
// MetadataHeader::VERSION == 1, but we want to upgrade to version 2.
//
// https://github.com/wasmerio/wasmer/issues/3513
#[ignore]
fn create_exe_works_multi_command() -> anyhow::Result<()> {
let temp_dir = tempfile::tempdir()?;
let operating_dir: PathBuf = temp_dir.path().to_owned();
@ -436,14 +424,8 @@ fn create_exe_works_multi_command() -> anyhow::Result<()> {
// Ignored because of -lunwind linker issue on Windows
// see https://github.com/wasmerio/wasmer/issues/3459
// #[cfg_attr(target_os = "windows", ignore)]
#[cfg_attr(target_os = "windows", ignore)]
#[test]
// Test temporarily ignored during the release of 3.2.0-alpha
// because create-exe links to the old libwasmer.a which expects
// MetadataHeader::VERSION == 1, but we want to upgrade to version 2.
//
// https://github.com/wasmerio/wasmer/issues/3513
#[ignore]
fn create_exe_works_with_file() -> anyhow::Result<()> {
let temp_dir = tempfile::tempdir()?;
let operating_dir: PathBuf = temp_dir.path().to_owned();
@ -509,12 +491,6 @@ fn create_exe_works_with_file() -> anyhow::Result<()> {
// see https://github.com/wasmerio/wasmer/issues/3459
#[cfg_attr(target_os = "windows", ignore)]
#[test]
// Test temporarily ignored during the release of 3.2.0-alpha
// because create-exe links to the old libwasmer.a which expects
// MetadataHeader::VERSION == 1, but we want to upgrade to version 2.
//
// https://github.com/wasmerio/wasmer/issues/3513
#[ignore]
fn create_exe_serialized_works() -> anyhow::Result<()> {
let temp_dir = tempfile::tempdir()?;
let operating_dir: PathBuf = temp_dir.path().to_owned();
@ -697,42 +673,24 @@ fn create_exe_with_object_input(args: Vec<String>) -> anyhow::Result<()> {
// Ignored because of -lunwind linker issue on Windows
// see https://github.com/wasmerio/wasmer/issues/3459
// #[cfg_attr(target_os = "windows", ignore)]
#[cfg_attr(target_os = "windows", ignore)]
#[test]
// Test temporarily ignored during the release of 3.2.0-alpha
// because create-exe links to the old libwasmer.a which expects
// MetadataHeader::VERSION == 1, but we want to upgrade to version 2.
//
// https://github.com/wasmerio/wasmer/issues/3513
#[ignore]
fn create_exe_with_object_input_default() -> anyhow::Result<()> {
create_exe_with_object_input(vec![])
}
// Ignored because of -lunwind linker issue on Windows
// see https://github.com/wasmerio/wasmer/issues/3459
// #[cfg_attr(target_os = "windows", ignore)]
#[cfg_attr(target_os = "windows", ignore)]
#[test]
// Test temporarily ignored during the release of 3.2.0-alpha
// because create-exe links to the old libwasmer.a which expects
// MetadataHeader::VERSION == 1, but we want to upgrade to version 2.
//
// https://github.com/wasmerio/wasmer/issues/3513
#[ignore]
fn create_exe_with_object_input_symbols() -> anyhow::Result<()> {
create_exe_with_object_input(vec!["--object-format".to_string(), "symbols".to_string()])
}
// Ignored because of -lunwind linker issue on Windows
// see https://github.com/wasmerio/wasmer/issues/3459
// #[cfg_attr(target_os = "windows", ignore)]
#[cfg_attr(target_os = "windows", ignore)]
#[test]
// Test temporarily ignored during the release of 3.2.0-alpha
// because create-exe links to the old libwasmer.a which expects
// MetadataHeader::VERSION == 1, but we want to upgrade to version 2.
//
// https://github.com/wasmerio/wasmer/issues/3513
#[ignore]
fn create_exe_with_object_input_serialized() -> anyhow::Result<()> {
create_exe_with_object_input(vec![
"--object-format".to_string(),

View File

@ -3,7 +3,7 @@
use anyhow::{bail, Context};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use wasmer_integration_tests_cli::{get_repo_root_path, get_wasmer_path, ASSET_PATH, C_ASSET_PATH};
use wasmer_integration_tests_cli::{get_libwasmer_path, get_wasmer_path, ASSET_PATH, C_ASSET_PATH};
fn wasi_test_python_path() -> PathBuf {
Path::new(C_ASSET_PATH).join("python-0.1.0.wasmer")
@ -21,6 +21,91 @@ fn test_no_start_wat_path() -> PathBuf {
Path::new(ASSET_PATH).join("no_start.wat")
}
/// Ignored on Windows because running vendored packages does not work
/// since Windows does not allow `::` characters in filenames (every other OS does)
///
/// The syntax for vendored package atoms has to be reworked for this to be fixed, see
/// https://github.com/wasmerio/wasmer/issues/3535
#[cfg_attr(target_os = "windows", ignore)]
#[test]
fn test_run_customlambda() -> anyhow::Result<()> {
let bindir = String::from_utf8(
Command::new(get_wasmer_path())
.arg("config")
.arg("--bindir")
.output()
.expect("failed to run wasmer config --bindir")
.stdout,
)
.expect("wasmer config --bindir stdout failed");
// /Users/fs/.wasmer/bin
let checkouts_path = Path::new(&bindir)
.parent()
.expect("--bindir: no parent")
.join("checkouts");
println!("checkouts path: {}", checkouts_path.display());
let _ = std::fs::remove_dir_all(&checkouts_path);
let output = Command::new(get_wasmer_path())
.arg("run")
.arg("https://wapm.io/ciuser/customlambda")
// TODO: this argument should not be necessary later
// see https://github.com/wasmerio/wasmer/issues/3514
.arg("customlambda.py")
.arg("55")
.output()?;
let stdout_output = std::str::from_utf8(&output.stdout).unwrap();
let stderr_output = std::str::from_utf8(&output.stderr).unwrap();
println!("first run:");
println!("stdout: {stdout_output}");
println!("stderr: {stderr_output}");
assert_eq!(stdout_output, "139583862445\n");
// Run again to verify the caching
let output = Command::new(get_wasmer_path())
.arg("run")
.arg("https://wapm.io/ciuser/customlambda")
// TODO: this argument should not be necessary later
// see https://github.com/wasmerio/wasmer/issues/3514
.arg("customlambda.py")
.arg("55")
.output()?;
let stdout_output = std::str::from_utf8(&output.stdout).unwrap();
let stderr_output = std::str::from_utf8(&output.stderr).unwrap();
println!("second run:");
println!("stdout: {stdout_output}");
println!("stderr: {stderr_output}");
assert_eq!(stdout_output, "139583862445\n");
Ok(())
}
fn assert_tarball_is_present_local(target: &str) -> Result<PathBuf, anyhow::Error> {
let wasmer_dir = std::env::var("WASMER_DIR").expect("no WASMER_DIR set");
let directory = match target {
"aarch64-darwin" => "wasmer-darwin-arm64.tar.gz",
"x86_64-darwin" => "wasmer-darwin-amd64.tar.gz",
"x86_64-linux-gnu" => "wasmer-linux-amd64.tar.gz",
"aarch64-linux-gnu" => "wasmer-linux-aarch64.tar.gz",
"x86_64-windows-gnu" => "wasmer-windows-gnu64.tar.gz",
_ => return Err(anyhow::anyhow!("unknown target {target}")),
};
let libwasmer_cache_path = Path::new(&wasmer_dir).join("cache").join(directory);
if !libwasmer_cache_path.exists() {
return Err(anyhow::anyhow!(
"targz {} does not exist",
libwasmer_cache_path.display()
));
}
println!("using targz {}", libwasmer_cache_path.display());
Ok(libwasmer_cache_path)
}
#[test]
fn test_cross_compile_python_windows() -> anyhow::Result<()> {
let temp_dir = tempfile::TempDir::new()?;
@ -66,6 +151,10 @@ fn test_cross_compile_python_windows() -> anyhow::Result<()> {
println!("{t} target {c}");
let python_wasmer_path = temp_dir.path().join(format!("{t}-python"));
let tarball = match std::env::var("GITHUB_TOKEN") {
Ok(_) => Some(assert_tarball_is_present_local(t)?),
Err(_) => None,
};
let mut output = Command::new(get_wasmer_path());
output.arg("create-exe");
@ -75,12 +164,21 @@ fn test_cross_compile_python_windows() -> anyhow::Result<()> {
output.arg("-o");
output.arg(python_wasmer_path.clone());
output.arg(format!("--{c}"));
output.arg("--debug-dir");
output.arg(format!("{t}-{c}"));
if t.contains("x86_64") && *c == "singlepass" {
output.arg("-m");
output.arg("avx");
}
if let Some(t) = tarball {
output.arg("--tarball");
output.arg(t);
}
println!("command {:?}", output);
let output = output.output()?;
let stdout = std::str::from_utf8(&output.stdout)
@ -195,20 +293,6 @@ fn run_wasi_works() -> anyhow::Result<()> {
Ok(())
}
#[cfg(feature = "webc_runner")]
fn package_directory(in_dir: &PathBuf, out: &PathBuf) {
use flate2::write::GzEncoder;
use flate2::Compression;
use std::fs::File;
let tar = File::create(out).unwrap();
let enc = GzEncoder::new(tar, Compression::none());
let mut a = tar::Builder::new(enc);
a.append_dir_all("bin", in_dir.join("bin")).unwrap();
a.append_dir_all("lib", in_dir.join("lib")).unwrap();
a.append_dir_all("include", in_dir.join("include")).unwrap();
a.finish().unwrap();
}
/// TODO: on linux-musl, the packaging of libwasmer.a doesn't work properly
/// Tracked in https://github.com/wasmerio/wasmer/issues/3271
#[cfg(not(any(target_env = "musl", target_os = "windows")))]
@ -217,6 +301,8 @@ fn package_directory(in_dir: &PathBuf, out: &PathBuf) {
fn test_wasmer_create_exe_pirita_works() -> anyhow::Result<()> {
// let temp_dir = Path::new("debug");
// std::fs::create_dir_all(&temp_dir);
use wasmer_integration_tests_cli::get_repo_root_path;
let temp_dir = tempfile::TempDir::new()?;
let temp_dir = temp_dir.path().to_path_buf();
let python_wasmer_path = temp_dir.join("python.wasmer");
@ -224,24 +310,9 @@ fn test_wasmer_create_exe_pirita_works() -> anyhow::Result<()> {
let python_exe_output_path = temp_dir.join("python");
let native_target = target_lexicon::HOST;
let root_path = get_repo_root_path().unwrap();
let package_path = root_path.join("package");
if !package_path.exists() {
panic!("package path {} does not exist", package_path.display());
}
let tmp_targz_path = temp_dir.join("link.tar.gz");
let tmp_targz_path = get_repo_root_path().unwrap().join("link.tar.gz");
println!("compiling to target {native_target}");
println!(
"packaging /package to .tar.gz: {}",
tmp_targz_path.display()
);
package_directory(&package_path, &tmp_targz_path);
println!("packaging done");
println!(
"tmp tar gz path: {} - exists: {:?}",
tmp_targz_path.display(),
tmp_targz_path.exists()
);
let mut cmd = Command::new(get_wasmer_path());
cmd.arg("create-exe");
@ -576,7 +647,10 @@ fn run_test_caching_works_for_packages() -> anyhow::Result<()> {
.output()?;
if output.stdout != b"hello\n".to_vec() {
panic!("failed to run https://wapm.io/python/python for the first time");
panic!("failed to run https://wapm.io/python/python for the first time: stdout = {}, stderr = {}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
);
}
let time = std::time::Instant::now();