pointerless backing buffers for string ports
[bpt/guile.git] / libguile / objcodes.c
index 1c3c525..f4e20f8 100644 (file)
@@ -45,11 +45,11 @@ verify (((sizeof (SCM_OBJCODE_COOKIE) - 1) & 7) == 0);
  */
 
 /* The words in an objcode SCM object are as follows:
-     - scm_tc7_objcode | the flags for this objcode
+     - scm_tc7_objcode | type | flags
      - the struct scm_objcode C object
-     - the parent of this objcode, if this is a slice, or #f if none
-     - the file descriptor this objcode came from if this was mmaped,
-       or 0 if none
+     - the parent of this objcode: either another objcode, a bytevector,
+       or, in the case of mmap types, file descriptors (as an inum)
+     - "native code" -- not currently used.
  */
 
 static SCM
@@ -77,7 +77,13 @@ make_objcode_by_mmap (int fd)
       SCM_SYSERROR;
     }
 
-  if (memcmp (addr, SCM_OBJCODE_COOKIE, strlen (SCM_OBJCODE_COOKIE)))
+  /* The cookie ends with a version of the form M.N, where M is the
+     major version and N is the minor version.  For this Guile to be
+     able to load an objcode, M must be SCM_OBJCODE_MAJOR_VERSION, and N
+     must be less than or equal to SCM_OBJCODE_MINOR_VERSION.  Since N
+     is the last character, we do a strict comparison on all but the
+     last, then a <= on the last one.  */
+  if (memcmp (addr, SCM_OBJCODE_COOKIE, strlen (SCM_OBJCODE_COOKIE) - 1))
     {
       SCM args = scm_list_1 (scm_from_latin1_stringn
                              (addr, strlen (SCM_OBJCODE_COOKIE)));
@@ -86,6 +92,16 @@ make_objcode_by_mmap (int fd)
       scm_misc_error (FUNC_NAME, "bad header on object file: ~s", args);
     }
 
+  {
+    char minor_version = addr[strlen (SCM_OBJCODE_COOKIE) - 1];
+
+    if (minor_version > SCM_OBJCODE_MINOR_VERSION_STRING[0])
+      scm_misc_error (FUNC_NAME, "objcode minor version too new (~a > ~a)",
+                      scm_list_2 (scm_from_latin1_stringn (&minor_version, 1),
+                                  scm_from_latin1_string
+                                  (SCM_OBJCODE_MINOR_VERSION_STRING)));
+  }
+
   data = (struct scm_objcode*)(addr + strlen (SCM_OBJCODE_COOKIE));
 
   if (data->len + data->metalen != (st.st_size - sizeof (*data) - strlen (SCM_OBJCODE_COOKIE)))
@@ -100,8 +116,7 @@ make_objcode_by_mmap (int fd)
 
   sret = scm_double_cell (SCM_MAKE_OBJCODE_TAG (SCM_OBJCODE_TYPE_MMAP, 0),
                           (scm_t_bits)(addr + strlen (SCM_OBJCODE_COOKIE)),
-                          SCM_UNPACK (SCM_BOOL_F),
-                          (scm_t_bits)fd);
+                          SCM_UNPACK (scm_from_int (fd)), 0);
 
   /* FIXME: we leak ourselves and the file descriptor. but then again so does
      dlopen(). */