mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-12 06:21:40 +00:00
Clean.
This commit is contained in:
@ -17,6 +17,7 @@ script:
|
|||||||
- cargo build --release --verbose
|
- cargo build --release --verbose
|
||||||
- cargo test --release --verbose
|
- cargo test --release --verbose
|
||||||
- cargo test --release --manifest-path=spec/Cargo.toml
|
- cargo test --release --manifest-path=spec/Cargo.toml
|
||||||
|
- cargo test --manifest-path=pwasm-emscripten/Cargo.toml
|
||||||
after_success: |-
|
after_success: |-
|
||||||
[ $TRAVIS_BRANCH = master ] &&
|
[ $TRAVIS_BRANCH = master ] &&
|
||||||
[ $TRAVIS_PULL_REQUEST = false ] &&
|
[ $TRAVIS_PULL_REQUEST = false ] &&
|
||||||
|
@ -4,7 +4,7 @@ extern crate parity_wasm;
|
|||||||
|
|
||||||
use std::env::args;
|
use std::env::args;
|
||||||
|
|
||||||
use parity_wasm::{interpreter, ModuleInstanceInterface};
|
use parity_wasm::ModuleInstanceInterface;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<_> = args().collect();
|
let args: Vec<_> = args().collect();
|
||||||
|
@ -251,8 +251,26 @@ impl EnvParams {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn program_with_emscripten(params: EnvParams) -> ProgramInstance {
|
pub fn program_with_emscripten_env(params: EnvParams) -> Result<ProgramInstance, Error> {
|
||||||
let program = ProgramInstance::new();
|
let program = ProgramInstance::new();
|
||||||
program.insert_loaded_module("env", env_module(params).unwrap()).unwrap();
|
program.insert_loaded_module("env", env_module(params)?)?;
|
||||||
program
|
Ok(program)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::program_with_emscripten_env;
|
||||||
|
use parity_wasm::builder::module;
|
||||||
|
use parity_wasm::elements::{ImportEntry, External, GlobalType, ValueType};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn import_env_mutable_global() {
|
||||||
|
let program = program_with_emscripten_env(Default::default()).unwrap();
|
||||||
|
|
||||||
|
let module = module()
|
||||||
|
.with_import(ImportEntry::new("env".into(), "STACKTOP".into(), External::Global(GlobalType::new(ValueType::I32, false))))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
program.add_module("main", module, None).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,248 +0,0 @@
|
|||||||
//! This module provides some of the simplest exports
|
|
||||||
//! from the Emscripten runtime, such as `STACKTOP` or `abort`.
|
|
||||||
|
|
||||||
use std::sync::{Arc, Weak};
|
|
||||||
use builder::module;
|
|
||||||
use elements::{ExportEntry, Internal, ValueType};
|
|
||||||
use interpreter::Error;
|
|
||||||
use interpreter::native::{native_module, UserDefinedElements, UserFunctionDescriptor, UserFunctionExecutor};
|
|
||||||
use interpreter::module::{CallerContext, ModuleInstance, ModuleInstanceInterface};
|
|
||||||
use interpreter::memory::LINEAR_MEMORY_PAGE_SIZE;
|
|
||||||
use interpreter::value::RuntimeValue;
|
|
||||||
use interpreter::variable::{VariableInstance, VariableType};
|
|
||||||
|
|
||||||
/// Memory address, at which stack begins.
|
|
||||||
const DEFAULT_STACK_TOP: u32 = 256 * 1024;
|
|
||||||
/// Memory, allocated for stack.
|
|
||||||
const DEFAULT_TOTAL_STACK: u32 = 5 * 1024 * 1024;
|
|
||||||
/// Total memory, allocated by default.
|
|
||||||
const DEFAULT_TOTAL_MEMORY: u32 = 16 * 1024 * 1024;
|
|
||||||
/// Whether memory can be enlarged, or not.
|
|
||||||
const DEFAULT_ALLOW_MEMORY_GROWTH: bool = true;
|
|
||||||
/// Default tableBase variable value.
|
|
||||||
const DEFAULT_TABLE_BASE: u32 = 0;
|
|
||||||
/// Default tableBase variable value.
|
|
||||||
const DEFAULT_MEMORY_BASE: u32 = 0;
|
|
||||||
|
|
||||||
/// Default table size.
|
|
||||||
const DEFAULT_TABLE_SIZE: u32 = 64;
|
|
||||||
|
|
||||||
/// Index of default memory.
|
|
||||||
const INDEX_MEMORY: u32 = 0;
|
|
||||||
|
|
||||||
/// Index of default table.
|
|
||||||
const INDEX_TABLE: u32 = 0;
|
|
||||||
|
|
||||||
/// Emscripten environment parameters.
|
|
||||||
pub struct EnvParams {
|
|
||||||
/// Stack size in bytes.
|
|
||||||
pub total_stack: u32,
|
|
||||||
/// Total memory size in bytes.
|
|
||||||
pub total_memory: u32,
|
|
||||||
/// Allow memory growth.
|
|
||||||
pub allow_memory_growth: bool,
|
|
||||||
/// Table size.
|
|
||||||
pub table_size: u32,
|
|
||||||
/// Static reserve, if any
|
|
||||||
pub static_size: Option<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EmscriptenFunctionExecutor {
|
|
||||||
abort_global: Arc<VariableInstance>,
|
|
||||||
total_mem_global: Arc<VariableInstance>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> UserFunctionExecutor for EmscriptenFunctionExecutor {
|
|
||||||
fn execute(
|
|
||||||
&mut self,
|
|
||||||
name: &str,
|
|
||||||
context: CallerContext,
|
|
||||||
) -> Result<Option<RuntimeValue>, Error> {
|
|
||||||
match name {
|
|
||||||
"_abort" | "abort" => {
|
|
||||||
self.abort_global.set(RuntimeValue::I32(1))?;
|
|
||||||
Err(Error::Trap("abort".into()).into())
|
|
||||||
}
|
|
||||||
"assert" => {
|
|
||||||
let condition = context.value_stack.pop_as::<i32>()?;
|
|
||||||
if condition == 0 {
|
|
||||||
self.abort_global.set(RuntimeValue::I32(1))?;
|
|
||||||
Err(Error::Trap("assertion failed".into()))
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"enlargeMemory" => {
|
|
||||||
// TODO: support memory enlarge
|
|
||||||
Ok(Some(RuntimeValue::I32(0)))
|
|
||||||
}
|
|
||||||
"getTotalMemory" => {
|
|
||||||
let total_memory = self.total_mem_global.get();
|
|
||||||
Ok(Some(total_memory))
|
|
||||||
}
|
|
||||||
_ => Err(Error::Trap("not implemented".into()).into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn env_module(params: EnvParams) -> Result<Arc<ModuleInstanceInterface>, Error> {
|
|
||||||
debug_assert!(params.total_stack < params.total_memory);
|
|
||||||
debug_assert!((params.total_stack % LINEAR_MEMORY_PAGE_SIZE) == 0);
|
|
||||||
debug_assert!((params.total_memory % LINEAR_MEMORY_PAGE_SIZE) == 0);
|
|
||||||
|
|
||||||
let stack_top = params.static_size.unwrap_or(DEFAULT_STACK_TOP);
|
|
||||||
|
|
||||||
// Build module with defined memory and table,
|
|
||||||
// instantiate it and wrap into an Arc.
|
|
||||||
let instance = {
|
|
||||||
let builder = module()
|
|
||||||
// memory regions
|
|
||||||
.memory()
|
|
||||||
.with_min(params.total_memory / LINEAR_MEMORY_PAGE_SIZE)
|
|
||||||
.with_max(params.max_memory().map(|m| m / LINEAR_MEMORY_PAGE_SIZE))
|
|
||||||
.build()
|
|
||||||
.with_export(ExportEntry::new("memory".into(), Internal::Memory(INDEX_MEMORY)))
|
|
||||||
// tables
|
|
||||||
.table()
|
|
||||||
.with_min(params.table_size)
|
|
||||||
.build()
|
|
||||||
.with_export(ExportEntry::new("table".into(), Internal::Table(INDEX_TABLE)));
|
|
||||||
let mut instance = ModuleInstance::new(Weak::default(), "env".into(), builder.build())?;
|
|
||||||
instance.instantiate(None)?;
|
|
||||||
Arc::new(instance)
|
|
||||||
};
|
|
||||||
|
|
||||||
let abort_global = Arc::new(
|
|
||||||
VariableInstance::new(
|
|
||||||
false,
|
|
||||||
VariableType::I32,
|
|
||||||
RuntimeValue::I32(0)
|
|
||||||
).unwrap()
|
|
||||||
);
|
|
||||||
let total_mem_global = Arc::new(
|
|
||||||
VariableInstance::new(
|
|
||||||
false,
|
|
||||||
VariableType::I32,
|
|
||||||
RuntimeValue::I32(params.total_memory as i32),
|
|
||||||
).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let function_executor = EmscriptenFunctionExecutor {
|
|
||||||
abort_global: Arc::clone(&abort_global),
|
|
||||||
total_mem_global: Arc::clone(&total_mem_global),
|
|
||||||
};
|
|
||||||
|
|
||||||
const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
|
||||||
UserFunctionDescriptor::Static("_abort", &[], None),
|
|
||||||
UserFunctionDescriptor::Static("abort", &[], None),
|
|
||||||
UserFunctionDescriptor::Static("assert", &[ValueType::I32], None),
|
|
||||||
UserFunctionDescriptor::Static("enlargeMemory", &[], Some(ValueType::I32)),
|
|
||||||
UserFunctionDescriptor::Static("getTotalMemory", &[], Some(ValueType::I32)),
|
|
||||||
];
|
|
||||||
|
|
||||||
let elements = UserDefinedElements {
|
|
||||||
executor: Some(function_executor),
|
|
||||||
globals: vec![
|
|
||||||
(
|
|
||||||
"STACK_BASE".into(),
|
|
||||||
Arc::new(
|
|
||||||
VariableInstance::new(
|
|
||||||
false,
|
|
||||||
VariableType::I32,
|
|
||||||
RuntimeValue::I32(stack_top as i32),
|
|
||||||
).unwrap(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"STACKTOP".into(),
|
|
||||||
Arc::new(
|
|
||||||
VariableInstance::new(
|
|
||||||
false,
|
|
||||||
VariableType::I32,
|
|
||||||
RuntimeValue::I32(stack_top as i32),
|
|
||||||
).unwrap(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"STACK_MAX".into(),
|
|
||||||
Arc::new(
|
|
||||||
VariableInstance::new(
|
|
||||||
false,
|
|
||||||
VariableType::I32,
|
|
||||||
RuntimeValue::I32((stack_top + params.total_stack) as i32),
|
|
||||||
).unwrap(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"DYNAMIC_BASE".into(),
|
|
||||||
Arc::new(
|
|
||||||
VariableInstance::new(
|
|
||||||
false,
|
|
||||||
VariableType::I32,
|
|
||||||
RuntimeValue::I32((stack_top + params.total_stack) as i32),
|
|
||||||
).unwrap(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"DYNAMICTOP_PTR".into(),
|
|
||||||
Arc::new(
|
|
||||||
VariableInstance::new(
|
|
||||||
false,
|
|
||||||
VariableType::I32,
|
|
||||||
RuntimeValue::I32((stack_top + params.total_stack) as i32),
|
|
||||||
).unwrap(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"EXITSTATUS".into(),
|
|
||||||
Arc::new(
|
|
||||||
VariableInstance::new(false, VariableType::I32, RuntimeValue::I32(0)).unwrap(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"tableBase".into(),
|
|
||||||
Arc::new(
|
|
||||||
VariableInstance::new(
|
|
||||||
false,
|
|
||||||
VariableType::I32,
|
|
||||||
RuntimeValue::I32(DEFAULT_TABLE_BASE as i32),
|
|
||||||
).unwrap(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"memoryBase".into(),
|
|
||||||
Arc::new(
|
|
||||||
VariableInstance::new(
|
|
||||||
false,
|
|
||||||
VariableType::I32,
|
|
||||||
RuntimeValue::I32(DEFAULT_MEMORY_BASE as i32),
|
|
||||||
).unwrap(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
("TOTAL_MEMORY".into(), total_mem_global),
|
|
||||||
("ABORT".into(), abort_global),
|
|
||||||
].into_iter()
|
|
||||||
.collect(),
|
|
||||||
functions: ::std::borrow::Cow::from(SIGNATURES),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(native_module(instance, elements)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for EnvParams {
|
|
||||||
fn default() -> Self {
|
|
||||||
EnvParams {
|
|
||||||
total_stack: DEFAULT_TOTAL_STACK,
|
|
||||||
total_memory: DEFAULT_TOTAL_MEMORY,
|
|
||||||
allow_memory_growth: DEFAULT_ALLOW_MEMORY_GROWTH,
|
|
||||||
table_size: DEFAULT_TABLE_SIZE,
|
|
||||||
static_size: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EnvParams {
|
|
||||||
fn max_memory(&self) -> Option<u32> {
|
|
||||||
if self.allow_memory_growth { None } else { Some(self.total_memory) }
|
|
||||||
}
|
|
||||||
}
|
|
@ -116,7 +116,6 @@ impl<U> From<U> for Error where U: UserError + Sized {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod emscripten;
|
|
||||||
mod native;
|
mod native;
|
||||||
mod imports;
|
mod imports;
|
||||||
mod memory;
|
mod memory;
|
||||||
@ -140,4 +139,3 @@ pub use self::program::ProgramInstance;
|
|||||||
pub use self::value::RuntimeValue;
|
pub use self::value::RuntimeValue;
|
||||||
pub use self::variable::{VariableInstance, VariableType, ExternalVariableValue};
|
pub use self::variable::{VariableInstance, VariableType, ExternalVariableValue};
|
||||||
pub use self::native::{native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
|
pub use self::native::{native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
|
||||||
pub use self::emscripten::EmscriptenParams;
|
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use elements::{Internal, ValueType};
|
use elements::{Internal, ValueType};
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::module::{ModuleInstance, ModuleInstanceInterface, ExecutionParams, ItemIndex,
|
use interpreter::module::{ModuleInstanceInterface, ExecutionParams, ItemIndex,
|
||||||
CallerContext, ExportEntryType, InternalFunctionReference, InternalFunction, FunctionSignature};
|
CallerContext, ExportEntryType, InternalFunctionReference, InternalFunction, FunctionSignature};
|
||||||
use interpreter::memory::MemoryInstance;
|
use interpreter::memory::MemoryInstance;
|
||||||
use interpreter::table::TableInstance;
|
use interpreter::table::TableInstance;
|
||||||
use interpreter::value::RuntimeValue;
|
use interpreter::value::RuntimeValue;
|
||||||
use interpreter::variable::{VariableInstance, VariableType};
|
use interpreter::variable::{VariableInstance, VariableType};
|
||||||
use builder::module;
|
|
||||||
|
|
||||||
/// Min index of native function.
|
/// Min index of native function.
|
||||||
pub const NATIVE_INDEX_FUNC_MIN: u32 = 10001;
|
pub const NATIVE_INDEX_FUNC_MIN: u32 = 10001;
|
||||||
@ -285,12 +284,6 @@ pub fn native_module<'a, E: UserFunctionExecutor + 'a>(base: Arc<ModuleInstanceI
|
|||||||
Ok(Arc::new(NativeModuleInstance::new(base, user_elements)?))
|
Ok(Arc::new(NativeModuleInstance::new(base, user_elements)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn simple_native_module<'a, E: UserFunctionExecutor + 'a>(user_elements: UserDefinedElements<E>) -> Result<Arc<ModuleInstanceInterface + 'a>, Error> {
|
|
||||||
let mut instance = ModuleInstance::new(Weak::default(), "env".into(), module().build())?;
|
|
||||||
instance.instantiate(None)?;
|
|
||||||
native_module(Arc::new(instance), user_elements)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> PartialEq for UserFunctionDescriptor {
|
impl<'a> PartialEq for UserFunctionDescriptor {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.params() == other.params()
|
self.params() == other.params()
|
||||||
|
@ -3,7 +3,6 @@ use std::collections::HashMap;
|
|||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use elements::Module;
|
use elements::Module;
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::emscripten::{self, env_module};
|
|
||||||
use interpreter::module::{ModuleInstance, ModuleInstanceInterface};
|
use interpreter::module::{ModuleInstance, ModuleInstanceInterface};
|
||||||
|
|
||||||
/// Program instance. Program is a set of instantiated modules.
|
/// Program instance. Program is a set of instantiated modules.
|
||||||
@ -26,17 +25,6 @@ impl ProgramInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new program instance with added Emscripten's `env` module.
|
|
||||||
///
|
|
||||||
/// You can specify desired environment params. Or you can just pass `Default::default()`.
|
|
||||||
pub fn with_emscripten_env(params: emscripten::EnvParams) -> Result<Self, Error> {
|
|
||||||
let instance = ProgramInstance {
|
|
||||||
essence: Arc::new(ProgramInstanceEssence::new()),
|
|
||||||
};
|
|
||||||
// instance.essence.modules.write().insert("env".into(), env_module(params)?);
|
|
||||||
Ok(instance)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Instantiate module with validation.
|
/// Instantiate module with validation.
|
||||||
pub fn add_module<'a>(&self, name: &str, module: Module, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<Arc<ModuleInstance>, Error> {
|
pub fn add_module<'a>(&self, name: &str, module: Module, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<Arc<ModuleInstance>, Error> {
|
||||||
let mut module_instance = ModuleInstance::new(Arc::downgrade(&self.essence), name.into(), module)?;
|
let mut module_instance = ModuleInstance::new(Arc::downgrade(&self.essence), name.into(), module)?;
|
||||||
|
@ -7,12 +7,13 @@ use builder::module;
|
|||||||
use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType,
|
use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType,
|
||||||
InitExpr, ValueType, BlockType, Opcodes, Opcode, FunctionType, TableType, MemoryType};
|
InitExpr, ValueType, BlockType, Opcodes, Opcode, FunctionType, TableType, MemoryType};
|
||||||
use interpreter::{Error, UserError, ProgramInstance};
|
use interpreter::{Error, UserError, ProgramInstance};
|
||||||
use interpreter::native::{simple_native_module, native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
|
use interpreter::native::{native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
|
||||||
use interpreter::memory::MemoryInstance;
|
use interpreter::memory::MemoryInstance;
|
||||||
use interpreter::module::{ModuleInstance, ModuleInstanceInterface, CallerContext, ItemIndex, ExecutionParams, ExportEntryType, FunctionSignature};
|
use interpreter::module::{ModuleInstance, ModuleInstanceInterface, CallerContext, ItemIndex, ExecutionParams, ExportEntryType, FunctionSignature};
|
||||||
use interpreter::validator::{FunctionValidationContext, Validator};
|
use interpreter::validator::{FunctionValidationContext, Validator};
|
||||||
use interpreter::value::{RuntimeValue, TryInto};
|
use interpreter::value::{RuntimeValue, TryInto};
|
||||||
use interpreter::variable::{VariableInstance, ExternalVariableValue, VariableType};
|
use interpreter::variable::{VariableInstance, ExternalVariableValue, VariableType};
|
||||||
|
use super::utils::program_with_default_env;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn import_function() {
|
fn import_function() {
|
||||||
@ -195,14 +196,11 @@ impl<'a> UserFunctionExecutor for &'a mut FunctionExecutor {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn native_env_function() {
|
fn native_env_function() {
|
||||||
let program = ProgramInstance::new();
|
// create new program
|
||||||
let env_module = module()
|
let program = program_with_default_env();
|
||||||
.memory()
|
// => env module is created
|
||||||
.with_min(1)
|
let env_instance = program.module("env").unwrap();
|
||||||
.build()
|
// => linear memory is created
|
||||||
.with_export(ExportEntry::new("memory".into(), Internal::Memory(0)))
|
|
||||||
.build();
|
|
||||||
let env_instance = program.add_module("env", env_module, None).unwrap();
|
|
||||||
let env_memory = env_instance.memory(ItemIndex::Internal(0)).unwrap();
|
let env_memory = env_instance.memory(ItemIndex::Internal(0)).unwrap();
|
||||||
|
|
||||||
// create native env module executor
|
// create native env module executor
|
||||||
@ -259,7 +257,7 @@ fn native_env_function() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn native_env_function_own_memory() {
|
fn native_env_function_own_memory() {
|
||||||
// create program + env module is auto instantiated + env module memory is instantiated (we do not need this)
|
// create program + env module is auto instantiated + env module memory is instantiated (we do not need this)
|
||||||
let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap();
|
let program = program_with_default_env();
|
||||||
|
|
||||||
struct OwnMemoryReference {
|
struct OwnMemoryReference {
|
||||||
pub memory: RefCell<Option<Arc<MemoryInstance>>>,
|
pub memory: RefCell<Option<Arc<MemoryInstance>>>,
|
||||||
@ -287,9 +285,10 @@ fn native_env_function_own_memory() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let env_instance = program.module("env").unwrap();
|
||||||
let memory_ref = Arc::new(OwnMemoryReference { memory: RefCell::new(None) });
|
let memory_ref = Arc::new(OwnMemoryReference { memory: RefCell::new(None) });
|
||||||
let mut executor = OwnMemoryExecutor { memory_ref: memory_ref.clone() };
|
let mut executor = OwnMemoryExecutor { memory_ref: memory_ref.clone() };
|
||||||
let native_env_instance = simple_native_module(UserDefinedElements {
|
let native_env_instance = native_module(env_instance, UserDefinedElements {
|
||||||
executor: Some(&mut executor),
|
executor: Some(&mut executor),
|
||||||
globals: HashMap::new(),
|
globals: HashMap::new(),
|
||||||
functions: ::std::borrow::Cow::from(SIGNATURES),
|
functions: ::std::borrow::Cow::from(SIGNATURES),
|
||||||
@ -336,8 +335,9 @@ fn native_env_global() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let module_constructor = |elements: UserDefinedElements<DummyExecutor>| {
|
let module_constructor = |elements: UserDefinedElements<DummyExecutor>| {
|
||||||
let program = ProgramInstance::new();
|
let program = program_with_default_env();
|
||||||
let native_env_instance = simple_native_module(elements).unwrap();
|
let env_instance = program.module("env").unwrap();
|
||||||
|
let native_env_instance = native_module(env_instance, elements).unwrap();
|
||||||
let params = ExecutionParams::with_external("env".into(), native_env_instance);
|
let params = ExecutionParams::with_external("env".into(), native_env_instance);
|
||||||
|
|
||||||
let module = module()
|
let module = module()
|
||||||
@ -384,14 +384,8 @@ fn native_env_global() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn native_custom_error() {
|
fn native_custom_error() {
|
||||||
let program = ProgramInstance::new();
|
let program = program_with_default_env();
|
||||||
let env_module = module()
|
let env_instance = program.module("env").unwrap();
|
||||||
.memory()
|
|
||||||
.with_min(1)
|
|
||||||
.build()
|
|
||||||
.with_export(ExportEntry::new("memory".into(), Internal::Memory(0)))
|
|
||||||
.build();
|
|
||||||
let env_instance = program.add_module("env", env_module, None).unwrap();
|
|
||||||
let env_memory = env_instance.memory(ItemIndex::Internal(0)).unwrap();
|
let env_memory = env_instance.memory(ItemIndex::Internal(0)).unwrap();
|
||||||
|
|
||||||
let mut executor = FunctionExecutor { memory: env_memory.clone(), values: Vec::new() };
|
let mut executor = FunctionExecutor { memory: env_memory.clone(), values: Vec::new() };
|
||||||
@ -442,29 +436,10 @@ fn native_custom_error() {
|
|||||||
assert_eq!(user_error2.downcast_ref::<UserErrorWithCode>().unwrap(), &UserErrorWithCode { error_code: 777 });
|
assert_eq!(user_error2.downcast_ref::<UserErrorWithCode>().unwrap(), &UserErrorWithCode { error_code: 777 });
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move into pwasm-emscripten
|
|
||||||
#[ignore]
|
|
||||||
#[test]
|
|
||||||
fn import_env_mutable_global() {
|
|
||||||
let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap();
|
|
||||||
|
|
||||||
let module = module()
|
|
||||||
.with_import(ImportEntry::new("env".into(), "STACKTOP".into(), External::Global(GlobalType::new(ValueType::I32, false))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
program.add_module("main", module, None).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_native_export_entry_type_check() {
|
fn env_native_export_entry_type_check() {
|
||||||
let program = ProgramInstance::new();
|
let program = program_with_default_env();
|
||||||
let env_module = module()
|
let env_instance = program.module("env").unwrap();
|
||||||
.memory()
|
|
||||||
.with_min(1)
|
|
||||||
.build()
|
|
||||||
.with_export(ExportEntry::new("memory".into(), Internal::Memory(0)))
|
|
||||||
.build();
|
|
||||||
let env_instance = program.add_module("env", env_module, None).unwrap();
|
|
||||||
let env_memory = env_instance.memory(ItemIndex::Internal(0)).unwrap();
|
let env_memory = env_instance.memory(ItemIndex::Internal(0)).unwrap();
|
||||||
let mut function_executor = FunctionExecutor {
|
let mut function_executor = FunctionExecutor {
|
||||||
memory: env_memory,
|
memory: env_memory,
|
||||||
|
@ -1,3 +1,29 @@
|
|||||||
mod basics;
|
mod basics;
|
||||||
mod wabt;
|
mod wabt;
|
||||||
mod wasm;
|
mod wasm;
|
||||||
|
|
||||||
|
mod utils {
|
||||||
|
use elements::{Internal, ExportEntry, InitExpr, Opcode, ValueType, GlobalType, GlobalEntry};
|
||||||
|
use interpreter::ProgramInstance;
|
||||||
|
use builder::module;
|
||||||
|
|
||||||
|
pub fn program_with_default_env() -> ProgramInstance {
|
||||||
|
let program = ProgramInstance::new();
|
||||||
|
let env_module = module()
|
||||||
|
.memory()
|
||||||
|
.with_min(256) // 256 pages. 256 * 64K = 16MB
|
||||||
|
.build()
|
||||||
|
.with_export(ExportEntry::new("memory".into(), Internal::Memory(0)))
|
||||||
|
.table()
|
||||||
|
.with_min(64)
|
||||||
|
.build()
|
||||||
|
.with_export(ExportEntry::new("table".into(), Internal::Table(0)))
|
||||||
|
.with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(0)])))
|
||||||
|
.with_export(ExportEntry::new("tableBase".into(), Internal::Global(0)))
|
||||||
|
.with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(0)])))
|
||||||
|
.with_export(ExportEntry::new("memoryBase".into(), Internal::Global(1)))
|
||||||
|
.build();
|
||||||
|
program.add_module("env", env_module, None).unwrap();
|
||||||
|
program
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use elements::deserialize_file;
|
use elements::deserialize_file;
|
||||||
use elements::Module;
|
use elements::{Module, Internal, ExportEntry, InitExpr, Opcode, ValueType, GlobalType, GlobalEntry};
|
||||||
use interpreter::{ExecutionParams, ProgramInstance};
|
use interpreter::{ExecutionParams, ProgramInstance};
|
||||||
use interpreter::value::RuntimeValue;
|
use interpreter::value::RuntimeValue;
|
||||||
use interpreter::module::{ModuleInstanceInterface, ItemIndex};
|
use interpreter::module::{ModuleInstanceInterface, ItemIndex};
|
||||||
|
use builder::module;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn interpreter_inc_i32() {
|
fn interpreter_inc_i32() {
|
||||||
@ -11,7 +12,22 @@ fn interpreter_inc_i32() {
|
|||||||
// The WASM file containing the module and function
|
// The WASM file containing the module and function
|
||||||
const WASM_FILE: &str = &"res/cases/v1/inc_i32.wasm";
|
const WASM_FILE: &str = &"res/cases/v1/inc_i32.wasm";
|
||||||
|
|
||||||
let program = ProgramInstance::with_emscripten_env(Default::default()).expect("Failed to instanciate program");
|
let program = ProgramInstance::new();
|
||||||
|
let env_module = module()
|
||||||
|
.memory()
|
||||||
|
.with_min(256)
|
||||||
|
.build()
|
||||||
|
.with_export(ExportEntry::new("memory".into(), Internal::Memory(0)))
|
||||||
|
.table()
|
||||||
|
.with_min(64)
|
||||||
|
.build()
|
||||||
|
.with_export(ExportEntry::new("table".into(), Internal::Table(0)))
|
||||||
|
.with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(0)])))
|
||||||
|
.with_export(ExportEntry::new("tableBase".into(), Internal::Global(0)))
|
||||||
|
.with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(0)])))
|
||||||
|
.with_export(ExportEntry::new("memoryBase".into(), Internal::Global(1)))
|
||||||
|
.build();
|
||||||
|
let _env_instance = program.add_module("env", env_module, None).unwrap();
|
||||||
|
|
||||||
let module: Module =
|
let module: Module =
|
||||||
deserialize_file(WASM_FILE).expect("Failed to deserialize module from buffer");
|
deserialize_file(WASM_FILE).expect("Failed to deserialize module from buffer");
|
||||||
@ -43,7 +59,22 @@ fn interpreter_accumulate_u8() {
|
|||||||
const BUF: &[u8] = &[9,8,7,6,5,4,3,2,1];
|
const BUF: &[u8] = &[9,8,7,6,5,4,3,2,1];
|
||||||
|
|
||||||
// Declare the memory limits of the runtime-environment
|
// Declare the memory limits of the runtime-environment
|
||||||
let program = ProgramInstance::with_emscripten_env(Default::default()).expect("Failed to instanciate program");
|
let program = ProgramInstance::new();
|
||||||
|
let env_module = module()
|
||||||
|
.memory()
|
||||||
|
.with_min(256)
|
||||||
|
.build()
|
||||||
|
.with_export(ExportEntry::new("memory".into(), Internal::Memory(0)))
|
||||||
|
.table()
|
||||||
|
.with_min(64)
|
||||||
|
.build()
|
||||||
|
.with_export(ExportEntry::new("table".into(), Internal::Table(0)))
|
||||||
|
.with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(0)])))
|
||||||
|
.with_export(ExportEntry::new("tableBase".into(), Internal::Global(0)))
|
||||||
|
.with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(0)])))
|
||||||
|
.with_export(ExportEntry::new("memoryBase".into(), Internal::Global(1)))
|
||||||
|
.build();
|
||||||
|
let _env_instance = program.add_module("env", env_module, None).unwrap();
|
||||||
|
|
||||||
// Load the module-structure from wasm-file and add to program
|
// Load the module-structure from wasm-file and add to program
|
||||||
let module: Module =
|
let module: Module =
|
||||||
|
Reference in New Issue
Block a user