Skip to content

Commit

Permalink
runtime: Start allowing omitting default code in impl methods
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Feb 3, 2025
1 parent 94a19a0 commit 110db77
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 23 deletions.
1 change: 1 addition & 0 deletions dora-bytecode/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub struct FunctionData {
pub is_force_inline: bool,
pub is_never_inline: bool,
pub bytecode: Option<BytecodeFunction>,
pub trait_method_impl: Option<FunctionId>,
}

#[derive(Debug, Decode, Encode)]
Expand Down
2 changes: 1 addition & 1 deletion dora-frontend/src/exhaustiveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn check(sa: &Sema) {
file_id: fct.file_id,
analysis: fct.analysis(),
};
visit::walk_fct(&mut visitor, &fct.ast);
visit::walk_fct(&mut visitor, fct.ast().as_ref().expect("body expected"));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion dora-frontend/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub fn generate_fct(sa: &Sema, fct: &FctDefinition, src: &AnalysisData) -> Bytec
unit_register: None,
entered_contexts: Vec::new(),
};
ast_bytecode_generator.generate_fct(&fct.ast)
ast_bytecode_generator.generate_fct(fct.ast().expect("body expected"))
}

pub fn generate_global_initializer(
Expand Down
12 changes: 8 additions & 4 deletions dora-frontend/src/impldefck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,20 +110,23 @@ pub fn check_definition_against_trait(sa: &mut Sema) {
let return_type = trait_method.return_type();
let return_type = replace_type(sa, return_type, None, self_ty.clone());

let fct = FctDefinition::new(
let fct = FctDefinition::new_no_source(
impl_.package_id,
impl_.module_id,
impl_.file_id,
&trait_method.ast,
trait_method.declaration_span,
trait_method.span,
trait_method.ast(),
ParsedModifierList::default(),
trait_method.name,
trait_method
.type_param_definition()
.clone_with_new_parent(impl_.type_param_definition().to_owned()),
params,
return_type,
FctParent::Impl(impl_.id()),
);
fct.return_type.set_ty(return_type);
assert!(fct.trait_method_impl.set(*trait_method_id).is_ok());
new_fcts.push(fct);
}
}
Expand Down Expand Up @@ -168,12 +171,13 @@ fn check_impl_methods(

sa.report(
impl_method.file_id,
impl_method.ast.span,
impl_method.span,
ErrorMessage::AliasExists(method_name, existing_fct.span),
);
}

remaining_trait_methods.remove(&trait_method_id);
assert!(impl_method.trait_method_impl.set(trait_method_id).is_ok());

let trait_method = sa.fct(trait_method_id);

Expand Down
7 changes: 4 additions & 3 deletions dora-frontend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ pub fn emit_ast(sa: &Sema, filter: &str) {
for (_id, fct) in sa.fcts.iter() {
let fct_name = fct.display_name(sa);

if fct_pattern_match(&fct_name, filter) {
ast::dump::dump_fct(&fct.ast);
if fct_pattern_match(&fct_name, filter) && fct.has_body() {
ast::dump::dump_fct(fct.ast().expect("body expected"));
}
}
}
Expand Down Expand Up @@ -172,7 +172,8 @@ fn fct_pattern_match(name: &str, pattern: &str) -> bool {

fn internalck(sa: &Sema) {
for (_id, fct) in sa.fcts.iter() {
if !fct.has_body() && !fct.in_trait() && !fct.is_internal {
if !fct.has_body() && !fct.in_trait() && !fct.is_internal && !fct.use_trait_default_impl(sa)
{
sa.report(fct.file_id, fct.span, ErrorMessage::MissingFctBody);
}
}
Expand Down
6 changes: 6 additions & 0 deletions dora-frontend/src/program_emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@ fn create_functions(sa: &Sema, e: &mut Emitter) -> Vec<FunctionData> {
is_force_inline: fct.is_force_inline,
is_never_inline: fct.is_never_inline,
bytecode: fct.bytecode.get().cloned(),
trait_method_impl: fct
.trait_method_impl
.get()
.cloned()
.map(|id| convert_function_id(id)),
})
}

Expand Down Expand Up @@ -241,6 +246,7 @@ fn create_functions(sa: &Sema, e: &mut Emitter) -> Vec<FunctionData> {
is_force_inline: false,
is_never_inline: false,
bytecode: Some(global.bytecode().clone()),
trait_method_impl: None,
});

e.global_initializer.insert(global.id(), fct_id);
Expand Down
81 changes: 77 additions & 4 deletions dora-frontend/src/sema/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub struct FctDefinition {
pub package_id: PackageDefinitionId,
pub module_id: ModuleDefinitionId,
pub file_id: SourceFileId,
pub ast: Arc<ast::Function>,
pub ast: Option<Arc<ast::Function>>,
pub declaration_span: Span,
pub span: Span,
pub name: Name,
Expand All @@ -46,6 +46,7 @@ pub struct FctDefinition {
pub container_type_params: OnceCell<usize>,
pub bytecode: OnceCell<BytecodeFunction>,
pub intrinsic: OnceCell<Intrinsic>,
pub trait_method_impl: OnceCell<FctDefinitionId>,
}

impl FctDefinition {
Expand Down Expand Up @@ -73,7 +74,7 @@ impl FctDefinition {
file_id,
declaration_span: ast.declaration_span,
span: ast.span,
ast: ast.clone(),
ast: Some(ast.clone()),
name,
params,
return_type,
Expand All @@ -90,6 +91,49 @@ impl FctDefinition {
container_type_params: OnceCell::new(),
bytecode: OnceCell::new(),
intrinsic: OnceCell::new(),
trait_method_impl: OnceCell::new(),
}
}

pub(crate) fn new_no_source(
package_id: PackageDefinitionId,
module_id: ModuleDefinitionId,
file_id: SourceFileId,
declaration_span: Span,
span: Span,
ast: Option<&Arc<ast::Function>>,
modifiers: ParsedModifierList,
name: Name,
type_params: Rc<TypeParamDefinition>,
params: Params,
return_type: SourceType,
parent: FctParent,
) -> FctDefinition {
FctDefinition {
id: None,
package_id,
module_id,
file_id,
declaration_span: declaration_span,
span: span,
ast: ast.cloned(),
name,
params,
return_type: ParsedType::new_ty(return_type),
parent,
is_optimize_immediately: modifiers.is_optimize_immediately,
visibility: modifiers.visibility(),
is_static: modifiers.is_static,
is_test: modifiers.is_test,
is_internal: modifiers.is_internal,
is_force_inline: modifiers.is_force_inline,
is_never_inline: modifiers.is_never_inline,
analysis: OnceCell::new(),
type_param_definition: type_params,
container_type_params: OnceCell::new(),
bytecode: OnceCell::new(),
intrinsic: OnceCell::new(),
trait_method_impl: OnceCell::new(),
}
}

Expand Down Expand Up @@ -118,6 +162,21 @@ impl FctDefinition {
}
}

pub fn use_trait_default_impl(&self, sa: &Sema) -> bool {
if self.parent.is_impl() {
let trait_method_id = self
.trait_method_impl
.get()
.cloned()
.expect("missing trait method");

let trait_method = sa.fct(trait_method_id);
trait_method.has_body()
} else {
false
}
}

pub fn is_self_allowed(&self) -> bool {
match self.parent {
FctParent::Impl(..) | FctParent::Trait(..) | FctParent::Extension(..) => true,
Expand Down Expand Up @@ -169,11 +228,18 @@ impl FctDefinition {
}

pub fn has_body(&self) -> bool {
self.ast.block.is_some()
self.ast
.as_ref()
.map(|a| a.block.is_some())
.unwrap_or(false)
}

pub fn ast(&self) -> Option<&Arc<ast::Function>> {
self.ast.as_ref()
}

pub fn is_lambda(&self) -> bool {
self.ast.kind.is_lambda()
self.parent.is_function()
}

pub fn span(&self) -> Span {
Expand Down Expand Up @@ -315,6 +381,13 @@ impl FctParent {
}
}

pub fn is_function(&self) -> bool {
match self {
&FctParent::Function => true,
_ => false,
}
}

pub fn is_impl(&self) -> bool {
match self {
&FctParent::Impl(..) => true,
Expand Down
2 changes: 1 addition & 1 deletion dora-frontend/src/typeck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ fn check_function(
element: fct,
};

typeck.check_fct(&fct.ast);
typeck.check_fct(fct.ast().expect("body expected"));

assert!(fct.analysis.set(analysis).is_ok());
}
Expand Down
16 changes: 14 additions & 2 deletions dora-runtime/src/cannon/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub struct CannonCodeGen<'a> {
emit_code_comments: bool,

type_params: BytecodeTypeArray,
specialize_self: Option<BytecodeType>,

offset_to_address: HashMap<BytecodeOffset, usize>,
offset_to_label: HashMap<BytecodeOffset, Label>,
Expand Down Expand Up @@ -97,6 +98,7 @@ impl<'a> CannonCodeGen<'a> {
bytecode: compilation_data.bytecode_fct,
emit_code_comments: compilation_data.emit_code_comments,
type_params: compilation_data.type_params,
specialize_self: compilation_data.specialize_self,
offset_to_address: HashMap::new(),
offset_to_label: HashMap::new(),
current_offset: BytecodeOffset(0),
Expand Down Expand Up @@ -3932,11 +3934,21 @@ impl<'a> CannonCodeGen<'a> {
}

fn specialize_ty(&self, ty: BytecodeType) -> BytecodeType {
specialize_ty(self.vm, None, ty, &self.type_params)
specialize_ty(
self.vm,
self.specialize_self.as_ref(),
ty,
&self.type_params,
)
}

fn specialize_ty_array(&self, types: &BytecodeTypeArray) -> BytecodeTypeArray {
specialize_ty_array(self.vm, None, types, &self.type_params)
specialize_ty_array(
self.vm,
self.specialize_self.as_ref(),
types,
&self.type_params,
)
}

fn register_offset(&self, reg: Register) -> i32 {
Expand Down
25 changes: 22 additions & 3 deletions dora-runtime/src/compiler/aot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::vm::{
specialize_bty, specialize_bty_array, BytecodeTypeExt, Code, LazyCompilationSite, ShapeKind,
VM,
};
use crate::Shape;
use crate::{get_bytecode, Shape};

pub fn compile_boots_aot(vm: &VM) {
if vm.has_boots() {
Expand Down Expand Up @@ -247,15 +247,16 @@ impl<'a> TransitiveClosureComputation<'a> {
fn trace(&mut self, fct_id: FunctionId, type_params: BytecodeTypeArray) {
let fct = &self.vm.fct(fct_id);

if let Some(ref bytecode_function) = fct.bytecode {
self.iterate_bytecode(bytecode_function, type_params);
if let Some((bytecode_function, specialize_self)) = get_bytecode(self.vm, fct) {
self.iterate_bytecode(bytecode_function, type_params, specialize_self);
}
}

fn iterate_bytecode(
&mut self,
bytecode_function: &BytecodeFunction,
type_params: BytecodeTypeArray,
_specialize_self: Option<BytecodeType>,
) {
let reader = BytecodeReader::new(bytecode_function.code());

Expand Down Expand Up @@ -548,6 +549,24 @@ fn prepare_lazy_call_sites(
type_params,
const_pool_offset_from_ra,
} => {
let target = ctc
.function_addresses
.get(&(*fct_id, type_params.clone()))
.cloned();

if target.is_none() {
println!(
"code = {:?} {}",
code.descriptor(),
display_fct(&_vm.program, *fct_id)
);
println!(
" calls {} with {:?}",
display_fct(&_vm.program, *fct_id),
type_params
);
println!("offset = {}", offset);
}
let target = ctc
.function_addresses
.get(&(*fct_id, type_params.clone()))
Expand Down
Loading

0 comments on commit 110db77

Please sign in to comment.