Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a "private" field to struct cmark_node #287

Closed
nwellnhof opened this issue Jan 18, 2015 · 3 comments
Closed

Add a "private" field to struct cmark_node #287

nwellnhof opened this issue Jan 18, 2015 · 3 comments

Comments

@nwellnhof
Copy link
Contributor

For bindings from other languages to libcmark, it would be useful to add a "private" field to struct cmark_node that makes it possible to store a pointer to (or other identifier of) the object that represents the node in the other language. Something like:

typedef union {
    void *ptr;
    size_t id;
} cmark_private_data;

cmark_private_data
cmark_node_get_private_data(cmark_node *node);

int
cmark_node_set_private_data(cmark_node *node, cmark_private_data priv_data);
@jgm
Copy link
Member

jgm commented Jan 19, 2015

Can you say a bit about why this would be useful/how it would be used?

@nwellnhof
Copy link
Contributor Author

The biggest problem for language bindings is memory management of the node tree. The tree must only be freed if there are no more references to any of its nodes. The problematic case is when there are no more references to the root node but still some references to child nodes. So every node must somehow keep a reference to the object representing the root node or its parent node.

If a pointer to the target language object is stored in the private field, this object can be easily looked up given a only cmark_node. Because the target language only has to store pointers to cmark_nodes, this can simplify things especially for languages where its hard to store additional data (for example in a Perl SV, or a Ruby RData). It also results in a 1:1 mapping between cmark_nodes and the target language objects which is more memory-efficient.

A private field can also be useful for C users to store arbitrary stuff associated with a node.

Thinking more about it, I don't think using a union with an additional integer type is that useful. So I change my initial proposal to something like:

void*
cmark_node_get_private_data(cmark_node *node);

int
cmark_node_set_private_data(cmark_node *node, void *priv_data);

@jgm
Copy link
Member

jgm commented Jan 19, 2015

Thanks for the explanation. I have no objections to adding
such a field, if you want to submit a PR!

+++ Nick Wellnhofer [Jan 19 15 05:20 ]:

The biggest problem for language bindings is memory management of the
node tree. The tree must only be freed if there are no more references
to any of its nodes. The problematic case is when there are no more
references to the root node but still some references to child nodes.
So every node must somehow keep a reference to the object representing
the root node or its parent node.

If a pointer to the target language object is stored in the private
field, this object can be easily looked up given a only cmark_node.
Because the target language only has to store pointers to cmark_nodes,
this can simplify things especially for languages where its hard to
store additional data (for example in a Perl SV, or a Ruby RData). It
also results in a 1:1 mapping between cmark_nodes and the target
language objects which is more memory-efficient.

A private field can also be useful for C users to store arbitrary stuff
associated with a node.

Thinking more about it, I don't think using a union with an additional
integer type is that useful. So I change my initial proposal to
something like:
void*
cmark_node_get_private_data(cmark_node *node);

int
cmark_node_set_private_data(cmark_node *node, void *priv_data);


Reply to this email directly or [1]view it on GitHub.

References

  1. Add a "private" field to struct cmark_node #287 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants