Skip to content

Commit

Permalink
Support the Tail Call Proposal (#272)
Browse files Browse the repository at this point in the history
  • Loading branch information
CryZe committed Sep 10, 2024
1 parent e6fd953 commit fd7ea7b
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 6 deletions.
20 changes: 20 additions & 0 deletions crates/tests/tests/round_trip/return_call.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(module
(func $g (result i32)
i32.const 42
return)
(func $f (result i32)
return_call $g)
(export "f" (func $f)))

(; CHECK-ALL:
(module
(type (;0;) (func (result i32)))
(func $g (;0;) (type 0) (result i32)
i32.const 42
return
)
(func $f (;1;) (type 0) (result i32)
return_call $g
)
(export "f" (func $f))
;)
18 changes: 18 additions & 0 deletions crates/tests/tests/round_trip/return_call_indirect.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
(module
(type (func (result i32)))
(table 1 funcref)
(func (export "a") (param i32) (result i32)
local.get 0
return_call_indirect (type 0)))

(; CHECK-ALL:
(module
(type (;0;) (func (result i32)))
(type (;1;) (func (param i32) (result i32)))
(func (;0;) (type 1) (param i32) (result i32)
local.get 0
return_call_indirect (type 0)
)
(table (;0;) 1 funcref)
(export "a" (func 0))
;)
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 @@ -1316,6 +1316,20 @@ fn append_instruction(ctx: &mut ValidationContext, inst: Operator, loc: InstrLoc
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 @@ -1326,11 +1340,6 @@ fn append_instruction(ctx: &mut ValidationContext, inst: Operator, loc: InstrLoc
| 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 fd7ea7b

Please sign in to comment.