jscl
jscl copied to clipboard
How to define an `instanceof` operation in the FFI
While working on some FFI features prototypes I have tried to expose the instanceof
operation but my understanding of the compiler internals is too limited for this.
I am trying to implement jscl:js-instance-of
so that
(jscl:js-instanceof "String instance" #j:String)
=> T
My attempts were
;; Not good enough!
(define-builtin js-instanceof (x constructor)
(convert-to-bool `(instanceof ,x ,constructor)))
;; Not good enough eithehr!
(define-compilation js-instanceof (x constructor)
`(call-internal |js_to_lisp| (instanceof ,x ,constructor)))
Any idea, how I could implement this?
(jscl:js-instanceof "String instance" #j:String) => T
that is probably never going to be true because strings in JSCL are implemented as arrays. The reason is that strings in Common Lisp are mutable, but immutable in JS.
Oh I see, but then what about
(jscl:js-instanceof "String instance" #j:Object)
=> T
If I got my test rights, my definitions do not pass this either.
Ok, I found the problem! Additionally I'll share a cool trick to debug this kind of problems.
In the JSCL repl, evaluate #:Object
. Then in the JS console, do jscl.CL['*'].value
. That will show you the raw JS value of the last expression. You'll see that JSCL wrapped Object to be a CL function so it is not the constructor..
Using more the internals, you can get the raw value like this:
(js-instanceof "String instance" (%js-vref "Object" t))
That works for for first attempt! Note that 't' argument to %js-vref
means raw. You can find the definition in compiler/compiler.lisp
Note how that relates to the problem 3 from the FFI design discussions you just added:
https://github.com/jscl-project/jscl/wiki/FFI-Design-Discussions#problem-3-conversion-between-lisp-and-js-values
We definitely need that. Or even better, if we could think of a representation of functions in CL so no conversion is needed.
I prototyped a higher-level specification for foreign class interface, see the wiki and the linked gist!
BTW, is there a list of non-implemented features? (Aside from the README.)
BTW, is there a list of non-implemented features? (Aside from the README.)
Not really, we used to have a file with all symbols from CLHS and their implementation status, but not anymore.