undefined asyncify_get_state
Is there currently a recommended way to go about calling asyncify_get_state from inside native code? To manage this with other methods currently I'm doing:
#ifndef ASYNCJMP_SUPPORT_ASYNCIFY_H
#define ASYNCJMP_SUPPORT_ASYNCIFY_H
__attribute__((import_module("asyncify"), import_name("start_unwind"))) void asyncify_start_unwind(void *buf);
#define asyncify_start_unwind(buf) \
do \
{ \
extern void *pl_asyncify_unwind_buf; \
pl_asyncify_unwind_buf = (buf); \
asyncify_start_unwind((buf)); \
} while (0)
__attribute__((import_module("asyncify"), import_name("stop_unwind"))) void asyncify_stop_unwind(void);
#define asyncify_stop_unwind() \
do \
{ \
extern void *pl_asyncify_unwind_buf; \
pl_asyncify_unwind_buf = NULL; \
asyncify_stop_unwind(); \
} while (0)
__attribute__((import_module("asyncify"), import_name("start_rewind"))) void asyncify_start_rewind(void *buf);
__attribute__((import_module("asyncify"), import_name("stop_rewind"))) void asyncify_stop_rewind(void);
__attribute__((import_module("asyncify"), import_name("get_state"))) int asyncify_get_state(void);
#endif
Which all get successfully turned into exports. But for asyncify_get_state the pass raises an error:
"/opt/wasm-opt" zeroperl_unopt -O3 -o zeroperl_unopt
Fatal: call to unidenfied asyncify import: get_state
What I'm trying to achieve:
__attribute__((noinline))
ssize_t __wrap_read(int fd, void *buf, size_t count) {
if (asyncify_get_state() == 2) {
asyncify_stop_rewind();
if (have_saved_result) {
have_saved_result = false;
return saved_result;
}
return -1;
}
ssize_t r = sfs_read(fd, buf, count);
if (r >= 0) {
return r; // Fast path succeeded
}
ssize_t real_val = __real_read(fd, buf, count);
if (asyncify_get_state() == 1) {
saved_result = real_val;
have_saved_result = true;
asyncify_stop_unwind();
return real_val;
}
return real_val;
}
I'm using binaryen-version_121
edit:
looking at the pass more closely I can see get_state is missing from here & here, but the documentation says that it should be there
cc: @kripken
Here is a patch that unblocks me for the time being:
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp
index 994142e48..f6500ed2c 100644
--- a/src/passes/Asyncify.cpp
+++ b/src/passes/Asyncify.cpp
@@ -349,6 +349,7 @@ static const Name START_UNWIND = "start_unwind";
static const Name STOP_UNWIND = "stop_unwind";
static const Name START_REWIND = "start_rewind";
static const Name STOP_REWIND = "stop_rewind";
+static const Name GET_STATE = "get_state";
static const Name ASYNCIFY_GET_CALL_INDEX = "__asyncify_get_call_index";
static const Name ASYNCIFY_CHECK_CALL_INDEX = "__asyncify_check_call_index";
@@ -569,6 +570,8 @@ public:
renamings[func->name] = ASYNCIFY_START_REWIND;
} else if (func->base == STOP_REWIND) {
renamings[func->name] = ASYNCIFY_STOP_REWIND;
+ } else if (func->base == GET_STATE) {
+ renamings[func->name] = ASYNCIFY_GET_STATE;
} else {
Fatal() << "call to unidenfied asyncify import: " << func->base;
}
@@ -624,6 +627,8 @@ public:
} else if (target->base == STOP_REWIND) {
info.canChangeState = true;
info.isTopMostRuntime = true;
+ } else if (target->base == GET_STATE) {
+ // NOTE: asyncify.get_state doesn't actually change the state; NOOP
} else {
WASM_UNREACHABLE("call to unidenfied asyncify import");
}
The patch makes sense to me (though we don't need the last part that is just a comment, I think). get_state doesn't modify the state, which is why this was missed I guess. But it is part of the API. A PR would be welcome.