diff options
| author | Paul Eggert | 2017-04-04 14:06:25 -0700 |
|---|---|---|
| committer | Paul Eggert | 2017-04-04 14:07:54 -0700 |
| commit | 82b9efc869dddcbd5677867b84b20ae155b5b9da (patch) | |
| tree | c570068c6e5801726a2ea05474a3779bf5cd4fd6 /src/alloc.c | |
| parent | 12317ff4fb53f889a69a858a629df6beffacd051 (diff) | |
| download | emacs-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/alloc.c')
| -rw-r--r-- | src/alloc.c | 67 |
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 | ||
| 3399 | static struct Lisp_Vector * | 3399 | static struct Lisp_Vector * |
| 3400 | allocate_record (int count) | 3400 | allocate_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) | |||
| 3411 | DEFUN ("make-record", Fmake_record, Smake_record, 3, 3, 0, | 3412 | DEFUN ("make-record", Fmake_record, Smake_record, 3, 3, 0, |
| 3412 | doc: /* Create a new record. | 3413 | doc: /* Create a new record. |
| 3413 | TYPE is its type as returned by `type-of'. SLOTS is the number of | 3414 | TYPE is its type as returned by `type-of'. SLOTS is the number of |
| 3414 | slots, each initialized to INIT. The number of slots, including the | 3415 | non-type slots, each initialized to INIT. */) |
| 3415 | type 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 | ||
| 3439 | DEFUN ("record", Frecord, Srecord, 1, MANY, 0, | 3428 | DEFUN ("record", Frecord, Srecord, 1, MANY, 0, |
| 3440 | doc: /* Create a new record. | 3429 | doc: /* Create a new record. |
| 3441 | TYPE is its type as returned by `type-of'. SLOTS is used to | 3430 | TYPE is its type as returned by `type-of'. SLOTS is used to |
| 3442 | initialize the record slots with shallow copies of the arguments. The | 3431 | initialize the record slots with shallow copies of the arguments. |
| 3443 | number of slots, including the type slot, must fit in | ||
| 3444 | PSEUDOVECTOR_SIZE_BITS. | ||
| 3445 | usage: (record TYPE &rest SLOTS) */) | 3432 | usage: (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 | ||