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 09:41:08 +0000 Message-ID: References: <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> <5610ED13.1010406@dancol.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=047d7b5d5896db09880521443248 X-Trace: ger.gmane.org 1443951711 1997 80.91.229.3 (4 Oct 2015 09:41:51 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 4 Oct 2015 09:41:51 +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 11:41:41 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 1ZifnY-0000G9-Jl for ged-emacs-devel@m.gmane.org; Sun, 04 Oct 2015 11:41:40 +0200 Original-Received: from localhost ([::1]:41801 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZifnY-0006TR-1U for ged-emacs-devel@m.gmane.org; Sun, 04 Oct 2015 05:41:40 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:33518) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZifnH-0006TF-Lb for emacs-devel@gnu.org; Sun, 04 Oct 2015 05:41:25 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZifnF-00080Y-KB for emacs-devel@gnu.org; Sun, 04 Oct 2015 05:41:23 -0400 Original-Received: from mail-wi0-x232.google.com ([2a00:1450:400c:c05::232]:36134) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZifnC-0007zx-Sa; Sun, 04 Oct 2015 05:41:19 -0400 Original-Received: by wicgb1 with SMTP id gb1so82371685wic.1; Sun, 04 Oct 2015 02:41:18 -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=KZrCYP4oXwzCFb3lNBX3PjRGWuLTbfHPKS6elYtL2xk=; b=nJa/FDTB8vQPuW/PQVAjusFuRxaRxwjvK1PKGailun9+DLIhyHDBJIQLsh2YRYYS8N cLScmSlDACMw+8t6E0N07jNTLREzTspMCadnJ5cd/NR2o3+fEzsP44Nfes6ayzGfBE/k rwWrO+Fl1J8ZeevXCEnVYabxB146s7DQEmG9tixcN0+GO8NGH8a3Vanogh+KXTMdUhYX OLzxtUrqmsAVRMOUKFDt0++kS6emQ0Jv4xF7ru0yjrdL1LY/8ISERB28zyrTVTVnnjdR UphY9IuDepiPBxHnE4cSBwP9VCBUeYQRQl1WyffxgQ7DDLxId20OId84zHVqC/S1FU+I byCg== X-Received: by 10.194.5.135 with SMTP id s7mr29196422wjs.153.1443951678259; Sun, 04 Oct 2015 02:41:18 -0700 (PDT) In-Reply-To: <5610ED13.1010406@dancol.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c05::232 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:190862 Archived-At: --047d7b5d5896db09880521443248 Content-Type: text/plain; charset=UTF-8 Daniel Colascione schrieb am So., 4. Okt. 2015 um 11:10 Uhr: > On 10/04/2015 01:57 AM, Philipp Stephani wrote: > > 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. > > 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. --047d7b5d5896db09880521443248 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable


Daniel= Colascione <dancol@dancol.org&= gt; schrieb am So., 4. Okt. 2015 um 11:10=C2=A0Uhr:
On 10/04/2015 01:57 AM, Philipp Stephani wrote:
> Daniel Colascione <dancol@dancol.org <mailto:dancol@dancol.org>> schrieb
> am So., 15. Feb. 2015 um 21:21 Uhr:
>
>=C2=A0 =C2=A0 =C2=A0Here's a broad outline of what I have in mind.<= br> >
>
> Thanks, that looks really good. Just a few minor issues that I
> encountered over the last couple of weeks.
>
>
>=C2=A0 =C2=A0 =C2=A0Thread-local environments
>=C2=A0 =C2=A0 =C2=A0-------------------------
>
>=C2=A0 =C2=A0 =C2=A0The `get_environment' member lets us do anythin= g else interesting. As
>=C2=A0 =C2=A0 =C2=A0in Java, environments are thread-local. We only sup= port one thread for
>=C2=A0 =C2=A0 =C2=A0the moment, so this constraint is easy to enforce. = (Just abort if we
>=C2=A0 =C2=A0 =C2=A0use 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.
=C2=A0
=

>
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef struct emacs_value_tag* emacs_value;=
>
>
> I think it's important that this is a pointer to a struct (for typ= e
> 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 whethe= r it can be any type.
=C2=A0
= >=C2=A0 =C2=A0 =C2=A0Modules can use make_global_reference to allocate a= global reference
>=C2=A0 =C2=A0 =C2=A0(i.e., a GC root) for any emacs_value; modules must= then free these
>=C2=A0 =C2=A0 =C2=A0references explicitly.
>
>=C2=A0 =C2=A0 =C2=A0All routines (except make_global_reference) that re= turn emacs_value
>=C2=A0 =C2=A0 =C2=A0values return local references.=C2=A0 It's up t= o modules to register
>=C2=A0 =C2=A0 =C2=A0long-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 dynami= c extent of the emacs_env the whole program, starting from the module initi= alizer?
=C2=A0

>=C2=A0 =C2=A0 =C2=A0Like JNI, we can just declare that it's illegal= to call all but a few
>=C2=A0 =C2=A0 =C2=A0specially-marked functions (like global reference d= eregistration) with
>=C2=A0 =C2=A0 =C2=A0a 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() i= n all cases right now, the test should be really fast.
=C2=A0

>
>
>=C2=A0 =C2=A0 =C2=A0If Lisp signals or throws, `funcall' returns NU= LL.
>
>
> 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 specifi= c
> 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.
=C2=A0

>=C2=A0 =C2=A0 =C2=A03) How exactly do we represent catch/throw values?<= br> >
>
> 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 retu= rn an
> enum { normal, signal, throw }. One could come up with something like<= br> > creating a list (error-kind error-tag error-value), but it looks like<= br> > the module implementation would create such lists only for the module<= br> > code to convert them back, so it's simpler to represent the two ki= nds 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=C2=A0

(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 coul= d be removed from the module code. But I think the 'magic lists' id= iom 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.
=C2= =A0

>=C2=A0 =C2=A0 =C2=A04) Do we need to use int64_t for integers?
>
>
> Maybe just intmax_t and a static check that that is larger than an Eli= sp
> 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 wil= l be larger than 64 bits is probably far in the future.=C2=A0
--047d7b5d5896db09880521443248--