From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Philipp Stephani Newsgroups: gmane.emacs.devel Subject: Re: Dynamic loading progress Date: Sun, 04 Oct 2015 08:57:36 +0000 Message-ID: References: <83y4oiiw81.fsf@gnu.org> <838ugdf251.fsf@gnu.org> <87bnl1vmqf.fsf@lifelogs.com> <87vbj8tow4.fsf@lifelogs.com> <87r3twtagf.fsf@lifelogs.com> <85siebl7ws.fsf@stephe-leake.org> <85a90ilwmm.fsf@stephe-leake.org> <83386a6f7z.fsf@gnu.org> <85h9upjz7v.fsf@stephe-leake.org> <83wq3k3kl4.fsf@gnu.org> <85bnkwil1c.fsf@stephe-leake.org> <83pp9cwky8.fsf@gnu.org> <85a90ggf2d.fsf@stephe-leake.org> <54E0A40F.5080603@dancol.org> <83sie7un20.fsf@gnu.org> <54E0D181.2080802@dancol.org> <83r3trulse.fsf@gnu.org> <54E0D7E0.305@[87.69.4.28]> <83h9unukbg.fsf@gnu.org> <54E0DEF8.7020901@dancol> <83egpruiyp.fsf@gnu.org> <54E0FF93.2000104@dancol.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=001a1134c69c2090140521439779 X-Trace: ger.gmane.org 1443949077 30703 80.91.229.3 (4 Oct 2015 08:57:57 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 4 Oct 2015 08:57:57 +0000 (UTC) Cc: =?UTF-8?Q?Aur=C3=A9lien_Aptel?= , stephen_leake@stephe-leake.org, emacs-devel@gnu.org To: Daniel Colascione , Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Oct 04 10:57:56 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Zif7E-0002bL-4I for ged-emacs-devel@m.gmane.org; Sun, 04 Oct 2015 10:57:56 +0200 Original-Received: from localhost ([::1]:41698 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zif7D-0004sv-6m for ged-emacs-devel@m.gmane.org; Sun, 04 Oct 2015 04:57:55 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:55056) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zif78-0004sj-A6 for emacs-devel@gnu.org; Sun, 04 Oct 2015 04:57:51 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zif76-000361-Oi for emacs-devel@gnu.org; Sun, 04 Oct 2015 04:57:50 -0400 Original-Received: from mail-wi0-x229.google.com ([2a00:1450:400c:c05::229]:38738) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zif74-00034o-7y; Sun, 04 Oct 2015 04:57:46 -0400 Original-Received: by wiclk2 with SMTP id lk2so77858604wic.1; Sun, 04 Oct 2015 01:57:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-type; bh=Ro4tnsgj11oB1KIPY94CcWfps3botFygrLgCgEid7OM=; b=lLtb780rmtFVz8lzf9+ZPwEXEvuYXhi5dLXm3+/H35HThuS24Q8vHsa6EmxzpapBDu 7YhfNhj/DD6vWY1LO0fwQzHBavoyP4WN1edIHh5a7yw7E6TUg0o6SyJ05E+6WNyW/SUL xtY5CL+Ei/hKWX1E1AnvUF12WpgSINj7V0iK3TPoX/ozVWr2SzdDJWRrn9Z+qqcNGf4+ XbKy/3L+EthKIhloKwUJvkWbSTjolz7hkNwULJAP4Gmv4Yqr7GPlp4K/0wVu2ypRB/zM I5upMte7ksx2/oEfvjQswvVi26/4531TDn9NwsPn0/9gNWCudnnsGff8CBtHaZE8R8sl ABog== X-Received: by 10.180.216.36 with SMTP id on4mr5883909wic.65.1443949065570; Sun, 04 Oct 2015 01:57:45 -0700 (PDT) In-Reply-To: <54E0FF93.2000104@dancol.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c05::229 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:190857 Archived-At: --001a1134c69c2090140521439779 Content-Type: text/plain; charset=UTF-8 Daniel Colascione 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? --001a1134c69c2090140521439779 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Daniel Colasci= one <dancol@dancol.org> schr= ieb am So., 15. Feb. 2015 um 21:21=C2=A0Uhr:
Here's a broad outline of what I have in mind.

Thanks, that looks really good. Just a few minor issu= es that I encountered over the last couple of weeks.
=C2=A0
=
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 shou= ld 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 corre= ct thread would be on the caller's side.
=C2=A0
=C2=A0 typedef struct emacs_value_tag* emacs_value;<= br>

I think it's important that this is= a pointer to a struct (for type safety and size correctness) rather than j= ust an arbitrary type.
=C2=A0

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

Coul= d 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.=
=C2=A0
=C2=A0 =C2=A0emacs_va= lue (*make_function)(
=C2=A0 =C2=A0 =C2=A0 emacs_env* env,
=C2=A0 =C2=A0 =C2=A0 int min_arity,
=C2=A0 =C2=A0 =C2=A0 int max_arity,
=C2=A0 =C2=A0 =C2=A0 emacs_subr function);

<= div>Similary, here void* data should be passed to be retrieved later.
=
=C2=A0

=C2=A0 =C2=A0 emacs_value (*funcall)(
=C2=A0 =C2=A0 =C2=A0 emacs_env* env,
=C2=A0 =C2=A0 =C2=A0 emacs_value function,
=C2=A0 =C2=A0 =C2=A0 int nargs,
=C2=A0 =C2=A0 =C2=A0 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?
=C2=A0
<= blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px= #ccc solid;padding-left:1ex"> =C2=A0 =C2=A0 int64_t (*fixnum_to_int)(
=C2=A0 =C2=A0 =C2=A0 emacs_env* env,
=C2=A0 =C2=A0 =C2=A0 emacs_value value);

=C2=A0 =C2=A0 emacs_value (*make_fixnum)(
=C2=A0 =C2=A0 =C2=A0 emacs_env* env,
=C2=A0 =C2=A0 =C2=A0 int64_t value);


What's the behavior of these funct= ions if the source would not fit into the result? Undefined behavior, abort= (), raising a signal?
=C2=A0
= 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.=C2=A0 It's up to modules to register long-lived references explicitly.

In wh= ich cases would global references be necessary?
=C2=A0
Like JNI, we can just declare that it's illeg= al to call all but a few
specially-marked functions (like global reference deregistration) with
a pending error.

What's the behavio= r if other functions are called? abort()?
=C2=A0
If Lisp signals or throws, `funcall' returns NULL.<= br>

Hmm, with the current implementation em= acs_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 for= ce the user to use check_error?
=C2=A0
1) Do we need JNI-style local variable frames and functions that<= br> =C2=A0 =C2=A0release local references?

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

No idea about these.
=C2=A0

3) How exactly do we represent catch/throw values?
I've thought about this a bit, and I think it would be simp= lest to add a new function env->set_throw and have get_error and check_e= rror return an enum { normal, signal, throw }. One could come up with somet= hing 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 o= f non-local exits directly in the interface.
=C2=A0

4) Do we need to use int64_t for integers?

<= div>Maybe just intmax_t and a static check that that is larger than an Elis= p integer?
--001a1134c69c2090140521439779--