@@ -117,11 +117,7 @@ gccFlags i = if i then ["-fwrapv"]
117117 else ["-fwrapv", "-fno-strict-overflow"]
118118
119119gccDbg DEBUG = ["-g"]
120−-- clang optimises sibling calls in O1, but gcc doesn't
121−-- on the other hand, O1 compiles significantly faster in clang without
122−-- any noticeable performance hit.
123−gccDbg TRACE = ["-O1", "-foptimize-sibling-calls"]
124−gccDbg _ = ["-O1", "-foptimize-sibling-calls"]
120+gccDbg _ = []
125121
126122cname :: Name -> String
127123cname n = "_idris_" ++ concatMap cchar (showCG n)
@@ -137,14 +133,14 @@ creg (T i) = "TOP(" ++ show i ++ ")"
137133creg Tmp = "REG1"
138134
139135toDecl :: Name -> String
140−toDecl f = "void " ++ cname f ++ "(VM*, VAL*);\n"
136+toDecl f = "void* " ++ cname f ++ "(VM*, VAL*);\n"
141137
142138toC :: Name -> [BC] -> String
143139toC f code
144140 = -- "/* " ++ show code ++ "*/\n\n" ++
145− "void " ++ cname f ++ "(VM* vm, VAL* oldbase) {\n" ++
146− indent 1 ++ "INITFRAME;\n" ++
147− concatMap (bcc 1) code ++ "}\n\n"
141+ "void* " ++ cname f ++ "(VM* vm, VAL* oldbase) {\n" ++
142+ indent 1 ++ "INITFRAME;\nloop:\n" ++
143+ concatMap (bcc f 1) code ++ "}\n\n"
148144
149145showCStr :: String -> String
150146showCStr s = '"' : foldr ((++) . showChar) "\"" s
@@ -180,9 +176,9 @@ showCStr s = '"' : foldr ((++) . showChar) "\"" s
180176 2 -> s
181177 _ -> error $ "Can't happen: String of invalid length " ++ show s
182178
183−bcc :: Int -> BC -> String
184−bcc i (ASSIGN l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
185−bcc i (ASSIGNCONST l c)
179+bcc :: Name -> Int -> BC -> String
180+bcc f i (ASSIGN l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
181+bcc f i (ASSIGNCONST l c)
186182 = indent i ++ creg l ++ " = " ++ mkConst c ++ ";\n"
187183 where
188184 mkConst (I i) = "MKINT(" ++ show i ++ ")"
@@ -203,10 +199,10 @@ bcc i (ASSIGNCONST l c)
203199 mkConst c | isTypeConst c = "MKINT(42424242)"
204200 mkConst c = error $ "mkConst of (" ++ show c ++ ") not implemented"
205201
206−bcc i (UPDATE l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
207−bcc i (MKCON l loc tag []) | tag < 256
202+bcc f i (UPDATE l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
203+bcc f i (MKCON l loc tag []) | tag < 256
208204 = indent i ++ creg l ++ " = NULL_CON(" ++ show tag ++ ");\n"
209−bcc i (MKCON l loc tag args)
205+bcc f i (MKCON l loc tag args)
210206 = indent i ++ alloc loc tag ++
211207 indent i ++ setArgs 0 args ++ "\n" ++
212208 indent i ++ creg l ++ " = " ++ creg Tmp ++ ";\n"
@@ -220,21 +216,21 @@ bcc i (MKCON l loc tag args)
220216 = "updateCon(" ++ creg Tmp ++ ", " ++ creg old ++ ", " ++ show tag ++ ", " ++
221217 show (length args) ++ ");\n"
222218
223−bcc i (PROJECT l loc a) = indent i ++ "PROJECT(vm, " ++ creg l ++ ", " ++ show loc ++
219+bcc f i (PROJECT l loc a) = indent i ++ "PROJECT(vm, " ++ creg l ++ ", " ++ show loc ++
224220 ", " ++ show a ++ ");\n"
225−bcc i (PROJECTINTO r t idx)
221+bcc f i (PROJECTINTO r t idx)
226222 = indent i ++ creg r ++ " = GETARG(" ++ creg t ++ ", " ++ show idx ++ ");\n"
227−bcc i (CASE True r [(_, alt)] Nothing)
223+bcc f i (CASE True r [(_, alt)] Nothing)
228224 = indent i ++ showCode i alt
229225 where
230226 showCode :: Int -> [BC] -> String
231− showCode i bc = "{\n" ++ concatMap (bcc (i + 1)) bc ++
227+ showCode i bc = "{\n" ++ concatMap (bcc f (i + 1)) bc ++
232228 indent i ++ "}\n"
233−bcc i (CASE True r code def)
229+bcc f i (CASE True r code def)
234230 | length code < 6 && length code > 1 = showCase i def code
235231 where
236232 showCode :: Int -> [BC] -> String
237− showCode i bc = "{\n" ++ concatMap (bcc (i + 1)) bc ++
233+ showCode i bc = "{\n" ++ concatMap (bcc f (i + 1)) bc ++
238234 indent i ++ "}\n"
239235
240236 showCase :: Int -> Maybe [BC] -> [(Int, [BC])] -> String
@@ -244,7 +240,7 @@ bcc i (CASE True r code def)
244240 = indent i ++ "if (CTAG(" ++ creg r ++ ") == " ++ show t ++ ") " ++ showCode i c
245241 ++ indent i ++ "else\n" ++ showCase i def cs
246242
247−bcc i (CASE safe r code def)
243+bcc f i (CASE safe r code def)
248244 = indent i ++ "switch(" ++ ctag safe ++ "(" ++ creg r ++ ")) {\n" ++
249245 concatMap (showCase i) code ++
250246 showDef i def ++
@@ -254,11 +250,12 @@ bcc i (CASE safe r code def)
254250 ctag False = "TAG"
255251
256252 showCase i (t, bc) = indent i ++ "case " ++ show t ++ ":\n"
257− ++ concatMap (bcc (i+1)) bc ++ indent (i + 1) ++ "break;\n"
258− showDef i Nothing = ""
253+ ++ concatMap (bcc f (i+1)) bc ++ indent (i + 1) ++ "break;\n"
254+ showDef i Nothing = indent i ++ "default:\n" ++
255+ indent (i + 1) ++ "return NULL;\n"
259256 showDef i (Just c) = indent i ++ "default:\n"
260− ++ concatMap (bcc (i+1)) c ++ indent (i + 1) ++ "break;\n"
261−bcc i (CONSTCASE r code def)
257+ ++ concatMap (bcc f (i+1)) c ++ indent (i + 1) ++ "break;\n"
258+bcc f i (CONSTCASE r code def)
262259 | intConsts code
263260-- = indent i ++ "switch(GETINT(" ++ creg r ++ ")) {\n" ++
264261-- concatMap (showCase i) code ++
@@ -290,65 +287,67 @@ bcc i (CONSTCASE r code def)
290287
291288 strCase sv (s, bc) =
292289 indent i ++ "if (strcmp(" ++ sv ++ ", " ++ show s ++ ") == 0) {\n" ++
293− concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
290+ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
294291 biCase bv (BI b, bc) =
295292 indent i ++ "if (bigEqConst(" ++ bv ++ ", " ++ show b ++ ")) {\n"
296− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
293+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
297294 iCase v (I b, bc) =
298295 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show b ++ ") {\n"
299− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
296+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
300297 iCase v (Ch b, bc) =
301298 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show (fromEnum b) ++ ") {\n"
302− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
299+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
303300 iCase v (B8 w, bc) =
304301 indent i ++ "if (GETBITS8(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
305− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
302+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
306303 iCase v (B16 w, bc) =
307304 indent i ++ "if (GETBITS16(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
308− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
305+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
309306 iCase v (B32 w, bc) =
310307 indent i ++ "if (GETBITS32(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
311− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
308+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
312309 iCase v (B64 w, bc) =
313310 indent i ++ "if (GETBITS64(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
314− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
311+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
315312 showDefS i Nothing = ""
316− showDefS i (Just c) = concatMap (bcc (i+1)) c
317−
318−bcc i (CALL n) = indent i ++ "CALL(" ++ cname n ++ ");\n"
319−bcc i (TAILCALL n) = indent i ++ "TAILCALL(" ++ cname n ++ ");\n"
320−bcc i (SLIDE n) = indent i ++ "SLIDE(vm, " ++ show n ++ ");\n"
321−bcc i REBASE = indent i ++ "REBASE;\n"
322−bcc i (RESERVE 0) = ""
323−bcc i (RESERVE n) = indent i ++ "RESERVE(" ++ show n ++ ");\n"
324−bcc i (ADDTOP 0) = ""
325−bcc i (ADDTOP n) = indent i ++ "ADDTOP(" ++ show n ++ ");\n"
326−bcc i (TOPBASE n) = indent i ++ "TOPBASE(" ++ show n ++ ");\n"
327−bcc i (BASETOP n) = indent i ++ "BASETOP(" ++ show n ++ ");\n"
328−bcc i STOREOLD = indent i ++ "STOREOLD;\n"
329−bcc i (OP l fn args) = indent i ++ doOp (creg l ++ " = ") fn args ++ ";\n"
330−bcc i (FOREIGNCALL l rty (FStr ('#':name)) [])
313+ showDefS i (Just c) = concatMap (bcc f (i+1)) c
314+
315+bcc f i (CALL n) = indent i ++ "CALL(" ++ cname n ++ ");\n"
316+bcc f i (TAILCALL n)
317+ | f == n = indent i ++ "goto loop;\n"
318+ | otherwise = indent i ++ "TAILCALL(" ++ cname n ++ ");\n"
319+bcc f i (SLIDE n) = indent i ++ "SLIDE(vm, " ++ show n ++ ");\n"
320+bcc f i REBASE = indent i ++ "REBASE;\n"
321+bcc f i (RESERVE 0) = ""
322+bcc f i (RESERVE n) = indent i ++ "RESERVE(" ++ show n ++ ");\n"
323+bcc f i (ADDTOP 0) = ""
324+bcc f i (ADDTOP n) = indent i ++ "ADDTOP(" ++ show n ++ ");\n"
325+bcc f i (TOPBASE n) = indent i ++ "TOPBASE(" ++ show n ++ ");\n"
326+bcc f i (BASETOP n) = indent i ++ "BASETOP(" ++ show n ++ ");\n"
327+bcc f i STOREOLD = indent i ++ "STOREOLD;\n"
328+bcc f i (OP l fn args) = indent i ++ doOp (creg l ++ " = ") fn args ++ ";\n"
329+bcc f i (FOREIGNCALL l rty (FStr ('#':name)) [])
331330 = indent i ++
332331 c_irts (toFType rty) (creg l ++ " = ") name ++ ";\n"
333−bcc i (FOREIGNCALL l rty (FStr fn@('&':name)) [])
332+bcc f i (FOREIGNCALL l rty (FStr fn@('&':name)) [])
334333 = indent i ++
335334 c_irts (toFType rty) (creg l ++ " = ") fn ++ ";\n"
336−bcc i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%wrapper"
335+bcc f i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%wrapper"
337336 = indent i ++
338337 c_irts (toFType rty) (creg l ++ " = ")
339338 ("_idris_get_wrapper(" ++ creg (snd x) ++ ")") ++ ";\n"
340−bcc i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%dynamic"
339+bcc f i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%dynamic"
341340 = indent i ++ c_irts (toFType rty) (creg l ++ " = ")
342341 ("(*(" ++ cFnSig "" rty xs ++ ") GETPTR(" ++ creg (snd x) ++ "))" ++
343342 "(" ++ showSep "," (map fcall xs) ++ ")") ++ ";\n"
344−bcc i (FOREIGNCALL l rty (FStr fn) args)
343+bcc f i (FOREIGNCALL l rty (FStr fn) args)
345344 = indent i ++
346345 c_irts (toFType rty) (creg l ++ " = ")
347346 (fn ++ "(" ++ showSep "," (map fcall args) ++ ")") ++ ";\n"
348−bcc i (FOREIGNCALL l rty _ args) = error "Foreign Function calls cannot be partially applied, without being inlined."
349−bcc i (NULL r) = indent i ++ creg r ++ " = NULL;\n" -- clear, so it'll be GCed
350−bcc i (ERROR str) = indent i ++ "fprintf(stderr, " ++ show str ++ "); fprintf(stderr, \"\\n\"); exit(-1);\n"
351−-- bcc i c = error (show c) -- indent i ++ "// not done yet\n"
347+bcc f i (FOREIGNCALL l rty _ args) = error "Foreign Function calls cannot be partially applied, without being inlined."
348+bcc f i (NULL r) = indent i ++ creg r ++ " = NULL;\n" -- clear, so it'll be GCed
349+bcc f i (ERROR str) = indent i ++ "fprintf(stderr, " ++ show str ++ "); fprintf(stderr, \"\\n\"); exit(-1);\n"
350+-- bcc f i c = error (show c) -- indent i ++ "// not done yet\n"
352351
353352fcall (t, arg) = irts_c (toFType t) (creg arg)
354353-- Deconstruct the Foreign type in the defunctionalised expression and build