Changeset 15013
- Timestamp:
- 05/23/17 11:00:13 (6 years ago)
- Location:
- trunk/abcl
- Files:
-
- 7 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/abcl/abcl.asd
r15009 r15013 74 74 :pathname "t/" 75 75 :components ((:test-file "resolve-multiple-maven-dependencies") 76 (:test-file "disassemble") 76 77 (:test-file "pathname"))))) 77 78 -
trunk/abcl/contrib/abcl-introspect/abcl-introspect.asd
r15008 r15013 1 1 ;;;; -*- Mode: LISP -*- 2 2 (defsystem abcl-introspect 3 :author "Alan Ruttenberg"3 :author ("Alan Ruttenberg" "Mark Evenson") 4 4 :description "Introspection on compiled function to aid source location and other debugging functions." 5 5 :long-description "<urn:abcl.org/release/1.5.0/contrib/abcl-introspect#>" 6 :version " 1.0.1"6 :version "2.0.0" 7 7 :depends-on (jss) 8 8 :components ((:file "abcl-introspect") 9 (:file "stacktrace"))) 9 (:file "stacktrace")) 10 :in-order-to ((test-op (test-op abcl-introspect-tests)))) 11 -
trunk/abcl/src/org/armedbear/lisp/Symbol.java
r14916 r15013 3085 3085 public static final Symbol DIRECT_SUPERCLASSES = 3086 3086 PACKAGE_SYS.addExternalSymbol("DIRECT-SUPERCLASSES"); 3087 public static final Symbol __DISASSEMBLERS__ = 3088 PACKAGE_SYS.addExternalSymbol("*DISASSEMBLERS*"); 3089 public static final Symbol CHOOSE_DISASSEMBLER = 3090 PACKAGE_SYS.addExternalSymbol("CHOOSE-DISASSEMBLER"); 3087 3091 public static final Symbol _DOCUMENTATION = 3088 3092 PACKAGE_SYS.addExternalSymbol("%DOCUMENTATION"); -
trunk/abcl/src/org/armedbear/lisp/disassemble.lisp
r14960 r15013 30 30 ;;; exception statement from your version. 31 31 32 (in-package #:system) 33 34 (require '#:clos) 35 36 (defvar *disassembler-function* NIL) 37 38 ;; default is :external, jad, which is what the abcl java code calls 32 (in-package :system) 33 (require :clos) 34 35 (defvar *disassembler-function* nil 36 "The currently used function for CL:DISASSEMBLE. 37 38 Available disassemblers are configured by pushing a strategy to SYSTEM:*DISASSEMBLERS*. 39 40 SYSTEM:CHOOSE-DISASSEMBLER selects a current strategy from this list .") 39 41 40 42 (defvar *disassemblers* 41 `((:objectweb . objectweb-disassemble) 42 (:external . disassemble-class-bytes))) 43 `((:jad . disassemble-class-bytes)) 44 "Methods of invoking CL:DISASSEMBLE consisting of a pushable list of (name function), where function takes a object to disassemble, returns the results as a string. 45 46 The system is :jad using the venerable-but-still-works JAD. 47 ") 43 48 44 49 (defun choose-disassembler (&optional name) 45 (setf *disassembler-function* 46 (if name 47 (or (funcall (cdr (assoc name *disassemblers*))) 48 (error "Can't find suitable disassembler.")) 49 (loop 50 for (NIL . test) in *disassemblers* 51 for result = (funcall test) 52 when result 53 do (return result) 54 finally (warn "Can't find suitable disassembler."))))) 50 "Hook to choose invoked behavior of CL:DISASSEMBLE by using one of the methods registered in SYSTEM:*DISASSEMBLERS*. 51 52 Optionally, prefer the strategy named NAME if one exists." 53 (setf *disassembler-function* 54 (if name 55 (let ((disassembler (cdr (assoc name *disassemblers*)))) 56 (if (and disassembler 57 (fboundp disassembler)) 58 disassembler 59 (error "Disassembler ~a doesn't appear to work." name))) 60 (loop 61 :for (nil . disassembler) in *disassemblers* 62 :when (and disassembler 63 (fboundp disassembler)) 64 :do (return disassembler) 65 finally (warn "Can't find suitable disassembler."))))) 55 66 56 67 (eval-when (:compile-toplevel :load-toplevel :execute) … … 81 92 (read-byte-array-from-stream stream))) 82 93 83 ;; alanr: disassemble more things 94 (defun disassemble-bytes (bytes) 95 "Disassemble jvm code BYTES returning a string." 96 (funcall (or *disassembler-function* (choose-disassembler)) 97 bytes)) 98 84 99 (defun disassemble-function (arg) 85 (flet ((disassemble-bytes (bytes) (funcall (or *disassembler-function* 'disassemble-class-bytes) bytes))) 86 (let ((function (cond ((java::java-object-p arg) 87 (cond ((java::jinstance-of-p arg "java.lang.Class") 88 arg) 89 ((java::jinstance-of-p arg "java.lang.reflect.Method") 90 (java::jmethod-declaring-class arg)) 91 )) 92 ((functionp arg) 93 arg) 94 ((symbolp arg) 95 (or (macro-function arg) (symbol-function arg))) 96 (t arg)))) 97 98 (when (typep function 'generic-function) 99 (setf function (mop::funcallable-instance-function function))) 100 ;; use isInstance instead of jinstance-of-p 101 ;; because the latter checked java-object-p 102 ;; which fails since its a lisp object 103 (when (and (java:jcall "isInstance" (java:jclass "org.armedbear.lisp.Closure") function) 104 (not (java:jcall "isInstance" (java:jclass "org.armedbear.lisp.CompiledClosure") function))) 105 (return-from disassemble-function 106 (with-output-to-string (s) 107 (format s "Not a compiled function: ~%") 108 (pprint (java:jcall "getBody" function) s)))) 109 (let ((bytes (or (and (java:jcall "isInstance" (java:jclass "org.armedbear.lisp.Function") function) 110 (ignore-errors (getf (function-plist function))) 'class-bytes) 111 (and (java:jcall "isInstance" (java:jclass "org.armedbear.lisp.CompiledClosure") function) 112 (equalp (java::jcall "getName" (java::jobject-class 113 (java:jcall "getClassLoader" (java::jcall "getClass" function)))) 114 "org.armedbear.lisp.FaslClassLoader") 115 (fasl-compiled-closure-class-bytes function))))) 116 ;; we've got bytes here then we've covered the case that the disassembler already handled 117 ;; If not then we've either got a primitive (in function) or we got passed a method object as arg. 118 (if bytes 119 (disassemble-bytes bytes) 120 (let ((class (if (java:java-object-p function) function (java:jcall "getClass" function)))) 121 (let ((classloader (java:jcall "getClassLoader" class))) 122 (if (or (java:jinstance-of-p classloader "org.armedbear.lisp.MemoryClassLoader") 123 (java:jinstance-of-p classloader "org.armedbear.lisp.FaslClassLoader")) 124 (disassemble-bytes 125 (java:jcall "getFunctionClassBytes" classloader class)) 126 (disassemble-bytes 127 (read-byte-array-from-stream 128 (java:jcall-raw 129 "getResourceAsStream" 130 (java:jcall-raw "getClassLoader" class) 131 (class-resource-path class)))))))))))) 100 (let ((function (cond ((java::java-object-p arg) 101 (cond ((java::jinstance-of-p arg "java.lang.Class") 102 arg) 103 ((java::jinstance-of-p arg "java.lang.reflect.Method") 104 (java::jmethod-declaring-class arg)) 105 )) 106 ((functionp arg) 107 arg) 108 ((symbolp arg) 109 (or (macro-function arg) (symbol-function arg))) 110 (t arg)))) 111 (when (typep function 'generic-function) 112 (setf function (mop::funcallable-instance-function function))) 113 ;; use isInstance instead of jinstance-of-p 114 ;; because the latter checked java-object-p 115 ;; which fails since its a lisp object 116 (when (and (java:jcall "isInstance" (java:jclass "org.armedbear.lisp.Closure") function) 117 (not (java:jcall "isInstance" (java:jclass "org.armedbear.lisp.CompiledClosure") function))) 118 (return-from disassemble-function 119 (with-output-to-string (s) 120 (format s "Not a compiled function: ~%") 121 (pprint (java:jcall "getBody" function) s)))) 122 (let ((bytes (or (and (java:jcall "isInstance" (java:jclass "org.armedbear.lisp.Function") function) 123 (ignore-errors (getf (function-plist function))) 'class-bytes) 124 (and (java:jcall "isInstance" (java:jclass "org.armedbear.lisp.CompiledClosure") function) 125 (equalp (java::jcall "getName" (java::jobject-class 126 (java:jcall "getClassLoader" (java::jcall "getClass" function)))) 127 "org.armedbear.lisp.FaslClassLoader") 128 (fasl-compiled-closure-class-bytes function))))) 129 ;; we've got bytes here then we've covered the case that the disassembler already handled 130 ;; If not then we've either got a primitive (in function) or we got passed a method object as arg. 131 (if bytes 132 (disassemble-bytes bytes) 133 (let ((class (if (java:java-object-p function) function (java:jcall "getClass" function)))) 134 (let ((classloader (java:jcall "getClassLoader" class))) 135 (if (or (java:jinstance-of-p classloader "org.armedbear.lisp.MemoryClassLoader") 136 (java:jinstance-of-p classloader "org.armedbear.lisp.FaslClassLoader")) 137 (disassemble-bytes 138 (java:jcall "getFunctionClassBytes" classloader class)) 139 (disassemble-bytes 140 (read-byte-array-from-stream 141 (java:jcall-raw 142 "getResourceAsStream" 143 (java:jcall-raw "getClassLoader" class) 144 (class-resource-path class))))))))))) 132 145 133 146 (defparameter +propertyList+ … … 144 157 145 158 ;; PITA. make loadedFrom public 159 ;;; TODO Java9 work out a sensible story to preserve existing values if required 146 160 (defun get-loaded-from (function) 147 161 (let* ((jfield (find "loadedFrom" (java:jcall "getDeclaredFields" (java:jclass "org.armedbear.lisp.Function")) … … 172 186 173 187 ;; closure bindings 174 ;; (get-java-field (elt (#"get" (elt (#"getFields" (#"getClass" #'foo)) 0) #'foo) 0) "value") 188 ;; (get-java-field (elt (#"get" (elt (#"getFields" (#"getClass" #'foo)) 0) #'foo) 0) "value") 175 189 176 190 (defun disassemble (arg) … … 186 200 (terpri))))) 187 201 188 (defun objectweb-disassemble (object)189 (let* ((reader (java:jnew "org.objectweb.asm.ClassReader" object))190 (writer (java:jnew "java.io.StringWriter"))191 (printer (java:jnew "java.io.PrintWriter" writer))192 (tracer (java:jnew "org.objectweb.asm.util.TraceClassVisitor" java:+null+ printer))193 ;; this is to support both the 1.X and subsequent releases194 (flags (ignore-errors (java:jfield "org.objectweb.asm.ClassReader" "SKIP_DEBUG"))))195 (java:jcall-raw "accept" reader tracer (or flags java:+false+))196 (java:jcall "toString" writer)))197
Note: See TracChangeset
for help on using the changeset viewer.