poke-devel
[Top][All Lists]
Advanced

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

[PATCH 2/2] pkl,libpoke: report exception in pk{l,}_load functions


From: Mohammad-Reza Nabipoor
Subject: [PATCH 2/2] pkl,libpoke: report exception in pk{l,}_load functions
Date: Sat, 23 Sep 2023 23:36:14 +0200

2023-09-23  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>

        * libpoke/libpoke.h (pk_load): Add `exit_exception' parameter.
        * libpoke/libpoke.c (pk_load): Likewise.
        * libpoke/pkl.h (pkl_load): Likewise.
        * libpoke/pkl.c (pkl_load): Likewise.
        * poke/pk-cmd.c (pk_cmd_init): Call default handler for loading
        `pk-cmd' module.
        * poke/poke.c (initialize): Update use of `pk_load'.
        * pokefmt/pokefmt.l (poke_init): Likewise.
        * testsuite/poke.libpoke/api.c (test_pk_load): New function for
        `pk_load'-related tests.
        (main): Call `test_pk_load'.
---
 ChangeLog                    | 14 ++++++++++++++
 libpoke/libpoke.c            |  5 +++--
 libpoke/libpoke.h            | 11 ++++++++---
 libpoke/pkl.c                | 19 +++++++++++++------
 libpoke/pkl.h                | 12 +++++++++---
 poke/pk-cmd.c                |  9 +++++++--
 poke/poke.c                  |  4 ++--
 pokefmt/pokefmt.l            |  3 ++-
 testsuite/poke.libpoke/api.c | 20 +++++++++++++++++++-
 9 files changed, 77 insertions(+), 20 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4dc275cb..04c17b71 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2023-09-23  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
+
+       * libpoke/libpoke.h (pk_load): Add `exit_exception' parameter.
+       * libpoke/libpoke.c (pk_load): Likewise.
+       * libpoke/pkl.h (pkl_load): Likewise.
+       * libpoke/pkl.c (pkl_load): Likewise.
+       * poke/pk-cmd.c (pk_cmd_init): Call default handler for loading
+       `pk-cmd' module.
+       * poke/poke.c (initialize): Update use of `pk_load'.
+       * pokefmt/pokefmt.l (poke_init): Likewise.
+       * testsuite/poke.libpoke/api.c (test_pk_load): New function for
+       `pk_load'-related tests.
+       (main): Call `test_pk_load'.
+
 2023-09-23  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
 
        * libpoke/pkl.c (pkl_execute_buffer): Don't dereference
diff --git a/libpoke/libpoke.c b/libpoke/libpoke.c
index 8d542ce0..e7241e59 100644
--- a/libpoke/libpoke.c
+++ b/libpoke/libpoke.c
@@ -230,9 +230,10 @@ pk_compile_expression (pk_compiler pkc, const char *buffer,
 }
 
 int
-pk_load (pk_compiler pkc, const char *module)
+pk_load (pk_compiler pkc, const char *module, pk_val *exit_exception)
 {
-  PK_RETURN (pkl_load (pkc->compiler, module) == 0 ? PK_ERROR : PK_OK);
+  PK_RETURN (pkl_load (pkc->compiler, module, exit_exception) == 0 ? PK_ERROR
+                                                                   : PK_OK);
 }
 
 void
diff --git a/libpoke/libpoke.h b/libpoke/libpoke.h
index 83b51c50..cd2557c5 100644
--- a/libpoke/libpoke.h
+++ b/libpoke/libpoke.h
@@ -270,10 +270,15 @@ int pk_compile_expression_with_loc (pk_compiler pkc, 
const char *buffer,
    and all the definitions are re-defined.  This is the same behavior
    than the `load' Poke language construction.
 
-   If the module cannot be loaded, return PK_ERROR.  Otherwise,
-   return PK_OK.  */
+   EXIT_EXCEPTION, if not NULL, is a pointer to a pk_val variable that
+   is set to an Exception value if the moudle load results in an
+   unhandled exception, PK_NULL otherwise.
+
+   If the module cannot be loaded (either compile-time error or run-time
+   exception), return PK_ERROR.  Otherwise, return PK_OK.  */
 
-int pk_load (pk_compiler pkc, const char *module) LIBPOKE_API;
+int pk_load (pk_compiler pkc, const char *module,
+             pk_val *exit_exception) LIBPOKE_API;
 
 /* Print a disassembly of a named function.
 
diff --git a/libpoke/pkl.c b/libpoke/pkl.c
index 17041be0..97eb407f 100644
--- a/libpoke/pkl.c
+++ b/libpoke/pkl.c
@@ -775,19 +775,26 @@ pkl_resolve_module (pkl_compiler compiler,
 }
 
 int
-pkl_load (pkl_compiler compiler, const char *module)
+pkl_load (pkl_compiler compiler, const char *module, pvm_val *exit_exception)
 {
-  pvm_val exit_exception;
+  pvm_val exception;
   char *module_filename = pkl_resolve_module (compiler,
                                               module,
                                               0 /* filename_p */);
+
+  if (exit_exception)
+    *exit_exception = PVM_NULL;
+
   if (!module_filename)
     return 0;
 
-  if (!pkl_execute_file (compiler, module_filename,
-                         &exit_exception)
-      || exit_exception != PVM_NULL)
-    return 0;
+  if (!pkl_execute_file (compiler, module_filename, &exception)
+      || exception != PVM_NULL)
+    {
+      if (exit_exception)
+        *exit_exception = exception;
+      return 0;
+    }
 
   return 1;
 }
diff --git a/libpoke/pkl.h b/libpoke/pkl.h
index e90dedcb..98389c75 100644
--- a/libpoke/pkl.h
+++ b/libpoke/pkl.h
@@ -295,10 +295,16 @@ char *pkl_resolve_module (pkl_compiler compiler, const 
char *module,
                           int filename_p);
 
 /* Load a module using the given compiler.
-   If the module cannot be loaded, return 0.
-   Otherwise, return 1.  */
 
-int pkl_load (pkl_compiler compiler, const char *module);
+   If the module cannot be loaded (either compile-time error or run-time
+   exception), return 0.  Otherwise, return 1.
+
+   If not NULL, *EXIT_EXCEPTION is set to an exception value if the
+   execution of the program gets interrupted by an unhandled exception.
+   Otherwise *EXIT_EXCEPTION is set to PK_NULL.  */
+
+int pkl_load (pkl_compiler compiler, const char *module,
+              pvm_val *exit_exception);
 
 /* Declare a variable in the global environmnt.
 
diff --git a/poke/pk-cmd.c b/poke/pk-cmd.c
index 74aaa87e..fc4d1b1b 100644
--- a/poke/pk-cmd.c
+++ b/poke/pk-cmd.c
@@ -763,6 +763,8 @@ pk_cmd_exec_script (const char *filename)
 void
 pk_cmd_init (void)
 {
+  pk_val exception;
+
   cmds_trie = pk_trie_from_cmds (dot_cmds);
   info_trie = pk_trie_from_cmds (info_cmds);
   vm_trie = pk_trie_from_cmds (vm_cmds);
@@ -777,8 +779,11 @@ pk_cmd_init (void)
   set_cmd.subcommands = set_cmds;
 
   /* Compile commands written in Poke.  */
-  if (pk_load (poke_compiler, "pk-cmd") != PK_OK)
-    pk_fatal ("unable to load the pk-cmd module");
+  if (pk_load (poke_compiler, "pk-cmd", &exception) != PK_OK)
+    {
+      poke_handle_exception (exception);
+      pk_fatal ("unable to load the pk-cmd module");
+    }
 }
 
 void
diff --git a/poke/poke.c b/poke/poke.c
index d6ecf596..becd5cae 100644
--- a/poke/poke.c
+++ b/poke/poke.c
@@ -654,11 +654,11 @@ initialize (int argc, char *argv[])
   /* The Poke hyperlinks facilities must be loaded before poke.pk and
      the cmd subsystem.  This is done even if the hserver is
      disabled.  */
-  if (pk_load (poke_compiler, "pk-hserver") != PK_OK)
+  if (pk_load (poke_compiler, "pk-hserver", NULL) != PK_OK)
     pk_fatal ("unable to load the pk-hserver module");
 
   /* Load poke.pk  */
-  if (pk_load (poke_compiler, "poke") != PK_OK)
+  if (pk_load (poke_compiler, "poke", NULL) != PK_OK)
     pk_fatal ("unable to load the poke module");
 
   /* Set the values of a few global variables defined in poke.pk.  */
diff --git a/pokefmt/pokefmt.l b/pokefmt/pokefmt.l
index fffda29f..829a9619 100644
--- a/pokefmt/pokefmt.l
+++ b/pokefmt/pokefmt.l
@@ -503,7 +503,8 @@ poke_init (struct poke *pk, const char *poke_src_file, FILE 
*output)
     free (user_load_path);
   }
 
-  if (pk_load (pk->compiler, "pokefmt") != PK_OK)
+  /* There's no default exception handler yet.  */
+  if (pk_load (pk->compiler, "pokefmt", /*exit_exception*/ NULL) != PK_OK)
     errx (1, "pk_load() failed for pokefmt.pk");
 
   if (pk_decl_val (pk->compiler, "pokefmt_expr_printer") == PK_NULL)
diff --git a/testsuite/poke.libpoke/api.c b/testsuite/poke.libpoke/api.c
index c37dfde8..0389334e 100644
--- a/testsuite/poke.libpoke/api.c
+++ b/testsuite/poke.libpoke/api.c
@@ -105,6 +105,23 @@ test_pk_keyword_p (pk_compiler pkc)
   T ("pk_keyword_p_2", !pk_keyword_p (pkc, "foo"));
 }
 
+static void
+test_pk_load (pk_compiler pkc)
+{
+  /* An invalid value for pk_val, just to make sure pk_load set it
+     to PK_NULL.  */
+  pk_val exception = 0;
+
+  T ("pk_load_1", pk_load (pkc, "std", &exception) == PK_OK);
+  T ("pk_load_1 exception", exception == PK_NULL);
+
+  exception = 0;  /* Again resetting to an invalid value.  */
+
+  T ("pk_load_2", pk_load (pkc, "a-module_which-does_not-exist",
+                           &exception) == PK_ERROR);
+  T ("pk_load_1 exception", exception == PK_NULL);
+}
+
 int
 main ()
 {
@@ -112,8 +129,9 @@ main ()
 
   pkc = test_pk_compiler_new ();
 
-  test_pk_compiler_free (pkc);
   test_pk_keyword_p (pkc);
+  test_pk_load (pkc);
+  test_pk_compiler_free (pkc);
 
   return 0;
 }
-- 
2.42.0




reply via email to

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