emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Dynamic loading progress


From: Philipp Stephani
Subject: Re: Dynamic loading progress
Date: Sun, 04 Oct 2015 09:41:08 +0000



Daniel Colascione <address@hidden> schrieb am So., 4. Okt. 2015 um 11:10 Uhr:
On 10/04/2015 01:57 AM, Philipp Stephani wrote:
> Daniel Colascione <address@hidden <mailto:address@hidden>> schrieb
> am So., 15. Feb. 2015 um 21:21 Uhr:
>
>     Here's a broad outline of what I have in mind.
>
>
> Thanks, that looks really good. Just a few minor issues that I
> encountered over the last couple of weeks.
>
>
>     Thread-local environments
>     -------------------------
>
>     The `get_environment' member lets us do anything else interesting. As
>     in Java, environments are thread-local. We only support one thread for
>     the moment, so this constraint is easy to enforce. (Just abort if we
>     use an emacs_env off the main thread.)
>
>
> Would you really abort, or rather use the error handling functions? We
> should be able to make the error values thread-local so that calling a
> function from the wrong thread would be the equivalent of raising a
> signal, giving the caller a chance to react. Otherwise the burden of
> remembering the correct thread would be on the caller's side.

If we abort, thread mismatch is a programming error, and we can omit
optionally the check for performance. If we fail in some recoverable
way, we have to perform the thread check every time, since it's now
contractual.

OK.
 

>
>
>       typedef struct emacs_value_tag* emacs_value;
>
>
> I think it's important that this is a pointer to a struct (for type
> safety and size correctness) rather than just an arbitrary type.

A typedef is exactly as typesafe. The question of whether to use a
struct or a typedef is aesthetic. I strongly prefer a typedef, just like
pthreads, and I believe that the people who advocate using structs
directly are simply wrong.

Ah, I'm not against the typedef, I'm just asking whether you would make it part of the API contract that it's a typedef of a struct pointer, or whether it can be any type.
 
>     Modules can use make_global_reference to allocate a global reference
>     (i.e., a GC root) for any emacs_value; modules must then free these
>     references explicitly.
>
>     All routines (except make_global_reference) that return emacs_value
>     values return local references.  It's up to modules to register
>     long-lived references explicitly.
>
>
> In which cases would global references be necessary?

Any time you want to hold onto a lisp value outside the dynamic extent
of your emacs_env.

Isn't the dynamic extent of the emacs_env the whole program, starting from the module initializer?
 

>     Like JNI, we can just declare that it's illegal to call all but a few
>     specially-marked functions (like global reference deregistration) with
>     a pending error.
>
>
> What's the behavior if other functions are called? abort()?

abort in check mode; unspecified when optimizing for performance.

OK, makes sense. Probably it should be abort() in all cases right now, the test should be really fast.
 

>
>
>     If Lisp signals or throws, `funcall' returns NULL.
>
>
> Hmm, with the current implementation emacs_value is just the same as
> Lisp_Object, i.e. not a real pointer, so NULL doesn't have specific
> semantics. Should it return Qnil instead and force the user to use
> check_error?

I thought we make Qnil equal zero. In any case, I *don't* like the idea
of Lisp_Object being emacs_value. I'd much rather emacs_value be a
pointer to a Lisp_Object, solving this problem completely.

I agree with you, but that's how it's currently implemented.
 

>     3) How exactly do we represent catch/throw values?
>
>
> I've thought about this a bit, and I think it would be simplest to add a
> new function env->set_throw and have get_error and check_error return an
> enum { normal, signal, throw }. One could come up with something like
> creating a list (error-kind error-tag error-value), but it looks like
> the module implementation would create such lists only for the module
> code to convert them back, so it's simpler to represent the two kinds of
> non-local exits directly in the interface.

I'm fine with a list; keep in mind that we'll need to handle OOM
somehow, so I'd suggest an opaque type.

I think OOM is currently handled by doing the equivalent of 

(apply #'signal memory-signal-data)

so it would be part of the normal signal handling. Using a list would be possible, but then the distinction between error tag and data could be removed from the module code. But I think the 'magic lists' idiom common in Emacs is more of an antipattern and we should try to avoid it in the module interface, thus the suggestion to use an enum.
 

>     4) Do we need to use int64_t for integers?
>
>
> Maybe just intmax_t and a static check that that is larger than an Elisp
> integer?

Why make the behavior vary depending on what intmax_t is? At least
int64_t is nice and explicit.


True. The time when Emacs integers will be larger than 64 bits is probably far in the future. 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]