mirror of
https://github.com/fluencelabs/wasm-utils
synced 2025-03-15 11:10:49 +00:00
Teach stack limiter to handle start fn
This commit is contained in:
parent
fe25beca2b
commit
3db0d60e70
@ -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
|
||||
//!
|
||||
|
@ -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)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ macro_rules! def_stack_height_test {
|
||||
}
|
||||
|
||||
def_stack_height_test!(simple);
|
||||
def_stack_height_test!(start);
|
||||
def_stack_height_test!(table);
|
||||
def_stack_height_test!(global);
|
||||
def_stack_height_test!(imports);
|
||||
|
44
tests/expectations/stack-height/start.wat
Normal file
44
tests/expectations/stack-height/start.wat
Normal file
@ -0,0 +1,44 @@
|
||||
(module
|
||||
(type (;0;) (func (param i32 i32)))
|
||||
(type (;1;) (func))
|
||||
(import "env" "ext_return" (func (;0;) (type 0)))
|
||||
(import "env" "memory" (memory (;0;) 1 1))
|
||||
(func (;1;) (type 1)
|
||||
(local i32))
|
||||
(func (;2;) (type 1))
|
||||
(func (;3;) (type 1)
|
||||
get_global 0
|
||||
i32.const 1
|
||||
i32.add
|
||||
set_global 0
|
||||
get_global 0
|
||||
i32.const 1024
|
||||
i32.gt_u
|
||||
if ;; label = @1
|
||||
unreachable
|
||||
end
|
||||
call 1
|
||||
get_global 0
|
||||
i32.const 1
|
||||
i32.sub
|
||||
set_global 0)
|
||||
(func (;4;) (type 1)
|
||||
get_global 0
|
||||
i32.const 1
|
||||
i32.add
|
||||
set_global 0
|
||||
get_global 0
|
||||
i32.const 1024
|
||||
i32.gt_u
|
||||
if ;; label = @1
|
||||
unreachable
|
||||
end
|
||||
call 1
|
||||
get_global 0
|
||||
i32.const 1
|
||||
i32.sub
|
||||
set_global 0)
|
||||
(global (;0;) (mut i32) (i32.const 0))
|
||||
(export "exported_start" (func 4))
|
||||
(export "call" (func 2))
|
||||
(start 4))
|
11
tests/fixtures/stack-height/start.wat
vendored
Normal file
11
tests/fixtures/stack-height/start.wat
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
(module
|
||||
(import "env" "ext_return" (func $ext_return (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(start $start)
|
||||
(func $start (export "exported_start")
|
||||
(local i32)
|
||||
)
|
||||
(func (export "call")
|
||||
)
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user