&& !EQ (sym->u.s.val.value, Qunbound))
{
struct Lisp_Binding *binding = XBINDING (sym->u.s.val.value);
- binding->b[dst] = binding->b[src];
+ binding->r[dst] = true;
+ binding->b[dst] = make_fixnum (src);
}
if (!NILP (sym->u.s._function))
{
struct Lisp_Binding *binding = XBINDING (sym->u.s._function);
- binding->b[dst] = binding->b[src];
+ binding->r[dst] = true;
+ binding->b[dst] = make_fixnum (src);
}
if (sym->u.s.next == 0)
break;
{
union vectorlike_header header;
Lisp_Object b[MAX_LEXSPACES];
+ /* true if redirect. */
+ bool r[MAX_LEXSPACES];
};
INLINE bool
if (EQ (sym->u.s.val.value, Qunbound))
return Qunbound;
eassert (BINDINGP (sym->u.s.val.value));
- /* FIXME: add loop to follow indirection. */
- return XBINDING (sym->u.s.val.value)->b[curr_lexspace];
+ EMACS_INT lexspace = curr_lexspace;
+ struct Lisp_Binding *binding = XBINDING (sym->u.s.val.value);
+ /* Follow redirections. */
+ while (binding->r[lexspace])
+ lexspace = XFIXNUM (binding->b[lexspace]);
+ return binding->b[lexspace];
}
INLINE Lisp_Object
SYMBOL_FUNCTION (struct Lisp_Symbol *sym)
{
- if (!NILP (sym->u.s._function))
- return XBINDING (sym->u.s._function)->b[curr_lexspace];
- return Qnil;
+ if (NILP (sym->u.s._function))
+ return Qnil;
+ EMACS_INT lexspace = curr_lexspace;
+ struct Lisp_Binding *binding = XBINDING (sym->u.s._function);
+ /* Follow redirections. */
+ while (binding->r[lexspace])
+ lexspace = XFIXNUM (binding->b[lexspace]);
+ return binding->b[lexspace];
}
INLINE struct Lisp_Symbol *
if (EQ (sym->u.s.val.value, Qunbound))
sym->u.s.val.value = make_binding (Qunbound);
struct Lisp_Binding *binding = XBINDING (sym->u.s.val.value);
+ binding->r[curr_lexspace] = false;
binding->b[curr_lexspace] = v;
}
visit_static_gc_roots (visitor);
}
-enum { PDUMPER_MAX_OBJECT_SIZE = 2048 };
+enum { PDUMPER_MAX_OBJECT_SIZE = 4096 };
static dump_off
field_relpos (const void *in_start, const void *in_field)
return dump_object_finish (ctx, &out, sizeof (out));
}
+static dump_off
+dump_binding (struct dump_context *ctx, const struct Lisp_Binding *binding)
+{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Binding_A2586197DB)
+# error "Lisp_Binding changed. See CHECK_STRUCTS comment in config.h."
+#endif
+ START_DUMP_PVEC (ctx, &binding->header, struct Lisp_Binding, out);
+ dump_pseudovector_lisp_fields (ctx, &out->header, &binding->header);
+ for (ptrdiff_t i = 0; i < MAX_LEXSPACES; ++i)
+ DUMP_FIELD_COPY (out, binding, r[i]);
+ return finish_dump_pvec (ctx, &out->header);
+}
+
static void
fill_pseudovec (union vectorlike_header *header, Lisp_Object item)
{
case PVEC_CHAR_TABLE:
case PVEC_SUB_CHAR_TABLE:
case PVEC_RECORD:
- case PVEC_BINDING:
offset = dump_vectorlike_generic (ctx, &v->header);
break;
case PVEC_BOOL_VECTOR:
case PVEC_SUBR:
offset = dump_subr (ctx, XSUBR (lv));
break;
+ case PVEC_BINDING:
+ offset = dump_binding (ctx, XBINDING (lv));
+ break;
case PVEC_FRAME:
case PVEC_WINDOW:
case PVEC_PROCESS: