Migrating code to object (from faerie) (#1848)
* Using the "object" library everywhere in wasmtime. * scroll_derive
This commit is contained in:
@@ -13,7 +13,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
wasmtime-environ = { path = "../environ", version = "0.17.0" }
|
||||
faerie = "0.15.0"
|
||||
object = { version = "0.18", default-features = false, features = ["write"] }
|
||||
more-asserts = "0.2.1"
|
||||
|
||||
[badges]
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
use anyhow::Result;
|
||||
use faerie::{Artifact, Decl};
|
||||
use object::write::{Object, StandardSection, Symbol, SymbolSection};
|
||||
use object::{SymbolFlags, SymbolKind, SymbolScope};
|
||||
use wasmtime_environ::DataInitializer;
|
||||
|
||||
/// Declares data segment symbol
|
||||
pub fn declare_data_segment(
|
||||
obj: &mut Artifact,
|
||||
obj: &mut Object,
|
||||
_data_initaliazer: &DataInitializer,
|
||||
index: usize,
|
||||
) -> Result<()> {
|
||||
let name = format!("_memory_{}", index);
|
||||
obj.declare(name, Decl::data())?;
|
||||
let _symbol_id = obj.add_symbol(Symbol {
|
||||
name: name.as_bytes().to_vec(),
|
||||
value: 0,
|
||||
size: 0,
|
||||
kind: SymbolKind::Data,
|
||||
scope: SymbolScope::Linkage,
|
||||
weak: false,
|
||||
section: SymbolSection::Undefined,
|
||||
flags: SymbolFlags::None,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Emit segment data and initialization location
|
||||
pub fn emit_data_segment(
|
||||
obj: &mut Artifact,
|
||||
obj: &mut Object,
|
||||
data_initaliazer: &DataInitializer,
|
||||
index: usize,
|
||||
) -> Result<()> {
|
||||
let name = format!("_memory_{}", index);
|
||||
obj.define(name, Vec::from(data_initaliazer.data))?;
|
||||
let symbol_id = obj.symbol_id(name.as_bytes()).unwrap();
|
||||
let section_id = obj.section_id(StandardSection::Data);
|
||||
obj.add_symbol_data(symbol_id, section_id, data_initaliazer.data, 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use faerie::{Artifact, Decl, Link};
|
||||
use object::write::{Object, Relocation, StandardSection, Symbol, SymbolSection};
|
||||
use object::{RelocationEncoding, RelocationKind, SymbolFlags, SymbolKind, SymbolScope};
|
||||
use wasmtime_environ::entity::EntityRef;
|
||||
use wasmtime_environ::settings;
|
||||
use wasmtime_environ::settings::Configurable;
|
||||
@@ -7,25 +8,43 @@ use wasmtime_environ::{Compilation, Module, RelocationTarget, Relocations};
|
||||
|
||||
/// Defines module functions
|
||||
pub fn declare_functions(
|
||||
obj: &mut Artifact,
|
||||
obj: &mut Object,
|
||||
module: &Module,
|
||||
relocations: &Relocations,
|
||||
) -> Result<()> {
|
||||
for i in 0..module.local.num_imported_funcs {
|
||||
let string_name = format!("_wasm_function_{}", i);
|
||||
obj.declare(string_name, Decl::function_import())?;
|
||||
let _symbol_id = obj.add_symbol(Symbol {
|
||||
name: string_name.as_bytes().to_vec(),
|
||||
value: 0,
|
||||
size: 0,
|
||||
kind: SymbolKind::Text,
|
||||
scope: SymbolScope::Unknown,
|
||||
weak: false,
|
||||
section: SymbolSection::Undefined,
|
||||
flags: SymbolFlags::None,
|
||||
});
|
||||
}
|
||||
for (i, _function_relocs) in relocations.iter().rev() {
|
||||
let func_index = module.local.func_index(i);
|
||||
let string_name = format!("_wasm_function_{}", func_index.index());
|
||||
obj.declare(string_name, Decl::function().global())?;
|
||||
let _symbol_id = obj.add_symbol(Symbol {
|
||||
name: string_name.as_bytes().to_vec(),
|
||||
value: 0,
|
||||
size: 0,
|
||||
kind: SymbolKind::Text,
|
||||
scope: SymbolScope::Linkage,
|
||||
weak: false,
|
||||
section: SymbolSection::Undefined,
|
||||
flags: SymbolFlags::None,
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Emits module functions
|
||||
pub fn emit_functions(
|
||||
obj: &mut Artifact,
|
||||
obj: &mut Object,
|
||||
module: &Module,
|
||||
compilation: &Compilation,
|
||||
relocations: &Relocations,
|
||||
@@ -46,22 +65,35 @@ pub fn emit_functions(
|
||||
let func_index = module.local.func_index(i);
|
||||
let string_name = format!("_wasm_function_{}", func_index.index());
|
||||
|
||||
obj.define(string_name, body.clone())?;
|
||||
let symbol_id = obj.symbol_id(string_name.as_bytes()).unwrap();
|
||||
let section_id = obj.section_id(StandardSection::Text);
|
||||
|
||||
obj.add_symbol_data(symbol_id, section_id, body, 1);
|
||||
}
|
||||
|
||||
for (i, function_relocs) in relocations.iter() {
|
||||
let func_index = module.local.func_index(i);
|
||||
let string_name = format!("_wasm_function_{}", func_index.index());
|
||||
let symbol_id = obj.symbol_id(string_name.as_bytes()).unwrap();
|
||||
let (_, section_offset) = obj.symbol_section_and_offset(symbol_id).unwrap();
|
||||
let section_id = obj.section_id(StandardSection::Text);
|
||||
for r in function_relocs {
|
||||
debug_assert_eq!(r.addend, 0);
|
||||
match r.reloc_target {
|
||||
RelocationTarget::UserFunc(target_index) => {
|
||||
let target_name = format!("_wasm_function_{}", target_index.index());
|
||||
obj.link(Link {
|
||||
from: &string_name,
|
||||
to: &target_name,
|
||||
at: r.offset as u64,
|
||||
})?;
|
||||
let target_symbol = obj.symbol_id(target_name.as_bytes()).unwrap();
|
||||
obj.add_relocation(
|
||||
section_id,
|
||||
Relocation {
|
||||
offset: section_offset + r.offset as u64,
|
||||
size: 64, // FIXME for all targets
|
||||
kind: RelocationKind::Absolute,
|
||||
encoding: RelocationEncoding::Generic,
|
||||
symbol: target_symbol,
|
||||
addend: 0,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
RelocationTarget::JumpTable(_, _) => {
|
||||
// ignore relocations for jump tables
|
||||
|
||||
@@ -3,24 +3,44 @@ use crate::data_segment::{declare_data_segment, emit_data_segment};
|
||||
use crate::function::{declare_functions, emit_functions};
|
||||
use crate::table::{declare_table, emit_table};
|
||||
use anyhow::Result;
|
||||
use faerie::{Artifact, Decl, Link};
|
||||
use object::write::{Object, Relocation, StandardSection, Symbol, SymbolSection};
|
||||
use object::{RelocationEncoding, RelocationKind, SymbolFlags, SymbolKind, SymbolScope};
|
||||
use wasmtime_environ::isa::TargetFrontendConfig;
|
||||
use wasmtime_environ::{Compilation, DataInitializer, Module, Relocations};
|
||||
|
||||
fn emit_vmcontext_init(
|
||||
obj: &mut Artifact,
|
||||
obj: &mut Object,
|
||||
module: &Module,
|
||||
target_config: &TargetFrontendConfig,
|
||||
) -> Result<()> {
|
||||
let (data, table_relocs) = layout_vmcontext(module, target_config);
|
||||
obj.declare_with("_vmcontext_init", Decl::data().global(), data.to_vec())?;
|
||||
let symbol_id = obj.add_symbol(Symbol {
|
||||
name: "_vmcontext_init".as_bytes().to_vec(),
|
||||
value: 0,
|
||||
size: 0,
|
||||
kind: SymbolKind::Data,
|
||||
scope: SymbolScope::Linkage,
|
||||
weak: false,
|
||||
section: SymbolSection::Undefined,
|
||||
flags: SymbolFlags::None,
|
||||
});
|
||||
let section_id = obj.section_id(StandardSection::Data);
|
||||
let section_offset = obj.add_symbol_data(symbol_id, section_id, &data, 1);
|
||||
|
||||
for reloc in table_relocs.iter() {
|
||||
let target_name = format!("_table_{}", reloc.index);
|
||||
obj.link(Link {
|
||||
from: "_vmcontext_init",
|
||||
to: &target_name,
|
||||
at: reloc.offset as u64,
|
||||
})?;
|
||||
let target_symbol = obj.symbol_id(target_name.as_bytes()).unwrap();
|
||||
obj.add_relocation(
|
||||
section_id,
|
||||
Relocation {
|
||||
offset: section_offset + reloc.offset as u64,
|
||||
size: 64, // FIXME for all targets
|
||||
kind: RelocationKind::Absolute,
|
||||
encoding: RelocationEncoding::Generic,
|
||||
symbol: target_symbol,
|
||||
addend: 0,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -28,7 +48,7 @@ fn emit_vmcontext_init(
|
||||
/// Emits a module that has been emitted with the `wasmtime-environ` environment
|
||||
/// implementation to a native object file.
|
||||
pub fn emit_module(
|
||||
obj: &mut Artifact,
|
||||
obj: &mut Object,
|
||||
module: &Module,
|
||||
compilation: &Compilation,
|
||||
relocations: &Relocations,
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
use anyhow::Result;
|
||||
use faerie::{Artifact, Decl};
|
||||
use object::write::{Object, StandardSection, Symbol, SymbolSection};
|
||||
use object::{SymbolFlags, SymbolKind, SymbolScope};
|
||||
|
||||
/// Declares data segment symbol
|
||||
pub fn declare_table(obj: &mut Artifact, index: usize) -> Result<()> {
|
||||
pub fn declare_table(obj: &mut Object, index: usize) -> Result<()> {
|
||||
let name = format!("_table_{}", index);
|
||||
obj.declare(name, Decl::data())?;
|
||||
let _symbol_id = obj.add_symbol(Symbol {
|
||||
name: name.as_bytes().to_vec(),
|
||||
value: 0,
|
||||
size: 0,
|
||||
kind: SymbolKind::Data,
|
||||
scope: SymbolScope::Linkage,
|
||||
weak: false,
|
||||
section: SymbolSection::Undefined,
|
||||
flags: SymbolFlags::None,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Emit segment data and initialization location
|
||||
pub fn emit_table(obj: &mut Artifact, index: usize) -> Result<()> {
|
||||
pub fn emit_table(obj: &mut Object, index: usize) -> Result<()> {
|
||||
let name = format!("_table_{}", index);
|
||||
let symbol_id = obj.symbol_id(name.as_bytes()).unwrap();
|
||||
let section_id = obj.section_id(StandardSection::Data);
|
||||
// FIXME: We need to initialize table using function symbols
|
||||
obj.define(name, Vec::new())?;
|
||||
obj.add_symbol_data(symbol_id, section_id, &[], 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user