Skip to content

Commit

Permalink
Support the Tail Call Proposal
Browse files Browse the repository at this point in the history
This adds support for the Tail Call proposal.
  • Loading branch information
CryZe committed Sep 1, 2024
1 parent 2c3ddf9 commit 213baa9
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 6 deletions.
21 changes: 20 additions & 1 deletion src/ir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,20 @@ pub enum Instr {
/// The destination table
dst: TableId,
},

/// `return_call`
ReturnCall {
/// The function being invoked.
func: FunctionId,
},

/// `return_call_indirect`
ReturnCallIndirect {
/// The type signature of the function we're calling
ty: TypeId,
/// The table which `func` below is indexing into
table: TableId,
},
}

/// Argument in `V128Shuffle` of lane indices to select
Expand Down Expand Up @@ -1215,7 +1229,12 @@ impl Instr {
/// (`i32.add`, etc...).
pub fn following_instructions_are_unreachable(&self) -> bool {
match *self {
Instr::Unreachable(..) | Instr::Br(..) | Instr::BrTable(..) | Instr::Return(..) => true,
Instr::Unreachable(..)
| Instr::Br(..)
| Instr::BrTable(..)
| Instr::Return(..)
| Instr::ReturnCall(..)
| Instr::ReturnCallIndirect(..) => true,

// No `_` arm to make sure that we properly update this function as
// we add support for new instructions.
Expand Down
1 change: 1 addition & 0 deletions src/module/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ impl ModuleConfig {
features.insert(WasmFeatures::REFERENCE_TYPES);
features.insert(WasmFeatures::BULK_MEMORY);
features.insert(WasmFeatures::SIMD);
features.insert(WasmFeatures::TAIL_CALL);
// Enable supported active proposals.
if !self.only_stable_features {
// # Fully supported proposals.
Expand Down
9 changes: 9 additions & 0 deletions src/module/functions/local_function/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,15 @@ impl<'instr> Visitor<'instr> for Emit<'_> {
}
}
ElemDrop(e) => Instruction::ElemDrop(self.indices.get_element_index(e.elem)),
ReturnCall(e) => Instruction::ReturnCall(self.indices.get_func_index(e.func)),
ReturnCallIndirect(e) => {
let type_index = self.indices.get_type_index(e.ty);
let table_index = self.indices.get_table_index(e.table);
Instruction::ReturnCallIndirect {
type_index,
table_index,
}
}
});
}
}
Expand Down
19 changes: 14 additions & 5 deletions src/module/functions/local_function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,20 @@ fn append_instruction<'context>(
ctx.alloc_instr(ElemDrop { elem }, loc);
}

Operator::ReturnCall { function_index } => {
let func = ctx.indices.get_func(function_index).unwrap();
ctx.alloc_instr(ReturnCall { func }, loc);
}

Operator::ReturnCallIndirect {
type_index,
table_index,
} => {
let ty = ctx.indices.get_type(type_index).unwrap();
let table = ctx.indices.get_table(table_index).unwrap();
ctx.alloc_instr(ReturnCallIndirect { ty, table }, loc);
}

// List all unimplmented operators instead of have a catch-all arm.
// So that future upgrades won't miss additions to this list that may be important to know.
Operator::TryTable { try_table: _ }
Expand All @@ -1333,11 +1347,6 @@ fn append_instruction<'context>(
| Operator::Rethrow { relative_depth: _ }
| Operator::Delegate { relative_depth: _ }
| Operator::CatchAll
| Operator::ReturnCall { function_index: _ }
| Operator::ReturnCallIndirect {
type_index: _,
table_index: _,
}
| Operator::RefEq
| Operator::StructNew {
struct_type_index: _,
Expand Down

0 comments on commit 213baa9

Please sign in to comment.