From 82b9efc869dddcbd5677867b84b20ae155b5b9da Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 4 Apr 2017 14:06:25 -0700 Subject: [PATCH] Minor simplifications and doc for records * doc/lispref/records.texi (Records): Mention size limit. * etc/NEWS: Mention records. * src/alloc.c (allocate_pseudovector, allocate_record): Prefer 'PSEUDOVECTOR_SIZE_MASK' to its definiens. (allocate_record): Check arg range here, not in callers, as this simplifies the code. Use allocate_vectorlike instead of allocate_vector, to avoid duplicate runtime tests. (Fmake_record, record): Don't mention PSEUDOVECTOR_SIZE_BITS in the doc string, as it is not visible to the user. (Fmake_record, record, Fcopy_record): Prefer make_lisp_ptr to XSETVECTOR. (record): Broaden memcpy to copy the type, too. --- doc/lispref/records.texi | 6 ++-- etc/NEWS | 6 ++++ src/alloc.c | 67 ++++++++++++---------------------------- 3 files changed, 29 insertions(+), 50 deletions(-) diff --git a/doc/lispref/records.texi b/doc/lispref/records.texi index 9a5d900cfc9..a6c560cbcb9 100644 --- a/doc/lispref/records.texi +++ b/doc/lispref/records.texi @@ -14,8 +14,10 @@ instances. Internally, a record object is much like a vector; its slots can be accessed using @code{aref}. However, the first slot is used to hold -its type as returned by @code{type-of}. Like arrays, records use -zero-origin indexing: the first slot has index 0. +its type as returned by @code{type-of}. Also, in the current +implementation records can have at most 4096 slots, whereas vectors +can be much larger. Like arrays, records use zero-origin indexing: +the first slot has index 0. The printed representation of records is @samp{#s} followed by a list specifying the contents. The first list element must be the diff --git a/etc/NEWS b/etc/NEWS index fc076569862..8b17f1648bf 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -839,6 +839,12 @@ instead of its first. * Lisp Changes in Emacs 26.1 ++++ +** Emacs now supports records for user-defined types, via the new +functions 'copy-record', 'make-record', 'record', and 'recordp'. +Records are now used internally to represent cl-defstruct and defclass +instances, for example. + +++ ** 'save-some-buffers' now uses 'save-some-buffers-default-predicate' to decide which buffers to ask about, if the PRED argument is nil. diff --git a/src/alloc.c b/src/alloc.c index 5024b1211e5..a58824fb0f3 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -3371,7 +3371,7 @@ allocate_pseudovector (int memlen, int lisplen, eassert (0 <= tag && tag <= PVEC_FONT); eassert (0 <= lisplen && lisplen <= zerolen && zerolen <= memlen); eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1); - eassert (lisplen <= (1 << PSEUDOVECTOR_SIZE_BITS) - 1); + eassert (lisplen <= PSEUDOVECTOR_SIZE_MASK); /* Only the first LISPLEN slots will be traced normally by the GC. */ memclear (v->contents, zerolen * word_size); @@ -3393,16 +3393,17 @@ allocate_buffer (void) } -/* Allocate a new record with COUNT slots. Return NULL if COUNT is - too large. */ +/* Allocate a record with COUNT slots. COUNT must be positive, and + includes the type slot. */ static struct Lisp_Vector * -allocate_record (int count) +allocate_record (EMACS_INT count) { - if (count >= (1 << PSEUDOVECTOR_SIZE_BITS)) - return NULL; - - struct Lisp_Vector *p = allocate_vector (count); + if (count > PSEUDOVECTOR_SIZE_MASK) + error ("Attempt to allocate a record of %"pI"d slots; max is %d", + count, PSEUDOVECTOR_SIZE_MASK); + struct Lisp_Vector *p = allocate_vectorlike (count); + p->header.size = count; XSETPVECTYPE (p, PVEC_RECORD); return p; } @@ -3411,53 +3412,29 @@ allocate_record (int count) DEFUN ("make-record", Fmake_record, Smake_record, 3, 3, 0, doc: /* Create a new record. TYPE is its type as returned by `type-of'. SLOTS is the number of -slots, each initialized to INIT. The number of slots, including the -type slot, must fit in PSEUDOVECTOR_SIZE_BITS. */) +non-type slots, each initialized to INIT. */) (Lisp_Object type, Lisp_Object slots, Lisp_Object init) { - Lisp_Object record; - ptrdiff_t size, i; - struct Lisp_Vector *p; - CHECK_NATNUM (slots); - - size = XFASTINT (slots) + 1; - p = allocate_record (size); - if (p == NULL) - error ("Attempt to allocate a record of %"pD"d slots; max is %d", - size, (1 << PSEUDOVECTOR_SIZE_BITS) - 1); - + EMACS_INT size = XFASTINT (slots) + 1; + struct Lisp_Vector *p = allocate_record (size); p->contents[0] = type; - for (i = 1; i < size; i++) + for (ptrdiff_t i = 1; i < size; i++) p->contents[i] = init; - - XSETVECTOR (record, p); - return record; + return make_lisp_ptr (p, Lisp_Vectorlike); } DEFUN ("record", Frecord, Srecord, 1, MANY, 0, doc: /* Create a new record. TYPE is its type as returned by `type-of'. SLOTS is used to -initialize the record slots with shallow copies of the arguments. The -number of slots, including the type slot, must fit in -PSEUDOVECTOR_SIZE_BITS. +initialize the record slots with shallow copies of the arguments. usage: (record TYPE &rest SLOTS) */) (ptrdiff_t nargs, Lisp_Object *args) { struct Lisp_Vector *p = allocate_record (nargs); - if (p == NULL) - error ("Attempt to allocate a record of %"pD"d slots; max is %d", - nargs, (1 << PSEUDOVECTOR_SIZE_BITS) - 1); - - Lisp_Object type = args[0]; - Lisp_Object record; - - p->contents[0] = type; - memcpy (p->contents + 1, args + 1, (nargs - 1) * sizeof *args); - - XSETVECTOR (record, p); - return record; + memcpy (p->contents, args, nargs * sizeof *args); + return make_lisp_ptr (p, Lisp_Vectorlike); } @@ -3466,17 +3443,11 @@ DEFUN ("copy-record", Fcopy_record, Scopy_record, 1, 1, 0, (Lisp_Object record) { CHECK_RECORD (record); - struct Lisp_Vector *src = XVECTOR (record); ptrdiff_t size = ASIZE (record) & PSEUDOVECTOR_SIZE_MASK; struct Lisp_Vector *new = allocate_record (size); - if (new == NULL) - error ("Attempt to allocate a record of %"pD"d slots; max is %d", - size, (1 << PSEUDOVECTOR_SIZE_BITS) - 1); - - memcpy (&(new->contents[0]), &(src->contents[0]), + memcpy (new->contents, XVECTOR (record)->contents, size * sizeof (Lisp_Object)); - XSETVECTOR (record, new); - return record; + return make_lisp_ptr (new, Lisp_Vectorlike); } -- 2.39.2