Changeset 6246

Apr 9, 2007, 5:58:40 AM (14 years ago)

Update for 070408.

(Yes, it's 070409 here already ...)

1 edited


  • trunk/ccl/release-notes.txt

    r5934 r6246  
     1OpenMCL 1.1-pre-070408
     2- The FASL version changed (old FASL files won't work with this
     3  lisp version), as did the version information which tries to
     4  keep the kernel in sync with heap images.  Note that it's generally
     5  a lot easier to recompile recent sources with recent images, e.g.,
     6  trying to compile 070408 sources with an 070214 image is unlikely
     7  to work without tricky bootstrapping.
     8- There's now a Trac bug-tracking/wiki site for OpenMCL at
     9  <>.  It needs bug reports; please
     10  visit that site and use the features there to report any bugs
     11  that you find.
     13  (CCL:DEFSTATIC var value &optional doc-string)
     14  is like DEFPARAMETER in that it proclaims the variable "var" to
     15  be special, sets its value to "value", and sets the symbol's
     16  VARIABLE documentation to the optional doc-string.  It differs
     17  from DEFPARAMETER in that it further asserts that the variable
     18  should never be bound dynamically in any thread (via LET/LAMBDA/etc.);
     19  the compiler treats any attempts to bind a "static" variable as an
     20  error.
     21  It is legal to change the value of a "static" variable, but since
     22  all threads see the same (static) binding of that variable it may
     23  be necessary to synchronize assignments made from multiple threads.
     24  (A "static" variable binding is effectively a shared, global resource;
     25  a dynamic binding is thread-private.)
     26  Access to the value of a static variable is typically faster than
     27  is access to the value a special variable that's not proclaimed to
     28  be "static".
     29  This functionality has been in MCL/OpenMCL for a long time under
     30  the name CCL:DEFGLOBAL; CCL:DEFGLOBAL is an alias for CCL:DEFSTATIC,
     31  but the latter seemed to be a better name.
     32- The type of foreign object that a MACPTR points to can now be
     33  asserted (this means that a MACPTR object can contain a small
     34  integer which identifies the alleged FOREIGN-TYPE of the object that
     35  the points to.  RLET, MAKE-RECORD, and MAKE-GCABLE-RECORD (see below)
     36  assert the foreign type of the object that the MACPTR object they
     37  create (as do some new features of the ObjC bridge, described further
     38  below.)
     39  PRINT-OBJECT on a MACPTR will try to print information about the
     40  asserted type of that pointer, as well as information about where
     41  the pointer was allocated (heap, stack) and whether it's scheduled
     42  for automatic reclamation by the GC.
     43  A few constructs that conceivable should assert the type of the
     44  pointers they create (e.g., some flavor of PREF, SLOT-VALUE in
     45  the ObjC bridge) don't yet do so.
     46  A rather obvious way of exploiting typed pointers - namely, extending
     47  DESCRIBE and INSPECT to show the contents of foreign records - is
     48  not yet implemented.
     49- MAKE-GCABLE-RECORD is like MAKE-RECORD, in that it "makes an instance
     50  of a foreign record type".  (Or, to be more banal about it, uses
     51  #_malloc to allocate a block of foreign memory of the size of the
     52  foreign record type named by its argument.)  MAKE-GCABLE-RECORD
     53  additionally tells the lisp garbage collector that it should free
     54  the foreign memory when the MACPTR object that describes it becomes
     55  garbage.
     56  When using "gcable pointers", it's important to remember the
     57  distinction between a MACPTR object (which is a lisp object, more-
     58  or-less like any other) and the block of foreign memory that the
     59  MACPTR object points to.  If a gcable MACPTR is the only thing
     60  in the world ("lisp world" or "foreign world") that references
     61  the underlying block of foreign memory, then freeing the foreign
     62  memory when it becomes impossible to reference it is convenient
     63  and sane.  If other lisp MACPTRs reference the underlying block
     64  of foreign memory or if the address of that foreign memory is
     65  passed to and retained by foreign code, having the GC free the
     66  memory may have unpleasant consequences if those other references
     67  are used.
     68- CCL:FREE (which is mostly just a wrapper around #_free that allows
     69  #_free to be called early in the bootstrapping process) is now
     70  exported; if its argument is a gcable pointer (e.g., created via
     71  MAKE-GCABLE-POINTER), it will tell the GC that the pointer's
     72  foreign memory has been freed "manually" before calling #_free.
     73- The mechanisms used to implement locks has changed (for the curious,
     74  the changes involve the use of spinlocks rather than a sequence
     75  of atomic additions.)  Someone demonstrated a case of deadlock
     76  (where a thread was waiting for a lock that was available) under
     77  the old implementation.  I'm not sure that I fully understand how
     78  that could have happened, but the new implementation at least has
     79  the advantage of being a little easier to understand and might be
     80  a tiny bit faster.  Please let me know if either of these assumptions
     81  was incorrect.
     82- An EOF (control-d) in the REPL (when standard input is a tty or pty
     83  device) has traditionally caused an exit to the outer break loop
     84  (or had no effect if the REPL was not in a break loop).  If
     85  CCL:*QUIT-ON-EOF* is set, an EOF causes the lisp to quit.  (It
     86  actually invokes a listener-specific method, so in a multi-listener
     87  window system environemt, it might simply cause the listener which
     88  receives the EOF to exit.)
     89  None of this has any effect when running under environments like
     90  SLIME, and (as mentioned above) only matters if the standard input
     91  devices is a tty or pseudo-tty (where it's possible to continue
     92  reading after an EOF has been read.)  If running under an xterm
     93  or OSX, standard input is probably a pty; if running
     94  in an Emacs shell buffer or under other means under emacs, different
     95  types of IPC mechanisms (pipes, sockets) might be used.
     96- SAVE-APPLICATION has historically changed the type of all MACPTR
     97  objects (turning them into "dead macptrs", since it's generally
     98  meaningless to refer to a foreign pointer from a previous session
     99  and generally better to get a type error than some more mysterious
     100  or severe failure).  This no longer happens for null pointers (pointers
     101  to address 0); COMPILE-FILE also now allows null pointers to be referenced
     102  as constants in compiled code.
     103- Not entirely coincidentally, CCL:+NULL-PTR+ is now defined as a constant
     104  (whose value is a null pointer.)  In some cases, it may be more
     105  efficient or convenient to pass CCL:+NULL-PTR+ to foreign code than
     106  it would be to call (CCL:%NULL-PTR) to "produce" one.
     107- Historically, OpenMCL (and MCL) have maintained a list of open file
     108  streams in the value of CCL:*OPEN-FILE-STREAMS*; maintaining this
     109  list helps to ensure that streams get closed in as orderly a manner
     110  as possible when the lisp exits.  The code which accessed this list
     111  didn't do so in a thread-safe manner.
     112  The list is now maintained in a lexical variable; the function
     113  CCL:OPEN-FILE-STREAMS returns a copy of that list,
     114  CCL:NOTE-OPEN-FILE-STREAM adds its argument (a file stream) to the
     115  list, and CCL:REMOVE-OPEN-FILE-STREAM removes its argument (a file stream)
     116  from the list.  (All of these functions use appropriate locking.)
     117- There were a number of timing-related problems related to PROCESS-INTERRUPT
     118  (usually involving rapidly and repeatedly interrupting a thread over
     119  a long period of time.)  This should be a lot more reliable now
     120  (exactly what could go wrong and why and how is all a little hard to
     121  describe.)
     122- Some Linux distributions may initialize the user's environment in
     123  a way that imposes a soft limit on the amount of virtual memory that
     124  a process is allowed to map.  OpenMCL now tries to raise this limit
     125  before reserving what may be a very large amount of address space,
     126  thanks to a patch from Andi Kleen.
     127- There were a number of problems with UTF-16 streams, found and
     128  fixed by Takehiko Abe.
     129- Takehiko Abe also provided fixes for some code in "ccl:lib;xref.lisp"
     130  and in source-file recording/reporting that (still) didn't understand
     131  the concept of EQL-SPECIALIZER metaobjects.
     132- ObjC bridge and ObjC examples
     133  The ObjC bridge provides a few new mechanisms for defining ObjC
     134  methods, for calling ObjC "generic functions" (e.g., message sending),
     135  and for dealing with frequently-used record types and with differences
     136  between 32-bit and (forthcoming) 64-bit ObjC/Cocoa implementations.
     138  A lot of macros/functions/other things that really should have been
     139  exported from some package for the last few years finally have been
     140  exported from the OBJC or NS packages (and a lot of things that have
     141  historically been internal to CCL are re-imported into CCL).
     143  Cocoa (and the underlying Core Graphics libraries) have historically
     144  used 32-bit floats and 32-bit integers in data structures that describe
     145  geometry, font sizes and metrics, and elsewhere.  64-bit Cocoa will
     146  use 64-bit floats and 64-bit integers in many cases.
     148  The bridge defines the type NS:CGFLOAT as the lisp type of the
     149  preferred float type on the platform, and the constant NS:+CGFLOAT+.
     150  On DarwinPPC32, the foreign types :cgfloat, :<NSUI>nteger, and
     151  :<NSI>nteger are defined by the bridge (as 32-bit float, 32-bit
     152  unsigned integer, and 32-bit signed integer, respectively.); these
     153  types are defined (as 64-bit variants) in the 64-bit interfaces.
     155  All ObjC classes are properly named, either with a name exported
     156  from the NS package (in the case of a predefined class declared in
     157  the interface files) or with the name provided in the DEFCLASS
     158  form (with :METACLASS NS:+NS-OBJECT) which defines the class from
     159  lisp.  The class's lisp name is now proclaimed to be a "static"
     160  variable (as if by DEFSTATIC, as described above) and given the
     161  class object as its value.  In other words:
     163(send (find-class 'ns:ns-application) 'shared-application)
     165  and
     167(send ns:ns-application 'shared-application)
     169  are equivalent.  (Since it's not legal to bind a "static" variable,
     170  it may be necessary to rename some things so that unrelated
     171  variables whose names coincidentally conflict with ObjC class names
     172  don't do so.)
     174- A new reader macro - #/ - reads a sequence of "constituent" characters
     175  (including colons) from the stream on which it appears and interns
     176  that sequence - with case preserved and colons intact - in a new package
     177  whose name is NEXTSTEP-FUNCTIONS, exporting the symbol from that package.
     178  This means that the act of reading "#/alloc" returns the the symbol
     179  NEXTSTEP-FUNCTIONS:|alloc|, and the act of reading "#/initWithFrame:"
     180  returns the symbol NEXTSTEP-FUNCTIONS:|initWithFrame:|.  The intent
     181  is that the reader macro can be used to construct symbols whose names
     182  match ObjC message names; the reader macro tries to do some sanity
     183  checks (such as insisting that a name that contains at least one
     184  colon ends in a colon), but isn't totally rigourous about enforcing
     185  ObjC message name conventions.
     187  A symbol read using this macro can be used as an operand in
     188  most places where an ObjC message name can be used, such as
     189  in the (@SELECTOR ...) construct (which is now OBJC:@SELECTOR,
     190  btw.)
     192  Marco Baringer proposed the idea of using a reader macro to
     193  construct lisp symbols which matched ObjC message names.
     195- The act of interning a new symbol in the NEXTSTEP-FUNCTIONS
     196  package triggers an interface database lookup of Objc methods
     197  with the corresponding message name.  If any such information
     198  is found, a special type of dispatching function is created
     199  and initialized and the weird-looking symbol is given that
     200  dispatching function as its function definition.
     202  The dispatching knows how to call declared ObjC methods defined on
     203  the message.  In many cases, all methods have the same foreign type
     204  signature, and the dispatching function merely passes any arguments
     205  that it receives to a function that does an ObjC message send with
     206  the indicated foreign argument and return types.  In other cases,
     207  where different ObjC messages have different type signatures, the
     208  dispatching function tries to choose a function that handles the
     209  right type signature based on the class of the dispatching function's
     210  first argument.
     212  If new information about ObjC methods is introduced (e.g., by
     213  using additional interface files or as ObjC methods are defined
     214  from lisp), the dispatch function is reinitialized to recognize
     215  newly-introduced foreign type signatures.
     217  The argument and result coercion that the bridge has tradionally
     218  supported is supported by the new mechanism (e.g., :<BOOL> arguments
     219  can be specified as lisp booleans and :<BOOL> results are returned
     220  as lisp boolean values, and an argument value of NIL is coerced to
     221  a null pointer if the corresponding argument type is :ID.
     223  Some ObjC methods accept variable numbers of arguments; the
     224  foreign types of non-required arguments are determined by the
     225  lisp types of those arguments (e.g., integers are passed as
     226  integers, floats as floats, pointers as pointers, record types
     227  by reference.)
     229  Some examples:
     231;;; #/alloc is a known message.
     232? #'#/alloc
     234;;; Sadly, #/foo is not ...
     235? #'#/foo
     236> Error: Undefined function: NEXTSTEP-FUNCTIONS:|foo|
     238;;; We can send an "init" message to a newly-allocated instance of
     239;;; "NSObject" by:
     241(send (send ns:ns-object 'alloc) 'init)
     243;;; or by
     245(#/init (#/alloc ns:ns-object))
     247  ObjC methods that "return" structures return them as gcable pointers
     248  when called via dispatch functions.  E.g., if "my-window" is an
     249  NS:NS-WINDOW instance, then
     251(#/frame my-window)
     253  will return a gcable pointer to a structure that describes that window's
     254  frame rectangle.  (The good news is that there's no need to use SLET
     255  or special structure-returning message send syntax; the bad news is
     256  that #_malloc, #_free, and the GC are all involved in the creation
     257  and eventual destruction of structure-typed return values.  Unless
     258  and until those factors negatively affect performance, the advantages
     259  seem to outweigh the disadvantages.)
     261- Since foreign pointers are now (sometimes, somewhat) typed, it's
     262  possible to treat pointers to some foreign types as "instances of
     263  built-in classes."  Specifically, a pointer to an :<NSR>ect is
     264  recognized as an instance of the built-in class NS:NS-RECT, a
     265  pointer to an <NSS>ize is treated as an instance of NS:NS-SIZE,
     266  <NSP>oint is recognized as NS:NS-POINT, and <NSR>ange maps to
     267  NS:NS-RANGE.  (There are a few other more obscure structure
     268  types that get this treatment, and with a little more work the
     269  mechanism could be made extensible.)
     271  For each of these built-in classes:
     273  - a PRINT-OBJECT method is defined
     275  - a foreign type name derived from the class name (e.g., :NS-RECT
     276    for NS:NS-RECT) is made an alias for the corresponding type
     277    (so it's possible to say (RLET ((R :NS-RECT)) ...)).
     279  - the class is is integrated into the type system (so that
     280    (TYPEP R 'NS:NS-RECT) is fairly efficently implemented.)
     282  - inlined accessor and setf inverses are defined for the structure
     283    type's fields.  In the case of an :<NSR>ect, the fields in question
     284    are the fields of the embedded point and size, so NS:NS-RECT-X,
     285    NS:NS-RECT-Y, NS:NS-RECT-WIDTH, NS-RECT-HEIGHT and SETF inverses
     286    are defined.  The accessors and setter functions typecheck their
     287    arguments and the setters handle coercion to the approprate type
     288    of CGFLOAT where applicable.
     290  - an initialization function is defined; (NS:INIT-NS-SIZE s w h) is
     291    roughly equivalent to (SETF (NS:NS-SIZE-WIDTH s) w
     292    (NS:NS-SIZE-HEIGHT s) h), but might be a little more efficient.
     294  - a creation function is defined: (NS:NS-MAKE-POINT x y) is basically
     295    equivalent to:
     297      (NS:INIT-NS-POINT P X Y)
     298      p)
     300  - a macro is defined which (much like RLET) stack-allocates an
     301    instance of the foreign record type, optionally iniitializes
     302    that instance, and executes a body of code with a variable
     303    bound to that instance.  E.g.
     305    (ns:with-ns-range (r loc len)
     306      (format t "~& range has location ~s, length ~s"
     307         (ns:ns-range-location r) (ns:ns-range-length r)))
     309    which is probably not the world's most realistic example.
     311   Note that it's possible to construct a record
     312   instance that has a very short useful lifetime:
     314   (#/initWithFrame: new-view (ns:ns-make-rect 100 100 200 200))
     316   The rectangle above will -eventually- get reclaimed by the GC;
     317   if you don't want to give the GC so much work to do, you might
     318   prefer to do:
     320   (ns:with-ns-rect (r 100 100 200 200)
     321     (#/initWithFrame: new-view r))
     324 - The macro OBJC:DEFMETHOD can be used to define ObjC methods.
     325   It looks superficially like CL:DEFMETHOD in some respects.
     326   The syntax is:
     328   (OBC:DEFMETHOD name-and-result-type ((receiver-arg-and-class) &rest other-args) &body body)
     330   where:
     332   "name-and-result-type" is either an ObjC message name (use #/ !)
     333   for methods that return a value of type :ID, or a list of an ObjC
     334   message name and a foreign type specifier for methods with a different
     335   foreign result type
     337   "receiver-type-and-class" is a two-element list whose CAR is
     338   a variable name and whose CADR is the lisp name of an ObjC class
     339   or metaclass.  The receiver variable name can be any bindable
     340   lisp variable name, but SELF (in some package) might be a reasonable
     341   choice.  The receiver variable is declared to be "unsettable", i.e.,
     342   it is an error to try to change the value of the receiver in the
     343   body of the method definition.
     345   "other-args" are either variable names (denoting parameters of type
     346   :ID) or 2-element lists whose first element is a variable name and
     347    whose second element is a foreign type specifier.
     349  For example:
     351(objc:defmethod (#/characterAtIndex: :unichar)
     352    ((self hemlock-buffer-string) (index :<NSUI>nteger))
     353  ...)
     355  The method "characterAtIndex:", when invoked on an object of class
     356  HEMLOCK-BUFFER-STRING with an additional argument of type :<NSU>integer
     357  returns a value of type :unichar.)
     359  Arguments that wind up as some non-:ID pointer type (pointers,
     360  records passed by value) are represented as typed foreign pointers
     361  (so the higher-level, type-checking accessors can be used on
     362  arguments of type :ns-rect, :ns-pointe, etc.)
     364  Within the body of methods defined via OBJC:DEFMETHOD, the local
     365  function CL:CALL-NEXT-METHOD is defined.  It isn't quite as
     366  general as CL:CALL-NEXT-METHOD is when used in a CLOS method,
     367  but it has some of the same semantics.  It accepts as many arguments
     368  as are present in the containing method's "other args" list and
     369  invokes version of the containing method that would have been
     370  invoked on instances of the receiver's class's superclass with
     371  the receiver and other provided arguments.  (The idiom of passing
     372  the current method's arguments to the next method is common enough
     373  that the CALL-NEXT-METHOD in OBJC:DEFMETHODs should probably do
     374  this if it receives no arguments.)
     376  A method defined via OBJC:DEFMETHOD that returns a structure "by value"
     377  can do so by returning a record created via MAKE-GCABLE-RECORD, by
     378  returning the value returned via CALL-NEXT-METHOD, or by other similar
     379  means.  Behind the scenes, there may be a pre-allocated instance of
     380  the record type (used to support native structure-return conventions),
     381  and any value returned by the method body will be copied to this
     382  internal record instance.  Within the body of a method defined with
     383  OBJC:DEFMETHOD that's declared to return a structure type, the local
     384  macro OBJC:RETURNING-FOREIGN-STRUCT can be used to access the internal
     385  structure:
     387  (objc:defmethod (#/reallyTinyRectangleAtPoint: :ns-rect)
     388    ((self really-tiny-view) (where :ns-point))
     389    (objc:returning-foreign-struct (r)
     390      (ns:init-ns-rect r (ns:ns-point-x where) (ns:ns-point-y where)
     391                          single-float-epsilon single-float-epsilon)
     392      r))
     394 - If OBJC:DEFMETHOD introduces a new ObjC message, a ... message
     395   to that effect.  Sometimes, these messages are merely informative
     396   (and barely informative, at that ...), but they may also indicate
     397   that a message name is misspelled (or possibly missing a trailing
     398   colon.)  If a method is redefined in such a way that it's type
     399   signature changes, a continuable error is signaled.
     401 - there used to be some fairly obscure reasons that led to
     402   MAKE-OBJC-INSTANCE being a bit more efficient than MAKE-INSTANCE
     403   in some cases (some of the methods invoked by MAKE-INSTANCE did
     404   some extra work to handle Lisp slots even if the class didn't
     405   define any Lisp slots.  This work isn't done anymore, and consequently
     406   there's less reason to prefer MAKE-OBJC-INSTANCE.  (MAKE-OBJC-INSTANCE
     407   is still defined and exported from the OBJC:PACKAGE).
     409 - the preferred means of loading an add-on framework and processing
     410   the declarations in its interfaces has changed several times over
     411   the last several months.  The currently preferred (new) way to
     412   do that is via the new function OBJC:LOAD-FRAMEWORK
     414   (OBJC:LOAD-FRAMEWORK framework-name interface-dir)
     416   where "framework-name" is a string which names the framework and
     417   "interface-dir" is a keyword that names the associated set of
     418   interfaces.  OBJC:LOAD-FRAMEWORK should find and initialize the
     419   framework bundle (looking in standard framework search paths),
     420   introduce new ObjC classes to CLOS, update information about
     421   declared messages and their methods' type signatures, adjust
     422   affected dispatch functions, and make the interfaces other
     423   definitions available.  The order in which it does these
     424   things isn't specified, and may change in the future.
     426 - Most Cocoa-related examples (the demo IDE, the Rubix and Webkit
     427   examples) have been rewritten to use the new bridge features.
     428   (I may have missed some contributed examples; if people want
     429   to convert these, that'd be great.)  It's too early to say
     430   whether the new approach is better or worse than the old, but
     431   I've (so far) found some of the code easier to read and maintain.
     432   We might find that some things that (for instance) SEND does
     433   more efficiently could and should be done via SEND (I'm thinking
     434   mostly of struct-return stuff), but so far I haven't seen the
     435   new stuff keel over.
     437   The converted code looks like "lisp code with strange-looking
     438   function names" at first glance, and that seems about right.
     439   The function names might get to look more familiar as the
     440   reader becomes more familiar with Cocoa; as someone here pointed
     441   out, it's arguably good that the function names are distinctive
     442   in that that helps to remind the reader that these are likely
     443   lower-level functions that are less tolerant of type- and other
     444   errors than the typical lisp function would be.
    1448OpenMCL 1.1-pre-070214
    2449- The FASL version changed (old FASL files won't work with this
Note: See TracChangeset for help on using the changeset viewer.