On Sun, Jul 18, 2010 at 7:53 AM, David Kastrup <d...@gnu.org> wrote: <snip rant and anti-rant>
> File: elisp, Node: Writing Emacs Primitives, Next: Object Internals, > Prev: Memory Usage, Up: GNU Emacs Internals > > E.5 Writing Emacs Primitives > ============================ > > Lisp primitives are Lisp functions implemented in C. The details of > interfacing the C function so that Lisp can call it are handled by a few > C macros. The only way to really understand how to write new C code is > to read the source, but we can explain some things here. > > An example of a special form is the definition of `or', from > `eval.c'. (An ordinary function would have the same general > appearance.) > > DEFUN ("or", For, Sor, 0, UNEVALLED, 0, > doc: /* Eval args until one of them yields non-nil, then return that > value. The remaining args are not evalled at all. > If all args return nil, return nil. > usage: (or CONDITIONS ...) */) > (Lisp_Object args) > { > register Lisp_Object val = Qnil; > struct gcpro gcpro1; > > GCPRO1 (args); > > while (CONSP (args)) > { > val = Feval (XCAR (args)); > if (!NILP (val)) > break; > args = XCDR (args); > } > > UNGCPRO; > return val; > } > > Let's start with a precise explanation of the arguments to the > `DEFUN' macro. Here is a template for them: > > DEFUN (LNAME, FNAME, SNAME, MIN, MAX, INTERACTIVE, DOC) > > LNAME > This is the name of the Lisp symbol to define as the function > name; in the example above, it is `or'. > > FNAME > This is the C function name for this function. This is the name > that is used in C code for calling the function. The name is, by > convention, `F' prepended to the Lisp name, with all dashes (`-') > in the Lisp name changed to underscores. Thus, to call this > function from C code, call `For'. Remember that the arguments must > be of type `Lisp_Object'; various macros and functions for creating > values of type `Lisp_Object' are declared in the file `lisp.h'. > > SNAME > This is a C variable name to use for a structure that holds the > data for the subr object that represents the function in Lisp. > This structure conveys the Lisp symbol name to the initialization > routine that will create the symbol and store the subr object as > its definition. By convention, this name is always FNAME with `F' > replaced with `S'. > > MIN > This is the minimum number of arguments that the function > requires. The function `or' allows a minimum of zero arguments. > > MAX > This is the maximum number of arguments that the function accepts, > if there is a fixed maximum. Alternatively, it can be `UNEVALLED', > indicating a special form that receives unevaluated arguments, or > `MANY', indicating an unlimited number of evaluated arguments (the > equivalent of `&rest'). Both `UNEVALLED' and `MANY' are macros. > If MAX is a number, it may not be less than MIN and it may not be > greater than eight. > > INTERACTIVE > This is an interactive specification, a string such as might be > used as the argument of `interactive' in a Lisp function. In the > case of `or', it is 0 (a null pointer), indicating that `or' > cannot be called interactively. A value of `""' indicates a > function that should receive no arguments when called > interactively. If the value begins with a `(', the string is > evaluated as a Lisp form. > > DOC > This is the documentation string. It uses C comment syntax rather > than C string syntax because comment syntax requires nothing > special to include multiple lines. The `doc:' identifies the > comment that follows as the documentation string. The `/*' and > `*/' delimiters that begin and end the comment are not part of the > documentation string. > > If the last line of the documentation string begins with the > keyword `usage:', the rest of the line is treated as the argument > list for documentation purposes. This way, you can use different > argument names in the documentation string from the ones used in > the C code. `usage:' is required if the function has an unlimited > number of arguments. > > All the usual rules for documentation strings in Lisp code (*note > Documentation Tips::) apply to C code documentation strings too. > > After the call to the `DEFUN' macro, you must write the argument > list that every C function must have, including the types for the > arguments. For a function with a fixed maximum number of arguments, > declare a C argument for each Lisp argument, and give them all type > `Lisp_Object'. When a Lisp function has no upper limit on the number > of arguments, its implementation in C actually receives exactly two > arguments: the first is the number of Lisp arguments, and the second is > the address of a block containing their values. They have types `int' > and `Lisp_Object *'. > > Within the function `For' itself, note the use of the macros > `GCPRO1' and `UNGCPRO'. `GCPRO1' is used to "protect" a variable from > garbage collection--to inform the garbage collector that it must look > in that variable and regard its contents as an accessible object. GC > protection is necessary whenever you call `Feval' or anything that can > directly or indirectly call `Feval'. At such a time, any Lisp object > that this function may refer to again must be protected somehow. > > It suffices to ensure that at least one pointer to each object is > GC-protected; that way, the object cannot be recycled, so all pointers > to it remain valid. Thus, a particular local variable can do without > protection if it is certain that the object it points to will be > preserved by some other pointer (such as another local variable which > has a `GCPRO')(1). Otherwise, the local variable needs a `GCPRO'. > > The macro `GCPRO1' protects just one local variable. If you want to > protect two variables, use `GCPRO2' instead; repeating `GCPRO1' will > not work. Macros `GCPRO3', `GCPRO4', `GCPRO5', and `GCPRO6' also > exist. All these macros implicitly use local variables such as > `gcpro1'; you must declare these explicitly, with type `struct gcpro'. > Thus, if you use `GCPRO2', you must declare `gcpro1' and `gcpro2'. > Alas, we can't explain all the tricky details here. > > `UNGCPRO' cancels the protection of the variables that are protected > in the current function. It is necessary to do this explicitly. > > Built-in functions that take a variable number of arguments actually > accept two arguments at the C level: the number of Lisp arguments, and > a `Lisp_Object *' pointer to a C vector containing those Lisp > arguments. This C vector may be part of a Lisp vector, but it need not > be. The responsibility for using `GCPRO' to protect the Lisp arguments > from GC if necessary rests with the caller in this case, since the > caller allocated or found the storage for them. > > You must not use C initializers for static or global variables unless > the variables are never written once Emacs is dumped. These variables > with initializers are allocated in an area of memory that becomes > read-only (on certain operating systems) as a result of dumping Emacs. > *Note Pure Storage::. > > Do not use static variables within functions--place all static > variables at top level in the file. This is necessary because Emacs on > some operating systems defines the keyword `static' as a null macro. > (This definition is used because those systems put all variables > declared static in a place that becomes read-only after dumping, whether > they have initializers or not.) > > Defining the C function is not enough to make a Lisp primitive > available; you must also create the Lisp symbol for the primitive and > store a suitable subr object in its function cell. The code looks like > this: > > defsubr (&SUBR-STRUCTURE-NAME); > > Here SUBR-STRUCTURE-NAME is the name you used as the third argument to > `DEFUN'. > > If you add a new primitive to a file that already has Lisp primitives > defined in it, find the function (near the end of the file) named > `syms_of_SOMETHING', and add the call to `defsubr' there. If the file > doesn't have this function, or if you create a new file, add to it a > `syms_of_FILENAME' (e.g., `syms_of_myfile'). Then find the spot in > `emacs.c' where all of these functions are called, and add a call to > `syms_of_FILENAME' there. > > The function `syms_of_FILENAME' is also the place to define any C > variables that are to be visible as Lisp variables. `DEFVAR_LISP' > makes a C variable of type `Lisp_Object' visible in Lisp. `DEFVAR_INT' > makes a C variable of type `int' visible in Lisp with a value that is > always an integer. `DEFVAR_BOOL' makes a C variable of type `int' > visible in Lisp with a value that is either `t' or `nil'. Note that > variables defined with `DEFVAR_BOOL' are automatically added to the list > `byte-boolean-vars' used by the byte compiler. > > If you define a file-scope C variable of type `Lisp_Object', you > must protect it from garbage-collection by calling `staticpro' in > `syms_of_FILENAME', like this: > > staticpro (&VARIABLE); > > Here is another example function, with more complicated arguments. > This comes from the code in `window.c', and it demonstrates the use of > macros and functions to manipulate Lisp objects. > > DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, > Scoordinates_in_window_p, 2, 2, > "xSpecify coordinate pair: \nXExpression which evals to window: ", > "Return non-nil if COORDINATES is in WINDOW.\n\ > COORDINATES is a cons of the form (X . Y), X and Y being distances\n\ > ... > If they are on the border between WINDOW and its right sibling,\n\ > `vertical-line' is returned.") > (coordinates, window) > register Lisp_Object coordinates, window; > { > int x, y; > > CHECK_LIVE_WINDOW (window, 0); > CHECK_CONS (coordinates, 1); > x = XINT (Fcar (coordinates)); > y = XINT (Fcdr (coordinates)); > > switch (coordinates_in_window (XWINDOW (window), &x, &y)) > { > case 0: /* NOT in window at all. */ > return Qnil; > > case 1: /* In text part of window. */ > return Fcons (make_number (x), make_number (y)); > > case 2: /* In mode line of window. */ > return Qmode_line; > > case 3: /* On right border of window. */ > return Qvertical_line; > > default: > abort (); > } > } > > Note that C code cannot call functions by name unless they are > defined in C. The way to call a function written in Lisp is to use > `Ffuncall', which embodies the Lisp function `funcall'. Since the Lisp > function `funcall' accepts an unlimited number of arguments, in C it > takes two: the number of Lisp-level arguments, and a one-dimensional > array containing their values. The first Lisp-level argument is the > Lisp function to call, and the rest are the arguments to pass to it. > Since `Ffuncall' can call the evaluator, you must protect pointers from > garbage collection around the call to `Ffuncall'. > > The C functions `call0', `call1', `call2', and so on, provide handy > ways to call a Lisp function conveniently with a fixed number of > arguments. They work by calling `Ffuncall'. > > `eval.c' is a very good file to look through for examples; `lisp.h' > contains the definitions for some important macros and functions. > > If you define a function which is side-effect free, update the code > in `byte-opt.el' which binds `side-effect-free-fns' and > `side-effect-and-error-free-fns' so that the compiler optimizer knows > about it. > > ---------- Footnotes ---------- > > (1) Formerly, strings were a special exception; in older Emacs > versions, every local variable that might point to a string needed a > `GCPRO'. > <moar snip> To me, this is amazing documentation. I would love it if there were something this explicit for the C API. Geremy Condra -- http://mail.python.org/mailman/listinfo/python-list