aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2017-04-04 14:06:25 -0700
committerPaul Eggert2017-04-04 14:07:54 -0700
commit82b9efc869dddcbd5677867b84b20ae155b5b9da (patch)
treec570068c6e5801726a2ea05474a3779bf5cd4fd6 /src
parent12317ff4fb53f889a69a858a629df6beffacd051 (diff)
downloademacs-82b9efc869dddcbd5677867b84b20ae155b5b9da.tar.gz
emacs-82b9efc869dddcbd5677867b84b20ae155b5b9da.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c67
1 files changed, 19 insertions, 48 deletions
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,
3371 eassert (0 <= tag && tag <= PVEC_FONT); 3371 eassert (0 <= tag && tag <= PVEC_FONT);
3372 eassert (0 <= lisplen && lisplen <= zerolen && zerolen <= memlen); 3372 eassert (0 <= lisplen && lisplen <= zerolen && zerolen <= memlen);
3373 eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1); 3373 eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1);
3374 eassert (lisplen <= (1 << PSEUDOVECTOR_SIZE_BITS) - 1); 3374 eassert (lisplen <= PSEUDOVECTOR_SIZE_MASK);
3375 3375
3376 /* Only the first LISPLEN slots will be traced normally by the GC. */ 3376 /* Only the first LISPLEN slots will be traced normally by the GC. */
3377 memclear (v->contents, zerolen * word_size); 3377 memclear (v->contents, zerolen * word_size);
@@ -3393,16 +3393,17 @@ allocate_buffer (void)
3393} 3393}
3394 3394
3395 3395
3396/* Allocate a new record with COUNT slots. Return NULL if COUNT is 3396/* Allocate a record with COUNT slots. COUNT must be positive, and
3397 too large. */ 3397 includes the type slot. */
3398 3398
3399static struct Lisp_Vector * 3399static struct Lisp_Vector *
3400allocate_record (int count) 3400allocate_record (EMACS_INT count)
3401{ 3401{
3402 if (count >= (1 << PSEUDOVECTOR_SIZE_BITS)) 3402 if (count > PSEUDOVECTOR_SIZE_MASK)
3403 return NULL; 3403 error ("Attempt to allocate a record of %"pI"d slots; max is %d",
3404 3404 count, PSEUDOVECTOR_SIZE_MASK);
3405 struct Lisp_Vector *p = allocate_vector (count); 3405 struct Lisp_Vector *p = allocate_vectorlike (count);
3406 p->header.size = count;
3406 XSETPVECTYPE (p, PVEC_RECORD); 3407 XSETPVECTYPE (p, PVEC_RECORD);
3407 return p; 3408 return p;
3408} 3409}
@@ -3411,53 +3412,29 @@ allocate_record (int count)
3411DEFUN ("make-record", Fmake_record, Smake_record, 3, 3, 0, 3412DEFUN ("make-record", Fmake_record, Smake_record, 3, 3, 0,
3412 doc: /* Create a new record. 3413 doc: /* Create a new record.
3413TYPE is its type as returned by `type-of'. SLOTS is the number of 3414TYPE is its type as returned by `type-of'. SLOTS is the number of
3414slots, each initialized to INIT. The number of slots, including the 3415non-type slots, each initialized to INIT. */)
3415type slot, must fit in PSEUDOVECTOR_SIZE_BITS. */)
3416 (Lisp_Object type, Lisp_Object slots, Lisp_Object init) 3416 (Lisp_Object type, Lisp_Object slots, Lisp_Object init)
3417{ 3417{
3418 Lisp_Object record;
3419 ptrdiff_t size, i;
3420 struct Lisp_Vector *p;
3421
3422 CHECK_NATNUM (slots); 3418 CHECK_NATNUM (slots);
3423 3419 EMACS_INT size = XFASTINT (slots) + 1;
3424 size = XFASTINT (slots) + 1; 3420 struct Lisp_Vector *p = allocate_record (size);
3425 p = allocate_record (size);
3426 if (p == NULL)
3427 error ("Attempt to allocate a record of %"pD"d slots; max is %d",
3428 size, (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
3429
3430 p->contents[0] = type; 3421 p->contents[0] = type;
3431 for (i = 1; i < size; i++) 3422 for (ptrdiff_t i = 1; i < size; i++)
3432 p->contents[i] = init; 3423 p->contents[i] = init;
3433 3424 return make_lisp_ptr (p, Lisp_Vectorlike);
3434 XSETVECTOR (record, p);
3435 return record;
3436} 3425}
3437 3426
3438 3427
3439DEFUN ("record", Frecord, Srecord, 1, MANY, 0, 3428DEFUN ("record", Frecord, Srecord, 1, MANY, 0,
3440 doc: /* Create a new record. 3429 doc: /* Create a new record.
3441TYPE is its type as returned by `type-of'. SLOTS is used to 3430TYPE is its type as returned by `type-of'. SLOTS is used to
3442initialize the record slots with shallow copies of the arguments. The 3431initialize the record slots with shallow copies of the arguments.
3443number of slots, including the type slot, must fit in
3444PSEUDOVECTOR_SIZE_BITS.
3445usage: (record TYPE &rest SLOTS) */) 3432usage: (record TYPE &rest SLOTS) */)
3446 (ptrdiff_t nargs, Lisp_Object *args) 3433 (ptrdiff_t nargs, Lisp_Object *args)
3447{ 3434{
3448 struct Lisp_Vector *p = allocate_record (nargs); 3435 struct Lisp_Vector *p = allocate_record (nargs);
3449 if (p == NULL) 3436 memcpy (p->contents, args, nargs * sizeof *args);
3450 error ("Attempt to allocate a record of %"pD"d slots; max is %d", 3437 return make_lisp_ptr (p, Lisp_Vectorlike);
3451 nargs, (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
3452
3453 Lisp_Object type = args[0];
3454 Lisp_Object record;
3455
3456 p->contents[0] = type;
3457 memcpy (p->contents + 1, args + 1, (nargs - 1) * sizeof *args);
3458
3459 XSETVECTOR (record, p);
3460 return record;
3461} 3438}
3462 3439
3463 3440
@@ -3466,17 +3443,11 @@ DEFUN ("copy-record", Fcopy_record, Scopy_record, 1, 1, 0,
3466 (Lisp_Object record) 3443 (Lisp_Object record)
3467{ 3444{
3468 CHECK_RECORD (record); 3445 CHECK_RECORD (record);
3469 struct Lisp_Vector *src = XVECTOR (record);
3470 ptrdiff_t size = ASIZE (record) & PSEUDOVECTOR_SIZE_MASK; 3446 ptrdiff_t size = ASIZE (record) & PSEUDOVECTOR_SIZE_MASK;
3471 struct Lisp_Vector *new = allocate_record (size); 3447 struct Lisp_Vector *new = allocate_record (size);
3472 if (new == NULL) 3448 memcpy (new->contents, XVECTOR (record)->contents,
3473 error ("Attempt to allocate a record of %"pD"d slots; max is %d",
3474 size, (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
3475
3476 memcpy (&(new->contents[0]), &(src->contents[0]),
3477 size * sizeof (Lisp_Object)); 3449 size * sizeof (Lisp_Object));
3478 XSETVECTOR (record, new); 3450 return make_lisp_ptr (new, Lisp_Vectorlike);
3479 return record;
3480} 3451}
3481 3452
3482 3453