poke-devel
[Top][All Lists]
Advanced

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

[PATCH] pkl: Remove global state from IOS


From: Mohammad-Reza Nabipoor
Subject: [PATCH] pkl: Remove global state from IOS
Date: Mon, 20 Dec 2021 01:19:10 +0330

2021-12-20  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>

        * libpoke/ios.h (ios_meta): New type.
        (ios_init): Returns `ios_meta`.
        (ios_shutdown): Add new `ios_meta` 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-file.c (ios_dev_file_open): Likewise.
        * libpoke/ios-dev-mem.c (ios_dev_mem_open): Likewise.
        * libpoke/ios-dev-nbd.c (ios_dev_nbd_open): Likewise.
        * libpoke/ios-dev-proc.c (ios_dev_proc_open): Likewise.
        * libpoke/ios-dev-stream.c (ios_dev_stream_open): Likewise.
        * libpoke/ios-dev-zero.c (ios_dev_zero_open): Likewise.
        * libpoke/ios-dev-sub.c (ios_dev_sub_open): Likewise.
        (struct ios_dev_sub): Add new field.
        * libpoke/ios-dev.h (struct ios_dev_if): Change `open` to accept new
        `ios_meta` param.
        * libpoke/libpoke.h (struct pk_iod_if): Likewise.
        * libpoke/ios.c (struct ios_meta): New struct.
        (ios_next_id): Removed.
        (io_list): Likewise.
        (cur_io): Likewise.
        (ios_meta): Returns `ios_meta`.
        (ios_shutdown): Add new `ios_meta` 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_meta): New function.
        * libpoke/pvm.c (pvm_ios_meta): Likewise.
        (PVM_STATE_IOS_META): 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_meta`.
        (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_meta`.
        * libpoke/pvm.jitter (wrapped-functions): Add `ios_init`.
        (state-struct-backing-c): Add new field (`imeta`).
        (state-initialization-c): Initialize new field.
        (open): Update to use `imeta` field.
        (close): Likewise.
        (flush): Likewise.
        (pushios): Likewise.
        (popios): Likewise.
        (ioflags): Likewise.
        (iosize): Likewise.
        (iogetb): Likewise.
        (iosetb): Likewise.
        (peeks): Likewise.
        (pokes): Likewise.
---

Hello, Jose.

This patch removes global state from IOS by introducing a new struct
`ios_meta`.
I'll send another patch later for removing global termif.
I think, not having a global state is a good thing. With no global state,
one can run `libpoke` instances in different threads, safely. Also a program
using `libpoke` can use a library that uses `libpoke` itself.

I changed `open` function pointer of `struct pk_iod_if` to be compatible
with the rest of world. But user doesn't need (and should not care about
this new first parameter). I don't like this new unused parameter here.
WDYT?


Regards,
Mohammad-Reza


 ChangeLog                |  77 +++++++++++++
 libpoke/ios-dev-file.c   |   4 +-
 libpoke/ios-dev-mem.c    |   4 +-
 libpoke/ios-dev-nbd.c    |   4 +-
 libpoke/ios-dev-proc.c   |   4 +-
 libpoke/ios-dev-stream.c |   4 +-
 libpoke/ios-dev-sub.c    |  10 +-
 libpoke/ios-dev-zero.c   |   3 +-
 libpoke/ios-dev.h        |   2 +-
 libpoke/ios.c            | 227 +++++++++++++++++++++------------------
 libpoke/ios.h            |  26 ++---
 libpoke/libpoke.c        |  63 +++++------
 libpoke/libpoke.h        |   2 +-
 libpoke/pvm.c            |  26 ++++-
 libpoke/pvm.h            |   4 +
 libpoke/pvm.jitter       |  50 ++++++---
 16 files changed, 329 insertions(+), 181 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d7415fa5..6ff064c5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,80 @@
+2021-12-20  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
+
+       * libpoke/ios.h (ios_meta): New type.
+       (ios_init): Returns `ios_meta`.
+       (ios_shutdown): Add new `ios_meta` 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-file.c (ios_dev_file_open): Likewise.
+       * libpoke/ios-dev-mem.c (ios_dev_mem_open): Likewise.
+       * libpoke/ios-dev-nbd.c (ios_dev_nbd_open): Likewise.
+       * libpoke/ios-dev-proc.c (ios_dev_proc_open): Likewise.
+       * libpoke/ios-dev-stream.c (ios_dev_stream_open): Likewise.
+       * libpoke/ios-dev-zero.c (ios_dev_zero_open): Likewise.
+       * libpoke/ios-dev-sub.c (ios_dev_sub_open): Likewise.
+       (struct ios_dev_sub): Add new field.
+       * libpoke/ios-dev.h (struct ios_dev_if): Change `open` to accept new
+       `ios_meta` param.
+       * libpoke/libpoke.h (struct pk_iod_if): Likewise.
+       * libpoke/ios.c (struct ios_meta): New struct.
+       (ios_next_id): Removed.
+       (io_list): Likewise.
+       (cur_io): Likewise.
+       (ios_meta): Returns `ios_meta`.
+       (ios_shutdown): Add new `ios_meta` 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_meta): New function.
+       * libpoke/pvm.c (pvm_ios_meta): Likewise.
+       (PVM_STATE_IOS_META): 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_meta`.
+       (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_meta`.
+       * libpoke/pvm.jitter (wrapped-functions): Add `ios_init`.
+       (state-struct-backing-c): Add new field (`imeta`).
+       (state-initialization-c): Initialize new field.
+       (open): Update to use `imeta` field.
+       (close): Likewise.
+       (flush): Likewise.
+       (pushios): Likewise.
+       (popios): Likewise.
+       (ioflags): Likewise.
+       (iosize): Likewise.
+       (iogetb): Likewise.
+       (iosetb): Likewise.
+       (peeks): Likewise.
+       (pokes): Likewise.
+
 2021-12-19  Jose E. Marchesi  <jemarch@termi>
 
        * doc/poke.texi (Optional Fields): Explain how optional fields are
diff --git a/libpoke/ios-dev-file.c b/libpoke/ios-dev-file.c
index d470c62e..82e1fbee 100644
--- a/libpoke/ios-dev-file.c
+++ b/libpoke/ios-dev-file.c
@@ -96,7 +96,7 @@ ios_dev_file_convert_flags (int mode_flags, char 
**mode_for_fdopen)
 }
 
 static void *
-ios_dev_file_open (const char *handler, uint64_t flags, int *error)
+ios_dev_file_open (ios_meta m, const char *handler, uint64_t flags, int *error)
 {
   struct ios_dev_file *fio = NULL;
   FILE *f = NULL;
@@ -107,6 +107,8 @@ ios_dev_file_open (const char *handler, uint64_t flags, int 
*error)
   int flags_for_open = 0;
   int fd;
 
+  (void)m;
+
   if (mode_flags != 0)
     {
       /* Decide what mode to use to open the file.  */
diff --git a/libpoke/ios-dev-mem.c b/libpoke/ios-dev-mem.c
index c1757500..22a63e7c 100644
--- a/libpoke/ios-dev-mem.c
+++ b/libpoke/ios-dev-mem.c
@@ -56,11 +56,13 @@ ios_dev_mem_handler_normalize (const char *handler, 
uint64_t flags, int *error)
 }
 
 static void *
-ios_dev_mem_open (const char *handler, uint64_t flags, int *error)
+ios_dev_mem_open (ios_meta m, const char *handler, uint64_t flags, int *error)
 {
   int internal_error = IOD_ERROR;
   struct ios_dev_mem *mio = malloc (sizeof (struct ios_dev_mem));
 
+  (void)m;
+
   if (!mio)
     {
       internal_error = IOD_ENOMEM;
diff --git a/libpoke/ios-dev-nbd.c b/libpoke/ios-dev-nbd.c
index 2c3fa6ab..afa0086a 100644
--- a/libpoke/ios-dev-nbd.c
+++ b/libpoke/ios-dev-nbd.c
@@ -66,7 +66,7 @@ ios_dev_nbd_handler_normalize (const char *handler, uint64_t 
flags, int* error)
 }
 
 static void *
-ios_dev_nbd_open (const char *handler, uint64_t flags, int *error)
+ios_dev_nbd_open (ios_meta m, const char *handler, uint64_t flags, int *error)
 {
   struct ios_dev_nbd *nio = NULL;
   struct nbd_handle *nbd = NULL;
@@ -74,6 +74,8 @@ ios_dev_nbd_open (const char *handler, uint64_t flags, int 
*error)
   int internal_error = IOD_ERROR;
   int64_t size;
 
+  (void)m;
+
   /* We have to connect before we know if server permits writes.  */
   nbd = nbd_create ();
   if (nbd == NULL)
diff --git a/libpoke/ios-dev-proc.c b/libpoke/ios-dev-proc.c
index a6ad9247..8df62386 100644
--- a/libpoke/ios-dev-proc.c
+++ b/libpoke/ios-dev-proc.c
@@ -71,7 +71,7 @@ ios_dev_proc_handler_normalize (const char *handler, uint64_t 
flags, int *error)
 }
 
 static void *
-ios_dev_proc_open (const char *handler, uint64_t flags, int *error)
+ios_dev_proc_open (ios_meta m, const char *handler, uint64_t flags, int *error)
 {
   struct ios_dev_proc *proc = malloc (sizeof (struct ios_dev_proc));
 
@@ -110,7 +110,7 @@ ios_dev_proc_open (const char *handler, uint64_t flags, int 
*error)
       return NULL;
     }
 
-  proc->memfile = ios_dev_file.open (proc->memfile_path,
+  proc->memfile = ios_dev_file.open (m, proc->memfile_path,
                                      IOS_F_READ | IOS_F_WRITE,
                                      error);
   if (proc->memfile == NULL)
diff --git a/libpoke/ios-dev-stream.c b/libpoke/ios-dev-stream.c
index 5a566657..568ad668 100644
--- a/libpoke/ios-dev-stream.c
+++ b/libpoke/ios-dev-stream.c
@@ -70,11 +70,13 @@ ios_dev_stream_handler_normalize (const char *handler, 
uint64_t flags, int *erro
 }
 
 static void *
-ios_dev_stream_open (const char *handler, uint64_t flags, int *error)
+ios_dev_stream_open (ios_meta m, const char *handler, uint64_t flags, int 
*error)
 {
   struct ios_dev_stream *sio;
   int internal_error = IOD_ERROR;
 
+  (void)m;
+
   sio = malloc (sizeof (struct ios_dev_stream));
   if (!sio)
     {
diff --git a/libpoke/ios-dev-sub.c b/libpoke/ios-dev-sub.c
index fe061511..1947c6a5 100644
--- a/libpoke/ios-dev-sub.c
+++ b/libpoke/ios-dev-sub.c
@@ -32,6 +32,7 @@
 
 struct ios_dev_sub
 {
+  ios_meta imeta;
   int base_ios_id;
   ios_dev_off base;
   ios_dev_off size;
@@ -68,7 +69,7 @@ ios_dev_sub_handler_normalize (const char *handler, uint64_t 
flags, int* error)
 }
 
 static void *
-ios_dev_sub_open (const char *handler, uint64_t flags, int *error)
+ios_dev_sub_open (ios_meta m, const char *handler, uint64_t flags, int *error)
 {
   struct ios_dev_sub *sub = malloc (sizeof (struct ios_dev_sub));
   const char *p;
@@ -83,6 +84,7 @@ ios_dev_sub_open (const char *handler, uint64_t flags, int 
*error)
     }
 
   sub->name = NULL; /* To ease error management below.  */
+  sub->imeta = m;
 
   /* 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)
     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->imeta, 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->imeta, 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->imeta, sub->base_ios_id);
 
   if (ios == NULL || !(sub->flags & IOS_F_WRITE))
     return IOD_ERROR;
diff --git a/libpoke/ios-dev-zero.c b/libpoke/ios-dev-zero.c
index 2772c81d..e8da5873 100644
--- a/libpoke/ios-dev-zero.c
+++ b/libpoke/ios-dev-zero.c
@@ -53,8 +53,9 @@ ios_dev_zero_handler_normalize (const char *handler, uint64_t 
flags, int *error)
 }
 
 static void *
-ios_dev_zero_open (const char *handler, uint64_t flags, int *error)
+ios_dev_zero_open (ios_meta m, const char *handler, uint64_t flags, int *error)
 {
+  (void)m;
   /* This IOD doesn't need to keep any state.  */
   if (error)
     *error = IOD_OK;
diff --git a/libpoke/ios-dev.h b/libpoke/ios-dev.h
index 2ffd5fea..64ec20b7 100644
--- a/libpoke/ios-dev.h
+++ b/libpoke/ios-dev.h
@@ -67,7 +67,7 @@ struct ios_dev_if
      IOD_OK.  Note that this function assumes that HANDLER is recognized as a
      handler by the backend.  */
 
-  void * (*open) (const char *handler, uint64_t flags, int *error);
+  void * (*open) (ios_meta m, const char *handler, uint64_t flags, int *error);
 
   /* Close the given device.  Return the error code if there was an error
      during the operation, IOD_OK otherwise.  */
diff --git a/libpoke/ios.c b/libpoke/ios.c
index b12f5e57..27663b62 100644
--- a/libpoke/ios.c
+++ b/libpoke/ios.c
@@ -78,14 +78,13 @@ 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;
+struct ios_meta
+{
+  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 *foreign_dev_if;
+};
 
 /* The available backends are implemented in their own files, and
    provide the following interfaces.  */
@@ -104,7 +103,6 @@ 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,
@@ -120,65 +118,71 @@ static struct ios_dev_if *ios_dev_ifs[] =
    NULL,
   };
 
-void
+ios_meta
 ios_init (void)
 {
-  /* Nothing to do here... yet.  */
+  return calloc (1, sizeof(struct ios_meta));
 }
 
 void
-ios_shutdown (void)
+ios_shutdown (ios_meta m)
 {
+  ios inext;
+
+  if (!m)
+    return;
   /* Close and free all open IO spaces.  */
-  while (io_list)
-    ios_close (io_list);
+  for (ios i = m->io_list; i; i = inext)
+    {
+      inext = i->next;
+      ios_close (m, i);
+    }
+  free (m);
 }
 
 int
-ios_open (const char *handler, uint64_t flags, int set_cur)
+ios_open (ios_meta m, const char *handler, uint64_t flags, int set_cur_p)
 {
   struct ios *io;
   struct ios_dev_if **dev_if = NULL;
   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.  */
+  if (m->foreign_dev_if)
+    {
+      dev_if = &m->foreign_dev_if;
+      io->handler = m->foreign_dev_if->handler_normalize (handler, flags,
+                                                          &iod_error);
+      if (iod_error != IOD_OK)
+        goto error;
+      if (io->handler)
+        goto found;
+    }
   dev_if = ios_dev_ifs;
   do
     {
-      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 (iod_error != IOD_OK)
         goto error;
       if (io->handler)
         break;
-
-      ++dev_if;
     }
-  while (*dev_if);
+  while (*++dev_if);
 
   if (*dev_if == NULL)
     goto error;
 
+ found:
   io->dev_if = *dev_if;
 
   /* Do not re-open an already-open IO space.  */
-  for (ios i = io_list; i; i = i->next)
+  for (ios i = m->io_list; i; i = i->next)
     if (STREQ (i->handler, io->handler))
       {
         error = IOS_EOPEN;
@@ -186,20 +190,20 @@ ios_open (const char *handler, uint64_t flags, int 
set_cur)
       }
 
   /* Open the device using the interface found above.  */
-  io->dev = io->dev_if->open (handler, flags, &iod_error);
+  io->dev = io->dev_if->open (m, handler, flags, &iod_error);
   if (iod_error || io->dev == NULL)
     goto error;
 
   /* Increment the id counter after all possible errors are avoided.  */
-  io->id = ios_next_id++;
+  io->id = m->next_id++;
 
   /* Add the newly created space to the list, and update the current
      space.  */
-  io->next = io_list;
-  io_list = io;
+  io->next = m->io_list;
+  m->io_list = io;
 
-  if (!cur_io || set_cur == 1)
-    cur_io = io;
+  if (!m->cur_io || set_cur_p)
+    m->cur_io = io;
 
   return io->id;
 
@@ -215,11 +219,13 @@ ios_open (const char *handler, uint64_t flags, int 
set_cur)
 }
 
 int
-ios_close (ios io)
+ios_close (ios_meta m, ios io)
 {
-  struct ios *tmp;
   int ret;
 
+  assert (m);
+  assert (io);
+
   /* XXX: if not saved, ask before closing.  */
 
   /* Close the device operated by the IO space.
@@ -227,55 +233,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 (m->io_list != NULL); /* The list contains at least this IO space.  */
+  if (m->io_list == io)
+    m->io_list = m->io_list->next;
   else
     {
-      for (tmp = io_list; tmp->next != io; tmp = tmp->next)
+      struct ios *tmp;
+
+      for (tmp = m->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 == m->cur_io)
+    m->cur_io = m->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_meta m)
 {
-  return io->handler;
+  return m->io_list;
 }
 
 ios
-ios_cur (void)
+ios_cur (ios_meta m)
 {
-  return cur_io;
+  return m->cur_io;
 }
 
 void
-ios_set_cur (ios io)
+ios_set_cur (ios_meta m, ios io)
 {
-  cur_io = io;
+  ios i = m->io_list;
+
+  for (; i && i != io; i = i->next)
+    ;
+  assert(i == io);
+  m->cur_io = io;
 }
 
 ios
-ios_search (const char *handler)
+ios_search (ios_meta m, const char *handler)
 {
   ios io;
 
-  for (io = io_list; io; io = io->next)
+  for (io = m->io_list; io; io = io->next)
     if (STREQ (io->handler, handler))
       break;
 
@@ -283,27 +290,47 @@ ios_search (const char *handler)
 }
 
 ios
-ios_search_by_id (int id)
+ios_search_by_id (ios_meta m, int id)
 {
   ios io;
 
-  for (io = io_list; io; io = io->next)
+  for (io = m->io_list; io; io = io->next)
     if (io->id == id)
       break;
 
   return io;
 }
 
+void
+ios_map (ios_meta m, ios_map_fn cb, void *data)
+{
+  ios io;
+  ios io_next;
+
+  for (io = m->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
@@ -318,10 +345,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 ios->dev_if;
+}
+
+const char *
+ios_get_dev_if_name (ios io)
 {
-  return io_list;
+  return io->dev_if->get_if_name ();
 }
 
 bool
@@ -336,18 +381,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.  */
@@ -1604,42 +1641,18 @@ 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_meta m)
 {
-  return ios_dev_ifs[0];
+  return m->foreign_dev_if;
 }
 
 int
-ios_register_foreign_iod (struct ios_dev_if *iod_if)
+ios_register_foreign_iod (ios_meta m, struct ios_dev_if *iod_if)
 {
-  if (ios_dev_ifs[0] != NULL)
+  if (m->foreign_dev_if != NULL)
     return IOS_ERROR;
 
-  ios_dev_ifs[0] = iod_if;
+  m->foreign_dev_if = iod_if;
   return IOS_OK;
 }
diff --git a/libpoke/ios.h b/libpoke/ios.h
index 3af10d67..1698319f 100644
--- a/libpoke/ios.h
+++ b/libpoke/ios.h
@@ -23,12 +23,14 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+typedef struct ios_meta *ios_meta;
+
 /* The following two functions intialize and shutdown the IO poke
    subsystem.  */
 
-void ios_init (void);
+ios_meta ios_init (void);
 
-void ios_shutdown (void);
+void ios_shutdown (ios_meta);
 
 /* "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_meta 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_meta 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_meta m);
 
 /* Set the current IO space to IO.  */
 
-void ios_set_cur (ios io);
+void ios_set_cur (ios_meta 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_meta 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_meta 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_meta 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_meta 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_meta 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_meta m, struct ios_dev_if *iod_if);
 
 #endif /* ! IOS_H */
diff --git a/libpoke/libpoke.c b/libpoke/libpoke.c
index 072205cf..0c632da1 100644
--- a/libpoke/libpoke.c
+++ b/libpoke/libpoke.c
@@ -36,8 +36,14 @@ 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 */
+  struct ios_dev_if foreign_iod_if;
+
+  /* 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 +63,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 +297,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 +322,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 +338,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_meta (pkc->vm)) : ios_next (io);
 
   int len  = strlen (text);
   while (1)
@@ -357,6 +360,8 @@ pk_ios_completion_function (pk_compiler pkc __attribute__ 
((unused)),
     }
 
   return NULL;
+
+#undef io
 }
 
 int
@@ -448,14 +453,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_meta (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_meta (pkc->vm), (ios) io);
   pkc->status = PK_OK;
 }
 
@@ -475,16 +479,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_meta (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_meta (pkc->vm), id);
 }
 
 int
@@ -492,9 +494,9 @@ pk_ios_open (pk_compiler pkc,
              const char *handler, uint64_t flags, int set_cur_p)
 {
   int ret;
+  ios_meta iom = pvm_ios_meta (pkc->vm);
 
-  /* XXX use pkc */
-  if ((ret = ios_open (handler, flags, set_cur_p)) >= 0)
+  if ((ret = ios_open (iom, handler, flags, set_cur_p)) >= 0)
     return ret;
 
   switch (ret)
@@ -515,8 +517,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_meta (pkc->vm), (ios) io);
   pkc->status = PK_OK;
 }
 
@@ -562,8 +563,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_meta (pkc->vm), my_ios_map_fn, (void *) &payload);
   pkc->status = PK_OK;
 }
 
@@ -957,14 +957,15 @@ 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)
 {
+  ios_meta imeta = pvm_ios_meta (pkc->vm);
+
   pkc->status = PK_OK;
 
-#define CF(FN) foreign_iod_if.FN = iod_if->FN
+#define CF(FN) pkc->foreign_iod_if.FN = iod_if->FN
   CF (get_if_name);
   CF (handler_normalize);
   CF (open);
@@ -976,6 +977,6 @@ pk_register_iod (pk_compiler pkc, struct pk_iod_if *iod_if)
   CF (flush);
 #undef CF
 
-  (void) ios_register_foreign_iod (&foreign_iod_if);
+  (void) ios_register_foreign_iod (imeta, &pkc->foreign_iod_if);
   return pkc->status;
 }
diff --git a/libpoke/libpoke.h b/libpoke/libpoke.h
index 7d6d6134..28d87645 100644
--- a/libpoke/libpoke.h
+++ b/libpoke/libpoke.h
@@ -1074,7 +1074,7 @@ struct pk_iod_if
 {
   const char *(*get_if_name) ();
   char *(*handler_normalize) (const char *handler, uint64_t flags, int *error);
-  void * (*open) (const char *handler, uint64_t flags, int *error);
+  void * (*open) (void *, const char *handler, uint64_t flags, int *error);
   int (*close) (void *dev);
   int (*pread) (void *dev, void *buf, size_t count, pk_iod_off offset);
   int (*pwrite) (void *dev, const void *buf, size_t count, pk_iod_off offset);
diff --git a/libpoke/pvm.c b/libpoke/pvm.c
index 7b64a96e..9411c667 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_META(PVM)                         \
+  (PVM_STATE_BACKING_FIELD (& (PVM)->pvm_state, imeta))
 #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_meta imeta;
+
+  apvm = calloc (1, sizeof (struct pvm));
   if (!apvm)
     return NULL;
 
+  /* Initialize the IO space.  */
+  imeta = ios_init ();
+  if (!imeta) {
+    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_META (apvm) = imeta;
 
   /* Initialize pvm-program.  */
   pvm_program_init ();
@@ -245,6 +258,17 @@ pvm_shutdown (pvm apvm)
 
   /* Finalize the memory allocator.  */
   pvm_alloc_finalize ();
+
+  /* Shutdown the IO space.  */
+  ios_shutdown (PVM_STATE_IOS_META (apvm));
+}
+
+ios_meta
+pvm_ios_meta (pvm apvm)
+{
+  assert (apvm);
+  assert (PVM_STATE_IOS_META (apvm));
+  return PVM_STATE_IOS_META (apvm);
 }
 
 enum ios_endian
diff --git a/libpoke/pvm.h b/libpoke/pvm.h
index 80e388d8..531e916f 100644
--- a/libpoke/pvm.h
+++ b/libpoke/pvm.h
@@ -569,6 +569,10 @@ pvm pvm_init (void);
 
 void pvm_shutdown (pvm pvm);
 
+/* Get the meta data of IO space.  */
+
+ios_meta pvm_ios_meta (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..28654cf5 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_meta iom = PVM_STATE_BACKING_FIELD (imeta);                         \
                                                                              \
      offset = PVM_VAL_ULONG (JITTER_TOP_STACK ());                           \
      if (JITTER_UNDER_TOP_STACK () == PVM_NULL)                              \
-       io = ios_cur ();                                                      \
+       io = ios_cur (iom);                                                   \
      else                                                                    \
-       io = ios_search_by_id (PVM_VAL_INT (JITTER_UNDER_TOP_STACK ()));      \
+       io = ios_search_by_id (iom, 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_meta iom = PVM_STATE_BACKING_FIELD (imeta);                         \
                                                                              \
      JITTER_DROP_STACK ();                                                   \
      JITTER_DROP_STACK ();                                                   \
                                                                              \
      if (JITTER_TOP_STACK () == PVM_NULL)                                    \
-       io = ios_cur ();                                                      \
+       io = ios_cur (iom);                                                   \
      else                                                                    \
-       io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));            \
+       io = ios_search_by_id (iom, 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_meta imeta;
   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->imeta = 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_meta iom = PVM_STATE_BACKING_FIELD (imeta);
 
-     int ret = ios_open (filename, flags, 0);
+     int ret = ios_open (iom, 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_meta iom = PVM_STATE_BACKING_FIELD (imeta);
+    ios io = ios_search_by_id (iom, io_id);
 
     if (io == NULL)
       PVM_RAISE_DFL (PVM_E_NO_IOS);
 
-    if (ios_close (io) != IOS_OK)
+    if (ios_close (iom, 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_meta iom = PVM_STATE_BACKING_FIELD (imeta);
+    ios io = ios_search_by_id (iom, 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_meta iom = PVM_STATE_BACKING_FIELD (imeta);
+    ios cur_io = ios_cur (iom);
 
     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_meta iom = PVM_STATE_BACKING_FIELD (imeta);
+    ios io = ios_search_by_id (iom, PVM_VAL_INT (JITTER_TOP_STACK ()));
 
     if (io == NULL)
       PVM_RAISE_DFL (PVM_E_NO_IOS);
-    ios_set_cur (io);
+    ios_set_cur (iom, 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_meta iom = PVM_STATE_BACKING_FIELD (imeta);
+    ios io = ios_search_by_id (iom, 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_meta iom = PVM_STATE_BACKING_FIELD (imeta);
+    ios io = ios_search_by_id (iom, 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_meta iom = PVM_STATE_BACKING_FIELD (imeta);
+    ios io = ios_search_by_id (iom, 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_meta iom = PVM_STATE_BACKING_FIELD (imeta);
+    ios io = ios_search_by_id (iom, PVM_VAL_INT (JITTER_TOP_STACK ()));
 
     JITTER_DROP_STACK ();
 
@@ -5948,9 +5962,10 @@ instruction peeks ()
     ios_off offset;
     char *ios_str;
     int ret;
+    ios_meta iom = PVM_STATE_BACKING_FIELD (imeta);
 
     offset = PVM_VAL_ULONG (JITTER_TOP_STACK ());
-    io = ios_search_by_id (PVM_VAL_INT (JITTER_UNDER_TOP_STACK ()));
+    io = ios_search_by_id (iom, 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_meta iom = PVM_STATE_BACKING_FIELD (imeta);
 
     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 (iom, PVM_VAL_INT (JITTER_TOP_STACK ()));
 
     if (io == NULL)
       PVM_RAISE_DFL (PVM_E_NO_IOS);
-- 
2.34.1




reply via email to

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