Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Direct function calls #251

Merged
merged 22 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3c44ac7
Generate direct calls to global functions.
robinheghan Jun 27, 2024
87cdb6f
On to something.
robinheghan Jun 27, 2024
1c3f0d5
Implement function definitions correctly.
robinheghan Jun 30, 2024
d47325d
Make direct functin calls to custom type constructors.
robinheghan Jun 30, 2024
6b90363
Update compiler build, makes it easier to see new diffs.
robinheghan Jun 30, 2024
c38f92c
Remove unused argument.
robinheghan Jun 30, 2024
a6ebb96
Fix source mapping.
robinheghan Jun 30, 2024
b9eaeb1
Make direct function calls to recursive functions.
robinheghan Jun 30, 2024
52da4e3
Code formatting.
robinheghan Jun 30, 2024
2baf2d5
Add sourcemaps for recursive functions.
robinheghan Jul 1, 2024
a63730e
Optimize direct calls for non-tail recursive functions.
robinheghan Jul 1, 2024
4c6f7ab
Add sourcemaps for Debug functions.
robinheghan Jul 1, 2024
5b523cb
Fix minor codegen issues.
robinheghan Jul 1, 2024
6e7507c
Rever test changes, and compile gren-in-gren with latest compiler.
robinheghan Jul 1, 2024
9f75298
Derive Show on Opt.Expr
robinheghan Jul 2, 2024
efa2671
Add missing branches to isLiteral check, fixing an optimization that …
robinheghan Jul 2, 2024
54ad744
Fix direct call optimization for mutually recursive functions.
robinheghan Jul 2, 2024
7fecbc6
Fix regression in optimizing string appends.
robinheghan Jul 2, 2024
251e58d
Add position of anonymous functions in source maps.
robinheghan Aug 6, 2024
ed647c2
Run prettier.
robinheghan Aug 7, 2024
c595709
Simplify position check.
robinheghan Aug 7, 2024
430fd9b
Build with official compiler.
robinheghan Aug 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions compiler/src/AST/Optimized.hs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ data Expr
| VarDebug A.Region Name ModuleName.Canonical (Maybe Name)
| VarKernel A.Region Name Name
| Array A.Region [Expr]
| Function [A.Located Name] Expr
| Function A.Region [A.Located Name] Expr
| Call A.Region Expr [Expr]
| TailCall Name [(Name, Expr)]
| If [(Expr, Expr)] Expr
Expand All @@ -64,24 +64,29 @@ data Expr
| Access Expr A.Region Name
| Update A.Region Expr (Map.Map (A.Located Name) Expr)
| Record A.Region (Map.Map (A.Located Name) Expr)
deriving (Show)

data Global = Global ModuleName.Canonical Name
deriving (Show)

-- DEFINITIONS

data Def
= Def A.Region Name Expr
| TailDef A.Region Name [A.Located Name] Expr
deriving (Show)

data Destructor
= Destructor Name Path
deriving (Show)

data Path
= Index Index.ZeroBased Path
| ArrayIndex Index.ZeroBased Path
| Field Name Path
| Unbox Path
| Root Name
deriving (Show)

-- BRANCHING

Expand All @@ -97,11 +102,12 @@ data Decider a
_tests :: [(DT.Test, Decider a)],
_fallback :: Decider a
}
deriving (Eq)
deriving (Show, Eq)

data Choice
= Inline Expr
| Jump Int
deriving (Show)

-- OBJECT GRAPH

Expand Down Expand Up @@ -219,7 +225,7 @@ instance Binary Expr where
VarDebug a b c d -> putWord8 10 >> put a >> put b >> put c >> put d
VarKernel a b c -> putWord8 11 >> put a >> put b >> put c
Array a b -> putWord8 12 >> put a >> put b
Function a b -> putWord8 13 >> put a >> put b
Function a b c -> putWord8 13 >> put a >> put b >> put c
Call a b c -> putWord8 14 >> put a >> put b >> put c
TailCall a b -> putWord8 15 >> put a >> put b
If a b -> putWord8 16 >> put a >> put b
Expand Down Expand Up @@ -248,7 +254,7 @@ instance Binary Expr where
10 -> liftM4 VarDebug get get get get
11 -> liftM3 VarKernel get get get
12 -> liftM2 Array get get
13 -> liftM2 Function get get
13 -> liftM3 Function get get get
14 -> liftM3 Call get get get
15 -> liftM2 TailCall get get
16 -> liftM2 If get get
Expand Down
109 changes: 90 additions & 19 deletions compiler/src/Generate/JavaScript.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,41 @@ import Prelude hiding (cycle, print)

type Graph = Map.Map Opt.Global Opt.Node

type FnArgLookup = ModuleName.Canonical -> Name.Name -> Maybe Int

type Mains = Map.Map ModuleName.Canonical Opt.Main

data GeneratedResult = GeneratedResult
{ _source :: B.Builder,
_sourceMap :: SourceMap.SourceMap
}

makeArgLookup :: Graph -> ModuleName.Canonical -> Name.Name -> Maybe Int
makeArgLookup graph home name =
case Map.lookup (Opt.Global home name) graph of
Just (Opt.Define _ (Opt.Function _ args _) _) ->
Just (length args)
Just (Opt.Ctor _ arity) ->
Just arity
Just (Opt.Link global) ->
case Map.lookup global graph of
Just (Opt.Cycle names _ defs _) ->
case List.find (\d -> defName d == name) defs of
Just (Opt.Def _ _ (Opt.Function _ args _)) ->
Just (length args)
Just (Opt.TailDef _ _ args _) ->
Just (length args)
_ ->
error (show names)
_ ->
Nothing
_ ->
Nothing

defName :: Opt.Def -> Name.Name
defName (Opt.Def _ name _) = name
defName (Opt.TailDef _ name _ _) = name

prelude :: B.Builder
prelude =
"(function(scope){\n'use strict';"
Expand Down Expand Up @@ -140,18 +168,32 @@ addGlobalHelp :: Mode.Mode -> Graph -> Opt.Global -> State -> State
addGlobalHelp mode graph global@(Opt.Global home _) state =
let addDeps deps someState =
Set.foldl' (addGlobal mode graph) someState deps

argLookup = makeArgLookup graph
in case graph ! global of
Opt.Define region (Opt.Function (A.Region funcStart _) args body) deps
| length args > 1 ->
addStmt
(addDeps deps state)
( trackedFn region global args (Expr.generateFunctionImplementation mode argLookup home funcStart args body)
)
Opt.Define region expr deps ->
addStmt
(addDeps deps state)
( trackedVar region global (Expr.generate mode home expr)
( trackedVar region global (Expr.generate mode argLookup home expr)
)
Opt.DefineTailFunc region argNames body deps ->
addStmt
(addDeps deps state)
( let (Opt.Global _ name) = global
in trackedVar region global (Expr.generateTailDef mode home name argNames body)
in trackedVar region global (Expr.generateTailDef mode argLookup home name argNames body)
)
Opt.Ctor index arity
| arity > 1 ->
addStmt
state
( ctor global arity (Expr.generateCtorImplementation mode global index arity)
)
Opt.Ctor index arity ->
addStmt
state
Expand All @@ -162,7 +204,7 @@ addGlobalHelp mode graph global@(Opt.Global home _) state =
Opt.Cycle names values functions deps ->
addStmt
(addDeps deps state)
( generateCycle mode global names values functions
( generateCycle mode argLookup global names values functions
)
Opt.Manager effectsType ->
generateManager mode graph global effectsType state
Expand Down Expand Up @@ -207,17 +249,35 @@ trackedVar :: A.Region -> Opt.Global -> Expr.Code -> JS.Stmt
trackedVar (A.Region startPos _) (Opt.Global home name) code =
JS.TrackedVar home startPos (JsName.fromGlobalHumanReadable home name) (JsName.fromGlobal home name) (Expr.codeToExpr code)

trackedFn :: A.Region -> Opt.Global -> [A.Located Name.Name] -> Expr.Code -> JS.Stmt
trackedFn (A.Region startPos _) (Opt.Global home name) args code =
let directFnName = JsName.fromGlobalDirectFn home name
argNames = map (\(A.At _ arg) -> JsName.fromLocal arg) args
in JS.Block
[ JS.TrackedVar home startPos (JsName.fromGlobalHumanReadable home name) directFnName (Expr.codeToExpr code),
JS.Var (JsName.fromGlobal home name) $ Expr.codeToExpr (Expr.generateCurriedFunctionRef argNames directFnName)
]

ctor :: Opt.Global -> Int -> Expr.Code -> JS.Stmt
ctor (Opt.Global home name) arity code =
let directFnName = JsName.fromGlobalDirectFn home name
argNames = Index.indexedMap (\i _ -> JsName.fromIndex i) [1 .. arity]
in JS.Block
[ JS.Var directFnName (Expr.codeToExpr code),
JS.Var (JsName.fromGlobal home name) $ Expr.codeToExpr (Expr.generateCurriedFunctionRef argNames directFnName)
]

isDebugger :: Opt.Global -> Bool
isDebugger (Opt.Global (ModuleName.Canonical _ home) _) =
home == Name.debugger

-- GENERATE CYCLES

generateCycle :: Mode.Mode -> Opt.Global -> [Name.Name] -> [(Name.Name, Opt.Expr)] -> [Opt.Def] -> JS.Stmt
generateCycle mode (Opt.Global home _) names values functions =
generateCycle :: Mode.Mode -> FnArgLookup -> Opt.Global -> [Name.Name] -> [(Name.Name, Opt.Expr)] -> [Opt.Def] -> JS.Stmt
generateCycle mode argLookup (Opt.Global home _) names values functions =
JS.Block
[ JS.Block $ map (generateCycleFunc mode home) functions,
JS.Block $ map (generateSafeCycle mode home) values,
[ JS.Block $ map (generateCycleFunc mode argLookup home) functions,
JS.Block $ map (generateSafeCycle mode argLookup home) values,
case map (generateRealCycle home) values of
[] ->
JS.EmptyStmt
Expand All @@ -238,18 +298,29 @@ generateCycle mode (Opt.Global home _) names values functions =
<> " to learn how to fix it!"
]

generateCycleFunc :: Mode.Mode -> ModuleName.Canonical -> Opt.Def -> JS.Stmt
generateCycleFunc mode home def =
generateCycleFunc :: Mode.Mode -> FnArgLookup -> ModuleName.Canonical -> Opt.Def -> JS.Stmt
generateCycleFunc mode argLookup home def =
case def of
Opt.Def _ name expr ->
JS.Var (JsName.fromGlobal home name) (Expr.codeToExpr (Expr.generate mode home expr))
Opt.TailDef _ name args expr ->
JS.Var (JsName.fromGlobal home name) (Expr.codeToExpr (Expr.generateTailDef mode home name args expr))

generateSafeCycle :: Mode.Mode -> ModuleName.Canonical -> (Name.Name, Opt.Expr) -> JS.Stmt
generateSafeCycle mode home (name, expr) =
Opt.Def region name (Opt.Function (A.Region funcStartPos _) args body)
| length args > 1 ->
trackedFn region (Opt.Global home name) args (Expr.generateFunctionImplementation mode argLookup home funcStartPos args body)
Opt.Def (A.Region startPos _) name expr ->
JS.TrackedVar home startPos (JsName.fromGlobalHumanReadable home name) (JsName.fromGlobal home name) (Expr.codeToExpr (Expr.generate mode argLookup home expr))
Opt.TailDef (A.Region startPos _) name args expr
| length args > 1 ->
let directFnName = JsName.fromGlobalDirectFn home name
argNames = map (\(A.At _ arg) -> JsName.fromLocal arg) args
in JS.Block
[ JS.TrackedVar home startPos (JsName.fromGlobalHumanReadable home name) directFnName (Expr.codeToExpr (Expr.generateTailDefImplementation mode argLookup home name args expr)),
JS.Var (JsName.fromGlobal home name) (Expr.codeToExpr (Expr.generateCurriedFunctionRef argNames directFnName))
]
Opt.TailDef (A.Region startPos _) name args expr ->
JS.TrackedVar home startPos (JsName.fromGlobalHumanReadable home name) (JsName.fromGlobal home name) (Expr.codeToExpr (Expr.generateTailDef mode argLookup home name args expr))

generateSafeCycle :: Mode.Mode -> FnArgLookup -> ModuleName.Canonical -> (Name.Name, Opt.Expr) -> JS.Stmt
generateSafeCycle mode argLookup home (name, expr) =
JS.FunctionStmt (JsName.fromCycle home name) [] $
Expr.codeToStmtList (Expr.generate mode home expr)
Expr.codeToStmtList (Expr.generate mode argLookup home expr)

generateRealCycle :: ModuleName.Canonical -> (Name.Name, expr) -> JS.Stmt
generateRealCycle home (name, _) =
Expand Down Expand Up @@ -338,7 +409,7 @@ generatePort mode (Opt.Global home name) makePort converter =
JS.Call
(JS.Ref (JsName.fromKernel Name.platform makePort))
[ JS.String (Name.toBuilder name),
Expr.codeToExpr (Expr.generate mode home converter)
Expr.codeToExpr (Expr.generate mode (\_ _ -> Nothing) home converter)
]

-- GENERATE MANAGER
Expand Down Expand Up @@ -408,7 +479,7 @@ generateExports mode (Trie maybeMain subs) =
"{"
Just (home, main) ->
"{'init':"
<> JS._code (JS.exprToBuilder (Expr.generateMain mode home main) (JS.emptyBuilder 0))
<> JS._code (JS.exprToBuilder (Expr.generateMain mode (\_ _ -> Nothing) home main) (JS.emptyBuilder 0))
<> end
in case Map.toList subs of
[] ->
Expand Down
9 changes: 6 additions & 3 deletions compiler/src/Generate/JavaScript/Builder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ data Expr
| Call Expr [Expr]
| TrackedNormalCall ModuleName.Canonical A.Position Expr Expr [Expr]
| Function (Maybe Name) [Name] [Stmt]
| TrackedFunction ModuleName.Canonical [A.Located Name] [Stmt]
| TrackedFunction ModuleName.Canonical A.Position [A.Located Name] [Stmt]

data LValue
= LRef Name
Expand Down Expand Up @@ -627,9 +627,12 @@ fromExpr level@(Level indent nextLevel) grouping expression builder =
& fromStmtBlock nextLevel stmts
& addByteString indent
& addAscii "}"
TrackedFunction moduleName args stmts ->
TrackedFunction moduleName startPos args stmts ->
builder
& addAscii "function"
& ( if startPos == A.zeroPosition
then addAscii "function"
else addTrackedByteString moduleName startPos "function"
)
& addAscii "("
& commaSepExpr (\(A.At (A.Region start _) name) -> addName moduleName start name name) args
& addAscii ") {"
Expand Down
Loading
Loading