[Openmcl-devel] OpenMCL, FFI and Obj-C bridge

Gary Byers gb at clozure.com
Sat Jan 3 16:35:47 PST 2004



On Sat, 3 Jan 2004, Camille Troillard wrote:

> Hi,
>
> I am currently trying to have CL-SDL working with OpenMCL.
> I had the 2D demo successfully working (I haven't tried the OpenGL
> demos yet), but I am wondering about some issues I ran into :
>
> 1.  CL-SDL uses FFI to access the library.  The +null-pointer+ constant
> is defined as NIL.  If I try the examples with NIL as value, it doesn't
> work because NIL is not of the expected type MACPTR.  If I redefine
> this constant with the value of (ccl:%null-ptr) it works.  The problem
> is that OpenMCL won't compile anymore CL-SDL because it says it doesn't
> know how to dump #<A Null Mac Pointer> :
>
> Can't dump #<A Null Mac Pointer> - unknown type
>     [Condition of type SIMPLE-ERROR]
> [...]
>
> Backtrace:
>    0: (CCL::FASL-UNKNOWN #<A Null Mac Pointer>)
>    1: (CCL::FASL-SCAN-GVECTOR)
>    2: (CCL::FASL-SCAN)
> [...]
>
> I am not sure where is the problem: OpenMCL, UFFI or CL-SDL?
> Most lisp implementations accept NIL as the representation of the
> null-pointer.  Allegro uses the number '0' (it seems).  I admit that I
> prefer a semantically different definition of the null-pointer as it is
> done in OpenMCL.  Is it possible, though, to dump the "Null Mac
> Pointer"?

If you don't care about preserving identity (and in this case, you
probably don't) you can use define a MAKE-LOAD-FORM method:

(defmethod make-load-form ((p ccl:macptr) &optional env)
  ;; Warning: this looks simple enough that Nothing Can Go Wrong,
  ;; but I haven't actually tried it.
  (declare (ignore env))
  (values `(ccl:%int-to-ptr ,(ccl:%ptr-to-int p)) nil))

We might find in the near future that Not All MACPTRs Are Created
Equal, so this method might need to be re-thought at that point.

>
>
> 2.  In order to display a SDL window, I need to (require "COCOA")
> first.  Not doing so would mess everything with the NSAutoReleasePool
> not being properly set.  I would like to know if there is a way to load
> only the ObjC bridge portion and the autorelease-pool stuff so that I
> can run any bridged Cocoa/Foundation application in OpenMCL without
> having the OpenMCL debugger.  I've heard that some work was in progress
> in order to have a more modular bridge architecture, is that right?

The change to do this is actually fairly small (moving the stuff which
sets up the "fake CFBundle path" out of OBJC-SUPPORT and into things
like cocoa.lisp. )  I'll try to check these changes into CVS tonight
or tomorrow.

That enables you to (REQUIRE "OBJC-SUPPORT"), which in turn opens
the Cocoa shared libraries.  If the shared libraries are loaded
into an application (like regular command-line OpenMCL) that isn't
contained in an application bundle (a .app directory), it's hard
to reliably transform this command-line application into a GUI
application (at least one that can use NSBundle/CFBundle to find
its resources.).  (My sense is that Jaguar made this harder than 10.1
did and that Panther makes it harder still.)  The "fake cfbundle
path" stuff sets an environment variable that takes effect when
the shared libraries (CoreFoundation, in this case) are first
initialized.

This is certainly confusing (and may not have been explained well).
It may be that the best way of becoming a bundled application (and
avoiding the need for this nonsense) is to be a bundled app. (That's
the appoach that Mikel Evins has been taking.)  In any case, it's
clear that the need to fool CFBundle into thinking that the application's
somewhere else should be decoupled from the ObjC Bridge.


>
> 3.  Now a real problem for me as I don't understand what happens:  If I
> load the SDL code (which make a big use of FFI) and then (require
> "COCOA"), OpenMCL goes into the kernel-debugger :
>
> 	Unhandled exception 11 at 0x05486b34, context->regs at #xf02683d8
> 	Read operation to unmapped address 0x80000008
> 	 While executing: #<Function PROCESS-MODULE-CLASSES #x05486d26>
>
> The full backtrace is provided at the end of the mail for those who are
> interested.
> However, if I load COCOA first, and then SDL, everything is working.

In order for some of the things that the bridge does to work reliably,
it has to find "all" ObjC classes and the methods defined on them; this
is currently done by traversing all shared libraries that're loaded
and trying to find ObjC objects inside of them.  (There are other
ways - #_objc_getClassList, IIRC - to enumerate all classes; there was
a problem in this at some point, but that might ultimately be a
more robust way of doing this.)

That in turn means that the bridge has to be told whenever a library
that contains ObjC code is loaded.  The code that's processing classes
defined in loaded modules shouldn't segfault, but I suspect that that
module-walking code is running in an environment that's a little different
from what it's used to.  I'll see if I can reproduce this.
>
>
> A last suggestion:  don't you think it may be a good idea to put all
> the Obj-C bridge in "ccl:lib;" instead of "ccl:examples;"?
>

The Big Plan is to layer a Cocoa-based IDE (a real, usable one) on top
of OpenMCL, and certainly by that time it'd be a more integral part
of the lisp.  If there were an "experimental" directory, that might
be the best place for it at the moment, but the Cocoa stuff is certainly
intended to move "closer" to the rest of the lisp (as close as it can
get and still be an independent layer.)


>
> Help appreciated!
>
> Best,
> Camille
>
>
>
>
>
>
> [10297] OpenMCL kernel debugger: b
>
>
> (#xF02688C0) #x05489298 : #<Function PROCESS-MODULE-METHODS #x0548935e>
> + 260
> (#xF02688D0) #x00004E9C : (subprimitive _ret1valn)
> (#xF02688E0) #x05488EDC : #<Function PROCESS-SECTION-METHODS
> #x05488eee> + 144
> (#xF02688F0) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268900) #x05488BF0 : #<Anonymous Function #x05488bfe> + 92
> (#xF0268910) #x05487BA0 : #<Function PROCESS-SECTION-IN-ALL-LIBRARIES
> #x05487bee> + 780
> (#xF0268920) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268930) #x05487794 : #<Function PROCESS-OBJC-MODULES #x0548779e> +
> 40
> (#xF0268940) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268950) #x0548FD60 : #<Function NOTE-ALL-LIBRARY-METHODS
> #x0548fd6e> + 92
> (#xF0268960) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268970) #x054FA7E8 : #<Function UPDATE-TYPE-SIGNATURES #x054fa7f6>
> + 28
> (#xF0268980) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268990) #x05519864 : #<Anonymous Function #x05519876> + 104
> (#xF02689A0) #x05519824 : #<Anonymous Function #x05519876> + 40
> (#xF02689B0) #x00004E9C : (subprimitive _ret1valn)
> (#xF02689C0) #x0110F0B8 : #<Function CHEAP-EVAL-IN-ENVIRONMENT
> #x0510d7d6> + 1284
> (#xF02689D0) #x010FE7C8 : #<Function LOAD-FROM-STREAM #x050fa33e> + 220
> (#xF02689E0) #x010FEE50 : #<Function %LOAD #x050fa76e> + 1316
> (#xF02689F0) #x010FEDB4 : #<Function %LOAD #x050fa76e> + 1160
> (#xF0268A00) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268A10) #x010F3670 : #<Function LOAD #x050eead6> + 636
> (#xF0268A20) #x010F36CC : #<Function LOAD #x050eead6> + 728
> (#xF0268A30) #x010FE2A8 : #<Function REQUIRE #x050f9e1e> + 644
> (#xF0268A40) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268A50) #x01115EFC : #<Function CALL-CHECK-REGS #x0511a37e> + 72
> (#xF0268A60) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268A70) #x0110F0B8 : #<Function CHEAP-EVAL-IN-ENVIRONMENT
> #x0510d7d6> + 1284
> (#xF0268A80) #x010FE7C8 : #<Function LOAD-FROM-STREAM #x050fa33e> + 220
> (#xF0268A90) #x010FEE50 : #<Function %LOAD #x050fa76e> + 1316
> (#xF0268AA0) #x010FEDB4 : #<Function %LOAD #x050fa76e> + 1160
> (#xF0268AB0) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268AC0) #x010F3670 : #<Function LOAD #x050eead6> + 636
> (#xF0268AD0) #x010F36CC : #<Function LOAD #x050eead6> + 728
> (#xF0268AE0) #x010FE2A8 : #<Function REQUIRE #x050f9e1e> + 644
> (#xF0268AF0) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268B00) #x01115EFC : #<Function CALL-CHECK-REGS #x0511a37e> + 72
> (#xF0268B10) #x010FE7C8 : #<Function LOAD-FROM-STREAM #x050fa33e> + 220
> (#xF0268B20) #x010FEE50 : #<Function %LOAD #x050fa76e> + 1316
> (#xF0268B30) #x010FEDB4 : #<Function %LOAD #x050fa76e> + 1160
> (#xF0268B40) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268B50) #x010F3670 : #<Function LOAD #x050eead6> + 636
> (#xF0268B60) #x010F36CC : #<Function LOAD #x050eead6> + 728
> (#xF0268B70) #x010FE2A8 : #<Function REQUIRE #x050f9e1e> + 644
> (#xF0268B80) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268B90) #x01115EFC : #<Function CALL-CHECK-REGS #x0511a37e> + 72
> (#xF0268BA0) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268BB0) #x0538BA58 : #<Function INTERACTIVE-EVAL #x0538ba9e> + 68
> (#xF0268BC0) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268BD0) #x01115EFC : #<Function CALL-CHECK-REGS #x0511a37e> + 72
> (#xF0268BE0) #x0538C010 : #<Function EVAL-STRING #x0538c08e> + 372
> (#xF0268BF0) #x0538BF18 : #<Function EVAL-STRING #x0538c08e> + 124
> (#xF0268C00) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268C10) #x010AEB28 : #<Function FUNCALL #x05081dde> + 52
> (#xF0268C20) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268C30) #x0537D29C : #<Function CALL-WITH-SLIME-STREAMS
> #x0537d2ce> + 272
> (#xF0268C40) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268C50) #x0537D02C : #<Function READ-FROM-EMACS #x0537d036> + 128
> (#xF0268C60) #x053970B4 : #<Function SERVE-ONE-REQUEST #x0539719e> + 328
> (#xF0268C70) #x053970D8 : #<Function SERVE-ONE-REQUEST #x0539719e> + 364
> (#xF0268C80) #x05397168 : #<Function SERVE-ONE-REQUEST #x0539719e> + 508
> (#xF0268C90) #x05397184 : #<Function SERVE-ONE-REQUEST #x0539719e> + 536
> (#xF0268CA0) #x0539742C : #<Function REQUEST-LOOP #x0539744e> + 272
> (#xF0268CB0) #x053973C8 : #<Function REQUEST-LOOP #x0539744e> + 172
> (#xF0268CC0) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268CD0) #x05397510 : #<Function ACCEPT-ONE-CLIENT #x0539751e> + 52
> (#xF0268CE0) #x05397640 : #<Function ACCEPT-LOOP #x0539765e> + 140
> (#xF0268CF0) #x053975D4 : #<Function ACCEPT-LOOP #x0539765e> + 32
> (#xF0268D00) #x011003C8 : #<Function RUN-PROCESS-INITIAL-FORM
> #x050fc446> + 348
> (#xF0268D10) #x01100400 : #<Function RUN-PROCESS-INITIAL-FORM
> #x050fc446> + 404
> (#xF0268D20) #x01100444 : #<Function RUN-PROCESS-INITIAL-FORM
> #x050fc446> + 472
> (#xF0268D30) #x00004E9C : (subprimitive _ret1valn)
> (#xF0268D40) #x011005BC : #<Anonymous Function #x050fc56e> + 152
> (#xF0268D50) #x011005A4 : #<Anonymous Function #x050fc56e> + 128
> (#xF0268D60) #x010FC788 : #<Anonymous Function #x050f80b6> + 172
> (#xF0268D70) #x0000895C : (subprimitive toplevel_loop)
> (#xF0268D80) #x00008968 : (subprimitive toplevel_loop)
> (#xf0268d90) #x00008A34 : _start_lisp + 180
> (#xf0268e50) #x0001321C : _lisp_thread_entry + 152
> (#xf0268eb0) #x900247E8 : __pthread_body + 40
> (#xf0268f00) #x00000000 : (null) + 0
>
>
> cstack area #x00101fb0
>
>
> (#xF0135B70) #x01038010 : #<Function FD-READ #x05028626> + 100
> (#xF0135B80) #x010EE5F4 : #<Function FD-STREAM-ADVANCE #x050e89f6> + 632
> (#xF0135B90) #x010E26AC : #<Function %IOBLOCK-TYI #x050d07de> + 384
> (#xF0135BA0) #x00004E9C : (subprimitive _ret1valn)
> (#xF0135BB0) #x010E98C0 : #<Method-Function () #<CLASS-WRAPPER
> @#x050bd83e> (#<CLASS-WRAPPER @#x050bd83e> . #<header ? #x0000076a>)
> #x050e23d6> + 204
> (#xF0135BC0) #x010E9854 : #<Method-Function () #<CLASS-WRAPPER
> @#x050bd83e> (#<CLASS-WRAPPER @#x050bd83e> . #<header ? #x0000076a>)
> #x050e23d6> + 96
> (#xF0135BD0) #x010E38C4 : #<Method-Function () #<CLASS-WRAPPER
> @#x050bd83e> (#<CLASS-WRAPPER @#x050bd83e> . #<header ? #x0000076a>)
> #x050d361e> + 96
> (#xF0135BE0) #x01109B44 : #<Function %NEXT-CHAR-AND-ATTR #x05108d9e> +
> 88
> (#xF0135BF0) #x00004E9C : (subprimitive _ret1valn)
> (#xF0135C00) #x01109A88 : #<Function %NEXT-NON-WHITESPACE-CHAR-AND-ATTR
> #x05108cfe> + 52
> (#xF0135C10) #x011126B4 : #<Function %READ-FORM #x0511301e> + 192
> (#xF0135C20) #x00004E9C : (subprimitive _ret1valn)
> (#xF0135C30) #x01112D68 : #<Function READ #x0511353e> + 212
> (#xF0135C40) #x01114C5C : #<Function TOPLEVEL-READ #x05118a96> + 224
> (#xF0135C50) #x01114D88 : #<Function TOPLEVEL-READ #x05118a96> + 524
> (#xF0135C60) #x011150C4 : #<Function READ-LOOP #x05118ee6> + 656
> (#xF0135C70) #x01115188 : #<Function READ-LOOP #x05118ee6> + 852
> (#xF0135C80) #x011151B4 : #<Function READ-LOOP #x05118ee6> + 896
> (#xF0135C90) #x011151E0 : #<Function READ-LOOP #x05118ee6> + 940
> (#xF0135CA0) #x01115E48 : #<Function TOPLEVEL-LOOP #x0511a14e> + 44
> (#xF0135CB0) #x01115E50 : #<Function TOPLEVEL-LOOP #x0511a14e> + 52
> (#xF0135CC0) #x011108FC : #<Anonymous Function #x0510f08e> + 104
> (#xF0135CD0) #x00004E9C : (subprimitive _ret1valn)
> (#xF0135CE0) #x01123298 : #<Anonymous Function #x05138b56> + 500
> (#xF0135CF0) #x01123110 : #<Anonymous Function #x05138b56> + 108
> (#xF0135D00) #x011003C8 : #<Function RUN-PROCESS-INITIAL-FORM
> #x050fc446> + 348
> (#xF0135D10) #x01100400 : #<Function RUN-PROCESS-INITIAL-FORM
> #x050fc446> + 404
> (#xF0135D20) #x01100444 : #<Function RUN-PROCESS-INITIAL-FORM
> #x050fc446> + 472
> (#xF0135D30) #x00004E9C : (subprimitive _ret1valn)
> (#xF0135D40) #x011005BC : #<Anonymous Function #x050fc56e> + 152
> (#xF0135D50) #x011005A4 : #<Anonymous Function #x050fc56e> + 128
> (#xF0135D60) #x010FC788 : #<Anonymous Function #x050f80b6> + 172
> (#xF0135D70) #x0000895C : (subprimitive toplevel_loop)
> (#xF0135D80) #x00008968 : (subprimitive toplevel_loop)
> (#xf0135d90) #x00008A34 : _start_lisp + 180
> (#xf0135e50) #x0001321C : _lisp_thread_entry + 152
> (#xf0135eb0) #x900247E8 : __pthread_body + 40
> (#xf0135f00) #x00000000 : (null) + 0
>
>
> cstack area #x00100590
>
>
> (#xBFFFFC50) #x010FD570 : #<Function %NANOSLEEP #x050f90ae> + 268
> (#xBFFFFC60) #x01110878 : #<Anonymous Function #x0510efde> + 52
> (#xBFFFFC70) #x0000895C : (subprimitive toplevel_loop)
> (#xBFFFFC80) #x00008968 : (subprimitive toplevel_loop)
> (#xbffffc90) #x00008A34 : _start_lisp + 180
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>



More information about the Openmcl-devel mailing list