summaryrefslogtreecommitdiff
path: root/src/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c483
1 files changed, 291 insertions, 192 deletions
diff --git a/src/data.c b/src/data.c
index 3a51129d182..e2c1a288a8f 100644
--- a/src/data.c
+++ b/src/data.c
@@ -31,6 +31,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "character.h"
#include "buffer.h"
#include "keyboard.h"
+#include "process.h"
#include "frame.h"
#include "keymap.h"
@@ -138,7 +139,7 @@ wrong_length_argument (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
make_number (bool_vector_size (a3)));
}
-Lisp_Object
+_Noreturn void
wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value)
{
/* If VALUE is not even a valid Lisp object, we'd want to abort here
@@ -258,6 +259,12 @@ for example, (type-of 1) returns `integer'. */)
return Qfont_entity;
if (FONT_OBJECT_P (object))
return Qfont_object;
+ if (THREADP (object))
+ return Qthread;
+ if (MUTEXP (object))
+ return Qmutex;
+ if (CONDVARP (object))
+ return Qcondition_variable;
return Qvector;
case Lisp_Float:
@@ -528,6 +535,33 @@ DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0,
return Qnil;
}
+DEFUN ("threadp", Fthreadp, Sthreadp, 1, 1, 0,
+ doc: /* Return t if OBJECT is a thread. */)
+ (Lisp_Object object)
+{
+ if (THREADP (object))
+ return Qt;
+ return Qnil;
+}
+
+DEFUN ("mutexp", Fmutexp, Smutexp, 1, 1, 0,
+ doc: /* Return t if OBJECT is a mutex. */)
+ (Lisp_Object object)
+{
+ if (MUTEXP (object))
+ return Qt;
+ return Qnil;
+}
+
+DEFUN ("condition-variable-p", Fcondition_variable_p, Scondition_variable_p,
+ 1, 1, 0,
+ doc: /* Return t if OBJECT is a condition variable. */)
+ (Lisp_Object object)
+{
+ if (CONDVARP (object))
+ return Qt;
+ return Qnil;
+}
/* Extract and set components of lists. */
@@ -700,6 +734,9 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
{
register Lisp_Object function;
CHECK_SYMBOL (symbol);
+ /* Perhaps not quite the right error signal, but seems good enough. */
+ if (NILP (symbol))
+ xsignal1 (Qsetting_constant, symbol);
function = XSYMBOL (symbol)->function;
@@ -1140,9 +1177,7 @@ swap_in_symval_forwarding (struct Lisp_Symbol *symbol, struct Lisp_Buffer_Local_
tem1 = blv->where;
if (NILP (tem1)
- || (blv->frame_local
- ? !EQ (selected_frame, tem1)
- : current_buffer != XBUFFER (tem1)))
+ || current_buffer != XBUFFER (tem1))
{
/* Unload the previously loaded binding. */
@@ -1153,16 +1188,8 @@ swap_in_symval_forwarding (struct Lisp_Symbol *symbol, struct Lisp_Buffer_Local_
{
Lisp_Object var;
XSETSYMBOL (var, symbol);
- if (blv->frame_local)
- {
- tem1 = assq_no_quit (var, XFRAME (selected_frame)->param_alist);
- set_blv_where (blv, selected_frame);
- }
- else
- {
- tem1 = assq_no_quit (var, BVAR (current_buffer, local_var_alist));
- set_blv_where (blv, Fcurrent_buffer ());
- }
+ tem1 = assq_no_quit (var, BVAR (current_buffer, local_var_alist));
+ set_blv_where (blv, Fcurrent_buffer ());
}
if (!(blv->found = !NILP (tem1)))
tem1 = blv->defcell;
@@ -1225,21 +1252,22 @@ DEFUN ("set", Fset, Sset, 2, 2, 0,
doc: /* Set SYMBOL's value to NEWVAL, and return NEWVAL. */)
(register Lisp_Object symbol, Lisp_Object newval)
{
- set_internal (symbol, newval, Qnil, 0);
+ set_internal (symbol, newval, Qnil, SET_INTERNAL_SET);
return newval;
}
/* Store the value NEWVAL into SYMBOL.
- If buffer/frame-locality is an issue, WHERE specifies which context to use.
+ If buffer-locality is an issue, WHERE specifies which context to use.
(nil stands for the current buffer/frame).
- If BINDFLAG is false, then if this symbol is supposed to become
- local in every buffer where it is set, then we make it local.
- If BINDFLAG is true, we don't do that. */
+ If BINDFLAG is SET_INTERNAL_SET, then if this symbol is supposed to
+ become local in every buffer where it is set, then we make it
+ local. If BINDFLAG is SET_INTERNAL_BIND or SET_INTERNAL_UNBIND, we
+ don't do that. */
void
set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
- bool bindflag)
+ enum Set_Internal_Bind bindflag)
{
bool voide = EQ (newval, Qunbound);
struct Lisp_Symbol *sym;
@@ -1250,18 +1278,31 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
return; */
CHECK_SYMBOL (symbol);
- if (SYMBOL_CONSTANT_P (symbol))
+ sym = XSYMBOL (symbol);
+ switch (sym->trapped_write)
{
+ case SYMBOL_NOWRITE:
if (NILP (Fkeywordp (symbol))
- || !EQ (newval, Fsymbol_value (symbol)))
- xsignal1 (Qsetting_constant, symbol);
+ || !EQ (newval, Fsymbol_value (symbol)))
+ xsignal1 (Qsetting_constant, symbol);
else
- /* Allow setting keywords to their own value. */
- return;
- }
+ /* Allow setting keywords to their own value. */
+ return;
+
+ case SYMBOL_TRAPPED_WRITE:
+ /* Setting due to thread-switching doesn't count. */
+ if (bindflag != SET_INTERNAL_THREAD_SWITCH)
+ notify_variable_watchers (symbol, voide? Qnil : newval,
+ (bindflag == SET_INTERNAL_BIND? Qlet :
+ bindflag == SET_INTERNAL_UNBIND? Qunlet :
+ voide? Qmakunbound : Qset),
+ where);
+ /* FALLTHROUGH! */
+ case SYMBOL_UNTRAPPED_WRITE:
+ break;
- maybe_set_redisplay (symbol);
- sym = XSYMBOL (symbol);
+ default: emacs_abort ();
+ }
start:
switch (sym->redirect)
@@ -1272,15 +1313,10 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
{
struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
if (NILP (where))
- {
- if (blv->frame_local)
- where = selected_frame;
- else
- XSETBUFFER (where, current_buffer);
- }
+ XSETBUFFER (where, current_buffer);
+
/* If the current buffer is not the buffer whose binding is
- loaded, or if there may be frame-local bindings and the frame
- isn't the right one, or if it's a Lisp_Buffer_Local_Value and
+ loaded, or if it's a Lisp_Buffer_Local_Value and
the default binding is loaded, the loaded binding may be the
wrong one. */
if (!EQ (blv->where, where)
@@ -1297,9 +1333,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
/* Find the new binding. */
XSETSYMBOL (symbol, sym); /* May have changed via aliasing. */
tem1 = assq_no_quit (symbol,
- (blv->frame_local
- ? XFRAME (where)->param_alist
- : BVAR (XBUFFER (where), local_var_alist)));
+ BVAR (XBUFFER (where), local_var_alist));
set_blv_where (blv, where);
blv->found = 1;
@@ -1326,9 +1360,6 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
and load that binding. */
else
{
- /* local_if_set is only supported for buffer-local
- bindings, not for frame-local bindings. */
- eassert (!blv->frame_local);
tem1 = Fcons (symbol, XCDR (blv->defcell));
bset_local_var_alist
(XBUFFER (where),
@@ -1366,7 +1397,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
int offset = XBUFFER_OBJFWD (innercontents)->offset;
int idx = PER_BUFFER_IDX (offset);
if (idx > 0
- && !bindflag
+ && bindflag == SET_INTERNAL_SET
&& !let_shadows_buffer_binding_p (sym))
SET_PER_BUFFER_VALUE_P (buf, idx, 1);
}
@@ -1385,6 +1416,127 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
}
return;
}
+
+static void
+set_symbol_trapped_write (Lisp_Object symbol, enum symbol_trapped_write trap)
+{
+ struct Lisp_Symbol* sym = XSYMBOL (symbol);
+ if (sym->trapped_write == SYMBOL_NOWRITE)
+ xsignal1 (Qtrapping_constant, symbol);
+ sym->trapped_write = trap;
+}
+
+static void
+restore_symbol_trapped_write (Lisp_Object symbol)
+{
+ set_symbol_trapped_write (symbol, SYMBOL_TRAPPED_WRITE);
+}
+
+static void
+harmonize_variable_watchers (Lisp_Object alias, Lisp_Object base_variable)
+{
+ if (!EQ (base_variable, alias)
+ && EQ (base_variable, Findirect_variable (alias)))
+ set_symbol_trapped_write
+ (alias, XSYMBOL (base_variable)->trapped_write);
+}
+
+DEFUN ("add-variable-watcher", Fadd_variable_watcher, Sadd_variable_watcher,
+ 2, 2, 0,
+ doc: /* Cause WATCH-FUNCTION to be called when SYMBOL is set.
+
+It will be called with 4 arguments: (SYMBOL NEWVAL OPERATION WHERE).
+SYMBOL is the variable being changed.
+NEWVAL is the value it will be changed to.
+OPERATION is a symbol representing the kind of change, one of: `set',
+`let', `unlet', `makunbound', and `defvaralias'.
+WHERE is a buffer if the buffer-local value of the variable being
+changed, nil otherwise.
+
+All writes to aliases of SYMBOL will call WATCH-FUNCTION too. */)
+ (Lisp_Object symbol, Lisp_Object watch_function)
+{
+ symbol = Findirect_variable (symbol);
+ set_symbol_trapped_write (symbol, SYMBOL_TRAPPED_WRITE);
+ map_obarray (Vobarray, harmonize_variable_watchers, symbol);
+
+ Lisp_Object watchers = Fget (symbol, Qwatchers);
+ Lisp_Object member = Fmember (watch_function, watchers);
+ if (NILP (member))
+ Fput (symbol, Qwatchers, Fcons (watch_function, watchers));
+ return Qnil;
+}
+
+DEFUN ("remove-variable-watcher", Fremove_variable_watcher, Sremove_variable_watcher,
+ 2, 2, 0,
+ doc: /* Undo the effect of `add-variable-watcher'.
+Remove WATCH-FUNCTION from the list of functions to be called when
+SYMBOL (or its aliases) are set. */)
+ (Lisp_Object symbol, Lisp_Object watch_function)
+{
+ symbol = Findirect_variable (symbol);
+ Lisp_Object watchers = Fget (symbol, Qwatchers);
+ watchers = Fdelete (watch_function, watchers);
+ if (NILP (watchers))
+ {
+ set_symbol_trapped_write (symbol, SYMBOL_UNTRAPPED_WRITE);
+ map_obarray (Vobarray, harmonize_variable_watchers, symbol);
+ }
+ Fput (symbol, Qwatchers, watchers);
+ return Qnil;
+}
+
+DEFUN ("get-variable-watchers", Fget_variable_watchers, Sget_variable_watchers,
+ 1, 1, 0,
+ doc: /* Return a list of SYMBOL's active watchers. */)
+ (Lisp_Object symbol)
+{
+ return (SYMBOL_TRAPPED_WRITE_P (symbol) == SYMBOL_TRAPPED_WRITE)
+ ? Fget (Findirect_variable (symbol), Qwatchers)
+ : Qnil;
+}
+
+void
+notify_variable_watchers (Lisp_Object symbol,
+ Lisp_Object newval,
+ Lisp_Object operation,
+ Lisp_Object where)
+{
+ symbol = Findirect_variable (symbol);
+
+ ptrdiff_t count = SPECPDL_INDEX ();
+ record_unwind_protect (restore_symbol_trapped_write, symbol);
+ /* Avoid recursion. */
+ set_symbol_trapped_write (symbol, SYMBOL_UNTRAPPED_WRITE);
+
+ if (NILP (where)
+ && !EQ (operation, Qset_default) && !EQ (operation, Qmakunbound)
+ && !NILP (Flocal_variable_if_set_p (symbol, Fcurrent_buffer ())))
+ {
+ XSETBUFFER (where, current_buffer);
+ }
+
+ if (EQ (operation, Qset_default))
+ operation = Qset;
+
+ for (Lisp_Object watchers = Fget (symbol, Qwatchers);
+ CONSP (watchers);
+ watchers = XCDR (watchers))
+ {
+ Lisp_Object watcher = XCAR (watchers);
+ /* Call subr directly to avoid gc. */
+ if (SUBRP (watcher))
+ {
+ Lisp_Object args[] = { symbol, newval, operation, where };
+ funcall_subr (XSUBR (watcher), ARRAYELTS (args), args);
+ }
+ else
+ CALLN (Ffuncall, watcher, symbol, newval, operation, where);
+ }
+
+ unbind_to (count, Qnil);
+}
+
/* Access or set a buffer-local symbol's default value. */
@@ -1462,31 +1614,42 @@ local bindings in certain buffers. */)
xsignal1 (Qvoid_variable, symbol);
}
-DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0,
- doc: /* Set SYMBOL's default value to VALUE. SYMBOL and VALUE are evaluated.
-The default value is seen in buffers that do not have their own values
-for this variable. */)
- (Lisp_Object symbol, Lisp_Object value)
+void
+set_default_internal (Lisp_Object symbol, Lisp_Object value,
+ enum Set_Internal_Bind bindflag)
{
struct Lisp_Symbol *sym;
CHECK_SYMBOL (symbol);
- if (SYMBOL_CONSTANT_P (symbol))
+ sym = XSYMBOL (symbol);
+ switch (sym->trapped_write)
{
+ case SYMBOL_NOWRITE:
if (NILP (Fkeywordp (symbol))
- || !EQ (value, Fdefault_value (symbol)))
- xsignal1 (Qsetting_constant, symbol);
+ || !EQ (value, Fsymbol_value (symbol)))
+ xsignal1 (Qsetting_constant, symbol);
else
- /* Allow setting keywords to their own value. */
- return value;
+ /* Allow setting keywords to their own value. */
+ return;
+
+ case SYMBOL_TRAPPED_WRITE:
+ /* Don't notify here if we're going to call Fset anyway. */
+ if (sym->redirect != SYMBOL_PLAINVAL
+ /* Setting due to thread switching doesn't count. */
+ && bindflag != SET_INTERNAL_THREAD_SWITCH)
+ notify_variable_watchers (symbol, value, Qset_default, Qnil);
+ /* FALLTHROUGH! */
+ case SYMBOL_UNTRAPPED_WRITE:
+ break;
+
+ default: emacs_abort ();
}
- sym = XSYMBOL (symbol);
start:
switch (sym->redirect)
{
case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
- case SYMBOL_PLAINVAL: return Fset (symbol, value);
+ case SYMBOL_PLAINVAL: set_internal (symbol, value, Qnil, bindflag); return;
case SYMBOL_LOCALIZED:
{
struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
@@ -1497,7 +1660,7 @@ for this variable. */)
/* If the default binding is now loaded, set the REALVALUE slot too. */
if (blv->fwd && EQ (blv->defcell, blv->valcell))
store_symval_forwarding (blv->fwd, value, NULL);
- return value;
+ return;
}
case SYMBOL_FORWARDED:
{
@@ -1523,15 +1686,25 @@ for this variable. */)
if (!PER_BUFFER_VALUE_P (b, idx))
set_per_buffer_value (b, offset, value);
}
- return value;
}
else
- return Fset (symbol, value);
+ set_internal (symbol, value, Qnil, bindflag);
+ return;
}
default: emacs_abort ();
}
}
+DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0,
+ doc: /* Set SYMBOL's default value to VALUE. SYMBOL and VALUE are evaluated.
+The default value is seen in buffers that do not have their own values
+for this variable. */)
+ (Lisp_Object symbol, Lisp_Object value)
+{
+ set_default_internal (symbol, value, SET_INTERNAL_SET);
+ return value;
+}
+
DEFUN ("setq-default", Fsetq_default, Ssetq_default, 0, UNEVALLED, 0,
doc: /* Set the default value of variable VAR to VALUE.
VAR, the variable name, is literal (not evaluated);
@@ -1589,7 +1762,6 @@ make_blv (struct Lisp_Symbol *sym, bool forwarded,
eassert (!(forwarded && KBOARD_OBJFWDP (valcontents.fwd)));
blv->fwd = forwarded ? valcontents.fwd : NULL;
set_blv_where (blv, Qnil);
- blv->frame_local = 0;
blv->local_if_set = 0;
set_blv_defcell (blv, tem);
set_blv_valcell (blv, tem);
@@ -1619,8 +1791,8 @@ The function `default-value' gets the default value and `set-default' sets it.
{
struct Lisp_Symbol *sym;
struct Lisp_Buffer_Local_Value *blv = NULL;
- union Lisp_Val_Fwd valcontents IF_LINT (= {LISP_INITIALLY_ZERO});
- bool forwarded IF_LINT (= 0);
+ union Lisp_Val_Fwd valcontents;
+ bool forwarded;
CHECK_SYMBOL (variable);
sym = XSYMBOL (variable);
@@ -1636,9 +1808,6 @@ The function `default-value' gets the default value and `set-default' sets it.
break;
case SYMBOL_LOCALIZED:
blv = SYMBOL_BLV (sym);
- if (blv->frame_local)
- error ("Symbol %s may not be buffer-local",
- SDATA (SYMBOL_NAME (variable)));
break;
case SYMBOL_FORWARDED:
forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym);
@@ -1651,7 +1820,7 @@ The function `default-value' gets the default value and `set-default' sets it.
default: emacs_abort ();
}
- if (sym->constant)
+ if (SYMBOL_CONSTANT_P (variable))
error ("Symbol %s may not be buffer-local", SDATA (SYMBOL_NAME (variable)));
if (!blv)
@@ -1697,8 +1866,8 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
(Lisp_Object variable)
{
Lisp_Object tem;
- bool forwarded IF_LINT (= 0);
- union Lisp_Val_Fwd valcontents IF_LINT (= {LISP_INITIALLY_ZERO});
+ bool forwarded;
+ union Lisp_Val_Fwd valcontents;
struct Lisp_Symbol *sym;
struct Lisp_Buffer_Local_Value *blv = NULL;
@@ -1713,9 +1882,6 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
forwarded = 0; valcontents.value = SYMBOL_VAL (sym); break;
case SYMBOL_LOCALIZED:
blv = SYMBOL_BLV (sym);
- if (blv->frame_local)
- error ("Symbol %s may not be buffer-local",
- SDATA (SYMBOL_NAME (variable)));
break;
case SYMBOL_FORWARDED:
forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym);
@@ -1726,7 +1892,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
default: emacs_abort ();
}
- if (sym->constant)
+ if (sym->trapped_write == SYMBOL_NOWRITE)
error ("Symbol %s may not be buffer-local",
SDATA (SYMBOL_NAME (variable)));
@@ -1832,12 +1998,13 @@ From now on the default value will apply in this buffer. Return VARIABLE. */)
}
case SYMBOL_LOCALIZED:
blv = SYMBOL_BLV (sym);
- if (blv->frame_local)
- return variable;
break;
default: emacs_abort ();
}
+ if (sym->trapped_write == SYMBOL_TRAPPED_WRITE)
+ notify_variable_watchers (variable, Qnil, Qmakunbound, Fcurrent_buffer ());
+
/* Get rid of this buffer's alist element, if any. */
XSETSYMBOL (variable, sym); /* Propagate variable indirection. */
tem = Fassq (variable, BVAR (current_buffer, local_var_alist));
@@ -1864,81 +2031,6 @@ From now on the default value will apply in this buffer. Return VARIABLE. */)
/* Lisp functions for creating and removing buffer-local variables. */
-/* Obsolete since 22.2. NB adjust doc of modify-frame-parameters
- when/if this is removed. */
-
-DEFUN ("make-variable-frame-local", Fmake_variable_frame_local, Smake_variable_frame_local,
- 1, 1, "vMake Variable Frame Local: ",
- doc: /* Enable VARIABLE to have frame-local bindings.
-This does not create any frame-local bindings for VARIABLE,
-it just makes them possible.
-
-A frame-local binding is actually a frame parameter value.
-If a frame F has a value for the frame parameter named VARIABLE,
-that also acts as a frame-local binding for VARIABLE in F--
-provided this function has been called to enable VARIABLE
-to have frame-local bindings at all.
-
-The only way to create a frame-local binding for VARIABLE in a frame
-is to set the VARIABLE frame parameter of that frame. See
-`modify-frame-parameters' for how to set frame parameters.
-
-Note that since Emacs 23.1, variables cannot be both buffer-local and
-frame-local any more (buffer-local bindings used to take precedence over
-frame-local bindings). */)
- (Lisp_Object variable)
-{
- bool forwarded;
- union Lisp_Val_Fwd valcontents;
- struct Lisp_Symbol *sym;
- struct Lisp_Buffer_Local_Value *blv = NULL;
-
- CHECK_SYMBOL (variable);
- sym = XSYMBOL (variable);
-
- start:
- switch (sym->redirect)
- {
- case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
- case SYMBOL_PLAINVAL:
- forwarded = 0; valcontents.value = SYMBOL_VAL (sym);
- if (EQ (valcontents.value, Qunbound))
- valcontents.value = Qnil;
- break;
- case SYMBOL_LOCALIZED:
- if (SYMBOL_BLV (sym)->frame_local)
- return variable;
- else
- error ("Symbol %s may not be frame-local",
- SDATA (SYMBOL_NAME (variable)));
- case SYMBOL_FORWARDED:
- forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym);
- if (KBOARD_OBJFWDP (valcontents.fwd) || BUFFER_OBJFWDP (valcontents.fwd))
- error ("Symbol %s may not be frame-local",
- SDATA (SYMBOL_NAME (variable)));
- break;
- default: emacs_abort ();
- }
-
- if (sym->constant)
- error ("Symbol %s may not be frame-local", SDATA (SYMBOL_NAME (variable)));
-
- blv = make_blv (sym, forwarded, valcontents);
- blv->frame_local = 1;
- sym->redirect = SYMBOL_LOCALIZED;
- SET_SYMBOL_BLV (sym, blv);
- {
- Lisp_Object symbol;
- XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */
- if (let_shadows_global_binding_p (symbol))
- {
- AUTO_STRING (format, "Making %s frame-local while let-bound!");
- CALLN (Fmessage, format, SYMBOL_NAME (variable));
- }
- }
- return variable;
-}
-
DEFUN ("local-variable-p", Flocal_variable_p, Slocal_variable_p,
1, 2, 0,
doc: /* Non-nil if VARIABLE has a local binding in buffer BUFFER.
@@ -1970,10 +2062,7 @@ BUFFER defaults to the current buffer. */)
{
elt = XCAR (tail);
if (EQ (variable, XCAR (elt)))
- {
- eassert (!blv->frame_local);
- return Qt;
- }
+ return Qt;
}
return Qnil;
}
@@ -2032,7 +2121,6 @@ DEFUN ("variable-binding-locus", Fvariable_binding_locus, Svariable_binding_locu
1, 1, 0,
doc: /* Return a value indicating where VARIABLE's current binding comes from.
If the current binding is buffer-local, the value is the current buffer.
-If the current binding is frame-local, the value is the selected frame.
If the current binding is global (the default), the value is nil. */)
(register Lisp_Object variable)
{
@@ -2463,7 +2551,7 @@ uintmax_t
cons_to_unsigned (Lisp_Object c, uintmax_t max)
{
bool valid = 0;
- uintmax_t val IF_LINT (= 0);
+ uintmax_t val;
if (INTEGERP (c))
{
valid = 0 <= XINT (c);
@@ -2516,7 +2604,7 @@ intmax_t
cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max)
{
bool valid = 0;
- intmax_t val IF_LINT (= 0);
+ intmax_t val;
if (INTEGERP (c))
{
val = XINT (c);
@@ -2774,7 +2862,7 @@ float_arith_driver (double accum, ptrdiff_t argnum, enum arithop code,
case Alogand:
case Alogior:
case Alogxor:
- return wrong_type_argument (Qinteger_or_marker_p, val);
+ wrong_type_argument (Qinteger_or_marker_p, val);
case Amax:
if (!argnum || isnan (next) || next > accum)
accum = next;
@@ -2924,48 +3012,42 @@ usage: (logxor &rest INTS-OR-MARKERS) */)
return arith_driver (Alogxor, nargs, args);
}
-DEFUN ("ash", Fash, Sash, 2, 2, 0,
- doc: /* Return VALUE with its bits shifted left by COUNT.
-If COUNT is negative, shifting is actually to the right.
-In this case, the sign bit is duplicated. */)
- (register Lisp_Object value, Lisp_Object count)
+static Lisp_Object
+ash_lsh_impl (register Lisp_Object value, Lisp_Object count, bool lsh)
{
register Lisp_Object val;
CHECK_NUMBER (value);
CHECK_NUMBER (count);
- if (XINT (count) >= BITS_PER_EMACS_INT)
+ if (XINT (count) >= EMACS_INT_WIDTH)
XSETINT (val, 0);
else if (XINT (count) > 0)
XSETINT (val, XUINT (value) << XFASTINT (count));
- else if (XINT (count) <= -BITS_PER_EMACS_INT)
- XSETINT (val, XINT (value) < 0 ? -1 : 0);
+ else if (XINT (count) <= -EMACS_INT_WIDTH)
+ XSETINT (val, lsh ? 0 : XINT (value) < 0 ? -1 : 0);
else
- XSETINT (val, XINT (value) >> -XINT (count));
+ XSETINT (val, lsh ? XUINT (value) >> -XINT (count) : \
+ XINT (value) >> -XINT (count));
return val;
}
+DEFUN ("ash", Fash, Sash, 2, 2, 0,
+ doc: /* Return VALUE with its bits shifted left by COUNT.
+If COUNT is negative, shifting is actually to the right.
+In this case, the sign bit is duplicated. */)
+ (register Lisp_Object value, Lisp_Object count)
+{
+ return ash_lsh_impl (value, count, false);
+}
+
DEFUN ("lsh", Flsh, Slsh, 2, 2, 0,
doc: /* Return VALUE with its bits shifted left by COUNT.
If COUNT is negative, shifting is actually to the right.
In this case, zeros are shifted in on the left. */)
(register Lisp_Object value, Lisp_Object count)
{
- register Lisp_Object val;
-
- CHECK_NUMBER (value);
- CHECK_NUMBER (count);
-
- if (XINT (count) >= BITS_PER_EMACS_INT)
- XSETINT (val, 0);
- else if (XINT (count) > 0)
- XSETINT (val, XUINT (value) << XFASTINT (count));
- else if (XINT (count) <= -BITS_PER_EMACS_INT)
- XSETINT (val, 0);
- else
- XSETINT (val, XUINT (value) >> -XINT (count));
- return val;
+ return ash_lsh_impl (value, count, true);
}
DEFUN ("1+", Fadd1, Sadd1, 1, 1, 0,
@@ -3031,24 +3113,24 @@ bool_vector_spare_mask (EMACS_INT nr_bits)
/* Info about unsigned long long, falling back on unsigned long
if unsigned long long is not available. */
-#if HAVE_UNSIGNED_LONG_LONG_INT && defined ULLONG_MAX
-enum { BITS_PER_ULL = CHAR_BIT * sizeof (unsigned long long) };
+#if HAVE_UNSIGNED_LONG_LONG_INT && defined ULLONG_WIDTH
+enum { ULL_WIDTH = ULLONG_WIDTH };
# define ULL_MAX ULLONG_MAX
#else
-enum { BITS_PER_ULL = CHAR_BIT * sizeof (unsigned long) };
+enum { ULL_WIDTH = ULONG_WIDTH };
# define ULL_MAX ULONG_MAX
# define count_one_bits_ll count_one_bits_l
# define count_trailing_zeros_ll count_trailing_zeros_l
#endif
/* Shift VAL right by the width of an unsigned long long.
- BITS_PER_ULL must be less than BITS_PER_BITS_WORD. */
+ ULL_WIDTH must be less than BITS_PER_BITS_WORD. */
static bits_word
shift_right_ull (bits_word w)
{
/* Pacify bogus GCC warning about shift count exceeding type width. */
- int shift = BITS_PER_ULL - BITS_PER_BITS_WORD < 0 ? BITS_PER_ULL : 0;
+ int shift = ULL_WIDTH - BITS_PER_BITS_WORD < 0 ? ULL_WIDTH : 0;
return w >> shift;
}
@@ -3065,7 +3147,7 @@ count_one_bits_word (bits_word w)
{
int i = 0, count = 0;
while (count += count_one_bits_ll (w),
- (i += BITS_PER_ULL) < BITS_PER_BITS_WORD)
+ (i += ULL_WIDTH) < BITS_PER_BITS_WORD)
w = shift_right_ull (w);
return count;
}
@@ -3210,18 +3292,18 @@ count_trailing_zero_bits (bits_word val)
{
int count;
for (count = 0;
- count < BITS_PER_BITS_WORD - BITS_PER_ULL;
- count += BITS_PER_ULL)
+ count < BITS_PER_BITS_WORD - ULL_WIDTH;
+ count += ULL_WIDTH)
{
if (val & ULL_MAX)
return count + count_trailing_zeros_ll (val);
val = shift_right_ull (val);
}
- if (BITS_PER_BITS_WORD % BITS_PER_ULL != 0
+ if (BITS_PER_BITS_WORD % ULL_WIDTH != 0
&& BITS_WORD_MAX == (bits_word) -1)
val |= (bits_word) 1 << pre_value (ULONG_MAX < BITS_WORD_MAX,
- BITS_PER_BITS_WORD % BITS_PER_ULL);
+ BITS_PER_BITS_WORD % ULL_WIDTH);
return count + count_trailing_zeros_ll (val);
}
}
@@ -3471,6 +3553,7 @@ syms_of_data (void)
DEFSYM (Qcyclic_variable_indirection, "cyclic-variable-indirection");
DEFSYM (Qvoid_variable, "void-variable");
DEFSYM (Qsetting_constant, "setting-constant");
+ DEFSYM (Qtrapping_constant, "trapping-constant");
DEFSYM (Qinvalid_read_syntax, "invalid-read-syntax");
DEFSYM (Qinvalid_function, "invalid-function");
@@ -3549,6 +3632,8 @@ syms_of_data (void)
PUT_ERROR (Qvoid_variable, error_tail, "Symbol's value as variable is void");
PUT_ERROR (Qsetting_constant, error_tail,
"Attempt to set a constant symbol");
+ PUT_ERROR (Qtrapping_constant, error_tail,
+ "Attempt to trap writes to a constant symbol");
PUT_ERROR (Qinvalid_read_syntax, error_tail, "Invalid read syntax");
PUT_ERROR (Qinvalid_function, error_tail, "Invalid function");
PUT_ERROR (Qwrong_number_of_arguments, error_tail,
@@ -3606,6 +3691,9 @@ syms_of_data (void)
DEFSYM (Qchar_table, "char-table");
DEFSYM (Qbool_vector, "bool-vector");
DEFSYM (Qhash_table, "hash-table");
+ DEFSYM (Qthread, "thread");
+ DEFSYM (Qmutex, "mutex");
+ DEFSYM (Qcondition_variable, "condition-variable");
DEFSYM (Qdefun, "defun");
@@ -3646,6 +3734,9 @@ syms_of_data (void)
defsubr (&Ssubrp);
defsubr (&Sbyte_code_function_p);
defsubr (&Schar_or_string_p);
+ defsubr (&Sthreadp);
+ defsubr (&Smutexp);
+ defsubr (&Scondition_variable_p);
defsubr (&Scar);
defsubr (&Scdr);
defsubr (&Scar_safe);
@@ -3672,7 +3763,6 @@ syms_of_data (void)
defsubr (&Smake_variable_buffer_local);
defsubr (&Smake_local_variable);
defsubr (&Skill_local_variable);
- defsubr (&Smake_variable_frame_local);
defsubr (&Slocal_variable_p);
defsubr (&Slocal_variable_if_set_p);
defsubr (&Svariable_binding_locus);
@@ -3727,10 +3817,19 @@ syms_of_data (void)
DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum,
doc: /* The largest value that is representable in a Lisp integer. */);
Vmost_positive_fixnum = make_number (MOST_POSITIVE_FIXNUM);
- XSYMBOL (intern_c_string ("most-positive-fixnum"))->constant = 1;
+ make_symbol_constant (intern_c_string ("most-positive-fixnum"));
DEFVAR_LISP ("most-negative-fixnum", Vmost_negative_fixnum,
doc: /* The smallest value that is representable in a Lisp integer. */);
Vmost_negative_fixnum = make_number (MOST_NEGATIVE_FIXNUM);
- XSYMBOL (intern_c_string ("most-negative-fixnum"))->constant = 1;
+ make_symbol_constant (intern_c_string ("most-negative-fixnum"));
+
+ DEFSYM (Qwatchers, "watchers");
+ DEFSYM (Qmakunbound, "makunbound");
+ DEFSYM (Qunlet, "unlet");
+ DEFSYM (Qset, "set");
+ DEFSYM (Qset_default, "set-default");
+ defsubr (&Sadd_variable_watcher);
+ defsubr (&Sremove_variable_watcher);
+ defsubr (&Sget_variable_watchers);
}