Saturday, December 12, 2009
Sunday, December 6, 2009
Also patched was an annoying little warning in "vm/salsa.c" related to an implicit pointer cast, and the process loop now performs a 100 microsecond sleep when all processes are polling. (Previously, this was handled by the OS process, which doesn't correctly handle the possibility of more than one process polling for external events.)
Friday, December 26, 2008
A new release will be uploaded, today, 0.4.1, with some minor bugfixes and a simple terminal abstraction library, "lib/scud." This library supports cursor relocation, changing terminal colors, and clearing the screen on both VT100-capable terminals and Windows. Also, a new primitive has been added, "unbuffer-console", which puts the Windows and UNIX standard input into a raw, unbuffered mode. This makes it possible to capture individual keypresses by the user without waiting for linebreaks.
Why the fuss with terminals? Because I have been working on a lot of console mode applications, and this module gives me the bare minimum while supporting both Windows and UNIX platforms. There is still a lot of planning and work ongoing with 0.5, but not much of it is suitable for release, yet.
Thursday, September 18, 2008
Work will begin soon on Wasp 0.5, which consist of more primitive namespace cleanup, bug fixes and, hopefully, WaspDoc.
Tuesday, September 2, 2008
- FlexDLL -- Emulates UNIX dlopen on Win32.
- EDLL -- Reimplements the dynamic linker for Windows; also catalogues common workarounds for the DLL plugin paradox.
- DLL Creation in MinGW -- A succinct tutorial on LoadLibrary / GetProcAddress.
- The University of Colorado MinGW FAQ -- Contains a nice list of common MinGW gotchas.
- The Program Library HOWTO -- More about how to design libraries on UNIX systems than Win32, but discusses those techniques thoroughly.
- Wikipedia: Dynamic Loading -- Contains an interesting technique for DLLs to access the original process's symbols.
- Dynamic Linking in Linux and Windows, part two -- More in-depth discussion of DLLs and their limitations.
- Permits a plugin subsystem to call routines in the virtual machine. (Blocks naked use of DLLs and LoadLibrary / GetProcAddress.)
- Shares data structures in the virtual machine process with all plugins.
- Does not bloat the virtual machine.
- Does not require special effort by plugin authors. (Disqualifying passing a structure of API function pointers to the plugin.)
- Does not tightly couple the plugin to the binary. (Disqualifying various --output-implib tricks.)
- Does not excessively complicate the build process. (Disqualifying LibTool.)
Monday, September 1, 2008
Sunday, August 17, 2008
Wednesday, August 13, 2008
;;; -- SNIP -- ;;; "in" is an input channel, waiting on it causes a process to block. ;;; "out" is an output channel, which connects to the next coroutine. (define buf (make-string)) (define (wait-for-any) (forever (define evt (wait in)) (when (string? evt) (string-append! buf evt) (return)) (send evt out))) (define (wait-for-field len) (while (< (string-length buf) len) (wait-for-any)) (string-read! buf len)) (define (wait-for-int) (string->quad (wait-for-field 4)))Wait-for-int causes the process to idle until it has four bytes in the buffer, then permits the process to continue. If a process got 30 bytes at once, then it would be able to read 7 integers successively without having to idle at all, then would need to idle for at least 2 more bytes. Also visible, above, is some logic forwarding any status messages outwards; that is a common idiom found in filters -- if they can't handle the event, they assume that something further along in the chain would. A filter is a process that consumes data from an input and yields results to an output, acting very much like a coroutine. Since they can be composed into chains, Wasp can make many tricky data flows easy to express and understand. For example, MOSREF's outbound cryptography chain:
;;; -- SNIP -- (input-chain recv (decrypt-filter recv-decrypt) (check-collation-filter) (check-checksum-filter crc32))The first argument is the input that the next filter will wait on; each subsequent form spawns a new coroutine, supplying them with the supplied arguments for initialization. The result is a new input that provides a decrypted and carefully groomed sequence of messages from another MOSREF node. It's almost embarassing how simple that looks, like much of MOSREF's code. Much of my effort has been invested in Wasp Lisp for complicated I/O applications.