Teach stack limiter to handle start fn

This commit is contained in:
Sergey Pepyakin
2018-12-24 19:20:33 +01:00
parent fe25beca2b
commit 3db0d60e70
5 changed files with 64 additions and 2 deletions
+2 -1
View File
@@ -25,11 +25,12 @@
//! Because stack height is increased prior the call few problems arises:
//!
//! - Stack height isn't increased upon an entry to the first function, i.e. exported function.
//! - Start function is executed externally (similar to exported functions).
//! - It is statically unknown what function will be invoked in an indirect call.
//!
//! The solution for this problems is to generate a intermediate functions, called 'thunks', which
//! will increase before and decrease the stack height after the call to original function, and
//! then make exported function and table entries to point to a corresponding thunks.
//! then make exported function and table entries, start section to point to a corresponding thunks.
//!
//! # Stack cost
//!
+6 -1
View File
@@ -35,6 +35,8 @@ pub(crate) fn generate_thunks(
.elements_section()
.map(|es| es.entries())
.unwrap_or(&[]);
let start_func_idx = module
.start_section();
let exported_func_indicies = exports.iter().filter_map(|entry| match *entry.internal() {
Internal::Function(ref function_idx) => Some(*function_idx),
@@ -48,7 +50,7 @@ pub(crate) fn generate_thunks(
// Replacement map is at least export section size.
let mut replacement_map: Map<u32, Thunk> = Map::new();
for func_idx in exported_func_indicies.chain(table_func_indicies) {
for func_idx in exported_func_indicies.chain(table_func_indicies).chain(start_func_idx.into_iter()) {
let callee_stack_cost = ctx.stack_cost(func_idx).ok_or_else(|| {
Error(format!("function with idx {} isn't found", func_idx))
})?;
@@ -154,6 +156,9 @@ pub(crate) fn generate_thunks(
}
}
}
elements::Section::Start(ref mut start_idx) => {
fixup(start_idx)
}
_ => {}
}
}