ghcjs / ghcjs-base

base library for GHCJS for JavaScript interaction and marshalling, used by higher level libraries like JSC
MIT License
45 stars 67 forks source link

export roundtrip throws internal exception #42

Closed wereHamster closed 7 years ago

wereHamster commented 9 years ago

I was expecting this to print Just 424242424242. Instead it throws a RTS exception.

import GHCJS.Foreign.Export
main = do
    withExport (424242424242 :: Int) $ \r -> do
        v <- derefExport r
        print (v :: Maybe Int)
uncaught exception in Haskell main thread: TypeError: Cannot read property 't' of undefined
rts.js:10133 TypeError: Cannot read property 't' of undefined
    at h$ap_1_0_fast (rts.js:18020)
    at h$$nm (out.js:14090)
    at h$mainLoop (rts.js:11317)
    at rts.js:3765
    at runIfPresent (rts.js:3784)
    at onGlobalMessage (rts.js:3832)

The problem appears to be that the heap object root is the integer, while h$ap_1_0_fast expects it to be an object with a f property.

luite commented 9 years ago

hmm, that's not ok. it looks like the Int is treated as an IO Int

luite commented 9 years ago

Think I've found the problem

luite commented 9 years ago

https://github.com/ghcjs/ghcjs-base/blob/master/GHCJS/Foreign/Export.hs#L69

This line is wrong (or the foreign import is)

luite commented 9 years ago

should be fixed with 05d8df85e7202320c5bcecb53596aa1a99266472

wereHamster commented 9 years ago

Is there a way to use ghcjs-base directly from the git repo? Or do I have to wait until you make another release?

luite commented 9 years ago

You can just cabal install ghcjs-base as any normal package. If you want to make sure that the updated version is used, just bump the version number and add a constraint to your project.

wereHamster commented 9 years ago

Doesn't seem to be fixed yet. Still getting the exception when the RTS tries to access f property on a number (the 424242424242).

luite commented 9 years ago

Ok, I'll look into this again. Admittedly I hadn't tested it.

luite commented 9 years ago

Ack, missing Just, I'm too used to the type system catching things like this for me. I shouldn't take risks around unsafeCoerce :)

luite commented 9 years ago

fixed it here and have a test case, will push later tonight when i have some other things cleaned up.

iand675 commented 9 years ago

I'm not sure if this is the same issue or not, but it seems related:

I've got a function:

patch :: Typeable a => Node -> a -> (a -> IO ()) -> IO ()
patch n x f = do
  xRef <- export x
  cb <- syncCallback1 ThrowWouldBlock $ \ref -> do
    (Just xVal) <- derefExport ref
    f xVal
  js_patch n cb xRef 
  releaseCallback cb
  releaseExport xRef

When I call it with pretty much any value I've tried so far as the value of a, I get the exception h$ap_1_0_fast: unexpected closure type: 2

luite commented 9 years ago

I haven't been able reproduce this with the latest version of shims and ghcjs-base. can you make a runnable example that does this?

iand675 commented 9 years ago

It appears to be fixed now that I'm running on master for both, but it seems like there's no longer a way to convert from JSVal -> Export a without an unsafeCoerce AFAICT. Am I missing something?

hamishmack commented 7 years ago

it seems like there's no longer a way to convert from JSVal -> Export a without an unsafeCoerce AFAICT. Am I missing something?

I think that is intentional. In normal usage you would Export a as the return value of a jsffi (so no coercing is needed):

foreign import javascript "getTheStoredExport()" getTheStoredExport :: IO (Export a)