Justification for `my_copy_struct` and `my_size_object` in `erl_db_util.c`?

While reading the code of the BEAM, I’ve encountered the following two functions in erl_db_util.c:

static Uint my_size_object(Eterm t);
static Eterm my_copy_struct(Eterm t, Eterm **hp, ErlOffHeap* off_heap);

As far as I can tell, they are strictly less powerful than the generic size_object and copy_struct functions, are recursive where the generic versions take great pains to be iterative and avoid potential stack overflows, and they are only used in static void do_emit_constant(DMCContext *context, DMC_STACK_TYPE(UWord) *text, Eterm t) .

I’ve not found any comment explaining why they are used instead of the generic versions, and when I used git blame to find the commit message that corresponded to their introduction, all I could find was a commit from 2009 with the message “The R13B03 release.”.

Does anyone know why these two functions exist?

3 Likes

It’s for copying (the awkward) match spec syntax where tuples have a special syntax.

{const, Term} translates to Term
and {{...}} translates to {...}.

In order to escape the special meaning of tuples and certain atoms,
like the expression {'+', '$1', '$2'}.

I agree an explaining comment would be nice or even more describing names than my_*.

2 Likes

Thank you for the explanation, it now makes perfect sense.
I did not realize that a function called my_copy_struct alters the data it moves instead of just copying it.
Maybe it should be called something like transfer_match_spec?

2 Likes