<feed xmlns='http://www.w3.org/2005/Atom'>
<title>puzzles/cmake/platforms/emscripten.cmake, branch rockbox-devel</title>
<subtitle>My sgt-puzzles tree</subtitle>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/'/>
<entry>
<title>Reset non-WASM Firefox version back to 48.</title>
<updated>2024-03-01T12:42:15+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2024-03-01T12:42:15+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=db804ea5a1d2de8d9d7d6e8fe569f5f8ec231832'/>
<id>db804ea5a1d2de8d9d7d6e8fe569f5f8ec231832</id>
<content type='text'>
That's what the comment said I'd left it at, but in some kind of
editing goof, I failed to actually do so.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
That's what the comment said I'd left it at, but in some kind of
editing goof, I failed to actually do so.
</pre>
</div>
</content>
</entry>
<entry>
<title>Emergency fix to Puzzles WASM builds.</title>
<updated>2024-03-01T12:31:33+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2024-03-01T12:24:05+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=cc91f8b9deafbf284609e3511ff900104499da9c'/>
<id>cc91f8b9deafbf284609e3511ff900104499da9c</id>
<content type='text'>
I updated Emscripten recently, to version 3.1.54. The result was that
none of the WASM puzzles run any more, because they produce a stack
trace at startup with the error message "to do setValue(i64) use
WASM_BIGINT".

I don't fully understand this. The stack trace comes via a JS wrapper
around a WASM-compiled function called __main_argc_argv, which sounds
like something in the Emscripten library startup. Somewhere in there
it goes via _js_get_date_64(), which tries to write an i64 into the
WASM memory array, which hits this abort in setValue().

Web searching for the error message turned up
https://github.com/godotengine/godot/pull/88594 which gave me the clue
that '-s WASM_BIGINT' is a command-line setting for the Emscripten
linker. And indeed, setting that makes the startup-time error go away
and the puzzles run again. But it also causes older versions of all
browsers to be unsupported, presumably on the grounds that they don't
have whatever WASM bigint feature this flag causes the code to use.

I don't really understand what's going on here. I assume
_js_get_date_64 is being called to handle a 64-bit time_t. But the
Puzzles code doesn't work with time_t at all, so this is entirely in
the Emscripten standard library. And if the pre-main() startup code
needs a 64-bit integer write, which won't work without this flag, then
surely _nothing_ would work without this flag, and surely someone
would have noticed that, and made that flag the default? This all
seems confusing and I wonder if I've misunderstood something.

However, if I don't fix it in _some_ way, the web puzzles will stay
out of action for days and I'll get lots of email complaints. So
here's something that makes them basically work again, and maybe we
can figure out the rest of the story later.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
I updated Emscripten recently, to version 3.1.54. The result was that
none of the WASM puzzles run any more, because they produce a stack
trace at startup with the error message "to do setValue(i64) use
WASM_BIGINT".

I don't fully understand this. The stack trace comes via a JS wrapper
around a WASM-compiled function called __main_argc_argv, which sounds
like something in the Emscripten library startup. Somewhere in there
it goes via _js_get_date_64(), which tries to write an i64 into the
WASM memory array, which hits this abort in setValue().

Web searching for the error message turned up
https://github.com/godotengine/godot/pull/88594 which gave me the clue
that '-s WASM_BIGINT' is a command-line setting for the Emscripten
linker. And indeed, setting that makes the startup-time error go away
and the puzzles run again. But it also causes older versions of all
browsers to be unsupported, presumably on the grounds that they don't
have whatever WASM bigint feature this flag causes the code to use.

I don't really understand what's going on here. I assume
_js_get_date_64 is being called to handle a 64-bit time_t. But the
Puzzles code doesn't work with time_t at all, so this is entirely in
the Emscripten standard library. And if the pre-main() startup code
needs a 64-bit integer write, which won't work without this flag, then
surely _nothing_ would work without this flag, and surely someone
would have noticed that, and made that flag the default? This all
seems confusing and I wonder if I've misunderstood something.

However, if I don't fix it in _some_ way, the web puzzles will stay
out of action for days and I'll get lots of email complaints. So
here's something that makes them basically work again, and maybe we
can figure out the rest of the story later.
</pre>
</div>
</content>
</entry>
<entry>
<title>Emscripten build: stop setting MIN_EDGE_VERSION.</title>
<updated>2024-02-29T07:55:38+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2024-02-29T07:54:24+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=e20644a3baa70dfd5baf790047ce821b396df312'/>
<id>e20644a3baa70dfd5baf790047ce821b396df312</id>
<content type='text'>
Emscripten 3.1.51 withdrew support for legacy (pre-Chrome) Edge
completely, and this command-line option now provokes an error from
the compiler.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Emscripten 3.1.51 withdrew support for legacy (pre-Chrome) Edge
completely, and this command-line option now provokes an error from
the compiler.
</pre>
</div>
</content>
</entry>
<entry>
<title>Windows: leave puzzles.rc out of auxiliary GUI tools.</title>
<updated>2023-11-19T15:04:50+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2023-11-19T15:03:40+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=595338fa43d40f356f04b8704f72f060651669e8'/>
<id>595338fa43d40f356f04b8704f72f060651669e8</id>
<content type='text'>
There's no reason to put the .rc file into developer tools like
galaxieseditor at all. Its current job is to add an icon, and those
tools don't have any. I'm about to add version information, and they
won't have that either (in particular, no description string like the
games do).

The CLI developer tools already don't include puzzles.rc, and GUI dev
tools are more like those than they are like puzzles.

puzzles.rc was being added to an aux GUI tool's source file list by
get_platform_puzzle_extra_source_files(), which is called for aux GUI
tools as well as for puzzles proper. However, it's not as simple as
just eliminating that call, because on Unix, we _do_ need to add the
same extra source files to GUI dev tools that we do for puzzles,
because gtk.c contains external references to either an array of the
puzzle's icons or an empty array indicating that there aren't any, so
_something_ has to provide that.

So instead, get_platform_puzzle_extra_source_files now takes an extra
argument saying whether the program is a real puzzle or an aux tool;
windows.cmake leaves out puzzles.rc in the latter case, but unix.cmake
puts the icon array in unconditionally.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
There's no reason to put the .rc file into developer tools like
galaxieseditor at all. Its current job is to add an icon, and those
tools don't have any. I'm about to add version information, and they
won't have that either (in particular, no description string like the
games do).

The CLI developer tools already don't include puzzles.rc, and GUI dev
tools are more like those than they are like puzzles.

puzzles.rc was being added to an aux GUI tool's source file list by
get_platform_puzzle_extra_source_files(), which is called for aux GUI
tools as well as for puzzles proper. However, it's not as simple as
just eliminating that call, because on Unix, we _do_ need to add the
same extra source files to GUI dev tools that we do for puzzles,
because gtk.c contains external references to either an array of the
puzzle's icons or an empty array indicating that there aren't any, so
_something_ has to provide that.

So instead, get_platform_puzzle_extra_source_files now takes an extra
argument saying whether the program is a real puzzle or an aux tool;
windows.cmake leaves out puzzles.rc in the latter case, but unix.cmake
puts the icon array in unconditionally.
</pre>
</div>
</content>
</entry>
<entry>
<title>js: Copy-to-clipboard support</title>
<updated>2023-07-05T18:39:57+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-07-05T18:39:57+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=ad7042db989eb525defea9298b2b14d564498473'/>
<id>ad7042db989eb525defea9298b2b14d564498473</id>
<content type='text'>
Now using the browser's "copy" operation while the focus is in the
puzzle will copy the puzzle state to the clipboard.  Browsers seem to
have odd ideas about whate element to target with the "copy" event:
Firefox targets the parent of the &lt;canvas&gt; while Chromium targets the
&lt;body&gt;.  To cope with these and possible future weirdness I attach the
event handler to the document and then look to see if it's plausibly
related to the canvas.

Arguably we might want to handle a wider range of "copy" events, maybe
any where the selection isn't empty.  I'm not sure, though, so we'll
start with the minimal change.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Now using the browser's "copy" operation while the focus is in the
puzzle will copy the puzzle state to the clipboard.  Browsers seem to
have odd ideas about whate element to target with the "copy" event:
Firefox targets the parent of the &lt;canvas&gt; while Chromium targets the
&lt;body&gt;.  To cope with these and possible future weirdness I attach the
event handler to the document and then look to see if it's plausibly
related to the canvas.

Arguably we might want to handle a wider range of "copy" events, maybe
any where the selection isn't empty.  I'm not sure, though, so we'll
start with the minimal change.
</pre>
</div>
</content>
</entry>
<entry>
<title>js: pass preferences file from JS to C on the heap, not the stack</title>
<updated>2023-05-30T15:00:31+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-05-30T14:55:22+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=5acce15ed907d29a5575668a09e7d94cf7a36b3f'/>
<id>5acce15ed907d29a5575668a09e7d94cf7a36b3f</id>
<content type='text'>
The C stack used by Emscripten is quite small, so passing more than a
few klilobytes of data on it tends to cause an overflow.  Current
versions of puzzles will only generate tiny preferences files, but this
might change in future and in any case Puzzles shouldn't crash just
because the preferences in local storage have got corrupted.

To fix this, we now have JavaScript allocate a suitable amount of C heap
memory using malloc() and stick the preferences file in there.

This could plausibly fail if the preferences file were really big, but
that's unlikely since browsers generally limit an origin to about 5 MB
of local storage.  In any case, if malloc() does fail, we'll just ignore
the preferences file, which is probably the right thing to do.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The C stack used by Emscripten is quite small, so passing more than a
few klilobytes of data on it tends to cause an overflow.  Current
versions of puzzles will only generate tiny preferences files, but this
might change in future and in any case Puzzles shouldn't crash just
because the preferences in local storage have got corrupted.

To fix this, we now have JavaScript allocate a suitable amount of C heap
memory using malloc() and stick the preferences file in there.

This could plausibly fail if the preferences file were really big, but
that's unlikely since browsers generally limit an origin to about 5 MB
of local storage.  In any case, if malloc() does fail, we'll just ignore
the preferences file, which is probably the right thing to do.
</pre>
</div>
</content>
</entry>
<entry>
<title>Support user preferences in the Emscripten frontend.</title>
<updated>2023-04-24T09:17:33+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2023-04-24T09:17:33+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=43db4aa38e83595dc6df245cb952795f9f306ed0'/>
<id>43db4aa38e83595dc6df245cb952795f9f306ed0</id>
<content type='text'>
Here, user preferences are stored in localStorage, so that they can
persist when you come back to the same puzzle page later.

localStorage is global across a whole web server, which means we need
to take care to put our uses of it in a namespace reasonably unlikely
to collide with unrelated web pages on the same server. Ben suggested
that a good way to do this would be to store things in localStorage
under keys derived from location.pathname. In this case I've appended
a fragment id "#preferences" to that, so that space alongside it
remains for storing other things we might want in future (such as
serialised saved-game files used as quick-save slots).

When loading preferences, I've chosen to pass the whole serialised
preferences buffer from Javascript to C as a single C string argument
to a callback, rather than reusing the existing system for C to read
the save file a chunk at a time. Partly that's because preferences
data is bounded in size whereas saved games can keep growing; also
it's because the way I'm storing preferences data means it will be a
UTF-8 string, and I didn't fancy trying to figure out byte offsets in
the data on the JS side.

I think at this point I should stop keeping a list in the docs of
which frontends support preferences. Most of the in-tree ones do now,
and that means the remaining interesting frontends are ones I don't
have a full list of. At this moment I guess no out-of-tree frontends
support preferences (unless someone is _very_ quick off the mark), but
as and when that changes, I won't necessarily know, and don't want to
have to keep updating the docs when I find out.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Here, user preferences are stored in localStorage, so that they can
persist when you come back to the same puzzle page later.

localStorage is global across a whole web server, which means we need
to take care to put our uses of it in a namespace reasonably unlikely
to collide with unrelated web pages on the same server. Ben suggested
that a good way to do this would be to store things in localStorage
under keys derived from location.pathname. In this case I've appended
a fragment id "#preferences" to that, so that space alongside it
remains for storing other things we might want in future (such as
serialised saved-game files used as quick-save slots).

When loading preferences, I've chosen to pass the whole serialised
preferences buffer from Javascript to C as a single C string argument
to a callback, rather than reusing the existing system for C to read
the save file a chunk at a time. Partly that's because preferences
data is bounded in size whereas saved games can keep growing; also
it's because the way I'm storing preferences data means it will be a
UTF-8 string, and I didn't fancy trying to figure out byte offsets in
the data on the JS side.

I think at this point I should stop keeping a list in the docs of
which frontends support preferences. Most of the in-tree ones do now,
and that means the remaining interesting frontends are ones I don't
have a full list of. At this moment I guess no out-of-tree frontends
support preferences (unless someone is _very_ quick off the mark), but
as and when that changes, I won't necessarily know, and don't want to
have to keep updating the docs when I find out.
</pre>
</div>
</content>
</entry>
<entry>
<title>js: explicitly tell Emscripten which browsers to target</title>
<updated>2023-04-06T22:05:52+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-04-06T08:58:21+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=d505f08f671c2f0a3fdd0b7d733e4ce987aa4786'/>
<id>d505f08f671c2f0a3fdd0b7d733e4ce987aa4786</id>
<content type='text'>
Emscripten has settings indicating which browser versions it should
build code for.  These are now by default slightly newer than I'd been
targeting with my hand-written JavaScript.  They also don't include
Firefox 48, which KaiOS 2.5 is based on.

This commit adds CMake variables to set the minimum versions that we
pass to Emscripten.  They default to the earliest versions with
WebAssembly support, except that Firefox 48 is also supported.

I think the main consequence of this change is to stop Emscripten using
sign-extension and mutable-globals in WebAssembly, which it's done by
default since version 3.1.26.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Emscripten has settings indicating which browser versions it should
build code for.  These are now by default slightly newer than I'd been
targeting with my hand-written JavaScript.  They also don't include
Firefox 48, which KaiOS 2.5 is based on.

This commit adds CMake variables to set the minimum versions that we
pass to Emscripten.  They default to the earliest versions with
WebAssembly support, except that Firefox 48 is also supported.

I think the main consequence of this change is to stop Emscripten using
sign-extension and mutable-globals in WebAssembly, which it's done by
default since version 3.1.26.
</pre>
</div>
</content>
</entry>
<entry>
<title>js: set -s ENVIRONMENT=web in Emscripten</title>
<updated>2023-04-06T22:05:52+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-04-06T08:23:16+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=b5f87e6175db229e3e84e054ce23a1194cc535e4'/>
<id>b5f87e6175db229e3e84e054ce23a1194cc535e4</id>
<content type='text'>
Puzzles only runs in Web browsers, so there's no need to include
support for Node or (for now at least) running in a Web worker.  This
removes about 5 kiB of code from the boilerplate JavaScript.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Puzzles only runs in Web browsers, so there's no need to include
support for Node or (for now at least) running in a Web worker.  This
removes about 5 kiB of code from the boilerplate JavaScript.
</pre>
</div>
</content>
</entry>
<entry>
<title>KaiOS: include extra copyright notices in manual</title>
<updated>2023-04-05T23:21:43+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-04-05T23:00:07+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=7a66855947c043e502d00fa41cd7b7c06127adf9'/>
<id>7a66855947c043e502d00fa41cd7b7c06127adf9</id>
<content type='text'>
The KaiOS build includes compiled versions of various Emscripten library
files.  These are generally under the MIT licence like Puzzles itself.
The MIT licence requires that the licence, and the copyright notice, be
"included in all copies or substantial portions of the Software."

Since each KaiOS package includes the full manual, which already
contains the licence for Puzzles itself, adding the copyright notices
there seems like the best approach.  I've done this by providing an
additional input file that contains the licences for source files used
by a current Emscripten build.  More automation might be nice, but the
set of copyright notices is unlikely to change very much.  There are
basically one for Emscripten, one for musl, and a few for odd bits of
third-party code embedded in musl.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The KaiOS build includes compiled versions of various Emscripten library
files.  These are generally under the MIT licence like Puzzles itself.
The MIT licence requires that the licence, and the copyright notice, be
"included in all copies or substantial portions of the Software."

Since each KaiOS package includes the full manual, which already
contains the licence for Puzzles itself, adding the copyright notices
there seems like the best approach.  I've done this by providing an
additional input file that contains the licences for source files used
by a current Emscripten build.  More automation might be nice, but the
set of copyright notices is unlikely to change very much.  There are
basically one for Emscripten, one for musl, and a few for odd bits of
third-party code embedded in musl.
</pre>
</div>
</content>
</entry>
</feed>
