GNU bug report logs - #9313
24.0.50; Emacs 24 cannot load byte-compiled code from Emacs 23.3 when using EIEIO's defmethod

Previous Next

Package: emacs;

Reported by: David Engster <deng <at> randomsample.de>

Date: Wed, 17 Aug 2011 15:55:01 UTC

Severity: normal

Found in version 24.0.50

Done: Stefan Monnier <monnier <at> iro.umontreal.ca>

Bug is archived. No further changes may be made.

Full log


Message #8 received at 9313 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: David Engster <deng <at> randomsample.de>
Cc: 9313 <at> debbugs.gnu.org
Subject: Re: bug#9313: 24.0.50;
	Emacs 24 cannot load byte-compiled code from Emacs 23.3 when using
	EIEIO's defmethod
Date: Mon, 22 Aug 2011 17:47:17 -0400
> This is a very late followup to an older message from emacs-devel,
> regarding the issue that Emacs24 after the lexbind merge cannot run
> byte-compiled code from Emacs23.3 if that is using EIEIO's 'defmethod':

Does the patch below fix the problem for you?


        Stefan


=== modified file 'lisp/emacs-lisp/eieio.el'
--- lisp/emacs-lisp/eieio.el	2011-05-23 00:39:25 +0000
+++ lisp/emacs-lisp/eieio.el	2011-08-22 21:46:05 +0000
@@ -2864,6 +2864,106 @@
 )
 
 
+;;; Obsolete backward compatibility functions.
+;; Used to run byte-code compiled with Emacs-23.
+
+(defun eieio-defmethod (method args)
+  "Work part of the `defmethod' macro defining METHOD with ARGS."
+  (let ((key nil) (body nil) (firstarg nil) (argfix nil) (argclass nil) loopa)
+    ;; find optional keys
+    (setq key
+	  (cond ((or (eq ':BEFORE (car args))
+		     (eq ':before (car args)))
+		 (setq args (cdr args))
+		 method-before)
+		((or (eq ':AFTER (car args))
+		     (eq ':after (car args)))
+		 (setq args (cdr args))
+		 method-after)
+		((or (eq ':PRIMARY (car args))
+		     (eq ':primary (car args)))
+		 (setq args (cdr args))
+		 method-primary)
+		((or (eq ':STATIC (car args))
+		     (eq ':static (car args)))
+		 (setq args (cdr args))
+		 method-static)
+		;; Primary key
+		(t method-primary)))
+    ;; get body, and fix contents of args to be the arguments of the fn.
+    (setq body (cdr args)
+	  args (car args))
+    (setq loopa args)
+    ;; Create a fixed version of the arguments
+    (while loopa
+      (setq argfix (cons (if (listp (car loopa)) (car (car loopa)) (car loopa))
+			 argfix))
+      (setq loopa (cdr loopa)))
+    ;; make sure there is a generic
+    (eieio-defgeneric
+     method
+     (if (stringp (car body))
+	 (car body) (format "Generically created method `%s'." method)))
+    ;; create symbol for property to bind to.  If the first arg is of
+    ;; the form (varname vartype) and `vartype' is a class, then
+    ;; that class will be the type symbol.  If not, then it will fall
+    ;; under the type `primary' which is a non-specific calling of the
+    ;; function.
+    (setq firstarg (car args))
+    (if (listp firstarg)
+	(progn
+	  (setq argclass  (nth 1 firstarg))
+	  (if (not (class-p argclass))
+	      (error "Unknown class type %s in method parameters"
+		     (nth 1 firstarg))))
+      (if (= key -1)
+	  (signal 'wrong-type-argument (list :static 'non-class-arg)))
+      ;; generics are higher
+      (setq key (eieio-specialized-key-to-generic-key key)))
+    ;; Put this lambda into the symbol so we can find it
+    (if (byte-code-function-p (car-safe body))
+	(eieiomt-add method (car-safe body) key argclass)
+      (eieiomt-add method (append (list 'lambda (reverse argfix)) body)
+		   key argclass))
+    )
+
+  (when eieio-optimize-primary-methods-flag
+    ;; Optimizing step:
+    ;;
+    ;; If this method, after this setup, only has primary methods, then
+    ;; we can setup the generic that way.
+    (if (generic-primary-only-p method)
+	;; If there is only one primary method, then we can go one more
+	;; optimization step.
+	(if (generic-primary-only-one-p method)
+	    (eieio-defgeneric-reset-generic-form-primary-only-one method)
+	  (eieio-defgeneric-reset-generic-form-primary-only method))
+      (eieio-defgeneric-reset-generic-form method)))
+
+  method)
+(make-obsolete 'eieio-defmethod 'eieio--defmethod "24.1")
+
+(defun eieio-defgeneric (method doc-string)
+  "Engine part to `defgeneric' macro defining METHOD with DOC-STRING."
+  (if (and (fboundp method) (not (generic-p method))
+	   (or (byte-code-function-p (symbol-function method))
+	       (not (eq 'autoload (car (symbol-function method)))))
+	   )
+      (error "You cannot create a generic/method over an existing symbol: %s"
+	     method))
+  ;; Don't do this over and over.
+  (unless (fboundp 'method)
+    ;; This defun tells emacs where the first definition of this
+    ;; method is defined.
+    `(defun ,method nil)
+    ;; Make sure the method tables are installed.
+    (eieiomt-install method)
+    ;; Apply the actual body of this function.
+    (fset method (eieio-defgeneric-form method doc-string))
+    ;; Return the method
+    'method))
+(make-obsolete 'eieio-defgeneric nil "24.1")
+
 ;;; Interfacing with edebug
 ;;
 (defun eieio-edebug-prin1-to-string (object &optional noescape)





This bug report was last modified 13 years and 331 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.