编译器的信号和错误之间的差异(sbcl 1.2.4)



我从SBCL编译器中得到了一个奇怪的错误,所以可能有人可以向我解释那里发生了什么。有关信息,该包使用optima和drakma。我真的试着缩小发布的代码,但这个数量需要理解问题。

(defun signal-vk-error (code)
  (error ;; <--- HERE IS THING
    (case code
      (100 'parse-error)
      (otherwise 'error))))
(defmacro match-with-error (response matcher)
  `(match ,response
         ((alist (:ERROR . code))
          (signal-vk-error code))
         ,matcher))
(defun api-call-response (resp)
  (match-with-error
    resp
    ((alist (:RESPONSE . data)) data)))

编译我得到的这个文件:

; caught ERROR:
;   don't know how to dump CODE (default MAKE-LOAD-FORM method called).
Unhandled TYPE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
                                  {1002BF6F03}>:
  The value NIL is not of type (AND ATOM (NOT NULL)).

所以看起来sbcl(1.2.4)无法创建二进制表示,但我无法理解为什么。

如果我只是在信号vk-ERROR中将ERROR更改为SIGNAL,那么everything将按预期编译、加载和工作。我也可以在slime和eval中加载文件,它将在没有错误和警告的情况下工作。

那么,问题是,error出了什么问题?errorsignal的主要区别是什么?

UPDATE 1:有趣的观察结果是,如果我删除信号vk错误函数,并将此代码放入宏防御中,它将编译正常。

UPDATE 2:感谢@RainerJoswig,声明signal-vk-error不内联解决了问题。向SBCL团队报告,看起来他们正在进行一些优化,在这种情况下会中断编译。

再现问题的最小方法:

(defun signal-vk-error ()
  (error 'error))
(defun api-call-response ()
  (optima:match 1
    ((not 2)
     (signal-vk-error))))

如果我宏展开或遍历match表单,问题就会消失。

以下内容也使问题消失。

(declaim (notinline error))

事实上,编译器中存在一个问题,实际上有两个问题,其中一个据称是一个特性。任何感兴趣的人都可以阅读SBCL黑客之一与bugtracker中optima的作者之间的对话。

目前,在optima方面,通过在宏扩展期间不显示模式对象,解决了这一问题,提交d7ec93d0df4920b9a7b4a492e7aadf52480f437c

最新更新