rpav / ScriptL

Shell scripting made Lisp-like! Or, live-coding remote function calls for the shell.
73 stars 11 forks source link

Error under LispWorks 7.1.2 when running cli command #10

Open svetlyak40wt opened 3 years ago

svetlyak40wt commented 3 years ago

When running server under LispWorks 7.1.2 I get this error during command execution (I'm trying example from the README):

#(48 48 48 48 48 48 48 54) cannot be converted to foreign type "Statically allocated (LISP-ARRAY NIL)".
Call to ERROR
Call to FLI::FOREIGN-TYPE-ERROR-FUNCTION
Call to FLI::CHECKED-LISP-ARRAY
Call to FLI::SET-DYNAMIC-LISP-ARRAY-POINTER
Call to IOLIB/STREAMS::IOBUF-COPY-FROM-LISP-ARRAY
Call to IOLIB/STREAMS::IOBUF-APPEND-SLICE
Call to IOLIB/STREAMS::%WRITE-SIMPLE-ARRAY-UB8
Call to WRITE-SEQUENCE
Call to SCRIPTL::SEND-PACKET
Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION 2 (HARLEQUIN-COMMON-LISP:SUBFUNCTION 2 SCRIPTL::CLIENT-LOOP))
Call to SIGNAL
Call to ERROR
Interpreted call to COMMON-LISP-USER::MY-COMMAND
Call to (METHOD SCRIPTL::HANDLE-CLIENT-FOR ((EQL 2) T))
Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION 2 SCRIPTL::CLIENT-LOOP)
Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION (LABELS BORDEAUX-THREADS::%BINDING-DEFAULT-SPECIALS-WRAPPER) BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS)
Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION (LABELS BORDEAUX-THREADS::%JOIN-THREAD-WRAPPER) BORDEAUX-THREADS::%MAKE-THREAD)
Call to MP::PROCESS-SG-FUNCTION
svetlyak40wt commented 3 years ago

To reproduce this error we can use this minimal example:

(defun test-vector ()
  (let ((vector (scriptl::to-octets (format nil "~8,'0X" 10))))
    (fli:with-dynamic-lisp-array-pointer (ptr-var vector)
      ptr-var)))
svetlyak40wt commented 3 years ago

As a quickfix, I've wrapped the TO-OCTETS body with system:in-static-area macro (which is deprecated in LW, but still works):

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defun to-octets (value)
    (system:in-static-area
      (etypecase value
        (string (string-to-utf-8-bytes value))
        ((unsigned-byte 8) (make-array 1 :element-type '(unsigned-byte 8)
                                       :initial-element value))
        (octet-vector value)
        (t (string-to-utf-8-bytes (princ-to-string value)))))))
svetlyak40wt commented 3 years ago

If you wish, I'll make a patch which will run to-octets under the in-static-area macro?

Or may be it is better to convert it's result into a static vectro separately because in-static-area is deprecated?

rpav commented 3 years ago

Submitting a PR for LispWorks with whatever the best strategy is will be the most expedient thing... I'm not really set up for CL development at the moment and was never too familiar with the LW implementation.

At a glance I'm not sure why static vectors are being used at all here; I don't see them explicitly mentioned in either ScriptL or trivial-utf8, and it would seem excessive to require such. But it's early and I've only had a few sips of coffee. Perhaps this isn't the static-vectors sense.

svetlyak40wt commented 3 years ago

At a glance I'm not sure why static vectors are being used at all here; I don't see them explicitly mentioned in either ScriptL or trivial-utf8, and it would seem excessive to require such. But it's early and I've only had a few sips of coffee. Perhaps this isn't the static-vectors sense.

Under the hood, when you are using write-sequence on the socket, returned by iolib's accept, it uses cffi macro with-pointer-to-vector-data before call to memcpy:

(with-pointer-to-vector-data (src-ptr src)
      (isys:memcpy
       (inc-pointer dst-ptr doff)
       (inc-pointer src-ptr soff)
       length))

And here is this macro definition for LispWorks:

(defmacro with-pointer-to-vector-data ((ptr-var vector) &body body)
  "Bind PTR-VAR to a pointer at the data in VECTOR."
  `(fli:with-dynamic-lisp-array-pointer (,ptr-var ,vector)
     ,@body))

But documentation on with-dynamic-lisp-array-pointer says the vector have to be static.

That is why when you are using write-sequence to write to iolib's socket, under the LispWorks you need to provide a statically allocated vector.

I'll create a pull request soon.

svetlyak40wt commented 3 years ago

Created a pull: https://github.com/rpav/ScriptL/pull/11 it works for me.