Write assembler to backing memory.
(&mut self)
| 296 | |
| 297 | /// Write assembler to backing memory. |
| 298 | pub fn commit(&mut self) -> Result<(), &str> { |
| 299 | if self.cursor() > self.len { |
| 300 | return Err("Assembled code doesn't fit into backing allocation"); |
| 301 | } |
| 302 | if let Err(e) = self.encode_relocs() { |
| 303 | println!("{:?}", e); |
| 304 | return Err("Failed to encode relocations"); |
| 305 | } |
| 306 | |
| 307 | // Number of bytes in the buffer |
| 308 | let num_bytes = self.ops.len(); |
| 309 | |
| 310 | let src = self.ops.as_ptr(); |
| 311 | let dst = self.ptr as *mut u8; |
| 312 | |
| 313 | // NOTE: Some memcpy implementations *really dislike* when we decide |
| 314 | // to use the null pointer as virtual address 0. |
| 315 | unsafe { |
| 316 | // Zero out the whole allocation |
| 317 | //dst.write_bytes(0, self.len); |
| 318 | |
| 319 | if dst == std::ptr::null_mut() |
| 320 | { |
| 321 | for i in 0..num_bytes { |
| 322 | let b = src.offset(i as _).read(); |
| 323 | dst.offset(i as _).write_volatile(b); |
| 324 | } |
| 325 | } else { |
| 326 | dst.write_bytes(0, self.len); |
| 327 | std::ptr::copy_nonoverlapping(src, dst, num_bytes); |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | self.committed = true; |
| 332 | Ok(()) |
| 333 | } |
| 334 | |
| 335 | /// Clear all bytes in the backing allocation and reset the state |
| 336 | /// of this assembler. |
no test coverage detected