@@ -140,9 +140,10 @@ import GHC.Driver.Hooks
140
140
import GHC.Driver.GenerateCgIPEStub (generateCgIPEStub )
141
141
142
142
import GHC.Runtime.Context
143
- import GHC.Runtime.Interpreter ( addSptEntry )
143
+ import GHC.Runtime.Interpreter
144
+ import GHC.Runtime.Interpreter.JS
144
145
import GHC.Runtime.Loader ( initializePlugins )
145
- import GHCi.RemoteTypes ( ForeignHValue )
146
+ import GHCi.RemoteTypes
146
147
import GHC.ByteCode.Types
147
148
148
149
import GHC.Linker.Loader
@@ -156,6 +157,9 @@ import GHC.HsToCore
156
157
157
158
import GHC.StgToByteCode ( byteCodeGen )
158
159
import GHC.StgToJS ( stgToJS )
160
+ import GHC.StgToJS.Ids
161
+ import GHC.StgToJS.Types
162
+ import GHC.JS.Syntax
159
163
160
164
import GHC.IfaceToCore ( typecheckIface , typecheckWholeCoreBindings )
161
165
@@ -172,7 +176,6 @@ import GHC.Core
172
176
import GHC.Core.Lint.Interactive ( interactiveInScope )
173
177
import GHC.Core.Tidy ( tidyExpr )
174
178
import GHC.Core.Type ( Type , Kind )
175
- import GHC.Core.Multiplicity
176
179
import GHC.Core.Utils ( exprType )
177
180
import GHC.Core.ConLike
178
181
import GHC.Core.Opt.Pipeline
@@ -201,7 +204,6 @@ import GHC.Stg.Pipeline ( stg2stg, StgCgInfos )
201
204
202
205
import GHC.Builtin.Utils
203
206
import GHC.Builtin.Names
204
- import GHC.Builtin.Uniques ( mkPseudoUniqueE )
205
207
206
208
import qualified GHC.StgToCmm as StgToCmm ( codeGen )
207
209
import GHC.StgToCmm.Types (CmmCgInfos (.. ), ModuleLFInfos , LambdaFormInfo (.. ))
@@ -231,7 +233,7 @@ import GHC.Types.SourceError
231
233
import GHC.Types.SafeHaskell
232
234
import GHC.Types.ForeignStubs
233
235
import GHC.Types.Name.Env ( mkNameEnv )
234
- import GHC.Types.Var.Env ( emptyTidyEnv )
236
+ import GHC.Types.Var.Env ( mkEmptyTidyEnv )
235
237
import GHC.Types.Error
236
238
import GHC.Types.Fixity.Env
237
239
import GHC.Types.CostCentre
@@ -245,6 +247,8 @@ import GHC.Types.Name.Ppr
245
247
import GHC.Types.Name.Set (NonCaffySet )
246
248
import GHC.Types.TyThing
247
249
import GHC.Types.HpcInfo
250
+ import GHC.Types.Unique.Supply (uniqFromMask )
251
+ import GHC.Types.Unique (getKey )
248
252
249
253
import GHC.Utils.Fingerprint ( Fingerprint )
250
254
import GHC.Utils.Panic
@@ -289,6 +293,7 @@ import System.IO.Unsafe ( unsafeInterleaveIO )
289
293
import GHC.Iface.Env ( trace_if )
290
294
import GHC.Stg.InferTags.TagSig (seqTagSig )
291
295
import GHC.Types.Unique.FM
296
+ import GHC.Types.Unique.DFM
292
297
293
298
294
299
{- **********************************************************************
@@ -1853,7 +1858,7 @@ hscGenHardCode hsc_env cgguts location output_filename = do
1853
1858
c `seqList`
1854
1859
d `seqList`
1855
1860
(seqEltsUFM (seqTagSig) tag_env))
1856
- (myCoreToStg logger dflags (hsc_IC hsc_env) False this_mod location prepd_binds)
1861
+ (myCoreToStg logger dflags (interactiveInScope ( hsc_IC hsc_env) ) False this_mod location prepd_binds)
1857
1862
1858
1863
let cost_centre_info =
1859
1864
(late_local_ccs ++ caf_ccs, caf_cc_stacks)
@@ -1975,7 +1980,7 @@ hscInteractive hsc_env cgguts location = do
1975
1980
-- omit it here
1976
1981
(stg_binds, _infotable_prov, _caf_ccs__caf_cc_stacks, _ignore_stg_cg_infos)
1977
1982
<- {-# SCC "CoreToStg" #-}
1978
- myCoreToStg logger dflags (hsc_IC hsc_env) True this_mod location prepd_binds
1983
+ myCoreToStg logger dflags (interactiveInScope ( hsc_IC hsc_env) ) True this_mod location prepd_binds
1979
1984
----------------- Generate byte code ------------------
1980
1985
comp_bc <- byteCodeGen hsc_env this_mod stg_binds data_tycons mod_breaks
1981
1986
------------------ Create f-x-dynamic C-side stuff -----
@@ -2150,46 +2155,21 @@ doCodeGen hsc_env this_mod denv data_tycons
2150
2155
2151
2156
return $ Stream. mapM dump2 $ generateCgIPEStub hsc_env this_mod denv pipeline_stream
2152
2157
2153
- myCoreToStgExpr :: Logger -> DynFlags -> InteractiveContext
2154
- -> Bool
2155
- -> Module -> ModLocation -> CoreExpr
2156
- -> IO ( Id
2157
- , [CgStgTopBinding ]
2158
- , InfoTableProvMap
2159
- , CollectedCCs
2160
- , StgCgInfos )
2161
- myCoreToStgExpr logger dflags ictxt for_bytecode this_mod ml prepd_expr = do
2162
- {- Create a temporary binding (just because myCoreToStg needs a
2163
- binding for the stg2stg step) -}
2164
- let bco_tmp_id = mkSysLocal (fsLit " BCO_toplevel" )
2165
- (mkPseudoUniqueE 0 )
2166
- ManyTy
2167
- (exprType prepd_expr)
2168
- (stg_binds, prov_map, collected_ccs, stg_cg_infos) <-
2169
- myCoreToStg logger
2170
- dflags
2171
- ictxt
2172
- for_bytecode
2173
- this_mod
2174
- ml
2175
- [NonRec bco_tmp_id prepd_expr]
2176
- return (bco_tmp_id, stg_binds, prov_map, collected_ccs, stg_cg_infos)
2177
-
2178
- myCoreToStg :: Logger -> DynFlags -> InteractiveContext
2158
+ myCoreToStg :: Logger -> DynFlags -> [Var ]
2179
2159
-> Bool
2180
2160
-> Module -> ModLocation -> CoreProgram
2181
2161
-> IO ( [CgStgTopBinding ] -- output program
2182
2162
, InfoTableProvMap
2183
2163
, CollectedCCs -- CAF cost centre info (declared and used)
2184
2164
, StgCgInfos )
2185
- myCoreToStg logger dflags ictxt for_bytecode this_mod ml prepd_binds = do
2165
+ myCoreToStg logger dflags ic_inscope for_bytecode this_mod ml prepd_binds = do
2186
2166
let (stg_binds, denv, cost_centre_info)
2187
2167
= {-# SCC "Core2Stg" #-}
2188
2168
coreToStg (initCoreToStgOpts dflags) this_mod ml prepd_binds
2189
2169
2190
2170
(stg_binds_with_fvs,stg_cg_info)
2191
2171
<- {-# SCC "Stg2Stg" #-}
2192
- stg2stg logger (interactiveInScope ictxt) (initStgPipelineOpts dflags for_bytecode)
2172
+ stg2stg logger ic_inscope (initStgPipelineOpts dflags for_bytecode)
2193
2173
this_mod stg_binds
2194
2174
2195
2175
putDumpFileMaybe logger Opt_D_dump_stg_cg " CodeGenInput STG:" FormatSTG
@@ -2350,7 +2330,7 @@ hscParsedDecls hsc_env decls = runInteractiveHsc hsc_env $ do
2350
2330
<- {-# SCC "CoreToStg" #-}
2351
2331
liftIO $ myCoreToStg (hsc_logger hsc_env)
2352
2332
(hsc_dflags hsc_env)
2353
- (hsc_IC hsc_env)
2333
+ (interactiveInScope ( hsc_IC hsc_env) )
2354
2334
True
2355
2335
this_mod
2356
2336
iNTERACTIVELoc
@@ -2558,56 +2538,135 @@ hscCompileCoreExpr hsc_env loc expr =
2558
2538
Just h -> h hsc_env loc expr
2559
2539
2560
2540
hscCompileCoreExpr' :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue , [Linkable ], PkgsLoaded )
2561
- hscCompileCoreExpr' hsc_env srcspan ds_expr
2562
- = do { {- Simplify it -}
2563
- -- Question: should we call SimpleOpt.simpleOptExpr here instead?
2564
- -- It is, well, simpler, and does less inlining etc.
2565
- let dflags = hsc_dflags hsc_env
2566
- ; let logger = hsc_logger hsc_env
2567
- ; let ic = hsc_IC hsc_env
2568
- ; let unit_env = hsc_unit_env hsc_env
2569
- ; let simplify_expr_opts = initSimplifyExprOpts dflags ic
2570
- ; simpl_expr <- simplifyExpr logger (ue_eps unit_env) simplify_expr_opts ds_expr
2571
-
2572
- {- Tidy it (temporary, until coreSat does cloning) -}
2573
- ; let tidy_expr = tidyExpr emptyTidyEnv simpl_expr
2574
-
2575
- {- Prepare for codegen -}
2576
- ; cp_cfg <- initCorePrepConfig hsc_env
2577
- ; prepd_expr <- corePrepExpr
2578
- logger cp_cfg
2579
- tidy_expr
2580
-
2581
- {- Lint if necessary -}
2582
- ; lintInteractiveExpr (text " hscCompileExpr" ) hsc_env prepd_expr
2583
- ; let iNTERACTIVELoc = ModLocation { ml_hs_file = Nothing ,
2584
- ml_hi_file = panic " hscCompileCoreExpr':ml_hi_file" ,
2585
- ml_obj_file = panic " hscCompileCoreExpr':ml_obj_file" ,
2586
- ml_dyn_obj_file = panic " hscCompileCoreExpr': ml_obj_file" ,
2587
- ml_dyn_hi_file = panic " hscCompileCoreExpr': ml_dyn_hi_file" ,
2588
- ml_hie_file = panic " hscCompileCoreExpr':ml_hie_file" }
2589
-
2590
- ; let ictxt = hsc_IC hsc_env
2591
- ; (binding_id, stg_expr, _, _, _stg_cg_info) <-
2592
- myCoreToStgExpr logger
2593
- dflags
2594
- ictxt
2595
- True
2596
- (icInteractiveModule ictxt)
2597
- iNTERACTIVELoc
2598
- prepd_expr
2599
-
2600
- {- Convert to BCOs -}
2601
- ; bcos <- byteCodeGen hsc_env
2602
- (icInteractiveModule ictxt)
2603
- stg_expr
2604
- [] Nothing
2605
-
2606
- {- load it -}
2607
- ; (fv_hvs, mods_needed, units_needed) <- loadDecls (hscInterp hsc_env) hsc_env srcspan bcos
2608
- {- Get the HValue for the root -}
2609
- ; return (expectJust " hscCompileCoreExpr'"
2610
- $ lookup (idName binding_id) fv_hvs, mods_needed, units_needed) }
2541
+ hscCompileCoreExpr' hsc_env srcspan ds_expr = do
2542
+ {- Simplify it -}
2543
+ -- Question: should we call SimpleOpt.simpleOptExpr here instead?
2544
+ -- It is, well, simpler, and does less inlining etc.
2545
+ let dflags = hsc_dflags hsc_env
2546
+ let logger = hsc_logger hsc_env
2547
+ let ic = hsc_IC hsc_env
2548
+ let unit_env = hsc_unit_env hsc_env
2549
+ let simplify_expr_opts = initSimplifyExprOpts dflags ic
2550
+
2551
+ simpl_expr <- simplifyExpr logger (ue_eps unit_env) simplify_expr_opts ds_expr
2552
+
2553
+ -- Create a unique temporary binding
2554
+ --
2555
+ -- The id has to be exported for the JS backend. This isn't required for the
2556
+ -- byte-code interpreter but it does no harm to always do it.
2557
+ u <- uniqFromMask ' I'
2558
+ let binding_name = mkSystemVarName u (fsLit (" BCO_toplevel" ))
2559
+ let binding_id = mkExportedVanillaId binding_name (exprType simpl_expr)
2560
+
2561
+ {- Tidy it (temporary, until coreSat does cloning) -}
2562
+ let tidy_occ_env = initTidyOccEnv [occName binding_id]
2563
+ let tidy_env = mkEmptyTidyEnv tidy_occ_env
2564
+ let tidy_expr = tidyExpr tidy_env simpl_expr
2565
+
2566
+ {- Prepare for codegen -}
2567
+ cp_cfg <- initCorePrepConfig hsc_env
2568
+ prepd_expr <- corePrepExpr
2569
+ logger cp_cfg
2570
+ tidy_expr
2571
+
2572
+ {- Lint if necessary -}
2573
+ lintInteractiveExpr (text " hscCompileExpr" ) hsc_env prepd_expr
2574
+ let this_loc = ModLocation { ml_hs_file = Nothing ,
2575
+ ml_hi_file = panic " hscCompileCoreExpr':ml_hi_file" ,
2576
+ ml_obj_file = panic " hscCompileCoreExpr':ml_obj_file" ,
2577
+ ml_dyn_obj_file = panic " hscCompileCoreExpr': ml_obj_file" ,
2578
+ ml_dyn_hi_file = panic " hscCompileCoreExpr': ml_dyn_hi_file" ,
2579
+ ml_hie_file = panic " hscCompileCoreExpr':ml_hie_file" }
2580
+
2581
+ -- Ensure module uniqueness by giving it a name like "GhciNNNN".
2582
+ -- This uniqueness is needed by the JS linker. Without it we break the 1-1
2583
+ -- relationship between modules and object files, i.e. we get different object
2584
+ -- files for the same module and the JS linker doesn't support this.
2585
+ --
2586
+ -- Note that we can't use icInteractiveModule because the ic_mod_index value
2587
+ -- isn't bumped between invocations of hscCompileExpr, so uniqueness isn't
2588
+ -- guaranteed.
2589
+ --
2590
+ -- We reuse the unique we obtained for the binding, but any unique would do.
2591
+ let this_mod = mkInteractiveModule (getKey u)
2592
+ let for_bytecode = True
2593
+
2594
+ (stg_binds, _prov_map, _collected_ccs, _stg_cg_infos) <-
2595
+ myCoreToStg logger
2596
+ dflags
2597
+ (interactiveInScope (hsc_IC hsc_env))
2598
+ for_bytecode
2599
+ this_mod
2600
+ this_loc
2601
+ [NonRec binding_id prepd_expr]
2602
+
2603
+ let interp = hscInterp hsc_env
2604
+ let tmpfs = hsc_tmpfs hsc_env
2605
+ let tmp_dir = tmpDir dflags
2606
+
2607
+ case interp of
2608
+ -- always generate JS code for the JS interpreter (no bytecode!)
2609
+ Interp (ExternalInterp (ExtJS i)) _ ->
2610
+ jsCodeGen logger tmpfs tmp_dir unit_env (initStgToJSConfig dflags) interp i
2611
+ this_mod stg_binds binding_id
2612
+
2613
+ _ -> do
2614
+ {- Convert to BCOs -}
2615
+ bcos <- byteCodeGen hsc_env
2616
+ this_mod
2617
+ stg_binds
2618
+ [] Nothing
2619
+
2620
+ {- load it -}
2621
+ (fv_hvs, mods_needed, units_needed) <- loadDecls interp hsc_env srcspan bcos
2622
+ {- Get the HValue for the root -}
2623
+ return (expectJust " hscCompileCoreExpr'"
2624
+ $ lookup (idName binding_id) fv_hvs, mods_needed, units_needed)
2625
+
2626
+
2627
+
2628
+ -- | Generate JS code for the given bindings and return the HValue for the given id
2629
+ jsCodeGen
2630
+ :: Logger
2631
+ -> TmpFs
2632
+ -> TempDir
2633
+ -> UnitEnv
2634
+ -> StgToJSConfig
2635
+ -> Interp
2636
+ -> JSInterp
2637
+ -> Module
2638
+ -> [CgStgTopBinding ]
2639
+ -> Id
2640
+ -> IO (ForeignHValue , [Linkable ], PkgsLoaded )
2641
+ jsCodeGen logger tmpfs tmp_dir unit_env js_config interp i this_mod stg_binds binding_id = do
2642
+ let foreign_stubs = NoStubs
2643
+ spt_entries = mempty
2644
+ cost_centre_info = mempty
2645
+
2646
+ -- codegen into object file whose path is in out_obj
2647
+ out_obj <- newTempName logger tmpfs tmp_dir TFL_CurrentModule " o"
2648
+ stgToJS logger js_config stg_binds this_mod spt_entries foreign_stubs cost_centre_info out_obj
2649
+
2650
+ let TxtI id_sym = makeIdentForId binding_id Nothing IdPlain this_mod
2651
+ -- link code containing binding "id_sym = expr", using id_sym as root
2652
+ withJSInterp i $ \ inst -> do
2653
+ let roots = mkExportedModFuns this_mod [id_sym]
2654
+ jsLinkObject logger tmpfs tmp_dir js_config unit_env inst out_obj roots
2655
+
2656
+ -- look up "id_sym" closure and create a StablePtr (HValue) from it
2657
+ href <- lookupClosure interp (unpackFS id_sym) >>= \ case
2658
+ Nothing -> pprPanic " Couldn't find just linked TH closure" (ppr id_sym)
2659
+ Just r -> pure r
2660
+
2661
+ binding_fref <- withJSInterp i $ \ inst ->
2662
+ mkForeignRef href (freeReallyRemoteRef inst href)
2663
+
2664
+ -- FIXME (#23013): the JS linker doesn't use the LoaderState.
2665
+ -- The state is only maintained in the interpreter instance (jsLinkState field) for now.
2666
+ let linkables = mempty
2667
+ let loaded_pkgs = emptyUDFM
2668
+
2669
+ return (castForeignRef binding_fref, linkables, loaded_pkgs)
2611
2670
2612
2671
2613
2672
{- **********************************************************************
0 commit comments