From 5a1285a2a89350c9e30e9a17275467b8c6ed08f3 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Fri, 12 Jun 2026 15:53:51 +0200 Subject: [PATCH 1/7] Removed allocation in favor of stack --- crates/codegen/src/class_decl.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 6524ded..fcaaf76 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -107,13 +107,15 @@ impl ClassProcessedData { cg.indent += 1; cg.add_indentedln( - "pub _m_oop: (&'static [*const std::ffi::c_void], *mut std::ffi::c_void),", + "pub _vptr: (&'static [*const std::ffi::c_void], *mut std::ffi::c_void),", ); + cg.add_indentedln("_pin: std::marker::PhantomPinned,"); + if let Some(ref inherits) = self.inherits { - cg.add_indented("pub _super: Box<"); + cg.add_indented("pub _super: "); cg.add(&get_type_from_path(inherits).get_rust()); - cg.addln(">,"); + cg.addln(","); } for field in &self.fields { @@ -321,12 +323,12 @@ impl ClassProcessedData { param.gen_rust(ctx, cg); } - cg.addln(") -> Box {"); + cg.addln(") -> Self {"); cg.indent += 1; - cg.add_indentedln("let mut this = Box::new(unsafe { std::mem::MaybeUninit::::zeroed().assume_init() });"); - 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("let mut this: Self = unsafe { std::mem::MaybeUninit::::zeroed().assume_init() };"); + cg.add_indentedln("let this_ptr = &mut this as *mut Self as *mut std::ffi::c_void;"); + cg.add_indentedln("this._vptr = (&Self::__V_TABLE, this_ptr);"); // Inline field declarations and initializers for field in &self.fields { @@ -355,7 +357,7 @@ impl ClassProcessedData { // Direct base class layout updates None => { cg.add_indentedln(&format!( - "this._super._m_oop.0 = Self::__SUPER_V_TABLES[{}];", + "this._super._vptr.0 = Self::__SUPER_V_TABLES[{}];", idx )); } @@ -363,7 +365,7 @@ impl ClassProcessedData { Some(path) => { cg.add_indentedln(&v.get_comment()); cg.add_indentedln(&format!( - "(|v: &mut {}| {{v._m_oop.0 = Self::__SUPER_V_TABLES[{}];}})(&mut this);", + "(|v: &mut {}| {{v._vptr = (Self::__SUPER_V_TABLES[{}], this_ptr);}})(&mut this);", path.get_rust(), idx )); @@ -552,7 +554,7 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC cg.indent += 1; cg.add_indentedln(&format!( - "let func_ptr = self._m_oop.0[Self::__FN_{}];", + "let func_ptr = self._vptr.0[Self::__FN_{}];", method.name.0.to_uppercase() )); @@ -588,11 +590,11 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC cg.add(&TypeExpr::StaticFn(param_types, method.return_type.clone().map(Box::new)).get_rust()); cg.addln(" = std::mem::transmute(func_ptr);"); - cg.add_indented("func(self._m_oop.1"); + cg.add_indented("func(self._vptr.1"); for (i, param) in ¶ms { if *i == 0 { - continue; // self._m_oop.1 already fulfills it + continue; // self._vptr.1 already fulfills it } cg.add(", "); ctx.expr_ensure_semicolon = false; From 37e3da5d6782dd7317716ea4bb478dc65d80764b Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Fri, 12 Jun 2026 16:04:33 +0200 Subject: [PATCH 2/7] Simplified vptr --- crates/codegen/src/class_decl.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index fcaaf76..c3bf7d6 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -106,9 +106,7 @@ impl ClassProcessedData { )); cg.indent += 1; - cg.add_indentedln( - "pub _vptr: (&'static [*const std::ffi::c_void], *mut std::ffi::c_void),", - ); + cg.add_indentedln("pub _vptr: &'static [*const std::ffi::c_void],"); cg.add_indentedln("_pin: std::marker::PhantomPinned,"); @@ -327,8 +325,7 @@ impl ClassProcessedData { cg.indent += 1; cg.add_indentedln("let mut this: Self = unsafe { std::mem::MaybeUninit::::zeroed().assume_init() };"); - cg.add_indentedln("let this_ptr = &mut this as *mut Self as *mut std::ffi::c_void;"); - cg.add_indentedln("this._vptr = (&Self::__V_TABLE, this_ptr);"); + cg.add_indentedln("this._vptr = &Self::__V_TABLE;"); // Inline field declarations and initializers for field in &self.fields { @@ -357,7 +354,7 @@ impl ClassProcessedData { // Direct base class layout updates None => { cg.add_indentedln(&format!( - "this._super._vptr.0 = Self::__SUPER_V_TABLES[{}];", + "this._super._vptr = Self::__SUPER_V_TABLES[{}];", idx )); } @@ -365,7 +362,7 @@ impl ClassProcessedData { Some(path) => { cg.add_indentedln(&v.get_comment()); cg.add_indentedln(&format!( - "(|v: &mut {}| {{v._vptr = (Self::__SUPER_V_TABLES[{}], this_ptr);}})(&mut this);", + "(|v: &mut {}| {{v._vptr = Self::__SUPER_V_TABLES[{}];}})(&mut this);", path.get_rust(), idx )); @@ -554,7 +551,7 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC cg.indent += 1; cg.add_indentedln(&format!( - "let func_ptr = self._vptr.0[Self::__FN_{}];", + "let func_ptr = self._vptr[Self::__FN_{}];", method.name.0.to_uppercase() )); @@ -568,14 +565,14 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC .filter_map(|v| v.type_) .collect(); - if !param_types.is_empty() { - param_types.remove(0); - } + let TypeExpr::Ref { mutable, .. } = param_types.remove(0) else { + panic!("") + }; param_types.insert( 0, TypeExpr::UnsafePtr { - mutable: true, + mutable, ty: Box::new(TypeExpr::Path( Path(vec![ Identifier(String::from("std")), @@ -590,11 +587,15 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC cg.add(&TypeExpr::StaticFn(param_types, method.return_type.clone().map(Box::new)).get_rust()); cg.addln(" = std::mem::transmute(func_ptr);"); - cg.add_indented("func(self._vptr.1"); + if mutable { + cg.add_indented("func(self as *mut Self as *const std::ffi::c_void"); + } else { + cg.add_indented("func(self as *const Self as *const std::ffi::c_void"); + } for (i, param) in ¶ms { if *i == 0 { - continue; // self._vptr.1 already fulfills it + continue; // self already fulfills it } cg.add(", "); ctx.expr_ensure_semicolon = false; From 526b479ea4633451c2fe2a73afb24507857a4d68 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Fri, 12 Jun 2026 16:14:32 +0200 Subject: [PATCH 3/7] Added method vptr condition --- crates/codegen/src/class_decl.rs | 27 +++++++++++++++++++++------ mist-test/src/items/class_test.mist | 4 ++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index c3bf7d6..85b8591 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -412,13 +412,28 @@ impl ClassProcessedData { for method in &self.methods { match method.item.visibility { Visibility::Public => { - if method.item.is_override.is_none() { - gen_method_point(&method.item, ctx, cg); - } + let is_using_self = match method.item.params.0.get(0) { + Some(VarDecl { name, .. }) => { + if let Pattern::Path(_, v) = name { + v.0.len() == 1 && v.0[0].0 == "self" + } else { + false + } + } + _ => false, + }; - let mut prefixed = method.clone(); - prefixed.item.name.0.insert_str(0, "__m_"); - prefixed.gen_rust(ctx, cg); + if is_using_self { + if method.item.is_override.is_none() { + gen_method_point(&method.item, ctx, cg); + } + + let mut prefixed = method.clone(); + prefixed.item.name.0.insert_str(0, "__m_"); + prefixed.gen_rust(ctx, cg); + } else { + method.gen_rust(ctx, cg); + } } _ => { method.gen_rust(ctx, cg); diff --git a/mist-test/src/items/class_test.mist b/mist-test/src/items/class_test.mist index d50ff9c..7284982 100644 --- a/mist-test/src/items/class_test.mist +++ b/mist-test/src/items/class_test.mist @@ -19,7 +19,7 @@ pub class Animal { pub class Mammal : Animal { constructor() { - super -> Super::new(); + super = Super::new(); } pub fn args_test(*self, x i32, y *str) {} @@ -31,7 +31,7 @@ pub class Mammal : Animal { pub class Dog : Mammal { constructor() { - super -> Super::new(); + super = Super::new(); } pub override(Animal) fn speak(*self) { From b19b1bb41dd3924f41553dfd098990dd90695584 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Fri, 12 Jun 2026 16:21:46 +0200 Subject: [PATCH 4/7] Fixed vptr condition on static methods --- crates/codegen/src/class_decl.rs | 17 ++++------------- crates/parser/src/ast/top_level.rs | 15 +++++++++++++++ mist-test/src/items/class_test.mist | 2 ++ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 85b8591..9938d0b 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -51,7 +51,9 @@ impl ClassProcessedData { if matches!(method.item.visibility, Visibility::Public) { match &method.item.is_override { None => { - v_table.push(method.item.name.clone()); + if method.item.is_using_self() { + v_table.push(method.item.name.clone()); + } } Some(override_spec) => { override_v_table @@ -412,18 +414,7 @@ impl ClassProcessedData { for method in &self.methods { match method.item.visibility { Visibility::Public => { - let is_using_self = match method.item.params.0.get(0) { - Some(VarDecl { name, .. }) => { - if let Pattern::Path(_, v) = name { - v.0.len() == 1 && v.0[0].0 == "self" - } else { - false - } - } - _ => false, - }; - - if is_using_self { + if method.item.is_using_self() { if method.item.is_override.is_none() { gen_method_point(&method.item, ctx, cg); } diff --git a/crates/parser/src/ast/top_level.rs b/crates/parser/src/ast/top_level.rs index be4a4b3..2899893 100644 --- a/crates/parser/src/ast/top_level.rs +++ b/crates/parser/src/ast/top_level.rs @@ -125,3 +125,18 @@ pub struct FieldDeclStmt { pub decl: FieldDecl, pub init: Option, } + +impl FunctionDecl { + pub fn is_using_self(&self) -> bool { + match self.params.0.get(0) { + Some(VarDecl { name, .. }) => { + if let Pattern::Path(_, v) = name { + v.0.len() == 1 && v.0[0].0 == "self" + } else { + false + } + } + _ => false, + } + } +} diff --git a/mist-test/src/items/class_test.mist b/mist-test/src/items/class_test.mist index 7284982..8c441e4 100644 --- a/mist-test/src/items/class_test.mist +++ b/mist-test/src/items/class_test.mist @@ -15,6 +15,8 @@ pub class Animal { pub fn test_speak(*self) { self.speak(); } + + pub fn static_method() {} } pub class Mammal : Animal { From d3ff83411166f9364cb55389607d9d757f94e75a Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Fri, 12 Jun 2026 16:25:16 +0200 Subject: [PATCH 5/7] Put super as the first field, and removed _pin --- crates/codegen/src/class_decl.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 9938d0b..93eb23b 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -108,16 +108,14 @@ impl ClassProcessedData { )); cg.indent += 1; - cg.add_indentedln("pub _vptr: &'static [*const std::ffi::c_void],"); - - cg.add_indentedln("_pin: std::marker::PhantomPinned,"); - if let Some(ref inherits) = self.inherits { cg.add_indented("pub _super: "); cg.add(&get_type_from_path(inherits).get_rust()); cg.addln(","); } + cg.add_indentedln("pub _vptr: &'static [*const std::ffi::c_void],"); + for field in &self.fields { cg.add_indentedln(&field.get_comment()); cg.add_indentedln(&field.item.decl.get_rust()); From fab7326357de85e8cc07e248dd863e38d07418e1 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Fri, 12 Jun 2026 17:04:24 +0200 Subject: [PATCH 6/7] Optimized v table and vptr --- crates/codegen/src/class_decl.rs | 148 ++++++++++++++----------------- 1 file changed, 67 insertions(+), 81 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 93eb23b..31ee22a 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -112,10 +112,10 @@ impl ClassProcessedData { cg.add_indented("pub _super: "); cg.add(&get_type_from_path(inherits).get_rust()); 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 { cg.add_indentedln(&field.get_comment()); cg.add_indentedln(&field.item.decl.get_rust()); @@ -133,9 +133,7 @@ impl ClassProcessedData { )); cg.indent += 1; - self.emit_v_table(cg); - - self.emit_super_v_table(cg); + self.emit_unified_vtable(cg); self.emit_super_v_tests(cg); self.emit_constructor(ctx, cg); @@ -145,81 +143,92 @@ impl ClassProcessedData { 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() { cg.add_indentedln(&format!( - "pub const __FN_{}: usize = {i};", + "pub const __FN_{}: usize = Self::__PARENT_V_COUNT + {i};", method_name.0.to_uppercase() )); } 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() )); + + cg.add_indentedln("pub const __V_TABLE: &'static [*const std::ffi::c_void] = &{"); cg.indent += 1; - for method_name in &self.v_table { - cg.add_indented("Self::__m_"); - cg.add(&method_name.get_rust()); - cg.add(" as *const std::ffi::c_void"); - cg.addln(","); - } + if has_parent { + cg.add_indentedln(&format!( + "let mut table = [std::ptr::null(); {}::__V_COUNT + {}];", + parent_path, + self.v_table.len() + )); - cg.indent -= 1; - cg.add_indentedln("];"); - } + cg.add_indentedln(&format!("let parent_table = {}::__V_TABLE;", parent_path)); + 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) { - if self.override_v_table.is_empty() { - return; - } - - cg.add_indentedln(&format!( - "pub const __SUPER_V_TABLES: [&'static [*const std::ffi::c_void]; {}] = [", - self.override_v_table.len() - )); - cg.indent += 1; - - for (override_tier, overriden_method_idents) in &self.override_v_table { - let target_path = match &override_tier.0 { - 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 - } + for (override_tier, overriden_method_idents) in &self.override_v_table { + let base_class_path = override_tier + .0 + .as_ref() + .unwrap_or(self.inherits.as_ref().unwrap()) + .get_rust(); + for method_ident in &overriden_method_idents.item { + cg.add_indentedln(&format!( + "table[{}::__FN_{}] = {}::__m_{} as *const std::ffi::c_void;", + base_class_path, + method_ident.0.to_uppercase(), + self.self_path.get_rust(), + method_ident.get_rust() + )); } - }; + } - let target_rust_path = target_path.get_rust(); - - // 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 { + for method_name in &self.v_table { cg.add_indentedln(&format!( - "table[{}::__FN_{}] = {}::__m_{} as *const std::ffi::c_void;", - target_rust_path, - method_ident.0.to_uppercase(), - self.self_path.get_rust(), - method_ident.get_rust() + "table[Self::__FN_{}] = Self::__m_{} as *const std::ffi::c_void;", + method_name.0.to_uppercase(), + method_name.get_rust() )); } 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.add_indentedln("},"); + cg.add_indentedln("]"); } cg.indent -= 1; - cg.add_indentedln("];"); + cg.add_indentedln("};"); } fn emit_super_v_tests(&self, cg: &mut RustCodegen) { @@ -234,7 +243,7 @@ impl ClassProcessedData { if let Some(parent_path) = &self.inherits { parent_path.clone() } 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::::zeroed().assume_init() };"); cg.add_indentedln("this._vptr = &Self::__V_TABLE;"); - // Inline field declarations and initializers for field in &self.fields { let comment = field.get_comment(); @@ -348,28 +356,7 @@ impl ClassProcessedData { } cg.addln(");"); - if self.inherits.is_some() && !self.override_v_table.is_empty() { - 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("this._vptr = &Self::__V_TABLE;"); cg.add_indentedln(&constructor_comment); @@ -377,7 +364,6 @@ impl ClassProcessedData { cg.indent -= 1; cg.add_indentedln("}\n"); - // Generate matching inner initialization body block let mut constructor_params = vec![VarDecl { name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])), type_: Some(TypeExpr::Ref { From d0716fb7350a82a41e3a674cb221489633f8b088 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Fri, 12 Jun 2026 17:19:53 +0200 Subject: [PATCH 7/7] Override target testing --- crates/codegen/src/class_decl.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 31ee22a..888a20c 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -232,7 +232,7 @@ impl ClassProcessedData { } fn emit_super_v_tests(&self, cg: &mut RustCodegen) { - cg.add_indentedln(&format!("const fn __test_vt() {{")); + cg.add_indentedln(&format!("fn __test_vt() {{")); cg.indent += 1; for (override_tier, _) in self.override_v_table.iter() { @@ -293,6 +293,19 @@ impl ClassProcessedData { } } + // Deref tests for override targets + if self.inherits.is_some() && !self.override_v_table.is_empty() { + cg.add_indentedln("let this: &Self = &unsafe { std::mem::MaybeUninit::::zeroed().assume_init() };"); + + for (override_tier, v) in &self.override_v_table { + if let Some(path) = &override_tier.0 { + cg.add_indentedln(&v.get_comment()); + // This forces the compiler to statically verify that &Self can Deref into &Target + cg.add_indentedln(&format!("let _: &{} = this;", path.get_rust())); + } + } + } + cg.indent -= 1; cg.add_indentedln("}"); }