From: Mark Wooding Date: Wed, 21 Oct 2015 23:46:28 +0000 (+0100) Subject: src/builtin.lisp, src/codegen-proto.lisp: Improve slot initialization. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/sod/commitdiff_plain/1d8206e9888ca942c039986ffb9c185c80b1e74c?ds=inline src/builtin.lisp, src/codegen-proto.lisp: Improve slot initialization. The fundamental difficulty is that actually we're not initializing an instance's slots: we're assigning values to them. Previously, we tried to distinguish scalar from aggregate initializers. The former got converted into sod__obj->nick.slot = EXPR; while the latter ended up as sod__obj->nick.slot = (TYPE) { COMPOUND-INIT }; There are two problems with this. The first is easy: aggregate literals, such are used in the latter case, are shiny and new in C99. The second is more subtle: we distinguish aggregate from scalar initializers from whether they're wrapped up in braces -- but in fact they needn't be if they've been concealed in a macro, e.g., `PTHREAD_MUTEX_INITIALIZER', or `DSTR_INIT'. Under the previous rules, you'd have to write something like pthread_mutex_t slot = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; as your slot definition in order to get the right effect, and that's just annoying. (It would be a disservice to users to insert the cast unconditionally, of course, since that would eliminate useful type checking.) Change all of this. Instead, actually initialize an object of the right type (we know that type that is, of course), and then assign it to the slot. A decent compiler will turn this into exactly the same object code (yes, I tested this), and it means that our heuristic is no longer needed for anything important. I've preserved the distinction anyway, because we can format compound initializers slightly more prettily, but it no longer makes any semantic difference, and the dependency on C99 has been eliminated. --- diff --git a/src/builtin.lisp b/src/builtin.lisp index 5aad5f5..7bb38e5 100644 --- a/src/builtin.lisp +++ b/src/builtin.lisp @@ -140,19 +140,22 @@ (define-class-slot "init" (class stream) " struct ~A *sod__obj = ~A__imprint(p);~2%" (ilayout-struct-tag class) class) (setf used t)) - (format stream " ~A.~A =" isl - (sod-slot-name dslot)) + (format stream " {~% ~A ~A =" + (sod-slot-type dslot) + *sod-tmp-val*) (ecase (sod-initializer-value-kind init) (:simple (write (sod-initializer-value-form init) :stream stream :pretty nil :escape nil) (format stream ";~%")) - (:compound (format stream " (~A) {" - (sod-slot-type dslot)) + (:compound (format stream " {") (write (sod-initializer-value-form init) :stream stream :pretty nil :escape nil) - (format stream "};~%")))))))))))) + (format stream " };~%"))) + (format stream " ~A.~A = ~A;~% }~%" + isl (sod-slot-name dslot) + *sod-tmp-val*)))))))))) (unless used (format stream " ~A__imprint(p);~%" class)) (format stream "~&~: diff --git a/src/codegen-proto.lisp b/src/codegen-proto.lisp index 42175a5..6dc6dc1 100644 --- a/src/codegen-proto.lisp +++ b/src/codegen-proto.lisp @@ -64,6 +64,8 @@ (defparameter *sod-master-ap* (make-instance 'temporary-name :tag "sod__master_ap")) (defparameter *sod-tmp-ap* (make-instance 'temporary-name :tag "sod__tmp_ap")) +(defparameter *sod-tmp-val* + (make-instance 'temporary-name :tag "sod__t")) ;;;-------------------------------------------------------------------------- ;;; Instructions.