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 08:57:36 +0000

Daniel Colascione <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.
 
  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.
 

  typedef emacs_value (*emacs_subr)(
    emacs_env* env,
    int nargs,
    emacs_value args[]);

Could we give this a void* data parameter for storing arbitrary user data? This is common for callbacks in C interfaces and allows C++ users to store C++ objects in the pointer. This can be implemented using another save pointer.
 
   emacs_value (*make_function)(
      emacs_env* env,
      int min_arity,
      int max_arity,
      emacs_subr function);

Similary, here void* data should be passed to be retrieved later.
 

    emacs_value (*funcall)(
      emacs_env* env,
      emacs_value function,
      int nargs,
      emacs_value args[]);

Does function have to be a function object, or can it be a symbol? I.e. is the user supposed to call symbol-function first?
 
    int64_t (*fixnum_to_int)(
      emacs_env* env,
      emacs_value value);

    emacs_value (*make_fixnum)(
      emacs_env* env,
      int64_t value);


What's the behavior of these functions if the source would not fit into the result? Undefined behavior, abort(), raising a signal?
 
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?
 
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()?
 
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?
 
1) Do we need JNI-style local variable frames and functions that
   release local references?

2) Maybe we want a separate, non-emacs_value type for global references?

No idea about these.
 

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.
 

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?

reply via email to

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