Lines
100 %
Functions
20 %
Branches
//! `Operation::Delete` entity record. No data payload — just an
//! entity header carrying the id of the row to remove. Runs after
//! a CRUD list is iterated, so the `entity_type` rides a wasm local
//! rather than being known at compile time.
use std::mem::offset_of;
use scripting_format::{ENTITY_HEADER_SIZE, EntityHeader, Operation};
use crate::compiler::emit::FunctionEmitter;
use crate::compiler::expr::LOCAL_ENTITY_BASE;
use super::headers::OutputSerializer;
impl OutputSerializer {
pub fn write_delete_entity(
&mut self,
emit: &mut FunctionEmitter,
entity_type_local: u32,
input_header_local: u32,
) {
self.load_entity_base(emit);
let ent = LOCAL_ENTITY_BASE;
// entity_type from a runtime local.
emit.local_get(ent);
emit.i32_const(offset_of!(EntityHeader, entity_type) as i32);
emit.i32_add();
emit.local_get(entity_type_local);
emit.i32_store8_raw();
emit.store_u8_dynamic(
ent,
offset_of!(EntityHeader, operation) as u32,
Operation::Delete as u8,
);
emit.store_u8_dynamic(ent, offset_of!(EntityHeader, flags) as u32, 0);
// Copy the 16-byte id from the input entity header.
for i in 0..4u32 {
emit.i32_const((offset_of!(EntityHeader, id) as u32 + i * 4) as i32);
emit.local_get(input_header_local);
emit.i32_load((offset_of!(EntityHeader, id) + (i as usize) * 4) as u64);
emit.i32_store_raw();
}
emit.store_i32_dynamic(ent, offset_of!(EntityHeader, parent_idx) as u32, -1);
// data_offset = (entity_base - output_base) + ENTITY_HEADER_SIZE.
emit.i32_const(offset_of!(EntityHeader, data_offset) as i32);
emit.local_get(self.output_base_local);
emit.i32_sub();
emit.i32_const(ENTITY_HEADER_SIZE as i32);
emit.store_i32_dynamic(ent, offset_of!(EntityHeader, data_size) as u32, 0);
self.bump_entity_count(emit);
self.advance_past(emit, ENTITY_HEADER_SIZE as u32);