When trying to grab the window pointer off the notification in a
windowDidBecomeKey implementation, I kept getting segfaults calling
notification->object(). The second argument of these needs to be a SEL.
https://developer.apple.com/documentation/objectivec/class_addmethod(_:_:_:_:)?language=objc#Discussion
I imagine existing code is getting by by setting the window information
in the delegate's context userdata, which works fine when you only have
one window as you can avoid needing to call notification->object(),
until you want one delegate assigned to two windows, hard to work around.
Fixes#5151
- Removes `SHARED_VALIDATE` from the enum and turns it into `Map_Shared_Validate :: Map_Flags{.SHARED, .PRIVATE}` so it has the proper value of 0x03.
- Adds `DROPPABLE`.
- Adds constants `MAP_HUGE_SHIFT` and `MAP_HUGE_MASK`.
- Adds the huge page precomputed constants from `mman.h`, defined as the log2 of the size shifted left by `MAP_HUGE_SHIFT`:
Map_Huge_16KB
Map_Huge_64KB
Map_Huge_512KB
Map_Huge_1MB
Map_Huge_2MB
Map_Huge_8MB
Map_Huge_16MB
Map_Huge_32MB
Map_Huge_256MB
Map_Huge_512MB
Map_Huge_1GB
Map_Huge_2GB
Map_Huge_16GB
There were multiple issues here:
1. listeners stored in the same key overwriting the previous one
2. missing `use_capture` parameter in `remove_event_listener`/`remove_window_event_listener`
The key used to store the listener function in `listenerMap` was a
javascript `Object`, when used as a key it was thus serialized to
the string `"[object Object]"`, meaning all listeners where effectively
set to the same key when calling `add_event_listener`/`add_window_event_listener`.
Later on when calling `remove_event_listener`/`remove_window_event_listener`,
it then tried to remove the incorrect one or none at all if there was a
mix of the same event name registered on an element or the window.
To fix I implemented a function `listener_key` in the javascript code
which will generate a different key based on the event's:
- `id`: dom element's id or 'window' (when event listener added to the
window)
- `name`: the event name (eg: `click`), each event handler should be
removed for the event name it was register on.
- `data`: we can register events with different data, each one generate
a new listener which has to be removed.
- `callback`: same as `data`, if you register two similar handler but
with two different callback, each one should be removed.
- `useCapture`: this one is a bit tricky, but when you register an event
handler in javascript, if you don't pass `useCapture`, it defaults to `false`.
When you remove an handler, you have to pass the exact same
`useCapture` option you registered it with. In this case, we allowed
to register an event with different `useCapture`, but didn't allow to
pass the `useCapture` when removing it. We always called `removeEventListener`
without the `useCapture` parameter which removed the handler properly
only when it was registered with `useCapture=false`.
I also switched the `WasmMemoryInterface.listenerMap` from `{}`
(javascript object) to a `new Map()`, which is available everywhere
nowadays.