From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Philipp Stephani Newsgroups: gmane.emacs.devel Subject: [PATCH] Require full GMP for big integer module functions. Date: Thu, 25 Apr 2019 19:09:04 +0200 Message-ID: <20190425170904.99105-1-phst@google.com> References: <83y33yxdsc.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="131348"; mail-complaints-to="usenet@blaine.gmane.org" Cc: Philipp Stephani , emacs-devel@gnu.org To: eliz@gnu.org, eggert@cs.ucla.edu Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Apr 25 19:16:48 2019 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hJhzL-000Y21-9R for ged-emacs-devel@m.gmane.org; Thu, 25 Apr 2019 19:16:47 +0200 Original-Received: from localhost ([127.0.0.1]:32797 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hJhzK-00037l-0r for ged-emacs-devel@m.gmane.org; Thu, 25 Apr 2019 13:16:46 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:33008) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hJhz1-0002uB-KO for emacs-devel@gnu.org; Thu, 25 Apr 2019 13:16:31 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hJhrq-00070g-PU for emacs-devel@gnu.org; Thu, 25 Apr 2019 13:09:04 -0400 Original-Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:39123) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hJhro-0006yV-83; Thu, 25 Apr 2019 13:09:00 -0400 Original-Received: by mail-wm1-x341.google.com with SMTP id n25so265804wmk.4; Thu, 25 Apr 2019 10:08:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eHODZ/7v/1W9dPt/0r927TO8qI5FIi1qqIv/X2fCr3k=; b=YE6IeYg/ZJXFUDtGaMz4DWOCgo1KMj6x5zM4Uei95yGB5gNzSohTOv77U1b+itThkm jNew/ULqOJJ9HvkV5BI6w6uvF2OSAvX9mB9N47pwUns9hHEXvApNzdSXhhh5ySZvNqse 2QJcTqIdzBkE+9NkQCLZkqP7LlF6FRfI+TOLhgugKt1a/+8V24hj1HnVTZbXwrnilHDN yrlcOYuYckgOeKitlin+0lRtAqeTcJsWIrT8Q0ZoP0kcmEJUREL+nb5cbvLxs8BABPZy gUkT2JLMZJ2hKC+4/FqAF6uq7ILxUSPDMxneg27YvDN74VGUXJ4HVpwNiSnivG2TJ3i0 b6JQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eHODZ/7v/1W9dPt/0r927TO8qI5FIi1qqIv/X2fCr3k=; b=sRohQtmsJahWP3VqZjaQ32BnTcFmiKDSJxknZ+qQwjz8jJmnlfDbh3KfDtT/FwCvD0 cocvEk1bci14VSrRPgYdSKal8ewe5phFJgZKNf2BDHqxSqgu7VVEPwMSDcsqbUSCjc3c dqG7cE9OLbdaAK0+5QjvqQs4CH7IHZHRj/DZs49cyuxkNM+I7MMOpcBKmLx+fEjREM+q JKeBhUmoyXZRhdB0QkS6gWc1+6Q6kbBev1T4si9dKAZVlLhfsSGScbafCandAGgLif7J K2ZYHSoAozPCN3MFYsjTPUhxG0dOXnQ2B+1gH5vJBQJy2ejm5rQKX7rAcqRBfeCeSes7 EkyA== X-Gm-Message-State: APjAAAVTVPRLjqAqABk8IVeidTxL4AYnaaYqXzbpGEdPNDEemfhFX8rR fRZo4dboE9rlPrUYiyeLqekmCvEw X-Google-Smtp-Source: APXvYqyf7nJMwxUtK1UHKDfccjC7v+ZU8kjdGuETKgEzPVkN5z7lDreXkzN5EX8HrZzGLr0TI9Ak9Q== X-Received: by 2002:a1c:be13:: with SMTP id o19mr4294108wmf.19.1556212137881; Thu, 25 Apr 2019 10:08:57 -0700 (PDT) Original-Received: from p.cm.cablesurf.de (85.233.42.145.dynamic.cablesurf.de. [85.233.42.145]) by smtp.gmail.com with ESMTPSA id v184sm34931492wma.6.2019.04.25.10.08.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Apr 2019 10:08:56 -0700 (PDT) X-Google-Original-From: Philipp Stephani X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <83y33yxdsc.fsf@gnu.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::341 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 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" Xref: news.gmane.org gmane.emacs.devel:235931 Archived-At: This allows mini-gmp to not stay binary-compatible with full GMP. * src/emacs-module.h.in: Don’t check EMACS_MODULE_HAVE_MPZ_T macro. * src/emacs-module.c: Define EMACS_MODULE_GMP only if GMP is available. (module_extract_big_integer, module_make_big_integer): Implement only if GMP is available. Otherwise signal an error. (syms_of_module): Define new error ‘unimplemented’. * test/Makefile.in ($(test_module)): Remove support for mini-gmp. * test/data/emacs-module/mod-test.c (EMACS_MODULE_GMP) (Fmod_test_nanoseconds, Fmod_test_double): Define only if GMP is available. * test/src/emacs-module-tests.el (mod-test-nanoseconds) (mod-test-double): Skip if GMP is unavailable. * doc/lispref/internals.texi (Module Values): Document changed behavior. --- doc/lispref/internals.texi | 6 +++++- src/emacs-module.c | 19 +++++++++++++++---- src/emacs-module.h.in | 2 +- test/Makefile.in | 3 +-- test/data/emacs-module/mod-test.c | 11 +++++++---- test/src/emacs-module-tests.el | 10 ++++++++++ 6 files changed, 39 insertions(+), 12 deletions(-) diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index 5ae71afbef..a8bf2ee31b 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -1519,7 +1519,8 @@ Module Values @end deftp @noindent -Then you can use the following additional functions: +If Emacs itself is compiled with GMP support, you can use the +following additional functions: @deftypefn Function bool extract_big_integer (emacs_env *@var{env}, emacs_value @var{arg}, struct emacs_mpz *@var{result}) This function, which is available since Emacs 27, extracts the @@ -1543,6 +1544,9 @@ Module Values or similar. @end deftypefn +If Emacs is compiled without GMP support, these functions will signal +an error of type @code{unimplemented}. + The following example uses GMP to calculate the next probable prime after a given integer: diff --git a/src/emacs-module.c b/src/emacs-module.c index 0b7b3d6ffb..3d9d9e5757 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -70,12 +70,10 @@ To add a new module function, proceed as follows: #include -#ifndef HAVE_GMP -#include "mini-gmp.h" -#define EMACS_MODULE_HAVE_MPZ_T +#ifdef HAVE_GMP +#define EMACS_MODULE_GMP #endif -#define EMACS_MODULE_GMP #include "emacs-module.h" #include @@ -788,20 +786,28 @@ module_extract_big_integer (emacs_env *env, emacs_value value, struct emacs_mpz *result) { MODULE_FUNCTION_BEGIN (); +#ifdef HAVE_GMP Lisp_Object o = value_to_lisp (value); CHECK_INTEGER (o); if (FIXNUMP (o)) mpz_set_intmax (result->value, XFIXNUM (o)); else mpz_set (result->value, XBIGNUM (o)->value); +#else + xsignal0 (Qunimplemented); +#endif } static emacs_value module_make_big_integer (emacs_env *env, const struct emacs_mpz *value) { MODULE_FUNCTION_BEGIN (NULL); +#ifdef HAVE_GMP mpz_set (mpz[0], value->value); return lisp_to_value (env, make_integer_mpz ()); +#else + xsignal0 (Qunimplemented); +#endif } @@ -1384,6 +1390,11 @@ syms_of_module (void) Fput (Qinvalid_arity, Qerror_message, build_pure_c_string ("Invalid function arity")); + DEFSYM (Qunimplemented, "unimplemented"); + Fput (Qunimplemented, Qerror_conditions, pure_list (Qunimplemented, Qerror)); + Fput (Qunimplemented, Qerror_message, + build_pure_c_string ("Function not implemented")); + DEFSYM (Qmodule_function_p, "module-function-p"); defsubr (&Smodule_load); diff --git a/src/emacs-module.h.in b/src/emacs-module.h.in index fbc62a61ef..e61aadfc3a 100644 --- a/src/emacs-module.h.in +++ b/src/emacs-module.h.in @@ -28,7 +28,7 @@ along with GNU Emacs. If not, see . */ #include #endif -#if defined EMACS_MODULE_GMP && !defined EMACS_MODULE_HAVE_MPZ_T +#ifdef EMACS_MODULE_GMP #include #endif diff --git a/test/Makefile.in b/test/Makefile.in index ec20a427ba..2282ccd951 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -257,7 +257,6 @@ FPIC_CFLAGS = HYBRID_MALLOC = @HYBRID_MALLOC@ LIBEGNU_ARCHIVE = ../lib/lib$(if $(HYBRID_MALLOC),e)gnu.a GMP_LIB = @GMP_LIB@ -GMP_OBJ = $(if @GMP_OBJ@, ../src/@GMP_OBJ@) # Note: emacs-module.h is generated from emacs-module.h.in, hence we # look in ../src, not $(srcdir)/../src. @@ -270,7 +269,7 @@ src/emacs-module-tests.log: $(test_module): $(test_module:${SO}=.c) ../src/emacs-module.h $(LIBEGNU_ARCHIVE) $(AM_V_at)${MKDIR_P} $(dir $@) $(AM_V_CCLD)$(CC) -shared $(CPPFLAGS) $(MODULE_CFLAGS) $(LDFLAGS) \ - -o $@ $< $(LIBEGNU_ARCHIVE) $(GMP_LIB) $(GMP_OBJ) + -o $@ $< $(LIBEGNU_ARCHIVE) $(GMP_LIB) endif ## Check that there is no 'automated' subdirectory, which would diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c index b7007bd80f..a264c0170f 100644 --- a/test/data/emacs-module/mod-test.c +++ b/test/data/emacs-module/mod-test.c @@ -29,12 +29,9 @@ along with GNU Emacs. If not, see . */ #ifdef HAVE_GMP #include -#else -#include "mini-gmp.h" -#define EMACS_MODULE_HAVE_MPZ_T +#define EMACS_MODULE_GMP #endif -#define EMACS_MODULE_GMP #include #include "timespec.h" @@ -386,6 +383,8 @@ Fmod_test_add_nanosecond (emacs_env *env, ptrdiff_t nargs, emacs_value *args, return env->make_time (env, time); } +#ifdef HAVE_GMP + static emacs_value Fmod_test_nanoseconds (emacs_env *env, ptrdiff_t nargs, emacs_value *args, void *data) { assert (nargs == 1); @@ -417,6 +416,8 @@ Fmod_test_double (emacs_env *env, ptrdiff_t nargs, emacs_value *args, return result; } +#endif /* HAVE_GMP */ + /* Lisp utilities for easier readability (simple wrappers). */ /* Provide FEATURE to Emacs. */ @@ -486,8 +487,10 @@ emacs_module_init (struct emacs_runtime *ert) NULL, NULL); DEFUN ("mod-test-sleep-until", Fmod_test_sleep_until, 2, 2, NULL, NULL); DEFUN ("mod-test-add-nanosecond", Fmod_test_add_nanosecond, 1, 1, NULL, NULL); +#ifdef HAVE_GMP DEFUN ("mod-test-nanoseconds", Fmod_test_nanoseconds, 1, 1, NULL, NULL); DEFUN ("mod-test-double", Fmod_test_double, 1, 1, NULL, NULL); +#endif #undef DEFUN diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el index 173b63670f..fcd122626e 100644 --- a/test/src/emacs-module-tests.el +++ b/test/src/emacs-module-tests.el @@ -344,6 +344,9 @@ module--test-assertion (ert-deftest mod-test-nanoseconds () "Test truncation when converting to `struct timespec'." + ;; `mod-test-nanoseconds' is not defined if the test module was + ;; compiled without GMP support. + (skip-unless (fboundp 'mod-test-nanoseconds)) (dolist (test-case '((0 . 0) (-1 . -1000000000) ((1 . 1000000000) . 1) @@ -362,10 +365,17 @@ module--test-assertion (should (eq (mod-test-nanoseconds input) expected)))))) (ert-deftest mod-test-double () + ;; `mod-test-double' is not defined if the test module was compiled + ;; without GMP support. + (skip-unless (fboundp 'mod-test-double)) (dolist (input (list 0 1 2 -1 42 12345678901234567890 most-positive-fixnum (1+ most-positive-fixnum) most-negative-fixnum (1- most-negative-fixnum))) (ert-info ((format "input: %d" input)) (should (= (mod-test-double input) (* 2 input)))))) +;; Prevent compiler warnings for conditionally-defined functions. +(declare-function mod-test-nanoseconds "mod-test.so" (arg)) +(declare-function mod-test-double "mod-test.so" (arg)) + ;;; emacs-module-tests.el ends here -- 2.20.1 (Apple Git-117)