My webasm updates, gdc in D
Posted 2021-10-18
Blog
Articles- arsd 10.5 coming this week, new midi code, a FF1 nsf player/editor application
- December 27, 2021
- my thoughts on std.socket design
- arsd work in progress updates and new "do it in D" idioms section
- December 6, 2021
- gdc sync going upstream, arsd 10.4 released, otherwise i was busy.
- working toward arsd 10.4
- DConf Online 2021 livestream
- arsd.webview work, public imports in adrdox changed
- importC released, preview of arsd web, database, gui updates, phobos2 coming, dual context tip of the week
- October 25, 2021
- My webasm updates, gdc in D
- Assorted quick thoughts
- October 4, 2021
- arsd 10.3, dmd -target, druntime.dll
- A potential GC puzzler discovered
- nanovega font improvement from me. from community: DConf Online 2021 announcement, GtkD blog back to work, DCompute update
- Rant: using Firefox is meaningless
- August 30, 2021
- Improving today's error handling
- Thoughts on error handling
- August 9, 2021
- August 2, 2021
- arsd.qrcode introduced and on my wish list: __arguments.
- July 19, 2021
- Drama on the github
- arsd 10.2 with http cookies support
- June 28, 2021
- arsd 10.1, thought on virtual functions, community announces light weight Druntime 0.3 among others
- arsd v10 tagged
- New dmd and ldc releases, ldc with druntime.dll!
- gdc 11 out with a lot of D updates
- May 24, 2021 general update
- Progress continues toward minigui 2.0
- C compiler in dmd? new string type in Phobos? brief update on my minigui overhaul
- Simpledisplay additions, minigui event changes
- April 26, 2021
- arsd 9.5 -- UPDATE: false alarm i forgot to tag it!
- April 12, 2021
- arsd 9.4 tagged, adrdox 2.5 released
- Tip of the week: using C libs from D
- working on gdc on Windows
- tip: use union to manually control struct member destructor
- Rant: people in the past weren't stupid
- Tip on DIY closures
- arsd 9.2
- Did you know about D anonymous classes?
- "Mental friction": my view on why D rox
- String interpolation DIP prototype
- terminal inline syntax highlighting, sdpy fonts improved
- January 18, 2021
- gdb debugging tips
- A little work on sdpy/terminal interop and apng debugging
- New plain tcp fiber socket class (with "how it works" docs), new arsd docs started, new dub subpackages in arsd. Also Turkish newsgroups added to forum.dlang.org
- Little audio player in D
- Thoughts on tutorial writing benefits, D marketing, and some simpledisplay.d improvements.
- arsd 9.0 rollup release, my thoughts on "google it" culture and related practices
- dpldocs.info cross-package search finally released! and more terminal getline enhancements
- I did a dconf livestream!
- New selective mouse input in terminal stack, Xft used in simpledisplay to improve TrueType font support
- simpleaudio now has playOgg, Mp3, Wav with resampling and can access multiple soundcards on Linux, adrdox gets ddoc on function params
- Weekend experiment: declarative GUI in D
- October 26, 2020
- My DConf livestream sneak preview
- Off topic jrpg video game review
- My thoughts on breakage, and I'll be in DConf Online 2020
- cgi.d hybrid server basically working, terminal.d can redirect stdout to a window if requested
- Some talk on cgi.d in benchmarks
- September 14, 2020
- New D update "dwidder" website launched, making-of post here
- white noise app in D
- More modern opengl in simpledisplay, document undocumented on dpldocs.info, tip on default template args
- Xlib taskbar in D
- D Tetris running on Webassembly
- Tetris in D
- Zero-runtime classes
- DConf online in the works for Nov 21-22, image copy/paste coming to sdpy soon
- July 13, 2020
- July 6, 2020
- simpledisplay getting dynamic loads, terminal gui gracefully degrades, i muse on scope raii classes
- Adam's dynamic link transition
- June 15, 2020
- June 8, 2020
- June 1, 2020
- foot pedal and midi fun, some dmd speed enhancements. Forum argues about @safe by default on extern.
- May 18, 2020
- simpleaudio dev work, rasp pi gpio module, static foreach rant, gcc 10's D support upped
- May 4, 2020
- my http more compatible with ssl, script+jsvar can do subclasses of D objects
- i want to make a jrpg, and have eye damage.
- Dustmite post on official blog
- What if I were dictator?
- March 30, 2020
- terminal.d with built-in emulator option releaed
- Online DConf in the works
- Dconf 2020 cancelled, Adam plays with terminal gui integration
- March 2, 2020
- some adrdox/dpldocsinfo updates
- terminal.d gets clipboard functions, ldc 1.20 out.
- DConf keynote speaker announced: Lua architect Roberto Ierusalimschy, Named args DIP discussed
- February 3, 2020
- Adam's terminal suite explained
- Understanding mixin templates, terminal.d improvements
- My attribute-by-default proposal. Also dmd 2.090 came out.
- DConf 2020 announced: June 17-20 in London. @safe by default debated. Adam did: Android, JNI, WebSocket in arsd libs
- tar.xz, --DRT tip, dom bug fixes, more Android and JNI, link to old phobos docs
- LDC 1.19 - Android, AVR. My rant on tests, update on JNI and COM.
- Walter's string interpolation proposal is OK but not great. My Android thing nearing beta release. dub downtime explained.
- Android project update, introduction to arsd.jni
- New pattern about interface contracts
- Adam shares Windows console secrets - DO NOT USE chcp!!
- Adam's rant on benchmarks
- Socket tutorial
- November 4, 2019
- October 28, 2019
- arsd package updates, forum nonsense
- Update on Android also with mtriple appendix
- Adam does iOS "goodbye world"
- September 30, 2019
- D turns 20, Adam rants on software freedom
- Named arg DIPs and my thoughts on code organization
- September 9, 2019
- I wrote about mixin templates vs string mixins on Stack Overflow
- August 26, 2019
- Bug bounty in D again - my hot take, on reusing code, a fun picture, my tentative plan for the next month
- Time invested is worth a lot
- cgi.d's new scheduler, static this tricks
- July 29, 2019
- July 22, 2019
- Solving vs managing problems
- A big week in the arsd repo
- July 1, 2019
- June 24, 2019
- June 17, 2019
- CRTP thoughts, named arguments DIP review, DConf videos now on youtube
- musings on hybrid CT/RT tests, some more progress on new web framework
- a little more webassembly
- May 20, 2019
- Adam's string interpolation proposal
- DMD 2.086 live, GCC 9 with D support formally released, DConf coming soon, links to posts on builder pattern and disallowing implicit conversions with templates, and 2d array op overloads
- template constraint error improvements coming?
- dmd 2.086 beta, dstep 1.0 released, Adam works on memory usage
- obj-c and webassembly report, tips on is expressions linked.
- new ldc, new dmd, dpp on the blog
- D's future discussed in forums
- LDC beta, DConf blog link, Adam introduces gamehelpers.d
- March 18, 2019
- LDC 1.15.0-beta1, responsive design rant
- dmd 2.085.0 released
- Obj-C interop and D without druntime code to copy/paste
- dmd beta, more info coming next time, demo of new web framework initial prototype
- automatic web interface discussion, reflection tips and tricks
- Adam busy with weather and a move, lots of community announcements
- January 28, 2019
- Working on official blog 2018 retro, C++ new wrapped, dmd reading zips?
- dmd obj-c growing, Adam static foreaches an interface to RPC
- dmd 2.084, hope for future, but busy non-D week for me
- IDE tools released, my cgi.d gets new features
- DConf announced, tip, Adam rants: mouse trap
- This Week in D is back!
I wrote a malloc and free finally! Some talk on assumeSafeAppend and webasm drawing.
Core D Development Statistics
In the community
Community announcements
See more at the announce forum.
GDC using new frontend
If you want to build a branch yourself, gdc using newer dmd code is available in Iain's branch now. I got a report from a user that s/he was able to build it without difficulty and it worked well for their special purpose (running on esoteric hardware).
My custom webassembly update
GC rox but
I haven't done much on webassembly since last dconf and with the next one coming up again soon, I wanted to refresh myself on it and maybe even make a garbage collector.
I've argued previously that druntime's standard GC should just work in webassembly. I am now fairly certain that I was wrong about that. The standard GC can read the webassembly memory space, but it cannot read webassembly parameters as that stack is hidden from the application.
It might be possible with compiler support; some llvm intrinsics related to GC and maybe it could make a shadow stack or something that can be scanned. I don't know enough to say that for sure.
But this means the druntime webasm port is going to need more work to figure out, probably with some level of compiler support (same with exceptions and even blocking calls btw, llvm has intrinsics to help with exceptions that might work and blocking calls actually need stop+resume points too).
And for my part, with my minimal webasm runtime and special library ports, I don't think I will bother writing a GC for it anymore. Instead, I'll probably just do a basic mallocator with free.
Realistically, lightweight webassembly is a different enough target from Windows and Linux that programs are likely to need some kind of adaptation anyway. This can be kinda minimal depending on the kind of program - like async event loops tend to basically work just because the code is already written that way - but there might be other things necessary too like version blocks with alternate implementations. That's the price of keeping things light; you don't want to emulate everything since that costs code - sometimes a lot of code - elsewhere.
Now that I have a custom runtime and am open to custom code versioning in, this gives me some options I wouldn't normally condone, like doing some manual frees, assumeSafeAppend or similar to optimize the ~= operator, or even replacing the global allocator with an autorelease pool at times. I can either version these out or make them harmless no-ops in real D to maintain most the compatibility with other builds.
Or, of course, I can always just leak memory. Seriously, that might be acceptable in certain situations. And there's other pooling strategies that are harmless to beneficial in other scenarios too, I just don't often do them because it it is extra work that isn't really necessary normally. But there's a variety of available options.
What I added so far
First, I had to actually implement a malloc that was more than push-the-pointer nonsense. It needs to actually support free, extend, and alignment (javascript data view objects need the data to be aligned! i kept getting a "index X is out of bounds" when trying to construct a Float64Array and it baffled me for a while until I realized the address wasn't a multiple of 8. so yeah, gotta align these things). I've never actually done that before!
Of course, I could probably just bring in one of the many higher quality malloc implementations out there. But where's the fun in that?! And besides, they're all kinda big and part of the reason for me doing this all myself is I want to keep the webassembly distribution small.
In my info block, I put in a blockSize and used fields. This allowed me to implement druntime's assumeSafeAppend function, and druntime's reasonably good append operator, all with the built-in array syntax, just like the real thing. (Doing this in a user-defined type is easy enough regardless, that's what you'd typically do in betterC and thanks to operator overloads it is pretty nice.
But here, I want to take the code I already wrote that uses the append operator on build in arrays and use it. I'm trying to minimize the code changes in the actual program. Using things like reserve and assumeSafeAppend is often a good idea in the normal D implementation too and now my mini webasm runtime can do all these reasonably efficiently too... whereas before I could use them but it just leaked memory and wasted a lot of time moving around.
However, now that I no longer think writing a webasm GC is actually doable at this time, I have to open myself to some small source edits. I could just call free(arr.ptr); as needed, but when everything else is managed by ~= it seemed a bit annoying to have to keep the old pointer, compare and free outside.
Instead, I added a new function arr.assumeUniqueReference which sets a flag in the memory block. When you do that and it reallocates, it outright frees the old pointer instead of leaving it behind for the GC to verify it is safe to free. In real D, I can either simply version this out, or have a no-op function you can call but it doesn't necessarily do anything.
I'm tempted to do some kind of reference count option for delegates too. It could stick that right in the memory block too and again just version or stub those out for real D. The scary thing here would be if you call addRef on something that the compiler did NOT allocate a closure for... what does it do then? I don't know yet. I'll probably just go with a call to free. The LWDR - lightweight D runtime - project in the works right now for embedded ARM situations does that too. (In fact, LWDR used my webasm runtime as it was a few months ago as a starting point.) I'm helping the author and we share some ideas, though the two projects are not quite interchangeable due to the different targets. (Like he probably WILL do a GC of some sort.)
In other webasm news
I also optimized the port of simpledisplay's ScreenPainter to webassembly. The old one leaned on my eval function which, well, evals a string in Javascript. This is very slow. I optimized it a little to cache results and it made a difference (though I kinda wish I took strings only at compile time in it instead of a runtime string. I might change that, since if they are all compile time it makes building a list of them and indexing the cache a lot easier), but I wanted to try something else too.
I ended up making it into a little stack machine that builds up info in a reused array, then does a single call across the Javascript bridge to execute it.
The result I saw so far:
I also want to try a smarter cache since I really do like that code style - each D module can define its own JS bridge as-needed - and I also want to try ditching my silly bytecode function and just calling JS imports directly and see what happens. Preparing arbitrary JS imports is a pain but I could always do something else about that in the build (my webasm server here just recompiles as needed when it serves so I don't even run the make anyway).
None of these results are very good though. The test program is a simple line animation, this should be like 0.3% cpu. It isn't just the bridge's fault though; firefox's canvas seems to not be especially well implemented anyway.
But meh it is good enough for what little I do with this. I still don't find webasm all that useful anyway lol.
anyway, it is coming together to be reasonably useful. Hopefully by Nov 20, when I'm on DConf Online again doing another livestream, I'll fix enough of this to make finishing the programs nice and easy. I'd rather demo minigui on that stream if I have time anyway!