Optimized vt tests
This commit is contained in:
@@ -4,8 +4,6 @@ use mist_parser::ast::*;
|
|||||||
|
|
||||||
use crate::{Context, GenRust, GetRust, RustCodegen};
|
use crate::{Context, GenRust, GetRust, RustCodegen};
|
||||||
|
|
||||||
// ── Stage 1: Data Collection & Metadata Analysis ──────────────────────
|
|
||||||
|
|
||||||
pub struct ClassProcessedData {
|
pub struct ClassProcessedData {
|
||||||
visibility: Visibility,
|
visibility: Visibility,
|
||||||
name: Identifier,
|
name: Identifier,
|
||||||
@@ -38,9 +36,8 @@ impl ClassProcessedData {
|
|||||||
|
|
||||||
let self_ty = get_type_from_path(&self_path);
|
let self_ty = get_type_from_path(&self_path);
|
||||||
|
|
||||||
// 1. Gather all raw methods from the class items
|
|
||||||
let methods = items
|
let methods = items
|
||||||
.iter() // Switched to reference iteration to prevent unnecessary cloning
|
.iter()
|
||||||
.filter_map(|item| match item {
|
.filter_map(|item| match item {
|
||||||
ClassItem::ImplDecl(_) => None,
|
ClassItem::ImplDecl(_) => None,
|
||||||
ClassItem::Method(method) => Some(method.clone()),
|
ClassItem::Method(method) => Some(method.clone()),
|
||||||
@@ -50,15 +47,12 @@ impl ClassProcessedData {
|
|||||||
let mut v_table = Vec::new();
|
let mut v_table = Vec::new();
|
||||||
let mut override_v_table = std::collections::HashMap::new();
|
let mut override_v_table = std::collections::HashMap::new();
|
||||||
|
|
||||||
// 2. Distribute public methods between base table slots and inheritance overrides
|
|
||||||
for method in &methods {
|
for method in &methods {
|
||||||
if matches!(method.item.visibility, Visibility::Public) {
|
if matches!(method.item.visibility, Visibility::Public) {
|
||||||
match &method.item.is_override {
|
match &method.item.is_override {
|
||||||
// It's a brand new virtual method introduced by this class!
|
|
||||||
None => {
|
None => {
|
||||||
v_table.push(method.item.name.clone());
|
v_table.push(method.item.name.clone());
|
||||||
}
|
}
|
||||||
// It's an override targeting either the immediate super or a deep ancestor
|
|
||||||
Some(override_spec) => {
|
Some(override_spec) => {
|
||||||
override_v_table
|
override_v_table
|
||||||
.entry(override_spec.clone())
|
.entry(override_spec.clone())
|
||||||
@@ -172,26 +166,19 @@ impl ClassProcessedData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn emit_super_v_table(&self, cg: &mut RustCodegen) {
|
fn emit_super_v_table(&self, cg: &mut RustCodegen) {
|
||||||
// If we aren't overriding anything across the tree, we don't need the table array
|
|
||||||
if self.override_v_table.is_empty() {
|
if self.override_v_table.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Emit the outer 2D array declaration
|
|
||||||
cg.add_indentedln(&format!(
|
cg.add_indentedln(&format!(
|
||||||
"pub const __SUPER_V_TABLES: [&'static [*const std::ffi::c_void]; {}] = [",
|
"pub const __SUPER_V_TABLES: [&'static [*const std::ffi::c_void]; {}] = [",
|
||||||
self.override_v_table.len()
|
self.override_v_table.len()
|
||||||
));
|
));
|
||||||
cg.indent += 1;
|
cg.indent += 1;
|
||||||
|
|
||||||
// We enumerate over the map so each target class gets a stable outer index
|
|
||||||
for (override_tier, overriden_method_idents) in &self.override_v_table {
|
for (override_tier, overriden_method_idents) in &self.override_v_table {
|
||||||
// Resolve the target path for this specific sub-table
|
|
||||||
let target_path = match &override_tier.0 {
|
let target_path = match &override_tier.0 {
|
||||||
// Override(Some(path)) / Override::Path(path) -> Targets deep ancestor
|
|
||||||
Some(path) => path.clone(),
|
Some(path) => path.clone(),
|
||||||
|
|
||||||
// Override(None) / Override::Default -> Targets our immediate parent
|
|
||||||
None => {
|
None => {
|
||||||
if let Some(parent_path) = &self.inherits {
|
if let Some(parent_path) = &self.inherits {
|
||||||
parent_path.clone()
|
parent_path.clone()
|
||||||
@@ -231,13 +218,13 @@ impl ClassProcessedData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn emit_super_v_tests(&self, cg: &mut RustCodegen) {
|
fn emit_super_v_tests(&self, cg: &mut RustCodegen) {
|
||||||
for (idx, (override_tier, _)) in self.override_v_table.iter().enumerate() {
|
cg.add_indentedln(&format!("const fn __test_vt() {{"));
|
||||||
// Resolve the target path for this specific sub-table
|
cg.indent += 1;
|
||||||
|
|
||||||
|
for (override_tier, _) in self.override_v_table.iter() {
|
||||||
let target_path = match &override_tier.0 {
|
let target_path = match &override_tier.0 {
|
||||||
// Override(Some(path)) / Override::Path(path) -> Targets deep ancestor
|
|
||||||
Some(path) => path.clone(),
|
Some(path) => path.clone(),
|
||||||
|
|
||||||
// Override(None) / Override::Default -> Targets our immediate parent
|
|
||||||
None => {
|
None => {
|
||||||
if let Some(parent_path) = &self.inherits {
|
if let Some(parent_path) = &self.inherits {
|
||||||
parent_path.clone()
|
parent_path.clone()
|
||||||
@@ -249,12 +236,7 @@ impl ClassProcessedData {
|
|||||||
|
|
||||||
let target_rust_path = target_path.get_rust();
|
let target_rust_path = target_path.get_rust();
|
||||||
|
|
||||||
// 3. Emit the compile-time signature layout validation test for this specific index
|
|
||||||
cg.add_indentedln(&format!("const fn __test_vt_{}() {{", idx));
|
|
||||||
cg.indent += 1;
|
|
||||||
|
|
||||||
for method in &self.methods {
|
for method in &self.methods {
|
||||||
// Only validate the methods that actually belong to the current target slice tier
|
|
||||||
if method.item.is_override.as_ref() == Some(override_tier) {
|
if method.item.is_override.as_ref() == Some(override_tier) {
|
||||||
let mut params = method
|
let mut params = method
|
||||||
.item
|
.item
|
||||||
@@ -294,11 +276,11 @@ impl ClassProcessedData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cg.indent -= 1;
|
cg.indent -= 1;
|
||||||
cg.add_indentedln("}");
|
cg.add_indentedln("}");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn emit_constructor(&self, ctx: &mut Context, cg: &mut RustCodegen) {
|
fn emit_constructor(&self, ctx: &mut Context, cg: &mut RustCodegen) {
|
||||||
let constructor_comment = self.constructor.get_comment();
|
let constructor_comment = self.constructor.get_comment();
|
||||||
@@ -312,7 +294,6 @@ impl ClassProcessedData {
|
|||||||
self.constructor.item.generics.get_rust()
|
self.constructor.item.generics.get_rust()
|
||||||
));
|
));
|
||||||
|
|
||||||
// Enumerate and build constructor call parameters
|
|
||||||
let params = self
|
let params = self
|
||||||
.constructor
|
.constructor
|
||||||
.item
|
.item
|
||||||
@@ -337,7 +318,6 @@ impl ClassProcessedData {
|
|||||||
cg.addln(") -> Box<Self> {");
|
cg.addln(") -> Box<Self> {");
|
||||||
cg.indent += 1;
|
cg.indent += 1;
|
||||||
|
|
||||||
// Allocate and zero-initialize state pointer
|
|
||||||
cg.add_indentedln("let mut this = Box::new(unsafe { std::mem::MaybeUninit::<Self>::zeroed().assume_init() });");
|
cg.add_indentedln("let mut this = Box::new(unsafe { std::mem::MaybeUninit::<Self>::zeroed().assume_init() });");
|
||||||
cg.add_indentedln("let this_ptr = &mut *this as *mut Self as *mut std::ffi::c_void;");
|
cg.add_indentedln("let this_ptr = &mut *this as *mut Self as *mut std::ffi::c_void;");
|
||||||
cg.add_indentedln("this._m_oop = (&Self::__V_TABLE, this_ptr);");
|
cg.add_indentedln("this._m_oop = (&Self::__V_TABLE, this_ptr);");
|
||||||
@@ -353,7 +333,6 @@ impl ClassProcessedData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call Mist internal execution hook
|
|
||||||
cg.add_indented("this.constructor(");
|
cg.add_indented("this.constructor(");
|
||||||
for (i, param) in ¶ms {
|
for (i, param) in ¶ms {
|
||||||
if *i > 0 {
|
if *i > 0 {
|
||||||
@@ -364,7 +343,6 @@ impl ClassProcessedData {
|
|||||||
}
|
}
|
||||||
cg.addln(");");
|
cg.addln(");");
|
||||||
|
|
||||||
// --- MULTI-INHERITANCE 2D VTABLE ASSIGNMENTS ---
|
|
||||||
if self.inherits.is_some() && !self.override_v_table.is_empty() {
|
if self.inherits.is_some() && !self.override_v_table.is_empty() {
|
||||||
for (idx, (override_tier, _)) in self.override_v_table.iter().enumerate() {
|
for (idx, (override_tier, _)) in self.override_v_table.iter().enumerate() {
|
||||||
match &override_tier.0 {
|
match &override_tier.0 {
|
||||||
@@ -494,8 +472,6 @@ impl ClassProcessedData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Public entry point (delegates to the two-stage pipeline) ──────────
|
|
||||||
|
|
||||||
pub fn class_decl(
|
pub fn class_decl(
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
cg: &mut RustCodegen,
|
cg: &mut RustCodegen,
|
||||||
|
|||||||
Reference in New Issue
Block a user