Skip to content
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

[wasm32-wasi] About function pointer casting in build/static_src #3012

Open
lum1n0us opened this issue Jul 19, 2024 · 5 comments
Open

[wasm32-wasi] About function pointer casting in build/static_src #3012

lum1n0us opened this issue Jul 19, 2024 · 5 comments
Assignees
Labels
enhancement An improvement rather than a bug help wanted Please help with this, we think you can

Comments

@lum1n0us
Copy link
Contributor

I notice there is a widely coding pattern in build/static_src/CompiledXType.c. It will cause a trap during execution(Step 18.) when using as a wasm32-wasi target.

Take CompiledFunctionType.c as an example.

  • Define Nuitka_Function_get_name as static PyObject *Nuitka_Function_get_name(struct Nuitka_FunctionObject *function). With one argument.
  • When refer it in static PyGetSetDef Nuitka_Function_getset[], cast it to getter(from Include/descrobject.h). It means cast PyObject*(struct Nuitka_FunctionObject*) -> PyObject *(PyObject *, void *).
  • Therefore, callers will execute Nuitka_Function_get_name in a form likes get(obj, closure)(getset_get() in Objects/descrobject.c).

From caller side, callee is a function with two arguments. On the other side, callee is a function with one argument. It works well in C. But it confuses wasm.

A call with function pointers will be transferred into call_indirect in Wasm, and pack the callee type together. During execution, there is a type check between expected function type(like PyObject*(void*,void*)) and actually function type(PyObject*(void*)) (all pointers are same types). Eventually, the checker will hit a trap because of different amount of arguments.


P.S.

I am thinking about using a different function signature for wasm32-wasi target like:

#if __wasi__
static PyObject *Nuitka_Function_get_name(struct Nuitka_FunctionObject *function, void *data) {
#else
static PyObject *Nuitka_Function_get_name(struct Nuitka_FunctionObject *function) {
#endif
@kayhayen
Copy link
Member

I am OK with these functions getting modified to specify an unused argument instead. But ideally we also it it in a way, where the cast to getter and setter becomes unnecessary, that means we accept PyObject *self and cast it to the function object instead, this can only be good at catching errors. If you were to do that, it will be very acceptable.

@lum1n0us
Copy link
Contributor Author

Something like?

#if __wasi__
static PyObject *Nuitka_Function_get_name(PyObject *self, void *data) {
#else
static PyObject *Nuitka_Function_get_name(PyObject *self,) {
#endif
  struct Nuitka_FunctionObject *function = (struct Nuitka_FunctionObject *)self;
  // ...

@kayhayen
Copy link
Member

Yes, but without the need for the define, just follow the signature of getter and setter:

typedef PyObject *(*getter)(PyObject *, void *);
typedef int (*setter)(PyObject *, PyObject *, void *);

Trailing commas wouldn't work btw.

@kayhayen kayhayen added enhancement An improvement rather than a bug help wanted Please help with this, we think you can labels Jul 20, 2024
@lum1n0us
Copy link
Contributor Author

lum1n0us commented Jul 28, 2024

  • There are extra (getter) and (setter) in MetaPathBasedLoaderX.c
  • Similar problems happens on (PyCFunction) casting.

Highly likely there are more (not-strictly-compatible)function pointer casting in build/static_src.

P.S.
I guess some gcc compilation options, like -Wbad-function-cast -Wcast-function-type, are able to detect those. But I am wondering where I can use them.

@kayhayen
Copy link
Member

You have made excellent progress already. The ones I saw in the loader right now seem standard and PyCFunction looks like it's just more of the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement An improvement rather than a bug help wanted Please help with this, we think you can
Projects
None yet
Development

No branches or pull requests

2 participants