Custom Search
|
Date: December 31, 2006
From: Brent Fulgham <bfulg@xxxxxxxxxxx>
In-reply-to:
<20061231124409.L11509@xxxxxxxxxxx>
References:
<20061231124409.L11509@xxxxxxxxxxx>
On Dec 31, 2006, at 11:58 AM, Gary Byers wrote: > There are new (061231) snapshot archives in <ftp://clozure.com/pub/ > testing>. > > OpenMCL 1.1-pre-061231 > - The FASL version changed (old FASL files won't work with this > lisp version), as did the version information which tries to > keep the kernel in sync with heap images. The update works great for me. The various graphic tests for the "Open Agent Engine" all build and work just fine. Thanks, -Brent
Date: December 31, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
There are new (061231) snapshot archives in <ftp://clozure.com/pub/testing>. OpenMCL 1.1-pre-061231 - The FASL version changed (old FASL files won't work with this lisp version), as did the version information which tries to keep the kernel in sync with heap images. The binary incompatibility has to do with how a few pages of low memory in the lisp kernel's address space are mapped and used. OpenMCL was generally assuming that these pages were otherwise unused and could be used to map a small static data area from the heap image file; on some platforms, the dynamic linker may have already allocated data in those unused pages before the lisp kernel even starts to run. Fixing this involved changing the address of that small static data area slightly, and this caused the addresses of some objects contained within that static data area - notably NIL - to change, as well. - This snapshot is otherwise just a set of bug fixes/work-in-progress changes. - Even though no supported filesystem actually supports versioned files, OpenMCL now tries to retain PATHNAME-VERSION informaton for physical pathnames. (The fact that it didn't caused several ANSI test failures.) This change introduced/exposed a few other bugs; I think that I've caught at least the most obvious ones, but it's possible that some new pathname-related bugs have been introduced. - The cron job that runs on clozure.com and updates the ChangeLog from CVS commit info stopped running as of a system upgrade in late November. The problem was fixed a couple of weeks ago, so it's once again meaningful to refer to the ChangeLog for details of bug fixes. - FSQRT and FSQRTS instructions are "optional" on the PPC. In practice, that often meant that they are implemented on chips made by IBM and not on chips made by Motorola/FreeScale. This version of OpenMCL assumes that they're implemented and emulates them if they aren't. - OSX 10.2 (Jaguar) and earlier versions are officially no longer supported. I honestly don't know if things have actually worked on Jaguar in a while, but some recent changes are known not to work on Jaguar and the kernel now inists on at least Panther on startup.
Date: December 30, 2006
From: Phil <pbpublist@xxxxxxxxxxx>
In-reply-to:
<20061229001858.J11509@xxxxxxxxxxx>
References:
<69891860-715E-4903-BB4E-D19C544D8F8A@xxxxxxxxxxx> <20061101004307.E20390@xxxxxxxxxxx> <68DFB388-C312-4A1F-8857-FC12AF6173DA@xxxxxxxxxxx> <20061229001858.J11509@xxxxxxxxxxx>
That's great news and I've got a system waiting here for testing purposes whenever the snapshot is ready. Also, per our last exchange, I have an open request in with developer relations but have yet to get a response (not holding my breath, but it can't hurt to ask) On Dec 29, 2006, at 2:47 AM, Gary Byers wrote: > The good news is that I'm getting close to having a releasable > interface > translator that can handle ObjC 2.x syntax. (I stopped whining and > merged > a couple of gcc branches together.) > > The bad news is that I just discovered that the Darwin ppc64 port > seems to have trouble loading shared libraries under ... post-Tiger > systems. The ultimate reason for this has to do with the lisp > expecting some low-memory pages that contain things like NIL being > unused until the lisp kernel maps them in from the heap image; there's > never been any guarantee that the dynamic linker wouldn't decide to > use those pages for its own evil purposes, and if the lisp steps on > some dynamic linker data it's not too surprising that loading shared > libraries or trying to resolve symbols in those libraries starts to > fail. The dynamic linker seems glad to map its data elsewhere under > Tiger and earlier, but that's probably just been blind luck. > > The workaround for this involves being more explicit about needing the > memory pages in question. For arcane reasons, it'll also involve > changing the address of NIL (which is assumed to be a constant) and > that in turn will involve some bootstrapping/chaos. I'll have to look > more carefully at the ppc32 and x86-64 Darwin ports: they seem to be > lucking out (the pages that they assume are free are indeed free), but > so was the ppc64 until fairly recently. It might be wise to make a > similar change to the ppc32 & x86-64 ports as well, rather than trust > that their luck will hold. > > So: > - total chaos in CVS for a day or two until all hosts/targets agree > on where NIL is > - new snapshots soon after > - interface translator is a separate/orthogonal issue, but I can > probably put together a set of patches relative to Apple's > GCC-5363 (sources to which are available on an Apple website.) > This would probably only be of interest to people with access > to Leopard via ADC; it'd be of even more interest to those people > if OpenMCL could reliably load and use shared libraries on > platforms of interest. >
Date: December 29, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
In-reply-to:
<68DFB388-C312-4A1F-8857-FC12AF6173DA@xxxxxxxxxxx>
References:
<69891860-715E-4903-BB4E-D19C544D8F8A@xxxxxxxxxxx> <20061101004307.E20390@xxxxxxxxxxx> <68DFB388-C312-4A1F-8857-FC12AF6173DA@xxxxxxxxxxx>
The good news is that I'm getting close to having a releasable interface translator that can handle ObjC 2.x syntax. (I stopped whining and merged a couple of gcc branches together.) The bad news is that I just discovered that the Darwin ppc64 port seems to have trouble loading shared libraries under ... post-Tiger systems. The ultimate reason for this has to do with the lisp expecting some low-memory pages that contain things like NIL being unused until the lisp kernel maps them in from the heap image; there's never been any guarantee that the dynamic linker wouldn't decide to use those pages for its own evil purposes, and if the lisp steps on some dynamic linker data it's not too surprising that loading shared libraries or trying to resolve symbols in those libraries starts to fail. The dynamic linker seems glad to map its data elsewhere under Tiger and earlier, but that's probably just been blind luck. The workaround for this involves being more explicit about needing the memory pages in question. For arcane reasons, it'll also involve changing the address of NIL (which is assumed to be a constant) and that in turn will involve some bootstrapping/chaos. I'll have to look more carefully at the ppc32 and x86-64 Darwin ports: they seem to be lucking out (the pages that they assume are free are indeed free), but so was the ppc64 until fairly recently. It might be wise to make a similar change to the ppc32 & x86-64 ports as well, rather than trust that their luck will hold. So: - total chaos in CVS for a day or two until all hosts/targets agree on where NIL is - new snapshots soon after - interface translator is a separate/orthogonal issue, but I can probably put together a set of patches relative to Apple's GCC-5363 (sources to which are available on an Apple website.) This would probably only be of interest to people with access to Leopard via ADC; it'd be of even more interest to those people if OpenMCL could reliably load and use shared libraries on platforms of interest. On Thu, 21 Dec 2006, Phil wrote: > It's been a while since anything was stated on the topic of Leopard > testing. So just checking in to see if things are nearing a point > where said testing would be worthwhile? > > Thanks, > Phil > > On Nov 1, 2006, at 3:00 AM, Gary Byers wrote: > >> >> That support (for both ppc64 and x86-64) is an announced feature of >> Leopard. >> >> (I have, coincidentally, been working on this lately. If/when things >> reach some level of usability, it'd be good if there was some way of >> (a) making Leopard .cdb files available to Leopard beta testers and >> (b) doing (a) in a way that doesn't violate the letter/spirit of >> applicable NDAs.) > > _______________________________________________ > Openmcl-devel mailing list > Openmcl-devel@xxxxxxxxxxx > http://clozure.com/mailman/listinfo/openmcl-devel > >
Date: December 29, 2006
From: Brent Fulgham <bfulg@xxxxxxxxxxx>
Just a quick note to the list to say that the OpenMCL "Open Agent Engine" port mostly works. You can take a look at http:// lwat.blogspot.com/. If you want to try the (buggy) code, you can grab the 15 MB tarball from http://www.debian.org/~bfulgham/Open_Agent_Engine_OpenMCL.tar.bz2. Thanks, -Brent
Date: December 29, 2006
From: Brent Fulgham <bfulg@xxxxxxxxxxx>
In-reply-to:
<20061228181502.I11509@xxxxxxxxxxx>
References:
<20061229011121.53336.qmail@xxxxxxxxxxxxxxxxxxxxxxxxxxx> <20061228181502.I11509@xxxxxxxxxxx>
Thanks, Gary. As usual, this solved the problem. Thanks also for the _CFURLCreateWithFileSystemPath stuff made it possible to use normal Unix pathing, which was a huge help for loading the textures. Thanks! -Brent On Dec 28, 2006, at 5:59 PM, Gary Byers wrote: > A handle (in the Classic MacOS memory manager) is basically a pointer > to a pointer. If H is a handle, then: > > (rlet ((p (%get-ptr h))) > ;; "p" probably points to something interesting ... > ) > > It wasn't always that simple: the address obtained by indirecting > through a handle could change over time (though the "master pointer" - > the handle itself - remained at a constant address). It was possible > to lock and unlock a handle (via #_HLock/#_HUnLock; I hope that I'm > capitalizing those names correctly) to keep things from moving while > you were accessing. > > Some handles denoted the in-core contents of "resources", which > were loaded from files. When memory got really tight, resource-based > handles could be "purged" from memory, so dereferencing such a handle > without first un-purging it (I forget how ...) yielded a null pointer. > > Having purgeable/relocatable blocks of memory helped early Mac > applications to run in small address spaces, but didn't scale > particularly well. The only reasons that I can think of for > handles to continue to exist involve backward-compatibility; #_HLock > and #_HUnLock are no-ops on OSX, and a "handle" is just something > that involves an extra level of indirection for no obvious reason. > > If a function returns a handle by reference, that means that the > caller reserves space for a handle somewhere and passes a pointer > to that space to that function. RLET ((<var> <type>)) reserves some > space for (generally uninitialized) instance of <type>, and binds > <var> to a pointer to that reserved space. So: > > > (rlet (.... > (&ImageDescriptor :<I>mage<D>escription)) > > allocates an (uninitialized) ImageDescription handle and binds > &ImageDescriptor to a pointer to that 4 or 8 bytes of garbage. > > (If we were to do (PREF &ImageDescriptor :<I>mage<D>escription) > at this point, we'd get some random bits instead of a real handle; > if we'd said RLETZ instead of RLET, those bits would be 0.) > > > If we then do : > > (let ((err (#_GraphicsImportGetImageDescription &gi > &ImageDescriptor))) > (unless (= err #$noErr) > (error "GraphicsImportGetImageDescription ~a" err))) > > and don't get an error, we'd be able to say: > > (let* ((descriptor-handle (PREF > &ImageDescriptor :<I>mage<D>escription))) > > and the value accessed by PREF should be a "real" handle. > > (let* ((descriptor-pointer (%get-ptr descriptor-handle))) > > If we cared about Classic MacOS compatibility, we would have locked > the handle before dereferencing it. > > (let ((Width (pref descriptor-pointer :<I>mage<D>escription.width)) > (Height (pref descriptor-pointer :<I>mage<D>escription.height)) > (Depth (pref descriptor-pointer :<I>mage<D>escription.depth)) > > should give meaningful values. > > The documentation for #_GraphicsImportGetImageDescription should > probably tell you whether or not it's necessary to dispose of the > handle when you're done with it. Disposing of the handle will > make the memory that it (indirecly) pointed to free as well as > freeing the handle itself. > > > On Thu, 28 Dec 2006, Brent Fulgham wrote: > >> I'm attempting to call a QuickTime API function, which expects to >> be passed a >> >> First call is to a function to get the graphics importer. >> OSErr GetGraphicsImporterForFile ( >> const FSSpec *theFile, >> ComponentInstance *gi ); >> This call is done in Lisp as: >> >> (rlet ((&gi :<G>raphics<I>mport<C>omponent) >> (Fsspec :<FSS>pec) >> (Fsref :<FSR>ef) >> (&ImageDescriptor :<I>mage<D>escription) >> ... Get a FSRef from a CURL-based path (per Gary's earlier >> instructions).... >> >> (let ((err (#_GetGraphicsImporterForFile Fsspec &gi))) >> (unless (= err #$noErr) >> (error "GetGraphicsImporterForFile ~a" err))) >> >> This works great, returns no error, and produces a &gi value that >> can be used further in the routine. >> >> Later (with the enclosing rlet above) I wish to get the graphics >> description of my image file, using the API call: >> ComponentResult GraphicsImportGetImageDescription ( >> GraphicsImportComponent ci, >> ImageDescriptionHandle *desc ); >> >> In this case, the component instance is supposed to be the actual >> GraphicsImportComponent object >> (whereas the earlier call used a pointer to a >> <C>omponent<I>nstance). The FFI seems to handle this >> properly, or at least returns a <G>raphics<I>mport<C>omponent >> object that I can pass to the above >> function without API complaints. >> >> However, I wish to get an <I>mage<D>escription from the >> ImageDescriptionHandle*, which is effectively >> a "ImageDescriptionHandle**". >> >> This looks like the following (still inside the above rlet, so the >> stuff is in scope): >> >> (let ((err (#_GraphicsImportGetImageDescription &gi >> &ImageDescriptor))) >> (unless (= err #$noErr) >> (error "GraphicsImportGetImageDescription ~a" err))) >> >> This seems to work, but produces incorrect results. If I attempt >> to extract values from the ImageDescriptor: >> >> (let ((Width (rref &ImageDescriptor :<I>mage<D>escription.width)) >> (Height (rref &ImageDescriptor :<I>mage<D>escription.height)) >> (Depth (rref &ImageDescriptor :<I>mage<D>escription.depth)) >> ... >> >> I get very strange values. >> >> I think my problem has to do with the pointer-to-pointer >> dereferencing, but I'm not sure how to express this using the >> OpenMCL FFI. >> >> I could do something like: >> (let ((id-ptr (%get-ptr &ImageDescriptor))) >> (let ((err (#_GraphicsImportGetImageDescription &gi id-ptr))) >> (unless (= err #$noErr) >> (error "GraphicsImportGetImageDescription ~a" err))) >> >> ... But trying this also gives me weird values. >> >> Can anyone help me figure out how to pass these FFI values? >> >> Thanks, >> >> -Brent >> >> >> >>
Date: December 29, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
In-reply-to:
<20061229011121.53336.qmail@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
References:
<20061229011121.53336.qmail@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
A handle (in the Classic MacOS memory manager) is basically a pointer
to a pointer. If H is a handle, then:
(rlet ((p (%get-ptr h)))
;; "p" probably points to something interesting ...
)
It wasn't always that simple: the address obtained by indirecting
through a handle could change over time (though the "master pointer" -
the handle itself - remained at a constant address). It was possible
to lock and unlock a handle (via #_HLock/#_HUnLock; I hope that I'm
capitalizing those names correctly) to keep things from moving while
you were accessing.
Some handles denoted the in-core contents of "resources", which
were loaded from files. When memory got really tight, resource-based
handles could be "purged" from memory, so dereferencing such a handle
without first un-purging it (I forget how ...) yielded a null pointer.
Having purgeable/relocatable blocks of memory helped early Mac
applications to run in small address spaces, but didn't scale
particularly well. The only reasons that I can think of for
handles to continue to exist involve backward-compatibility; #_HLock
and #_HUnLock are no-ops on OSX, and a "handle" is just something
that involves an extra level of indirection for no obvious reason.
If a function returns a handle by reference, that means that the
caller reserves space for a handle somewhere and passes a pointer
to that space to that function. RLET ((<var> <type>)) reserves some
space for (generally uninitialized) instance of <type>, and binds
<var> to a pointer to that reserved space. So:
(rlet (....
(&ImageDescriptor :<I>mage<D>escription))
allocates an (uninitialized) ImageDescription handle and binds
&ImageDescriptor to a pointer to that 4 or 8 bytes of garbage.
(If we were to do (PREF &ImageDescriptor :<I>mage<D>escription)
at this point, we'd get some random bits instead of a real handle;
if we'd said RLETZ instead of RLET, those bits would be 0.)
If we then do :
(let ((err (#_GraphicsImportGetImageDescription &gi &ImageDescriptor)))
(unless (= err #$noErr)
(error "GraphicsImportGetImageDescription ~a" err)))
and don't get an error, we'd be able to say:
(let* ((descriptor-handle (PREF &ImageDescriptor :<I>mage<D>escription)))
and the value accessed by PREF should be a "real" handle.
(let* ((descriptor-pointer (%get-ptr descriptor-handle)))
If we cared about Classic MacOS compatibility, we would have locked
the handle before dereferencing it.
(let ((Width (pref descriptor-pointer :<I>mage<D>escription.width))
(Height (pref descriptor-pointer :<I>mage<D>escription.height))
(Depth (pref descriptor-pointer :<I>mage<D>escription.depth))
should give meaningful values.
The documentation for #_GraphicsImportGetImageDescription should
probably tell you whether or not it's necessary to dispose of the
handle when you're done with it. Disposing of the handle will
make the memory that it (indirecly) pointed to free as well as
freeing the handle itself.
On Thu, 28 Dec 2006, Brent Fulgham wrote:
> I'm attempting to call a QuickTime API function, which expects to be passed a
>
> First call is to a function to get the graphics importer.
> OSErr GetGraphicsImporterForFile (
> const FSSpec *theFile,
> ComponentInstance *gi );
> This call is done in Lisp as:
>
> (rlet ((&gi :<G>raphics<I>mport<C>omponent)
> (Fsspec :<FSS>pec)
> (Fsref :<FSR>ef)
> (&ImageDescriptor :<I>mage<D>escription)
> ... Get a FSRef from a CURL-based path (per Gary's earlier instructions)....
>
> (let ((err (#_GetGraphicsImporterForFile Fsspec &gi)))
> (unless (= err #$noErr)
> (error "GetGraphicsImporterForFile ~a" err)))
>
> This works great, returns no error, and produces a &gi value that can be used
> further in the routine.
>
> Later (with the enclosing rlet above) I wish to get the graphics description
> of my image file, using the API call:
> ComponentResult GraphicsImportGetImageDescription (
> GraphicsImportComponent ci,
> ImageDescriptionHandle *desc );
>
> In this case, the component instance is supposed to be the actual
> GraphicsImportComponent object
> (whereas the earlier call used a pointer to a <C>omponent<I>nstance). The
> FFI seems to handle this
> properly, or at least returns a <G>raphics<I>mport<C>omponent object that I
> can pass to the above
> function without API complaints.
>
> However, I wish to get an <I>mage<D>escription from the
> ImageDescriptionHandle*, which is effectively
> a "ImageDescriptionHandle**".
>
> This looks like the following (still inside the above rlet, so the stuff is
> in scope):
>
> (let ((err (#_GraphicsImportGetImageDescription &gi &ImageDescriptor)))
> (unless (= err #$noErr)
> (error "GraphicsImportGetImageDescription ~a" err)))
>
> This seems to work, but produces incorrect results. If I attempt to extract
> values from the ImageDescriptor:
>
> (let ((Width (rref &ImageDescriptor :<I>mage<D>escription.width))
> (Height (rref &ImageDescriptor :<I>mage<D>escription.height))
> (Depth (rref &ImageDescriptor :<I>mage<D>escription.depth))
> ...
>
> I get very strange values.
>
> I think my problem has to do with the pointer-to-pointer dereferencing, but
> I'm not sure how to express this using the OpenMCL FFI.
>
> I could do something like:
> (let ((id-ptr (%get-ptr &ImageDescriptor)))
> (let ((err (#_GraphicsImportGetImageDescription &gi id-ptr)))
> (unless (= err #$noErr)
> (error "GraphicsImportGetImageDescription ~a" err)))
>
> ... But trying this also gives me weird values.
>
> Can anyone help me figure out how to pass these FFI values?
>
> Thanks,
>
> -Brent
>
>
>
>
Date: December 29, 2006
From: Brent Fulgham <bfulg@xxxxxxxxxxx>
I'm attempting to call a QuickTime API function, which expects to be passed a
First call is to a function to get the graphics importer.
OSErr GetGraphicsImporterForFile (
const FSSpec *theFile,
ComponentInstance *gi );
This call is done in Lisp as:
(rlet ((&gi :<G>raphics<I>mport<C>omponent)
(Fsspec :<FSS>pec)
(Fsref :<FSR>ef)
(&ImageDescriptor :<I>mage<D>escription)
... Get a FSRef from a CURL-based path (per Gary's earlier instructions)....
(let ((err (#_GetGraphicsImporterForFile Fsspec &gi)))
(unless (= err #$noErr)
(error "GetGraphicsImporterForFile ~a" err)))
This works great, returns no error, and produces a &gi value that can be used
further in the routine.
Later (with the enclosing rlet above) I wish to get the graphics description of
my image file, using the API call:
ComponentResult GraphicsImportGetImageDescription (
GraphicsImportComponent ci,
ImageDescriptionHandle *desc );
In this case, the component instance is supposed to be the actual
GraphicsImportComponent object
(whereas the earlier call used a pointer to a <C>omponent<I>nstance). The FFI
seems to handle this
properly, or at least returns a <G>raphics<I>mport<C>omponent object that I can
pass to the above
function without API complaints.
However, I wish to get an <I>mage<D>escription from the
ImageDescriptionHandle*, which is effectively
a "ImageDescriptionHandle**".
This looks like the following (still inside the above rlet, so the stuff is in
scope):
(let ((err (#_GraphicsImportGetImageDescription &gi &ImageDescriptor)))
(unless (= err #$noErr)
(error "GraphicsImportGetImageDescription ~a" err)))
This seems to work, but produces incorrect results. If I attempt to extract
values from the ImageDescriptor:
(let ((Width (rref &ImageDescriptor :<I>mage<D>escription.width))
(Height (rref &ImageDescriptor :<I>mage<D>escription.height))
(Depth (rref &ImageDescriptor :<I>mage<D>escription.depth))
...
I get very strange values.
I think my problem has to do with the pointer-to-pointer dereferencing, but I'm
not sure how to express this using the OpenMCL FFI.
I could do something like:
(let ((id-ptr (%get-ptr &ImageDescriptor)))
(let ((err (#_GraphicsImportGetImageDescription &gi id-ptr)))
(unless (= err #$noErr)
(error "GraphicsImportGetImageDescription ~a" err)))
... But trying this also gives me weird values.
Can anyone help me figure out how to pass these FFI values?
Thanks,
-Brent
Date: December 21, 2006
From: Phil <pbpublist@xxxxxxxxxxx>
In-reply-to:
<20061221002105.W72856@xxxxxxxxxxx>
References:
<69891860-715E-4903-BB4E-D19C544D8F8A@xxxxxxxxxxx> <20061101004307.E20390@xxxxxxxxxxx> <68DFB388-C312-4A1F-8857-FC12AF6173DA@xxxxxxxxxxx> <20061221002105.W72856@xxxxxxxxxxx>
On Dec 21, 2006, at 3:12 AM, Gary Byers wrote: > At least in theory, it'd be easier to get the ffi translator working > on ppc64 (where there's at least a branch in the gcc svn tree that > supports both ObjC 2.x and ppc64 under Darwin) than on x86-64 (where > it seems like merging a few branches would be necessary in order to > get both ObjC 2.x support and 64-bit support under Darwin.) Doing that > would also expose some 32-bit-isms in the bridge and would also expose > any ObjC 2.0 issues that might arise. I imagine, though, that there's > more interest in the long term in x86-64 support than in ppc64 > support. I'm probably an edge case but I'm not totally focussed on x86-64 support right now but am rather more interested in Obj-C 2.0 support than Intel support. I'll also be supporting/working with PPC machines (32- and 64-bit) for at least a couple more years. Apple's customer base is still largely running PPC and will be for a while. > If anyone knows how to get one's hands on the source to - oh, let's > say Apple version 5427 or so of - GCC, please let me know. I'll fight the good fight with ADC and make a case for getting you the requested access. You've probably got better connections with these folks than I do, but another voice can't hurt. Thanks, Phil
Date: December 21, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
In-reply-to:
<68DFB388-C312-4A1F-8857-FC12AF6173DA@xxxxxxxxxxx>
References:
<69891860-715E-4903-BB4E-D19C544D8F8A@xxxxxxxxxxx> <20061101004307.E20390@xxxxxxxxxxx> <68DFB388-C312-4A1F-8857-FC12AF6173DA@xxxxxxxxxxx>
I got stuck at some point a few weeks ago and haven't gotten back to it. At least in theory, it'd be easier to get the ffi translator working on ppc64 (where there's at least a branch in the gcc svn tree that supports both ObjC 2.x and ppc64 under Darwin) than on x86-64 (where it seems like merging a few branches would be necessary in order to get both ObjC 2.x support and 64-bit support under Darwin.) Doing that would also expose some 32-bit-isms in the bridge and would also expose any ObjC 2.0 issues that might arise. I imagine, though, that there's more interest in the long term in x86-64 support than in ppc64 support. If anyone knows how to get one's hands on the source to - oh, let's say Apple version 5427 or so of - GCC, please let me know. (That shouldn't be difficult, of course, since GCC is GPL'ed and anyone distibuting it has make those sources publicly available, right ?) The current FFIGEN "sources" are basically a Makefile and a set of patches relative to gcc-4.0.0 (and gcc-objc-4.0.0). If I get something working under x86-64 Darwin, I presumably have to distribute a set of patches to merge the 64-bit support available in some public GCC source trees/archives with the ObjC 2.x support that currently only seems to be available in a Apple branch of the GCC svn tree, as well as the (slightly modified) set of patches which enable .ffi generation. I'd rather do this once (for both Darwin ppc64 and x86-64) than twice. On Thu, 21 Dec 2006, Phil wrote: > It's been a while since anything was stated on the topic of Leopard > testing. So just checking in to see if things are nearing a point > where said testing would be worthwhile? > > Thanks, > Phil > > On Nov 1, 2006, at 3:00 AM, Gary Byers wrote: > >> >> That support (for both ppc64 and x86-64) is an announced feature of >> Leopard. >> >> (I have, coincidentally, been working on this lately. If/when things >> reach some level of usability, it'd be good if there was some way of >> (a) making Leopard .cdb files available to Leopard beta testers and >> (b) doing (a) in a way that doesn't violate the letter/spirit of >> applicable NDAs.) > > _______________________________________________ > Openmcl-devel mailing list > Openmcl-devel@xxxxxxxxxxx > http://clozure.com/mailman/listinfo/openmcl-devel > >
Date: December 21, 2006
From: Phil <pbpublist@xxxxxxxxxxx>
In-reply-to:
<20061101004307.E20390@xxxxxxxxxxx>
References:
<69891860-715E-4903-BB4E-D19C544D8F8A@xxxxxxxxxxx> <20061101004307.E20390@xxxxxxxxxxx>
It's been a while since anything was stated on the topic of Leopard testing. So just checking in to see if things are nearing a point where said testing would be worthwhile? Thanks, Phil On Nov 1, 2006, at 3:00 AM, Gary Byers wrote: > > That support (for both ppc64 and x86-64) is an announced feature of > Leopard. > > (I have, coincidentally, been working on this lately. If/when things > reach some level of usability, it'd be good if there was some way of > (a) making Leopard .cdb files available to Leopard beta testers and > (b) doing (a) in a way that doesn't violate the letter/spirit of > applicable NDAs.)
Date: December 16, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
In-reply-to:
<8757cb490612151743w280b7a63i24b8805d5409602e@xxxxxxxxxxxxxx>
References:
<20061216004055.91590.qmail@xxxxxxxxxxxxxxxxxxxxxxxxxxx> <8757cb490612151743w280b7a63i24b8805d5409602e@xxxxxxxxxxxxxx>
On Fri, 15 Dec 2006, Bill Clementson wrote: > Hi Brent, > >> I remember someone (probably Gary) mentioning that OpenMCL had originally >> been envisioned for use in spacecraft and so forth. >> >> I was curious if OpenMCL had ever been used for such an application? > > You'll find some background on Erann Gat's page "Lisping at JPL" > (http://www.flownet.com/gat/jpl-lisp.html) - in particular, the > section titled "2000 - MDS". > > There is also some information in the presentation that Gary Byers > gave to the ACL2 seminar (http://bc.tech.coop/blog/050824.html). > > I'm sure Gary has a lot of additional tidbits that he can share. ;-) > I'm not sure if there's too much to add to that. The idea was to target VxWorks/PPC (a real-time OS that was used on most flight hardware) that had a fairly spartan development environment. It happened to be the case that PPC Linux used the same object file format and foreign calling sequence, but Linux (usually) didn't have to be rebooted every time a buggy application scribbled over memory randomly, so it was generally a lot more sensible to port to Linux, try to get the Linux version stable, and use a PPC Linux box to develop for VxWorks. (This eventually became OpenMCL, which was available for about a year on LinuxPPC before it was ported to Darwin.) As both Erann's paper and my presentation mention, none of what eventually became OpenMCL ever flew on a JPL mission. It's probably worth mentioning that the idea of trying to get an MCL source license and using MCL as the basis for a small- footprint CL for embedded systems was Erann's; I was pretty skeptical about a lot of the things that were involved in that, but that skepticism turned out to be mostly unfounded. > -- > Bill Clementson
Date: December 16, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
I got the old (MoinMoin 1.1) OpenMCL wiki running on the new server. In the long run, it might be better to upgrade to (and reformat the data for) a newer version of MoinMoin, or switch to another Wiki engine, or something. In the meantime, the old content seems to at least be there, and that's at least a step up from a broken link.
Date: December 16, 2006
From: "Bill Clementson" <billclem@xxxxxxxxx>
In-reply-to:
<20061216004055.91590.qmail@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
References:
<20061216004055.91590.qmail@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
Hi Brent, > I remember someone (probably Gary) mentioning that OpenMCL had originally > been envisioned for use in spacecraft and so forth. > > I was curious if OpenMCL had ever been used for such an application? You'll find some background on Erann Gat's page "Lisping at JPL" (http://www.flownet.com/gat/jpl-lisp.html) - in particular, the section titled "2000 - MDS". There is also some information in the presentation that Gary Byers gave to the ACL2 seminar (http://bc.tech.coop/blog/050824.html). I'm sure Gary has a lot of additional tidbits that he can share. ;-) -- Bill Clementson
Date: December 16, 2006
From: Brent Fulgham <bfulg@xxxxxxxxxxx>
I remember someone (probably Gary) mentioning that OpenMCL had originally been envisioned for use in spacecraft and so forth. I was curious if OpenMCL had ever been used for such an application? Thanks, -Brent
Date: December 15, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
In-reply-to:
<382E6903-B6AD-4BBD-A379-6507CFD82AD1@xxxxxxxxxxx>
References:
<382E6903-B6AD-4BBD-A379-6507CFD82AD1@xxxxxxxxxxx>
IIRC, CCL::MAKE-NS-POINT is just a magic pseudofunction that can only
appear inside an SLET. It's not a real function or macro, though
it might be possible to have SLET macroexpand into something that
defined it via MACROLET or FLET or something.
This all has to do with C "structure return and assignement"
conventions. A C function that "returns a structure" doesn't
really do so in the sense that Lisp functions return values.
In C or ObjC, you might see a code fragment like:
NSPoint p; /* reserve space for a point on the stack */
p = NSMakePoint(x,y); /* Initialize the fields of .. the result */
If NSMakePoint was a real function - I think that it's actually defined
as an inline function in the Cocoa header files and doesn't exist in
any library - it would be implemented as if it took an invisible first
argument of type "pointer to NSPoint", something like:
void
NSMakePoint(NSPoint *result,float x, float y)
{
result->x = x;
result->y = y;
}
and the "assignment" to p compiles to something like:
NSMakePoint(&r,x,y);
This is extremely concise, extremely convenient, and extremely
antiperistaltic.
SLET is an attempt to lispify this a little; it tries to combine the
allocation of a foreign structure instance with "assignment" to that
foreign structure. It magically recognizes a few "structure-returning"
forms and can recognize message sends that (pretend to) "return"
structures. It works, and has essentially the same characteristices
(all three of 'em) as the C conventions it's trying to mirror.
Randall Beer and I were (and I think still are) generally interested
in the general idea of "making Cocoa easier to use by hiding ObjC
ugliness", and I think that we convinced ourselves that part of
that would be to bury the C structure-returning stuff at some
level that people would hopefully rarely have to deal with. A
message or function that was defined to "return a structure"
would in fact return a (lisp) structure, messages/functions that
accepted a structure argument would accept a lisp structure, and
the bridge would handle mapping between lisp structures and foreign
structures according to an extensible set of rules. We were also
talking (in the same timeframe) about the notion of replacing
SEND with generic functions and replacing DEFINE-OBJC-METHOD
with DEFMETHOD, and Randall was able to get some of this working.
We both ran out of time/funding around that time, and the other
problems that the ObjC bridge was experiencing at that time
(extreme sensitivity to minor changes in library versions,
slow/imprecise parsing of encoded ObjC type information, a few
other related things) also needed to be addressed. When I got
around to trying to address them, I managed to break Randall's
generic-function and structure-coercion code. It's still there -
conditionalized out in objc-clos.lisp - and the conditionalizd-out
code includes the definition of NS-MAKE-POINT that you're seeing.
I still think that moving away from SEND and SLET towards generic
functions and lisp structures is the right thing and have been
planning on un-breaking Randall's code - which was basically
working or very close to it - for over a year now.
On Thu, 14 Dec 2006, Brent Fulgham wrote:
> I've done a "(require 'cocoa)" in a program, which I can see loads
> the "examples/objc-clos" file. But when I attempt to use anything
> from the file I get an error:
>
> ;;; From ccl/examples/objc-clos.lisp:
>
> (defstruct (ns-point (:constructor make-ns-point (x y)))
> x
> y)
>
> (defun ns-make-point (x y)
> (make-ns-point (coerce x 'single-float) (coerce y 'single-float)))
>
> ;;;;
>
> If I load the routines:
>
> ;Loading #P"openmcl/compat.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/cocoa.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/fake-cfbundle-
> path.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/objc-support.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/bridge.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/objc-runtime.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/library/splay-tree.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/name-
> translation.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/process-objc-
> modules.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/objc-clos.lisp"...
> [ ... ]
>
> Welcome to OpenMCL Version 1.1-pre-061110 (DarwinPPC32)!
> ? (ccl::ns-make-point 0.1 0.2)
> > Error: Undefined function CCL::NS-MAKE-POINT called with arguments
> (0.1 0.2) .
> > While executing: CCL::TOPLEVEL-EVAL, in process Listener(4).
> > Type :GO to continue, :POP to abort, :R for a list of available
> restarts.
> > If continued: Retry applying CCL::NS-MAKE-POINT to (0.1 0.2).
> > Type :? for other options.
>
> I don't see any 'package declarations that would help me figure out
> if these things are exported. I'm sure this has an obvious answer,
> but I'm not seeing what I'm doing wrong...
>
> Thanks,
>
> -Brent
>
>
>
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel@xxxxxxxxxxx
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>
Date: December 15, 2006
From: Brent Fulgham <bfulg@xxxxxxxxxxx>
I've done a "(require 'cocoa)" in a program, which I can see loads the "examples/objc-clos" file. But when I attempt to use anything from the file I get an error: ;;; From ccl/examples/objc-clos.lisp: (defstruct (ns-point (:constructor make-ns-point (x y))) x y) (defun ns-make-point (x y) (make-ns-point (coerce x 'single-float) (coerce y 'single-float))) ;;;; If I load the routines: ;Loading #P"openmcl/compat.lisp"... ;Loading #P"/opt/local/share/openmcl/1.1/examples/cocoa.lisp"... ;Loading #P"/opt/local/share/openmcl/1.1/examples/fake-cfbundle- path.lisp"... ;Loading #P"/opt/local/share/openmcl/1.1/examples/objc-support.lisp"... ;Loading #P"/opt/local/share/openmcl/1.1/examples/bridge.lisp"... ;Loading #P"/opt/local/share/openmcl/1.1/examples/objc-runtime.lisp"... ;Loading #P"/opt/local/share/openmcl/1.1/library/splay-tree.lisp"... ;Loading #P"/opt/local/share/openmcl/1.1/examples/name- translation.lisp"... ;Loading #P"/opt/local/share/openmcl/1.1/examples/process-objc- modules.lisp"... ;Loading #P"/opt/local/share/openmcl/1.1/examples/objc-clos.lisp"... [ ... ] Welcome to OpenMCL Version 1.1-pre-061110 (DarwinPPC32)! ? (ccl::ns-make-point 0.1 0.2) > Error: Undefined function CCL::NS-MAKE-POINT called with arguments (0.1 0.2) . > While executing: CCL::TOPLEVEL-EVAL, in process Listener(4). > Type :GO to continue, :POP to abort, :R for a list of available restarts. > If continued: Retry applying CCL::NS-MAKE-POINT to (0.1 0.2). > Type :? for other options. I don't see any 'package declarations that would help me figure out if these things are exported. I'm sure this has an obvious answer, but I'm not seeing what I'm doing wrong... Thanks, -Brent
Date: December 11, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
In-reply-to:
<2B0469D8-A8FB-4D64-8C47-60F0B01260BC@xxxxxxxxxxx>
References:
<F531A933-DB59-4F04-8431-74762E703631@xxxxxxxxxxx> <20061210171634.E66845@xxxxxxxxxxx> <8F938295-50D0-423C-A364-E68C6A01782F@xxxxxxxxxxx> <20061211002429.O66845@xxxxxxxxxxx> <2B0469D8-A8FB-4D64-8C47-60F0B01260BC@xxxxxxxxxxx>
On Mon, 11 Dec 2006, Brent Fulgham wrote: > > One last question for the night: > > Is there an easy way to test that the "windowRef" returned for a Cocoa window > is valid? According to > "http://developer.apple.com/documentation/Cocoa/Conceptual/CarbonCocoaDoc/Articles/CarbonCocoaComm.html" > > the windowref in a Cocoa application should be a valid Carbon reference. > However, this doesn't seem to work. > > If I do something like: > ?(require 'cocoa) > > ... lots of stuff ... > > ? (defvar *A* (ccl::new-cocoa-window)) > *A* > ? (defvar *B* (ccl::send *A* 'window-ref)) > *B* > ? *A* > #<NS-WINDOW <NSWindow: 0x3a6cb0> (#x3A6CB0)> > ? *B* > #<NS-OBJECT <NSCFType: 0x3ad950> (#x3AD950)> > ? (defvar *C* (ccl::%get-ptr *B*)) > *C* > ? *C* > #<A Mac Pointer #xA07C35C0> > > I don't think the NS-OBJECT returned is what I want, because calling various > Carbon-based things don't seem to do anything. The thing printed as an NS-OBJECT of mostly unknown class - the thing returned by invoking *A*' window-ref method and which you have assiged to *B* - is what Carbon would call a "windowRef". ? (#_IsValidWindowPtr *B*) 1 ; boolean true A lot of things (some documented, some not) are "toll-free bridged" between Cocoa and CoreFoundation. Something that's just a random CoreFoundation type is (apparently) also an instance of an internal NSCFType Cocoa class. The bridge tries very hard -not- to know about ObjC classes that aren't declared in header files. (This is intentional: it makes it easier to run applications under different OS releases than they were compiled/saved under); it can tell that the NSCFType is an ObjC object, but since it doesn't really want to know about the internal NSCFType class it just claims that the object is an instance of the first superclass of NSCFType that it believes in. In this case, it's just an NSObject. The first word of any ObjC object is a pointer to its class. If we look up the address of the (internal) NSCFType class, ? (ccl::lookup-objc-class "NSCFType") #<A Mac Pointer #xA07C35C0> we see that that class has the same address as *C* in your example. (Of course, the exact address of the class depends on what version of the Cocoa libraries you have installed.) > > ? (#_HideWindow *C*) > NIL > Try (#_HideWindow *B*) (#_MoveWindow *B* 100 200) I honestly don't know if that'll work, but if it doesn't it may be because of Cocoa/Carbon integration issues. (You can probably do more mixing of Cocoa and Carbon in the same application than you could a few OS releases ago and I'd expect simple things like the above to work, but there may still be things that you can't quite do; it may (for instance) sometimes be the case that Carbon event handlers don't have the intended effect because Cocoa intercepts things earlier in the event process. I think (for instance) that Carbon and Cocoa handle view hierarchies and redisplay in ways that are somewhat similar but which may be different in enough details that it's hard to mix-and-match. The "modern" Carbon approach (HIView, etc.) is probably closer to Cocoa's approach (NSView, etc.), but I think that it may be non-trivial to try to mix HIViews and NSView in the same program (and it may not even be possible. I don't know.) > Does not hide the window. > > ? (#_MoveWindow *C* 100 200) > > Does not move the window. > > Thanks, > > -Brent > >
Date: December 11, 2006
From: Brent Fulgham <bfulg@xxxxxxxxxxx>
In-reply-to:
<20061211002429.O66845@xxxxxxxxxxx>
References:
<F531A933-DB59-4F04-8431-74762E703631@xxxxxxxxxxx> <20061210171634.E66845@xxxxxxxxxxx> <8F938295-50D0-423C-A364-E68C6A01782F@xxxxxxxxxxx> <20061211002429.O66845@xxxxxxxxxxx>
One last question for the night: Is there an easy way to test that the "windowRef" returned for a Cocoa window is valid? According to "http://developer.apple.com/ documentation/Cocoa/Conceptual/CarbonCocoaDoc/Articles/ CarbonCocoaComm.html" the windowref in a Cocoa application should be a valid Carbon reference. However, this doesn't seem to work. If I do something like: ?(require 'cocoa) ... lots of stuff ... ? (defvar *A* (ccl::new-cocoa-window)) *A* ? (defvar *B* (ccl::send *A* 'window-ref)) *B* ? *A* #<NS-WINDOW <NSWindow: 0x3a6cb0> (#x3A6CB0)> ? *B* #<NS-OBJECT <NSCFType: 0x3ad950> (#x3AD950)> ? (defvar *C* (ccl::%get-ptr *B*)) *C* ? *C* #<A Mac Pointer #xA07C35C0> I don't think the NS-OBJECT returned is what I want, because calling various Carbon-based things don't seem to do anything. ? (#_HideWindow *C*) NIL Does not hide the window. ? (#_MoveWindow *C* 100 200) Does not move the window. Thanks, -Brent On Dec 10, 2006, at 11:56 PM, Gary Byers wrote: > > > On Sun, 10 Dec 2006, Brent Fulgham wrote: > >> Speaking of the Cocoa bindings: >> >> 1. Do all child classes of things derived from NS:NS-OBJECT have >> to be declared as members of the NS:+NS-OBJECT meta-class? > > Yes. There are two axes involved when one defines a class: > > 1) one describes inheritance relationships that apply to instances. > A BINARY-FILE-STREAM is a FILE-STREAM and therefore also a STREAM. > The superclasses specified in a DEFCLASS form specify these > relationships. > > 2) the other - not used as often - describes inheritance relationships > that apply to the class itself. In most cases, CLASS objects are > just "instances of the class whose name is STANDARD-CLASS"; when > defining an ObjC class, we want the class object to something that > the ObjC runtime can use directly. > > In contrast to CLOS classes (which usually inherit from one of > a small number of CLASS metaobjects), ObjC classes typically > have their own unique metaclasses, but this unique metaclass > is usually created at the same time that the class object is. > Using (:metaclass ns:+ns-object) is kind of a hack to work > around the fact that the -real- metaclass doesn't exist yet. > > The AMOP says that the :METACLASS option to ENSURE-CLASS defaults to > STANDARD-CLASS. It might arguably have been better to make it default > to something based on the metaclasses of the superclass arguments > or something, though that may be harder to do in general than it > might seem at first clance. (The :metaclass option already controls > how the superclasses default, so there's a slippery slope there.) > >> >> 2. Is there any reason the "Cocoa" framework (which works quite >> nicely for creating windows from the console) is still part of >> "examples", rather than part of the main system image? It's >> really quite nice. > > It started out as an example, and not enough work has been done on it > in the last few years to really justify moving it elsewhere. (This is > of course circular, since some of the work that needs to be done is to > simply move it elsewhere.) > > Over much of that few years of underactivity, I've said "I hope that > it'll soon be possible to move forward with both the bridge/framework > and the proof-of-concept-but-not-too-usable demo IDE." Rather than > repeat that, I think that I'd rather say: > > 1) Clozure refuses to be held legally responsible for any unfortunate > breath- holding incidents. (E.g., don't hold your breath.) But > > 2) Stay tuned. > >> >> Thanks, >> >> -Brent >>
Date: December 11, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
In-reply-to:
<8F938295-50D0-423C-A364-E68C6A01782F@xxxxxxxxxxx>
References:
<F531A933-DB59-4F04-8431-74762E703631@xxxxxxxxxxx> <20061210171634.E66845@xxxxxxxxxxx> <8F938295-50D0-423C-A364-E68C6A01782F@xxxxxxxxxxx>
On Sun, 10 Dec 2006, Brent Fulgham wrote:
> Speaking of the Cocoa bindings:
>
> 1. Do all child classes of things derived from NS:NS-OBJECT have to be
> declared as members of the NS:+NS-OBJECT meta-class?
Yes. There are two axes involved when one defines a class:
1) one describes inheritance relationships that apply to instances.
A BINARY-FILE-STREAM is a FILE-STREAM and therefore also a STREAM.
The superclasses specified in a DEFCLASS form specify these
relationships.
2) the other - not used as often - describes inheritance relationships
that apply to the class itself. In most cases, CLASS objects are
just "instances of the class whose name is STANDARD-CLASS"; when
defining an ObjC class, we want the class object to something that
the ObjC runtime can use directly.
In contrast to CLOS classes (which usually inherit from one of
a small number of CLASS metaobjects), ObjC classes typically
have their own unique metaclasses, but this unique metaclass
is usually created at the same time that the class object is.
Using (:metaclass ns:+ns-object) is kind of a hack to work
around the fact that the -real- metaclass doesn't exist yet.
The AMOP says that the :METACLASS option to ENSURE-CLASS defaults to
STANDARD-CLASS. It might arguably have been better to make it default
to something based on the metaclasses of the superclass arguments
or something, though that may be harder to do in general than it
might seem at first clance. (The :metaclass option already controls
how the superclasses default, so there's a slippery slope there.)
>
> 2. Is there any reason the "Cocoa" framework (which works quite nicely for
> creating windows from the console) is still part of "examples", rather than
> part of the main system image? It's really quite nice.
It started out as an example, and not enough work has been done on it
in the last few years to really justify moving it elsewhere. (This is
of course circular, since some of the work that needs to be done is to
simply move it elsewhere.)
Over much of that few years of underactivity, I've said "I hope that
it'll soon be possible to move forward with both the bridge/framework
and the proof-of-concept-but-not-too-usable demo IDE." Rather than
repeat that, I think that I'd rather say:
1) Clozure refuses to be held legally responsible for any unfortunate
breath- holding incidents. (E.g., don't hold your breath.) But
2) Stay tuned.
>
> Thanks,
>
> -Brent
>
Date: December 11, 2006
From: Brent Fulgham <bfulg@xxxxxxxxxxx>
In-reply-to:
<20061210171634.E66845@xxxxxxxxxxx>
References:
<F531A933-DB59-4F04-8431-74762E703631@xxxxxxxxxxx> <20061210171634.E66845@xxxxxxxxxxx>
Speaking of the Cocoa bindings: 1. Do all child classes of things derived from NS:NS-OBJECT have to be declared as members of the NS:+NS-OBJECT meta-class? 2. Is there any reason the "Cocoa" framework (which works quite nicely for creating windows from the console) is still part of "examples", rather than part of the main system image? It's really quite nice. Thanks, -Brent
Date: December 11, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
In-reply-to:
<F531A933-DB59-4F04-8431-74762E703631@xxxxxxxxxxx>
References:
<F531A933-DB59-4F04-8431-74762E703631@xxxxxxxxxxx>
What do you think existing Carbon and Cocoa applications - including
MCL - do ? (Hint: they run event loops.)
A "modern" Carbon application typically installs Carbon event handlers
(callbacks) for events that it's interested in, does other initializaton,
then calls #_RunApplicationEventLoop in its initial thread. Usually,
RunApplicationEventLoop runs until the application terminates, fetching
events from the Window Server and other sources and using the Carbon
event mechanism to find and invoke handlers for events. In many cases,
"standard" (predefined) event handlers provide reasonable default
behavior.
A Cocoa application typically defines some classes and methods on them
(many of which directly or indirectly relate to how events are
handled), does other initialization, then sends the global
NSApplication instance a 'run message on the initial thread.
NSApplication's run method fetches events from the window server,
determines which objects should be involved in handling them, and
invokes event-related methods on those objects. In many cases,
"standard" (predefined) methods provide reasonable default behavior.
The communication between the window server and the application
happens by means of Mach message ports (an IPC mechanism). It
probably wouldn't work too well (at the very least it would
complicate things) if multiple threads could listen for incoming
event messages and reply to those messages. I'm not too sure
how well the low-level IPC stuff would handle that, and at a
higher level it would add a fair degree of complexity to ensure
that things were serialized when they needed to. Apple chose
not to support this; in OSX, only one thread can reliably receive
and reply to low-level event messages. There may be intentional
and/or unintentional exceptions from OS release to OS release,
but it generally seems to work best if this thread is the initial
thread. (It doesn't seem that GLUT - which uses Cocoa to provide
a simple framework for OpenGL drawing and event handling - enforces
this, but I don't know whether that's intentional or not.)
You will find that Carbon and Cocoa applications start event loops
on their initial threads; few things would work if they didn't.
(That's not quite the same as "nothing": certain things, IIRC,
can be handled entirely in the window server.)
MCL also ran an event loop, but
(a) it (mostly) used an older, non-extensible event API that
involved polling (busy-waiting, a little) for events rather
than blocking.
(b) even though it used some cooperative threading API that
made tools like Thread Manager aware of the existence of
its threads, the OS basically sees MCL as a single-threaded
application (whose stack pointer and other registers move
around from time to time.) The good news is that things
like the Mach port to the window server can be accessesed
from any "thread" (since it's all the same thread ...);
the bad new is that other things (per-thread OpenGL context
and other graphics state, per-thread AutoreleasePools in
Cocoa) are shared by MCL threads.
There are lots of reasons for favoring the more modern Carbon/Cocoa
event models, and Apple spent a few years articulating those reasons.
There are lots of reasons for letting the OS manage threads and their
scheduling rather than trying to do this at the application level.
(Being able to use the 1023 other CPU cores that're rumored to be
not-too-far-down-the-road might also count as a compelling reason.)
The combination of these and other factors mean that you pretty much
have to commit to doing all event processing in the initial (native)
thread. Once in a while, that's confusing or overly restrictive; most
of the time, it's pretty clearly the right thing.
On Sun, 10 Dec 2006, Brent Fulgham wrote:
> In playing with the MCL 5.1 demo program, I notice that the Window class
> included in the image allows one to instantiate the window, and it
> immediately pops up:
>
> Welcome to the demo version of Macintosh Common Lisp Version 5.1!
> ? (defvar *T* (make-instance 'window))
> *T*
>
> The window identifies itself as part of the MCL program (at least, no
> separate process or tray icon is created), and I continue to be able to
> interact with the MCL console to create new forms, etc.
>
> I've written (or rather, stolen) a window implementation based on Mikel's
> Clotho/Bosco stuff, and so I also get a nice window to pop up from my OpenMCL
> session. However, my window is "dead" in that it doesn't respond to events
> though I can update images in a graphic context embedded in the window.
>
> I fully understand that the problem is that the window I generated is not
> being serviced by any kind of an event/message loop. However, if I were to
> do so from the constructor of the window I would end up with a "locked"
> OpenMCL console since it would never return from the window (until the event
> loop was exited).
>
> So, I see a few options and I'm curious if anyone can provide
> context/suggestions for the right way to go.
>
> 1. Each window could be launched in its own thread which would execute the
> run-loop. I'm not sure if there would be any threading concerns here, but I
> imagine this would be a fairly simple approach. However, examining the MCL
> running image with the OS X development tool "Thread Viewer" shows no new
> threads created as I open windows. So, another possibility is:
>
> 2. A single event loop thread could be started if the "Carbon" or "Cocoa"
> environments were activated in OpenMCL. New windows could be created, then
> this thread could be notified to begin servicing the windows as part of its
> event loop. I'm guessing this is the approach MCL uses but of course have no
> way of knowing.
>
> Does anyone have any comments (or dire warnings) about either of these
> approaches?
>
> Thanks,
>
> -Brent
>
>
Date: December 10, 2006
From: Brent Fulgham <bfulg@xxxxxxxxxxx>
| In playing with the MCL 5.1 demo program, I notice that the Window class included in the image allows one to instantiate the window, and it immediately pops up: Welcome to the demo version of Macintosh Common Lisp Version 5.1! ? (defvar *T* (make-instance 'window)) *T* The window identifies itself as part of the MCL program (at least, no separate process or tray icon is created), and I continue to be able to interact with the MCL console to create new forms, etc. I've written (or rather, stolen) a window implementation based on Mikel's Clotho/Bosco stuff, and so I also get a nice window to pop up from my OpenMCL session. However, my window is "dead" in that it doesn't respond to events though I can update images in a graphic context embedded in the window. I fully understand that the problem is that the window I generated is not being serviced by any kind of an event/message loop. However, if I were to do so from the constructor of the window I would end up with a "locked" OpenMCL console since it would never return from the window (until the event loop was exited). So, I see a few options and I'm curious if anyone can provide context/suggestions for the right way to go. 1. Each window could be launched in its own thread which would execute the run-loop. I'm not sure if there would be any threading concerns here, but I imagine this would be a fairly simple approach. However, examining the MCL running image with the OS X development tool "Thread Viewer" shows no new threads created as I open windows. So, another possibility is: 2. A single event loop thread could be started if the "Carbon" or "Cocoa" environments were activated in OpenMCL. New windows could be created, then this thread could be notified to begin servicing the windows as part of its event loop. I'm guessing this is the approach MCL uses but of course have no way of knowing. Does anyone have any comments (or dire warnings) about either of these approaches? Thanks, -Brent |
_______________________________________________ Openmcl-devel mailing list Openmcl-devel@xxxxxxxxxxx http://clozure.com/mailman/listinfo/openmcl-devel
Date: December 08, 2006
From: Eric Marsden <eric.marsden@xxxxxxx>
References:
<87mz5zs83s.fsf@xxxxxxx>
These come from sacla-tests.
? (let ((x (make-array '(2 3) :initial-contents '((a b c) (x y z)))))
(and (eql (setf (aref x 0 0) 0.0) 0.0)
(eql (setf (aref x 0 1) 0.1) 0.1)
(eql (setf (aref x 0 2) 0.2) 0.2)
(eql (setf (aref x 1 0) 1.0) 1.0)
(eql (setf (aref x 1 1) 1.1) 1.1)
(eql (setf (aref x 1 2) 1.2) 1.2)
(equalp x #2A((0.0 0.1 0.2) (1.0 1.1 1.2)))))
Unhandled exception 11 at 0x40e68b, context->regs at #x40230868
? for help
[5768] OpenMCL kernel debugger: B
current thread: tcr = 0x402317e0, native thread ID = 0x1688, interrupts enabled
(#x00002AAAAACBBBA0) #x00003000404D7F7C : #<Function TOPLEVEL-EVAL
#x00003000404D7DCF> + 429
(#x00002AAAAACBBBF0) #x00003000404D9DB4 : #<Function READ-LOOP
#x00003000404D967F> + 1845
(#x00002AAAAACBBDF8) #x00003000404DFD34 : #<Function TOPLEVEL-LOOP
#x00003000404DFC6F> + 197
? (ELT '(0 1 . 2) 2)
Unhandled exception 11 at 0x30004012aa8e, context->regs at #x40230868
? for help
[5820] OpenMCL kernel debugger: B
current thread: tcr = 0x402317e0, native thread ID = 0x16bc, interrupts enabled
(#x00002AAAAACBBB68) #x00003000404E0494 : #<Function CALL-CHECK-REGS
#x00003000404E03AF> + 229
(#x00002AAAAACBBBA0) #x00003000404D7F7C : #<Function TOPLEVEL-EVAL
#x00003000404D7DCF> + 429
(#x00002AAAAACBBBF0) #x00003000404D9DB4 : #<Function READ-LOOP
#x00003000404D967F> + 1845
(#x00002AAAAACBBDF8) #x00003000404DFD34 : #<Function TOPLEVEL-LOOP
#x00003000404DFC6F> + 197
? (NOT (LET ((ARRAY (MAKE-ARRAY '(2 3) :INITIAL-CONTENTS '((0 1 2) (3 4 5)))))
(AND (EQL (AREF ARRAY 0 0) 0) (EQL (AREF ARRAY 0 1) 1) (EQL (AREF ARRAY 0 2) 2)
(EQL (AREF ARRAY 1 0) 3) (EQL (AREF ARRAY 1 1) 4) (EQL (AREF ARRAY 1 2) 5))))
> Error: bad regspec: NIL
> While executing: CCL::%HARD-REGSPEC-VALUE, in process listener(1).
--
Eric Marsden
Date: December 08, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
In-reply-to:
<87mz5zs83s.fsf@xxxxxxx>
References:
<87mz5zs83s.fsf@xxxxxxx>
On Thu, 7 Dec 2006, Eric Marsden wrote: > Hi, > > Some more bugs revealed by the ansi-test suite, still on Linux/AMD64. > Congratulations for all the quick fixes ! I can usually put bugs in faster than I can take them out. Here's a poll question (inspired by several cases in the test suite) ... ANSI CL says that an error "should be signaled" if the result of a floating-point compilation yields exponent overflow or underflow (12.1.4.3). "should be signaled" implies that the error might not be signaled in unsafe code, but that it must be signaled in unsafe code. ANSI CL also allows (and arguably encourages) implementations to support IEEE denormalized numbers, which are conceptually at least the product of exponent underflow. (If one were to take 12.1.4.3 literally, implementations are free to support denormalized numbers, but many operations on them - such as (- least-positive-single-float 0.0f0) would be required to signal errors in "safe code".) Being compliant with 12.1.4.3 would probably require that underflow traps be enabled in the FP hardware (and may also require that the implementation avoid using the OS's standard math library if it does not comply with 12.1.4.3's requirements, interpreted literally and pedantically.) I'm not too concerned about being "pedantically compliant" with aspects of the spec that are incomplete/inconsistent, but I am concerned about being consistent and offering means of overriding the default behavior (whatever it is ...) when it's necessary to do so. There are functions in OpenMCL that allow one to get and set IEEE FP parameters (enabled exceptions, rounding mode) that apply to the current thread. These should be documented and exported (I think that they're actually exported in some cases but not documented), and it should be possible to use them to write things like: (with-floating-point-underflow-disabled (computation-that-may-underflow)) to (possibly) get a denormalized result rather than an underflow exception and: (with-floating-point-underflow-enabled (computation-that-may-underflow)) to help ensure that an exception will be signaled. (It may still be hard to guarantee - as a pedantic interpretation of 12.1.4.3 may assume - that IEEE-compliant exceptions would be signaled by some math library functions; practically any implementation of these functions is likely to be compliant with -some- C standard, which is one of the benefits of having lots of standards ...) The poll question involves the most appropriate default: is it better in practice for the default behavior to be "underflow disabled, operations on/returning denormalized floats are fully supported" or "underflow enabled, operations which return denorms generally signal FLOATING-POINT-UNDERFLOW" ?
Date: December 07, 2006
From: Eric Marsden <eric.marsden@xxxxxxx>
Hi,
Some more bugs revealed by the ansi-test suite, still on Linux/AMD64.
Congratulations for all the quick fixes !
? (LET ((OS (MAKE-STRING-OUTPUT-STREAM)))
(LET ((*TERMINAL-IO* (MAKE-TWO-WAY-STREAM (MAKE-STRING-INPUT-STREAM "")
OS)))
(CLEAR-OUTPUT T)))
==> segfault
? (let ((s (make-concatenated-stream))) (close s) (open-stream-p s))
T
? (LET ((*STANDARD-OUTPUT* (MAKE-STRING-OUTPUT-STREAM))) (CLEAR-OUTPUT NIL))
> Error: value NIL is not of the expected type STRUCTURE.
> While executing: CCL::%IOBLOCK-CLEAR-OUTPUT, in process listener(1).
? (LET* ((IS (MAKE-STRING-INPUT-STREAM "foo")) (OS (MAKE-STRING-OUTPUT-STREAM))
(S (MAKE-ECHO-STREAM IS OS))) (VALUES (WRITE-CHAR #\0 S) (CLEAR-OUTPUT S)))
> Error: value NIL is not of the expected type STRUCTURE.
> While executing: CCL::%IOBLOCK-CLEAR-OUTPUT, in process listener(1).
? (map '(or (vector t 3) (vector t 5)) #'identity (list 1 2 3))
> Error: value (#<ARRAY-CTYPE (VECTOR T 5)>) is not of the expected type
> (SATISFIES CCL::CTYPE-P).
> While executing: CCL::TYPE-SPECIFIER, in process listener(1).
? (defvar *c* (class-of (make-array 1 :element-type 'fixnum :initial-element
1)))
*C*
? (subtypep *c* *c*)
T
T
? (subtypep (class-name *c*) *c*)
NIL ;; <-- expecting T here
T
--
Eric Marsden
Date: December 06, 2006
From: Gary Byers <gb@xxxxxxxxxxx>
Compressed tar archives for DarwinPPC(32/64),LinuxPPC(32/64),DarwinX8664, LinuxX8664, and FreeBSDX8664 are now available in <ftp://clozure.com/pub/testing> As always, these archives are self-contained (contain sources, binaries, interfaces, and the CVS ChangeLog and release-notes.txt file.) (The short version of the release notes is that this release mostly just packages up recent bugfixes. The slightly longer release-notes entry appears below.) OpenMCL 1.1-pre-061205 - This release is intended to package up the bug fixes since the 061110 tarballs. There aren't too many changes in functionality or any deep architectural changes since 061110, and it should be easy to bootstrap from current sources with 061110 images. (It'd still be a good idea to recompile your code with up-to-date images, whether you download those images or build them yourself from CVS.) - The one (barely) notable change in functionality has to do with how the lisp sets up pathname translations for the "ccl" logical host when the "CCL_DEFAULT_DIRECTORY" environment variable isn't set (e.g., when a shell script isn't used to invoke the lisp.) Previous versions just used the current directory; this version tries to use the directory containing the current heap image. The new scheme might get fooled by symbolic links (either following them or not following them could be wrong), but it's more likely to work for people who don't read or understand the discussion of the shell script in the documentation. - All (knock wood) bugs that have been reported since the 061110 images were released should be fixed. Well, almost all. The fixes include: - a typo (wrong register) in the "generic" version of the code which implements (SETF AREF) on 2-dimensional arrays on x86-64 - incorrect bounds checking on vector references on x86-64, which caused some invalid indices to be treated as valid (usually leading to a segfault). IIRC, the invalid indices that were erroneously accepted were fixnums whose absolute value was > (expt 2 56). (More or less.). - Missing stream methods (especially involving string streams) affecting all platforms. - Several bugs involving GCD, some of which were specific to 64-bit platforms and some of which affected all platforms. (These bugs sometimes affected results returned by #'/, LCM, and other funtions.) - OpenMCL has only ever supported an ELEMENT-TYPE argument of ([signed,unsigned]-byte 8|16|32|64) on binary file streams (with 64-bit types supported only on 64-bit platforms.) It has not previously tried to upgrade a supplied element-type to a supported one (it does now) and any errors that resulted from supplying an element-type that was not supported (and could not be upgraded) were either obscure side-effects or quiet misbehavior; an error (a SIMPLE-ERROR complaining about the unsupported element type) is now signaled as soon as attempts to upgrade to a supported element type fail. I believe that the current behavior is both compliant and reasonable; it's probably better to discuss that issue on openmcl-devel than to do so here.
Date: December 04, 2006
From: Brent Fulgham <bfulg@xxxxxxxxxxx>
What to do?1. Should I just encapsulate the ObjC stuff as a member of a set of STD classes to avoid this?2. Did I misunderstand the first error, and multiple inheritance is actually permitted?3. Other ideas?Thanks,-Brent
_______________________________________________ Openmcl-devel mailing list Openmcl-devel@xxxxxxxxxxx http://clozure.com/mailman/listinfo/openmcl-devel
Date: December 04, 2006
From: Brent Fulgham <bfulg@xxxxxxxxxxx>
| I've probably made a poor design decision, but I'm curious if there is a way to work around it. I've created a simple cocoa window class, based on the example code in the OpenMCL sources. The test is so simple that it immediately displays the "Tiny Cocoa" example output when you invoke: ? (make-instance 'ccl::window) So far, so good. The "Open Agent Architecture" uses views and windows to display information, much like Cocoa. I thought I might be able to use 'ns:ns-view as the root class of the OAA "simple-view" class, and likewise use my window class for the OAA "window" class. This would make connecting event handlers and so forth easier for me later on. Unfortunately, the actual window used in the OAA architecture is multiply inherited from simple-view and window. OpenMCL does not like this, complaining that : ;Loading #P"Texture-and-Image-Import.lisp"... ;Loading #P"Camera.lisp"... ;Loading #P"OpenGL for MCL.lisp"... ;Compiler warnings : ; Undeclared free variable *WATCH-CURSOR*, in (USE-TEXTURE (OPENGL-SIMPLE-VIEW T)) inside an anonymous lambda form. ;Compiler warnings : ; Undeclared free variable $GENEVA, in (MAKE-OPENGL-FONT (OPENGL-SIMPLE-VIEW)) inside an anonymous lambda form. > Error: Exactly one OBJC:OBJC-CLASS must appear in (#<OBJC:OBJC-CLASS WINDOW (#x364050)> #<OBJC:OBJC-CLASS OPENGL-SIMPLE-VIEW (#x3995F0)>), found 2 > While executing: #<STANDARD-METHOD ALLOCATE-INSTANCE (OBJC:OBJC-METACLASS)>, in process listener(1). > Type :GO to continue, :POP to abort, :R for a list of available restarts. > If continued: Skip loading "Load Op |