Optimized v table and vptr

This commit is contained in:
2026-06-12 17:04:24 +02:00
parent d3ff834111
commit fab7326357
+67 -81
View File
@@ -112,10 +112,10 @@ impl ClassProcessedData {
cg.add_indented("pub _super: "); cg.add_indented("pub _super: ");
cg.add(&get_type_from_path(inherits).get_rust()); cg.add(&get_type_from_path(inherits).get_rust());
cg.addln(","); cg.addln(",");
} else {
cg.add_indentedln("pub _vptr: &'static [*const std::ffi::c_void],");
} }
cg.add_indentedln("pub _vptr: &'static [*const std::ffi::c_void],");
for field in &self.fields { for field in &self.fields {
cg.add_indentedln(&field.get_comment()); cg.add_indentedln(&field.get_comment());
cg.add_indentedln(&field.item.decl.get_rust()); cg.add_indentedln(&field.item.decl.get_rust());
@@ -133,9 +133,7 @@ impl ClassProcessedData {
)); ));
cg.indent += 1; cg.indent += 1;
self.emit_v_table(cg); self.emit_unified_vtable(cg);
self.emit_super_v_table(cg);
self.emit_super_v_tests(cg); self.emit_super_v_tests(cg);
self.emit_constructor(ctx, cg); self.emit_constructor(ctx, cg);
@@ -145,81 +143,92 @@ impl ClassProcessedData {
cg.addln("}\n"); cg.addln("}\n");
} }
fn emit_v_table(&self, cg: &mut RustCodegen) { fn emit_unified_vtable(&self, cg: &mut RustCodegen) {
let has_parent = self.inherits.is_some();
let parent_path = self
.inherits
.as_ref()
.map(|p| p.get_rust())
.unwrap_or_default();
if has_parent {
cg.add_indentedln(&format!(
"pub const __PARENT_V_COUNT: usize = {}::__V_COUNT;",
parent_path
));
} else {
cg.add_indentedln("pub const __PARENT_V_COUNT: usize = 0;");
}
for (i, method_name) in self.v_table.iter().enumerate() { for (i, method_name) in self.v_table.iter().enumerate() {
cg.add_indentedln(&format!( cg.add_indentedln(&format!(
"pub const __FN_{}: usize = {i};", "pub const __FN_{}: usize = Self::__PARENT_V_COUNT + {i};",
method_name.0.to_uppercase() method_name.0.to_uppercase()
)); ));
} }
cg.add_indentedln(&format!( cg.add_indentedln(&format!(
"pub const __V_TABLE: [*const std::ffi::c_void; {}] = [", "pub const __V_COUNT: usize = Self::__PARENT_V_COUNT + {};",
self.v_table.len() self.v_table.len()
)); ));
cg.add_indentedln("pub const __V_TABLE: &'static [*const std::ffi::c_void] = &{");
cg.indent += 1; cg.indent += 1;
for method_name in &self.v_table { if has_parent {
cg.add_indented("Self::__m_"); cg.add_indentedln(&format!(
cg.add(&method_name.get_rust()); "let mut table = [std::ptr::null(); {}::__V_COUNT + {}];",
cg.add(" as *const std::ffi::c_void"); parent_path,
cg.addln(","); self.v_table.len()
} ));
cg.indent -= 1; cg.add_indentedln(&format!("let parent_table = {}::__V_TABLE;", parent_path));
cg.add_indentedln("];"); cg.add_indentedln(&format!(
} "let mut i = 0; while i < {}::__V_COUNT {{ table[i] = parent_table[i]; i += 1; }}",
parent_path
));
fn emit_super_v_table(&self, cg: &mut RustCodegen) { for (override_tier, overriden_method_idents) in &self.override_v_table {
if self.override_v_table.is_empty() { let base_class_path = override_tier
return; .0
} .as_ref()
.unwrap_or(self.inherits.as_ref().unwrap())
cg.add_indentedln(&format!( .get_rust();
"pub const __SUPER_V_TABLES: [&'static [*const std::ffi::c_void]; {}] = [", for method_ident in &overriden_method_idents.item {
self.override_v_table.len() cg.add_indentedln(&format!(
)); "table[{}::__FN_{}] = {}::__m_{} as *const std::ffi::c_void;",
cg.indent += 1; base_class_path,
method_ident.0.to_uppercase(),
for (override_tier, overriden_method_idents) in &self.override_v_table { self.self_path.get_rust(),
let target_path = match &override_tier.0 { method_ident.get_rust()
Some(path) => path.clone(), ));
None => {
if let Some(parent_path) = &self.inherits {
parent_path.clone()
} else {
continue; // Safeguard if AST has a dangling override without inheritance
}
} }
}; }
let target_rust_path = target_path.get_rust(); for method_name in &self.v_table {
// 2. Emit the block for this specific index table
cg.add_indentedln("&{");
cg.indent += 1;
// Initialize this sub-table with the target parent class's base vtable
cg.add_indentedln(&format!("let mut table = {}::__V_TABLE;", target_rust_path));
// Patch the slots for every method registered under this specific override tier
for method_ident in &overriden_method_idents.item {
cg.add_indentedln(&format!( cg.add_indentedln(&format!(
"table[{}::__FN_{}] = {}::__m_{} as *const std::ffi::c_void;", "table[Self::__FN_{}] = Self::__m_{} as *const std::ffi::c_void;",
target_rust_path, method_name.0.to_uppercase(),
method_ident.0.to_uppercase(), method_name.get_rust()
self.self_path.get_rust(),
method_ident.get_rust()
)); ));
} }
cg.add_indentedln("table"); cg.add_indentedln("table");
} else {
cg.add_indentedln("[");
cg.indent += 1;
for method_name in &self.v_table {
cg.add_indentedln(&format!(
"Self::__m_{} as *const std::ffi::c_void,",
method_name.get_rust()
));
}
cg.indent -= 1; cg.indent -= 1;
cg.add_indentedln("},"); cg.add_indentedln("]");
} }
cg.indent -= 1; cg.indent -= 1;
cg.add_indentedln("];"); cg.add_indentedln("};");
} }
fn emit_super_v_tests(&self, cg: &mut RustCodegen) { fn emit_super_v_tests(&self, cg: &mut RustCodegen) {
@@ -234,7 +243,7 @@ impl ClassProcessedData {
if let Some(parent_path) = &self.inherits { if let Some(parent_path) = &self.inherits {
parent_path.clone() parent_path.clone()
} else { } else {
continue; // Safeguard if AST has a dangling override without inheritance continue;
} }
} }
}; };
@@ -327,7 +336,6 @@ impl ClassProcessedData {
cg.add_indentedln("let mut this: Self = unsafe { std::mem::MaybeUninit::<Self>::zeroed().assume_init() };"); cg.add_indentedln("let mut this: Self = unsafe { std::mem::MaybeUninit::<Self>::zeroed().assume_init() };");
cg.add_indentedln("this._vptr = &Self::__V_TABLE;"); cg.add_indentedln("this._vptr = &Self::__V_TABLE;");
// Inline field declarations and initializers
for field in &self.fields { for field in &self.fields {
let comment = field.get_comment(); let comment = field.get_comment();
@@ -348,28 +356,7 @@ impl ClassProcessedData {
} }
cg.addln(");"); cg.addln(");");
if self.inherits.is_some() && !self.override_v_table.is_empty() { cg.add_indentedln("this._vptr = &Self::__V_TABLE;");
for (idx, (override_tier, v)) in self.override_v_table.iter().enumerate() {
match &override_tier.0 {
// Direct base class layout updates
None => {
cg.add_indentedln(&format!(
"this._super._vptr = Self::__SUPER_V_TABLES[{}];",
idx
));
}
// Deep ancestor trait table updates
Some(path) => {
cg.add_indentedln(&v.get_comment());
cg.add_indentedln(&format!(
"(|v: &mut {}| {{v._vptr = Self::__SUPER_V_TABLES[{}];}})(&mut this);",
path.get_rust(),
idx
));
}
}
}
}
cg.add_indentedln(&constructor_comment); cg.add_indentedln(&constructor_comment);
@@ -377,7 +364,6 @@ impl ClassProcessedData {
cg.indent -= 1; cg.indent -= 1;
cg.add_indentedln("}\n"); cg.add_indentedln("}\n");
// Generate matching inner initialization body block
let mut constructor_params = vec![VarDecl { let mut constructor_params = vec![VarDecl {
name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])), name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])),
type_: Some(TypeExpr::Ref { type_: Some(TypeExpr::Ref {