[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 2/2] pkl: Remove global state from IOS
From: |
Mohammad-Reza Nabipoor |
Subject: |
[PATCH v2 2/2] pkl: Remove global state from IOS |
Date: |
Thu, 23 Dec 2021 09:05:03 +0330 |
This patch introduces a new type `ios_context` to keep all
IOS-related data in one place for each instance of libpoke.
Also removes other IOS-related global states.
2021-12-23 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
* libpoke/ios.h (ios_context): New type.
(ios_init): Returns `ios_context`.
(ios_shutdown): Add new `ios_context` param.
(ios_open): Likewise.
(ios_close): Likewise.
(ios_cur): Likewise.
(ios_set_cur): Likewise.
(ios_search): Likewise.
(ios_search_by_id): Likewise.
(ios_begin): Likewise.
(ios_map): Likewise.
(ios_foreign_iod): Likewise.
(ios_register_foreign_iod): Likewise.
* libpoke/ios-dev-sub.c (struct ios_dev_sub): Add new field.
* libpoke/ios.c (struct ios_context): New struct.
(ios_next_id): Removed.
(io_list): Likewise.
(cur_io): Likewise.
(ios_dev_ifs): Likewise.
(ios_context): Returns `ios_context`.
(ios_shutdown): Add new `ios_context` param.
(ios_open): Likewise.
(ios_close): Likewise.
(ios_begin): Likewise.
(ios_cur): Likewise.
(ios_set_cur): Likewise.
(ios_search): Likewise.
(ios_search_by_id): Likewise.
(ios_map): Likewise.
(ios_foreign_iod): Likewise.
(ios_register_foreign_iod): Likewise.
* libpoke/pvm.h (pvm_ios_context): New function.
* libpoke/pvm.c (pvm_ios_context): Likewise.
(PVM_STATE_IOS_CONTEXT): New macro.
(pvm_init): Add IOS initialization.
(pvm_shutdown): Add IOS finalization.
* libpoke/libpoke.c (struct _pk_compiler): Move global variables here.
(pk_compiler_new_with_flags): Use `calloc` instead of `malloc`.
(pk_completion_function): Instead of static variables, use fields of
`pk_compiler`.
(pk_ios_completion_function): Likewise.
(pk_ios_cur): Update to use `ios_context`.
(pk_ios_set_cur): Likewise.
(pk_ios_search): Likewise.
(pk_ios_search_by_id): Likewise.
(pk_ios_open): Likewise.
(pk_ios_close): Likewise.
(pk_ios_map): Likewise.
(foreign_iod_if): Remove global variable.
(pk_register_iod): Rely on `pk_compiler` fields instead of global
variable. Use `ios_context`.
* libpoke/pvm.jitter (wrapped-functions): Add `ios_init`.
(state-struct-backing-c): Add new field (`ictx`).
(state-initialization-c): Initialize new field.
(open): Update to use IOS context.
(close): Likewise.
(flush): Likewise.
(pushios): Likewise.
(popios): Likewise.
(ioflags): Likewise.
(iosize): Likewise.
(iogetb): Likewise.
(iosetb): Likewise.
(peeks): Likewise.
(pokes): Likewise.
---
ChangeLog | 68 ++++++++++
libpoke/ios-dev-proc.c | 3 +-
libpoke/ios-dev-sub.c | 8 +-
libpoke/ios.c | 291 +++++++++++++++++++++++------------------
libpoke/ios.h | 26 ++--
libpoke/libpoke.c | 75 +++++------
libpoke/pvm.c | 26 +++-
libpoke/pvm.h | 4 +
libpoke/pvm.jitter | 50 ++++---
9 files changed, 344 insertions(+), 207 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 71d08114..600a8b9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,71 @@
+2021-12-23 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
+
+ * libpoke/ios.h (ios_context): New type.
+ (ios_init): Returns `ios_context`.
+ (ios_shutdown): Add new `ios_context` param.
+ (ios_open): Likewise.
+ (ios_close): Likewise.
+ (ios_cur): Likewise.
+ (ios_set_cur): Likewise.
+ (ios_search): Likewise.
+ (ios_search_by_id): Likewise.
+ (ios_begin): Likewise.
+ (ios_map): Likewise.
+ (ios_foreign_iod): Likewise.
+ (ios_register_foreign_iod): Likewise.
+ * libpoke/ios-dev-sub.c (struct ios_dev_sub): Add new field.
+ * libpoke/ios.c (struct ios_context): New struct.
+ (ios_next_id): Removed.
+ (io_list): Likewise.
+ (cur_io): Likewise.
+ (ios_dev_ifs): Likewise.
+ (ios_context): Returns `ios_context`.
+ (ios_shutdown): Add new `ios_context` param.
+ (ios_open): Likewise.
+ (ios_close): Likewise.
+ (ios_begin): Likewise.
+ (ios_cur): Likewise.
+ (ios_set_cur): Likewise.
+ (ios_search): Likewise.
+ (ios_search_by_id): Likewise.
+ (ios_map): Likewise.
+ (ios_foreign_iod): Likewise.
+ (ios_register_foreign_iod): Likewise.
+ * libpoke/pvm.h (pvm_ios_context): New function.
+ * libpoke/pvm.c (pvm_ios_context): Likewise.
+ (PVM_STATE_IOS_CONTEXT): New macro.
+ (pvm_init): Add IOS initialization.
+ (pvm_shutdown): Add IOS finalization.
+ * libpoke/libpoke.c (struct _pk_compiler): Move global variables here.
+ (pk_compiler_new_with_flags): Use `calloc` instead of `malloc`.
+ (pk_completion_function): Instead of static variables, use fields of
+ `pk_compiler`.
+ (pk_ios_completion_function): Likewise.
+ (pk_ios_cur): Update to use `ios_context`.
+ (pk_ios_set_cur): Likewise.
+ (pk_ios_search): Likewise.
+ (pk_ios_search_by_id): Likewise.
+ (pk_ios_open): Likewise.
+ (pk_ios_close): Likewise.
+ (pk_ios_map): Likewise.
+ (foreign_iod_if): Remove global variable.
+ (pk_register_iod): Rely on `pk_compiler` fields instead of global
+ variable. Use `ios_context`.
+ * libpoke/pvm.jitter (wrapped-functions): Add `ios_init`.
+ (state-struct-backing-c): Add new field (`ictx`).
+ (state-initialization-c): Initialize new field.
+ (open): Update to use IOS context.
+ (close): Likewise.
+ (flush): Likewise.
+ (pushios): Likewise.
+ (popios): Likewise.
+ (ioflags): Likewise.
+ (iosize): Likewise.
+ (iogetb): Likewise.
+ (iosetb): Likewise.
+ (peeks): Likewise.
+ (pokes): Likewise.
+
2021-12-23 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
* libpoke/ios-dev-file.c (ios_dev_file_open): Add new param `user_data`.
diff --git a/libpoke/ios-dev-proc.c b/libpoke/ios-dev-proc.c
index 257668d9..766eab95 100644
--- a/libpoke/ios-dev-proc.c
+++ b/libpoke/ios-dev-proc.c
@@ -74,6 +74,7 @@ static void *
ios_dev_proc_open (const char *handler, uint64_t flags, int *error, void *data)
{
struct ios_dev_proc *proc = malloc (sizeof (struct ios_dev_proc));
+ ios_context ictx = (ios_context)data;
if (proc == NULL)
{
@@ -112,7 +113,7 @@ ios_dev_proc_open (const char *handler, uint64_t flags, int
*error, void *data)
proc->memfile = ios_dev_file.open (proc->memfile_path,
IOS_F_READ | IOS_F_WRITE,
- error, NULL);
+ error, ictx);
if (proc->memfile == NULL)
{
free (proc);
diff --git a/libpoke/ios-dev-sub.c b/libpoke/ios-dev-sub.c
index f6646dab..7b798c0d 100644
--- a/libpoke/ios-dev-sub.c
+++ b/libpoke/ios-dev-sub.c
@@ -32,6 +32,7 @@
struct ios_dev_sub
{
+ ios_context ictx;
int base_ios_id;
ios_dev_off base;
ios_dev_off size;
@@ -83,6 +84,7 @@ ios_dev_sub_open (const char *handler, uint64_t flags, int
*error, void *data)
}
sub->name = NULL; /* To ease error management below. */
+ sub->ictx = (ios_context)data;
/* Flags: only IOS_F_READ and IOS_F_WRITE are allowed. */
sub->flags = explicit_flags_p ? flags : IOS_F_READ | IOS_F_WRITE;
@@ -143,7 +145,7 @@ ios_dev_sub_open (const char *handler, uint64_t flags, int
*error, void *data)
uint64_t iflags;
/* The referred IOS should exist. */
- base_ios = ios_search_by_id (sub->base_ios_id);
+ base_ios = ios_search_by_id (sub->ictx, sub->base_ios_id);
if (base_ios == NULL)
goto error;
@@ -207,7 +209,7 @@ static int
ios_dev_sub_pread (void *iod, void *buf, size_t count, ios_dev_off offset)
{
struct ios_dev_sub *sub = iod;
- ios ios = ios_search_by_id (sub->base_ios_id);
+ ios ios = ios_search_by_id (sub->ictx, sub->base_ios_id);
if (ios == NULL || !(sub->flags & IOS_F_READ))
return IOD_ERROR;
@@ -225,7 +227,7 @@ ios_dev_sub_pwrite (void *iod, const void *buf, size_t
count,
ios_dev_off offset)
{
struct ios_dev_sub *sub = iod;
- ios ios = ios_search_by_id (sub->base_ios_id);
+ ios ios = ios_search_by_id (sub->ictx, sub->base_ios_id);
if (ios == NULL || !(sub->flags & IOS_F_WRITE))
return IOD_ERROR;
diff --git a/libpoke/ios.c b/libpoke/ios.c
index 8b1acf7d..77ea770e 100644
--- a/libpoke/ios.c
+++ b/libpoke/ios.c
@@ -78,15 +78,6 @@ struct ios
struct ios *next;
};
-/* Next available IOS id. */
-
-static int ios_next_id = 0;
-
-/* List of IO spaces, and pointer to the current one. */
-
-static struct ios *io_list;
-static struct ios *cur_io;
-
/* The available backends are implemented in their own files, and
provide the following interfaces. */
@@ -102,83 +93,117 @@ extern struct ios_dev_if ios_dev_proc; /* ios-dev-proc.c
*/
#endif
extern struct ios_dev_if ios_dev_sub; /* ios-dev-sub.c */
-static struct ios_dev_if *ios_dev_ifs[] =
- {
- NULL, /* Optional foreign IOD. */
- &ios_dev_zero,
- &ios_dev_mem,
- &ios_dev_stream,
+enum
+{
+ IOS_DEV_FOREIGN, /* Foreign must be first */
+ IOS_DEV_ZERO,
+ IOS_DEV_MEM,
+ IOS_DEV_STREAM,
+ IOS_DEV_NBD,
+ IOS_DEV_PROC,
+ IOS_DEV_SUB,
+ IOS_DEV_FILE, /* File must be last */
+
+ IOS_DEV_COUNT
+};
+
+struct ios_context
+{
+ int next_id; /* Next available IOS id. */
+ struct ios *io_list; /* List of all IO spaces. */
+ struct ios *cur_io; /* Pointer to the current IOS. */
+ struct ios_dev_if dev_ifs[IOS_DEV_COUNT]; /* IO devices. */
+ int dev_ifs_valid_p[IOS_DEV_COUNT]; /* Validity of IO devices. */
+};
+
+ios_context
+ios_init (void)
+{
+ ios_context ictx = calloc (1, sizeof (struct ios_context));
+
+ if (!ictx)
+ return NULL;
+
+#define DEV_IF(idx, val) \
+ do \
+ { \
+ memcpy (&ictx->dev_ifs[IOS_DEV_##idx], &ios_dev_##val, \
+ sizeof (struct ios_dev_if)); \
+ ictx->dev_ifs_valid_p[IOS_DEV_##idx] = 1; \
+ } \
+ while (0)
+
+ DEV_IF(ZERO, zero);
+ DEV_IF(MEM, mem);
+ DEV_IF(STREAM, stream);
#ifdef HAVE_LIBNBD
- &ios_dev_nbd,
+ DEV_IF(NBD, nbd);
#endif
#ifdef HAVE_PROC
- &ios_dev_proc,
+ DEV_IF(PROC, proc);
+ ictx->dev_ifs[IOS_DEV_PROC].user_data = ictx;
#endif
- &ios_dev_sub,
- /* File must be last */
- &ios_dev_file,
- NULL,
- };
+ DEV_IF(SUB, sub);
+ ictx->dev_ifs[IOS_DEV_SUB].user_data = ictx;
+ DEV_IF(FILE, file);
-void
-ios_init (void)
-{
- /* Nothing to do here... yet. */
+#undef DEV_IF
+
+ return ictx;
}
void
-ios_shutdown (void)
+ios_shutdown (ios_context ictx)
{
+ ios inext;
+
+ if (!ictx)
+ return;
/* Close and free all open IO spaces. */
- while (io_list)
- ios_close (io_list);
+ for (ios i = ictx->io_list; i; i = inext)
+ {
+ inext = i->next;
+ ios_close (ictx, i);
+ }
+ free (ictx);
}
int
-ios_open (const char *handler, uint64_t flags, int set_cur)
+ios_open (ios_context ictx, const char *handler, uint64_t flags, int set_cur_p)
{
struct ios *io;
- struct ios_dev_if **dev_if = NULL;
+ int ios_dev_idx = -1;
int iod_error = IOD_OK, error = IOS_ERROR;
/* Allocate and initialize the new IO space. */
- io = malloc (sizeof (struct ios));
+ io = calloc (1, sizeof (struct ios));
if (!io)
return IOS_ENOMEM;
- io->handler = NULL;
- io->next = NULL;
- io->bias = 0;
-
/* Look for a device interface suitable to operate on the given
handler. */
- dev_if = ios_dev_ifs;
- do
+ for (int i = 0; i < IOS_DEV_COUNT; i++)
{
- if (*dev_if == NULL)
- {
- /* Skip the foreign IO device if it is not set. */
- ++dev_if;
- continue;
- }
-
- io->handler = (*dev_if)->handler_normalize (handler, flags, &iod_error);
+ if (!ictx->dev_ifs_valid_p[i])
+ continue;
+ io->handler = ictx->dev_ifs[i].handler_normalize(handler, flags,
+ &iod_error);
if (iod_error != IOD_OK)
goto error;
if (io->handler)
- break;
-
- ++dev_if;
+ {
+ ios_dev_idx = i;
+ break;
+ }
}
- while (*dev_if);
- if (*dev_if == NULL)
+ if (ios_dev_idx == -1)
goto error;
- io->dev_if = *dev_if;
+ io->dev_if = &ictx->dev_ifs[ios_dev_idx];
/* Do not re-open an already-open IO space. */
- for (ios i = io_list; i; i = i->next)
+ for (ios i = ictx->io_list; i; i = i->next)
if (STREQ (i->handler, io->handler))
{
error = IOS_EOPEN;
@@ -192,15 +217,15 @@ ios_open (const char *handler, uint64_t flags, int
set_cur)
goto error;
/* Increment the id counter after all possible errors are avoided. */
- io->id = ios_next_id++;
+ io->id = ictx->next_id++;
/* Add the newly created space to the list, and update the current
space. */
- io->next = io_list;
- io_list = io;
+ io->next = ictx->io_list;
+ ictx->io_list = io;
- if (!cur_io || set_cur == 1)
- cur_io = io;
+ if (!ictx->cur_io || set_cur_p)
+ ictx->cur_io = io;
return io->id;
@@ -216,11 +241,13 @@ ios_open (const char *handler, uint64_t flags, int
set_cur)
}
int
-ios_close (ios io)
+ios_close (ios_context ictx, ios io)
{
- struct ios *tmp;
int ret;
+ assert (ictx);
+ assert (io);
+
/* XXX: if not saved, ask before closing. */
/* Close the device operated by the IO space.
@@ -228,55 +255,56 @@ ios_close (ios io)
ret = io->dev_if->close (io->dev);
/* Unlink the IOS from the list. */
- assert (io_list != NULL); /* The list contains at least this IO space. */
- if (io_list == io)
- io_list = io_list->next;
+ assert (ictx->io_list != NULL); /* The list contains at least this IO space.
*/
+ if (ictx->io_list == io)
+ ictx->io_list = ictx->io_list->next;
else
{
- for (tmp = io_list; tmp->next != io; tmp = tmp->next)
+ struct ios *tmp;
+
+ for (tmp = ictx->io_list; tmp->next != io; tmp = tmp->next)
;
tmp->next = io->next;
}
/* Set the new current IO. */
- if (io == cur_io)
- cur_io = io_list;
+ if (io == ictx->cur_io)
+ ictx->cur_io = ictx->io_list;
free (io);
return IOD_ERROR_TO_IOS_ERROR (ret);
}
-uint64_t
-ios_flags (ios io)
-{
- return io->dev_if->get_flags (io->dev);
-}
-
-const char *
-ios_handler (ios io)
+ios
+ios_begin (ios_context ictx)
{
- return io->handler;
+ return ictx->io_list;
}
ios
-ios_cur (void)
+ios_cur (ios_context ictx)
{
- return cur_io;
+ return ictx->cur_io;
}
void
-ios_set_cur (ios io)
+ios_set_cur (ios_context ictx, ios io)
{
- cur_io = io;
+ ios i = ictx->io_list;
+
+ for (; i && i != io; i = i->next)
+ ;
+ assert(i == io);
+ ictx->cur_io = io;
}
ios
-ios_search (const char *handler)
+ios_search (ios_context ictx, const char *handler)
{
ios io;
- for (io = io_list; io; io = io->next)
+ for (io = ictx->io_list; io; io = io->next)
if (STREQ (io->handler, handler))
break;
@@ -284,27 +312,47 @@ ios_search (const char *handler)
}
ios
-ios_search_by_id (int id)
+ios_search_by_id (ios_context ictx, int id)
{
ios io;
- for (io = io_list; io; io = io->next)
+ for (io = ictx->io_list; io; io = io->next)
if (io->id == id)
break;
return io;
}
+void
+ios_map (ios_context ictx, ios_map_fn cb, void *data)
+{
+ ios io;
+ ios io_next;
+
+ for (io = ictx->io_list; io; io = io_next)
+ {
+ /* Note that the handler may close IO. */
+ io_next = io->next;
+ (*cb) (io, data);
+ }
+}
+
int
ios_get_id (ios io)
{
return io->id;
}
+uint64_t
+ios_flags (ios io)
+{
+ return io->dev_if->get_flags (io->dev);
+}
+
const char *
-ios_get_dev_if_name (ios io)
+ios_handler (ios io)
{
- return io->dev_if->get_if_name ();
+ return io->handler;
}
ios_off
@@ -319,10 +367,28 @@ ios_set_bias (ios io, ios_off bias)
io->bias = bias;
}
-ios
-ios_begin (void)
+uint64_t
+ios_size (ios io)
+{
+ return io->dev_if->size (io->dev);
+}
+
+void *
+ios_get_dev (ios ios)
+{
+ return ios->dev;
+}
+
+struct ios_dev_if *
+ios_get_dev_if (ios ios)
{
- return io_list;
+ return ios->dev_if;
+}
+
+const char *
+ios_get_dev_if_name (ios io)
+{
+ return io->dev_if->get_if_name ();
}
bool
@@ -337,18 +403,10 @@ ios_next (const ios io)
return io->next;
}
-void
-ios_map (ios_map_fn cb, void *data)
+int
+ios_flush (ios io, ios_off offset)
{
- ios io;
- ios io_next;
-
- for (io = io_list; io; io = io_next)
- {
- /* Note that the handler may close IO. */
- io_next = io->next;
- (*cb) (io, data);
- }
+ return io->dev_if->flush (io->dev, offset / 8);
}
/* Set all except the lowest SIGNIFICANT_BITS of VALUE to zero. */
@@ -1605,42 +1663,19 @@ ios_write_string (ios io, ios_off offset, int flags,
return IOS_OK;
}
-uint64_t
-ios_size (ios io)
-{
- return io->dev_if->size (io->dev);
-}
-
-int
-ios_flush (ios io, ios_off offset)
-{
- return io->dev_if->flush (io->dev, offset / 8);
-}
-
-void *
-ios_get_dev (ios ios)
-{
- return ios->dev;
-}
-
-struct ios_dev_if *
-ios_get_dev_if (ios ios)
-{
- return ios->dev_if;
-}
-
struct ios_dev_if *
-ios_foreign_iod (void)
+ios_foreign_iod (ios_context ictx)
{
- return ios_dev_ifs[0];
+ return &ictx->dev_ifs[IOS_DEV_FOREIGN];
}
int
-ios_register_foreign_iod (struct ios_dev_if *iod_if)
+ios_register_foreign_iod (ios_context ictx, struct ios_dev_if *iod_if)
{
- if (ios_dev_ifs[0] != NULL)
+ if (ictx->dev_ifs_valid_p[IOS_DEV_FOREIGN])
return IOS_ERROR;
- ios_dev_ifs[0] = iod_if;
+ memcpy(&ictx->dev_ifs[IOS_DEV_FOREIGN], iod_if, sizeof (struct ios_dev_if));
+ ictx->dev_ifs_valid_p[IOS_DEV_FOREIGN] = 1;
return IOS_OK;
}
diff --git a/libpoke/ios.h b/libpoke/ios.h
index 3af10d67..88dc671e 100644
--- a/libpoke/ios.h
+++ b/libpoke/ios.h
@@ -23,12 +23,14 @@
#include <stdint.h>
#include <stdbool.h>
+typedef struct ios_context *ios_context;
+
/* The following two functions intialize and shutdown the IO poke
subsystem. */
-void ios_init (void);
+ios_context ios_init (void);
-void ios_shutdown (void);
+void ios_shutdown (ios_context);
/* "IO spaces" are the entities used in poke in order to abstract the
heterogeneous devices that are suitable to be edited, such as
@@ -157,13 +159,13 @@ typedef int64_t ios_off;
If no IOS_F_READ or IOS_F_WRITE flags are specified, then the IOS
will be opened in whatever mode makes more sense. */
-int ios_open (const char *handler, uint64_t flags, int set_cur);
+int ios_open (ios_context m, const char *handler, uint64_t flags, int set_cur);
/* Close the given IO space, freing all used resources and flushing
the space cache associated with the space. Return IOS_OK on success
and the error code on failure. */
-int ios_close (ios io);
+int ios_close (ios_context m, ios io);
/* Return the flags which are active in a given IO. Note that this
doesn't necessarily correspond to the flags passed when opening the
@@ -179,21 +181,21 @@ const char *ios_handler (ios io);
/* Return the current IO space, or NULL if there are no open
spaces. */
-ios ios_cur (void);
+ios ios_cur (ios_context m);
/* Set the current IO space to IO. */
-void ios_set_cur (ios io);
+void ios_set_cur (ios_context m, ios io);
/* Return the IO space operating the given HANDLER. Return NULL if no
such space exists. */
-ios ios_search (const char *handler);
+ios ios_search (ios_context m, const char *handler);
/* Return the IO space having the given ID. Return NULL if no such
space exists. */
-ios ios_search_by_id (int id);
+ios ios_search_by_id (ios_context m, int id);
/* Return the ID of the given IO space. */
@@ -205,7 +207,7 @@ const char *ios_get_dev_if_name (ios io);
/* Return the first IO space. */
-ios ios_begin (void);
+ios ios_begin (ios_context m);
/* Return the space following IO. */
@@ -219,7 +221,7 @@ bool ios_end (const ios io);
typedef void (*ios_map_fn) (ios io, void *data);
-void ios_map (ios_map_fn cb, void *data);
+void ios_map (ios_context m, ios_map_fn cb, void *data);
/* **************** IOS properties************************ */
@@ -354,7 +356,7 @@ int ios_flush (ios io, ios_off offset);
If no forereign IO device is registered, return NULL.
Otherwise return a pointer to the interface. */
-struct ios_dev_if *ios_foreign_iod (void);
+struct ios_dev_if *ios_foreign_iod (ios_context m);
/* Register a foreign IO device.
@@ -364,6 +366,6 @@ struct ios_dev_if *ios_foreign_iod (void);
Return IOS_OK otherwise. */
struct ios_dev_if;
-int ios_register_foreign_iod (struct ios_dev_if *iod_if);
+int ios_register_foreign_iod (ios_context m, struct ios_dev_if *iod_if);
#endif /* ! IOS_H */
diff --git a/libpoke/libpoke.c b/libpoke/libpoke.c
index 393ec740..a5da875f 100644
--- a/libpoke/libpoke.c
+++ b/libpoke/libpoke.c
@@ -36,8 +36,13 @@ struct _pk_compiler
pkl_compiler compiler;
pvm vm;
- pkl_ast_node complete_type;
int status; /* Status of last API function call. Initialized with PK_OK */
+
+ /* Data for completion machinery. */
+ pkl_ast_node complete_type;
+ ios completion_ios;
+ int completion_idx;
+ struct pkl_ast_node_iter completion_iter;
};
struct pk_term_if libpoke_term_if;
@@ -57,7 +62,7 @@ pk_compiler_new_with_flags (struct pk_term_if *term_if,
uint32_t flags)
|| !term_if->hyperlink_fn || !term_if->end_hyperlink_fn)
return NULL;
- pkc = malloc (sizeof (struct _pk_compiler));
+ pkc = calloc (1, sizeof (struct _pk_compiler));
if (pkc)
{
uint32_t pkl_flags = 0;
@@ -291,9 +296,10 @@ char *
pk_completion_function (pk_compiler pkc,
const char *text, int state)
{
+#define idx pkc->completion_idx
+#define iter pkc->completion_iter
+
char *function_name;
- static int idx = 0;
- static struct pkl_ast_node_iter iter;
pkl_env env = pkl_get_env (pkc->compiler);
if (state == 0)
{
@@ -315,6 +321,9 @@ pk_completion_function (pk_compiler pkc,
function_name = pkl_env_get_next_matching_decl (env, &iter, text, len);
return function_name;
+
+#undef iter
+#undef idx
}
/* This function provides command line completion when the tag of an
@@ -328,18 +337,11 @@ pk_completion_function (pk_compiler pkc,
indicate that there are no more such tags.
*/
char *
-pk_ios_completion_function (pk_compiler pkc __attribute__ ((unused)),
- const char *text, int state)
+pk_ios_completion_function (pk_compiler pkc, const char *text, int state)
{
- static ios io;
- if (state == 0)
- {
- io = ios_begin ();
- }
- else
- {
- io = ios_next (io);
- }
+#define io pkc->completion_ios
+
+ io = state == 0 ? ios_begin (pvm_ios_context (pkc->vm)) : ios_next (io);
int len = strlen (text);
while (1)
@@ -357,6 +359,8 @@ pk_ios_completion_function (pk_compiler pkc __attribute__
((unused)),
}
return NULL;
+
+#undef io
}
int
@@ -448,14 +452,13 @@ pk_ios
pk_ios_cur (pk_compiler pkc)
{
pkc->status = PK_OK;
- return (pk_ios) ios_cur ();
+ return (pk_ios) ios_cur (pvm_ios_context (pkc->vm));
}
void
pk_ios_set_cur (pk_compiler pkc, pk_ios io)
{
- /* XXX use pkc */
- ios_set_cur ((ios) io);
+ ios_set_cur (pvm_ios_context (pkc->vm), (ios) io);
pkc->status = PK_OK;
}
@@ -475,16 +478,14 @@ pk_ios
pk_ios_search (pk_compiler pkc, const char *handler)
{
pkc->status = PK_OK;
- /* XXX use pkc */
- return (pk_ios) ios_search (handler);
+ return (pk_ios) ios_search (pvm_ios_context (pkc->vm), handler);
}
pk_ios
pk_ios_search_by_id (pk_compiler pkc, int id)
{
pkc->status = PK_OK;
- /* XXX use pkc */
- return (pk_ios) ios_search_by_id (id);
+ return (pk_ios) ios_search_by_id (pvm_ios_context (pkc->vm), id);
}
int
@@ -492,9 +493,9 @@ pk_ios_open (pk_compiler pkc,
const char *handler, uint64_t flags, int set_cur_p)
{
int ret;
+ ios_context ictx = pvm_ios_context (pkc->vm);
- /* XXX use pkc */
- if ((ret = ios_open (handler, flags, set_cur_p)) >= 0)
+ if ((ret = ios_open (ictx, handler, flags, set_cur_p)) >= 0)
return ret;
switch (ret)
@@ -515,8 +516,7 @@ pk_ios_open (pk_compiler pkc,
void
pk_ios_close (pk_compiler pkc, pk_ios io)
{
- /* XXX use pkc */
- ios_close ((ios) io);
+ ios_close (pvm_ios_context (pkc->vm), (ios) io);
pkc->status = PK_OK;
}
@@ -562,8 +562,7 @@ pk_ios_map (pk_compiler pkc,
pk_ios_map_fn cb, void *data)
{
struct ios_map_fn_payload payload = { cb, data };
- /* XXX use pkc */
- ios_map (my_ios_map_fn, (void *) &payload);
+ ios_map (pvm_ios_context (pkc->vm), my_ios_map_fn, (void *) &payload);
pkc->status = PK_OK;
}
@@ -957,26 +956,12 @@ pk_print_val_with_params (pk_compiler pkc, pk_val val,
indent, acutoff, flags);
}
-static struct ios_dev_if foreign_iod_if;
-
int
pk_register_iod (pk_compiler pkc, struct pk_iod_if *iod_if)
{
- pkc->status = PK_OK;
+ ios_context ictx = pvm_ios_context (pkc->vm);
-#define CF(FN) foreign_iod_if.FN = iod_if->FN
- CF (get_if_name);
- CF (handler_normalize);
- CF (open);
- CF (close);
- CF (pread);
- CF (pwrite);
- CF (get_flags);
- CF (size);
- CF (flush);
- CF (user_data);
-#undef CF
-
- (void) ios_register_foreign_iod (&foreign_iod_if);
+ pkc->status = PK_OK;
+ (void) ios_register_foreign_iod (ictx, (struct ios_dev_if *)iod_if);
return pkc->status;
}
diff --git a/libpoke/pvm.c b/libpoke/pvm.c
index 7b64a96e..4622c4db 100644
--- a/libpoke/pvm.c
+++ b/libpoke/pvm.c
@@ -39,6 +39,8 @@
(PVM_STATE_BACKING_FIELD (& (PVM)->pvm_state, exit_code))
#define PVM_STATE_VM(PVM) \
(PVM_STATE_BACKING_FIELD (& (PVM)->pvm_state, vm))
+#define PVM_STATE_IOS_CONTEXT(PVM) \
+ (PVM_STATE_BACKING_FIELD (& (PVM)->pvm_state, ictx))
#define PVM_STATE_ENV(PVM) \
(PVM_STATE_RUNTIME_FIELD (& (PVM)->pvm_state, env))
#define PVM_STATE_ENDIAN(PVM) \
@@ -108,10 +110,20 @@ pvm_initialize_state (pvm apvm, struct pvm_state *state)
pvm
pvm_init (void)
{
- pvm apvm = calloc (1, sizeof (struct pvm));
+ pvm apvm;
+ ios_context ictx;
+
+ apvm = calloc (1, sizeof (struct pvm));
if (!apvm)
return NULL;
+ /* Initialize the IO space. */
+ ictx = ios_init ();
+ if (!ictx) {
+ free (apvm);
+ return NULL;
+ }
+
/* Initialize the memory allocation subsystem. */
pvm_alloc_initialize ();
@@ -123,6 +135,7 @@ pvm_init (void)
/* Initialize the VM state. */
pvm_initialize_state (apvm, &apvm->pvm_state);
+ PVM_STATE_IOS_CONTEXT (apvm) = ictx;
/* Initialize pvm-program. */
pvm_program_init ();
@@ -235,6 +248,9 @@ pvm_shutdown (pvm apvm)
/* Finalize values. */
pvm_val_finalize ();
+ /* Shutdown the IO space. */
+ ios_shutdown (PVM_STATE_IOS_CONTEXT (apvm));
+
/* Finalize the VM state. */
pvm_state_finalize (&apvm->pvm_state);
@@ -247,6 +263,14 @@ pvm_shutdown (pvm apvm)
pvm_alloc_finalize ();
}
+ios_context
+pvm_ios_context (pvm apvm)
+{
+ assert (apvm);
+ assert (PVM_STATE_IOS_CONTEXT (apvm));
+ return PVM_STATE_IOS_CONTEXT (apvm);
+}
+
enum ios_endian
pvm_endian (pvm apvm)
{
diff --git a/libpoke/pvm.h b/libpoke/pvm.h
index 80e388d8..7c70d2d8 100644
--- a/libpoke/pvm.h
+++ b/libpoke/pvm.h
@@ -569,6 +569,10 @@ pvm pvm_init (void);
void pvm_shutdown (pvm pvm);
+/* Get the IO space context. */
+
+ios_context pvm_ios_context (pvm apvm);
+
/* Get the current run-time environment of PVM. */
pvm_env pvm_get_env (pvm pvm);
diff --git a/libpoke/pvm.jitter b/libpoke/pvm.jitter
index 4c48bef7..9fb4a7d8 100644
--- a/libpoke/pvm.jitter
+++ b/libpoke/pvm.jitter
@@ -96,6 +96,7 @@ wrapped-functions
pvm_val_reloc
pvm_val_unmap
pvm_val_ureloc
+ ios_init
ios_close
ios_cur
ios_flags
@@ -508,12 +509,13 @@ late-header-c
IOTYPE##64_t value; \
ios io; \
ios_off offset; \
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx); \
\
offset = PVM_VAL_ULONG (JITTER_TOP_STACK ()); \
if (JITTER_UNDER_TOP_STACK () == PVM_NULL) \
- io = ios_cur (); \
+ io = ios_cur (ictx); \
else \
- io = ios_search_by_id (PVM_VAL_INT (JITTER_UNDER_TOP_STACK ())); \
+ io = ios_search_by_id (ictx, PVM_VAL_INT (JITTER_UNDER_TOP_STACK ()));\
\
if (io == NULL) \
PVM_RAISE_DFL (PVM_E_NO_IOS); \
@@ -548,14 +550,15 @@ late-header-c
pvm_val offset_val = JITTER_UNDER_TOP_STACK (); \
ios io; \
ios_off offset; \
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx); \
\
JITTER_DROP_STACK (); \
JITTER_DROP_STACK (); \
\
if (JITTER_TOP_STACK () == PVM_NULL) \
- io = ios_cur (); \
+ io = ios_cur (ictx); \
else \
- io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ())); \
+ io = ios_search_by_id (ictx, PVM_VAL_INT (JITTER_TOP_STACK ())); \
\
if (io == NULL) \
PVM_RAISE_DFL (PVM_E_NO_IOS); \
@@ -965,6 +968,7 @@ state-struct-backing-c
pvm_val result_value;
jitter_stack_height canary;
pvm vm;
+ ios_context ictx;
end
end
@@ -990,6 +994,7 @@ state-initialization-c
jitter_state_backing->canary = NULL;
jitter_state_backing->exit_code = PVM_EXIT_OK;
jitter_state_backing->result_value = PVM_NULL;
+ jitter_state_backing->ictx = NULL;
jitter_state_runtime->endian = IOS_ENDIAN_MSB;
jitter_state_runtime->nenc = IOS_NENC_2;
jitter_state_runtime->pretty_print = 0;
@@ -1491,8 +1496,9 @@ instruction open ()
code
char *filename = PVM_VAL_STR (JITTER_UNDER_TOP_STACK ());
uint64_t flags = PVM_VAL_ULONG (JITTER_TOP_STACK ());
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx);
- int ret = ios_open (filename, flags, 0);
+ int ret = ios_open (ictx, filename, flags, 0);
if (ret == IOS_EFLAGS)
PVM_RAISE_DFL (PVM_E_IOFLAGS);
@@ -1520,12 +1526,13 @@ instruction close ()
# XXX make non-relocatable: see raise
code
int io_id = PVM_VAL_INT (JITTER_TOP_STACK ());
- ios io = ios_search_by_id (io_id);
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx);
+ ios io = ios_search_by_id (ictx, io_id);
if (io == NULL)
PVM_RAISE_DFL (PVM_E_NO_IOS);
- if (ios_close (io) != IOS_OK)
+ if (ios_close (ictx, io) != IOS_OK)
PVM_RAISE_DFL (PVM_E_IO);
JITTER_DROP_STACK ();
@@ -1550,7 +1557,8 @@ instruction flush ()
code
ios_off offset = PVM_VAL_ULONG (JITTER_TOP_STACK ());
int io_id = PVM_VAL_INT (JITTER_UNDER_TOP_STACK ());
- ios io = ios_search_by_id (io_id);
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx);
+ ios io = ios_search_by_id (ictx, io_id);
if (io == NULL)
PVM_RAISE_DFL (PVM_E_IO);
@@ -1576,7 +1584,8 @@ instruction pushios ()
branching # because of PVM_RAISE_DIRECT
# XXX make non-relocatable: see raise
code
- ios cur_io = ios_cur ();
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx);
+ ios cur_io = ios_cur (ictx);
if (cur_io == NULL)
PVM_RAISE_DFL (PVM_E_NO_IOS);
@@ -1597,11 +1606,12 @@ instruction popios ()
branching # because of PVM_RAISE_DIRECT
# XXX make non-relocatable: see raise
code
- ios io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx);
+ ios io = ios_search_by_id (ictx, PVM_VAL_INT (JITTER_TOP_STACK ()));
if (io == NULL)
PVM_RAISE_DFL (PVM_E_NO_IOS);
- ios_set_cur (io);
+ ios_set_cur (ictx, io);
JITTER_DROP_STACK ();
end
end
@@ -1620,7 +1630,8 @@ instruction ioflags ()
branching # because of PVM_RAISE_DIRECT
# XXX make non-relocatable: see raise
code
- ios io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx);
+ ios io = ios_search_by_id (ictx, PVM_VAL_INT (JITTER_TOP_STACK ()));
if (io == NULL)
PVM_RAISE_DFL (PVM_E_NO_IOS);
@@ -1642,7 +1653,8 @@ instruction iosize ()
branching # because of PVM_RAISE_DIRECT
# XXX make non-relocatable: see raise
code
- ios io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx);
+ ios io = ios_search_by_id (ictx, PVM_VAL_INT (JITTER_TOP_STACK ()));
if (io == NULL)
PVM_RAISE_DFL (PVM_E_NO_IOS);
@@ -1670,7 +1682,8 @@ instruction iogetb ()
branching # because of PVM_RAISE_DIRECT
# XXX make non-relocatable: see raise
code
- ios io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx);
+ ios io = ios_search_by_id (ictx, PVM_VAL_INT (JITTER_TOP_STACK ()));
if (io == NULL)
PVM_RAISE_DFL (PVM_E_NO_IOS);
@@ -1703,7 +1716,8 @@ instruction iosetb ()
# XXX make non-relocatable: see raise
code
pvm_val bias = JITTER_UNDER_TOP_STACK();
- ios io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx);
+ ios io = ios_search_by_id (ictx, PVM_VAL_INT (JITTER_TOP_STACK ()));
JITTER_DROP_STACK ();
@@ -5948,9 +5962,10 @@ instruction peeks ()
ios_off offset;
char *ios_str;
int ret;
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx);
offset = PVM_VAL_ULONG (JITTER_TOP_STACK ());
- io = ios_search_by_id (PVM_VAL_INT (JITTER_UNDER_TOP_STACK ()));
+ io = ios_search_by_id (ictx, PVM_VAL_INT (JITTER_UNDER_TOP_STACK ()));
if (io == NULL)
PVM_RAISE_DFL (PVM_E_NO_IOS);
@@ -5986,13 +6001,14 @@ instruction pokes ()
ios_off offset;
char *str;
int ret;
+ ios_context ictx = PVM_STATE_BACKING_FIELD (ictx);
str = PVM_VAL_STR (JITTER_TOP_STACK ());
offset = PVM_VAL_ULONG (JITTER_UNDER_TOP_STACK ());
JITTER_DROP_STACK();
JITTER_DROP_STACK();
- io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+ io = ios_search_by_id (ictx, PVM_VAL_INT (JITTER_TOP_STACK ()));
if (io == NULL)
PVM_RAISE_DFL (PVM_E_NO_IOS);
--
2.34.1
[PATCH v2 1/2] pkl: Add user_data in IO device API, Mohammad-Reza Nabipoor, 2021/12/23
- [PATCH v2 2/2] pkl: Remove global state from IOS,
Mohammad-Reza Nabipoor <=
[PATCH v4] pkl: Remove global state from IOS, Mohammad-Reza Nabipoor, 2021/12/28
Re: [PATCH v4] pkl: Remove global state from IOS, Jose E. Marchesi, 2021/12/28
Re: [PATCH v2 1/2] pkl: Add user_data in IO device API, Jose E. Marchesi, 2021/12/23