on master help sign in
Merge pull request #744 from Melvar/executor-null-string
abe366eEdwin Brady
idris.cabal+15
@@ -177,6 +177,21 @@ Extra-source-files:
177 test/reg024/run
177 test/reg024/run
178 test/reg024/*.idr
178 test/reg024/*.idr
179 test/reg024/expected
179 test/reg024/expected
180+ test/reg025/run
181+ test/reg025/*.idr
182+ test/reg025/expected
183+ test/reg026/run
184+ test/reg026/*.idr
185+ test/reg026/expected
186+ test/reg027/run
187+ test/reg027/*.idr
188+ test/reg027/expected
189+ test/reg028/run
190+ test/reg028/*.idr
191+ test/reg028/expected
192+ test/reg029/run
193+ test/reg029/*.idr
194+ test/reg029/expected
180 test/test001/run
195 test/test001/run
181 test/test001/*.idr
196 test/test001/*.idr
182 test/test001/expected
197 test/test001/expected
src/Core/Execute.hs+10−3
@@ -285,6 +285,12 @@ execApp' env ctxt (EP _ (UN "mkForeignPrim") _) (_:fn:(EPtr p):rest)
285 if p == nullPtr then 1 else 0
285 if p == nullPtr then 1 else 0
286 in execApp' env ctxt res (tail rest)
286 in execApp' env ctxt res (tail rest)
287
287
288+-- A foreign-returned char* has to be tested for NULL sometimes
289+execApp' env ctxt (EP _ (UN "mkForeignPrim") _) (_:fn:EConstant (Str s):rest)
290+ | Just (FFun "isNull" _ _) <- foreignFromTT fn
291+ = let res = ioWrap . EConstant . I $ 0
292+ in execApp' env ctxt res (tail rest)
293+
288-- Throw away the 'World' argument to the foreign function
294-- Throw away the 'World' argument to the foreign function
289
295
290execApp' env ctxt f@(EP _ (UN "mkForeignPrim") _) args@(ty:fn:xs)
296execApp' env ctxt f@(EP _ (UN "mkForeignPrim") _) args@(ty:fn:xs)
@@ -440,9 +446,10 @@ call (FFun name argTypes retType) args =
440 res <- execIO $ callFFI h retCChar (prepArgs args)
446 res <- execIO $ callFFI h retCChar (prepArgs args)
441 return (EConstant (Ch (castCCharToChar res)))
447 return (EConstant (Ch (castCCharToChar res)))
442 call' (Fun _ h) args FString = do res <- execIO $ callFFI h retCString (prepArgs args)
448 call' (Fun _ h) args FString = do res <- execIO $ callFFI h retCString (prepArgs args)
449+ if res == nullPtr
450+ then return (EPtr res)
443− hStr <- execIO $ peekCString res
451+ else do hStr <- execIO $ peekCString res
444−-- lift $ free res
445− return (EConstant (Str hStr))
452+ return (EConstant (Str hStr))
446
453
447 call' (Fun _ h) args FPtr = EPtr <$> (execIO $ callFFI h (retPtr retVoid) (prepArgs args))
454 call' (Fun _ h) args FPtr = EPtr <$> (execIO $ callFFI h (retPtr retVoid) (prepArgs args))
448 call' (Fun _ h) args FUnit = do _ <- execIO $ callFFI h retVoid (prepArgs args)
455 call' (Fun _ h) args FUnit = do _ <- execIO $ callFFI h retVoid (prepArgs args)
test/README+1
@@ -37,4 +37,5 @@ Tests:
37
37
38regxxx: various regression tests
38regxxx: various regression tests
39reg020: working strlen
39reg020: working strlen
40+reg029: executor doesn’t crash receiving a NULL String from C
40
41
test/reg029/expectednew file+4
@@ -0,0 +1,4 @@
1+Nothing
2+Just "exists!"
3+Nothing
4+Just "exists!"
test/reg029/reg029.idrnew file+10
@@ -0,0 +1,10 @@
1+module Main
2+
3+import System
4+
5+%dynamic "libm"
6+
7+main : IO ()
8+main = do
9+ print !(getEnv "IDRIS_REG029_NONEXISTENT_VAR")
10+ print !(getEnv "IDRIS_REG029_EXISTENT_VAR")
test/reg029/runnew file+5
@@ -0,0 +1,5 @@
1+#!/usr/bin/env bash
2+idris $@ reg029.idr -o reg029
3+env -u IDRIS_REG029_NONEXISTENT_VAR IDRIS_REG029_EXISTENT_VAR='exists!' ./reg029
4+env -u IDRIS_REG029_NONEXISTENT_VAR IDRIS_REG029_EXISTENT_VAR='exists!' idris $@ reg029.idr --exec
5+rm -f reg029 *.ibc