Make globals non leaking

This commit is contained in:
Syrus
2020-05-04 13:10:22 -07:00
parent 0885cb5c95
commit c24c5c6946
6 changed files with 26 additions and 35 deletions

View File

@@ -113,15 +113,10 @@ impl Global {
Self::from_type(store, GlobalType::new(val.ty(), Mutability::Var), val).unwrap() Self::from_type(store, GlobalType::new(val.ty(), Mutability::Var), val).unwrap()
} }
pub fn from_type(store: &Store, ty: GlobalType, val: Val) -> Result<Global, RuntimeError> { fn from_type(store: &Store, ty: GlobalType, val: Val) -> Result<Global, RuntimeError> {
if !val.comes_from_same_store(store) { if !val.comes_from_same_store(store) {
return Err(RuntimeError::new("cross-`Store` globals are not supported")); return Err(RuntimeError::new("cross-`Store` globals are not supported"));
} }
if val.ty() != ty.ty.clone() {
return Err(RuntimeError::new(
"value provided does not match the type of this global",
));
}
let mut definition = VMGlobalDefinition::new(); let mut definition = VMGlobalDefinition::new();
unsafe { unsafe {
match val { match val {

View File

@@ -10,8 +10,8 @@ use wasm_common::entity::PrimaryMap;
use wasm_common::FuncType; use wasm_common::FuncType;
use wasm_common::{ use wasm_common::{
DataIndex, DataInitializer, DataInitializerLocation, ElemIndex, ExportIndex, FuncIndex, DataIndex, DataInitializer, DataInitializerLocation, ElemIndex, ExportIndex, FuncIndex,
GlobalIndex, GlobalType, ImportIndex, LocalFuncIndex, MemoryIndex, MemoryType, SignatureIndex, GlobalIndex, GlobalInit, GlobalType, ImportIndex, LocalFuncIndex, MemoryIndex, MemoryType,
TableIndex, TableType, SignatureIndex, TableIndex, TableType,
}; };
use wasmer_runtime::{Module, TableElements}; use wasmer_runtime::{Module, TableElements};
@@ -263,8 +263,13 @@ impl<'data> ModuleEnvironment<'data> {
Ok(()) Ok(())
} }
pub(crate) fn declare_global(&mut self, global: GlobalType) -> WasmResult<()> { pub(crate) fn declare_global(
&mut self,
global: GlobalType,
initializer: GlobalInit,
) -> WasmResult<()> {
self.result.module.globals.push(global); self.result.module.globals.push(global);
self.result.module.global_initializers.push(initializer);
Ok(()) Ok(())
} }

View File

@@ -130,7 +130,6 @@ pub fn parse_import_section<'data>(
GlobalType { GlobalType {
ty: wptype_to_type(ty.content_type).unwrap(), ty: wptype_to_type(ty.content_type).unwrap(),
mutability: ty.mutable.into(), mutability: ty.mutable.into(),
initializer: GlobalInit::Import,
}, },
module_name, module_name,
field_name, field_name,
@@ -254,9 +253,8 @@ pub fn parse_global_section(
let global = GlobalType { let global = GlobalType {
ty: wptype_to_type(content_type).unwrap(), ty: wptype_to_type(content_type).unwrap(),
mutability: mutable.into(), mutability: mutable.into(),
initializer,
}; };
environ.declare_global(global)?; environ.declare_global(global, initializer)?;
} }
Ok(()) Ok(())

View File

@@ -1229,22 +1229,20 @@ fn initialize_memories(
fn initialize_globals(instance: &Instance) { fn initialize_globals(instance: &Instance) {
let module = Arc::clone(&instance.module); let module = Arc::clone(&instance.module);
let num_imports = module.num_imported_globals; for (index, initializer) in module.global_initializers.iter() {
for (index, global) in module.globals.iter().skip(num_imports) {
let def_index = module.local_global_index(index).unwrap();
unsafe { unsafe {
let to = instance.global_ptr(def_index); let to = instance.global_ptr(index);
match global.initializer { match initializer {
GlobalInit::I32Const(x) => *(*to).as_i32_mut() = x, GlobalInit::I32Const(x) => *(*to).as_i32_mut() = *x,
GlobalInit::I64Const(x) => *(*to).as_i64_mut() = x, GlobalInit::I64Const(x) => *(*to).as_i64_mut() = *x,
GlobalInit::F32Const(x) => *(*to).as_f32_mut() = x, GlobalInit::F32Const(x) => *(*to).as_f32_mut() = *x,
GlobalInit::F64Const(x) => *(*to).as_f64_mut() = x, GlobalInit::F64Const(x) => *(*to).as_f64_mut() = *x,
GlobalInit::V128Const(x) => *(*to).as_u128_bits_mut() = *x.bytes(), GlobalInit::V128Const(x) => *(*to).as_u128_bits_mut() = *x.bytes(),
GlobalInit::GetGlobal(x) => { GlobalInit::GetGlobal(x) => {
let from = if let Some(def_x) = module.local_global_index(x) { let from = if let Some(def_x) = module.local_global_index(*x) {
instance.global(def_x) instance.global(def_x)
} else { } else {
*instance.imported_global(x).definition *instance.imported_global(*x).definition
}; };
*to = from; *to = from;
} }

View File

@@ -10,8 +10,9 @@ use std::sync::Arc;
use wasm_common::entity::{EntityRef, PrimaryMap}; use wasm_common::entity::{EntityRef, PrimaryMap};
use wasm_common::{ use wasm_common::{
DataIndex, ElemIndex, ExportIndex, ExportType, ExternType, FuncIndex, FuncType, GlobalIndex, DataIndex, ElemIndex, ExportIndex, ExportType, ExternType, FuncIndex, FuncType, GlobalIndex,
GlobalType, ImportIndex, ImportType, LocalFuncIndex, LocalGlobalIndex, LocalMemoryIndex, GlobalInit, GlobalType, ImportIndex, ImportType, LocalFuncIndex, LocalGlobalIndex,
LocalTableIndex, MemoryIndex, MemoryType, Pages, SignatureIndex, TableIndex, TableType, LocalMemoryIndex, LocalTableIndex, MemoryIndex, MemoryType, Pages, SignatureIndex, TableIndex,
TableType,
}; };
/// A WebAssembly table initializer. /// A WebAssembly table initializer.
@@ -124,6 +125,9 @@ pub struct Module {
/// WebAssembly passive data segments. /// WebAssembly passive data segments.
pub passive_data: HashMap<DataIndex, Arc<[u8]>>, pub passive_data: HashMap<DataIndex, Arc<[u8]>>,
/// WebAssembly global initializers.
pub global_initializers: PrimaryMap<LocalGlobalIndex, GlobalInit>,
/// WebAssembly function names. /// WebAssembly function names.
pub func_names: HashMap<FuncIndex, String>, pub func_names: HashMap<FuncIndex, String>,
@@ -167,6 +171,7 @@ impl Module {
table_elements: Vec::new(), table_elements: Vec::new(),
passive_elements: HashMap::new(), passive_elements: HashMap::new(),
passive_data: HashMap::new(), passive_data: HashMap::new(),
global_initializers: PrimaryMap::new(),
func_names: HashMap::new(), func_names: HashMap::new(),
signatures: PrimaryMap::new(), signatures: PrimaryMap::new(),
functions: PrimaryMap::new(), functions: PrimaryMap::new(),

View File

@@ -110,20 +110,13 @@ pub enum ExternType {
} }
fn is_global_compatible(exported: &GlobalType, imported: &GlobalType) -> bool { fn is_global_compatible(exported: &GlobalType, imported: &GlobalType) -> bool {
match imported.initializer {
GlobalInit::Import => (),
_ => panic!("imported Global should have an Imported initializer"),
}
let GlobalType { let GlobalType {
ty: exported_ty, ty: exported_ty,
mutability: exported_mutability, mutability: exported_mutability,
initializer: _exported_initializer,
} = exported; } = exported;
let GlobalType { let GlobalType {
ty: imported_ty, ty: imported_ty,
mutability: imported_mutability, mutability: imported_mutability,
initializer: _imported_initializer,
} = imported; } = imported;
exported_ty == imported_ty && imported_mutability == exported_mutability exported_ty == imported_ty && imported_mutability == exported_mutability
} }
@@ -318,8 +311,6 @@ pub struct GlobalType {
pub ty: Type, pub ty: Type,
/// A flag indicating whether the value may change at runtime. /// A flag indicating whether the value may change at runtime.
pub mutability: Mutability, pub mutability: Mutability,
/// The source of the initial value.
pub initializer: GlobalInit,
} }
// Global Types // Global Types
@@ -344,7 +335,6 @@ impl GlobalType {
Self { Self {
ty: ty, ty: ty,
mutability: mutability, mutability: mutability,
initializer: GlobalInit::Import,
} }
} }
} }