[Module] Remove DataDescription's writable field.
It was redundant, as data object declarations also have a writable field, so just use that, avoiding the need for users to declare the same thing twice. Fixes #456.
This commit is contained in:
@@ -193,11 +193,11 @@ impl Backend for FaerieBackend {
|
|||||||
fn define_data(
|
fn define_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
_writable: bool,
|
||||||
data_ctx: &DataContext,
|
data_ctx: &DataContext,
|
||||||
namespace: &ModuleNamespace<Self>,
|
namespace: &ModuleNamespace<Self>,
|
||||||
) -> ModuleResult<FaerieCompiledData> {
|
) -> ModuleResult<FaerieCompiledData> {
|
||||||
let &DataDescription {
|
let &DataDescription {
|
||||||
writable: _writable,
|
|
||||||
ref init,
|
ref init,
|
||||||
ref function_decls,
|
ref function_decls,
|
||||||
ref data_decls,
|
ref data_decls,
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ where
|
|||||||
fn define_data(
|
fn define_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
writable: bool,
|
||||||
data_ctx: &DataContext,
|
data_ctx: &DataContext,
|
||||||
namespace: &ModuleNamespace<Self>,
|
namespace: &ModuleNamespace<Self>,
|
||||||
) -> ModuleResult<Self::CompiledData>;
|
) -> ModuleResult<Self::CompiledData>;
|
||||||
|
|||||||
@@ -34,19 +34,8 @@ impl Init {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A flag specifying whether data is readonly or may be written to.
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
|
||||||
pub enum Writability {
|
|
||||||
/// Data is readonly, meaning writes to it will trap.
|
|
||||||
Readonly,
|
|
||||||
/// Data is writable.
|
|
||||||
Writable,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A description of a data object.
|
/// A description of a data object.
|
||||||
pub struct DataDescription {
|
pub struct DataDescription {
|
||||||
/// Whether the data readonly or writable.
|
|
||||||
pub writable: Writability,
|
|
||||||
/// How the data should be initialized.
|
/// How the data should be initialized.
|
||||||
pub init: Init,
|
pub init: Init,
|
||||||
/// External function declarations.
|
/// External function declarations.
|
||||||
@@ -69,7 +58,6 @@ impl DataContext {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
description: DataDescription {
|
description: DataDescription {
|
||||||
writable: Writability::Readonly,
|
|
||||||
init: Init::Uninitialized,
|
init: Init::Uninitialized,
|
||||||
function_decls: PrimaryMap::new(),
|
function_decls: PrimaryMap::new(),
|
||||||
data_decls: PrimaryMap::new(),
|
data_decls: PrimaryMap::new(),
|
||||||
@@ -81,7 +69,6 @@ impl DataContext {
|
|||||||
|
|
||||||
/// Clear all data structures in this context.
|
/// Clear all data structures in this context.
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.description.writable = Writability::Readonly;
|
|
||||||
self.description.init = Init::Uninitialized;
|
self.description.init = Init::Uninitialized;
|
||||||
self.description.function_decls.clear();
|
self.description.function_decls.clear();
|
||||||
self.description.data_decls.clear();
|
self.description.data_decls.clear();
|
||||||
@@ -90,18 +77,16 @@ impl DataContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Define a zero-initialized object with the given size.
|
/// Define a zero-initialized object with the given size.
|
||||||
pub fn define_zeroinit(&mut self, size: usize, writable: Writability) {
|
pub fn define_zeroinit(&mut self, size: usize) {
|
||||||
debug_assert_eq!(self.description.init, Init::Uninitialized);
|
debug_assert_eq!(self.description.init, Init::Uninitialized);
|
||||||
self.description.writable = writable;
|
|
||||||
self.description.init = Init::Zeros { size };
|
self.description.init = Init::Zeros { size };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Define an object initialized with the given contents.
|
/// Define an object initialized with the given contents.
|
||||||
///
|
///
|
||||||
/// TODO: Can we avoid a Box here?
|
/// TODO: Can we avoid a Box here?
|
||||||
pub fn define(&mut self, contents: Box<[u8]>, writable: Writability) {
|
pub fn define(&mut self, contents: Box<[u8]>) {
|
||||||
debug_assert_eq!(self.description.init, Init::Uninitialized);
|
debug_assert_eq!(self.description.init, Init::Uninitialized);
|
||||||
self.description.writable = writable;
|
|
||||||
self.description.init = Init::Bytes { contents };
|
self.description.init = Init::Bytes { contents };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,14 +133,13 @@ impl DataContext {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use cranelift_codegen::ir;
|
use cranelift_codegen::ir;
|
||||||
use {DataContext, Init, Writability};
|
use {DataContext, Init};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic_data_context() {
|
fn basic_data_context() {
|
||||||
let mut data_ctx = DataContext::new();
|
let mut data_ctx = DataContext::new();
|
||||||
{
|
{
|
||||||
let description = &data_ctx.description;
|
let description = &data_ctx.description;
|
||||||
assert_eq!(description.writable, Writability::Readonly);
|
|
||||||
assert_eq!(description.init, Init::Uninitialized);
|
assert_eq!(description.init, Init::Uninitialized);
|
||||||
assert!(description.function_decls.is_empty());
|
assert!(description.function_decls.is_empty());
|
||||||
assert!(description.data_decls.is_empty());
|
assert!(description.data_decls.is_empty());
|
||||||
@@ -163,7 +147,7 @@ mod tests {
|
|||||||
assert!(description.data_relocs.is_empty());
|
assert!(description.data_relocs.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
data_ctx.define_zeroinit(256, Writability::Writable);
|
data_ctx.define_zeroinit(256);
|
||||||
|
|
||||||
let _func_a = data_ctx.import_function(ir::ExternalName::user(0, 0));
|
let _func_a = data_ctx.import_function(ir::ExternalName::user(0, 0));
|
||||||
let func_b = data_ctx.import_function(ir::ExternalName::user(0, 1));
|
let func_b = data_ctx.import_function(ir::ExternalName::user(0, 1));
|
||||||
@@ -177,7 +161,6 @@ mod tests {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let description = data_ctx.description();
|
let description = data_ctx.description();
|
||||||
assert_eq!(description.writable, Writability::Writable);
|
|
||||||
assert_eq!(description.init, Init::Zeros { size: 256 });
|
assert_eq!(description.init, Init::Zeros { size: 256 });
|
||||||
assert_eq!(description.function_decls.len(), 3);
|
assert_eq!(description.function_decls.len(), 3);
|
||||||
assert_eq!(description.data_decls.len(), 2);
|
assert_eq!(description.data_decls.len(), 2);
|
||||||
@@ -188,7 +171,6 @@ mod tests {
|
|||||||
data_ctx.clear();
|
data_ctx.clear();
|
||||||
{
|
{
|
||||||
let description = &data_ctx.description;
|
let description = &data_ctx.description;
|
||||||
assert_eq!(description.writable, Writability::Readonly);
|
|
||||||
assert_eq!(description.init, Init::Uninitialized);
|
assert_eq!(description.init, Init::Uninitialized);
|
||||||
assert!(description.function_decls.is_empty());
|
assert!(description.function_decls.is_empty());
|
||||||
assert!(description.data_decls.is_empty());
|
assert!(description.data_decls.is_empty());
|
||||||
@@ -198,10 +180,9 @@ mod tests {
|
|||||||
|
|
||||||
let contents = vec![33, 34, 35, 36];
|
let contents = vec![33, 34, 35, 36];
|
||||||
let contents_clone = contents.clone();
|
let contents_clone = contents.clone();
|
||||||
data_ctx.define(contents.into_boxed_slice(), Writability::Readonly);
|
data_ctx.define(contents.into_boxed_slice());
|
||||||
{
|
{
|
||||||
let description = data_ctx.description();
|
let description = data_ctx.description();
|
||||||
assert_eq!(description.writable, Writability::Readonly);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
description.init,
|
description.init,
|
||||||
Init::Bytes {
|
Init::Bytes {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ mod data_context;
|
|||||||
mod module;
|
mod module;
|
||||||
|
|
||||||
pub use backend::Backend;
|
pub use backend::Backend;
|
||||||
pub use data_context::{DataContext, DataDescription, Init, Writability};
|
pub use data_context::{DataContext, DataDescription, Init};
|
||||||
pub use module::{
|
pub use module::{
|
||||||
DataId, FuncId, FuncOrDataId, Linkage, Module, ModuleError, ModuleNamespace, ModuleResult,
|
DataId, FuncId, FuncOrDataId, Linkage, Module, ModuleError, ModuleNamespace, ModuleResult,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -507,6 +507,7 @@ where
|
|||||||
}
|
}
|
||||||
Some(self.backend.define_data(
|
Some(self.backend.define_data(
|
||||||
&info.decl.name,
|
&info.decl.name,
|
||||||
|
info.decl.writable,
|
||||||
data_ctx,
|
data_ctx,
|
||||||
&ModuleNamespace::<B> {
|
&ModuleNamespace::<B> {
|
||||||
contents: &self.contents,
|
contents: &self.contents,
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ use cranelift_codegen::isa::TargetIsa;
|
|||||||
use cranelift_codegen::{self, ir, settings};
|
use cranelift_codegen::{self, ir, settings};
|
||||||
use cranelift_module::{
|
use cranelift_module::{
|
||||||
Backend, DataContext, DataDescription, Init, Linkage, ModuleNamespace, ModuleResult,
|
Backend, DataContext, DataDescription, Init, Linkage, ModuleNamespace, ModuleResult,
|
||||||
Writability,
|
|
||||||
};
|
};
|
||||||
use cranelift_native;
|
use cranelift_native;
|
||||||
use libc;
|
use libc;
|
||||||
@@ -192,11 +191,11 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
|
|||||||
fn define_data(
|
fn define_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
_name: &str,
|
_name: &str,
|
||||||
|
writable: bool,
|
||||||
data: &DataContext,
|
data: &DataContext,
|
||||||
_namespace: &ModuleNamespace<Self>,
|
_namespace: &ModuleNamespace<Self>,
|
||||||
) -> ModuleResult<Self::CompiledData> {
|
) -> ModuleResult<Self::CompiledData> {
|
||||||
let &DataDescription {
|
let &DataDescription {
|
||||||
writable,
|
|
||||||
ref init,
|
ref init,
|
||||||
ref function_decls,
|
ref function_decls,
|
||||||
ref data_decls,
|
ref data_decls,
|
||||||
@@ -205,15 +204,14 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
|
|||||||
} = data.description();
|
} = data.description();
|
||||||
|
|
||||||
let size = init.size();
|
let size = init.size();
|
||||||
let storage = match writable {
|
let storage = if writable {
|
||||||
Writability::Readonly => self
|
self.writable_memory
|
||||||
.readonly_memory
|
|
||||||
.allocate(size)
|
.allocate(size)
|
||||||
.expect("TODO: handle OOM etc."),
|
.expect("TODO: handle OOM etc.")
|
||||||
Writability::Writable => self
|
} else {
|
||||||
.writable_memory
|
self.readonly_memory
|
||||||
.allocate(size)
|
.allocate(size)
|
||||||
.expect("TODO: handle OOM etc."),
|
.expect("TODO: handle OOM etc.")
|
||||||
};
|
};
|
||||||
|
|
||||||
match *init {
|
match *init {
|
||||||
|
|||||||
Reference in New Issue
Block a user