qt-webassembly-examples icon indicating copy to clipboard operation
qt-webassembly-examples copied to clipboard

'Pointer_stringify' is removed since emscripten v1.38.27

Open inobelar opened this issue 3 years ago • 1 comments

Description

After trying to use (amazingly useful) code from gui_localfiles/qhtml5file_html5.cpp (for opening/saving files via browser's file dialog), (in non-Qt application, by using currently latest emsdk (v2.0.16)), I noticed an error (in run-time, look for it browser's "Developer tools"): Pointer_stringify() is not defined.

Searching for this error let to the following results:

Simple replacement of this function by UTF8ToString works well, no other errors happens.

Possible solution

Since this repository is related to Qt, and showing it's WASM examples (which uses Qt for WebAssembly with kinda-old, but 'Known-good versions' of emsdk) - I guess this minor issue will never be accepted :disappointed: . Anyway I believe that this information will be useful for others who encounter this error :smiley:

Since simple stupid replacement (Pointer_stringify -> UTF8ToString) will not satisfy everyone, I suggest adding check for Emscripten version, like in Qt::

emscripten_version_check.hpp
#ifndef EMSCRIPTEN_VERSION_CHECK_HPP
#define EMSCRIPTEN_VERSION_CHECK_HPP

#if defined(__EMSCRIPTEN__)

// Make sure, that Emscripten's version is presented as 'uint8_t', otherwise
// packing in EMSCRIPTEN_VERSION_CHECK may be wrong
static_assert (__EMSCRIPTEN_major__ <= 255, "Emscripten::version.major is out of range");
static_assert (__EMSCRIPTEN_minor__ <= 255, "Emscripten::version.minor is out of range");
static_assert (__EMSCRIPTEN_tiny__  <= 255, "Emscripten::version.tiny  is out of range");

// Inspired by Qt :: QT_VERSION & QT_VERSION_CHECK from <qglobal.h>

/*
   EMSCRIPTEN_VERSION is (major << 16) + (minor << 8) + tiny.
*/
#define EMSCRIPTEN_VERSION \
    EMSCRIPTEN_VERSION_CHECK(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)

/*
   can be used like #if (EMSCRIPTEN_VERSION >= EMSCRIPTEN_VERSION_CHECK(2, 0, 16))
*/
#define EMSCRIPTEN_VERSION_CHECK(major, minor, tiny) \
    ( (major << 16) | (minor << 8) | (tiny) )

#endif // defined(__EMSCRIPTEN__)

#endif // EMSCRIPTEN_VERSION_CHECK_HPP

so each usage of Pointer_stringify in this repository must be wrapped like:

#include "emscripten_version_check.hpp"

#if (EMSCRIPTEN_VERSION >= EMSCRIPTEN_VERSION_CHECK(1, 38, 27))
    #define POINTER_STRINGIFY_DISABLED true
#else
    #define POINTER_STRINGIFY_DISABLED false
#endif

// ...

EM_ASM_({
  #if (POINTER_STRINGIFY_DISABLED)
    const str = UTF8ToString($0);
  #else
    const str = Pointer_stringify($0);
  #endif
  // ...
}, str_raw_ptr);

#undef POINTER_STRINGIFY_DISABLED

Pitfalls

Notice, that emscripten macro EM_ASM_ not works well with c++ macros, so the next (better) version NOT WORK (maybe, only in my case):

#include "emscripten_version_check.hpp"

#if (EMSCRIPTEN_VERSION >= EMSCRIPTEN_VERSION_CHECK(1, 38, 27))
    #define POINTER_TO_STRING UTF8ToString
#else
    #define POINTER_TO_STRING Pointer_stringify
#endif

EM_ASM_({
  const str = POINTER_TO_STRING($0);
  // ...
}, str_raw_ptr);
// ...

#undef POINTER_TO_STRING

It produces POINTER_TO_STRING is not defined error (in run-time, look for it in browser's "Developer tools"), and looks like macro being 'stringified', not replaced by wanted function.

inobelar avatar May 07 '21 15:05 inobelar

Thanks for the report! This particular example is a bit outdated at this point since I've stopped using EM_ASM_ inline JavaScript in favor of Emscripten bind.h/val.h. So I'm not sure if it's worth maintaining.

(Have a look at qtbase/src/gui/platform/wasm/qwasmlocalfileaccess.cpp for the updated version; or use QFileDialog:: getOpenFileContent() and saveFileContent())

msorvig avatar May 10 '21 12:05 msorvig