-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: ExecuteFunction without std::function #716
Conversation
0ba7217
to
ff0b51a
Compare
Codecov Report
@@ Coverage Diff @@
## master #716 +/- ##
==========================================
+ Coverage 99.24% 99.25% +0.01%
==========================================
Files 76 76
Lines 11482 11571 +89
==========================================
+ Hits 11395 11485 +90
+ Misses 87 86 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
13ae5ff
to
f05b6c4
Compare
e62f7d0
to
86b574b
Compare
8d42298
to
cadff06
Compare
I pushed a proposed implementation simplification. |
Have you seen #643 (comment)? |
Ok, but is it still worth to add memory allocation for wasm function case? Even if temporarily? |
Yeah, agree it might be a good optimization here. |
ff45d85
to
7ae3859
Compare
859532a
to
efc9b87
Compare
const auto bar_type = FuncType{{}, {ValType::i32}}; | ||
|
||
auto instance_reexported_function = | ||
instantiate(parse(wasm_reexported_function), {{bar, bar_type.inputs, bar_type.outputs}}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inputs/outputs seems to be like a stray change, but looking at other cases below we do seem to have a constructor for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's not required / can be split out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine with me, it is only this case so having a single PR for it would be overkill.
@@ -361,14 +363,14 @@ TEST(execute_call, imported_function_call_void) | |||
|
|||
const auto module = parse(wasm); | |||
|
|||
bool called = false; | |||
const auto host_foo = [&called](Instance&, const Value*, int) { | |||
static bool called = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, why not just capture this in the function below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lambda's capture can't be used, because only lambdas without capture can be converted into function pointer.
Another option is to pass it via host_context
, but I decided against it, see https://github.com/wasmx/fizzy/pull/716/files/5baa695073c325728d1e60ee321ef94bf77e7248#r580939050
Also a possible evolution of this that would allow lambdas with capture is in #740
@@ -652,13 +663,13 @@ TEST(execute_call, call_initial_depth) | |||
const auto wasm = from_hex("0061736d01000000010401600000020b01036d6f6403666f6f0000"); | |||
|
|||
auto module = parse(wasm); | |||
auto host_foo = [](Instance& /*instance*/, const Value*, int depth) -> ExecutionResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh actually why do we drop the explicit return type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be implicitly deduced.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, we just used it for clarity. But either way it is fine, the thing is typechecked in instantiate.
"0061736d0100000001070160027f7f017f020a01026d31037375620000030201000a0a0108002000200110000" | ||
"b"); | ||
|
||
const auto func_idx = fizzy::find_exported_function(*module1, "sub"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took me a while looking up headers what is going on. So confusing we have find_exported_function
with instance and module, returning different things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, in C API this one is fizzy_find_exported_function_index
, probably should be renamed in C++, too.
@@ -217,6 +217,40 @@ TEST(api, resolve_imported_function_duplicate) | |||
EXPECT_THAT(execute(*instance, 1, {0_u32}), Result(42)); | |||
} | |||
|
|||
TEST(api, resolve_imported_function_duplicate_with_context) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point of this test to check that even though the any
is duplicated in each ExternalFunction, they are somehow still reference to the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just to check that any
context is copied as we expect it to and to illustrate what you would do to share a context.
It's reference to the same only, if it's a pointer inside any
.
Maybe another case would be informative, when any
has non-shared copied values.
lib/fizzy/instantiate.hpp
Outdated
@@ -46,9 +46,6 @@ class ExecuteFunction | |||
std::any m_host_context; | |||
|
|||
public: | |||
/// Default function constructor. | |||
ExecuteFunction() noexcept = default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was the constructor of the line fizzy::ImportedFunction imported_func;
using this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
const auto& c_type = c_imported_func.external_function.type; | ||
imported_func.inputs.resize(c_type.inputs_size); | ||
|
||
std::vector<fizzy::ValType> inputs(c_type.inputs_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While using this constructor here and reserve
in the case below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here it's possible to default-construct ValType
s.
Not much difference, but I find it a bit simpler to use vector
constructor + transform
, than reserve
+ transform
+ back_inserter
.
}; | ||
const auto& host_func_type = module->typesec[0]; | ||
|
||
int counter = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you int
type here and uint32_t
type in the other test? Just because in the other case the value is returned to wasm?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think that was the motivation for uint32_t
in the test below.
test/unittests/execute_call_test.cpp
Outdated
EXPECT_EQ(counter, 2); | ||
} | ||
|
||
TEST(execute_call, imported_functions_with_shared_cotext) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this kind of a duplicate of resolve_imported_function_duplicate_with_context)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are somewhat similar, but in resolve it's a single function that is imported twice and context is copied internally.
Here it's different functions and the user copies the context.
1996489
to
31d5017
Compare
31d5017
to
16e12bc
Compare
16e12bc
to
0ad804f
Compare
Simpler alternative to #643.