You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The call instruction implementation needs to know the number or arguments in the callee. This is taken from module's function and type sections.
The required number of argument is "packed" into span<const Value> (remember this is a reference type).
The span of arguments is passed to the callee.
Callee copies the argument to the locals storage. Also allocates space for local variables and stack in single go.
In the end of callee execution, the execute() function returns the top stack item, if any.
The caller must drop the call arguments from the stack (i.e. move the stack pointer).
And copy the callee return value (if any) to the top of the stack. This is currently done by inspecting the function type, but can be done by inspecting ExecutionResult. Call optimization #554
Plan
Both caller and callee needs information about number of arguments. Caller takes this from the module, callee from the span. The callee can take it from the module as well, so execute() can skip this information by only passing const Value* without size. Although, in theory this may not be faster. Pass arguments as const Value* #552
Instead of allocating "stack space" in each call, we can pre-allocate shared execution-thread stack space. It can be fixed size (this can work as a valid wasm exhaustion limit) or infinite by allocate more segments when needed. Thread stack space #529
When 2 is implemented, arguments don't need to be copied because there are already in the right place (unless new segment must be allocated).
At the call end, locals must be dropped and the top stack item (if any) must be beginning of the "stack space" (where the first argument was). After returning, the caller will have the result on the top of the stack. Caller does not even need to know if there is any result.
Therefore, we don't need to return anything from the execute() except for the "trapped" flag.
Bonus (out-of-order items)
The call instruction always calls the same function, so the number or arguments can be encoded in immediates. No need to reach module each time.
Similarly, all execution required information (max stack height, number of arguments) may be added to the Code type. Then accessing function and type sections is not needed during execution.
TODO
It seems easy to wrap this "unsafe" execution API with a "safe" API which will check if passed argument are of the correct number and type. But also reverse-wrapping is needed for host function - unsafe host function entry point will only receive Value*. Some mechanism is needed to check and extract the type information about received arguments.
The text was updated successfully, but these errors were encountered:
Detailed calls optimization plan
Current status
In Fizzy 0.5, the internal calls work like this:
call
instruction implementation needs to know the number or arguments in the callee. This is taken from module's function and type sections.span<const Value>
(remember this is a reference type).execute()
function returns the top stack item, if any.ExecutionResult
. Call optimization #554Plan
execute()
can skip this information by only passingconst Value*
without size. Although, in theory this may not be faster. Pass arguments as const Value* #552execute()
except for the "trapped" flag.Bonus (out-of-order items)
call
instruction always calls the same function, so the number or arguments can be encoded in immediates. No need to reach module each time.Code
type. Then accessing function and type sections is not needed during execution.TODO
Value*
. Some mechanism is needed to check and extract the type information about received arguments.The text was updated successfully, but these errors were encountered: