@@ -12,6 +12,7 @@ import Util.System
13import Control.Arrow
13import Control.Arrow
14import Control.Applicative ((<$>), (<*>), pure)
14import Control.Applicative ((<$>), (<*>), pure)
15+import Control.Monad.RWS
15import Data.Char
16import Data.Char
16import Numeric
17import Numeric
17import Data.List
18import Data.List
@@ -303,7 +304,8 @@ codegenJS_all
303codegenJS_all target definitions includes filename outputType = do
304codegenJS_all target definitions includes filename outputType = do
304 let bytecode = map toBC definitions
305 let bytecode = map toBC definitions
305 let info = initCompileInfo bytecode
306 let info = initCompileInfo bytecode
306− let code = concat $ map ((concatMap compileJS) . (translateDecl info)) bytecode
307+ let js = concatMap (translateDecl info) bytecode
308+ let code = concatMap ((map compileJS) . collectSplitFunctions . (\x -> evalRWS (splitFunction x) () 0)) js
307 let (header, rt) = case target of
309 let (header, rt) = case target of
309 ("#!/usr/bin/env node\n", "-node")
311 ("#!/usr/bin/env node\n", "-node")
@@ -314,7 +316,7 @@ codegenJS_all target definitions includes filename outputType = do
314 tgtRuntime <- readFile $ concat [path, "Runtime", rt, ".js"]
316 tgtRuntime <- readFile $ concat [path, "Runtime", rt, ".js"]
315 jsbn <- readFile $ path ++ "jsbn/jsbn.js"
317 jsbn <- readFile $ path ++ "jsbn/jsbn.js"
316 let runtime = header ++ jsbn ++ idrRuntime ++ tgtRuntime
318 let runtime = header ++ jsbn ++ idrRuntime ++ tgtRuntime
317− writeFile filename $ runtime ++ code ++ main ++ invokeMain
319+ writeFile filename $ runtime ++ concat code ++ main ++ invokeMain
318 setPermissions filename (emptyPermissions { readable = True
320 setPermissions filename (emptyPermissions { readable = True
319 , executable = target == Node
321 , executable = target == Node
320 , writable = True
322 , writable = True
@@ -326,15 +328,59 @@ codegenJS_all target definitions includes filename outputType = do
326 JSSeq [ JSAlloc "vm" (Just $ JSNew "i$VM" [])
328 JSSeq [ JSAlloc "vm" (Just $ JSNew "i$VM" [])
327 , JSApp (
329 , JSApp (
328 JSIdent (translateName (sMN 0 "runMain"))
330 JSIdent (translateName (sMN 0 "runMain"))
329− ) [ JSIdent "vm"
331+ ) [ JSIdent "vm"
330− , JSNum (JSInt 0)
332+ , JSNum (JSInt 0)
335 invokeMain :: String
337 invokeMain :: String
336 invokeMain = compileJS $ JSApp (JSIdent "main") []
338 invokeMain = compileJS $ JSApp (JSIdent "main") []
340+collectSplitFunctions :: (JS, [(Int,JS)]) -> [JS]
341+collectSplitFunctions (fun, splits) = map generateSplitFunction splits ++ [fun]
343+ generateSplitFunction :: (Int,JS) -> JS
344+ generateSplitFunction (depth, JSAlloc name fun) =
345+ JSAlloc (name ++ "$" ++ show depth) fun
347+splitFunction :: JS -> RWS () [(Int,JS)] Int JS
348+splitFunction (JSAlloc name (Just (JSFunction args body))) = do
349+ b <- splitSequence body
350+ return $ JSAlloc name (Just (JSFunction args b))
352+ splitSequence :: JS -> RWS () [(Int, JS)] Int JS
353+ splitSequence js@(JSSeq seq) = do
354+ let (pre,post) = break isCall seq in
361+ new <- splitFunction (newFun rest)
363+ {-return $ JSSeq (pre ++ [newCall depth, call])-}
364+ return $ JSSeq (pre ++ [call, newCall depth])
366+ isCall :: JS -> Bool
367+ isCall (JSApp (JSIdent "i$CALL") _) = True
370+ newCall :: Int -> JS
372+ JSApp (JSIdent "i$CALL") [ JSIdent "vm"
373+ , JSIdent $ name ++ "$" ++ show depth
374+ , JSArray [JSIdent "vm"
376+ , JSIdent "myoldbase"
380+ newFun :: [JS] -> JS
382+ JSAlloc name (Just $ JSFunction ["vm", "oldbase", "myoldbase"] (JSSeq seq))
339translateDecl :: CompileInfo -> (Name, [BC]) -> [JS]
385translateDecl :: CompileInfo -> (Name, [BC]) -> [JS]
340translateDecl info (name@(MN 0 fun), bc)
386translateDecl info (name@(MN 0 fun), bc)
@@ -457,9 +503,9 @@ translateConstant (AType ATFloat) = JSType JSFloatTy
457translateConstant (AType (ATInt ITChar)) = JSType JSCharTy
503translateConstant (AType (ATInt ITChar)) = JSType JSCharTy
458translateConstant PtrType = JSType JSPtrTy
504translateConstant PtrType = JSType JSPtrTy
459translateConstant Forgot = JSType JSForgotTy
505translateConstant Forgot = JSType JSForgotTy
460−translateConstant (BI i) = jsBigInt (JSString $ show i)
461translateConstant (BI 0) = JSNum (JSInteger JSBigZero)
506translateConstant (BI 0) = JSNum (JSInteger JSBigZero)
462translateConstant (BI 1) = JSNum (JSInteger JSBigOne)
507translateConstant (BI 1) = JSNum (JSInteger JSBigOne)
508+translateConstant (BI i) = jsBigInt (JSString $ show i)
463translateConstant (B8 b) = JSWord (JSWord8 b)
509translateConstant (B8 b) = JSWord (JSWord8 b)
464translateConstant (B16 b) = JSWord (JSWord16 b)
510translateConstant (B16 b) = JSWord (JSWord16 b)
465translateConstant (B32 b) = JSWord (JSWord32 b)
511translateConstant (B32 b) = JSWord (JSWord32 b)
@@ -508,10 +554,22 @@ jsASSIGNCONST :: CompileInfo -> Reg -> Const -> JS
508jsASSIGNCONST _ r c = JSAssign (translateReg r) (translateConstant c)
554jsASSIGNCONST _ r c = JSAssign (translateReg r) (translateConstant c)
510jsCALL :: CompileInfo -> Name -> JS
556jsCALL :: CompileInfo -> Name -> JS
511−jsCALL _ n = JSApp (JSIdent (translateName n)) [JSIdent "vm", JSIdent "myoldbase"]
560+ ) [ JSIdent "vm", JSIdent (translateName n), JSArray [ JSIdent "vm"
561+ , JSIdent "myoldbase"
513jsTAILCALL :: CompileInfo -> Name -> JS
565jsTAILCALL :: CompileInfo -> Name -> JS
514−jsTAILCALL _ n = JSApp (JSIdent (translateName n)) [JSIdent "vm", JSIdent "oldbase"]
569+ ) [ JSIdent "vm", JSIdent (translateName n), JSArray [ JSIdent "vm"
516jsFOREIGN :: CompileInfo -> Reg -> String -> [(FType, Reg)] -> JS
574jsFOREIGN :: CompileInfo -> Reg -> String -> [(FType, Reg)] -> JS
517jsFOREIGN _ reg n args =
575jsFOREIGN _ reg n args =