1 //! Defines `Module` and related types. 2 3 // TODO: Should `ir::Function` really have a `name`? 4 5 // TODO: Factor out `ir::Function`'s `ext_funcs` and `global_values` into a struct 6 // shared with `DataContext`? 7 8 use super::HashMap; 9 use crate::data_context::DataContext; 10 use core::fmt::Display; 11 use cranelift_codegen::binemit::{CodeOffset, Reloc}; 12 use cranelift_codegen::entity::{entity_impl, PrimaryMap}; 13 use cranelift_codegen::ir::Function; 14 use cranelift_codegen::{binemit, MachReloc}; 15 use cranelift_codegen::{ir, isa, CodegenError, CompileError, Context}; 16 use std::borrow::ToOwned; 17 use std::string::String; 18 19 /// A module relocation. 20 #[derive(Clone)] 21 pub struct ModuleReloc { 22 /// The offset at which the relocation applies, *relative to the 23 /// containing section*. 24 pub offset: CodeOffset, 25 /// The kind of relocation. 26 pub kind: Reloc, 27 /// The external symbol / name to which this relocation refers. 28 pub name: ModuleExtName, 29 /// The addend to add to the symbol value. 30 pub addend: i64, 31 } 32 33 impl ModuleReloc { 34 /// Converts a `MachReloc` produced from a `Function` into a `ModuleReloc`. 35 pub fn from_mach_reloc(mach_reloc: &MachReloc, func: &Function) -> Self { 36 let name = match mach_reloc.name { 37 ir::ExternalName::User(reff) => { 38 let name = &func.params.user_named_funcs()[reff]; 39 ModuleExtName::user(name.namespace, name.index) 40 } 41 ir::ExternalName::TestCase(_) => unimplemented!(), 42 ir::ExternalName::LibCall(libcall) => ModuleExtName::LibCall(libcall), 43 ir::ExternalName::KnownSymbol(ks) => ModuleExtName::KnownSymbol(ks), 44 }; 45 Self { 46 offset: mach_reloc.offset, 47 kind: mach_reloc.kind, 48 name, 49 addend: mach_reloc.addend, 50 } 51 } 52 } 53 54 /// A function identifier for use in the `Module` interface. 55 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 56 pub struct FuncId(u32); 57 entity_impl!(FuncId, "funcid"); 58 59 /// Function identifiers are namespace 0 in `ir::ExternalName` 60 impl From<FuncId> for ModuleExtName { 61 fn from(id: FuncId) -> Self { 62 Self::User { 63 namespace: 0, 64 index: id.0, 65 } 66 } 67 } 68 69 impl FuncId { 70 /// Get the `FuncId` for the function named by `name`. 71 pub fn from_name(name: &ModuleExtName) -> FuncId { 72 if let ModuleExtName::User { namespace, index } = name { 73 debug_assert_eq!(*namespace, 0); 74 FuncId::from_u32(*index) 75 } else { 76 panic!("unexpected name in DataId::from_name") 77 } 78 } 79 } 80 81 /// A data object identifier for use in the `Module` interface. 82 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 83 pub struct DataId(u32); 84 entity_impl!(DataId, "dataid"); 85 86 /// Data identifiers are namespace 1 in `ir::ExternalName` 87 impl From<DataId> for ModuleExtName { 88 fn from(id: DataId) -> Self { 89 Self::User { 90 namespace: 1, 91 index: id.0, 92 } 93 } 94 } 95 96 impl DataId { 97 /// Get the `DataId` for the data object named by `name`. 98 pub fn from_name(name: &ModuleExtName) -> DataId { 99 if let ModuleExtName::User { namespace, index } = name { 100 debug_assert_eq!(*namespace, 1); 101 DataId::from_u32(*index) 102 } else { 103 panic!("unexpected name in DataId::from_name") 104 } 105 } 106 } 107 108 /// Linkage refers to where an entity is defined and who can see it. 109 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 110 pub enum Linkage { 111 /// Defined outside of a module. 112 Import, 113 /// Defined inside the module, but not visible outside it. 114 Local, 115 /// Defined inside the module, visible outside it, and may be preempted. 116 Preemptible, 117 /// Defined inside the module, visible inside the current static linkage unit, but not outside. 118 /// 119 /// A static linkage unit is the combination of all object files passed to a linker to create 120 /// an executable or dynamic library. 121 Hidden, 122 /// Defined inside the module, and visible outside it. 123 Export, 124 } 125 126 impl Linkage { 127 fn merge(a: Self, b: Self) -> Self { 128 match a { 129 Self::Export => Self::Export, 130 Self::Hidden => match b { 131 Self::Export => Self::Export, 132 Self::Preemptible => Self::Preemptible, 133 _ => Self::Hidden, 134 }, 135 Self::Preemptible => match b { 136 Self::Export => Self::Export, 137 _ => Self::Preemptible, 138 }, 139 Self::Local => match b { 140 Self::Export => Self::Export, 141 Self::Hidden => Self::Hidden, 142 Self::Preemptible => Self::Preemptible, 143 Self::Local | Self::Import => Self::Local, 144 }, 145 Self::Import => b, 146 } 147 } 148 149 /// Test whether this linkage can have a definition. 150 pub fn is_definable(self) -> bool { 151 match self { 152 Self::Import => false, 153 Self::Local | Self::Preemptible | Self::Hidden | Self::Export => true, 154 } 155 } 156 157 /// Test whether this linkage will have a definition that cannot be preempted. 158 pub fn is_final(self) -> bool { 159 match self { 160 Self::Import | Self::Preemptible => false, 161 Self::Local | Self::Hidden | Self::Export => true, 162 } 163 } 164 } 165 166 /// A declared name may refer to either a function or data declaration 167 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] 168 pub enum FuncOrDataId { 169 /// When it's a FuncId 170 Func(FuncId), 171 /// When it's a DataId 172 Data(DataId), 173 } 174 175 /// Mapping to `ModuleExtName` is trivial based on the `FuncId` and `DataId` mapping. 176 impl From<FuncOrDataId> for ModuleExtName { 177 fn from(id: FuncOrDataId) -> Self { 178 match id { 179 FuncOrDataId::Func(funcid) => Self::from(funcid), 180 FuncOrDataId::Data(dataid) => Self::from(dataid), 181 } 182 } 183 } 184 185 /// Information about a function which can be called. 186 #[derive(Debug)] 187 pub struct FunctionDeclaration { 188 pub name: String, 189 pub linkage: Linkage, 190 pub signature: ir::Signature, 191 } 192 193 impl FunctionDeclaration { 194 fn merge(&mut self, linkage: Linkage, sig: &ir::Signature) -> Result<(), ModuleError> { 195 self.linkage = Linkage::merge(self.linkage, linkage); 196 if &self.signature != sig { 197 return Err(ModuleError::IncompatibleSignature( 198 self.name.clone(), 199 self.signature.clone(), 200 sig.clone(), 201 )); 202 } 203 Ok(()) 204 } 205 } 206 207 /// Error messages for all `Module` methods 208 #[derive(Debug)] 209 pub enum ModuleError { 210 /// Indicates an identifier was used before it was declared 211 Undeclared(String), 212 213 /// Indicates an identifier was used as data/function first, but then used as the other 214 IncompatibleDeclaration(String), 215 216 /// Indicates a function identifier was declared with a 217 /// different signature than declared previously 218 IncompatibleSignature(String, ir::Signature, ir::Signature), 219 220 /// Indicates an identifier was defined more than once 221 DuplicateDefinition(String), 222 223 /// Indicates an identifier was defined, but was declared as an import 224 InvalidImportDefinition(String), 225 226 /// Wraps a `cranelift-codegen` error 227 Compilation(CodegenError), 228 229 /// Wraps a generic error from a backend 230 Backend(anyhow::Error), 231 } 232 233 impl<'a> From<CompileError<'a>> for ModuleError { 234 fn from(err: CompileError<'a>) -> Self { 235 Self::Compilation(err.inner) 236 } 237 } 238 239 // This is manually implementing Error and Display instead of using thiserror to reduce the amount 240 // of dependencies used by Cranelift. 241 impl std::error::Error for ModuleError { 242 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 243 match self { 244 Self::Undeclared { .. } 245 | Self::IncompatibleDeclaration { .. } 246 | Self::IncompatibleSignature { .. } 247 | Self::DuplicateDefinition { .. } 248 | Self::InvalidImportDefinition { .. } => None, 249 Self::Compilation(source) => Some(source), 250 Self::Backend(source) => Some(&**source), 251 } 252 } 253 } 254 255 impl std::fmt::Display for ModuleError { 256 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 257 match self { 258 Self::Undeclared(name) => { 259 write!(f, "Undeclared identifier: {}", name) 260 } 261 Self::IncompatibleDeclaration(name) => { 262 write!(f, "Incompatible declaration of identifier: {}", name,) 263 } 264 Self::IncompatibleSignature(name, prev_sig, new_sig) => { 265 write!( 266 f, 267 "Function {} signature {:?} is incompatible with previous declaration {:?}", 268 name, new_sig, prev_sig, 269 ) 270 } 271 Self::DuplicateDefinition(name) => { 272 write!(f, "Duplicate definition of identifier: {}", name) 273 } 274 Self::InvalidImportDefinition(name) => { 275 write!( 276 f, 277 "Invalid to define identifier declared as an import: {}", 278 name, 279 ) 280 } 281 Self::Compilation(err) => { 282 write!(f, "Compilation error: {}", err) 283 } 284 Self::Backend(err) => write!(f, "Backend error: {}", err), 285 } 286 } 287 } 288 289 impl std::convert::From<CodegenError> for ModuleError { 290 fn from(source: CodegenError) -> Self { 291 Self::Compilation { 0: source } 292 } 293 } 294 295 /// A convenient alias for a `Result` that uses `ModuleError` as the error type. 296 pub type ModuleResult<T> = Result<T, ModuleError>; 297 298 /// Information about a data object which can be accessed. 299 #[derive(Debug)] 300 pub struct DataDeclaration { 301 pub name: String, 302 pub linkage: Linkage, 303 pub writable: bool, 304 pub tls: bool, 305 } 306 307 impl DataDeclaration { 308 fn merge(&mut self, linkage: Linkage, writable: bool, tls: bool) { 309 self.linkage = Linkage::merge(self.linkage, linkage); 310 self.writable = self.writable || writable; 311 assert_eq!( 312 self.tls, tls, 313 "Can't change TLS data object to normal or in the opposite way", 314 ); 315 } 316 } 317 318 /// A translated `ExternalName` into something global we can handle. 319 #[derive(Clone)] 320 pub enum ModuleExtName { 321 /// User defined function, converted from `ExternalName::User`. 322 User { 323 /// Arbitrary. 324 namespace: u32, 325 /// Arbitrary. 326 index: u32, 327 }, 328 /// Call into a library function. 329 LibCall(ir::LibCall), 330 /// Symbols known to the linker. 331 KnownSymbol(ir::KnownSymbol), 332 } 333 334 impl ModuleExtName { 335 /// Creates a user-defined external name. 336 pub fn user(namespace: u32, index: u32) -> Self { 337 Self::User { namespace, index } 338 } 339 } 340 341 impl Display for ModuleExtName { 342 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 343 match self { 344 Self::User { namespace, index } => write!(f, "u{}:{}", namespace, index), 345 Self::LibCall(lc) => write!(f, "%{}", lc), 346 Self::KnownSymbol(ks) => write!(f, "{}", ks), 347 } 348 } 349 } 350 351 /// This provides a view to the state of a module which allows `ir::ExternalName`s to be translated 352 /// into `FunctionDeclaration`s and `DataDeclaration`s. 353 #[derive(Debug, Default)] 354 pub struct ModuleDeclarations { 355 names: HashMap<String, FuncOrDataId>, 356 functions: PrimaryMap<FuncId, FunctionDeclaration>, 357 data_objects: PrimaryMap<DataId, DataDeclaration>, 358 } 359 360 impl ModuleDeclarations { 361 /// Get the module identifier for a given name, if that name 362 /// has been declared. 363 pub fn get_name(&self, name: &str) -> Option<FuncOrDataId> { 364 self.names.get(name).copied() 365 } 366 367 /// Get an iterator of all function declarations 368 pub fn get_functions(&self) -> impl Iterator<Item = (FuncId, &FunctionDeclaration)> { 369 self.functions.iter() 370 } 371 372 /// Return whether `name` names a function, rather than a data object. 373 pub fn is_function(name: &ModuleExtName) -> bool { 374 match name { 375 ModuleExtName::User { namespace, .. } => *namespace == 0, 376 ModuleExtName::LibCall(_) | ModuleExtName::KnownSymbol(_) => { 377 panic!("unexpected module ext name") 378 } 379 } 380 } 381 382 /// Get the `FunctionDeclaration` for the function named by `name`. 383 pub fn get_function_decl(&self, func_id: FuncId) -> &FunctionDeclaration { 384 &self.functions[func_id] 385 } 386 387 /// Get an iterator of all data declarations 388 pub fn get_data_objects(&self) -> impl Iterator<Item = (DataId, &DataDeclaration)> { 389 self.data_objects.iter() 390 } 391 392 /// Get the `DataDeclaration` for the data object named by `name`. 393 pub fn get_data_decl(&self, data_id: DataId) -> &DataDeclaration { 394 &self.data_objects[data_id] 395 } 396 397 /// Declare a function in this module. 398 pub fn declare_function( 399 &mut self, 400 name: &str, 401 linkage: Linkage, 402 signature: &ir::Signature, 403 ) -> ModuleResult<(FuncId, Linkage)> { 404 // TODO: Can we avoid allocating names so often? 405 use super::hash_map::Entry::*; 406 match self.names.entry(name.to_owned()) { 407 Occupied(entry) => match *entry.get() { 408 FuncOrDataId::Func(id) => { 409 let existing = &mut self.functions[id]; 410 existing.merge(linkage, signature)?; 411 Ok((id, existing.linkage)) 412 } 413 FuncOrDataId::Data(..) => { 414 Err(ModuleError::IncompatibleDeclaration(name.to_owned())) 415 } 416 }, 417 Vacant(entry) => { 418 let id = self.functions.push(FunctionDeclaration { 419 name: name.to_owned(), 420 linkage, 421 signature: signature.clone(), 422 }); 423 entry.insert(FuncOrDataId::Func(id)); 424 Ok((id, self.functions[id].linkage)) 425 } 426 } 427 } 428 429 /// Declare an anonymous function in this module. 430 pub fn declare_anonymous_function( 431 &mut self, 432 signature: &ir::Signature, 433 ) -> ModuleResult<FuncId> { 434 let id = self.functions.push(FunctionDeclaration { 435 name: String::new(), 436 linkage: Linkage::Local, 437 signature: signature.clone(), 438 }); 439 self.functions[id].name = format!(".L{:?}", id); 440 Ok(id) 441 } 442 443 /// Declare a data object in this module. 444 pub fn declare_data( 445 &mut self, 446 name: &str, 447 linkage: Linkage, 448 writable: bool, 449 tls: bool, 450 ) -> ModuleResult<(DataId, Linkage)> { 451 // TODO: Can we avoid allocating names so often? 452 use super::hash_map::Entry::*; 453 match self.names.entry(name.to_owned()) { 454 Occupied(entry) => match *entry.get() { 455 FuncOrDataId::Data(id) => { 456 let existing = &mut self.data_objects[id]; 457 existing.merge(linkage, writable, tls); 458 Ok((id, existing.linkage)) 459 } 460 461 FuncOrDataId::Func(..) => { 462 Err(ModuleError::IncompatibleDeclaration(name.to_owned())) 463 } 464 }, 465 Vacant(entry) => { 466 let id = self.data_objects.push(DataDeclaration { 467 name: name.to_owned(), 468 linkage, 469 writable, 470 tls, 471 }); 472 entry.insert(FuncOrDataId::Data(id)); 473 Ok((id, self.data_objects[id].linkage)) 474 } 475 } 476 } 477 478 /// Declare an anonymous data object in this module. 479 pub fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId> { 480 let id = self.data_objects.push(DataDeclaration { 481 name: String::new(), 482 linkage: Linkage::Local, 483 writable, 484 tls, 485 }); 486 self.data_objects[id].name = format!(".L{:?}", id); 487 Ok(id) 488 } 489 } 490 491 /// Information about the compiled function. 492 pub struct ModuleCompiledFunction { 493 /// The size of the compiled function. 494 pub size: binemit::CodeOffset, 495 } 496 497 /// A `Module` is a utility for collecting functions and data objects, and linking them together. 498 pub trait Module { 499 /// Return the `TargetIsa` to compile for. 500 fn isa(&self) -> &dyn isa::TargetIsa; 501 502 /// Get all declarations in this module. 503 fn declarations(&self) -> &ModuleDeclarations; 504 505 /// Get the module identifier for a given name, if that name 506 /// has been declared. 507 fn get_name(&self, name: &str) -> Option<FuncOrDataId> { 508 self.declarations().get_name(name) 509 } 510 511 /// Return the target information needed by frontends to produce Cranelift IR 512 /// for the current target. 513 fn target_config(&self) -> isa::TargetFrontendConfig { 514 self.isa().frontend_config() 515 } 516 517 /// Create a new `Context` initialized for use with this `Module`. 518 /// 519 /// This ensures that the `Context` is initialized with the default calling 520 /// convention for the `TargetIsa`. 521 fn make_context(&self) -> Context { 522 let mut ctx = Context::new(); 523 ctx.func.signature.call_conv = self.isa().default_call_conv(); 524 ctx 525 } 526 527 /// Clear the given `Context` and reset it for use with a new function. 528 /// 529 /// This ensures that the `Context` is initialized with the default calling 530 /// convention for the `TargetIsa`. 531 fn clear_context(&self, ctx: &mut Context) { 532 ctx.clear(); 533 ctx.func.signature.call_conv = self.isa().default_call_conv(); 534 } 535 536 /// Create a new empty `Signature` with the default calling convention for 537 /// the `TargetIsa`, to which parameter and return types can be added for 538 /// declaring a function to be called by this `Module`. 539 fn make_signature(&self) -> ir::Signature { 540 ir::Signature::new(self.isa().default_call_conv()) 541 } 542 543 /// Clear the given `Signature` and reset for use with a new function. 544 /// 545 /// This ensures that the `Signature` is initialized with the default 546 /// calling convention for the `TargetIsa`. 547 fn clear_signature(&self, sig: &mut ir::Signature) { 548 sig.clear(self.isa().default_call_conv()); 549 } 550 551 /// Declare a function in this module. 552 fn declare_function( 553 &mut self, 554 name: &str, 555 linkage: Linkage, 556 signature: &ir::Signature, 557 ) -> ModuleResult<FuncId>; 558 559 /// Declare an anonymous function in this module. 560 fn declare_anonymous_function(&mut self, signature: &ir::Signature) -> ModuleResult<FuncId>; 561 562 /// Declare a data object in this module. 563 fn declare_data( 564 &mut self, 565 name: &str, 566 linkage: Linkage, 567 writable: bool, 568 tls: bool, 569 ) -> ModuleResult<DataId>; 570 571 /// Declare an anonymous data object in this module. 572 fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId>; 573 574 /// Use this when you're building the IR of a function to reference a function. 575 /// 576 /// TODO: Coalesce redundant decls and signatures. 577 /// TODO: Look into ways to reduce the risk of using a FuncRef in the wrong function. 578 fn declare_func_in_func(&mut self, func_id: FuncId, func: &mut ir::Function) -> ir::FuncRef { 579 let decl = &self.declarations().functions[func_id]; 580 let signature = func.import_signature(decl.signature.clone()); 581 let user_name_ref = func.declare_imported_user_function(ir::UserExternalName { 582 namespace: 0, 583 index: func_id.as_u32(), 584 }); 585 let colocated = decl.linkage.is_final(); 586 func.import_function(ir::ExtFuncData { 587 name: ir::ExternalName::user(user_name_ref), 588 signature, 589 colocated, 590 }) 591 } 592 593 /// Use this when you're building the IR of a function to reference a data object. 594 /// 595 /// TODO: Same as above. 596 fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue { 597 let decl = &self.declarations().data_objects[data]; 598 let colocated = decl.linkage.is_final(); 599 let user_name_ref = func.declare_imported_user_function(ir::UserExternalName { 600 namespace: 1, 601 index: data.as_u32(), 602 }); 603 func.create_global_value(ir::GlobalValueData::Symbol { 604 name: ir::ExternalName::user(user_name_ref), 605 offset: ir::immediates::Imm64::new(0), 606 colocated, 607 tls: decl.tls, 608 }) 609 } 610 611 /// TODO: Same as above. 612 fn declare_func_in_data(&self, func: FuncId, ctx: &mut DataContext) -> ir::FuncRef { 613 ctx.import_function(ModuleExtName::user(0, func.as_u32())) 614 } 615 616 /// TODO: Same as above. 617 fn declare_data_in_data(&self, data: DataId, ctx: &mut DataContext) -> ir::GlobalValue { 618 ctx.import_global_value(ModuleExtName::user(1, data.as_u32())) 619 } 620 621 /// Define a function, producing the function body from the given `Context`. 622 /// 623 /// Returns the size of the function's code and constant data. 624 /// 625 /// Note: After calling this function the given `Context` will contain the compiled function. 626 fn define_function( 627 &mut self, 628 func: FuncId, 629 ctx: &mut Context, 630 ) -> ModuleResult<ModuleCompiledFunction>; 631 632 /// Define a function, taking the function body from the given `bytes`. 633 /// 634 /// This function is generally only useful if you need to precisely specify 635 /// the emitted instructions for some reason; otherwise, you should use 636 /// `define_function`. 637 /// 638 /// Returns the size of the function's code. 639 fn define_function_bytes( 640 &mut self, 641 func_id: FuncId, 642 func: &ir::Function, 643 bytes: &[u8], 644 relocs: &[MachReloc], 645 ) -> ModuleResult<ModuleCompiledFunction>; 646 647 /// Define a data object, producing the data contents from the given `DataContext`. 648 fn define_data(&mut self, data: DataId, data_ctx: &DataContext) -> ModuleResult<()>; 649 } 650 651 impl<M: Module> Module for &mut M { 652 fn isa(&self) -> &dyn isa::TargetIsa { 653 (**self).isa() 654 } 655 656 fn declarations(&self) -> &ModuleDeclarations { 657 (**self).declarations() 658 } 659 660 fn get_name(&self, name: &str) -> Option<FuncOrDataId> { 661 (**self).get_name(name) 662 } 663 664 fn target_config(&self) -> isa::TargetFrontendConfig { 665 (**self).target_config() 666 } 667 668 fn make_context(&self) -> Context { 669 (**self).make_context() 670 } 671 672 fn clear_context(&self, ctx: &mut Context) { 673 (**self).clear_context(ctx) 674 } 675 676 fn make_signature(&self) -> ir::Signature { 677 (**self).make_signature() 678 } 679 680 fn clear_signature(&self, sig: &mut ir::Signature) { 681 (**self).clear_signature(sig) 682 } 683 684 fn declare_function( 685 &mut self, 686 name: &str, 687 linkage: Linkage, 688 signature: &ir::Signature, 689 ) -> ModuleResult<FuncId> { 690 (**self).declare_function(name, linkage, signature) 691 } 692 693 fn declare_anonymous_function(&mut self, signature: &ir::Signature) -> ModuleResult<FuncId> { 694 (**self).declare_anonymous_function(signature) 695 } 696 697 fn declare_data( 698 &mut self, 699 name: &str, 700 linkage: Linkage, 701 writable: bool, 702 tls: bool, 703 ) -> ModuleResult<DataId> { 704 (**self).declare_data(name, linkage, writable, tls) 705 } 706 707 fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId> { 708 (**self).declare_anonymous_data(writable, tls) 709 } 710 711 fn declare_func_in_func(&mut self, func: FuncId, in_func: &mut ir::Function) -> ir::FuncRef { 712 (**self).declare_func_in_func(func, in_func) 713 } 714 715 fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue { 716 (**self).declare_data_in_func(data, func) 717 } 718 719 fn declare_func_in_data(&self, func: FuncId, ctx: &mut DataContext) -> ir::FuncRef { 720 (**self).declare_func_in_data(func, ctx) 721 } 722 723 fn declare_data_in_data(&self, data: DataId, ctx: &mut DataContext) -> ir::GlobalValue { 724 (**self).declare_data_in_data(data, ctx) 725 } 726 727 fn define_function( 728 &mut self, 729 func: FuncId, 730 ctx: &mut Context, 731 ) -> ModuleResult<ModuleCompiledFunction> { 732 (**self).define_function(func, ctx) 733 } 734 735 fn define_function_bytes( 736 &mut self, 737 func_id: FuncId, 738 func: &ir::Function, 739 bytes: &[u8], 740 relocs: &[MachReloc], 741 ) -> ModuleResult<ModuleCompiledFunction> { 742 (**self).define_function_bytes(func_id, func, bytes, relocs) 743 } 744 745 fn define_data(&mut self, data: DataId, data_ctx: &DataContext) -> ModuleResult<()> { 746 (**self).define_data(data, data_ctx) 747 } 748 } 749