Merge pull request #77 from NikVolf/do_not_export_mutable_globals

All globals, exported by env are non-mutable
This commit is contained in:
Nikolay Volf 2017-07-28 11:19:41 +03:00 committed by GitHub
commit 01aa70463d
3 changed files with 12 additions and 14 deletions

View File

@ -86,7 +86,7 @@ pub struct EnvModuleInstance {
impl EnvModuleInstance { impl EnvModuleInstance {
pub fn new(params: EnvParams, module: Module) -> Result<Self, Error> { pub fn new(params: EnvParams, module: Module) -> Result<Self, Error> {
let mut instance = ModuleInstance::new(Weak::default(), "env".into(), module)?; let mut instance = ModuleInstance::new(Weak::default(), "env".into(), module)?;
instance.instantiate(false, None)?; instance.instantiate(None)?;
Ok(EnvModuleInstance { Ok(EnvModuleInstance {
_params: params, _params: params,
@ -183,19 +183,19 @@ pub fn env_module(params: EnvParams) -> Result<EnvModuleInstance, Error> {
// globals // globals
.with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(DEFAULT_STACK_BASE as i32)]))) .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(DEFAULT_STACK_BASE as i32)])))
.with_export(ExportEntry::new("STACK_BASE".into(), Internal::Global(INDEX_GLOBAL_STACK_BASE))) .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 as i32)]))) .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(DEFAULT_STACK_BASE as i32)])))
.with_export(ExportEntry::new("STACKTOP".into(), Internal::Global(INDEX_GLOBAL_STACK_TOP))) .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 + params.total_stack) as i32)]))) .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const((DEFAULT_STACK_BASE + params.total_stack) as i32)])))
.with_export(ExportEntry::new("STACK_MAX".into(), Internal::Global(INDEX_GLOBAL_STACK_MAX))) .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 + params.total_stack) as i32)]))) .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const((DEFAULT_STACK_BASE + params.total_stack) as i32)])))
.with_export(ExportEntry::new("DYNAMIC_BASE".into(), Internal::Global(INDEX_GLOBAL_DYNAMIC_BASE))) .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 + params.total_stack) as i32)]))) .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const((DEFAULT_STACK_BASE + params.total_stack) as i32)])))
.with_export(ExportEntry::new("DYNAMICTOP_PTR".into(), Internal::Global(INDEX_GLOBAL_DYNAMICTOP_PTR))) .with_export(ExportEntry::new("DYNAMICTOP_PTR".into(), Internal::Global(INDEX_GLOBAL_DYNAMICTOP_PTR)))
.with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, params.allow_memory_growth), InitExpr::new(vec![Opcode::I32Const(params.total_memory as i32)]))) .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, params.allow_memory_growth), InitExpr::new(vec![Opcode::I32Const(params.total_memory as i32)])))
.with_export(ExportEntry::new("TOTAL_MEMORY".into(), Internal::Global(INDEX_GLOBAL_TOTAL_MEMORY))) .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_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(0)])))
.with_export(ExportEntry::new("ABORT".into(), Internal::Global(INDEX_GLOBAL_ABORT))) .with_export(ExportEntry::new("ABORT".into(), Internal::Global(INDEX_GLOBAL_ABORT)))
.with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, true), InitExpr::new(vec![Opcode::I32Const(0)]))) .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(0)])))
.with_export(ExportEntry::new("EXITSTATUS".into(), Internal::Global(INDEX_GLOBAL_EXIT_STATUS))) .with_export(ExportEntry::new("EXITSTATUS".into(), Internal::Global(INDEX_GLOBAL_EXIT_STATUS)))
.with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(DEFAULT_TABLE_BASE as i32)]))) // TODO: what is this? .with_global(GlobalEntry::new(GlobalType::new(ValueType::I32, false), InitExpr::new(vec![Opcode::I32Const(DEFAULT_TABLE_BASE as i32)]))) // TODO: what is this?
.with_export(ExportEntry::new("tableBase".into(), Internal::Global(INDEX_GLOBAL_TABLE_BASE))) .with_export(ExportEntry::new("tableBase".into(), Internal::Global(INDEX_GLOBAL_TABLE_BASE)))

View File

@ -222,15 +222,13 @@ impl ModuleInstance {
} }
/// Run instantiation-time procedures (validation). Module is not completely validated until this call. /// Run instantiation-time procedures (validation). Module is not completely validated until this call.
pub fn instantiate<'a>(&mut self, is_user_module: bool, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<(), Error> { pub fn instantiate<'a>(&mut self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<(), Error> {
// validate start section // validate start section
if let Some(start_function) = self.module.start_section() { if let Some(start_function) = self.module.start_section() {
let func_type_index = self.require_function(ItemIndex::IndexSpace(start_function))?; let func_type_index = self.require_function(ItemIndex::IndexSpace(start_function))?;
if is_user_module { // tests use non-empty main functions let func_type = self.function_type_by_index(func_type_index)?;
let func_type = self.function_type_by_index(func_type_index)?; if func_type.return_type() != None || func_type.params().len() != 0 {
if func_type.return_type() != None || func_type.params().len() != 0 { return Err(Error::Validation("start function expected to have type [] -> []".into()));
return Err(Error::Validation("start function expected to have type [] -> []".into()));
}
} }
} }
@ -244,7 +242,7 @@ impl ModuleInstance {
}, },
&Internal::Global(global_index) => { &Internal::Global(global_index) => {
self.global(ItemIndex::IndexSpace(global_index), None) self.global(ItemIndex::IndexSpace(global_index), None)
.and_then(|g| if g.is_mutable() && is_user_module { .and_then(|g| if g.is_mutable() {
Err(Error::Validation(format!("trying to export mutable global {}", export.field()))) Err(Error::Validation(format!("trying to export mutable global {}", export.field())))
} else { } else {
Ok(()) Ok(())
@ -326,7 +324,7 @@ impl ModuleInstance {
} }
// validate every function body in user modules // validate every function body in user modules
if is_user_module && function_section_len != 0 { // tests use invalid code if function_section_len != 0 { // tests use invalid code
let function_section = self.module.function_section().expect("function_section_len != 0; qed"); let function_section = self.module.function_section().expect("function_section_len != 0; qed");
let code_section = self.module.code_section().expect("function_section_len != 0; function_section_len == code_section_len; qed"); let code_section = self.module.code_section().expect("function_section_len != 0; function_section_len == code_section_len; qed");
// check every function body // check every function body

View File

@ -34,7 +34,7 @@ impl ProgramInstance {
/// 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)?;
module_instance.instantiate(true, externals)?; module_instance.instantiate(externals)?;
let module_instance = Arc::new(module_instance); let module_instance = Arc::new(module_instance);
self.essence.modules.write().insert(name.into(), module_instance.clone()); self.essence.modules.write().insert(name.into(), module_instance.clone());