mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-05-11 18:10:57 -07:00
clos: ensure that funcallables are treated as functions
The fact taht gfdef is null does not mean that the funcallable is not a function. We distinguish funcallables from non-funcallables by checking the header flag x->instance.isgf -- when it is 0, then the instance is not funcallable. In this commit we are still lenient towards the behavior, that any instance may become a funcallable by a mere action of assigning the function -- initially we set assign the function (for funcallables) to nil, ensuring that .isgf is not ECL_NOT_FUNCALLABLE (but rather ECL_NULL_DISPATCH - a new state flag). This assignment is at this moment performed in the only method ALLOCATE-INSTANCE specialized to classes (and we verify the actual class using subtypep). A more strict implementation would: - assign isgf when the instance is allocated - refus to assign new function to instances that are not funcallables This commit is enough to fix the test MOP.0030, BUT NOT MOP.0031.
This commit is contained in:
parent
70a82ce17b
commit
e02fb7ea04
4 changed files with 6 additions and 3 deletions
|
|
@ -67,7 +67,7 @@ clos_set_funcallable_instance_function(cl_object x, cl_object function_or_t)
|
|||
x->instance.isgf = ECL_RESTRICTED_DISPATCH;
|
||||
x->instance.entry = generic_function_dispatch_vararg;
|
||||
} else if (function_or_t == ECL_NIL) {
|
||||
x->instance.isgf = ECL_NOT_FUNCALLABLE;
|
||||
x->instance.isgf = ECL_NULL_DISPATCH;
|
||||
x->instance.entry = FEnot_funcallable_vararg;
|
||||
} else if (function_or_t == @'clos::standard-optimized-reader-method') {
|
||||
x->instance.isgf = ECL_READER_DISPATCH;
|
||||
|
|
|
|||
|
|
@ -99,6 +99,9 @@
|
|||
(assert (class-finalized-p class))
|
||||
(let ((x (si::allocate-raw-instance nil class (class-size class))))
|
||||
(si::instance-sig-set x)
|
||||
(when (subtypep class 'funcallable-standard-class)
|
||||
;; INV this will initialize (x)->instance.isgf.
|
||||
(set-funcallable-instance-function x nil))
|
||||
x))
|
||||
|
||||
(defmethod make-instance ((class class) &rest initargs)
|
||||
|
|
|
|||
|
|
@ -80,8 +80,7 @@
|
|||
(when (symbolp slots)
|
||||
(setf slots (symbol-value slots)))
|
||||
`(let* ((%class ,class)
|
||||
(,object (si::allocate-raw-instance nil %class
|
||||
,(length slots))))
|
||||
(,object (si:allocate-raw-instance nil %class ,(length slots))))
|
||||
(declare (type standard-object ,object))
|
||||
,@(flet ((initializerp (name list)
|
||||
(not (eq (getf list name 'wrong) 'wrong))))
|
||||
|
|
|
|||
|
|
@ -1093,6 +1093,7 @@ struct ecl_condition_variable {
|
|||
#define ECL_READER_DISPATCH 3
|
||||
#define ECL_WRITER_DISPATCH 4
|
||||
#define ECL_USER_DISPATCH 5
|
||||
#define ECL_NULL_DISPATCH 6 /* funcallable, but gfdef is null */
|
||||
|
||||
struct ecl_instance { /* -- instance header -- */
|
||||
_ECL_HDR1(isgf); /* gf type */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue