diff --git a/src/interpreter/env.rs b/src/interpreter/env.rs index 9535445..2325da6 100644 --- a/src/interpreter/env.rs +++ b/src/interpreter/env.rs @@ -152,16 +152,15 @@ impl ModuleInstanceInterface for EnvModuleInstance { } } -pub fn env_module() -> Result { - let env_params = EnvParams::default(); - debug_assert!(env_params.total_stack < env_params.total_memory); - debug_assert!((env_params.total_stack % LINEAR_MEMORY_PAGE_SIZE) == 0); - debug_assert!((env_params.total_memory % LINEAR_MEMORY_PAGE_SIZE) == 0); +pub fn env_module(params: EnvParams) -> Result { + 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 builder = module() // memory regions .memory() - .with_min(env_params.total_memory / LINEAR_MEMORY_PAGE_SIZE) - .with_max(env_params.max_memory().map(|m| m / LINEAR_MEMORY_PAGE_SIZE)) + .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 @@ -174,13 +173,13 @@ pub fn env_module() -> Result { .with_export(ExportEntry::new("STACK_BASE".into(), Internal::Global(INDEX_GLOBAL_STACK_BASE))) .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, true), InitExpr::new(vec![Opcode::I32Const(DEFAULT_STACK_BASE.transmute_into())]))) .with_export(ExportEntry::new("STACKTOP".into(), Internal::Global(INDEX_GLOBAL_STACK_TOP))) - .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const((DEFAULT_STACK_BASE + env_params.total_stack).transmute_into())]))) + .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const((DEFAULT_STACK_BASE + params.total_stack).transmute_into())]))) .with_export(ExportEntry::new("STACK_MAX".into(), Internal::Global(INDEX_GLOBAL_STACK_MAX))) - .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const((DEFAULT_STACK_BASE + env_params.total_stack).transmute_into())]))) + .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const((DEFAULT_STACK_BASE + params.total_stack).transmute_into())]))) .with_export(ExportEntry::new("DYNAMIC_BASE".into(), Internal::Global(INDEX_GLOBAL_DYNAMIC_BASE))) - .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, true), InitExpr::new(vec![Opcode::I32Const((DEFAULT_STACK_BASE + env_params.total_stack).transmute_into())]))) + .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, true), InitExpr::new(vec![Opcode::I32Const((DEFAULT_STACK_BASE + params.total_stack).transmute_into())]))) .with_export(ExportEntry::new("DYNAMICTOP_PTR".into(), Internal::Global(INDEX_GLOBAL_DYNAMICTOP_PTR))) - .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, env_params.allow_memory_growth), InitExpr::new(vec![Opcode::I32Const(env_params.total_memory.transmute_into())]))) + .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, params.allow_memory_growth), InitExpr::new(vec![Opcode::I32Const(params.total_memory.transmute_into())]))) .with_export(ExportEntry::new("TOTAL_MEMORY".into(), Internal::Global(INDEX_GLOBAL_TOTAL_MEMORY))) .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, true), InitExpr::new(vec![Opcode::I32Const(0)]))) .with_export(ExportEntry::new("ABORT".into(), Internal::Global(INDEX_GLOBAL_ABORT))) @@ -210,7 +209,7 @@ pub fn env_module() -> Result { .build() .with_export(ExportEntry::new("getTotalMemory".into(), Internal::Function(INDEX_FUNC_GET_TOTAL_MEMORY))); - EnvModuleInstance::new(env_params, builder.build()) + EnvModuleInstance::new(params, builder.build()) } impl Default for EnvParams { diff --git a/src/interpreter/program.rs b/src/interpreter/program.rs index 41141f8..33c179d 100644 --- a/src/interpreter/program.rs +++ b/src/interpreter/program.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use parking_lot::RwLock; use elements::Module; use interpreter::Error; -use interpreter::env::env_module; +use interpreter::env::{self, env_module}; use interpreter::module::{ModuleInstance, ModuleInstanceInterface}; /// Program instance. Program is a set of instantiated modules. @@ -21,8 +21,13 @@ pub struct ProgramInstanceEssence { impl ProgramInstance { /// Create new program instance. pub fn new() -> Result { + ProgramInstance::with_env_params(env::EnvParams::default()) + } + + /// Create new program instance with custom env module params (mostly memory) + pub fn with_env_params(params: env::EnvParams) -> Result { Ok(ProgramInstance { - essence: Arc::new(ProgramInstanceEssence::new()?), + essence: Arc::new(ProgramInstanceEssence::with_env_params(params)?), }) } @@ -43,12 +48,16 @@ impl ProgramInstance { impl ProgramInstanceEssence { /// Create new program essence. pub fn new() -> Result { + ProgramInstanceEssence::with_env_params(env::EnvParams::default()) + } + + pub fn with_env_params(env_params: env::EnvParams) -> Result { let mut modules = HashMap::new(); - let env_module: Arc = Arc::new(env_module()?); + let env_module: Arc = Arc::new(env_module(env_params)?); modules.insert("env".into(), env_module); Ok(ProgramInstanceEssence { modules: RwLock::new(modules), - }) + }) } /// Get module reference.