[Git][ghc/ghc][master] 5 commits: rts: Refactor parsing of -h flags
by Marge Bot (@marge-bot) 26 Sep '25
by Marge Bot (@marge-bot) 26 Sep '25
26 Sep '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
d9e2a9a7 by mniip at 2025-09-26T16:00:50-04:00
rts: Refactor parsing of -h flags
We have a nontrivial amount of heap profiling flags available in the
non-profiled runtime, so it makes sense to reuse the parsing code
between the profiled and the non-profiled runtime, only restricting
which flags are allowed.
- - - - -
089e45aa by mniip at 2025-09-26T16:00:50-04:00
rts: Fix parsing of -h options with braces
When the "filter by" -h options were introduced in
bc210f7d267e8351ccb66972f4b3a650eb9338bb, the braces were mandatory.
Then in 3c22fb21fb18e27ce8d941069a6915fce584a526, the braces were made
optional. Then in d1ce35d2271ac8b79cb5e37677b1a989749e611c the brace
syntax stopped working, and no one seems to have noticed.
- - - - -
423f1472 by mniip at 2025-09-26T16:00:50-04:00
rts: add -hT<type> and -hi<table id> heap filtering options (#26361)
They are available in non-profiled builds.
Along the way fixed a bug where combining -he<era> and -hr<retainer>
would ignore whether the retainer matches or not.
- - - - -
4cda4785 by mniip at 2025-09-26T16:00:50-04:00
docs: Document -hT<type> and -hi<addr>
- - - - -
982ad30f by mniip at 2025-09-26T16:00:50-04:00
rts: Refactor dumping the heap census
Always do the printing of the total size right next to where the bucket
label is printed. This prevents accidentally printing a label without
the corresponding amount.
Fixed a bug where exactly this happened for -hi profile and the 0x0
(uncategorized) info table.
There is now also much more symmetry between fprintf(hp_file,...) and
the corresponding traceHeapProfSampleString.
- - - - -
8 changed files:
- docs/users_guide/profiling.rst
- libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc
- rts/ProfHeap.c
- rts/RetainerSet.c
- rts/RtsFlags.c
- rts/include/rts/Flags.h
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
Changes:
=====================================
docs/users_guide/profiling.rst
=====================================
@@ -1003,6 +1003,11 @@ follows:
The flags below are marked with ``:noindex:`` to avoid duplicate
ID warnings from Sphinx.
+.. rts-flag:: -hT ⟨type⟩
+ :noindex:
+
+ Restrict the profile to closures with the specified closure types.
+
.. rts-flag:: -hc ⟨name⟩
:noindex:
@@ -1050,6 +1055,13 @@ follows:
biographies, where ⟨bio⟩ is one of ``lag``, ``drag``, ``void``, or
``use``.
+.. rts-flag:: -hi ⟨addr⟩
+ :noindex:
+
+ Restrict the profile to closures with specified info table addresses. The
+ address should start with ``0x`` and be lowercase hexadecimal, just like the
+ addresses produced by :rts-flag:`-hi`.
+
For example, the following options will generate a retainer profile
restricted to ``Branch`` and ``Leaf`` constructors:
=====================================
libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc
=====================================
@@ -312,6 +312,8 @@ data ProfFlags = ProfFlags
, retainerSelector :: Maybe String
, bioSelector :: Maybe String
, eraSelector :: Word -- ^ @since base-4.20.0.0
+ , closureTypeSelector :: Maybe String
+ , infoTableSelector :: Maybe String
} deriving ( Show -- ^ @since base-4.8.0.0
, Generic -- ^ @since base-4.15.0.0
)
@@ -613,6 +615,8 @@ getProfFlags = do
<*> (peekCStringOpt =<< #{peek PROFILING_FLAGS, retainerSelector} ptr)
<*> (peekCStringOpt =<< #{peek PROFILING_FLAGS, bioSelector} ptr)
<*> #{peek PROFILING_FLAGS, eraSelector} ptr
+ <*> (peekCStringOpt =<< #{peek PROFILING_FLAGS, closureTypeSelector} ptr)
+ <*> (peekCStringOpt =<< #{peek PROFILING_FLAGS, infoTableSelector} ptr)
getTraceFlags :: IO TraceFlags
getTraceFlags = do
=====================================
rts/ProfHeap.c
=====================================
@@ -181,6 +181,28 @@ static void dumpCensus( Census *census );
static bool closureSatisfiesConstraints( const StgClosure* p );
+static const char *closureTypeIdentity( const StgClosure *p )
+{
+ const StgInfoTable *info = get_itbl(p);
+ switch (info->type) {
+ case CONSTR:
+ case CONSTR_1_0:
+ case CONSTR_0_1:
+ case CONSTR_2_0:
+ case CONSTR_1_1:
+ case CONSTR_0_2:
+ case CONSTR_NOCAF:
+ return GET_CON_DESC(itbl_to_con_itbl(info));
+ default:
+ return closure_type_names[info->type];
+ }
+}
+
+static void formatIPELabel( char *str, size_t size, uint64_t table_id )
+{
+ snprintf(str, size, "0x%" PRIx64, table_id);
+}
+
/* ----------------------------------------------------------------------------
* Find the "closure identity", which is a unique pointer representing
* the band to which this closure's heap space is attributed in the
@@ -215,26 +237,9 @@ closureIdentity( const StgClosure *p )
#endif
case HEAP_BY_CLOSURE_TYPE:
- {
- const StgInfoTable *info;
- info = get_itbl(p);
- switch (info->type) {
- case CONSTR:
- case CONSTR_1_0:
- case CONSTR_0_1:
- case CONSTR_2_0:
- case CONSTR_1_1:
- case CONSTR_0_2:
- case CONSTR_NOCAF:
- return GET_CON_DESC(itbl_to_con_itbl(info));
- default:
- return closure_type_names[info->type];
- }
- }
+ return closureTypeIdentity(p);
case HEAP_BY_INFO_TABLE:
- {
return (void *) (p->header.info);
- }
default:
barf("closureIdentity");
@@ -664,6 +669,8 @@ fprint_ccs(FILE *fp, CostCentreStack *ccs, uint32_t max_length)
fprintf(fp, "%s", buf);
}
+#endif /* PROFILING */
+
bool
strMatchesSelector( const char* str, const char* sel )
{
@@ -688,8 +695,6 @@ strMatchesSelector( const char* str, const char* sel )
}
}
-#endif /* PROFILING */
-
/* -----------------------------------------------------------------------------
* Figure out whether a closure should be counted in this census, by
* testing against all the specified constraints.
@@ -697,11 +702,8 @@ strMatchesSelector( const char* str, const char* sel )
static bool
closureSatisfiesConstraints( const StgClosure* p )
{
-#if !defined(PROFILING)
- (void)p; /* keep gcc -Wall happy */
- return true;
-#else
- bool b;
+ bool b;
+#if defined(PROFILING)
// The CCS has a selected field to indicate whether this closure is
// deselected by not being mentioned in the module, CC, or CCS
@@ -721,7 +723,8 @@ closureSatisfiesConstraints( const StgClosure* p )
if (!b) return false;
}
if (RtsFlags.ProfFlags.eraSelector) {
- return (p->header.prof.hp.era == RtsFlags.ProfFlags.eraSelector);
+ b = p->header.prof.hp.era == RtsFlags.ProfFlags.eraSelector;
+ if (!b) return false;
}
if (RtsFlags.ProfFlags.retainerSelector) {
RetainerSet *rs;
@@ -742,8 +745,21 @@ closureSatisfiesConstraints( const StgClosure* p )
}
return false;
}
- return true;
+#else
+ if (RtsFlags.ProfFlags.closureTypeSelector) {
+ b = strMatchesSelector( closureTypeIdentity(p),
+ RtsFlags.ProfFlags.closureTypeSelector );
+ if (!b) return false;
+ }
+ if (RtsFlags.ProfFlags.infoTableSelector) {
+ char str[100];
+ formatIPELabel(str, sizeof str, lookupIPEId(p->header.info));
+ b = strMatchesSelector( str,
+ RtsFlags.ProfFlags.infoTableSelector );
+ if (!b) return false;
+ }
#endif /* PROFILING */
+ return true;
}
/* -----------------------------------------------------------------------------
@@ -858,12 +874,11 @@ aggregateCensusInfo( void )
static void
recordIPEHeapSample(FILE *hp_file, uint64_t table_id, size_t count)
{
- // Print to heap profile file
- fprintf(hp_file, "0x%" PRIx64, table_id);
-
- // Create label string for tracing
char str[100];
- sprintf(str, "0x%" PRIx64, table_id);
+ formatIPELabel(str, sizeof str, table_id);
+
+ // Print to heap profile file
+ fprintf(hp_file, "%s\t%" FMT_Word "\n", str, (W_)(count * sizeof(W_)));
// Emit the profiling sample (convert count to bytes)
traceHeapProfSampleString(str, count * sizeof(W_));
@@ -961,7 +976,9 @@ dumpCensus( Census *census )
switch (RtsFlags.ProfFlags.doHeapProfile) {
case HEAP_BY_CLOSURE_TYPE:
- fprintf(hp_file, "%s", (char *)ctr->identity);
+ fprintf(hp_file, "%s\t%" FMT_Word "\n",
+ (char *)ctr->identity,
+ (W_)(count * sizeof(W_)));
traceHeapProfSampleString((char *)ctr->identity,
count * sizeof(W_));
break;
@@ -979,19 +996,26 @@ dumpCensus( Census *census )
case HEAP_BY_CCS:
fprint_ccs(hp_file, (CostCentreStack *)ctr->identity,
RtsFlags.ProfFlags.ccsLength);
+ fprintf(hp_file, "\t%" FMT_Word "\n",
+ (W_)(count * sizeof(W_)));
traceHeapProfSampleCostCentre((CostCentreStack *)ctr->identity,
count * sizeof(W_));
break;
case HEAP_BY_ERA:
- fprintf(hp_file, "%" FMT_Word, (StgWord)ctr->identity);
+ {
char str_era[100];
- sprintf(str_era, "%" FMT_Word, (StgWord)ctr->identity);
+ snprintf(str_era, sizeof str_era, "%" FMT_Word,
+ (StgWord)ctr->identity);
+ fprintf(hp_file, "%s\t%" FMT_Word "\n",
+ str_era, (W_)(count * sizeof(W_)));
traceHeapProfSampleString(str_era, count * sizeof(W_));
break;
+ }
case HEAP_BY_MOD:
case HEAP_BY_DESCR:
case HEAP_BY_TYPE:
- fprintf(hp_file, "%s", (char *)ctr->identity);
+ fprintf(hp_file, "%s\t%" FMT_Word "\n",
+ (char *)ctr->identity, (W_)(count * sizeof(W_)));
traceHeapProfSampleString((char *)ctr->identity,
count * sizeof(W_));
break;
@@ -1002,29 +1026,28 @@ dumpCensus( Census *census )
// it might be the distinguished retainer set rs_MANY:
if (rs == &rs_MANY) {
fprintf(hp_file, "MANY");
- break;
- }
+ } else {
- // Mark this retainer set by negating its id, because it
- // has appeared in at least one census. We print the
- // values of all such retainer sets into the log file at
- // the end. A retainer set may exist but not feature in
- // any censuses if it arose as the intermediate retainer
- // set for some closure during retainer set calculation.
- if (rs->id > 0)
- rs->id = -(rs->id);
-
- // report in the unit of bytes: * sizeof(StgWord)
- printRetainerSetShort(hp_file, rs, (W_)count * sizeof(W_)
- , RtsFlags.ProfFlags.ccsLength);
+ // Mark this retainer set by negating its id, because it
+ // has appeared in at least one census. We print the
+ // values of all such retainer sets into the log file at
+ // the end. A retainer set may exist but not feature in
+ // any censuses if it arose as the intermediate retainer
+ // set for some closure during retainer set calculation.
+ if (rs->id > 0)
+ rs->id = -(rs->id);
+
+ // report in the unit of bytes: * sizeof(StgWord)
+ printRetainerSetShort(hp_file, rs, (W_)(count * sizeof(W_))
+ , RtsFlags.ProfFlags.ccsLength);
+ }
+ fprintf(hp_file, "\t%" FMT_Word "\n", (W_)(count * sizeof(W_)));
break;
}
#endif
default:
barf("dumpCensus; doHeapProfile");
}
-
- fprintf(hp_file, "\t%" FMT_Word "\n", (W_)count * sizeof(W_));
}
// Print the unallocated data into the 0 band for info table profiling.
=====================================
rts/RetainerSet.c
=====================================
@@ -237,7 +237,7 @@ printRetainerSetShort(FILE *f, RetainerSet *rs, W_ total_size, uint32_t max_leng
// size = strlen(tmp);
}
}
- fputs(tmp, f);
+ fprintf(f, "%s\t%" FMT_Word "\n", tmp, total_size);
traceHeapProfSampleString(tmp, total_size);
}
=====================================
rts/RtsFlags.c
=====================================
@@ -112,9 +112,7 @@ static void bad_option (const char *s);
static void read_debug_flags(const char *arg);
#endif
-#if defined(PROFILING)
static bool read_heap_profiling_flag(const char *arg);
-#endif
#if defined(TRACING)
static void read_trace_flags(const char *arg);
@@ -237,6 +235,9 @@ void initRtsFlagsDefaults(void)
RtsFlags.ProfFlags.eraSelector = 0;
#endif
+ RtsFlags.ProfFlags.closureTypeSelector = NULL;
+ RtsFlags.ProfFlags.infoTableSelector = NULL;
+
#if defined(TRACING)
RtsFlags.TraceFlags.tracing = TRACE_NONE;
RtsFlags.TraceFlags.timestamp = false;
@@ -403,6 +404,8 @@ usage_text[] = {
" -hr<cc>... closures with specified retainers",
" -hb<bio>... closures with specified biographies (lag,drag,void,use)",
" -he<era>... closures with specified era",
+" -hT<typ>,... specified closure types",
+" -hi<adr>,... closures with specified info table addresses",
"",
" -R<size> Set the maximum retainer set size (default: 8)",
"",
@@ -418,6 +421,9 @@ usage_text[] = {
" -h Heap residency profile (output file <program>.hp)",
" -hT Produce a heap profile grouped by closure type",
" -hi Produce a heap profile grouped by info table address",
+" A subset of closures may be selected thusly:",
+" -hT<typ>,... specified closure types",
+" -hi<adr>,... closures with specified info table addresses",
" -po<file> Override profiling output file name prefix (program name by default)",
#endif /* PROFILING */
@@ -924,11 +930,10 @@ error = true;
#endif
#if defined(PROFILING)
-# define PROFILING_BUILD_ONLY(x) x
+# define PROFILING_BUILD_ONLY(_arg, x) x
#else
-# define PROFILING_BUILD_ONLY(x) \
-errorBelch("the flag %s requires the program to be built with -prof", \
- rts_argv[arg]); \
+# define PROFILING_BUILD_ONLY(arg, x) \
+errorBelch("the flag %s requires the program to be built with -prof", arg); \
error = true;
#endif
@@ -1485,11 +1490,11 @@ error = true;
RtsFlags.CcFlags.outputFileNameStem = rts_argv[arg]+3;
break;
default:
- PROFILING_BUILD_ONLY();
+ PROFILING_BUILD_ONLY(rts_argv[arg],);
} break;
#else
- PROFILING_BUILD_ONLY(
+ PROFILING_BUILD_ONLY(rts_argv[arg],
switch (rts_argv[arg][2]) {
case 'a':
RtsFlags.CcFlags.doCostCentres = COST_CENTRES_ALL;
@@ -1527,43 +1532,25 @@ error = true;
case 'R':
OPTION_SAFE;
- PROFILING_BUILD_ONLY(
+ PROFILING_BUILD_ONLY(rts_argv[arg],
RtsFlags.ProfFlags.maxRetainerSetSize =
atof(rts_argv[arg]+2);
) break;
case 'L':
OPTION_SAFE;
- PROFILING_BUILD_ONLY(
+ PROFILING_BUILD_ONLY(rts_argv[arg],
RtsFlags.ProfFlags.ccsLength = atof(rts_argv[arg]+2);
if(RtsFlags.ProfFlags.ccsLength <= 0) {
bad_option(rts_argv[arg]);
}
) break;
case 'h': /* serial heap profile */
-#if !defined(PROFILING)
- switch (rts_argv[arg][2]) {
- case '\0':
- errorBelch("-h is deprecated, use -hT instead.");
-
- FALLTHROUGH;
- case 'T':
- OPTION_UNSAFE;
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE;
- break;
- case 'i':
- OPTION_UNSAFE;
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_INFO_TABLE;
- break;
- default:
- OPTION_SAFE;
- PROFILING_BUILD_ONLY();
- }
-#else
+#if defined(PROFILING)
OPTION_SAFE;
- PROFILING_BUILD_ONLY(
- error = read_heap_profiling_flag(rts_argv[arg]);
- );
-#endif /* PROFILING */
+#else
+ OPTION_UNSAFE;
+#endif
+ error = read_heap_profiling_flag(rts_argv[arg]);
break;
case 'i': /* heap sample interval */
@@ -1840,7 +1827,7 @@ error = true;
case 'c': /* Debugging tool: show current cost centre on
an exception */
OPTION_SAFE;
- PROFILING_BUILD_ONLY(
+ PROFILING_BUILD_ONLY(rts_argv[arg],
RtsFlags.ProfFlags.showCCSOnException = true;
);
unchecked_arg_start++;
@@ -2341,139 +2328,171 @@ static void read_debug_flags(const char* arg)
}
#endif
-#if defined(PROFILING)
// Parse a "-h" flag, returning whether the parse resulted in an error.
static bool read_heap_profiling_flag(const char *arg)
{
- // Already parsed "-h"
-
+ // Already parsed arg[0:2] = "-h"
bool error = false;
- switch (arg[2]) {
- case '\0':
- errorBelch("-h is deprecated, use -hc instead.");
- FALLTHROUGH;
- case 'C':
- case 'c':
- case 'M':
- case 'm':
- case 'D':
- case 'd':
- case 'Y':
- case 'y':
- case 'i':
- case 'R':
- case 'r':
- case 'B':
- case 'b':
- case 'e':
- case 'T':
- if (arg[2] != '\0' && arg[3] != '\0') {
- {
- const char *left = strchr(arg, '{');
- const char *right = strrchr(arg, '}');
-
- // curly braces are optional, for
- // backwards compat.
- if (left)
- left = left+1;
- else
- left = arg + 3;
-
- if (!right)
- right = arg + strlen(arg);
-
- char *selector = stgStrndup(left, right - left + 1);
-
- switch (arg[2]) {
- case 'c': // cost centre label select
- RtsFlags.ProfFlags.ccSelector = selector;
- break;
- case 'C':
- RtsFlags.ProfFlags.ccsSelector = selector;
- break;
- case 'M':
- case 'm': // cost centre module select
- RtsFlags.ProfFlags.modSelector = selector;
- break;
- case 'D':
- case 'd': // closure descr select
- RtsFlags.ProfFlags.descrSelector = selector;
- break;
- case 'Y':
- case 'y': // closure type select
- RtsFlags.ProfFlags.typeSelector = selector;
- break;
- case 'R':
- case 'r': // retainer select
- RtsFlags.ProfFlags.retainerSelector = selector;
- break;
- case 'B':
- case 'b': // biography select
- RtsFlags.ProfFlags.bioSelector = selector;
- break;
- case 'E':
- case 'e': // era select
- RtsFlags.ProfFlags.eraSelector = strtoul(selector, (char **) NULL, 10);
- break;
- default:
- stgFree(selector);
- }
- }
- break;
- }
+ char property;
+ const char *filter;
+ if (arg[2] != '\0') {
+ property = arg[2];
+ filter = arg + 3;
+ } else {
+#if defined(PROFILING)
+ errorBelch("-h is deprecated, use -hc instead.");
+ property = 'c';
+ filter = arg + 2;
+#else
+ errorBelch("-h is deprecated, use -hT instead.");
+ property = 'T';
+ filter = arg + 2;
+#endif
+ }
+ // here property is initialized, and filter is a pointer inside arg
- if (RtsFlags.ProfFlags.doHeapProfile != 0) {
- errorBelch("multiple heap profile options");
- error = true;
- break;
- }
+ if (filter[0] != '\0') {
+ // For backwards compat, extract the portion between curly braces, else
+ // use the entire string
+ const char *left = strchr(filter, '{');
+ const char *right = strrchr(filter, '}');
- switch (arg[2]) {
- case '\0':
+ if (left)
+ left = left + 1;
+ else
+ left = filter;
+
+ if (!right)
+ right = filter + strlen(filter);
+
+ char *selector = stgStrndup(left, right - left);
+ switch (property) {
+#if defined(PROFILING)
+ case 'c': // cost centre label select
+ RtsFlags.ProfFlags.ccSelector = selector;
+ break;
case 'C':
- case 'c':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CCS;
+ RtsFlags.ProfFlags.ccsSelector = selector;
break;
case 'M':
- case 'm':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_MOD;
+ case 'm': // cost centre module select
+ RtsFlags.ProfFlags.modSelector = selector;
break;
case 'D':
- case 'd':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_DESCR;
+ case 'd': // closure descr select
+ RtsFlags.ProfFlags.descrSelector = selector;
break;
case 'Y':
- case 'y':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_TYPE;
+ case 'y': // closure type select
+ RtsFlags.ProfFlags.typeSelector = selector;
break;
- case 'i':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_INFO_TABLE;
+ case 'R':
+ case 'r': // retainer select
+ RtsFlags.ProfFlags.retainerSelector = selector;
break;
+ case 'B':
+ case 'b': // biography select
+ RtsFlags.ProfFlags.bioSelector = selector;
+ break;
+ case 'E':
+ case 'e': // era select
+ RtsFlags.ProfFlags.eraSelector = strtoul(selector, (char **) NULL, 10);
+ break;
+#else
+ case 'c':
+ case 'C':
+ case 'M':
+ case 'm':
+ case 'D':
+ case 'd':
+ case 'Y':
+ case 'y':
case 'R':
case 'r':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_RETAINER;
- break;
case 'B':
case 'b':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_LDV;
+ case 'E':
+ case 'e':
+ PROFILING_BUILD_ONLY(arg,);
break;
- case 'T':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE;
+ case 'T': /* closure type select */
+ RtsFlags.ProfFlags.closureTypeSelector = selector;
break;
- case 'e':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_ERA;
+ case 'i': /* info table select */
+ RtsFlags.ProfFlags.infoTableSelector = selector;
break;
- }
- break;
- default:
- errorBelch("invalid heap profile option: %s", arg);
- error = true;
+#endif /* PROFILING */
+ default:
+ stgFree(selector);
+ }
+ } else {
+ if (RtsFlags.ProfFlags.doHeapProfile != 0) {
+ errorBelch("multiple heap profile options");
+ error = true;
+ } else {
+ switch (property) {
+#if defined(PROFILING)
+ case 'C':
+ case 'c':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CCS;
+ break;
+ case 'M':
+ case 'm':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_MOD;
+ break;
+ case 'D':
+ case 'd':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_DESCR;
+ break;
+ case 'Y':
+ case 'y':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_TYPE;
+ break;
+ case 'R':
+ case 'r':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_RETAINER;
+ break;
+ case 'B':
+ case 'b':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_LDV;
+ break;
+ case 'e':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_ERA;
+ break;
+#else
+ case 'C':
+ case 'c':
+ case 'M':
+ case 'm':
+ case 'D':
+ case 'd':
+ case 'Y':
+ case 'y':
+ case 'R':
+ case 'r':
+ case 'B':
+ case 'b':
+ case 'e':
+ PROFILING_BUILD_ONLY(arg,);
+ break;
+#endif /* PROFILING*/
+ case 'T':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE;
+ break;
+ case 'i':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_INFO_TABLE;
+ break;
+ default:
+ errorBelch("invalid heap profile option: %s", arg);
+ error = true;
+ break;
+ }
+ }
}
return error;
}
-#endif
#if defined(TRACING)
static void read_trace_flags(const char *arg)
=====================================
rts/include/rts/Flags.h
=====================================
@@ -170,6 +170,8 @@ typedef struct _PROFILING_FLAGS {
const char* retainerSelector;
StgWord eraSelector;
const char* bioSelector;
+ const char* closureTypeSelector;
+ const char* infoTableSelector;
} PROFILING_FLAGS;
=====================================
testsuite/tests/interface-stability/ghc-experimental-exports.stdout
=====================================
@@ -6363,7 +6363,9 @@ module GHC.RTS.Flags.Experimental where
ccsSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
retainerSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
bioSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
- eraSelector :: GHC.Internal.Types.Word}
+ eraSelector :: GHC.Internal.Types.Word,
+ closureTypeSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
+ infoTableSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String}
type RTSFlags :: *
data RTSFlags = RTSFlags {gcFlags :: GCFlags, concurrentFlags :: ConcFlags, miscFlags :: MiscFlags, debugFlags :: DebugFlags, costCentreFlags :: CCFlags, profilingFlags :: ProfFlags, traceFlags :: TraceFlags, tickyFlags :: TickyFlags, parFlags :: ParFlags, hpcFlags :: HpcFlags}
type RtsTime :: *
=====================================
testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
=====================================
@@ -6366,7 +6366,9 @@ module GHC.RTS.Flags.Experimental where
ccsSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
retainerSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
bioSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
- eraSelector :: GHC.Internal.Types.Word}
+ eraSelector :: GHC.Internal.Types.Word,
+ closureTypeSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
+ infoTableSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String}
type RTSFlags :: *
data RTSFlags = RTSFlags {gcFlags :: GCFlags, concurrentFlags :: ConcFlags, miscFlags :: MiscFlags, debugFlags :: DebugFlags, costCentreFlags :: CCFlags, profilingFlags :: ProfFlags, traceFlags :: TraceFlags, tickyFlags :: TickyFlags, parFlags :: ParFlags, hpcFlags :: HpcFlags}
type RtsTime :: *
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b10296a90794d7182ec0c73b053c77…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b10296a90794d7182ec0c73b053c77…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26166] 2 commits: rts: Dynamically initialize built-in closures
by Ben Gamari (@bgamari) 26 Sep '25
by Ben Gamari (@bgamari) 26 Sep '25
26 Sep '25
Ben Gamari pushed to branch wip/T26166 at Glasgow Haskell Compiler / GHC
Commits:
b34aadda by Ben Gamari at 2025-09-26T15:23:16-04:00
rts: Dynamically initialize built-in closures
To resolve #26166 we need to eliminate references to undefined symbols
in the runtime system. One such source of these is the runtime's
static references to `I#` and `C#` due the `stg_INTLIKE` and
`stg_CHARLIKE` arrays.
To avoid this we make these dynamic, initializing them during RTS
start-up.
- - - - -
b4e79714 by Ben Gamari at 2025-09-26T15:23:49-04:00
rts: Avoid static symbol references to ghc-internal
This is the first step towards resolving #26166, a bug due to new
constraints placed by Apple's linker on undefined references.
One source of such references in the RTS is the many symbols referenced
in ghc-internal. To mitigate #26166, we make these references dynamic,
as described in Note [RTS/ghc-internal interface].
- - - - -
26 changed files:
- compiler/GHC/HsToCore/Foreign/C.hs
- + libraries/ghc-internal/cbits/RtsIface.c
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/include/RtsIfaceSymbols.h
- + rts/BuiltinClosures.c
- + rts/BuiltinClosures.h
- rts/Compact.cmm
- rts/ContinuationOps.cmm
- rts/Exception.cmm
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/RtsAPI.c
- rts/RtsStartup.c
- + rts/RtsToHsIface.c
- rts/Schedule.c
- rts/StgMiscClosures.cmm
- rts/StgStdThunks.cmm
- rts/include/Rts.h
- rts/include/RtsAPI.h
- rts/include/rts/Constants.h
- + rts/include/rts/RtsToHsIface.h
- rts/include/stg/MiscClosures.h
- rts/posix/Signals.c
- rts/rts.cabal
- rts/wasm/JSFFI.c
- utils/deriveConstants/Main.hs
Changes:
=====================================
compiler/GHC/HsToCore/Foreign/C.hs
=====================================
@@ -517,8 +517,8 @@ mkFExportCBits dflags c_nm maybe_target arg_htys res_hty is_IO_res_ty cc
text "rts_apply" <> parens (
cap
<> (if is_IO_res_ty
- then text "runIO_closure"
- else text "runNonIO_closure")
+ then text "ghc_hs_iface->runIO_closure"
+ else text "ghc_hs_iface->runNonIO_closure")
<> comma
<> expr_to_run
) <+> comma
=====================================
libraries/ghc-internal/cbits/RtsIface.c
=====================================
@@ -0,0 +1,51 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+#include "Rts.h"
+
+void init_ghc_hs_iface(void) __attribute__((constructor));
+
+// Forward declarations
+#define CLOSURE(module, symbol) \
+ extern StgClosure ghczminternal_##module##_##symbol;
+
+#define UNDEF_CLOSURE(module, symbol)
+
+#define INFO_TBL(module, symbol) \
+ extern StgInfoTable ghczminternal_##module##_##symbol;
+
+#include "RtsIfaceSymbols.h"
+
+#undef CLOSURE
+#undef INFO_TBL
+
+// HsIface definition
+#define CLOSURE(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+#define UNDEF_CLOSURE(module, symbol) \
+ .symbol = NULL,
+
+#define INFO_TBL(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+HsIface the_ghc_hs_iface = {
+#include "RtsIfaceSymbols.h"
+};
+
+void init_ghc_hs_iface(void)
+{
+ /*
+ * N.B. ghc-internal may be load multiple times, e.g., when the
+ * RTS linker is in use. For this reason we explicitly refuse to
+ * override ghc_hs_iface if it has already been initialized.
+ */
+ if (ghc_hs_iface == NULL) {
+ ghc_hs_iface = &the_ghc_hs_iface;
+ }
+}
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -43,6 +43,7 @@ extra-source-files:
include/winio_structs.h
include/WordSize.h
include/HsIntegerGmp.h.in
+ include/RtsIfaceSymbols.h
install-sh
source-repository head
@@ -431,6 +432,8 @@ Library
if !arch(javascript)
+ -- See Note [RTS/ghc-internal interface].
+ ld-options: -uinit_ghc_hs_iface
c-sources:
cbits/DarwinUtils.c
cbits/PrelIOUtils.c
@@ -457,6 +460,7 @@ Library
cbits/vectorQuotRem.c
cbits/word2float.c
cbits/Stack_c.c
+ cbits/RtsIface.c
cmm-sources:
cbits/StackCloningDecoding.cmm
=====================================
libraries/ghc-internal/include/RtsIfaceSymbols.h
=====================================
@@ -0,0 +1,59 @@
+// See Note [RTS/ghc-internal interface].
+
+#if defined(mingw32_HOST_OS)
+CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#else
+UNDEF_CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#endif
+CLOSURE(GHCziInternalziTopHandler, runIO_closure)
+CLOSURE(GHCziInternalziTopHandler, runNonIO_closure)
+CLOSURE(GHCziInternalziTuple, Z0T_closure)
+CLOSURE(GHCziInternalziTypes, True_closure)
+CLOSURE(GHCziInternalziTypes, False_closure)
+CLOSURE(GHCziInternalziPack, unpackCString_closure)
+CLOSURE(GHCziInternalziWeakziFinalizze, runFinalizzerBatch_closure)
+CLOSURE(GHCziInternalziIOziException, stackOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, heapOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, allocationLimitExceeded_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnMVar_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnSTM_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactFunction_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactPinned_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactMutable_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nonTermination_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nestedAtomically_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, noMatchingContinuationPrompt_closure)
+CLOSURE(GHCziInternalziEventziThread, blockedOnBadFD_closure)
+CLOSURE(GHCziInternalziConcziSync, runSparks_closure)
+CLOSURE(GHCziInternalziConcziIO, ensureIOManagerIsRunning_closure)
+CLOSURE(GHCziInternalziConcziIO, interruptIOManager_closure)
+CLOSURE(GHCziInternalziConcziIO, ioManagerCapabilitiesChanged_closure)
+CLOSURE(GHCziInternalziConcziSignal, runHandlersPtr_closure)
+CLOSURE(GHCziInternalziTopHandler, flushStdHandles_closure)
+CLOSURE(GHCziInternalziTopHandler, runMainIO_closure)
+INFO_TBL(GHCziInternalziTypes, Czh_con_info)
+INFO_TBL(GHCziInternalziTypes, Izh_con_info)
+INFO_TBL(GHCziInternalziTypes, Fzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Dzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Wzh_con_info)
+CLOSURE(GHCziInternalziPrimziPanic, absentSumFieldError_closure)
+CLOSURE(GHCziInternalziAllocationLimitHandler, runAllocationLimitHandler_closure)
+INFO_TBL(GHCziInternalziPtr, Ptr_con_info)
+INFO_TBL(GHCziInternalziPtr, FunPtr_con_info)
+INFO_TBL(GHCziInternalziInt, I8zh_con_info)
+INFO_TBL(GHCziInternalziInt, I16zh_con_info)
+INFO_TBL(GHCziInternalziInt, I32zh_con_info)
+INFO_TBL(GHCziInternalziInt, I64zh_con_info)
+INFO_TBL(GHCziInternalziWord, W8zh_con_info)
+INFO_TBL(GHCziInternalziWord, W16zh_con_info)
+INFO_TBL(GHCziInternalziWord, W32zh_con_info)
+INFO_TBL(GHCziInternalziWord, W64zh_con_info)
+INFO_TBL(GHCziInternalziStable, StablePtr_con_info)
+CLOSURE(GHCziInternalziStackziCloneStack, StackSnapshot_closure)
+CLOSURE(GHCziInternalziExceptionziType, divZZeroException_closure)
+CLOSURE(GHCziInternalziExceptionziType, underflowException_closure)
+CLOSURE(GHCziInternalziExceptionziType, overflowException_closure)
+CLOSURE(GHCziInternalziCString, unpackCStringzh_closure)
+INFO_TBL(GHCziInternalziCString, unpackCStringzh_info)
+INFO_TBL(GHCziInternalziCString, unpackCStringUtf8zh_info)
+
=====================================
rts/BuiltinClosures.c
=====================================
@@ -0,0 +1,29 @@
+#include "Rts.h"
+#include "BuiltinClosures.h"
+
+/*
+ * Note [CHARLIKE and INTLIKE closures]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * These are static representations of Chars and small Ints, so that
+ * we can remove dynamic Chars and Ints during garbage collection and
+ * replace them with references to the static objects.
+ */
+
+StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
+StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+
+void initBuiltinClosures() {
+ // INTLIKE closures
+ for (int i = MIN_INTLIKE; i <= MAX_INTLIKE - MIN_INTLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_INTLIKE_closure[i];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Izh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = MIN_INTLIKE + i;
+ }
+
+ // CHARLIKE closures
+ for (int i = MIN_CHARLIKE; i <= MAX_CHARLIKE - MIN_CHARLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_CHARLIKE_closure[i];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Czh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = MIN_CHARLIKE + i;
+ }
+}
=====================================
rts/BuiltinClosures.h
=====================================
@@ -0,0 +1,14 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ */
+
+#pragma once
+
+#include "BeginPrivate.h"
+
+void initBuiltinClosures(void);
+
+#include "EndPrivate.h"
=====================================
rts/Compact.cmm
=====================================
@@ -10,9 +10,6 @@
#include "Cmm.h"
#include "sm/ShouldCompact.h"
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE g0;
import CLOSURE large_alloc_lim;
@@ -124,7 +121,7 @@ eval:
SMALL_MUT_ARR_PTRS_CLEAN,
SMALL_MUT_ARR_PTRS_DIRTY,
COMPACT_NFDATA: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
+ jump stg_raisezh(HsIface_cannotCompactMutable_closure(W_[ghc_hs_iface]));
}
// We shouldn't see any functions, if this data structure was NFData.
@@ -139,7 +136,7 @@ eval:
BCO,
PAP,
CONTINUATION: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
+ jump stg_raisezh(HsIface_cannotCompactFunction_closure(W_[ghc_hs_iface]));
}
case ARR_WORDS: {
@@ -147,7 +144,7 @@ eval:
(should) = ccall shouldCompact(compact "ptr", p "ptr");
if (should == SHOULDCOMPACT_IN_CNF) { P_[pp] = p; return(); }
if (should == SHOULDCOMPACT_PINNED) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
+ jump stg_raisezh(HsIface_cannotCompactPinned_closure(W_[ghc_hs_iface]));
}
CHECK_HASH();
=====================================
rts/ContinuationOps.cmm
=====================================
@@ -12,7 +12,6 @@
#include "Cmm.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE ALLOC_RTS_ctr;
import CLOSURE ALLOC_RTS_tot;
@@ -104,7 +103,7 @@ stg_control0zh_ll // explicit stack
// see Note [When capturing the continuation fails] in Continuation.c
if (cont == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure);
+ jump stg_raisezh(HsIface_noMatchingContinuationPrompt_closure(W_[ghc_hs_iface]));
}
W_ apply_mask_frame;
=====================================
rts/Exception.cmm
=====================================
@@ -13,10 +13,6 @@
#include "Cmm.h"
#include "RaiseAsync.h"
-import CLOSURE ghczminternal_GHCziInternalziTypes_True_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_underflowException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_overflowException_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE CATCHF_PUSHED_ctr;
import CLOSURE RtsFlags;
@@ -539,7 +535,7 @@ retry_pop_stack:
Sp(10) = exception;
Sp(9) = stg_raise_ret_info;
Sp(8) = exception;
- Sp(7) = ghczminternal_GHCziInternalziTypes_True_closure; // True <=> an exception
+ Sp(7) = HsIface_True_closure(W_[ghc_hs_iface]); // True <=> an exception
Sp(6) = stg_ap_ppv_info;
Sp(5) = 0;
Sp(4) = stg_ap_n_info;
@@ -650,17 +646,17 @@ stg_raiseIOzh (P_ exception)
stg_raiseDivZZerozh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
+ jump stg_raisezh(HsIface_divZZeroException_closure(W_[ghc_hs_iface]));
}
stg_raiseUnderflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
+ jump stg_raisezh(HsIface_underflowException_closure(W_[ghc_hs_iface]));
}
stg_raiseOverflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
+ jump stg_raisezh(HsIface_overflowException_closure(W_[ghc_hs_iface]));
}
/* The FFI doesn't support variadic C functions so we can't directly expose
=====================================
rts/Prelude.h
=====================================
@@ -19,126 +19,69 @@
#define PRELUDE_CLOSURE(i) extern StgClosure (i)
#endif
-/* See Note [Wired-in exceptions are not CAFfy] in GHC.Core.Make. */
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure);
/* Define canonical names so we can abstract away from the actual
* modules these names are defined in.
*/
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTuple_Z0T_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_True_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_False_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCString_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCStringUtf8_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeak_runFinalizzerBatch_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure);
-
#if defined(IN_STG_CODE)
extern W_ ZCMain_main_closure[];
#else
extern StgClosure ZCMain_main_closure;
#endif
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSync_runSparks_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure);
-#if defined(mingw32_HOST_OS)
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure);
-#endif
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziCString_unpackCStringzh_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Czh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Izh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Fzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Dzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Wzh_con_info);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_Ptr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_FunPtr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziStable_StablePtr_con_info);
-
-#define Unit_closure (&(ghczminternal_GHCziInternalziTuple_Z0T_closure))
-#define True_closure (&(ghczminternal_GHCziInternalziTypes_True_closure))
-#define False_closure (&(ghczminternal_GHCziInternalziTypes_False_closure))
-#define unpackCString_closure (&(ghczminternal_GHCziInternalziPack_unpackCString_closure))
-#define runFinalizerBatch_closure (&(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure))
+#define Unit_closure ghc_hs_iface->Z0T_closure
+#define True_closure ghc_hs_iface->True_closure
+#define False_closure ghc_hs_iface->False_closure
+#define unpackCString_closure ghc_hs_iface->unpackCString_closure
+#define runFinalizerBatch_closure ghc_hs_iface->runFinalizzerBatch_closure
#define mainIO_closure (&ZCMain_main_closure)
-#define runSparks_closure (&(ghczminternal_GHCziInternalziConcziSync_runSparks_closure))
-#define ensureIOManagerIsRunning_closure (&(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure))
-#define interruptIOManager_closure (&(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure))
-#define ioManagerCapabilitiesChanged_closure (&(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure))
-#define runHandlersPtr_closure (&(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure))
+#define runSparks_closure ghc_hs_iface->runSparks_closure
+#define ensureIOManagerIsRunning_closure ghc_hs_iface->ensureIOManagerIsRunning_closure
+#define interruptIOManager_closure ghc_hs_iface->interruptIOManager_closure
+#define ioManagerCapabilitiesChanged_closure ghc_hs_iface->ioManagerCapabilitiesChanged_closure
+#define runHandlersPtr_closure ghc_hs_iface->runHandlersPtr_closure
#if defined(mingw32_HOST_OS)
-#define processRemoteCompletion_closure (&(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure))
+#define processRemoteCompletion_closure ghc_hs_iface->processRemoteCompletion_closure
#endif
-#define runAllocationLimitHandler_closure (&(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure))
-
-#define flushStdHandles_closure (&(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure))
-#define runMainIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure))
-
-#define stackOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure))
-#define heapOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure))
-#define allocationLimitExceeded_closure (&(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure))
-#define blockedIndefinitelyOnMVar_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure))
-#define blockedIndefinitelyOnSTM_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure))
-#define cannotCompactFunction_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure))
-#define cannotCompactPinned_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure))
-#define cannotCompactMutable_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure))
-#define nonTermination_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure))
-#define nestedAtomically_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure))
-#define absentSumFieldError_closure (&(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure))
-#define underflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure))
-#define overflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure))
-#define divZeroException_closure (&(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure))
-
-#define blockedOnBadFD_closure (&(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure))
-
-#define Czh_con_info (&(ghczminternal_GHCziInternalziTypes_Czh_con_info))
-#define Izh_con_info (&(ghczminternal_GHCziInternalziTypes_Izh_con_info))
-#define Fzh_con_info (&(ghczminternal_GHCziInternalziTypes_Fzh_con_info))
-#define Dzh_con_info (&(ghczminternal_GHCziInternalziTypes_Dzh_con_info))
-#define Wzh_con_info (&(ghczminternal_GHCziInternalziTypes_Wzh_con_info))
-#define W8zh_con_info (&(ghczminternal_GHCziInternalziWord_W8zh_con_info))
-#define W16zh_con_info (&(ghczminternal_GHCziInternalziWord_W16zh_con_info))
-#define W32zh_con_info (&(ghczminternal_GHCziInternalziWord_W32zh_con_info))
-#define W64zh_con_info (&(ghczminternal_GHCziInternalziWord_W64zh_con_info))
-#define I8zh_con_info (&(ghczminternal_GHCziInternalziInt_I8zh_con_info))
-#define I16zh_con_info (&(ghczminternal_GHCziInternalziInt_I16zh_con_info))
-#define I32zh_con_info (&(ghczminternal_GHCziInternalziInt_I32zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define Ptr_con_info (&(ghczminternal_GHCziInternalziPtr_Ptr_con_info))
-#define FunPtr_con_info (&(ghczminternal_GHCziInternalziPtr_FunPtr_con_info))
-#define StablePtr_static_info (&(ghczminternal_GHCziInternalziStable_StablePtr_static_info))
-#define StablePtr_con_info (&(ghczminternal_GHCziInternalziStable_StablePtr_con_info))
+#define runAllocationLimitHandler_closure ghc_hs_iface->runAllocationLimitHandler_closure
+
+#define flushStdHandles_closure ghc_hs_iface->flushStdHandles_closure
+#define runMainIO_closure ghc_hs_iface->runMainIO_closure
+
+#define stackOverflow_closure ghc_hs_iface->stackOverflow_closure
+#define heapOverflow_closure ghc_hs_iface->heapOverflow_closure
+#define allocationLimitExceeded_closure ghc_hs_iface->allocationLimitExceeded_closure
+#define blockedIndefinitelyOnMVar_closure ghc_hs_iface->blockedIndefinitelyOnMVar_closure
+#define blockedIndefinitelyOnSTM_closure ghc_hs_iface->blockedIndefinitelyOnSTM_closure
+#define cannotCompactFunction_closure ghc_hs_iface->cannotCompactFunction_closure
+#define cannotCompactPinned_closure ghc_hs_iface->cannotCompactPinned_closure
+#define cannotCompactMutable_closure ghc_hs_iface->cannotCompactMutable_closure
+#define nonTermination_closure ghc_hs_iface->nonTermination_closure
+#define nestedAtomically_closure ghc_hs_iface->nestedAtomically_closure
+#define absentSumFieldError_closure ghc_hs_iface->absentSumFieldError_closure
+#define underflowException_closure ghc_hs_iface->underflowException_closure
+#define overflowException_closure ghc_hs_iface->overflowException_closure
+#define divZeroException_closure ghc_hs_iface->divZZeroException_closure
+
+#define blockedOnBadFD_closure ghc_hs_iface->blockedOnBadFD_closure
+
+#define Czh_con_info ghc_hs_iface->Czh_con_info
+#define Izh_con_info ghc_hs_iface->Izh_con_info
+#define Fzh_con_info ghc_hs_iface->Fzh_con_info
+#define Dzh_con_info ghc_hs_iface->Dzh_con_info
+#define Wzh_con_info ghc_hs_iface->Wzh_con_info
+#define W8zh_con_info ghc_hs_iface->W8zh_con_info
+#define W16zh_con_info ghc_hs_iface->W16zh_con_info
+#define W32zh_con_info ghc_hs_iface->W32zh_con_info
+#define W64zh_con_info ghc_hs_iface->W64zh_con_info
+#define I8zh_con_info ghc_hs_iface->I8zh_con_info
+#define I16zh_con_info ghc_hs_iface->I16zh_con_info
+#define I32zh_con_info ghc_hs_iface->I32zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define Ptr_con_info ghc_hs_iface->Ptr_con_info
+#define FunPtr_con_info ghc_hs_iface->FunPtr_con_info
+#define StablePtr_static_info ghc_hs_iface->StablePtr_static_info
+#define StablePtr_con_info ghc_hs_iface->StablePtr_con_info
=====================================
rts/PrimOps.cmm
=====================================
@@ -25,12 +25,8 @@
#include "MachDeps.h"
#include "SMPClosureOps.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_heapOverflow_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
-import CLOSURE ghczminternal_GHCziInternalziTypes_False_closure;
#if defined(PROFILING)
import CLOSURE CCS_MAIN;
#endif
@@ -118,7 +114,7 @@ stg_newByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytes(MyCapability() "ptr", n, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -135,7 +131,7 @@ stg_newPinnedByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
BA_ALIGN, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -149,7 +145,7 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
alignment, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -364,7 +360,7 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -474,7 +470,7 @@ stg_newSmallArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateSmallMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -1090,7 +1086,7 @@ stg_listThreadszh ()
("ptr" arr) = ccall listThreads(MyCapability() "ptr");
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (arr);
@@ -1360,7 +1356,7 @@ stg_atomicallyzh (P_ stm)
/* Nested transactions are not allowed; raise an exception */
if (old_trec != NO_TREC) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
+ jump stg_raisezh(HsIface_nestedAtomically_closure(W_[ghc_hs_iface]));
}
code = stm;
@@ -2231,7 +2227,7 @@ stg_unpackClosurezh ( P_ closure )
dat_arr_sz = SIZEOF_StgArrBytes + WDS(len);
("ptr" dat_arr) = ccall allocateMightFail(MyCapability() "ptr", BYTES_TO_WDS(dat_arr_sz));
if (dat_arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
TICK_ALLOC_PRIM(SIZEOF_StgArrBytes, WDS(len), 0);
@@ -2251,7 +2247,7 @@ for:
("ptr" ptrArray) = foreign "C" heap_view_closurePtrs(MyCapability() "ptr", clos "ptr");
if (ptrArray == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (info, dat_arr, ptrArray);
@@ -2518,13 +2514,13 @@ stg_getSparkzh ()
W_ spark;
#if !defined(THREADED_RTS)
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
#else
("ptr" spark) = ccall findSpark(MyCapability() "ptr");
if (spark != 0) {
return (1,spark);
} else {
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
}
#endif
}
=====================================
rts/RtsAPI.c
=====================================
@@ -509,7 +509,7 @@ void rts_evalStableIOMain(/* inout */ Capability **cap,
SchedulerStatus stat;
p = (StgClosure *)deRefStablePtr(s);
- w = rts_apply(*cap, &ghczminternal_GHCziInternalziTopHandler_runMainIO_closure, p);
+ w = rts_apply(*cap, runMainIO_closure, p);
tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, w);
// async exceptions are always blocked by default in the created
// thread. See #1048.
@@ -961,7 +961,7 @@ void rts_done (void)
void hs_try_putmvar (/* in */ int capability,
/* in */ HsStablePtr mvar)
{
- hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, Unit_closure));
+ hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure));
}
void hs_try_putmvar_with_value (/* in */ int capability,
=====================================
rts/RtsStartup.c
=====================================
@@ -14,6 +14,7 @@
#include "linker/MMap.h"
#include "RtsFlags.h"
#include "RtsUtils.h"
+#include "BuiltinClosures.h"
#include "Prelude.h"
#include "Printer.h" /* DEBUG_LoadSymbols */
#include "Schedule.h" /* initScheduler */
@@ -182,8 +183,8 @@ static void initBuiltinGcRoots(void)
* these closures `Id`s of these can be safely marked as non-CAFFY
* in the compiler.
*/
- getStablePtr((StgPtr)runIO_closure);
- getStablePtr((StgPtr)runNonIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runNonIO_closure);
getStablePtr((StgPtr)flushStdHandles_closure);
getStablePtr((StgPtr)runFinalizerBatch_closure);
@@ -262,6 +263,11 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
setlocale(LC_CTYPE,"");
+ if (ghc_hs_iface == NULL) {
+ errorBelch("hs_init_ghc: ghc_hs_iface is uninitialized");
+ stg_exit(1);
+ }
+
/* Initialise the stats department, phase 0 */
initStats0();
@@ -373,6 +379,9 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
traceInitEvent(traceOSProcessInfo);
flushTrace();
+ /* initialize INTLIKE and CHARLIKE closures */
+ initBuiltinClosures();
+
/* initialize the storage manager */
initStorage();
=====================================
rts/RtsToHsIface.c
=====================================
@@ -0,0 +1,51 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ *
+ * Note [RTS/ghc-internal interface]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The runtime system depends upon a variety of symbols defined by Haskell
+ * modules living in `ghc-internal`. To avoid cyclic dependencies between
+ * ghc-internal and the RTS, these symbols are referenced indirectly via the
+ * the `HsIface` structure (specifically `ghc_hs_iface`):
+ *
+ * struct HsIface {
+ * StgClosure *runIO; // GHC.Internal.TopHandler.runIO
+ * StgClosure *Z0T; // GHC.Internal.Tuple.()
+ * // etc.
+ * };
+ *
+ * `ghc_hs_iface` is initialized during program loading via the
+ * `init_ghc_hs_iface` constructor in `ghc-interface`
+ *
+ * const struct HsIface the_hs_iface = {
+ * .runIO = &ghczminternal_GHCziInternalziTopHandler_runIO_closure,
+ * .Z0T = &ghczminternal_GHCziInternalziTuple_Z0T_closure,
+ * // etc.
+ * };
+ *
+ * void __attribute__((constructor)) init_ghc_hs_iface() {
+ * ghc_hs_iface = &the_hs_iface;
+ * }
+ *
+ * This effectively breaks the RTS's link-time dependency, replacing it with a
+ * run-time dependency at the cost of an indirection. It also has the pleasant
+ * side-effect of making the interface between the RTS and `ghc-internal`
+ * explicit.
+ *
+ * Note that the constructor is explicitly listed in `ld-options` of
+ * `ghc-internal.cabal` since we need to ensure that it is included
+ * in the final link, even when we link against `ghc-internal.a` (as
+ * only objects members which provide undefined symbols are included
+ * in the final object).
+ *
+ */
+
+#include "Rts.h"
+
+// This captures the symbols provided by ghc-internal which
+// are needed by the RTS.
+const HsIface *ghc_hs_iface = NULL;
=====================================
rts/Schedule.c
=====================================
@@ -1053,7 +1053,7 @@ scheduleProcessInbox (Capability **pcap USED_IF_THREADS)
while (p != NULL) {
pnext = p->link;
performTryPutMVar(cap, (StgMVar*)deRefStablePtr(p->mvar),
- Unit_closure);
+ ghc_hs_iface->Z0T_closure);
freeStablePtr(p->mvar);
stgFree(p);
p = pnext;
=====================================
rts/StgMiscClosures.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
import pthread_mutex_lock;
-import ghczminternal_GHCziInternalziTypes_Czh_info;
-import ghczminternal_GHCziInternalziTypes_Izh_info;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
@@ -23,7 +21,6 @@ import whitehole_lockClosure_spin;
import whitehole_lockClosure_yield;
#endif
-
#if !defined(UnregisterisedCompiler)
import CLOSURE CCS_SYSTEM;
import CLOSURE ENT_DYN_IND_ctr;
@@ -1031,554 +1028,3 @@ INFO_TABLE_CONSTR(stg_ASYNCIO_LIVE0,0,0,0,CONSTR_NOCAF,"ASYNCIO_LIVE0","ASYNCIO_
{ foreign "C" barf("ASYNCIO_LIVE0 object (%p) entered!", R1) never returns; }
CLOSURE(stg_ASYNCIO_LIVE0_closure,stg_ASYNCIO_LIVE0);
-
-/* ----------------------------------------------------------------------------
- Note [CHARLIKE and INTLIKE closures]
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- These are static representations of Chars and small Ints, so that
- we can remove dynamic Chars and Ints during garbage collection and
- replace them with references to the static objects.
- ------------------------------------------------------------------------- */
-
-#define Char_hash_con_info ghczminternal_GHCziInternalziTypes_Czh_con_info
-#define Int_hash_con_info ghczminternal_GHCziInternalziTypes_Izh_con_info
-
-#define CHARLIKE_HDR(n) CLOSURE(Char_hash_con_info, n)
-#define INTLIKE_HDR(n) CLOSURE(Int_hash_con_info, n)
-
-section "data" {
- stg_CHARLIKE_closure:
- CHARLIKE_HDR(0)
- CHARLIKE_HDR(1)
- CHARLIKE_HDR(2)
- CHARLIKE_HDR(3)
- CHARLIKE_HDR(4)
- CHARLIKE_HDR(5)
- CHARLIKE_HDR(6)
- CHARLIKE_HDR(7)
- CHARLIKE_HDR(8)
- CHARLIKE_HDR(9)
- CHARLIKE_HDR(10)
- CHARLIKE_HDR(11)
- CHARLIKE_HDR(12)
- CHARLIKE_HDR(13)
- CHARLIKE_HDR(14)
- CHARLIKE_HDR(15)
- CHARLIKE_HDR(16)
- CHARLIKE_HDR(17)
- CHARLIKE_HDR(18)
- CHARLIKE_HDR(19)
- CHARLIKE_HDR(20)
- CHARLIKE_HDR(21)
- CHARLIKE_HDR(22)
- CHARLIKE_HDR(23)
- CHARLIKE_HDR(24)
- CHARLIKE_HDR(25)
- CHARLIKE_HDR(26)
- CHARLIKE_HDR(27)
- CHARLIKE_HDR(28)
- CHARLIKE_HDR(29)
- CHARLIKE_HDR(30)
- CHARLIKE_HDR(31)
- CHARLIKE_HDR(32)
- CHARLIKE_HDR(33)
- CHARLIKE_HDR(34)
- CHARLIKE_HDR(35)
- CHARLIKE_HDR(36)
- CHARLIKE_HDR(37)
- CHARLIKE_HDR(38)
- CHARLIKE_HDR(39)
- CHARLIKE_HDR(40)
- CHARLIKE_HDR(41)
- CHARLIKE_HDR(42)
- CHARLIKE_HDR(43)
- CHARLIKE_HDR(44)
- CHARLIKE_HDR(45)
- CHARLIKE_HDR(46)
- CHARLIKE_HDR(47)
- CHARLIKE_HDR(48)
- CHARLIKE_HDR(49)
- CHARLIKE_HDR(50)
- CHARLIKE_HDR(51)
- CHARLIKE_HDR(52)
- CHARLIKE_HDR(53)
- CHARLIKE_HDR(54)
- CHARLIKE_HDR(55)
- CHARLIKE_HDR(56)
- CHARLIKE_HDR(57)
- CHARLIKE_HDR(58)
- CHARLIKE_HDR(59)
- CHARLIKE_HDR(60)
- CHARLIKE_HDR(61)
- CHARLIKE_HDR(62)
- CHARLIKE_HDR(63)
- CHARLIKE_HDR(64)
- CHARLIKE_HDR(65)
- CHARLIKE_HDR(66)
- CHARLIKE_HDR(67)
- CHARLIKE_HDR(68)
- CHARLIKE_HDR(69)
- CHARLIKE_HDR(70)
- CHARLIKE_HDR(71)
- CHARLIKE_HDR(72)
- CHARLIKE_HDR(73)
- CHARLIKE_HDR(74)
- CHARLIKE_HDR(75)
- CHARLIKE_HDR(76)
- CHARLIKE_HDR(77)
- CHARLIKE_HDR(78)
- CHARLIKE_HDR(79)
- CHARLIKE_HDR(80)
- CHARLIKE_HDR(81)
- CHARLIKE_HDR(82)
- CHARLIKE_HDR(83)
- CHARLIKE_HDR(84)
- CHARLIKE_HDR(85)
- CHARLIKE_HDR(86)
- CHARLIKE_HDR(87)
- CHARLIKE_HDR(88)
- CHARLIKE_HDR(89)
- CHARLIKE_HDR(90)
- CHARLIKE_HDR(91)
- CHARLIKE_HDR(92)
- CHARLIKE_HDR(93)
- CHARLIKE_HDR(94)
- CHARLIKE_HDR(95)
- CHARLIKE_HDR(96)
- CHARLIKE_HDR(97)
- CHARLIKE_HDR(98)
- CHARLIKE_HDR(99)
- CHARLIKE_HDR(100)
- CHARLIKE_HDR(101)
- CHARLIKE_HDR(102)
- CHARLIKE_HDR(103)
- CHARLIKE_HDR(104)
- CHARLIKE_HDR(105)
- CHARLIKE_HDR(106)
- CHARLIKE_HDR(107)
- CHARLIKE_HDR(108)
- CHARLIKE_HDR(109)
- CHARLIKE_HDR(110)
- CHARLIKE_HDR(111)
- CHARLIKE_HDR(112)
- CHARLIKE_HDR(113)
- CHARLIKE_HDR(114)
- CHARLIKE_HDR(115)
- CHARLIKE_HDR(116)
- CHARLIKE_HDR(117)
- CHARLIKE_HDR(118)
- CHARLIKE_HDR(119)
- CHARLIKE_HDR(120)
- CHARLIKE_HDR(121)
- CHARLIKE_HDR(122)
- CHARLIKE_HDR(123)
- CHARLIKE_HDR(124)
- CHARLIKE_HDR(125)
- CHARLIKE_HDR(126)
- CHARLIKE_HDR(127)
- CHARLIKE_HDR(128)
- CHARLIKE_HDR(129)
- CHARLIKE_HDR(130)
- CHARLIKE_HDR(131)
- CHARLIKE_HDR(132)
- CHARLIKE_HDR(133)
- CHARLIKE_HDR(134)
- CHARLIKE_HDR(135)
- CHARLIKE_HDR(136)
- CHARLIKE_HDR(137)
- CHARLIKE_HDR(138)
- CHARLIKE_HDR(139)
- CHARLIKE_HDR(140)
- CHARLIKE_HDR(141)
- CHARLIKE_HDR(142)
- CHARLIKE_HDR(143)
- CHARLIKE_HDR(144)
- CHARLIKE_HDR(145)
- CHARLIKE_HDR(146)
- CHARLIKE_HDR(147)
- CHARLIKE_HDR(148)
- CHARLIKE_HDR(149)
- CHARLIKE_HDR(150)
- CHARLIKE_HDR(151)
- CHARLIKE_HDR(152)
- CHARLIKE_HDR(153)
- CHARLIKE_HDR(154)
- CHARLIKE_HDR(155)
- CHARLIKE_HDR(156)
- CHARLIKE_HDR(157)
- CHARLIKE_HDR(158)
- CHARLIKE_HDR(159)
- CHARLIKE_HDR(160)
- CHARLIKE_HDR(161)
- CHARLIKE_HDR(162)
- CHARLIKE_HDR(163)
- CHARLIKE_HDR(164)
- CHARLIKE_HDR(165)
- CHARLIKE_HDR(166)
- CHARLIKE_HDR(167)
- CHARLIKE_HDR(168)
- CHARLIKE_HDR(169)
- CHARLIKE_HDR(170)
- CHARLIKE_HDR(171)
- CHARLIKE_HDR(172)
- CHARLIKE_HDR(173)
- CHARLIKE_HDR(174)
- CHARLIKE_HDR(175)
- CHARLIKE_HDR(176)
- CHARLIKE_HDR(177)
- CHARLIKE_HDR(178)
- CHARLIKE_HDR(179)
- CHARLIKE_HDR(180)
- CHARLIKE_HDR(181)
- CHARLIKE_HDR(182)
- CHARLIKE_HDR(183)
- CHARLIKE_HDR(184)
- CHARLIKE_HDR(185)
- CHARLIKE_HDR(186)
- CHARLIKE_HDR(187)
- CHARLIKE_HDR(188)
- CHARLIKE_HDR(189)
- CHARLIKE_HDR(190)
- CHARLIKE_HDR(191)
- CHARLIKE_HDR(192)
- CHARLIKE_HDR(193)
- CHARLIKE_HDR(194)
- CHARLIKE_HDR(195)
- CHARLIKE_HDR(196)
- CHARLIKE_HDR(197)
- CHARLIKE_HDR(198)
- CHARLIKE_HDR(199)
- CHARLIKE_HDR(200)
- CHARLIKE_HDR(201)
- CHARLIKE_HDR(202)
- CHARLIKE_HDR(203)
- CHARLIKE_HDR(204)
- CHARLIKE_HDR(205)
- CHARLIKE_HDR(206)
- CHARLIKE_HDR(207)
- CHARLIKE_HDR(208)
- CHARLIKE_HDR(209)
- CHARLIKE_HDR(210)
- CHARLIKE_HDR(211)
- CHARLIKE_HDR(212)
- CHARLIKE_HDR(213)
- CHARLIKE_HDR(214)
- CHARLIKE_HDR(215)
- CHARLIKE_HDR(216)
- CHARLIKE_HDR(217)
- CHARLIKE_HDR(218)
- CHARLIKE_HDR(219)
- CHARLIKE_HDR(220)
- CHARLIKE_HDR(221)
- CHARLIKE_HDR(222)
- CHARLIKE_HDR(223)
- CHARLIKE_HDR(224)
- CHARLIKE_HDR(225)
- CHARLIKE_HDR(226)
- CHARLIKE_HDR(227)
- CHARLIKE_HDR(228)
- CHARLIKE_HDR(229)
- CHARLIKE_HDR(230)
- CHARLIKE_HDR(231)
- CHARLIKE_HDR(232)
- CHARLIKE_HDR(233)
- CHARLIKE_HDR(234)
- CHARLIKE_HDR(235)
- CHARLIKE_HDR(236)
- CHARLIKE_HDR(237)
- CHARLIKE_HDR(238)
- CHARLIKE_HDR(239)
- CHARLIKE_HDR(240)
- CHARLIKE_HDR(241)
- CHARLIKE_HDR(242)
- CHARLIKE_HDR(243)
- CHARLIKE_HDR(244)
- CHARLIKE_HDR(245)
- CHARLIKE_HDR(246)
- CHARLIKE_HDR(247)
- CHARLIKE_HDR(248)
- CHARLIKE_HDR(249)
- CHARLIKE_HDR(250)
- CHARLIKE_HDR(251)
- CHARLIKE_HDR(252)
- CHARLIKE_HDR(253)
- CHARLIKE_HDR(254)
- CHARLIKE_HDR(255)
-}
-
-section "data" {
- stg_INTLIKE_closure:
- INTLIKE_HDR(-16) /* MIN_INTLIKE == -16 */
- INTLIKE_HDR(-15)
- INTLIKE_HDR(-14)
- INTLIKE_HDR(-13)
- INTLIKE_HDR(-12)
- INTLIKE_HDR(-11)
- INTLIKE_HDR(-10)
- INTLIKE_HDR(-9)
- INTLIKE_HDR(-8)
- INTLIKE_HDR(-7)
- INTLIKE_HDR(-6)
- INTLIKE_HDR(-5)
- INTLIKE_HDR(-4)
- INTLIKE_HDR(-3)
- INTLIKE_HDR(-2)
- INTLIKE_HDR(-1)
- INTLIKE_HDR(0)
- INTLIKE_HDR(1)
- INTLIKE_HDR(2)
- INTLIKE_HDR(3)
- INTLIKE_HDR(4)
- INTLIKE_HDR(5)
- INTLIKE_HDR(6)
- INTLIKE_HDR(7)
- INTLIKE_HDR(8)
- INTLIKE_HDR(9)
- INTLIKE_HDR(10)
- INTLIKE_HDR(11)
- INTLIKE_HDR(12)
- INTLIKE_HDR(13)
- INTLIKE_HDR(14)
- INTLIKE_HDR(15)
- INTLIKE_HDR(16)
- INTLIKE_HDR(17)
- INTLIKE_HDR(18)
- INTLIKE_HDR(19)
- INTLIKE_HDR(20)
- INTLIKE_HDR(21)
- INTLIKE_HDR(22)
- INTLIKE_HDR(23)
- INTLIKE_HDR(24)
- INTLIKE_HDR(25)
- INTLIKE_HDR(26)
- INTLIKE_HDR(27)
- INTLIKE_HDR(28)
- INTLIKE_HDR(29)
- INTLIKE_HDR(30)
- INTLIKE_HDR(31)
- INTLIKE_HDR(32)
- INTLIKE_HDR(33)
- INTLIKE_HDR(34)
- INTLIKE_HDR(35)
- INTLIKE_HDR(36)
- INTLIKE_HDR(37)
- INTLIKE_HDR(38)
- INTLIKE_HDR(39)
- INTLIKE_HDR(40)
- INTLIKE_HDR(41)
- INTLIKE_HDR(42)
- INTLIKE_HDR(43)
- INTLIKE_HDR(44)
- INTLIKE_HDR(45)
- INTLIKE_HDR(46)
- INTLIKE_HDR(47)
- INTLIKE_HDR(48)
- INTLIKE_HDR(49)
- INTLIKE_HDR(50)
- INTLIKE_HDR(51)
- INTLIKE_HDR(52)
- INTLIKE_HDR(53)
- INTLIKE_HDR(54)
- INTLIKE_HDR(55)
- INTLIKE_HDR(56)
- INTLIKE_HDR(57)
- INTLIKE_HDR(58)
- INTLIKE_HDR(59)
- INTLIKE_HDR(60)
- INTLIKE_HDR(61)
- INTLIKE_HDR(62)
- INTLIKE_HDR(63)
- INTLIKE_HDR(64)
- INTLIKE_HDR(65)
- INTLIKE_HDR(66)
- INTLIKE_HDR(67)
- INTLIKE_HDR(68)
- INTLIKE_HDR(69)
- INTLIKE_HDR(70)
- INTLIKE_HDR(71)
- INTLIKE_HDR(72)
- INTLIKE_HDR(73)
- INTLIKE_HDR(74)
- INTLIKE_HDR(75)
- INTLIKE_HDR(76)
- INTLIKE_HDR(77)
- INTLIKE_HDR(78)
- INTLIKE_HDR(79)
- INTLIKE_HDR(80)
- INTLIKE_HDR(81)
- INTLIKE_HDR(82)
- INTLIKE_HDR(83)
- INTLIKE_HDR(84)
- INTLIKE_HDR(85)
- INTLIKE_HDR(86)
- INTLIKE_HDR(87)
- INTLIKE_HDR(88)
- INTLIKE_HDR(89)
- INTLIKE_HDR(90)
- INTLIKE_HDR(91)
- INTLIKE_HDR(92)
- INTLIKE_HDR(93)
- INTLIKE_HDR(94)
- INTLIKE_HDR(95)
- INTLIKE_HDR(96)
- INTLIKE_HDR(97)
- INTLIKE_HDR(98)
- INTLIKE_HDR(99)
- INTLIKE_HDR(100)
- INTLIKE_HDR(101)
- INTLIKE_HDR(102)
- INTLIKE_HDR(103)
- INTLIKE_HDR(104)
- INTLIKE_HDR(105)
- INTLIKE_HDR(106)
- INTLIKE_HDR(107)
- INTLIKE_HDR(108)
- INTLIKE_HDR(109)
- INTLIKE_HDR(110)
- INTLIKE_HDR(111)
- INTLIKE_HDR(112)
- INTLIKE_HDR(113)
- INTLIKE_HDR(114)
- INTLIKE_HDR(115)
- INTLIKE_HDR(116)
- INTLIKE_HDR(117)
- INTLIKE_HDR(118)
- INTLIKE_HDR(119)
- INTLIKE_HDR(120)
- INTLIKE_HDR(121)
- INTLIKE_HDR(122)
- INTLIKE_HDR(123)
- INTLIKE_HDR(124)
- INTLIKE_HDR(125)
- INTLIKE_HDR(126)
- INTLIKE_HDR(127)
- INTLIKE_HDR(128)
- INTLIKE_HDR(129)
- INTLIKE_HDR(130)
- INTLIKE_HDR(131)
- INTLIKE_HDR(132)
- INTLIKE_HDR(133)
- INTLIKE_HDR(134)
- INTLIKE_HDR(135)
- INTLIKE_HDR(136)
- INTLIKE_HDR(137)
- INTLIKE_HDR(138)
- INTLIKE_HDR(139)
- INTLIKE_HDR(140)
- INTLIKE_HDR(141)
- INTLIKE_HDR(142)
- INTLIKE_HDR(143)
- INTLIKE_HDR(144)
- INTLIKE_HDR(145)
- INTLIKE_HDR(146)
- INTLIKE_HDR(147)
- INTLIKE_HDR(148)
- INTLIKE_HDR(149)
- INTLIKE_HDR(150)
- INTLIKE_HDR(151)
- INTLIKE_HDR(152)
- INTLIKE_HDR(153)
- INTLIKE_HDR(154)
- INTLIKE_HDR(155)
- INTLIKE_HDR(156)
- INTLIKE_HDR(157)
- INTLIKE_HDR(158)
- INTLIKE_HDR(159)
- INTLIKE_HDR(160)
- INTLIKE_HDR(161)
- INTLIKE_HDR(162)
- INTLIKE_HDR(163)
- INTLIKE_HDR(164)
- INTLIKE_HDR(165)
- INTLIKE_HDR(166)
- INTLIKE_HDR(167)
- INTLIKE_HDR(168)
- INTLIKE_HDR(169)
- INTLIKE_HDR(170)
- INTLIKE_HDR(171)
- INTLIKE_HDR(172)
- INTLIKE_HDR(173)
- INTLIKE_HDR(174)
- INTLIKE_HDR(175)
- INTLIKE_HDR(176)
- INTLIKE_HDR(177)
- INTLIKE_HDR(178)
- INTLIKE_HDR(179)
- INTLIKE_HDR(180)
- INTLIKE_HDR(181)
- INTLIKE_HDR(182)
- INTLIKE_HDR(183)
- INTLIKE_HDR(184)
- INTLIKE_HDR(185)
- INTLIKE_HDR(186)
- INTLIKE_HDR(187)
- INTLIKE_HDR(188)
- INTLIKE_HDR(189)
- INTLIKE_HDR(190)
- INTLIKE_HDR(191)
- INTLIKE_HDR(192)
- INTLIKE_HDR(193)
- INTLIKE_HDR(194)
- INTLIKE_HDR(195)
- INTLIKE_HDR(196)
- INTLIKE_HDR(197)
- INTLIKE_HDR(198)
- INTLIKE_HDR(199)
- INTLIKE_HDR(200)
- INTLIKE_HDR(201)
- INTLIKE_HDR(202)
- INTLIKE_HDR(203)
- INTLIKE_HDR(204)
- INTLIKE_HDR(205)
- INTLIKE_HDR(206)
- INTLIKE_HDR(207)
- INTLIKE_HDR(208)
- INTLIKE_HDR(209)
- INTLIKE_HDR(210)
- INTLIKE_HDR(211)
- INTLIKE_HDR(212)
- INTLIKE_HDR(213)
- INTLIKE_HDR(214)
- INTLIKE_HDR(215)
- INTLIKE_HDR(216)
- INTLIKE_HDR(217)
- INTLIKE_HDR(218)
- INTLIKE_HDR(219)
- INTLIKE_HDR(220)
- INTLIKE_HDR(221)
- INTLIKE_HDR(222)
- INTLIKE_HDR(223)
- INTLIKE_HDR(224)
- INTLIKE_HDR(225)
- INTLIKE_HDR(226)
- INTLIKE_HDR(227)
- INTLIKE_HDR(228)
- INTLIKE_HDR(229)
- INTLIKE_HDR(230)
- INTLIKE_HDR(231)
- INTLIKE_HDR(232)
- INTLIKE_HDR(233)
- INTLIKE_HDR(234)
- INTLIKE_HDR(235)
- INTLIKE_HDR(236)
- INTLIKE_HDR(237)
- INTLIKE_HDR(238)
- INTLIKE_HDR(239)
- INTLIKE_HDR(240)
- INTLIKE_HDR(241)
- INTLIKE_HDR(242)
- INTLIKE_HDR(243)
- INTLIKE_HDR(244)
- INTLIKE_HDR(245)
- INTLIKE_HDR(246)
- INTLIKE_HDR(247)
- INTLIKE_HDR(248)
- INTLIKE_HDR(249)
- INTLIKE_HDR(250)
- INTLIKE_HDR(251)
- INTLIKE_HDR(252)
- INTLIKE_HDR(253)
- INTLIKE_HDR(254)
- INTLIKE_HDR(255) /* MAX_INTLIKE == 255
- See #16961 for why 255 */
-}
=====================================
rts/StgStdThunks.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
#include "Updates.h"
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringzh_info;
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info;
#if !defined(UnregisterisedCompiler)
import CLOSURE STK_CHK_ctr;
import CLOSURE stg_bh_upd_frame_info;
@@ -348,7 +346,7 @@ stg_do_unpack_cstring(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringzh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringzh_info(W_[ghc_hs_iface]))(node, str);
}
}
@@ -372,7 +370,7 @@ stg_do_unpack_cstring_utf8(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringUtf8zh_info(W_[ghc_hs_iface]))(node, str);
}
}
=====================================
rts/include/Rts.h
=====================================
@@ -229,6 +229,7 @@ void _warnFail(const char *filename, unsigned int linenum);
#include "rts/storage/ClosureTypes.h"
#include "rts/storage/TSO.h"
#include "stg/MiscClosures.h" /* InfoTables, closures etc. defined in the RTS */
+
#include "rts/storage/Block.h"
#include "rts/storage/ClosureMacros.h"
#include "rts/storage/MBlock.h"
=====================================
rts/include/RtsAPI.h
=====================================
@@ -18,6 +18,7 @@ extern "C" {
#include "HsFFI.h"
#include "rts/Time.h"
#include "rts/Types.h"
+#include "rts/RtsToHsIface.h"
/*
* Running the scheduler
@@ -584,11 +585,6 @@ void rts_done (void);
// Note that RtsAPI.h is also included by foreign export stubs in
// the base package itself.
//
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runIO_closure;
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runNonIO_closure;
-
-#define runIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runIO_closure))
-#define runNonIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runNonIO_closure))
/* ------------------------------------------------------------------------ */
=====================================
rts/include/rts/Constants.h
=====================================
@@ -57,11 +57,12 @@
#define MAX_SPEC_CONSTR_SIZE 2
/* Range of built-in table of static small int-like and char-like closures.
+ * Range is inclusive of both minimum and maximum.
*
* NB. This corresponds with the number of actual INTLIKE/CHARLIKE
* closures defined in rts/StgMiscClosures.cmm.
*/
-#define MAX_INTLIKE 255
+#define MAX_INTLIKE 255 /* See #16961 for why 255 */
#define MIN_INTLIKE (-16)
#define MAX_CHARLIKE 255
=====================================
rts/include/rts/RtsToHsIface.h
=====================================
@@ -0,0 +1,64 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+typedef struct {
+ StgClosure *processRemoteCompletion_closure; // GHC.Internal.Event.Windows.processRemoteCompletion_closure
+ StgClosure *runIO_closure; // GHC.Internal.TopHandler.runIO_closure
+ StgClosure *runNonIO_closure; // GHC.Internal.TopHandler.runNonIO_closure
+ StgClosure *Z0T_closure; // GHC.Internal.Tuple.Z0T_closure
+ StgClosure *True_closure; // GHC.Internal.Types.True_closure
+ StgClosure *False_closure; // GHC.Internal.Types.False_closure
+ StgClosure *unpackCString_closure; // GHC.Internal.Pack.unpackCString_closure
+ StgClosure *runFinalizzerBatch_closure; // GHC.Internal.Weak.Finalizze.runFinalizzerBatch_closure
+ StgClosure *stackOverflow_closure; // GHC.Internal.IO.Exception.stackOverflow_closure
+ StgClosure *heapOverflow_closure; // GHC.Internal.IO.Exception.heapOverflow_closure
+ StgClosure *allocationLimitExceeded_closure; // GHC.Internal.IO.Exception.allocationLimitExceeded_closure
+ StgClosure *blockedIndefinitelyOnMVar_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnMVar_closure
+ StgClosure *blockedIndefinitelyOnSTM_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnSTM_closure
+ StgClosure *cannotCompactFunction_closure; // GHC.Internal.IO.Exception.cannotCompactFunction_closure
+ StgClosure *cannotCompactPinned_closure; // GHC.Internal.IO.Exception.cannotCompactPinned_closure
+ StgClosure *cannotCompactMutable_closure; // GHC.Internal.IO.Exception.cannotCompactMutable_closure
+ StgClosure *nonTermination_closure; // GHC.Internal.Control.Exception.Base.nonTermination_closure
+ StgClosure *nestedAtomically_closure; // GHC.Internal.Control.Exception.Base.nestedAtomically_closure
+ StgClosure *noMatchingContinuationPrompt_closure; // GHC.Internal.Control.Exception.Base.noMatchingContinuationPrompt_closure
+ StgClosure *blockedOnBadFD_closure; // GHC.Internal.Event.Thread.blockedOnBadFD_closure
+ StgClosure *runSparks_closure; // GHC.Internal.Conc.Sync.runSparks_closure
+ StgClosure *ensureIOManagerIsRunning_closure; // GHC.Internal.Conc.IO.ensureIOManagerIsRunning_closure
+ StgClosure *interruptIOManager_closure; // GHC.Internal.Conc.IO.interruptIOManager_closure
+ StgClosure *ioManagerCapabilitiesChanged_closure; // GHC.Internal.Conc.IO.ioManagerCapabilitiesChanged_closure
+ StgClosure *runHandlersPtr_closure; // GHC.Internal.Conc.Signal.runHandlersPtr_closure
+ StgClosure *flushStdHandles_closure; // GHC.Internal.TopHandler.flushStdHandles_closure
+ StgClosure *runMainIO_closure; // GHC.Internal.TopHandler.runMainIO_closure
+ StgInfoTable *Czh_con_info; // GHC.Internal.Types.Czh_con_info
+ StgInfoTable *Izh_con_info; // GHC.Internal.Types.Izh_con_info
+ StgInfoTable *Fzh_con_info; // GHC.Internal.Types.Fzh_con_info
+ StgInfoTable *Dzh_con_info; // GHC.Internal.Types.Dzh_con_info
+ StgInfoTable *Wzh_con_info; // GHC.Internal.Types.Wzh_con_info
+ StgClosure *absentSumFieldError_closure; // GHC.Internal.Prim.Panic.absentSumFieldError_closure
+ StgClosure *runAllocationLimitHandler_closure; // GHC.Internal.AllocationLimitHandler.runAllocationLimitHandler_closure
+ StgInfoTable *Ptr_con_info; // GHC.Internal.Ptr.Ptr_con_info
+ StgInfoTable *FunPtr_con_info; // GHC.Internal.Ptr.FunPtr_con_info
+ StgInfoTable *I8zh_con_info; // GHC.Internal.Int.I8zh_con_info
+ StgInfoTable *I16zh_con_info; // GHC.Internal.Int.I16zh_con_info
+ StgInfoTable *I32zh_con_info; // GHC.Internal.Int.I32zh_con_info
+ StgInfoTable *I64zh_con_info; // GHC.Internal.Int.I64zh_con_info
+ StgInfoTable *W8zh_con_info; // GHC.Internal.Word.W8zh_con_info
+ StgInfoTable *W16zh_con_info; // GHC.Internal.Word.W16zh_con_info
+ StgInfoTable *W32zh_con_info; // GHC.Internal.Word.W32zh_con_info
+ StgInfoTable *W64zh_con_info; // GHC.Internal.Word.W64zh_con_info
+ StgInfoTable *StablePtr_con_info; // GHC.Internal.Stable.StablePtr_con_info
+ StgClosure *StackSnapshot_closure; // GHC.Internal.Stack.CloneStack.StackSnapshot_closure
+ StgClosure *divZZeroException_closure; // GHC.Internal.Exception.Type.divZeroException_closure
+ StgClosure *underflowException_closure; // GHC.Internal.Exception.Type.underflowException_closure
+ StgClosure *overflowException_closure; // GHC.Internal.Exception.Type.overflowException_closure
+ StgClosure *unpackCStringzh_closure; // GHC.Internal.CString.unpackCStringzh_closure
+ StgInfoTable *unpackCStringzh_info; // GHC.Internal.CString.unpackCStringzh_info
+ StgInfoTable *unpackCStringUtf8zh_info; // GHC.Internal.CString.unpackCStringUtf8zh_info
+} HsIface;
+
+extern const HsIface *ghc_hs_iface;
=====================================
rts/include/stg/MiscClosures.h
=====================================
@@ -277,8 +277,8 @@ RTS_ENTRY(stg_NO_FINALIZER);
extern StgWordArray stg_CHARLIKE_closure;
extern StgWordArray stg_INTLIKE_closure;
#else
-extern StgIntCharlikeClosure stg_CHARLIKE_closure[];
-extern StgIntCharlikeClosure stg_INTLIKE_closure[];
+extern StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+extern StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
#endif
/* StgStartup */
=====================================
rts/posix/Signals.c
=====================================
@@ -222,7 +222,7 @@ ioManagerDie (void)
void
ioManagerStartCap (Capability **cap)
{
- rts_evalIO(cap,&ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure,NULL);
+ rts_evalIO(cap,ensureIOManagerIsRunning_closure,NULL);
}
void
@@ -493,7 +493,7 @@ startSignalHandlers(Capability *cap)
RtsFlags.GcFlags.initialStkSize,
rts_apply(cap,
rts_apply(cap,
- &ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure,
+ runHandlersPtr_closure,
rts_mkPtr(cap, info)),
rts_mkInt(cap, info->si_signo)));
scheduleThread(cap, t);
=====================================
rts/rts.cabal
=====================================
@@ -334,6 +334,7 @@ library
rts/storage/InfoTables.h
rts/storage/MBlock.h
rts/storage/TSO.h
+ rts/RtsToHsIface.h
stg/MachRegs.h
stg/MachRegs/arm32.h
stg/MachRegs/arm64.h
@@ -403,6 +404,7 @@ library
adjustor/AdjustorPool.c
ExecPage.c
Arena.c
+ BuiltinClosures.c
Capability.c
CheckUnload.c
CheckVectorSupport.c
@@ -448,6 +450,7 @@ library
RtsStartup.c
RtsSymbolInfo.c
RtsSymbols.c
+ RtsToHsIface.c
RtsUtils.c
STM.c
Schedule.c
=====================================
rts/wasm/JSFFI.c
=====================================
@@ -23,8 +23,8 @@ int __main_argc_argv(int argc, char *argv[]) {
hs_init_ghc(&argc, &argv, __conf);
// See Note [threadDelay on wasm] for details.
rts_JSFFI_flag = HS_BOOL_TRUE;
- getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
- rts_threadDelay_impl = getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->raiseJSException_closure);
+ rts_threadDelay_impl = getStablePtr((StgPtr)ghc_hs_iface->threadDelay_closure);
return 0;
}
@@ -112,7 +112,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
SET_HDR(w, &stg_WEAK_info, CCS_SYSTEM);
w->cfinalizers = (StgClosure *)cfin;
w->key = p;
- w->value = Unit_closure;
+ w->value = ghc_hs_iface->Z0T_closure;
w->finalizer = &stg_NO_FINALIZER_closure;
w->link = cap->weak_ptr_list_hd;
cap->weak_ptr_list_hd = w;
@@ -123,7 +123,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
p->payload[0] = (HaskellObj)w;
HaskellObj box = (HaskellObj)allocate(cap, CONSTR_sizeW(1, 0));
- SET_HDR(box, &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info, CCS_SYSTEM);
+ SET_HDR(box, ghc_hs_iface->JSVal_con_info, CCS_SYSTEM);
box->payload[0] = p;
return TAG_CLOSURE(1, box);
@@ -139,7 +139,7 @@ STATIC_INLINE HsJSVal rts_getJSValzh(HaskellObj p) {
HsJSVal rts_getJSVal(HaskellObj);
HsJSVal rts_getJSVal(HaskellObj box) {
- ASSERT(UNTAG_CLOSURE(box)->header.info == &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info);
+ ASSERT(UNTAG_CLOSURE(box)->header.info == ghc_hs_iface->JSVal_con_info);
return rts_getJSValzh(UNTAG_CLOSURE(box)->payload[0]);
}
@@ -188,7 +188,7 @@ void rts_schedulerLoop(void) {
__attribute__((export_name("rts_promiseResolveUnit")))
void rts_promiseResolveUnit(HsStablePtr);
void rts_promiseResolveUnit(HsStablePtr sp)
- mk_rtsPromiseCallback(TAG_CLOSURE(1, Unit_closure))
+ mk_rtsPromiseCallback(TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure))
mk_rtsPromiseResolve(JSVal)
mk_rtsPromiseResolve(Char)
@@ -212,7 +212,7 @@ mk_rtsPromiseResolve(Bool)
__attribute__((export_name("rts_promiseReject")))
void rts_promiseReject(HsStablePtr, HsJSVal);
void rts_promiseReject(HsStablePtr sp, HsJSVal js_err)
- mk_rtsPromiseCallback(rts_apply(cap, &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure, rts_mkJSVal(cap, js_err)))
+ mk_rtsPromiseCallback(rts_apply(cap, ghc_hs_iface->raiseJSException_closure, rts_mkJSVal(cap, js_err)))
__attribute__((export_name("rts_promiseThrowTo")))
void rts_promiseThrowTo(HsStablePtr, HsJSVal);
@@ -229,7 +229,7 @@ void rts_promiseThrowTo(HsStablePtr sp, HsJSVal js_err) {
cap, tso,
rts_apply(
cap,
- &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure,
+ ghc_hs_iface->raiseJSException_closure,
rts_mkJSVal(cap, js_err)));
tryWakeupThread(cap, tso);
rts_schedulerLoop();
=====================================
utils/deriveConstants/Main.hs
=====================================
@@ -667,6 +667,59 @@ wanteds os = concat
,structField C "StgAsyncIOResult" "errCode"]
else []
+ -- struct HsIface
+ ,structField C "HsIface" "processRemoteCompletion_closure"
+ ,structField C "HsIface" "runIO_closure"
+ ,structField C "HsIface" "runNonIO_closure"
+ ,structField C "HsIface" "Z0T_closure"
+ ,structField C "HsIface" "True_closure"
+ ,structField C "HsIface" "False_closure"
+ ,structField C "HsIface" "unpackCString_closure"
+ ,structField C "HsIface" "runFinalizzerBatch_closure"
+ ,structField C "HsIface" "stackOverflow_closure"
+ ,structField C "HsIface" "heapOverflow_closure"
+ ,structField C "HsIface" "allocationLimitExceeded_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnMVar_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnSTM_closure"
+ ,structField C "HsIface" "cannotCompactFunction_closure"
+ ,structField C "HsIface" "cannotCompactPinned_closure"
+ ,structField C "HsIface" "cannotCompactMutable_closure"
+ ,structField C "HsIface" "nonTermination_closure"
+ ,structField C "HsIface" "nestedAtomically_closure"
+ ,structField C "HsIface" "noMatchingContinuationPrompt_closure"
+ ,structField C "HsIface" "blockedOnBadFD_closure"
+ ,structField C "HsIface" "runSparks_closure"
+ ,structField C "HsIface" "ensureIOManagerIsRunning_closure"
+ ,structField C "HsIface" "interruptIOManager_closure"
+ ,structField C "HsIface" "ioManagerCapabilitiesChanged_closure"
+ ,structField C "HsIface" "runHandlersPtr_closure"
+ ,structField C "HsIface" "flushStdHandles_closure"
+ ,structField C "HsIface" "runMainIO_closure"
+ ,structField C "HsIface" "Czh_con_info"
+ ,structField C "HsIface" "Izh_con_info"
+ ,structField C "HsIface" "Fzh_con_info"
+ ,structField C "HsIface" "Dzh_con_info"
+ ,structField C "HsIface" "Wzh_con_info"
+ ,structField C "HsIface" "runAllocationLimitHandler_closure"
+ ,structField C "HsIface" "Ptr_con_info"
+ ,structField C "HsIface" "FunPtr_con_info"
+ ,structField C "HsIface" "I8zh_con_info"
+ ,structField C "HsIface" "I16zh_con_info"
+ ,structField C "HsIface" "I32zh_con_info"
+ ,structField C "HsIface" "I64zh_con_info"
+ ,structField C "HsIface" "W8zh_con_info"
+ ,structField C "HsIface" "W16zh_con_info"
+ ,structField C "HsIface" "W32zh_con_info"
+ ,structField C "HsIface" "W64zh_con_info"
+ ,structField C "HsIface" "StablePtr_con_info"
+ ,structField C "HsIface" "StackSnapshot_closure"
+ ,structField C "HsIface" "divZZeroException_closure"
+ ,structField C "HsIface" "underflowException_closure"
+ ,structField C "HsIface" "overflowException_closure"
+ ,structField C "HsIface" "unpackCStringzh_closure"
+ ,structField C "HsIface" "unpackCStringzh_info"
+ ,structField C "HsIface" "unpackCStringUtf8zh_info"
+
-- pre-compiled thunk types
,constantWord Haskell "MAX_SPEC_SELECTEE_SIZE" "MAX_SPEC_SELECTEE_SIZE"
,constantWord Haskell "MAX_SPEC_AP_SIZE" "MAX_SPEC_AP_SIZE"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/591e0f3012d17edc9a6b16870d7f01…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/591e0f3012d17edc9a6b16870d7f01…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26166] 2 commits: rts: Dynamically initialize built-in closures
by Ben Gamari (@bgamari) 26 Sep '25
by Ben Gamari (@bgamari) 26 Sep '25
26 Sep '25
Ben Gamari pushed to branch wip/T26166 at Glasgow Haskell Compiler / GHC
Commits:
22d8c926 by Ben Gamari at 2025-09-26T14:12:55-04:00
rts: Dynamically initialize built-in closures
To resolve #26166 we need to eliminate references to undefined symbols
in the runtime system. One such source of these is the runtime's
static references to `I#` and `C#` due the `stg_INTLIKE` and
`stg_CHARLIKE` arrays.
To avoid this we make these dynamic, initializing them during RTS
start-up.
- - - - -
591e0f30 by Ben Gamari at 2025-09-26T14:15:56-04:00
rts: Avoid static symbol references to ghc-internal
This is the first step towards resolving #26166, a bug due to new
constraints placed by Apple's linker on undefined references.
One source of such references in the RTS is the many symbols referenced
in ghc-internal. To mitigate #26166, we make these references dynamic,
as described in Note [RTS/ghc-internal interface].
- - - - -
26 changed files:
- compiler/GHC/HsToCore/Foreign/C.hs
- + libraries/ghc-internal/cbits/RtsIface.c
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/include/RtsIfaceSymbols.h
- + rts/BuiltinClosures.c
- + rts/BuiltinClosures.h
- rts/Compact.cmm
- rts/ContinuationOps.cmm
- rts/Exception.cmm
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/RtsAPI.c
- rts/RtsStartup.c
- + rts/RtsToHsIface.c
- rts/Schedule.c
- rts/StgMiscClosures.cmm
- rts/StgStdThunks.cmm
- rts/include/Rts.h
- rts/include/RtsAPI.h
- rts/include/rts/Constants.h
- + rts/include/rts/RtsToHsIface.h
- rts/include/stg/MiscClosures.h
- rts/posix/Signals.c
- rts/rts.cabal
- rts/wasm/JSFFI.c
- utils/deriveConstants/Main.hs
Changes:
=====================================
compiler/GHC/HsToCore/Foreign/C.hs
=====================================
@@ -517,8 +517,8 @@ mkFExportCBits dflags c_nm maybe_target arg_htys res_hty is_IO_res_ty cc
text "rts_apply" <> parens (
cap
<> (if is_IO_res_ty
- then text "runIO_closure"
- else text "runNonIO_closure")
+ then text "ghc_hs_iface->runIO_closure"
+ else text "ghc_hs_iface->runNonIO_closure")
<> comma
<> expr_to_run
) <+> comma
=====================================
libraries/ghc-internal/cbits/RtsIface.c
=====================================
@@ -0,0 +1,51 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+#include "Rts.h"
+
+void init_ghc_hs_iface(void) __attribute__((constructor));
+
+// Forward declarations
+#define CLOSURE(module, symbol) \
+ extern StgClosure ghczminternal_##module##_##symbol;
+
+#define UNDEF_CLOSURE(module, symbol)
+
+#define INFO_TBL(module, symbol) \
+ extern StgInfoTable ghczminternal_##module##_##symbol;
+
+#include "RtsIfaceSymbols.h"
+
+#undef CLOSURE
+#undef INFO_TBL
+
+// HsIface definition
+#define CLOSURE(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+#define UNDEF_CLOSURE(module, symbol) \
+ .symbol = NULL,
+
+#define INFO_TBL(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+HsIface the_ghc_hs_iface = {
+#include "RtsIfaceSymbols.h"
+};
+
+void init_ghc_hs_iface(void)
+{
+ /*
+ * N.B. ghc-internal may be load multiple times, e.g., when the
+ * RTS linker is in use. For this reason we explicitly refuse to
+ * override ghc_hs_iface if it has already been initialized.
+ */
+ if (ghc_hs_iface == NULL) {
+ ghc_hs_iface = &the_ghc_hs_iface;
+ }
+}
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -43,6 +43,7 @@ extra-source-files:
include/winio_structs.h
include/WordSize.h
include/HsIntegerGmp.h.in
+ include/RtsIfaceSymbols.h
install-sh
source-repository head
@@ -431,6 +432,8 @@ Library
if !arch(javascript)
+ -- See Note [RTS/ghc-internal interface].
+ ld-options: -uinit_ghc_hs_iface
c-sources:
cbits/DarwinUtils.c
cbits/PrelIOUtils.c
@@ -457,6 +460,7 @@ Library
cbits/vectorQuotRem.c
cbits/word2float.c
cbits/Stack_c.c
+ cbits/RtsIface.c
cmm-sources:
cbits/StackCloningDecoding.cmm
=====================================
libraries/ghc-internal/include/RtsIfaceSymbols.h
=====================================
@@ -0,0 +1,59 @@
+// See Note [RTS/ghc-internal interface].
+
+#if defined(mingw32_HOST_OS)
+CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#else
+UNDEF_CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#endif
+CLOSURE(GHCziInternalziTopHandler, runIO_closure)
+CLOSURE(GHCziInternalziTopHandler, runNonIO_closure)
+CLOSURE(GHCziInternalziTuple, Z0T_closure)
+CLOSURE(GHCziInternalziTypes, True_closure)
+CLOSURE(GHCziInternalziTypes, False_closure)
+CLOSURE(GHCziInternalziPack, unpackCString_closure)
+CLOSURE(GHCziInternalziWeakziFinalizze, runFinalizzerBatch_closure)
+CLOSURE(GHCziInternalziIOziException, stackOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, heapOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, allocationLimitExceeded_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnMVar_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnSTM_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactFunction_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactPinned_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactMutable_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nonTermination_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nestedAtomically_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, noMatchingContinuationPrompt_closure)
+CLOSURE(GHCziInternalziEventziThread, blockedOnBadFD_closure)
+CLOSURE(GHCziInternalziConcziSync, runSparks_closure)
+CLOSURE(GHCziInternalziConcziIO, ensureIOManagerIsRunning_closure)
+CLOSURE(GHCziInternalziConcziIO, interruptIOManager_closure)
+CLOSURE(GHCziInternalziConcziIO, ioManagerCapabilitiesChanged_closure)
+CLOSURE(GHCziInternalziConcziSignal, runHandlersPtr_closure)
+CLOSURE(GHCziInternalziTopHandler, flushStdHandles_closure)
+CLOSURE(GHCziInternalziTopHandler, runMainIO_closure)
+INFO_TBL(GHCziInternalziTypes, Czh_con_info)
+INFO_TBL(GHCziInternalziTypes, Izh_con_info)
+INFO_TBL(GHCziInternalziTypes, Fzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Dzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Wzh_con_info)
+CLOSURE(GHCziInternalziPrimziPanic, absentSumFieldError_closure)
+CLOSURE(GHCziInternalziAllocationLimitHandler, runAllocationLimitHandler_closure)
+INFO_TBL(GHCziInternalziPtr, Ptr_con_info)
+INFO_TBL(GHCziInternalziPtr, FunPtr_con_info)
+INFO_TBL(GHCziInternalziInt, I8zh_con_info)
+INFO_TBL(GHCziInternalziInt, I16zh_con_info)
+INFO_TBL(GHCziInternalziInt, I32zh_con_info)
+INFO_TBL(GHCziInternalziInt, I64zh_con_info)
+INFO_TBL(GHCziInternalziWord, W8zh_con_info)
+INFO_TBL(GHCziInternalziWord, W16zh_con_info)
+INFO_TBL(GHCziInternalziWord, W32zh_con_info)
+INFO_TBL(GHCziInternalziWord, W64zh_con_info)
+INFO_TBL(GHCziInternalziStable, StablePtr_con_info)
+CLOSURE(GHCziInternalziStackziCloneStack, StackSnapshot_closure)
+CLOSURE(GHCziInternalziExceptionziType, divZZeroException_closure)
+CLOSURE(GHCziInternalziExceptionziType, underflowException_closure)
+CLOSURE(GHCziInternalziExceptionziType, overflowException_closure)
+CLOSURE(GHCziInternalziCString, unpackCStringzh_closure)
+INFO_TBL(GHCziInternalziCString, unpackCStringzh_info)
+INFO_TBL(GHCziInternalziCString, unpackCStringUtf8zh_info)
+
=====================================
rts/BuiltinClosures.c
=====================================
@@ -0,0 +1,29 @@
+#include "Rts.h"
+#include "BuiltinClosures.h"
+
+/*
+ * Note [CHARLIKE and INTLIKE closures]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * These are static representations of Chars and small Ints, so that
+ * we can remove dynamic Chars and Ints during garbage collection and
+ * replace them with references to the static objects.
+ */
+
+StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
+StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+
+void initBuiltinClosures() {
+ // INTLIKE closures
+ for (int i = MIN_INTLIKE; i <= MAX_INTLIKE - MIN_INTLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_INTLIKE_closure[i];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Izh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = MIN_INTLIKE + i;
+ }
+
+ // CHARLIKE closures
+ for (int i = MIN_CHARLIKE; i <= MAX_CHARLIKE - MIN_CHARLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_CHARLIKE_closure[i];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Czh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = MIN_CHARLIKE + i;
+ }
+}
=====================================
rts/BuiltinClosures.h
=====================================
@@ -0,0 +1,14 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ */
+
+#pragma once
+
+#include "BeginPrivate.h"
+
+void initBuiltinClosures(void);
+
+#include "EndPrivate.h"
=====================================
rts/Compact.cmm
=====================================
@@ -10,9 +10,6 @@
#include "Cmm.h"
#include "sm/ShouldCompact.h"
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE g0;
import CLOSURE large_alloc_lim;
@@ -124,7 +121,7 @@ eval:
SMALL_MUT_ARR_PTRS_CLEAN,
SMALL_MUT_ARR_PTRS_DIRTY,
COMPACT_NFDATA: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
+ jump stg_raisezh(HsIface_cannotCompactMutable_closure(W_[ghc_hs_iface]));
}
// We shouldn't see any functions, if this data structure was NFData.
@@ -139,7 +136,7 @@ eval:
BCO,
PAP,
CONTINUATION: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
+ jump stg_raisezh(HsIface_cannotCompactFunction_closure(W_[ghc_hs_iface]));
}
case ARR_WORDS: {
@@ -147,7 +144,7 @@ eval:
(should) = ccall shouldCompact(compact "ptr", p "ptr");
if (should == SHOULDCOMPACT_IN_CNF) { P_[pp] = p; return(); }
if (should == SHOULDCOMPACT_PINNED) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
+ jump stg_raisezh(HsIface_cannotCompactPinned_closure(W_[ghc_hs_iface]));
}
CHECK_HASH();
=====================================
rts/ContinuationOps.cmm
=====================================
@@ -12,7 +12,6 @@
#include "Cmm.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE ALLOC_RTS_ctr;
import CLOSURE ALLOC_RTS_tot;
@@ -104,7 +103,7 @@ stg_control0zh_ll // explicit stack
// see Note [When capturing the continuation fails] in Continuation.c
if (cont == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure);
+ jump stg_raisezh(HsIface_noMatchingContinuationPrompt_closure(W_[ghc_hs_iface]));
}
W_ apply_mask_frame;
=====================================
rts/Exception.cmm
=====================================
@@ -13,10 +13,6 @@
#include "Cmm.h"
#include "RaiseAsync.h"
-import CLOSURE ghczminternal_GHCziInternalziTypes_True_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_underflowException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_overflowException_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE CATCHF_PUSHED_ctr;
import CLOSURE RtsFlags;
@@ -539,7 +535,7 @@ retry_pop_stack:
Sp(10) = exception;
Sp(9) = stg_raise_ret_info;
Sp(8) = exception;
- Sp(7) = ghczminternal_GHCziInternalziTypes_True_closure; // True <=> an exception
+ Sp(7) = HsIface_True_closure(W_[ghc_hs_iface]); // True <=> an exception
Sp(6) = stg_ap_ppv_info;
Sp(5) = 0;
Sp(4) = stg_ap_n_info;
@@ -650,17 +646,17 @@ stg_raiseIOzh (P_ exception)
stg_raiseDivZZerozh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
+ jump stg_raisezh(HsIface_divZZeroException_closure(W_[ghc_hs_iface]));
}
stg_raiseUnderflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
+ jump stg_raisezh(HsIface_underflowException_closure(W_[ghc_hs_iface]));
}
stg_raiseOverflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
+ jump stg_raisezh(HsIface_overflowException_closure(W_[ghc_hs_iface]));
}
/* The FFI doesn't support variadic C functions so we can't directly expose
=====================================
rts/Prelude.h
=====================================
@@ -19,126 +19,69 @@
#define PRELUDE_CLOSURE(i) extern StgClosure (i)
#endif
-/* See Note [Wired-in exceptions are not CAFfy] in GHC.Core.Make. */
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure);
/* Define canonical names so we can abstract away from the actual
* modules these names are defined in.
*/
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTuple_Z0T_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_True_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_False_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCString_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCStringUtf8_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeak_runFinalizzerBatch_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure);
-
#if defined(IN_STG_CODE)
extern W_ ZCMain_main_closure[];
#else
extern StgClosure ZCMain_main_closure;
#endif
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSync_runSparks_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure);
-#if defined(mingw32_HOST_OS)
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure);
-#endif
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziCString_unpackCStringzh_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Czh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Izh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Fzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Dzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Wzh_con_info);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_Ptr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_FunPtr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziStable_StablePtr_con_info);
-
-#define Unit_closure (&(ghczminternal_GHCziInternalziTuple_Z0T_closure))
-#define True_closure (&(ghczminternal_GHCziInternalziTypes_True_closure))
-#define False_closure (&(ghczminternal_GHCziInternalziTypes_False_closure))
-#define unpackCString_closure (&(ghczminternal_GHCziInternalziPack_unpackCString_closure))
-#define runFinalizerBatch_closure (&(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure))
+#define Unit_closure ghc_hs_iface->Z0T_closure
+#define True_closure ghc_hs_iface->True_closure
+#define False_closure ghc_hs_iface->False_closure
+#define unpackCString_closure ghc_hs_iface->unpackCString_closure
+#define runFinalizerBatch_closure ghc_hs_iface->runFinalizzerBatch_closure
#define mainIO_closure (&ZCMain_main_closure)
-#define runSparks_closure (&(ghczminternal_GHCziInternalziConcziSync_runSparks_closure))
-#define ensureIOManagerIsRunning_closure (&(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure))
-#define interruptIOManager_closure (&(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure))
-#define ioManagerCapabilitiesChanged_closure (&(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure))
-#define runHandlersPtr_closure (&(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure))
+#define runSparks_closure ghc_hs_iface->runSparks_closure
+#define ensureIOManagerIsRunning_closure ghc_hs_iface->ensureIOManagerIsRunning_closure
+#define interruptIOManager_closure ghc_hs_iface->interruptIOManager_closure
+#define ioManagerCapabilitiesChanged_closure ghc_hs_iface->ioManagerCapabilitiesChanged_closure
+#define runHandlersPtr_closure ghc_hs_iface->runHandlersPtr_closure
#if defined(mingw32_HOST_OS)
-#define processRemoteCompletion_closure (&(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure))
+#define processRemoteCompletion_closure ghc_hs_iface->processRemoteCompletion_closure
#endif
-#define runAllocationLimitHandler_closure (&(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure))
-
-#define flushStdHandles_closure (&(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure))
-#define runMainIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure))
-
-#define stackOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure))
-#define heapOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure))
-#define allocationLimitExceeded_closure (&(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure))
-#define blockedIndefinitelyOnMVar_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure))
-#define blockedIndefinitelyOnSTM_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure))
-#define cannotCompactFunction_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure))
-#define cannotCompactPinned_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure))
-#define cannotCompactMutable_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure))
-#define nonTermination_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure))
-#define nestedAtomically_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure))
-#define absentSumFieldError_closure (&(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure))
-#define underflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure))
-#define overflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure))
-#define divZeroException_closure (&(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure))
-
-#define blockedOnBadFD_closure (&(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure))
-
-#define Czh_con_info (&(ghczminternal_GHCziInternalziTypes_Czh_con_info))
-#define Izh_con_info (&(ghczminternal_GHCziInternalziTypes_Izh_con_info))
-#define Fzh_con_info (&(ghczminternal_GHCziInternalziTypes_Fzh_con_info))
-#define Dzh_con_info (&(ghczminternal_GHCziInternalziTypes_Dzh_con_info))
-#define Wzh_con_info (&(ghczminternal_GHCziInternalziTypes_Wzh_con_info))
-#define W8zh_con_info (&(ghczminternal_GHCziInternalziWord_W8zh_con_info))
-#define W16zh_con_info (&(ghczminternal_GHCziInternalziWord_W16zh_con_info))
-#define W32zh_con_info (&(ghczminternal_GHCziInternalziWord_W32zh_con_info))
-#define W64zh_con_info (&(ghczminternal_GHCziInternalziWord_W64zh_con_info))
-#define I8zh_con_info (&(ghczminternal_GHCziInternalziInt_I8zh_con_info))
-#define I16zh_con_info (&(ghczminternal_GHCziInternalziInt_I16zh_con_info))
-#define I32zh_con_info (&(ghczminternal_GHCziInternalziInt_I32zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define Ptr_con_info (&(ghczminternal_GHCziInternalziPtr_Ptr_con_info))
-#define FunPtr_con_info (&(ghczminternal_GHCziInternalziPtr_FunPtr_con_info))
-#define StablePtr_static_info (&(ghczminternal_GHCziInternalziStable_StablePtr_static_info))
-#define StablePtr_con_info (&(ghczminternal_GHCziInternalziStable_StablePtr_con_info))
+#define runAllocationLimitHandler_closure ghc_hs_iface->runAllocationLimitHandler_closure
+
+#define flushStdHandles_closure ghc_hs_iface->flushStdHandles_closure
+#define runMainIO_closure ghc_hs_iface->runMainIO_closure
+
+#define stackOverflow_closure ghc_hs_iface->stackOverflow_closure
+#define heapOverflow_closure ghc_hs_iface->heapOverflow_closure
+#define allocationLimitExceeded_closure ghc_hs_iface->allocationLimitExceeded_closure
+#define blockedIndefinitelyOnMVar_closure ghc_hs_iface->blockedIndefinitelyOnMVar_closure
+#define blockedIndefinitelyOnSTM_closure ghc_hs_iface->blockedIndefinitelyOnSTM_closure
+#define cannotCompactFunction_closure ghc_hs_iface->cannotCompactFunction_closure
+#define cannotCompactPinned_closure ghc_hs_iface->cannotCompactPinned_closure
+#define cannotCompactMutable_closure ghc_hs_iface->cannotCompactMutable_closure
+#define nonTermination_closure ghc_hs_iface->nonTermination_closure
+#define nestedAtomically_closure ghc_hs_iface->nestedAtomically_closure
+#define absentSumFieldError_closure ghc_hs_iface->absentSumFieldError_closure
+#define underflowException_closure ghc_hs_iface->underflowException_closure
+#define overflowException_closure ghc_hs_iface->overflowException_closure
+#define divZeroException_closure ghc_hs_iface->divZZeroException_closure
+
+#define blockedOnBadFD_closure ghc_hs_iface->blockedOnBadFD_closure
+
+#define Czh_con_info ghc_hs_iface->Czh_con_info
+#define Izh_con_info ghc_hs_iface->Izh_con_info
+#define Fzh_con_info ghc_hs_iface->Fzh_con_info
+#define Dzh_con_info ghc_hs_iface->Dzh_con_info
+#define Wzh_con_info ghc_hs_iface->Wzh_con_info
+#define W8zh_con_info ghc_hs_iface->W8zh_con_info
+#define W16zh_con_info ghc_hs_iface->W16zh_con_info
+#define W32zh_con_info ghc_hs_iface->W32zh_con_info
+#define W64zh_con_info ghc_hs_iface->W64zh_con_info
+#define I8zh_con_info ghc_hs_iface->I8zh_con_info
+#define I16zh_con_info ghc_hs_iface->I16zh_con_info
+#define I32zh_con_info ghc_hs_iface->I32zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define Ptr_con_info ghc_hs_iface->Ptr_con_info
+#define FunPtr_con_info ghc_hs_iface->FunPtr_con_info
+#define StablePtr_static_info ghc_hs_iface->StablePtr_static_info
+#define StablePtr_con_info ghc_hs_iface->StablePtr_con_info
=====================================
rts/PrimOps.cmm
=====================================
@@ -25,12 +25,8 @@
#include "MachDeps.h"
#include "SMPClosureOps.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_heapOverflow_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
-import CLOSURE ghczminternal_GHCziInternalziTypes_False_closure;
#if defined(PROFILING)
import CLOSURE CCS_MAIN;
#endif
@@ -118,7 +114,7 @@ stg_newByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytes(MyCapability() "ptr", n, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -135,7 +131,7 @@ stg_newPinnedByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
BA_ALIGN, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -149,7 +145,7 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
alignment, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -364,7 +360,7 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -474,7 +470,7 @@ stg_newSmallArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateSmallMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -1090,7 +1086,7 @@ stg_listThreadszh ()
("ptr" arr) = ccall listThreads(MyCapability() "ptr");
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (arr);
@@ -1360,7 +1356,7 @@ stg_atomicallyzh (P_ stm)
/* Nested transactions are not allowed; raise an exception */
if (old_trec != NO_TREC) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
+ jump stg_raisezh(HsIface_nestedAtomically_closure(W_[ghc_hs_iface]));
}
code = stm;
@@ -2231,7 +2227,7 @@ stg_unpackClosurezh ( P_ closure )
dat_arr_sz = SIZEOF_StgArrBytes + WDS(len);
("ptr" dat_arr) = ccall allocateMightFail(MyCapability() "ptr", BYTES_TO_WDS(dat_arr_sz));
if (dat_arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
TICK_ALLOC_PRIM(SIZEOF_StgArrBytes, WDS(len), 0);
@@ -2251,7 +2247,7 @@ for:
("ptr" ptrArray) = foreign "C" heap_view_closurePtrs(MyCapability() "ptr", clos "ptr");
if (ptrArray == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (info, dat_arr, ptrArray);
@@ -2518,13 +2514,13 @@ stg_getSparkzh ()
W_ spark;
#if !defined(THREADED_RTS)
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
#else
("ptr" spark) = ccall findSpark(MyCapability() "ptr");
if (spark != 0) {
return (1,spark);
} else {
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
}
#endif
}
=====================================
rts/RtsAPI.c
=====================================
@@ -509,7 +509,7 @@ void rts_evalStableIOMain(/* inout */ Capability **cap,
SchedulerStatus stat;
p = (StgClosure *)deRefStablePtr(s);
- w = rts_apply(*cap, &ghczminternal_GHCziInternalziTopHandler_runMainIO_closure, p);
+ w = rts_apply(*cap, runMainIO_closure, p);
tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, w);
// async exceptions are always blocked by default in the created
// thread. See #1048.
@@ -961,7 +961,7 @@ void rts_done (void)
void hs_try_putmvar (/* in */ int capability,
/* in */ HsStablePtr mvar)
{
- hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, Unit_closure));
+ hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure));
}
void hs_try_putmvar_with_value (/* in */ int capability,
=====================================
rts/RtsStartup.c
=====================================
@@ -14,6 +14,7 @@
#include "linker/MMap.h"
#include "RtsFlags.h"
#include "RtsUtils.h"
+#include "BuiltinClosures.h"
#include "Prelude.h"
#include "Printer.h" /* DEBUG_LoadSymbols */
#include "Schedule.h" /* initScheduler */
@@ -182,8 +183,8 @@ static void initBuiltinGcRoots(void)
* these closures `Id`s of these can be safely marked as non-CAFFY
* in the compiler.
*/
- getStablePtr((StgPtr)runIO_closure);
- getStablePtr((StgPtr)runNonIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runNonIO_closure);
getStablePtr((StgPtr)flushStdHandles_closure);
getStablePtr((StgPtr)runFinalizerBatch_closure);
@@ -262,6 +263,14 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
setlocale(LC_CTYPE,"");
+ if (ghc_hs_iface == NULL) {
+ errorBelch("hs_init_ghc: ghc_hs_iface is uninitialized");
+ stg_exit(1);
+ }
+
+
+ initBuiltinClosures();
+
/* Initialise the stats department, phase 0 */
initStats0();
=====================================
rts/RtsToHsIface.c
=====================================
@@ -0,0 +1,51 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ *
+ * Note [RTS/ghc-internal interface]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The runtime system depends upon a variety of symbols defined by Haskell
+ * modules living in `ghc-internal`. To avoid cyclic dependencies between
+ * ghc-internal and the RTS, these symbols are referenced indirectly via the
+ * the `HsIface` structure (specifically `ghc_hs_iface`):
+ *
+ * struct HsIface {
+ * StgClosure *runIO; // GHC.Internal.TopHandler.runIO
+ * StgClosure *Z0T; // GHC.Internal.Tuple.()
+ * // etc.
+ * };
+ *
+ * `ghc_hs_iface` is initialized during program loading via the
+ * `init_ghc_hs_iface` constructor in `ghc-interface`
+ *
+ * const struct HsIface the_hs_iface = {
+ * .runIO = &ghczminternal_GHCziInternalziTopHandler_runIO_closure,
+ * .Z0T = &ghczminternal_GHCziInternalziTuple_Z0T_closure,
+ * // etc.
+ * };
+ *
+ * void __attribute__((constructor)) init_ghc_hs_iface() {
+ * ghc_hs_iface = &the_hs_iface;
+ * }
+ *
+ * This effectively breaks the RTS's link-time dependency, replacing it with a
+ * run-time dependency at the cost of an indirection. It also has the pleasant
+ * side-effect of making the interface between the RTS and `ghc-internal`
+ * explicit.
+ *
+ * Note that the constructor is explicitly listed in `ld-options` of
+ * `ghc-internal.cabal` since we need to ensure that it is included
+ * in the final link, even when we link against `ghc-internal.a` (as
+ * only objects members which provide undefined symbols are included
+ * in the final object).
+ *
+ */
+
+#include "Rts.h"
+
+// This captures the symbols provided by ghc-internal which
+// are needed by the RTS.
+const HsIface *ghc_hs_iface = NULL;
=====================================
rts/Schedule.c
=====================================
@@ -1053,7 +1053,7 @@ scheduleProcessInbox (Capability **pcap USED_IF_THREADS)
while (p != NULL) {
pnext = p->link;
performTryPutMVar(cap, (StgMVar*)deRefStablePtr(p->mvar),
- Unit_closure);
+ ghc_hs_iface->Z0T_closure);
freeStablePtr(p->mvar);
stgFree(p);
p = pnext;
=====================================
rts/StgMiscClosures.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
import pthread_mutex_lock;
-import ghczminternal_GHCziInternalziTypes_Czh_info;
-import ghczminternal_GHCziInternalziTypes_Izh_info;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
@@ -23,7 +21,6 @@ import whitehole_lockClosure_spin;
import whitehole_lockClosure_yield;
#endif
-
#if !defined(UnregisterisedCompiler)
import CLOSURE CCS_SYSTEM;
import CLOSURE ENT_DYN_IND_ctr;
@@ -1031,554 +1028,3 @@ INFO_TABLE_CONSTR(stg_ASYNCIO_LIVE0,0,0,0,CONSTR_NOCAF,"ASYNCIO_LIVE0","ASYNCIO_
{ foreign "C" barf("ASYNCIO_LIVE0 object (%p) entered!", R1) never returns; }
CLOSURE(stg_ASYNCIO_LIVE0_closure,stg_ASYNCIO_LIVE0);
-
-/* ----------------------------------------------------------------------------
- Note [CHARLIKE and INTLIKE closures]
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- These are static representations of Chars and small Ints, so that
- we can remove dynamic Chars and Ints during garbage collection and
- replace them with references to the static objects.
- ------------------------------------------------------------------------- */
-
-#define Char_hash_con_info ghczminternal_GHCziInternalziTypes_Czh_con_info
-#define Int_hash_con_info ghczminternal_GHCziInternalziTypes_Izh_con_info
-
-#define CHARLIKE_HDR(n) CLOSURE(Char_hash_con_info, n)
-#define INTLIKE_HDR(n) CLOSURE(Int_hash_con_info, n)
-
-section "data" {
- stg_CHARLIKE_closure:
- CHARLIKE_HDR(0)
- CHARLIKE_HDR(1)
- CHARLIKE_HDR(2)
- CHARLIKE_HDR(3)
- CHARLIKE_HDR(4)
- CHARLIKE_HDR(5)
- CHARLIKE_HDR(6)
- CHARLIKE_HDR(7)
- CHARLIKE_HDR(8)
- CHARLIKE_HDR(9)
- CHARLIKE_HDR(10)
- CHARLIKE_HDR(11)
- CHARLIKE_HDR(12)
- CHARLIKE_HDR(13)
- CHARLIKE_HDR(14)
- CHARLIKE_HDR(15)
- CHARLIKE_HDR(16)
- CHARLIKE_HDR(17)
- CHARLIKE_HDR(18)
- CHARLIKE_HDR(19)
- CHARLIKE_HDR(20)
- CHARLIKE_HDR(21)
- CHARLIKE_HDR(22)
- CHARLIKE_HDR(23)
- CHARLIKE_HDR(24)
- CHARLIKE_HDR(25)
- CHARLIKE_HDR(26)
- CHARLIKE_HDR(27)
- CHARLIKE_HDR(28)
- CHARLIKE_HDR(29)
- CHARLIKE_HDR(30)
- CHARLIKE_HDR(31)
- CHARLIKE_HDR(32)
- CHARLIKE_HDR(33)
- CHARLIKE_HDR(34)
- CHARLIKE_HDR(35)
- CHARLIKE_HDR(36)
- CHARLIKE_HDR(37)
- CHARLIKE_HDR(38)
- CHARLIKE_HDR(39)
- CHARLIKE_HDR(40)
- CHARLIKE_HDR(41)
- CHARLIKE_HDR(42)
- CHARLIKE_HDR(43)
- CHARLIKE_HDR(44)
- CHARLIKE_HDR(45)
- CHARLIKE_HDR(46)
- CHARLIKE_HDR(47)
- CHARLIKE_HDR(48)
- CHARLIKE_HDR(49)
- CHARLIKE_HDR(50)
- CHARLIKE_HDR(51)
- CHARLIKE_HDR(52)
- CHARLIKE_HDR(53)
- CHARLIKE_HDR(54)
- CHARLIKE_HDR(55)
- CHARLIKE_HDR(56)
- CHARLIKE_HDR(57)
- CHARLIKE_HDR(58)
- CHARLIKE_HDR(59)
- CHARLIKE_HDR(60)
- CHARLIKE_HDR(61)
- CHARLIKE_HDR(62)
- CHARLIKE_HDR(63)
- CHARLIKE_HDR(64)
- CHARLIKE_HDR(65)
- CHARLIKE_HDR(66)
- CHARLIKE_HDR(67)
- CHARLIKE_HDR(68)
- CHARLIKE_HDR(69)
- CHARLIKE_HDR(70)
- CHARLIKE_HDR(71)
- CHARLIKE_HDR(72)
- CHARLIKE_HDR(73)
- CHARLIKE_HDR(74)
- CHARLIKE_HDR(75)
- CHARLIKE_HDR(76)
- CHARLIKE_HDR(77)
- CHARLIKE_HDR(78)
- CHARLIKE_HDR(79)
- CHARLIKE_HDR(80)
- CHARLIKE_HDR(81)
- CHARLIKE_HDR(82)
- CHARLIKE_HDR(83)
- CHARLIKE_HDR(84)
- CHARLIKE_HDR(85)
- CHARLIKE_HDR(86)
- CHARLIKE_HDR(87)
- CHARLIKE_HDR(88)
- CHARLIKE_HDR(89)
- CHARLIKE_HDR(90)
- CHARLIKE_HDR(91)
- CHARLIKE_HDR(92)
- CHARLIKE_HDR(93)
- CHARLIKE_HDR(94)
- CHARLIKE_HDR(95)
- CHARLIKE_HDR(96)
- CHARLIKE_HDR(97)
- CHARLIKE_HDR(98)
- CHARLIKE_HDR(99)
- CHARLIKE_HDR(100)
- CHARLIKE_HDR(101)
- CHARLIKE_HDR(102)
- CHARLIKE_HDR(103)
- CHARLIKE_HDR(104)
- CHARLIKE_HDR(105)
- CHARLIKE_HDR(106)
- CHARLIKE_HDR(107)
- CHARLIKE_HDR(108)
- CHARLIKE_HDR(109)
- CHARLIKE_HDR(110)
- CHARLIKE_HDR(111)
- CHARLIKE_HDR(112)
- CHARLIKE_HDR(113)
- CHARLIKE_HDR(114)
- CHARLIKE_HDR(115)
- CHARLIKE_HDR(116)
- CHARLIKE_HDR(117)
- CHARLIKE_HDR(118)
- CHARLIKE_HDR(119)
- CHARLIKE_HDR(120)
- CHARLIKE_HDR(121)
- CHARLIKE_HDR(122)
- CHARLIKE_HDR(123)
- CHARLIKE_HDR(124)
- CHARLIKE_HDR(125)
- CHARLIKE_HDR(126)
- CHARLIKE_HDR(127)
- CHARLIKE_HDR(128)
- CHARLIKE_HDR(129)
- CHARLIKE_HDR(130)
- CHARLIKE_HDR(131)
- CHARLIKE_HDR(132)
- CHARLIKE_HDR(133)
- CHARLIKE_HDR(134)
- CHARLIKE_HDR(135)
- CHARLIKE_HDR(136)
- CHARLIKE_HDR(137)
- CHARLIKE_HDR(138)
- CHARLIKE_HDR(139)
- CHARLIKE_HDR(140)
- CHARLIKE_HDR(141)
- CHARLIKE_HDR(142)
- CHARLIKE_HDR(143)
- CHARLIKE_HDR(144)
- CHARLIKE_HDR(145)
- CHARLIKE_HDR(146)
- CHARLIKE_HDR(147)
- CHARLIKE_HDR(148)
- CHARLIKE_HDR(149)
- CHARLIKE_HDR(150)
- CHARLIKE_HDR(151)
- CHARLIKE_HDR(152)
- CHARLIKE_HDR(153)
- CHARLIKE_HDR(154)
- CHARLIKE_HDR(155)
- CHARLIKE_HDR(156)
- CHARLIKE_HDR(157)
- CHARLIKE_HDR(158)
- CHARLIKE_HDR(159)
- CHARLIKE_HDR(160)
- CHARLIKE_HDR(161)
- CHARLIKE_HDR(162)
- CHARLIKE_HDR(163)
- CHARLIKE_HDR(164)
- CHARLIKE_HDR(165)
- CHARLIKE_HDR(166)
- CHARLIKE_HDR(167)
- CHARLIKE_HDR(168)
- CHARLIKE_HDR(169)
- CHARLIKE_HDR(170)
- CHARLIKE_HDR(171)
- CHARLIKE_HDR(172)
- CHARLIKE_HDR(173)
- CHARLIKE_HDR(174)
- CHARLIKE_HDR(175)
- CHARLIKE_HDR(176)
- CHARLIKE_HDR(177)
- CHARLIKE_HDR(178)
- CHARLIKE_HDR(179)
- CHARLIKE_HDR(180)
- CHARLIKE_HDR(181)
- CHARLIKE_HDR(182)
- CHARLIKE_HDR(183)
- CHARLIKE_HDR(184)
- CHARLIKE_HDR(185)
- CHARLIKE_HDR(186)
- CHARLIKE_HDR(187)
- CHARLIKE_HDR(188)
- CHARLIKE_HDR(189)
- CHARLIKE_HDR(190)
- CHARLIKE_HDR(191)
- CHARLIKE_HDR(192)
- CHARLIKE_HDR(193)
- CHARLIKE_HDR(194)
- CHARLIKE_HDR(195)
- CHARLIKE_HDR(196)
- CHARLIKE_HDR(197)
- CHARLIKE_HDR(198)
- CHARLIKE_HDR(199)
- CHARLIKE_HDR(200)
- CHARLIKE_HDR(201)
- CHARLIKE_HDR(202)
- CHARLIKE_HDR(203)
- CHARLIKE_HDR(204)
- CHARLIKE_HDR(205)
- CHARLIKE_HDR(206)
- CHARLIKE_HDR(207)
- CHARLIKE_HDR(208)
- CHARLIKE_HDR(209)
- CHARLIKE_HDR(210)
- CHARLIKE_HDR(211)
- CHARLIKE_HDR(212)
- CHARLIKE_HDR(213)
- CHARLIKE_HDR(214)
- CHARLIKE_HDR(215)
- CHARLIKE_HDR(216)
- CHARLIKE_HDR(217)
- CHARLIKE_HDR(218)
- CHARLIKE_HDR(219)
- CHARLIKE_HDR(220)
- CHARLIKE_HDR(221)
- CHARLIKE_HDR(222)
- CHARLIKE_HDR(223)
- CHARLIKE_HDR(224)
- CHARLIKE_HDR(225)
- CHARLIKE_HDR(226)
- CHARLIKE_HDR(227)
- CHARLIKE_HDR(228)
- CHARLIKE_HDR(229)
- CHARLIKE_HDR(230)
- CHARLIKE_HDR(231)
- CHARLIKE_HDR(232)
- CHARLIKE_HDR(233)
- CHARLIKE_HDR(234)
- CHARLIKE_HDR(235)
- CHARLIKE_HDR(236)
- CHARLIKE_HDR(237)
- CHARLIKE_HDR(238)
- CHARLIKE_HDR(239)
- CHARLIKE_HDR(240)
- CHARLIKE_HDR(241)
- CHARLIKE_HDR(242)
- CHARLIKE_HDR(243)
- CHARLIKE_HDR(244)
- CHARLIKE_HDR(245)
- CHARLIKE_HDR(246)
- CHARLIKE_HDR(247)
- CHARLIKE_HDR(248)
- CHARLIKE_HDR(249)
- CHARLIKE_HDR(250)
- CHARLIKE_HDR(251)
- CHARLIKE_HDR(252)
- CHARLIKE_HDR(253)
- CHARLIKE_HDR(254)
- CHARLIKE_HDR(255)
-}
-
-section "data" {
- stg_INTLIKE_closure:
- INTLIKE_HDR(-16) /* MIN_INTLIKE == -16 */
- INTLIKE_HDR(-15)
- INTLIKE_HDR(-14)
- INTLIKE_HDR(-13)
- INTLIKE_HDR(-12)
- INTLIKE_HDR(-11)
- INTLIKE_HDR(-10)
- INTLIKE_HDR(-9)
- INTLIKE_HDR(-8)
- INTLIKE_HDR(-7)
- INTLIKE_HDR(-6)
- INTLIKE_HDR(-5)
- INTLIKE_HDR(-4)
- INTLIKE_HDR(-3)
- INTLIKE_HDR(-2)
- INTLIKE_HDR(-1)
- INTLIKE_HDR(0)
- INTLIKE_HDR(1)
- INTLIKE_HDR(2)
- INTLIKE_HDR(3)
- INTLIKE_HDR(4)
- INTLIKE_HDR(5)
- INTLIKE_HDR(6)
- INTLIKE_HDR(7)
- INTLIKE_HDR(8)
- INTLIKE_HDR(9)
- INTLIKE_HDR(10)
- INTLIKE_HDR(11)
- INTLIKE_HDR(12)
- INTLIKE_HDR(13)
- INTLIKE_HDR(14)
- INTLIKE_HDR(15)
- INTLIKE_HDR(16)
- INTLIKE_HDR(17)
- INTLIKE_HDR(18)
- INTLIKE_HDR(19)
- INTLIKE_HDR(20)
- INTLIKE_HDR(21)
- INTLIKE_HDR(22)
- INTLIKE_HDR(23)
- INTLIKE_HDR(24)
- INTLIKE_HDR(25)
- INTLIKE_HDR(26)
- INTLIKE_HDR(27)
- INTLIKE_HDR(28)
- INTLIKE_HDR(29)
- INTLIKE_HDR(30)
- INTLIKE_HDR(31)
- INTLIKE_HDR(32)
- INTLIKE_HDR(33)
- INTLIKE_HDR(34)
- INTLIKE_HDR(35)
- INTLIKE_HDR(36)
- INTLIKE_HDR(37)
- INTLIKE_HDR(38)
- INTLIKE_HDR(39)
- INTLIKE_HDR(40)
- INTLIKE_HDR(41)
- INTLIKE_HDR(42)
- INTLIKE_HDR(43)
- INTLIKE_HDR(44)
- INTLIKE_HDR(45)
- INTLIKE_HDR(46)
- INTLIKE_HDR(47)
- INTLIKE_HDR(48)
- INTLIKE_HDR(49)
- INTLIKE_HDR(50)
- INTLIKE_HDR(51)
- INTLIKE_HDR(52)
- INTLIKE_HDR(53)
- INTLIKE_HDR(54)
- INTLIKE_HDR(55)
- INTLIKE_HDR(56)
- INTLIKE_HDR(57)
- INTLIKE_HDR(58)
- INTLIKE_HDR(59)
- INTLIKE_HDR(60)
- INTLIKE_HDR(61)
- INTLIKE_HDR(62)
- INTLIKE_HDR(63)
- INTLIKE_HDR(64)
- INTLIKE_HDR(65)
- INTLIKE_HDR(66)
- INTLIKE_HDR(67)
- INTLIKE_HDR(68)
- INTLIKE_HDR(69)
- INTLIKE_HDR(70)
- INTLIKE_HDR(71)
- INTLIKE_HDR(72)
- INTLIKE_HDR(73)
- INTLIKE_HDR(74)
- INTLIKE_HDR(75)
- INTLIKE_HDR(76)
- INTLIKE_HDR(77)
- INTLIKE_HDR(78)
- INTLIKE_HDR(79)
- INTLIKE_HDR(80)
- INTLIKE_HDR(81)
- INTLIKE_HDR(82)
- INTLIKE_HDR(83)
- INTLIKE_HDR(84)
- INTLIKE_HDR(85)
- INTLIKE_HDR(86)
- INTLIKE_HDR(87)
- INTLIKE_HDR(88)
- INTLIKE_HDR(89)
- INTLIKE_HDR(90)
- INTLIKE_HDR(91)
- INTLIKE_HDR(92)
- INTLIKE_HDR(93)
- INTLIKE_HDR(94)
- INTLIKE_HDR(95)
- INTLIKE_HDR(96)
- INTLIKE_HDR(97)
- INTLIKE_HDR(98)
- INTLIKE_HDR(99)
- INTLIKE_HDR(100)
- INTLIKE_HDR(101)
- INTLIKE_HDR(102)
- INTLIKE_HDR(103)
- INTLIKE_HDR(104)
- INTLIKE_HDR(105)
- INTLIKE_HDR(106)
- INTLIKE_HDR(107)
- INTLIKE_HDR(108)
- INTLIKE_HDR(109)
- INTLIKE_HDR(110)
- INTLIKE_HDR(111)
- INTLIKE_HDR(112)
- INTLIKE_HDR(113)
- INTLIKE_HDR(114)
- INTLIKE_HDR(115)
- INTLIKE_HDR(116)
- INTLIKE_HDR(117)
- INTLIKE_HDR(118)
- INTLIKE_HDR(119)
- INTLIKE_HDR(120)
- INTLIKE_HDR(121)
- INTLIKE_HDR(122)
- INTLIKE_HDR(123)
- INTLIKE_HDR(124)
- INTLIKE_HDR(125)
- INTLIKE_HDR(126)
- INTLIKE_HDR(127)
- INTLIKE_HDR(128)
- INTLIKE_HDR(129)
- INTLIKE_HDR(130)
- INTLIKE_HDR(131)
- INTLIKE_HDR(132)
- INTLIKE_HDR(133)
- INTLIKE_HDR(134)
- INTLIKE_HDR(135)
- INTLIKE_HDR(136)
- INTLIKE_HDR(137)
- INTLIKE_HDR(138)
- INTLIKE_HDR(139)
- INTLIKE_HDR(140)
- INTLIKE_HDR(141)
- INTLIKE_HDR(142)
- INTLIKE_HDR(143)
- INTLIKE_HDR(144)
- INTLIKE_HDR(145)
- INTLIKE_HDR(146)
- INTLIKE_HDR(147)
- INTLIKE_HDR(148)
- INTLIKE_HDR(149)
- INTLIKE_HDR(150)
- INTLIKE_HDR(151)
- INTLIKE_HDR(152)
- INTLIKE_HDR(153)
- INTLIKE_HDR(154)
- INTLIKE_HDR(155)
- INTLIKE_HDR(156)
- INTLIKE_HDR(157)
- INTLIKE_HDR(158)
- INTLIKE_HDR(159)
- INTLIKE_HDR(160)
- INTLIKE_HDR(161)
- INTLIKE_HDR(162)
- INTLIKE_HDR(163)
- INTLIKE_HDR(164)
- INTLIKE_HDR(165)
- INTLIKE_HDR(166)
- INTLIKE_HDR(167)
- INTLIKE_HDR(168)
- INTLIKE_HDR(169)
- INTLIKE_HDR(170)
- INTLIKE_HDR(171)
- INTLIKE_HDR(172)
- INTLIKE_HDR(173)
- INTLIKE_HDR(174)
- INTLIKE_HDR(175)
- INTLIKE_HDR(176)
- INTLIKE_HDR(177)
- INTLIKE_HDR(178)
- INTLIKE_HDR(179)
- INTLIKE_HDR(180)
- INTLIKE_HDR(181)
- INTLIKE_HDR(182)
- INTLIKE_HDR(183)
- INTLIKE_HDR(184)
- INTLIKE_HDR(185)
- INTLIKE_HDR(186)
- INTLIKE_HDR(187)
- INTLIKE_HDR(188)
- INTLIKE_HDR(189)
- INTLIKE_HDR(190)
- INTLIKE_HDR(191)
- INTLIKE_HDR(192)
- INTLIKE_HDR(193)
- INTLIKE_HDR(194)
- INTLIKE_HDR(195)
- INTLIKE_HDR(196)
- INTLIKE_HDR(197)
- INTLIKE_HDR(198)
- INTLIKE_HDR(199)
- INTLIKE_HDR(200)
- INTLIKE_HDR(201)
- INTLIKE_HDR(202)
- INTLIKE_HDR(203)
- INTLIKE_HDR(204)
- INTLIKE_HDR(205)
- INTLIKE_HDR(206)
- INTLIKE_HDR(207)
- INTLIKE_HDR(208)
- INTLIKE_HDR(209)
- INTLIKE_HDR(210)
- INTLIKE_HDR(211)
- INTLIKE_HDR(212)
- INTLIKE_HDR(213)
- INTLIKE_HDR(214)
- INTLIKE_HDR(215)
- INTLIKE_HDR(216)
- INTLIKE_HDR(217)
- INTLIKE_HDR(218)
- INTLIKE_HDR(219)
- INTLIKE_HDR(220)
- INTLIKE_HDR(221)
- INTLIKE_HDR(222)
- INTLIKE_HDR(223)
- INTLIKE_HDR(224)
- INTLIKE_HDR(225)
- INTLIKE_HDR(226)
- INTLIKE_HDR(227)
- INTLIKE_HDR(228)
- INTLIKE_HDR(229)
- INTLIKE_HDR(230)
- INTLIKE_HDR(231)
- INTLIKE_HDR(232)
- INTLIKE_HDR(233)
- INTLIKE_HDR(234)
- INTLIKE_HDR(235)
- INTLIKE_HDR(236)
- INTLIKE_HDR(237)
- INTLIKE_HDR(238)
- INTLIKE_HDR(239)
- INTLIKE_HDR(240)
- INTLIKE_HDR(241)
- INTLIKE_HDR(242)
- INTLIKE_HDR(243)
- INTLIKE_HDR(244)
- INTLIKE_HDR(245)
- INTLIKE_HDR(246)
- INTLIKE_HDR(247)
- INTLIKE_HDR(248)
- INTLIKE_HDR(249)
- INTLIKE_HDR(250)
- INTLIKE_HDR(251)
- INTLIKE_HDR(252)
- INTLIKE_HDR(253)
- INTLIKE_HDR(254)
- INTLIKE_HDR(255) /* MAX_INTLIKE == 255
- See #16961 for why 255 */
-}
=====================================
rts/StgStdThunks.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
#include "Updates.h"
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringzh_info;
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info;
#if !defined(UnregisterisedCompiler)
import CLOSURE STK_CHK_ctr;
import CLOSURE stg_bh_upd_frame_info;
@@ -348,7 +346,7 @@ stg_do_unpack_cstring(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringzh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringzh_info(W_[ghc_hs_iface]))(node, str);
}
}
@@ -372,7 +370,7 @@ stg_do_unpack_cstring_utf8(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringUtf8zh_info(W_[ghc_hs_iface]))(node, str);
}
}
=====================================
rts/include/Rts.h
=====================================
@@ -229,6 +229,7 @@ void _warnFail(const char *filename, unsigned int linenum);
#include "rts/storage/ClosureTypes.h"
#include "rts/storage/TSO.h"
#include "stg/MiscClosures.h" /* InfoTables, closures etc. defined in the RTS */
+
#include "rts/storage/Block.h"
#include "rts/storage/ClosureMacros.h"
#include "rts/storage/MBlock.h"
=====================================
rts/include/RtsAPI.h
=====================================
@@ -18,6 +18,7 @@ extern "C" {
#include "HsFFI.h"
#include "rts/Time.h"
#include "rts/Types.h"
+#include "rts/RtsToHsIface.h"
/*
* Running the scheduler
@@ -584,11 +585,6 @@ void rts_done (void);
// Note that RtsAPI.h is also included by foreign export stubs in
// the base package itself.
//
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runIO_closure;
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runNonIO_closure;
-
-#define runIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runIO_closure))
-#define runNonIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runNonIO_closure))
/* ------------------------------------------------------------------------ */
=====================================
rts/include/rts/Constants.h
=====================================
@@ -57,11 +57,12 @@
#define MAX_SPEC_CONSTR_SIZE 2
/* Range of built-in table of static small int-like and char-like closures.
+ * Range is inclusive of both minimum and maximum.
*
* NB. This corresponds with the number of actual INTLIKE/CHARLIKE
* closures defined in rts/StgMiscClosures.cmm.
*/
-#define MAX_INTLIKE 255
+#define MAX_INTLIKE 255 /* See #16961 for why 255 */
#define MIN_INTLIKE (-16)
#define MAX_CHARLIKE 255
=====================================
rts/include/rts/RtsToHsIface.h
=====================================
@@ -0,0 +1,64 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+typedef struct {
+ StgClosure *processRemoteCompletion_closure; // GHC.Internal.Event.Windows.processRemoteCompletion_closure
+ StgClosure *runIO_closure; // GHC.Internal.TopHandler.runIO_closure
+ StgClosure *runNonIO_closure; // GHC.Internal.TopHandler.runNonIO_closure
+ StgClosure *Z0T_closure; // GHC.Internal.Tuple.Z0T_closure
+ StgClosure *True_closure; // GHC.Internal.Types.True_closure
+ StgClosure *False_closure; // GHC.Internal.Types.False_closure
+ StgClosure *unpackCString_closure; // GHC.Internal.Pack.unpackCString_closure
+ StgClosure *runFinalizzerBatch_closure; // GHC.Internal.Weak.Finalizze.runFinalizzerBatch_closure
+ StgClosure *stackOverflow_closure; // GHC.Internal.IO.Exception.stackOverflow_closure
+ StgClosure *heapOverflow_closure; // GHC.Internal.IO.Exception.heapOverflow_closure
+ StgClosure *allocationLimitExceeded_closure; // GHC.Internal.IO.Exception.allocationLimitExceeded_closure
+ StgClosure *blockedIndefinitelyOnMVar_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnMVar_closure
+ StgClosure *blockedIndefinitelyOnSTM_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnSTM_closure
+ StgClosure *cannotCompactFunction_closure; // GHC.Internal.IO.Exception.cannotCompactFunction_closure
+ StgClosure *cannotCompactPinned_closure; // GHC.Internal.IO.Exception.cannotCompactPinned_closure
+ StgClosure *cannotCompactMutable_closure; // GHC.Internal.IO.Exception.cannotCompactMutable_closure
+ StgClosure *nonTermination_closure; // GHC.Internal.Control.Exception.Base.nonTermination_closure
+ StgClosure *nestedAtomically_closure; // GHC.Internal.Control.Exception.Base.nestedAtomically_closure
+ StgClosure *noMatchingContinuationPrompt_closure; // GHC.Internal.Control.Exception.Base.noMatchingContinuationPrompt_closure
+ StgClosure *blockedOnBadFD_closure; // GHC.Internal.Event.Thread.blockedOnBadFD_closure
+ StgClosure *runSparks_closure; // GHC.Internal.Conc.Sync.runSparks_closure
+ StgClosure *ensureIOManagerIsRunning_closure; // GHC.Internal.Conc.IO.ensureIOManagerIsRunning_closure
+ StgClosure *interruptIOManager_closure; // GHC.Internal.Conc.IO.interruptIOManager_closure
+ StgClosure *ioManagerCapabilitiesChanged_closure; // GHC.Internal.Conc.IO.ioManagerCapabilitiesChanged_closure
+ StgClosure *runHandlersPtr_closure; // GHC.Internal.Conc.Signal.runHandlersPtr_closure
+ StgClosure *flushStdHandles_closure; // GHC.Internal.TopHandler.flushStdHandles_closure
+ StgClosure *runMainIO_closure; // GHC.Internal.TopHandler.runMainIO_closure
+ StgInfoTable *Czh_con_info; // GHC.Internal.Types.Czh_con_info
+ StgInfoTable *Izh_con_info; // GHC.Internal.Types.Izh_con_info
+ StgInfoTable *Fzh_con_info; // GHC.Internal.Types.Fzh_con_info
+ StgInfoTable *Dzh_con_info; // GHC.Internal.Types.Dzh_con_info
+ StgInfoTable *Wzh_con_info; // GHC.Internal.Types.Wzh_con_info
+ StgClosure *absentSumFieldError_closure; // GHC.Internal.Prim.Panic.absentSumFieldError_closure
+ StgClosure *runAllocationLimitHandler_closure; // GHC.Internal.AllocationLimitHandler.runAllocationLimitHandler_closure
+ StgInfoTable *Ptr_con_info; // GHC.Internal.Ptr.Ptr_con_info
+ StgInfoTable *FunPtr_con_info; // GHC.Internal.Ptr.FunPtr_con_info
+ StgInfoTable *I8zh_con_info; // GHC.Internal.Int.I8zh_con_info
+ StgInfoTable *I16zh_con_info; // GHC.Internal.Int.I16zh_con_info
+ StgInfoTable *I32zh_con_info; // GHC.Internal.Int.I32zh_con_info
+ StgInfoTable *I64zh_con_info; // GHC.Internal.Int.I64zh_con_info
+ StgInfoTable *W8zh_con_info; // GHC.Internal.Word.W8zh_con_info
+ StgInfoTable *W16zh_con_info; // GHC.Internal.Word.W16zh_con_info
+ StgInfoTable *W32zh_con_info; // GHC.Internal.Word.W32zh_con_info
+ StgInfoTable *W64zh_con_info; // GHC.Internal.Word.W64zh_con_info
+ StgInfoTable *StablePtr_con_info; // GHC.Internal.Stable.StablePtr_con_info
+ StgClosure *StackSnapshot_closure; // GHC.Internal.Stack.CloneStack.StackSnapshot_closure
+ StgClosure *divZZeroException_closure; // GHC.Internal.Exception.Type.divZeroException_closure
+ StgClosure *underflowException_closure; // GHC.Internal.Exception.Type.underflowException_closure
+ StgClosure *overflowException_closure; // GHC.Internal.Exception.Type.overflowException_closure
+ StgClosure *unpackCStringzh_closure; // GHC.Internal.CString.unpackCStringzh_closure
+ StgInfoTable *unpackCStringzh_info; // GHC.Internal.CString.unpackCStringzh_info
+ StgInfoTable *unpackCStringUtf8zh_info; // GHC.Internal.CString.unpackCStringUtf8zh_info
+} HsIface;
+
+extern const HsIface *ghc_hs_iface;
=====================================
rts/include/stg/MiscClosures.h
=====================================
@@ -277,8 +277,8 @@ RTS_ENTRY(stg_NO_FINALIZER);
extern StgWordArray stg_CHARLIKE_closure;
extern StgWordArray stg_INTLIKE_closure;
#else
-extern StgIntCharlikeClosure stg_CHARLIKE_closure[];
-extern StgIntCharlikeClosure stg_INTLIKE_closure[];
+extern StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+extern StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
#endif
/* StgStartup */
=====================================
rts/posix/Signals.c
=====================================
@@ -222,7 +222,7 @@ ioManagerDie (void)
void
ioManagerStartCap (Capability **cap)
{
- rts_evalIO(cap,&ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure,NULL);
+ rts_evalIO(cap,ensureIOManagerIsRunning_closure,NULL);
}
void
@@ -493,7 +493,7 @@ startSignalHandlers(Capability *cap)
RtsFlags.GcFlags.initialStkSize,
rts_apply(cap,
rts_apply(cap,
- &ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure,
+ runHandlersPtr_closure,
rts_mkPtr(cap, info)),
rts_mkInt(cap, info->si_signo)));
scheduleThread(cap, t);
=====================================
rts/rts.cabal
=====================================
@@ -334,6 +334,7 @@ library
rts/storage/InfoTables.h
rts/storage/MBlock.h
rts/storage/TSO.h
+ rts/RtsToHsIface.h
stg/MachRegs.h
stg/MachRegs/arm32.h
stg/MachRegs/arm64.h
@@ -403,6 +404,7 @@ library
adjustor/AdjustorPool.c
ExecPage.c
Arena.c
+ BuiltinClosures.c
Capability.c
CheckUnload.c
CheckVectorSupport.c
@@ -448,6 +450,7 @@ library
RtsStartup.c
RtsSymbolInfo.c
RtsSymbols.c
+ RtsToHsIface.c
RtsUtils.c
STM.c
Schedule.c
=====================================
rts/wasm/JSFFI.c
=====================================
@@ -23,8 +23,8 @@ int __main_argc_argv(int argc, char *argv[]) {
hs_init_ghc(&argc, &argv, __conf);
// See Note [threadDelay on wasm] for details.
rts_JSFFI_flag = HS_BOOL_TRUE;
- getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
- rts_threadDelay_impl = getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->raiseJSException_closure);
+ rts_threadDelay_impl = getStablePtr((StgPtr)ghc_hs_iface->threadDelay_closure);
return 0;
}
@@ -112,7 +112,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
SET_HDR(w, &stg_WEAK_info, CCS_SYSTEM);
w->cfinalizers = (StgClosure *)cfin;
w->key = p;
- w->value = Unit_closure;
+ w->value = ghc_hs_iface->Z0T_closure;
w->finalizer = &stg_NO_FINALIZER_closure;
w->link = cap->weak_ptr_list_hd;
cap->weak_ptr_list_hd = w;
@@ -123,7 +123,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
p->payload[0] = (HaskellObj)w;
HaskellObj box = (HaskellObj)allocate(cap, CONSTR_sizeW(1, 0));
- SET_HDR(box, &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info, CCS_SYSTEM);
+ SET_HDR(box, ghc_hs_iface->JSVal_con_info, CCS_SYSTEM);
box->payload[0] = p;
return TAG_CLOSURE(1, box);
@@ -139,7 +139,7 @@ STATIC_INLINE HsJSVal rts_getJSValzh(HaskellObj p) {
HsJSVal rts_getJSVal(HaskellObj);
HsJSVal rts_getJSVal(HaskellObj box) {
- ASSERT(UNTAG_CLOSURE(box)->header.info == &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info);
+ ASSERT(UNTAG_CLOSURE(box)->header.info == ghc_hs_iface->JSVal_con_info);
return rts_getJSValzh(UNTAG_CLOSURE(box)->payload[0]);
}
@@ -188,7 +188,7 @@ void rts_schedulerLoop(void) {
__attribute__((export_name("rts_promiseResolveUnit")))
void rts_promiseResolveUnit(HsStablePtr);
void rts_promiseResolveUnit(HsStablePtr sp)
- mk_rtsPromiseCallback(TAG_CLOSURE(1, Unit_closure))
+ mk_rtsPromiseCallback(TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure))
mk_rtsPromiseResolve(JSVal)
mk_rtsPromiseResolve(Char)
@@ -212,7 +212,7 @@ mk_rtsPromiseResolve(Bool)
__attribute__((export_name("rts_promiseReject")))
void rts_promiseReject(HsStablePtr, HsJSVal);
void rts_promiseReject(HsStablePtr sp, HsJSVal js_err)
- mk_rtsPromiseCallback(rts_apply(cap, &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure, rts_mkJSVal(cap, js_err)))
+ mk_rtsPromiseCallback(rts_apply(cap, ghc_hs_iface->raiseJSException_closure, rts_mkJSVal(cap, js_err)))
__attribute__((export_name("rts_promiseThrowTo")))
void rts_promiseThrowTo(HsStablePtr, HsJSVal);
@@ -229,7 +229,7 @@ void rts_promiseThrowTo(HsStablePtr sp, HsJSVal js_err) {
cap, tso,
rts_apply(
cap,
- &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure,
+ ghc_hs_iface->raiseJSException_closure,
rts_mkJSVal(cap, js_err)));
tryWakeupThread(cap, tso);
rts_schedulerLoop();
=====================================
utils/deriveConstants/Main.hs
=====================================
@@ -667,6 +667,59 @@ wanteds os = concat
,structField C "StgAsyncIOResult" "errCode"]
else []
+ -- struct HsIface
+ ,structField C "HsIface" "processRemoteCompletion_closure"
+ ,structField C "HsIface" "runIO_closure"
+ ,structField C "HsIface" "runNonIO_closure"
+ ,structField C "HsIface" "Z0T_closure"
+ ,structField C "HsIface" "True_closure"
+ ,structField C "HsIface" "False_closure"
+ ,structField C "HsIface" "unpackCString_closure"
+ ,structField C "HsIface" "runFinalizzerBatch_closure"
+ ,structField C "HsIface" "stackOverflow_closure"
+ ,structField C "HsIface" "heapOverflow_closure"
+ ,structField C "HsIface" "allocationLimitExceeded_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnMVar_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnSTM_closure"
+ ,structField C "HsIface" "cannotCompactFunction_closure"
+ ,structField C "HsIface" "cannotCompactPinned_closure"
+ ,structField C "HsIface" "cannotCompactMutable_closure"
+ ,structField C "HsIface" "nonTermination_closure"
+ ,structField C "HsIface" "nestedAtomically_closure"
+ ,structField C "HsIface" "noMatchingContinuationPrompt_closure"
+ ,structField C "HsIface" "blockedOnBadFD_closure"
+ ,structField C "HsIface" "runSparks_closure"
+ ,structField C "HsIface" "ensureIOManagerIsRunning_closure"
+ ,structField C "HsIface" "interruptIOManager_closure"
+ ,structField C "HsIface" "ioManagerCapabilitiesChanged_closure"
+ ,structField C "HsIface" "runHandlersPtr_closure"
+ ,structField C "HsIface" "flushStdHandles_closure"
+ ,structField C "HsIface" "runMainIO_closure"
+ ,structField C "HsIface" "Czh_con_info"
+ ,structField C "HsIface" "Izh_con_info"
+ ,structField C "HsIface" "Fzh_con_info"
+ ,structField C "HsIface" "Dzh_con_info"
+ ,structField C "HsIface" "Wzh_con_info"
+ ,structField C "HsIface" "runAllocationLimitHandler_closure"
+ ,structField C "HsIface" "Ptr_con_info"
+ ,structField C "HsIface" "FunPtr_con_info"
+ ,structField C "HsIface" "I8zh_con_info"
+ ,structField C "HsIface" "I16zh_con_info"
+ ,structField C "HsIface" "I32zh_con_info"
+ ,structField C "HsIface" "I64zh_con_info"
+ ,structField C "HsIface" "W8zh_con_info"
+ ,structField C "HsIface" "W16zh_con_info"
+ ,structField C "HsIface" "W32zh_con_info"
+ ,structField C "HsIface" "W64zh_con_info"
+ ,structField C "HsIface" "StablePtr_con_info"
+ ,structField C "HsIface" "StackSnapshot_closure"
+ ,structField C "HsIface" "divZZeroException_closure"
+ ,structField C "HsIface" "underflowException_closure"
+ ,structField C "HsIface" "overflowException_closure"
+ ,structField C "HsIface" "unpackCStringzh_closure"
+ ,structField C "HsIface" "unpackCStringzh_info"
+ ,structField C "HsIface" "unpackCStringUtf8zh_info"
+
-- pre-compiled thunk types
,constantWord Haskell "MAX_SPEC_SELECTEE_SIZE" "MAX_SPEC_SELECTEE_SIZE"
,constantWord Haskell "MAX_SPEC_AP_SIZE" "MAX_SPEC_AP_SIZE"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b7898eb22b9a2b0ea81e43514761a…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b7898eb22b9a2b0ea81e43514761a…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc] Pushed new branch wip/supersven/test-master-full-ci
by Sven Tennie (@supersven) 26 Sep '25
by Sven Tennie (@supersven) 26 Sep '25
26 Sep '25
Sven Tennie pushed new branch wip/supersven/test-master-full-ci at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/supersven/test-master-full-ci
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/jeltsch/obtaining-os-handles] 138 commits: Comments only
by Wolfgang Jeltsch (@jeltsch) 26 Sep '25
by Wolfgang Jeltsch (@jeltsch) 26 Sep '25
26 Sep '25
Wolfgang Jeltsch pushed to branch wip/jeltsch/obtaining-os-handles at Glasgow Haskell Compiler / GHC
Commits:
00478944 by Simon Peyton Jones at 2025-08-27T16:48:30+01:00
Comments only
- - - - -
a7884589 by Simon Peyton Jones at 2025-08-28T11:08:23+01:00
Type-family occurs check in unification
The occurs check in `GHC.Core.Unify.uVarOrFam` was inadequate in dealing
with type families.
Better now. See Note [The occurs check in the Core unifier].
As I did this I realised that the whole apartness thing is trickier than I
thought: see the new Note [Shortcomings of the apartness test]
- - - - -
8adfc222 by sheaf at 2025-08-28T19:47:17-04:00
Fix orientation in HsWrapper composition (<.>)
This commit fixes the order in which WpCast HsWrappers are composed,
fixing a bug introduced in commit 56b32c5a2d5d7cad89a12f4d74dc940e086069d1.
Fixes #26350
- - - - -
eb2ab1e2 by Oleg Grenrus at 2025-08-29T11:00:53-04:00
Generalise thNameToGhcName by adding HasHscEnv
There were multiple single monad-specific `getHscEnv` across codebase.
HasHscEnv is modelled on HasDynFlags.
My first idea was to simply add thNameToGhcNameHsc and
thNameToGhcNameTc, but those would been exactly the same
as thNameToGhcName already.
Also add an usage example to thNameToGhcName and mention that it's
recommended way of looking up names in GHC plugins
- - - - -
2d575a7f by fendor at 2025-08-29T11:01:36-04:00
configure: Bump minimal bootstrap GHC version to 9.10
- - - - -
716274a5 by Simon Peyton Jones at 2025-08-29T17:27:12-04:00
Fix deep subsumption again
This commit fixed #26255:
commit 56b32c5a2d5d7cad89a12f4d74dc940e086069d1
Author: sheaf <sam.derbyshire(a)gmail.com>
Date: Mon Aug 11 15:50:47 2025 +0200
Improve deep subsumption
This commit improves the DeepSubsumption sub-typing implementation
in GHC.Tc.Utils.Unify.tc_sub_type_deep by being less eager to fall back
to unification.
But alas it still wasn't quite right for view patterns: #26331
This MR does a generalisation to fix it. A bit of a sledgehammer to crack
a nut, but nice.
* Add a field `ir_inst :: InferInstFlag` to `InferResult`, where
```
data InferInstFlag = IIF_Sigma | IIF_ShallowRho | IIF_DeepRho
```
* The flag says exactly how much `fillInferResult` should instantiate
before filling the hole.
* We can also use this to replace the previous very ad-hoc `tcInferSigma`
that was used to implement GHCi's `:type` command.
- - - - -
27206c5e by sheaf at 2025-08-29T17:28:14-04:00
Back-compat for TH SpecialiseP data-con of Pragma
This commit improves the backwards-compatibility story for the
SpecialiseP constructor of the Template Haskell 'Pragma' datatype.
Instead of keeping the constructor but deprecating it, this commit makes
it into a bundled pattern synonym of the Pragma datatype. We no longer
deprecate it; it's useful for handling old-form specialise pragmas.
- - - - -
26dbcf61 by fendor at 2025-08-30T05:10:08-04:00
Move stack decoding logic from ghc-heap to ghc-internal
The stack decoding logic in `ghc-heap` is more sophisticated than the one
currently employed in `CloneStack`. We want to use the stack decoding
implementation from `ghc-heap` in `base`.
We cannot simply depend on `ghc-heap` in `base` due do bootstrapping
issues.
Thus, we move the code that is necessary to implement stack decoding to
`ghc-internal`. This is the right location, as we don't want to add a
new API to `base`.
Moving the stack decoding logic and re-exposing it in ghc-heap is
insufficient, though, as we have a dependency cycle between.
* ghc-heap depends on stage1:ghc-internal
* stage0:ghc depends on stage0:ghc-heap
To fix this, we remove ghc-heap from the set of `stage0` dependencies.
This is not entirely straight-forward, as a couple of boot dependencies,
such as `ghci` depend on `ghc-heap`.
Luckily, the boot compiler of GHC is now >=9.10, so we can migrate `ghci`
to use `ghc-internal` instead of `ghc-heap`, which already exports the
relevant modules.
However, we cannot 100% remove ghc's dependency on `ghc-heap`, since
when we compile `stage0:ghc`, `stage1:ghc-internal` is not yet
available.
Thus, when we compile with the boot-compiler, we still depend on an
older version of `ghc-heap`, and only use the modules from `ghc-internal`,
if the `ghc-internal` version is recent enough.
-------------------------
Metric Increase:
T24602_perf_size
T25046_perf_size_gzip
T25046_perf_size_unicode
T25046_perf_size_unicode_gzip
size_hello_artifact
size_hello_artifact_gzip
size_hello_unicode
size_hello_unicode_gzip
-------------------------
These metric increases are unfortunate, they are most likely caused by
the larger (literally in terms of lines of code) stack decoder implementation
that are now linked into hello-word binaries.
On linux, it is almost a 10% increase, which is considerable.
- - - - -
bd80bb70 by fendor at 2025-08-30T05:10:08-04:00
Implement `decode` in terms of `decodeStackWithIpe`
Uses the more efficient stack decoder implementation.
- - - - -
24441165 by fendor at 2025-08-30T05:10:08-04:00
Remove stg_decodeStackzh
- - - - -
fb9cc882 by Simon Peyton Jones at 2025-08-30T05:10:51-04:00
Fix a long standing bug in the coercion optimiser
We were mis-optimising ForAllCo, leading to #26345
Part of the poblem was the tricky tower of abstractions leading to
the dreadful
GHC.Core.TyCo.Subst.substForAllCoTyVarBndrUsing
This function was serving two masters: regular substitution, but also
coercion optimsation. So tricky was it that it did so wrong.
In this MR I locate all the fancy footwork for coercion optimisation
in GHC.Core.Coercion.Opt, where it belongs. That leaves substitution
free to be much simpler.
- - - - -
6c78de2d by Sylvain Henry at 2025-09-01T08:46:19-04:00
Driver: substitute virtual Prim module in --make mode too
When we build ghc-internal with --make (e.g. with cabal-install), we
need to be careful to substitute the virtual interface file for
GHC.Internal.Prim:
- after code generation (we generate code for an empty module, so we get
an empty interface)
- when we try to reload its .hi file
- - - - -
26e0db16 by fendor at 2025-09-01T08:47:01-04:00
Expose Stack Annotation frames in IPE backtraces by default
When decoding the Haskell-native call stack and displaying the IPE information
for the stack frames, we print the `StackAnnotation` of the `AnnFrame` by default.
This means, when an exception is thrown, any intermediate stack annotations will
be displayed in the `IPE Backtrace`.
Example backtrace:
```
Exception: ghc-internal:GHC.Internal.Exception.ErrorCall:
Oh no!
IPE backtrace:
annotateCallStackIO, called at app/Main.hs:48:10 in backtrace-0.1.0.0-inplace-server:Main
annotateCallStackIO, called at app/Main.hs:46:13 in backtrace-0.1.0.0-inplace-server:Main
Main.handler (app/Main.hs:(46,1)-(49,30))
Main.liftIO (src/Servant/Server/Internal/Handler.hs:30:36-42)
Servant.Server.Internal.Delayed.runHandler' (src/Servant/Server/Internal/Handler.hs:27:31-41)
Control.Monad.Trans.Resource.runResourceT (./Control/Monad/Trans/Resource.hs:(192,14)-(197,18))
Network.Wai.Handler.Warp.HTTP1.processRequest (./Network/Wai/Handler/Warp/HTTP1.hs:195:20-22)
Network.Wai.Handler.Warp.HTTP1.processRequest (./Network/Wai/Handler/Warp/HTTP1.hs:(195,5)-(203,31))
Network.Wai.Handler.Warp.HTTP1.http1server.loop (./Network/Wai/Handler/Warp/HTTP1.hs:(141,9)-(157,42))
HasCallStack backtrace:
error, called at app/Main.hs:48:32 in backtrace-0.1.0.0-inplace-server:Main
```
The first two entries have been added by `annotateCallStackIO`, defined in `annotateCallStackIO`.
- - - - -
a1567efd by Sylvain Henry at 2025-09-01T23:01:35-04:00
RTS: rely less on Hadrian for flag setting (#25843)
Hadrian used to pass -Dfoo command-line flags directly to build the rts.
We can replace most of these flags with CPP based on cabal flags.
It makes building boot libraries with cabal-install simpler (cf #25843).
- - - - -
ca5b0283 by Sergey Vinokurov at 2025-09-01T23:02:23-04:00
Remove unnecessary irrefutable patterns from Bifunctor instances for tuples
Implementation of https://github.com/haskell/core-libraries-committee/issues/339
Metric Decrease:
mhu-perf
- - - - -
2da84b7a by sheaf at 2025-09-01T23:03:23-04:00
Only use active rules when simplifying rule RHSs
When we are simplifying the RHS of a rule, we make sure to only apply
rewrites from rules that are active throughout the original rule's
range of active phases.
For example, if a rule is always active, we only fire rules that are
themselves always active when simplifying the RHS. Ditto for inline
activations.
This is achieved by setting the simplifier phase to a range of phases,
using the new SimplPhaseRange constructor. Then:
1. When simplifying the RHS of a rule, or of a stable unfolding,
we set the simplifier phase to a range of phases, computed from
the activation of the RULE/unfolding activation, using the
function 'phaseFromActivation'.
The details are explained in Note [What is active in the RHS of a RULE?]
in GHC.Core.Opt.Simplify.Utils.
2. The activation check for other rules and inlinings is then:
does the activation of the other rule/inlining cover the whole
phase range set in sm_phase? This continues to use the 'isActive'
function, which now accounts for phase ranges.
On the way, this commit also moves the exact-print SourceText annotation
from the Activation datatype to the ActivationAnn type. This keeps the
main Activation datatype free of any extra cruft.
Fixes #26323
- - - - -
79816cc4 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
cleanup: Move dehydrateCgBreakInfo to Stg2Bc
This no longer has anything to do with Core.
- - - - -
53da94ff by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
rts/Disassembler: Fix spacing of BRK_FUN
- - - - -
08c0cf85 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Fix bciPtr in Step-out
We need to use `BCO_NEXT` to move bciPtr to ix=1, because ix=0 points to
the instruction itself!
I do not understand how this didn't crash before.
- - - - -
e7e021fa by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Allow BRK_FUNs to head case continuation BCOs
When we start executing a BCO, we may want to yield to the scheduler:
this may be triggered by a heap/stack check, context switch, or a
breakpoint. To yield, we need to put the stack in a state such that
when execution is resumed we are back to where we yielded from.
Previously, a BKR_FUN could only head a function BCO because we only
knew how to construct a valid stack for yielding from one -- simply add
`apply_interp_info` + the BCO to resume executing. This is valid because
the stack at the start of run_BCO is headed by that BCO's arguments.
However, in case continuation BCOs (as per Note [Case continuation BCOs]),
we couldn't easily reconstruct a valid stack that could be resumed
because we dropped too soon the stack frames regarding the value
returned (stg_ret) and received (stg_ctoi) by that continuation.
This is especially tricky because of the variable type and size return
frames (e.g. pointer ret_p/ctoi_R1p vs a tuple ret_t/ctoi_t2).
The trick to being able to yield from a BRK_FUN at the start of a case
cont BCO is to stop removing the ret frame headers eagerly and instead
keep them until the BCO starts executing. The new layout at the start of
a case cont. BCO is described by the new Note [Stack layout when entering run_BCO].
Now, we keep the ret_* and ctoi_* frames when entering run_BCO.
A BRK_FUN is then executed if found, and the stack is yielded as-is with
the preserved ret and ctoi frames.
Then, a case cont BCO's instructions always SLIDE off the headers of the
ret and ctoi frames, in StgToByteCode.doCase, turning a stack like
| .... |
+---------------+
| fv2 |
+---------------+
| fv1 |
+---------------+
| BCO |
+---------------+
| stg_ctoi_ret_ |
+---------------+
| retval |
+---------------+
| stg_ret_..... |
+---------------+
into
| .... |
+---------------+
| fv2 |
+---------------+
| fv1 |
+---------------+
| retval |
+---------------+
for the remainder of the BCO.
Moreover, this more uniform approach of keeping the ret and ctoi frames
means we need less ad-hoc logic concerning the variable size of
ret_tuple vs ret_p/np frames in the code generator and interpreter:
Always keep the return to cont. stack intact at the start of run_BCO,
and the statically generated instructions will take care of adjusting
it.
Unlocks BRK_FUNs at the start of case cont. BCOs which will enable a
better user-facing step-out (#26042) which is free of the bugs the
current BRK_ALTS implementation suffers from (namely, using BRK_FUN
rather than BRK_ALTS in a case cont. means we'll never accidentally end
up in a breakpoint "deeper" than the continuation, because we stop at
the case cont itself rather than on the first breakpoint we evaluate
after it).
- - - - -
ade3c1e6 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
BRK_FUN with InternalBreakLocs for code-generation time breakpoints
At the start of a case continuation BCO, place a BRK_FUN.
This BRK_FUN uses the new "internal breakpoint location" -- allowing us
to come up with a valid source location for this breakpoint that is not associated with a source-level tick.
For case continuation BCOs, we use the last tick seen before it as the
source location. The reasoning is described in Note [Debugger: Stepout internal break locs].
Note how T26042c, which was broken because it displayed the incorrect
behavior of the previous step out when we'd end up at a deeper level
than the one from which we initiated step-out, is now fixed.
As of this commit, BRK_ALTS is now dead code and is thus dropped.
Note [Debugger: Stepout internal break locs]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Step-out tells the interpreter to run until the current function
returns to where it was called from, and stop there.
This is achieved by enabling the BRK_FUN found on the first RET_BCO
frame on the stack (See [Note Debugger: Step-out]).
Case continuation BCOs (which select an alternative branch) must
therefore be headed by a BRK_FUN. An example:
f x = case g x of <--- end up here
1 -> ...
2 -> ...
g y = ... <--- step out from here
- `g` will return a value to the case continuation BCO in `f`
- The case continuation BCO will receive the value returned from g
- Match on it and push the alternative continuation for that branch
- And then enter that alternative.
If we step-out of `g`, the first RET_BCO on the stack is the case
continuation of `f` -- execution should stop at its start, before
selecting an alternative. (One might ask, "why not enable the breakpoint
in the alternative instead?", because the alternative continuation is
only pushed to the stack *after* it is selected by the case cont. BCO)
However, the case cont. BCO is not associated with any source-level
tick, it is merely the glue code which selects alternatives which do
have source level ticks. Therefore, we have to come up at code
generation time with a breakpoint location ('InternalBreakLoc') to
display to the user when it is stopped there.
Our solution is to use the last tick seen just before reaching the case
continuation. This is robust because a case continuation will thus
always have a relevant breakpoint location:
- The source location will be the last source-relevant expression
executed before the continuation is pushed
- So the source location will point to the thing you've just stepped
out of
- Doing :step-local from there will put you on the selected
alternative (which at the source level may also be the e.g. next
line in a do-block)
Examples, using angle brackets (<<...>>) to denote the breakpoint span:
f x = case <<g x>> {- step in here -} of
1 -> ...
2 -> ...>
g y = <<...>> <--- step out from here
...
f x = <<case g x of <--- end up here, whole case highlighted
1 -> ...
2 -> ...>>
doing :step-local ...
f x = case g x of
1 -> <<...>> <--- stop in the alternative
2 -> ...
A second example based on T26042d2, where the source is a do-block IO
action, optimised to a chain of `case expressions`.
main = do
putStrLn "hello1"
<<f>> <--- step-in here
putStrLn "hello3"
putStrLn "hello4"
f = do
<<putStrLn "hello2.1">> <--- step-out from here
putStrLn "hello2.2"
...
main = do
putStrLn "hello1"
<<f>> <--- end up here again, the previously executed expression
putStrLn "hello3"
putStrLn "hello4"
doing step/step-local ...
main = do
putStrLn "hello1"
f
<<putStrLn "hello3">> <--- straight to the next line
putStrLn "hello4"
Finishes #26042
- - - - -
c66910c0 by Rodrigo Mesquita at 2025-09-02T12:19:59-04:00
debugger: Re-use the last BreakpointId whole in step-out
Previously, to come up with a location to stop at for `:stepout`, we
would store the location of the last BreakpointId surrounding the
continuation, as described by Note [Debugger: Stepout internal break locs].
However, re-using just the location from the last source breakpoint
isn't sufficient to provide the necessary information in the break
location. Specifically, it wouldn't bind any variables at that location.
Really, there is no reason not to re-use the last breakpoint wholesale,
and re-use all the information we had there. Step-out should behave just
as if we had stopped at the call, but s.t. continuing will not
re-execute the call.
This commit updates the CgBreakInfo to always store a BreakpointId, be
it the original one or the one we're emulating (for step-out).
It makes variable bindings on :stepout work
- - - - -
e4abed7b by sheaf at 2025-09-02T12:20:40-04:00
Revert accidental changes to hie.yaml
- - - - -
003b715b by meooow25 at 2025-09-02T23:48:51+02:00
Adjust the strictness of Data.List.iterate'
* Don't force the next element in advance when generating a (:).
* Force the first element to WHNF like every other element.
Now every element in the output list is forced to WHNF when the (:)
containing it is forced.
CLC proposal:
https://github.com/haskell/core-libraries-committee/issues/335
- - - - -
b2f6aad0 by Simon Hengel at 2025-09-03T04:36:10-04:00
Refactoring: More consistently use logOutput, logInfo, fatalErrorMsg
- - - - -
60a16db7 by Rodrigo Mesquita at 2025-09-03T10:55:50+01:00
bytecode: Don't PUSH_L 0; SLIDE 1 1
While looking through bytecode I noticed a quite common unfortunate
pattern:
...
PUSH_L 0
SLIDE 1 1
We do this often by generically constructing a tail call from a function
atom that may be somewhere arbitrary on the stack.
However, for the special case that the function can be found directly on
top of the stack, as part of the arguments, it's plain redundant to push
then slide it.
In this commit we add a small optimisation to the generation of
tailcalls in bytecode. Simply: lookahead for the function in the stack.
If it is the first thing on the stack and it is part of the arguments
which would be dropped as we entered the tail call, then don't push then
slide it.
In a simple example (T26042b), this already produced a drastic
improvement in generated code (left is old, right is with this patch):
```diff
3c3
< 2025-07-29 10:14:02.081277 UTC
---
> 2025-07-29 10:50:36.560949 UTC
160,161c160
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
164,165d162
< PUSH_L 0
< SLIDE 1 1
175,176c172
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
179,180d174
< PUSH_L 0
< SLIDE 1 1
206,207d199
< PUSH_L 0
< SLIDE 1 1
210,211d201
< PUSH_L 0
< SLIDE 1 1
214,215d203
< PUSH_L 0
< SLIDE 1 1
218,219d205
< PUSH_L 0
< SLIDE 1 1
222,223d207
< PUSH_L 0
< SLIDE 1 1
...
600,601c566
< PUSH_L 0
< SLIDE 1 2
---
> SLIDE 1 1
604,605d568
< PUSH_L 0
< SLIDE 1 1
632,633d594
< PUSH_L 0
< SLIDE 1 1
636,637d596
< PUSH_L 0
< SLIDE 1 1
640,641d598
< PUSH_L 0
< SLIDE 1 1
644,645d600
< PUSH_L 0
< SLIDE 1 1
648,649d602
< PUSH_L 0
< SLIDE 1 1
652,653d604
< PUSH_L 0
< SLIDE 1 1
656,657d606
< PUSH_L 0
< SLIDE 1 1
660,661d608
< PUSH_L 0
< SLIDE 1 1
664,665d610
< PUSH_L 0
< SLIDE 1 1
```
I also compiled lib:Cabal to bytecode and counted the number of bytecode
lines with `find dist-newstyle -name "*.dump-BCOs" -exec wc {} +`:
with unoptimized core:
1190689 lines (before) - 1172891 lines (now)
= 17798 less redundant instructions (-1.5% lines)
with optimized core:
1924818 lines (before) - 1864836 lines (now)
= 59982 less redundant instructions (-3.1% lines)
- - - - -
8b2c72c0 by L0neGamer at 2025-09-04T06:32:03-04:00
Add Control.Monad.thenM and Control.Applicative.thenA
- - - - -
39e1b7cb by Teo Camarasu at 2025-09-04T06:32:46-04:00
ghc-internal: invert dependency of GHC.Internal.TH.Syntax on Data.Data
This means that Data.Data no longer blocks building TH.Syntax, which
allows greater parallelism in our builds.
We move the Data.Data.Data instances to Data.Data. Quasi depends on
Data.Data for one of its methods, so,
we split the Quasi/Q, etc definition out of GHC.Internal.TH.Syntax
into its own module. This has the added benefit of splitting up this
quite large module.
Previously TH.Syntax was a bottleneck when compiling ghc-internal. Now
it is less of a bottle-neck and is also slightly quicker to
compile (since it no longer contains these instances) at the cost of
making Data.Data slightly more expensive to compile.
TH.Lift which depends on TH.Syntax can also compile quicker and no
longer blocks ghc-internal finishing to compile.
Resolves #26217
-------------------------
Metric Decrease:
MultiLayerModulesTH_OneShot
T13253
T21839c
T24471
Metric Increase:
T12227
-------------------------
- - - - -
bdf82fd2 by Teo Camarasu at 2025-09-04T06:32:46-04:00
compiler: delete unused names in Builtins.Names.TH
returnQ and bindQ are no longer used in the compiler.
There was also a very old comment that referred to them that I have modernized
- - - - -
41a448e5 by Ben Gamari at 2025-09-04T19:21:43-04:00
hadrian: Pass lib & include directories to ghc `Setup configure`
- - - - -
46bb9a79 by Ben Gamari at 2025-09-04T19:21:44-04:00
rts/IPE: Fix compilation when zstd is enabled
This was broken by the refactoring undertaken in
c80dd91c0bf6ac034f0c592f16c548b9408a8481.
Closes #26312.
- - - - -
138a6e34 by sheaf at 2025-09-04T19:22:46-04:00
Make mkCast assertion a bit clearer
This commit changes the assertion message that gets printed when one
calls mkCast with a coercion whose kind does not match the type of the
inner expression. I always found the assertion message a bit confusing,
as it didn't clearly state what exactly was the error.
- - - - -
9d626be1 by sheaf at 2025-09-04T19:22:46-04:00
Simplifier/rules: fix mistakes in Notes & comments
- - - - -
94b62aa7 by Simon Peyton Jones at 2025-09-08T03:37:14-04:00
Refactor ForAllCo
This is a pure refactor, addressing #26389.
It arranges that the kind coercion in a ForAllCo is a MCoercion, rather
than a plain Coercion, thus removing redundancy in the common case.
See (FC8) in Note [ForAllCo]
It's a nice cleanup.
- - - - -
624afa4a by sheaf at 2025-09-08T03:38:05-04:00
Use tcMkScaledFunTys in matchExpectedFunTys
We should use tcMkScaledFunTys rather than mkScaledFunTys in
GHC.Tc.Utils.Unify.matchExpectedFunTys, as the latter crashes
when the kind of the result type is a bare metavariable.
We know the result is always Type-like, so we don't need scaledFunTys
to try to rediscover that from the kind.
Fixes #26277
- - - - -
0975d2b6 by sheaf at 2025-09-08T03:38:54-04:00
Revert "Remove hptAllFamInstances usage during upsweep"
This reverts commit 3bf6720eff5e86e673568e756161e6d6150eb440.
- - - - -
0cf34176 by soulomoon at 2025-09-08T03:38:54-04:00
Family consistency checks: add test for #26154
This commit adds the test T26154, to make sure that GHC doesn't crash
when performing type family consistency checks. This test case
was extracted from Agda.
Fixes #26154
- - - - -
ba210d98 by Simon Peyton Jones at 2025-09-08T16:26:36+01:00
Report solid equality errors before custom errors
This MR fixes #26255 by
* Reporting solid equality errors like
Int ~ Bool
before "custom type errors". See comments in `report1` in
`reportWanteds`
* Suppressing errors that arise from superclasses of
Wanteds. See (SCE1) in Note [Suppressing confusing errors]
More details in #26255.
- - - - -
b6249140 by Simon Peyton Jones at 2025-09-10T10:42:38-04:00
Fix a scoping error in Specialise
This small patch fixes #26329, which triggered a scoping error.
Test is in T21391, with -fpolymorphic-specialisation enabled
- - - - -
45305ab8 by sheaf at 2025-09-10T10:43:29-04:00
Make rationalTo{Float,Double} inline in phase 0
We hold off on inlining these until phase 0 to allow constant-folding
rules to fire. However, once we get to phase 0, we should inline them,
e.g. to expose unboxing opportunities.
See CLC proposal #356.
- - - - -
0959d4bc by Andreas Klebinger at 2025-09-10T10:44:12-04:00
Add regression test for #26056
- - - - -
dc79593d by sheaf at 2025-09-10T10:45:01-04:00
Deep subsumption: unify mults without tcEqMult
As seen in #26332, we may well end up with a non-reflexive multiplicity
coercion when doing deep subsumption. We should do the same thing that
we do without deep subsumption: unify the multiplicities normally,
without requiring that the coercion is reflexive (which is what
'tcEqMult' was doing).
Fixes #26332
- - - - -
4bfe2269 by sheaf at 2025-09-10T10:45:50-04:00
lint-codes: fixup MSYS drive letter on Windows
This change ensures that System.Directory.listDirectory doesn't trip up
on an MSYS-style path like '/c/Foo' when trying to list all testsuite
stdout/stderr files as required for testing coverage of GHC diagnostic
codes in the testsuite.
Fixes #25178
- - - - -
56540775 by Ben Gamari at 2025-09-10T10:46:32-04:00
gitlab-ci: Disable split sections on FreeBSD
Due to #26303.
- - - - -
1537784b by Moritz Angermann at 2025-09-10T10:47:13-04:00
Improve mach-o relocation information
This change adds more information about the symbol and addresses
we try to relocate in the linker. This significantly helps when
deubbging relocation issues reported by users.
- - - - -
4e67855b by Moritz Angermann at 2025-09-10T10:47:54-04:00
test.mk expect GhcLeadingUnderscore, not LeadingUnderscore (in line with the other Ghc prefixed variables.
- - - - -
c1cdd265 by Moritz Angermann at 2025-09-10T10:48:35-04:00
testsuite: Fix broken exec_signals_child.c
There is no signal 0. The signal mask is 1-32.
- - - - -
99ac335c by Moritz Angermann at 2025-09-10T10:49:15-04:00
testsuite: clarify Windows/Darwin locale rationale for skipping T6037 T2507 T8959a
- - - - -
0e8fa77a by Moritz Angermann at 2025-09-10T10:49:56-04:00
Skip broken tests on macOS (due to leading underscore not handled properly in the expected output.)
- - - - -
28570c59 by Zubin Duggal at 2025-09-10T10:50:37-04:00
docs(sphinx): fix links to reverse flags when using the :ghc-flag:`-fno-<flag>` syntax
This solution is rather hacky and I suspect there is a better way to do this but I don't know
enough about Sphinx to do better.
Fixes #26352
- - - - -
d17257ed by Cheng Shao at 2025-09-10T17:01:27+02:00
rel-eng: update alpine images to 3.22
This patch is a part of #25876 and updates alpine images to 3.22,
while still retaining 3.12 for x86_64 fully_static bindists.
-------------------------
Metric Decrease:
MultiComponentModulesRecomp
-------------------------
- - - - -
db3276bb by Sylvain Henry at 2025-09-11T11:27:28-04:00
T16180: indicate that the stack isn't executable
- - - - -
11eeeba7 by Sylvain Henry at 2025-09-11T11:27:28-04:00
Fix some tests (statically linked GHC vs libc)
When GHC is linked statically, the stdout C global variable that GHC uses
isn't shared with the stdout C global variable used by loaded code.
As a consequence, the latter must be explicitly flushed because GHC
won't flush it before exiting.
- - - - -
80a07571 by Sylvain Henry at 2025-09-11T11:28:18-04:00
Testsuite: fix debug_rts detection
Running the testsuite without Hadrian should set config.debug_rts
correctly too.
- - - - -
62ae97de by Duncan Coutts at 2025-09-12T13:23:33-04:00
Handle heap allocation failure in I/O primops
The current I/O managers do not use allocateMightFail, but future ones
will. To support this properly we need to be able to return to the
primop with a failure. We simply use a bool return value.
Currently however, we will just throw an exception rather than calling
the GC because that's what all the other primops do too.
For the general issue of primops invoking GC and retrying, see
https://gitlab.haskell.org/ghc/ghc/-/issues/24105
- - - - -
cb9093f5 by Duncan Coutts at 2025-09-12T13:23:33-04:00
Move (and rename) scheduleStartSignalHandlers into RtsSignals.h
Previously it was a local helper (static) function in Schedule.c.
Rename it to startPendingSignalHandlers and deifine it as an inline
header function in RtsSignals.h. So it should still be fast.
Each (new style) I/O manager is going to need to do the same, so eliminating
the duplication now makes sense.
- - - - -
9736d44a by Duncan Coutts at 2025-09-12T13:23:33-04:00
Reduce detail in printThreadBlockage I/O blocking cases
The printThreadBlockage is used in debug tracing output.
For the cases BlockedOn{Read,Write,Delay} the output previously included
the fd that was being waited on, and the delay target wake time.
Superficially this sounds useful, but it's clearly not that useful
because it was already wrong for the Win32 non-threaded I/O manager. In
that situation it will print garbage (the async_result pointer, cast to
a fd or a time).
So given that it apparently never mattered that the information was
accurate, then it's hardly a big jump to say it doesn't matter if it is
present at all.
A good reason to remove it is that otherwise we have to make a new
API and a per-I/O manager implementation to fetch the information. And
for some I/O manager implementations, this information is not available.
It is not available in the win32 non-threaded I/O manager. And for some
future Linux ones, there is no need for the fd to be stored, so storing
it would be just extra space used for very little gain.
So the simplest thing is to just remove the detail.
- - - - -
bc0f2d5d by Duncan Coutts at 2025-09-12T13:23:33-04:00
Add TimeoutQueue.{c,h} and corresponding tests
A data structure used to efficiently manage a collection of timeouts.
It is a priority queue based on absolute expiry time. It uses 64bit
high-precision Time for the keys. The values are normal closures which
allows for example using MVars for unblocking.
It is common in many applications for timeouts to be created and then
deleted or altered before they expire. Thus the choice of data structure
for timeouts should support this efficiently. The implementation choice
here is a leftist heap with the extra feature that it supports deleting
arbitrary elements, provided the caller retain a pointer to the element.
While the deleteMin operation takes O(log n) time, as in all heap
structures, the delete operation for arbitrary elements /typically/
takes O(1), and only O(log n) in the worst case. In practice, when
managing thousands of timeouts it can be a factor of 10 faster to delete
a random timeout queue element than to remove the minimum element. This
supports the common use case.
The plan is to use it in some of the RTS-side I/O managers to support
their timer functionality. In this use case the heap value will be an
MVar used for each timeout to unblock waiting threads.
- - - - -
d1679c9d by Duncan Coutts at 2025-09-12T13:23:33-04:00
Add ClosureTable.{c,h} and corresponding tests
A table of pointers to closures on the GC heap with stable indexes.
It provides O(1) alloc, free and lookup. The table can be expanded
using a simple doubling strategy: in which case allocation is typically
O(1) and occasionally O(n) for overall amortised O(1). No shrinking is
used.
The table itself is heap allocated, and points to other heap objects.
As such it's necessary to use markClosureTable to ensure the table is
used as a GC root to keep the table entries alive, and maintain proper
pointers to them as the GC moves heap objects about.
It is designed to be allocated and accesses exclusively from a single
capability, enabling it to work without any locking. It is thus similar
to the StablePtr table, but per-capability which removes the need for
locking. It _should_ also provide lower GC pause times with the
non-moving GC by spending only O(1) time in markClosureTable, vs O(n)
for markStablePtrTable.
The plan is to use it in some of the I/O managers to keep track of
in-flight I/O operations (but not timers). This allows the tracking
info to be kept on the (unpinned) GC heap, and shared with Haskell
code, and by putting a pointer to the tracking information in a table,
the index remains stable and can be passed via foreign code (like the
kernel).
- - - - -
78cb8dd5 by Duncan Coutts at 2025-09-12T13:23:33-04:00
Add the StgAsyncIOOp closure type
This is intended to be used by multiple I/O managers to help with
tracking in-flight I/O operations.
It is called asynchronous because from the point of view of the RTS we
have many such operations in progress at once. From the point of view of
a Haskell thread of course it can look synchronous.
- - - - -
a2839896 by Duncan Coutts at 2025-09-12T13:23:33-04:00
Add StgAsyncIOOp and StgTimeoutQueue to tso->block_info
These will be used by new I/O managers, for threads blocked on I/O or
timeouts.
- - - - -
fdc2451c by Duncan Coutts at 2025-09-12T13:23:33-04:00
Add a new I/O manager based on poll()
This is a proof of concept I/O manager, to show how to add new ones
neatly, using the ClosureTable and TimeoutQueue infrastructure.
It uses the old unix poll() API, so it is of course limited in
performance by that, but it should have the benefit of wide
compatibility. Also we neatly avoid a name clash with the existing
select() I/O manager.
Compared to the select() I/O manager:
1. beause it uses poll() it is not limited to 1024 file descriptors
(but it's still O(n) so don't expect great performance);
2. it should have much faster threadDelay (when using it in lots of
threads at once) because it's based on the new TimeoutQueue which is
O(log n) rather than O(n).
Some of the code related to timers/timouts is put into a shared module
rts/posix/Timeout.{h,c} since it is intended to be shared with other
similar I/O managers.
- - - - -
6c273b76 by Duncan Coutts at 2025-09-12T13:23:34-04:00
Document the I/O managers in the user guide
and note the new poll I/O manager in the release notes.
- - - - -
824fab74 by Duncan Coutts at 2025-09-12T13:23:34-04:00
Use the poll() I/O manager by default
That is, for the non-threaded RTS, prefer the poll I/O manager over the
legacy select() one, if both can be enabled.
This patch is primarily for CI testing, so we should probably remove
this patch before merging. We can change defaults later after wider
testing and feedback.
- - - - -
39392532 by Luite Stegeman at 2025-09-12T13:24:16-04:00
Support larger unboxed sums
Change known constructor encoding for sums in interfaces to use
11 bits for both the arity and the alternative (up from 8 and 6,
respectively)
- - - - -
2af12e21 by Luite Stegeman at 2025-09-12T13:24:16-04:00
Decompose padding smallest-first in Cmm toplevel data constructors
This makes each individual padding value aligned
- - - - -
418fa78f by Luite Stegeman at 2025-09-12T13:24:16-04:00
Use slots smaller than word as tag for smaller unboxed sums
This packs unboxed sums more efficiently by allowing
Word8, Word16 and Word32 for the tag field if the number of
constructors is small enough
- - - - -
8d7e912f by Rodrigo Mesquita at 2025-09-12T17:57:24-04:00
ghc-toolchain: Use ByteOrder rather than new Endianness
Don't introduce a duplicate datatype when the previous one is equivalent
and already used elsewhere. This avoids unnecessary translation between
the two.
- - - - -
7d378476 by Rodrigo Mesquita at 2025-09-12T17:57:24-04:00
Read Toolchain.Target files rather than 'settings'
This commit makes GHC read `lib/targets/default.target`, a file with a
serialized value of `ghc-toolchain`'s `GHC.Toolchain.Target`.
Moreover, it removes all the now-redundant entries from `lib/settings`
that are configured as part of a `Target` but were being written into
`settings`.
This makes it easier to support multiple targets from the same compiler
(aka runtime retargetability). `ghc-toolchain` can be re-run many times
standalone to produce a `Target` description for different targets, and,
in the future, GHC will be able to pick at runtime amongst different
`Target` files.
This commit only makes it read the default `Target` configured in-tree
or configured when installing the bindist.
The remaining bits of `settings` need to be moved to `Target` in follow
up commits, but ultimately they all should be moved since they are
per-target relevant.
Fixes #24212
On Windows, the constant overhead of parsing a slightly more complex
data structure causes some small-allocation tests to wiggle around 1 to
2 extra MB (1-2% in these cases).
-------------------------
Metric Increase:
MultiLayerModulesTH_OneShot
T10421
T10547
T12234
T12425
T13035
T18140
T18923
T9198
TcPlugin_RewritePerf
-------------------------
- - - - -
e0780a16 by Rodrigo Mesquita at 2025-09-12T17:57:24-04:00
ghc-toolchain: Move TgtHasLibm to per-Target file
TargetHasLibm is now part of the per-target configuration
Towards #26227
- - - - -
8235dd8c by Rodrigo Mesquita at 2025-09-12T17:57:24-04:00
ghc-toolchain: Move UseLibdw to per-Target file
To support DWARF unwinding, the RTS must be built with the -f+libdw flag
and with the -DUSE_LIBDW macro definition. These flags are passed on
build by Hadrian when --enable-dwarf-unwinding is specified at configure
time.
Whether the RTS was built with support for DWARF is a per-target
property, and as such, it was moved to the per-target
GHC.Toolchain.Target.Target file.
Additionally, we keep in the target file the include and library paths
for finding libdw, since libdw should be checked at configure time (be
it by configure, or ghc-toolchain, that libdw is properly available).
Preserving the user-given include paths for libdw facilitates in the
future building the RTS on demand for a given target (if we didn't keep
that user input, we couldn't)
Towards #26227
- - - - -
d5ecf2e8 by Rodrigo Mesquita at 2025-09-12T17:57:25-04:00
ghc-toolchain: Make "Support SMP" a query on a Toolchain.Target
"Support SMP" is merely a function of target, so we can represent it as
such in `ghc-toolchain`.
Hadrian queries the Target using this predicate to determine how to
build GHC, and GHC queries the Target similarly to report under --info
whether it "Support SMP"
Towards #26227
- - - - -
e07b031a by Rodrigo Mesquita at 2025-09-12T17:57:25-04:00
ghc-toolchain: Make "tgt rts linker only supports shared libs" function on Target
Just like with "Support SMP", "target RTS linker only supports shared
libraries" is a predicate on a `Target` so we can just compute it when
necessary from the given `Target`.
Towards #26227
- - - - -
14123ee6 by Simon Peyton Jones at 2025-09-12T17:58:07-04:00
Solve forall-constraints via an implication, again
In this earlier commit:
commit 953fd8f1dc080f1c56e3a60b4b7157456949be29
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Jul 21 10:06:43 2025 +0100
Solve forall-constraints immediately, or not at all
I used a all-or-nothing strategy for quantified constraints
(aka forall-constraints). But alas that fell foul of #26315,
and #26376.
So this MR goes back to solving a quantified constraint by
turning it into an implication; UNLESS we are simplifying
constraints from a SPECIALISE pragma, in which case the
all-or-nothing strategy is great. See:
Note [Solving a Wanted forall-constraint]
Other stuff in this MR:
* TcSMode becomes a record of flags, rather than an enumeration
type; much nicer.
* Some fancy footwork to avoid error messages worsening again
(The above MR made them better; we want to retain that.)
See `GHC.Tc.Errors.Ppr.pprQCOriginExtra`.
-------------------------
Metric Decrease:
T24471
-------------------------
- - - - -
e6c192e2 by Simon Peyton Jones at 2025-09-12T17:58:07-04:00
Add a test case for #26396
...same bug ast #26315
- - - - -
8f3d80ff by Luite Stegeman at 2025-09-13T08:43:09+02:00
Use mkVirtHeapOffsets for reconstructing terms in RTTI
This makes mkVirtHeapOffsets the single source of truth for
finding field offsets in closures.
- - - - -
eb389338 by Luite Stegeman at 2025-09-13T08:43:09+02:00
Sort non-pointer fields by size for more efficient packing
This sorts non-pointer fields in mkVirtHeapOffsets, always
storing the largest field first. The relative order of
equally sized fields remains unchanged.
This reduces wasted padding/alignment space in closures with
differently sized fields.
- - - - -
99b233f4 by Alison at 2025-09-13T16:51:04-04:00
ghc-heap: Fix race condition with profiling builds
Apply the same fix from Closures.hs (64fd0fac83) to Heap.hs by adding
empty imports to make way-dependent dependencies visible to `ghc -M`.
Fixes #15197, #26407
- - - - -
77deaa7a by Cheng Shao at 2025-09-14T21:29:45-04:00
hadrian: build in-tree gmp with -fvisibility=hidden
When hadrian builds in-tree gmp, it should build the shared objects
with -fvisibility=hidden. The gmp symbols are only used by bignum
logic in ghc-internal and shouldn't be exported by the ghc-internal
shared library. We should always strive to keep shared library symbol
table lean, which benefits platforms with slow dynamic linker or even
hard limits about how many symbols can be exported (e.g. macos dyld,
win32 dll and wasm dyld).
- - - - -
42a18960 by Cheng Shao at 2025-09-14T21:30:26-04:00
Revert "wasm: add brotli compression for ghci browser mode"
This reverts commit 731217ce68a1093b5f9e26a07d5bd2cdade2b352.
Benchmarks show non-negligible overhead when browser runs on the same
host, which is the majority of actual use cases.
- - - - -
e6755b9f by Cheng Shao at 2025-09-14T21:30:26-04:00
wasm: remove etag logic in ghci browser mode web server
This commit removes the etag logic in dyld script's ghci browser mode
web server. It was meant to support caching logic of wasm shared
libraries, but even if the port is manually specified to make caching
even relevant, for localhost the extra overhead around etag logic is
simply not worth it according to benchmarks.
- - - - -
ac5859b9 by sheaf at 2025-09-16T14:58:38-04:00
Add 'Outputable Natural' instance
This commit adds an Outputable instance for the Natural natural-number type,
as well as a "natural :: Natural -> SDoc" function that mirrors the existing
"integer" function.
- - - - -
d48ebc23 by Cheng Shao at 2025-09-16T14:59:18-04:00
autoconf: emit warning instead of error for FIND_PYTHON logic
This patch makes FIND_PYTHON logic emit warning instead of error, so
when the user doesn't expect to run the testsuite driver (especially
when installing a bindist), python would not be mandatory. Fixes #26347.
- - - - -
54b5950e by Sylvain Henry at 2025-09-17T04:45:18-04:00
Print fully qualified unit names in name mismatch
It's more user-friendly to directly print the right thing instead of
requiring the user to retry with the additional `-dppr-debug` flag.
- - - - -
403cb665 by Ben Gamari at 2025-09-17T04:46:00-04:00
configure: Fix consistency between distrib and source CC check
Previously distrib/configure.ac did not
include `cc`.
Closes #26394.
- - - - -
2dcd4cb9 by Oleg Grenrus at 2025-09-17T04:46:41-04:00
Use isPrint in showUnique
The comment say
```
-- Avoid emitting non-printable characters in pretty uniques. See #25989.
```
so let the code do exactly that.
There are tags (at least : and 0 .. 9) which weren't in A .. z range.
- - - - -
e5dd754b by Oleg Grenrus at 2025-09-17T04:46:42-04:00
Shorten in-module links in hyperlinked source
Instead of href="This.Module#ident" to just "#ident"
- - - - -
63189b2c by Oleg Grenrus at 2025-09-17T04:46:42-04:00
Use showUnique in internalAnchorIdent
Showing the key of Unique as a number is generally not a great idea.
GHC Unique has a tag in high bits, so the raw number is unnecessarily
big.
So now we have
```html
<a href="#l-rvgK"><span class="hs-identifier hs-var hs-var">bar</span></a>
```
instead of
```html
<a href="#local-6989586621679015689"><span class="hs-identifier hs-var hs-var">bar</span></a>
```
Together with previous changes of shorter intra-module links the effect
on compressed files is not huge, that is expected as we simply remove
repetitive contents which pack well.
```
12_694_206 Agda-2.9.0-docs-orig.tar.gz
12_566_065 Agda-2.9.0-docs.tar.gz
```
However when unpacked, the difference can be significant,
e.g. Agda's largest module source got 5% reduction:
```
14_230_117 Agda.Syntax.Parser.Parser.html
13_422_109 Agda.Syntax.Parser.Parser.html
```
The whole hyperlinked source code directory got similar reduction
```
121M Agda-2.9.0-docs-orig/src
114M Agda-2.9.0-docs/src
```
For the reference, sources are about 2/3 of the generated haddocks
```
178M Agda-2.9.0-docs-old
172M Agda-2.9.0-docs
```
so we get around 3.5% size reduction overall. Not bad for a small local
changes.
- - - - -
6f63f57b by Stefan Schulze Frielinghaus at 2025-09-17T04:47:22-04:00
rts: Fix alignment for gen_workspace #26334
After a0fa4941903272c48b050d24e93eec819eff51bd bootstrap is broken on
s390x and errors out with
rts/sm/GCThread.h:207:5: error:
error: alignment of array elements is greater than element size
207 | gen_workspace gens[];
| ^~~~~~~~~~~~~
The alignment constraint is applied via the attribute to the type
gen_workspace and leaves the underlying type struct gen_workspace_
untouched. On Aarch64, x86, and s390x the struct has a size of 128
bytes. On Aarch64 and x86 the alignments of 128 and 64 are divisors of
the size, respectively, which is why the type is a viable member type
for an array. However, on s390x, the alignment is 256 and therefore is
not a divisor of the size and hence cannot be used for arrays.
Basically I see two fixes here. Either decrease the alignment
requirement on s390x, or by applying the alignment constraint on the
struct itself. The former might affect performance as noted in
a0fa4941903272c48b050d24e93eec819eff51bd. The latter introduces padding
bits whenever necessary in order to ensure that
sizeof(gen_workspace[N])==N*sizeof(gen_workspace) holds which is done by
this patch.
- - - - -
06d25623 by Cheng Shao at 2025-09-17T19:32:27-04:00
ghci: add :shell command
This patch adds a new :shell command to ghci which works similarly to
:!, except it guarantees to run the command via sh -c. On POSIX hosts
the behavior is identical to :!, but on Windows it uses the msys2
shell instead of system cmd.exe shell. This is convenient when writing
simple ghci scripts that run simple POSIX commands, and the behavior
can be expected to be coherent on both Windows and POSIX.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
186054f7 by Cheng Shao at 2025-09-17T19:32:27-04:00
testsuite: remove legacy :shell trick
This commit makes use of the built-in :shell functionality in ghci in
the test cases, and remove the legacy :shell trick.
- - - - -
0a3a4aa3 by Cheng Shao at 2025-09-17T19:32:27-04:00
docs: document :shell in ghci
This commit documents the :shell command in ghci.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
a4ff12bb by Cheng Shao at 2025-09-17T19:33:09-04:00
ghc-internal: fix codepages program
codepages was not properly updated during the base -> ghc-internal
migration, this commit fixes it.
- - - - -
7e094def by Cheng Shao at 2025-09-17T19:33:09-04:00
ghc-internal: relax ucd2haskell cabal upper bounds
This commit relaxes ucd2haskell cabal upper bounds to make it runnable
via ghc 9.12/9.14.
- - - - -
7077c9f7 by Cheng Shao at 2025-09-17T19:33:09-04:00
ghc-internal: update to unicode 17.0.0
This commit updates the generated code in ghc-internal to match
unicode 17.0.0.
- - - - -
cef8938f by sheaf at 2025-09-17T19:34:09-04:00
Bad record update msg: allow out-of-scope datacons
This commit ensures that, when we encounter an invalid record update
(because no constructor exists which contains all of the record fields
mentioned in the record update), we graciously handle the situation in
which the constructors themselves are not in scope. In that case,
instead of looking up the constructors in the GlobalRdrEnv, directly
look up their GREInfo using the lookupGREInfo function.
Fixes #26391
- - - - -
a2d9d7c2 by sheaf at 2025-09-17T19:34:09-04:00
Improve Notes about disambiguating record updates
This commit updates the notes [Disambiguating record updates] and
[Type-directed record disambiguation], in particular adding more
information about the deprecation status of type-directed disambiguation
of record updates.
- - - - -
de44e69e by sheaf at 2025-09-19T05:16:51-04:00
Enable TcM plugins in initTc
This commit ensures that we run typechecker plugins and defaulting
plugins whenever we call initTc.
In particular, this ensures that the pattern-match checker, which calls
'initTcDsForSolver' which calls 'initTc', runs with typechecker plugins
enabled. This matters for situations like:
merge :: Vec n a -> Vec n a -> Vec (2 * n) a
merge Nil Nil = Nil
merge (a <: as) (b <: bs) = a :< (b <: merge as bs)
in which we need the typechecker plugin to run in order to tell us that
the Givens would be inconsistent in the additional equation
merge (_ <: _) Nil
and thus that the equation is not needed.
Fixes #26395
- - - - -
2c378ad2 by Cheng Shao at 2025-09-19T05:17:33-04:00
rel-eng: update fedora image to 42
This patch is a part of #25876 and updates fedora image to 42.
- - - - -
0a9d9ffc by Sylvain Henry at 2025-09-19T13:12:14-04:00
Fix output of T14999 (#23685)
Fix output of T14999 to:
- take into account the +1 offset to DW_AT_low_pc (see Note [Info Offset])
- always use Intel's syntax to force consistency: it was reported that
sometimes GDB prints `jmpq` instead of `jmp` with the AT&T syntax
- - - - -
1480872a by Vladislav Zavialov at 2025-09-19T13:12:54-04:00
Fix PREP_MAYBE_LIBRARY in prep_target_file.m4
This change fixes a configure error introduced in:
commit 8235dd8c4945db9cb03e3be3c388d729d576ed1e
ghc-toolchain: Move UseLibdw to per-Target file
Now the build no longer fails with:
acghc-toolchain: Failed to read a valid Target value from hadrian/cfg/default.target
- - - - -
d1d9e39e by Ben Gamari at 2025-09-19T18:24:52-04:00
StgToByteCode: Don't assume that data con workers are nullary
Previously StgToByteCode assumed that all data-con workers were of a
nullary representation. This is not a valid assumption, as seen
in #23210, where an unsaturated application of a unary data
constructor's worker resulted in invalid bytecode. Sadly, I have not yet
been able to reduce a minimal testcase for this.
Fixes #23210.
- - - - -
3eeecd50 by Ben Gamari at 2025-09-19T18:24:53-04:00
testsuite: Mark T23146* as unbroken
- - - - -
2e73f342 by sheaf at 2025-09-19T18:24:53-04:00
Add test for #26216
- - - - -
c2efb912 by Sven Tennie at 2025-09-19T18:25:36-04:00
Generate correct test header
This increases convenience when copying & pasting...
- - - - -
d2fb811e by Sven Tennie at 2025-09-19T18:25:36-04:00
foundation test: Fix shift amount (#26248)
Shift primops' results are only defined for shift amounts of 0 to word
size - 1. The approach is similar to testing div-like operations (which
have a constraint regarding zero operands.)
This was partly vibe coded (https://github.com/supersven/ghc/pull/1) but
then heavily refactored.
- - - - -
a62ce115 by Andreas Klebinger at 2025-09-19T18:26:18-04:00
Tweak jspace test
I've given it a longer timeout, and tweaked the test file generation
to speed it up a bit. Hopefully that is enough to make it constentily pass.
Last but not least it now also always uses three threads.
- - - - -
0f034942 by Cheng Shao at 2025-09-19T18:26:59-04:00
rts: remove obsolete CC_SUPPORTS_TLS logic
This patch removes obsolete CC_SUPPORTS_TLS logic throughout the rts,
given __thread is now uniformly supported by C toolchains of all
platforms we currently support.
- - - - -
ef705655 by Cheng Shao at 2025-09-19T18:27:41-04:00
rts: remove obsolete HAS_VISIBILITY_HIDDEN logic
This patch removes obsolete HAS_VISIBILITY_HIDDEN logic throughout the
rts, given __attribute__((visibility("hidden"))) is uniformly
supported by C toolchains of all platforms we currently support.
- - - - -
9fdc1f7d by Cheng Shao at 2025-09-19T18:28:21-04:00
rts: remove -O3 pragma hack in Hash.c
This patch removes an obsolete gcc pragma to specify -O3 in Hash.c.
Hadrian already passes the right flag.
- - - - -
b8cfa8f7 by Cheng Shao at 2025-09-19T18:29:01-04:00
rts: remove obsolete COMPILING_WINDOWS_DLL logic
This patch removes obsolete COMPILING_WINDOWS_DLL logic throughout the
rts. They were once used for compiling to win32 DLLs, but we haven't
been able to compile Haskell units to win32 DLLs for many years now,
due to PE format's restriction of no more than 65536 exported symbols
in a single DLL.
- - - - -
bb760611 by Cheng Shao at 2025-09-19T18:29:42-04:00
wasm: bump browser_wasi_shim to 0.4.2
This patch bumps the browser_wasi_shim dependency of wasm dyld script
to 0.4.2.
- - - - -
8b0940db by Cheng Shao at 2025-09-20T06:48:05-04:00
compiler: move Binary instance of Map to GHC.Utils.Binary
This patch moves `Binary` instance of `Map` from `haddock-api` to
`GHC.Utils.Binary`. This also allows us to remove a redundant instance
defined for `NameEntityInfo`, which is a type synonym for `Map`.
- - - - -
4a8fed75 by Vladislav Zavialov at 2025-09-20T06:48:47-04:00
Fix keyword in ExplicitNamespaces error message (#26418)
Consider this module header and the resulting error:
{-# LANGUAGE NoExplicitNamespaces #-}
module T26418 (data HeadC) where
-- error: [GHC-47007]
-- Illegal keyword 'type'
Previously, the error message would mention 'type' (as shown above),
even though the user wrote 'data'. This has now been fixed.
The error location has also been corrected: it is now reported at the
keyword position rather than at the position of the associated
import/export item.
- - - - -
867c2675 by Cheng Shao at 2025-09-20T06:49:28-04:00
wasm: fix dyld handling for forward declared GOT.func items
This patch fixes wasm shared linker's handling of forward declared
GOT.func items, see linked issue for details. Also adds T26430 test to
witness the fix. Fixes #26430.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
e7df6cc0 by Simon Peyton Jones at 2025-09-23T14:34:39-04:00
Improve pretty printer for HsExpr
Given a very deeply-nested application, it just kept printing
deeper and deeper. This small change makes it cut off.
Test is in #26330, but we also get a dramatic decrease in compile
time for perf/compiler/InstanceMatching:
InstanceMatching 4,086,884,584 1,181,767,232 -71.1% GOOD
Why? Because before we got a GIGANTIC error message that took
ages to pretty-print; now we get this much more civilised message
(I have removed some whitespace.)
Match.hs:1007:1: error:
• No instance for ‘Show (F001 a)’ arising from a use of ‘showsPrec’
• In the second argument of ‘showString’, namely
‘(showsPrec
11 b1
(GHC.Internal.Show.showSpace
(showsPrec
11 b2
(GHC.Internal.Show.showSpace
(showsPrec
11 b3
(GHC.Internal.Show.showSpace
(showsPrec
11 b4
(GHC.Internal.Show.showSpace
(showsPrec
11 b5
(GHC.Internal.Show.showSpace
(showsPrec
11 b6
(GHC.Internal.Show.showSpace (showsPrec ...)))))))))))))’
-----------------------
The main payload is
* At the start of `pprExpr`
* In the defn of `pprApp`
A little bit of refactoring:
* It turned out that we were setting the default cut-off depth to a
fixed value in two places, so changing one didn't change the other.
See defaultSDocDepth and defaultSDocCols
* I refactored `pprDeeperList` a bit so I could understand it better.
Because the depth calculation has changed, there are lots of small
error message wibbles.
Metric Decrease:
InstanceMatching
- - - - -
209f0158 by Simon Peyton Jones at 2025-09-23T14:34:39-04:00
Use Outputable.ellipsis rather than text "..."
- - - - -
64bb0e37 by Sylvain Henry at 2025-09-23T14:35:56-04:00
deriveConstants: automatically pass -fcommon CC flag (#26393)
By mistake we tried to use deriveConstants without passing
`--gcc-flag -fcommon` (which Hadrian does) and it failed.
This patch:
1. adds parsing support for constants stored in the .bss section (i.e.
when -fcommon isn't passed)
2. enables passing `-fcommon` automatically to the C compiler because
Windows requires this for subtle reasons
3. Documents the subtle reasons
(1) isn't strictly necessary because we always do (2) but it does no
harm and it is still useful if the CC flags ever contain -fno-common
- - - - -
afcdf92f by Oleg Grenrus at 2025-09-23T14:36:41-04:00
Don't wrap spaces in <span>s
Doing similar comparison as in 63189b2ceca07edf4e179f4180ca60d470c62cb3
With this change the gzipped documentation is now 2% smaller (previously 1%)
12_694_206 Agda-2.9.0-docs-orig.tar.gz
12_436_829 Agda-2.9.0-docs.tar.gz
Unzipped docs are 5% smaller (previously 3%)
178M Agda-2.9.0-docs-orig
169M Agda-2.9.0-docs
Individual hyperlinked sources are around 7-10% smaller (previously 5%)
(`Parser` module is generated by happy and has relatively little whitespace)
14_230_117 Agda.Syntax.Parser.Parser.html
13_220_758 Agda.Syntax.Parser.Parser.html
Agda's hyperlinked sources are 9% smaller now:
121M Agda-2.9.0-docs-orig/src
110M Agda-2.9.0-docs/src
- - - - -
67de53a6 by Cheng Shao at 2025-09-23T14:37:31-04:00
rts: remove obsolete __GNUC__ related logic
This patch removes obsolete `__GNUC__` related logic, given on any
currently supported platform and toolchain, `__GNUC__ >= 4` is
universally true. Also pulls some other weeds and most notably, use
`__builtin___clear_cache` for clang as well, since clang has supported
this gcc intrinsic since 2014, see
https://github.com/llvm/llvm-project/commit/c491a8d4577052bc6b3b4c72a7db6a7….
- - - - -
c4d32493 by Sven Tennie at 2025-09-23T20:40:57-04:00
RV64: Fix: Add missing truncation to MO_S_Shr (#26248)
Sub-double word (<W64) registers need to be truncated after the
operation.
- - - - -
41dce477 by Sven Tennie at 2025-09-23T20:40:57-04:00
RV64: Cleanup shift emitting cases/code
Remove overlapping cases to make the shift logic easier to understand.
- - - - -
0a601c30 by Alex Washburn at 2025-09-23T20:41:41-04:00
Correcting LLVM linking of Intel BMI intrinsics pdep{8,16} and pext{8,16}.
This patch fixes #26065.
The LLVM interface does not expose bindings to:
- llvm.x86.bmi.pdep.8
- llvm.x86.bmi.pdep.16
- llvm.x86.bmi.pext.8
- llvm.x86.bmi.pext.16
So calls are instead made to llvm.x86.bmi.{pdep,pext}.32 in these cases,
with pre/post-operation truncation to constrain the logical value range.
- - - - -
89e8ff3d by Peng Fan at 2025-09-23T20:42:37-04:00
NCG/LA64: Implement MO_BSwap and MO_BRev with bit-manipulation Instructions
- - - - -
50f6be09 by Sylvain Henry at 2025-09-23T20:43:29-04:00
Allow Core plugins to access unoptimized Core (#23337)
Make the first simple optimization pass after desugaring a real CoreToDo
pass. This allows CorePlugins to decide whether they want to be executed
before or after this pass.
- - - - -
30ef0aac by Simon Hengel at 2025-09-23T20:44:12-04:00
docs: Fix typo in scoped_type_variables.rst
- - - - -
f8919262 by Cheng Shao at 2025-09-23T20:44:54-04:00
ghci: fix bootstrapping with 9.12.3-rc1 and above
This patch fixes bootstrapping GHC with 9.12.3-rc1 and above. ghci
defines `Binary` instance for `HalfWord` in `ghc-heap`, which is a
proper `newtype` in 9.14 and starting from 9.12.3. Given we don't
build `ghc-heap` in stage0, we need to fix this predicate so that it
corresponds to the boot ghc versions that contain the right version of
`ghc-heap`.
- - - - -
a7f15858 by sheaf at 2025-09-24T09:49:53-04:00
User's guide: clarify optimisation of INLINABLE unfoldings
This updates the user's guide section on INLINABLE pragmas to explain how
the unfoldings of inlineable functions are optimised. The user's guide incorrectly
stated that the RHS was not optimised at all, but this is not true. Instead, GHC
is careful about phase control to optmise the RHS while retaining the guarantee
that GHC behaves as if the original RHS had been written.
- - - - -
495886d9 by Rodrigo Mesquita at 2025-09-24T09:50:35-04:00
cleanup: Delete historical artifact of COMPILING_WINDOWS_DLL
Namely, drop the obsolete
- DLL_IMPORT_RTS
- DLL_IMPORT_DATA_VAR
- DLL_IMPORT_DATA_VARNAME
- DLL_IMPORT_DATA_REF
These macros were not doing anything and placed inconsistently
Looking at the git logs reveal these macros were used to support
dynamic libraries on Win32, a feature that was dropped
in b8cfa8f741729ef123569fb321c4b2ab4a1a941c
This allows us to get rid of the rts/DLL.h file too.
- - - - -
5ae89054 by Sylvain Henry at 2025-09-24T17:07:00-04:00
Allow disabling builtin rules (#20298)
Add a way to disable built-in rules programmatically and with a debug flag.
I also took the opportunity to add a debug flag to disable bignum rules,
which was only possible programmatically (e.g. in a plugin).
- - - - -
135242ca by Rodrigo Mesquita at 2025-09-24T17:07:44-04:00
Don't use build CFLAGS and friends as target settings
In the GHC in tree configure, `CFLAGS`, `CXXFLAGS`, and similar tool
configuration flags apply to the BUILD phase of the compiler, i.e. to
the tools run to compile GHC itself.
Notably, they should /not/ be carried over to the Target settings, i.e.
these flags should /not/ apply to the tool which GHC invokes at runtime.
Fixes #25637
- - - - -
b418408b by Irene Knapp at 2025-09-25T09:47:54-04:00
Document etymology of "bind" as the name for `>>=`
It took me twenty years of contemplation to realize why it's called that.
I therefore feel that it may not be obvious to beginners.
- - - - -
e9c5e46f by Brandon Chinn at 2025-09-25T09:48:36-04:00
Fix tabs in string gaps (#26415)
Tabs in string gaps were broken in bb030d0d because previously, string gaps were manually parsed, but now it's lexed by the usual Alex grammar and post-processed after successful lexing.
It broke because of a discrepancy between GHC's lexer grammar and the Haskell Report. The Haskell Report includes tabs in whitechar:
whitechar → newline | vertab | space | tab | uniWhite
$whitechar used to include tabs until 18 years ago, when it was removed in order to exclude tabs from $white_no_nl in order to warn on tabs: 6e202120. In this MR, I'm adding \t back into $whitechar, and explicitly excluding \t from the $white_no_nl+ rule ignoring all whitespace in source code, which more accurately colocates the "ignore all whitespace except tabs, which is handled in the next line" logic.
As a side effect of this MR, tabs are now allowed in pragmas; currently, a pragma written as {-# \t LANGUAGE ... #-} is interpreted as the tab character being the pragma name, and GHC warns "Unrecognized pragma". With this change, tabs are ignored as whitespace, which more closely matches the Report anyway.
- - - - -
8bf5b309 by Cheng Shao at 2025-09-25T09:49:18-04:00
wasm: remove the --no-turbo-fast-api-calls hack from dynamic linker shebang
This patch removes the `--no-turbo-fast-api-calls` hack from the dyld
script shebang; it was used to workaround v8 fast call coredumps in
nodejs and no longer needed, and comes with a performance penalty,
hence the removal.
- - - - -
c1cab0c3 by Sylvain Henry at 2025-09-26T10:36:30-04:00
Revert "Add necessary flag for js linking"
This reverts commit 84f68e2231b2eddb2e1dc4e90af394ef0f2e803f.
This commit didn't have the expected effect. See discussion in #26290.
Instead we export HEAP8 and HEAPU8 from rts/js/mem.js
- - - - -
0a434a80 by Sylvain Henry at 2025-09-26T10:36:30-04:00
JS: export HEAPU8 (#26290)
This is now required by newer Emscripten versions.
- - - - -
b10296a9 by Andreas Klebinger at 2025-09-26T10:37:11-04:00
sizeExpr: Improve Tick handling.
When determining if we scrutinize a function argument we
now properly look through ticks. Fixes #26444.
- - - - -
b6ef1bfd by Wolfgang Jeltsch at 2025-09-26T21:09:30+03:00
Add operations for obtaining operating-system handles
This resolves #26265.
- - - - -
623 changed files:
- .gitlab-ci.yml
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- compiler/GHC/Builtin/Names/TH.hs
- compiler/GHC/Builtin/Uniques.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm/Utils.hs
- compiler/GHC/CmmToAsm/LA64/CodeGen.hs
- compiler/GHC/CmmToAsm/LA64/Instr.hs
- compiler/GHC/CmmToAsm/LA64/Ppr.hs
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Coercion.hs-boot
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/ConstantFold.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/Pipeline/Types.hs
- compiler/GHC/Core/Opt/Simplify.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Inline.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/Reduction.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/Rules/Config.hs
- compiler/GHC/Core/TyCo/Compare.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/TyCo/Tidy.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unfold.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Data/IOEnv.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Config/Core/Opt/Simplify.hs
- compiler/GHC/Driver/Config/Core/Rules.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Env/Types.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc/Ppr.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Pmc/Types.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Iface/Errors/Ppr.hs
- compiler/GHC/Iface/Ext/Types.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Llvm/Ppr.hs
- compiler/GHC/Llvm/Types.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/Lexer/String.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/Types.hs
- compiler/GHC/Plugins.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Runtime/Loader.hs
- compiler/GHC/Settings.hs
- compiler/GHC/Settings/IO.hs
- compiler/GHC/Stg/Lint.hs
- compiler/GHC/Stg/Unarise.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/DataCon.hs
- compiler/GHC/StgToCmm/Layout.hs
- compiler/GHC/SysTools/BaseDir.hs
- compiler/GHC/Tc/Deriv/Generics.hs
- compiler/GHC/Tc/Deriv/Utils.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs-boot
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Gen/Splice.hs-boot
- compiler/GHC/Tc/Instance/Family.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Solver/Solve.hs-boot
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Types/TH.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Zonk/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Types/Unique.hs
- compiler/GHC/Unit/Home/Graph.hs
- compiler/GHC/Unit/Home/PackageTable.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/GHC/Utils/Ppr.hs
- compiler/ghc.cabal.in
- configure.ac
- distrib/configure.ac.in
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/debugging.rst
- docs/users_guide/exts/pragmas.rst
- docs/users_guide/exts/scoped_type_variables.rst
- docs/users_guide/flags.py
- docs/users_guide/ghci.rst
- docs/users_guide/runtime_control.rst
- ghc/GHCi/UI.hs
- hadrian/bindist/Makefile
- hadrian/bindist/config.mk.in
- hadrian/cfg/default.host.target.in
- hadrian/cfg/default.target.in
- hadrian/cfg/system.config.in
- hadrian/src/Base.hs
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Oracles/TestSettings.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Rules/ToolArgs.hs
- hadrian/src/Settings/Builders/DeriveConstants.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- libraries/base/src/Control/Applicative.hs
- libraries/base/src/Control/Monad.hs
- libraries/base/src/Data/Array/Byte.hs
- libraries/base/src/Data/Bifunctor.hs
- libraries/base/src/Data/Fixed.hs
- libraries/base/src/GHC/RTS/Flags.hs
- libraries/base/src/GHC/Stack/CloneStack.hs
- + libraries/base/src/System/IO/OS.hs
- libraries/base/tests/unicode002.stdout
- libraries/base/tests/unicode003.stdout
- + libraries/ghc-boot-th/GHC/Boot/TH/Monad.hs
- libraries/ghc-boot-th/GHC/Boot/TH/Ppr.hs
- libraries/ghc-boot-th/ghc-boot-th.cabal.in
- libraries/ghc-boot/GHC/Settings/Utils.hs
- libraries/ghc-boot/ghc-boot.cabal.in
- libraries/ghc-experimental/src/GHC/Stack/Annotation/Experimental.hs
- libraries/ghc-heap/GHC/Exts/Heap.hs
- libraries/ghc-heap/GHC/Exts/Heap/ClosureTypes.hs
- libraries/ghc-heap/GHC/Exts/Heap/Closures.hs
- + libraries/ghc-heap/GHC/Exts/Heap/Constants.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTable.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTable/Types.hs
- + libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hs
- libraries/ghc-heap/GHC/Exts/Heap/ProfInfo/Types.hs
- + libraries/ghc-heap/GHC/Exts/Stack/Constants.hs
- libraries/ghc-heap/GHC/Exts/Stack/Decode.hs
- libraries/ghc-heap/ghc-heap.cabal.in
- − libraries/ghc-heap/tests/stack-annotation/ann_frame004.stdout
- libraries/ghc-heap/cbits/HeapPrim.cmm → libraries/ghc-internal/cbits/HeapPrim.cmm
- libraries/ghc-heap/cbits/Stack.cmm → libraries/ghc-internal/cbits/Stack.cmm
- libraries/ghc-internal/cbits/StackCloningDecoding.cmm
- libraries/ghc-heap/cbits/Stack_c.c → libraries/ghc-internal/cbits/Stack_c.c
- libraries/ghc-internal/cbits/atomic.c
- libraries/ghc-internal/cbits/ctz.c
- libraries/ghc-internal/codepages/MakeTable.hs
- libraries/ghc-internal/codepages/Makefile
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/jsbits/base.js
- libraries/ghc-internal/src/GHC/Internal/Base.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs
- libraries/ghc-internal/src/GHC/Internal/Float.hs
- + libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghc-heap/GHC/Exts/Heap/Constants.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/Constants.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTable.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTable/Types.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable/Types.hsc
- libraries/ghc-heap/GHC/Exts/Heap/InfoTableProf.hsc → libraries/ghc-internal/src/GHC/Internal/Heap/InfoTableProf.hsc
- + libraries/ghc-internal/src/GHC/Internal/Heap/ProfInfo/Types.hs
- libraries/ghc-internal/src/GHC/Internal/List.hs
- libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc
- libraries/ghc-internal/src/GHC/Internal/ResponseFile.hs
- + libraries/ghc-internal/src/GHC/Internal/Stack/Annotation.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/CloneStack.hs
- libraries/ghc-heap/GHC/Exts/Stack/Constants.hsc → libraries/ghc-internal/src/GHC/Internal/Stack/Constants.hsc
- + libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- + libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/DerivedCoreProperties.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/GeneralCategory.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleLowerCaseMapping.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleTitleCaseMapping.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleUpperCaseMapping.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Version.hs
- libraries/ghc-heap/tests/stack-annotation/Makefile → libraries/ghc-internal/tests/stack-annotation/Makefile
- libraries/ghc-heap/tests/stack-annotation/TestUtils.hs → libraries/ghc-internal/tests/stack-annotation/TestUtils.hs
- libraries/ghc-heap/tests/stack-annotation/all.T → libraries/ghc-internal/tests/stack-annotation/all.T
- libraries/ghc-heap/tests/stack-annotation/ann_frame001.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame001.hs
- libraries/ghc-heap/tests/stack-annotation/ann_frame001.stdout → libraries/ghc-internal/tests/stack-annotation/ann_frame001.stdout
- libraries/ghc-heap/tests/stack-annotation/ann_frame002.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame002.hs
- libraries/ghc-heap/tests/stack-annotation/ann_frame002.stdout → libraries/ghc-internal/tests/stack-annotation/ann_frame002.stdout
- libraries/ghc-heap/tests/stack-annotation/ann_frame003.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame003.hs
- libraries/ghc-heap/tests/stack-annotation/ann_frame003.stdout → libraries/ghc-internal/tests/stack-annotation/ann_frame003.stdout
- libraries/ghc-heap/tests/stack-annotation/ann_frame004.hs → libraries/ghc-internal/tests/stack-annotation/ann_frame004.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame004.stdout
- libraries/ghc-internal/tools/ucd2haskell/ucd.sh
- libraries/ghc-internal/tools/ucd2haskell/ucd2haskell.cabal
- libraries/ghc-internal/tools/ucd2haskell/unicode_version
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/Run.hs
- libraries/ghci/GHCi/TH.hs
- libraries/ghci/ghci.cabal.in
- libraries/template-haskell/Language/Haskell/TH/Lib.hs
- libraries/template-haskell/Language/Haskell/TH/Quote.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- libraries/template-haskell/changelog.md
- linters/lint-codes/LintCodes/Coverage.hs
- m4/find_python.m4
- m4/fp_find_libdw.m4
- − m4/fp_settings.m4
- m4/fp_setup_windows_toolchain.m4
- − m4/fp_visibility_hidden.m4
- m4/fptools_set_c_ld_flags.m4
- m4/ghc_toolchain.m4
- m4/prep_target_file.m4
- + m4/subst_tooldir.m4
- mk/hsc2hs.in
- rts/BeginPrivate.h
- rts/CloneStack.c
- rts/CloneStack.h
- + rts/ClosureTable.c
- + rts/ClosureTable.h
- rts/Disassembler.c
- rts/EndPrivate.h
- rts/Hash.c
- rts/IOManager.c
- rts/IOManager.h
- rts/IOManagerInternals.h
- rts/IPE.c
- rts/Interpreter.c
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/Profiling.c
- − rts/RtsDllMain.c
- − rts/RtsDllMain.h
- rts/RtsMessages.c
- rts/RtsSignals.h
- rts/RtsStartup.c
- rts/RtsSymbols.c
- rts/RtsUtils.c
- rts/Schedule.c
- rts/StgMiscClosures.cmm
- rts/Task.c
- rts/Task.h
- rts/Threads.c
- + rts/TimeoutQueue.c
- + rts/TimeoutQueue.h
- rts/Trace.c
- rts/configure.ac
- rts/include/Rts.h
- rts/include/RtsAPI.h
- rts/include/Stg.h
- rts/include/rts/Bytecodes.h
- rts/include/rts/Constants.h
- rts/include/rts/Flags.h
- rts/include/rts/NonMoving.h
- rts/include/rts/OSThreads.h
- rts/include/rts/StableName.h
- rts/include/rts/StablePtr.h
- rts/include/rts/Types.h
- rts/include/rts/storage/Closures.h
- rts/include/rts/storage/TSO.h
- − rts/include/stg/DLL.h
- rts/include/stg/MiscClosures.h
- rts/js/mem.js
- rts/linker/MachO.c
- rts/posix/OSThreads.c
- + rts/posix/Poll.c
- + rts/posix/Poll.h
- + rts/posix/Timeout.c
- + rts/posix/Timeout.h
- rts/rts.cabal
- rts/sm/BlockAlloc.c
- rts/sm/Evac.c
- rts/sm/Evac.h
- rts/sm/GCTDecl.h
- rts/sm/GCThread.h
- rts/sm/Storage.c
- rts/win32/OSThreads.c
- testsuite/driver/testlib.py
- testsuite/ghc-config/ghc-config.hs
- testsuite/mk/test.mk
- testsuite/tests/arrows/gadt/T17423.stderr
- testsuite/tests/backpack/should_fail/bkpfail11.stderr
- testsuite/tests/backpack/should_fail/bkpfail43.stderr
- + testsuite/tests/bytecode/T26216.hs
- + testsuite/tests/bytecode/T26216.script
- + testsuite/tests/bytecode/T26216.stdout
- + testsuite/tests/bytecode/T26216_aux.hs
- testsuite/tests/bytecode/all.T
- testsuite/tests/codeGen/should_compile/Makefile
- testsuite/tests/codeGen/should_compile/T14999.stdout
- + testsuite/tests/codeGen/should_compile/T20298a.hs
- + testsuite/tests/codeGen/should_compile/T20298a.stderr
- + testsuite/tests/codeGen/should_compile/T20298b.hs
- + testsuite/tests/codeGen/should_compile/T20298b.stderr
- + testsuite/tests/codeGen/should_compile/T20298c.hs
- + testsuite/tests/codeGen/should_compile/T20298c.stderr
- testsuite/tests/codeGen/should_compile/T25166.stdout → testsuite/tests/codeGen/should_compile/T25166.stdout-ws-32
- + testsuite/tests/codeGen/should_compile/T25166.stdout-ws-64
- testsuite/tests/codeGen/should_compile/all.T
- testsuite/tests/codeGen/should_run/T13825-unit.hs
- testsuite/tests/codeGen/should_run/T23146/all.T
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/deriving/should_compile/T14682.stderr
- + testsuite/tests/deriving/should_compile/T26396.hs
- testsuite/tests/deriving/should_compile/all.T
- testsuite/tests/deriving/should_compile/drv-empty-data.stderr
- testsuite/tests/deriving/should_fail/T12768.stderr
- testsuite/tests/deriving/should_fail/T1496.stderr
- testsuite/tests/deriving/should_fail/T21302.stderr
- testsuite/tests/deriving/should_fail/T22696b.stderr
- testsuite/tests/deriving/should_fail/T5498.stderr
- testsuite/tests/deriving/should_fail/T7148.stderr
- testsuite/tests/deriving/should_fail/T7148a.stderr
- testsuite/tests/driver/all.T
- testsuite/tests/driver/j-space/Makefile
- testsuite/tests/driver/j-space/all.T
- testsuite/tests/driver/j-space/genJspace
- + testsuite/tests/driver/make-prim/GHC/Internal/Prim.hs
- + testsuite/tests/driver/make-prim/Makefile
- + testsuite/tests/driver/make-prim/Test.hs
- + testsuite/tests/driver/make-prim/Test2.hs
- + testsuite/tests/driver/make-prim/all.T
- testsuite/tests/driver/multipleHomeUnits/all.T
- testsuite/tests/ffi/should_run/T1288_c.c
- testsuite/tests/ffi/should_run/T1288_ghci_c.c
- testsuite/tests/ffi/should_run/T2276_c.c
- testsuite/tests/ffi/should_run/T2276_ghci_c.c
- testsuite/tests/ghc-api/T20757.hs
- testsuite/tests/ghc-api/settings-escape/T24265.hs
- testsuite/tests/ghc-api/settings-escape/T24265.stderr
- + testsuite/tests/ghc-api/settings-escape/ghc-install-folder/lib with spaces/targets/.gitkeep
- + testsuite/tests/ghci-wasm/Makefile
- + testsuite/tests/ghci-wasm/T26430.hs
- + testsuite/tests/ghci-wasm/T26430A.c
- + testsuite/tests/ghci-wasm/T26430B.c
- + testsuite/tests/ghci-wasm/all.T
- testsuite/tests/ghci.debugger/scripts/T26042b.script
- testsuite/tests/ghci.debugger/scripts/T26042b.stdout
- testsuite/tests/ghci.debugger/scripts/T26042c.script
- testsuite/tests/ghci.debugger/scripts/T26042c.stdout
- + testsuite/tests/ghci.debugger/scripts/T26042d2.hs
- + testsuite/tests/ghci.debugger/scripts/T26042d2.script
- + testsuite/tests/ghci.debugger/scripts/T26042d2.stdout
- testsuite/tests/ghci.debugger/scripts/T26042e.stdout
- testsuite/tests/ghci.debugger/scripts/T26042f.script
- testsuite/tests/ghci.debugger/scripts/T26042f1.stdout
- testsuite/tests/ghci.debugger/scripts/T26042f2.stdout
- testsuite/tests/ghci.debugger/scripts/T26042g.stdout
- testsuite/tests/ghci.debugger/scripts/all.T
- testsuite/tests/ghci.debugger/scripts/break022/all.T
- testsuite/tests/ghci.debugger/scripts/break022/break022.script
- testsuite/tests/ghci.debugger/scripts/break023/all.T
- testsuite/tests/ghci.debugger/scripts/break023/break023.script
- testsuite/tests/ghci/prog001/prog001.T
- testsuite/tests/ghci/prog001/prog001.script
- testsuite/tests/ghci/prog002/prog002.T
- testsuite/tests/ghci/prog002/prog002.script
- testsuite/tests/ghci/prog003/prog003.T
- testsuite/tests/ghci/prog003/prog003.script
- testsuite/tests/ghci/prog005/prog005.T
- testsuite/tests/ghci/prog005/prog005.script
- testsuite/tests/ghci/prog010/all.T
- testsuite/tests/ghci/prog010/ghci.prog010.script
- testsuite/tests/ghci/prog012/all.T
- testsuite/tests/ghci/prog012/prog012.script
- testsuite/tests/ghci/recompTHghci/all.T
- testsuite/tests/ghci/recompTHghci/recompTHghci.script
- testsuite/tests/ghci/scripts/T18330.script
- testsuite/tests/ghci/scripts/T18330.stdout
- testsuite/tests/ghci/scripts/T1914.script
- testsuite/tests/ghci/scripts/T20587.script
- testsuite/tests/ghci/scripts/T6106.script
- testsuite/tests/ghci/scripts/T7388.hs
- testsuite/tests/ghci/scripts/T7388.script
- testsuite/tests/ghci/scripts/T8353.script
- testsuite/tests/ghci/scripts/all.T
- testsuite/tests/ghci/scripts/ghci038.script
- testsuite/tests/ghci/scripts/ghci058.script
- testsuite/tests/ghci/scripts/ghci063.script
- − testsuite/tests/ghci/shell.hs
- testsuite/tests/impredicative/T17332.stderr
- testsuite/tests/indexed-types/should_compile/PushedInAsGivens.stderr
- testsuite/tests/indexed-types/should_fail/T26176.stderr
- testsuite/tests/indexed-types/should_fail/T2693.stderr
- testsuite/tests/indexed-types/should_fail/T4093b.stderr
- testsuite/tests/indexed-types/should_fail/T8518.stderr
- testsuite/tests/indexed-types/should_fail/T9662.stderr
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- + testsuite/tests/linear/should_compile/T26332.hs
- testsuite/tests/linear/should_compile/all.T
- testsuite/tests/linear/should_fail/Linear17.stderr
- testsuite/tests/linear/should_fail/LinearLet7.stderr
- + testsuite/tests/llvm/should_run/T26065.hs
- + testsuite/tests/llvm/should_run/T26065.stdout
- testsuite/tests/llvm/should_run/all.T
- testsuite/tests/numeric/should_run/foundation.hs
- + testsuite/tests/overloadedrecflds/should_fail/T26391.hs
- + testsuite/tests/overloadedrecflds/should_fail/T26391.stderr
- testsuite/tests/overloadedrecflds/should_fail/all.T
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail10.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail11.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail13.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
- testsuite/tests/parser/should_fail/T16270h.stderr
- + testsuite/tests/parser/should_fail/T26418.hs
- + testsuite/tests/parser/should_fail/T26418.stderr
- testsuite/tests/parser/should_fail/all.T
- + testsuite/tests/parser/should_run/T26415.hs
- + testsuite/tests/parser/should_run/T26415.stdout
- testsuite/tests/parser/should_run/all.T
- testsuite/tests/partial-sigs/should_compile/T21719.stderr
- + testsuite/tests/patsyn/should_compile/T26331.hs
- + testsuite/tests/patsyn/should_compile/T26331a.hs
- testsuite/tests/patsyn/should_compile/all.T
- testsuite/tests/perf/compiler/MultiLayerModulesDefsGhci.script
- testsuite/tests/perf/compiler/T4007.stdout
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/plugins/annotation-plugin/SayAnnNames.hs
- testsuite/tests/plugins/late-plugin/LatePlugin.hs
- testsuite/tests/plugins/plugins10.stdout
- testsuite/tests/plugins/simple-plugin/Simple/ReplacePlugin.hs
- testsuite/tests/polykinds/T13393.stderr
- + testsuite/tests/profiling/should_compile/T26056.hs
- testsuite/tests/profiling/should_compile/all.T
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/quantified-constraints/T19690.stderr
- testsuite/tests/quantified-constraints/T19921.stderr
- testsuite/tests/quantified-constraints/T21006.stderr
- testsuite/tests/rep-poly/T12709.stderr
- testsuite/tests/roles/should_fail/RolesIArray.stderr
- + testsuite/tests/rts/ClosureTable.hs
- + testsuite/tests/rts/ClosureTable_c.c
- + testsuite/tests/rts/TimeoutQueue.c
- + testsuite/tests/rts/TimeoutQueue.stdout
- testsuite/tests/rts/all.T
- testsuite/tests/rts/exec_signals_child.c
- testsuite/tests/rts/linker/T11223/all.T
- testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs
- testsuite/tests/simplCore/should_compile/DsSpecPragmas.stderr
- testsuite/tests/simplCore/should_compile/OpaqueNoCastWW.stderr
- testsuite/tests/simplCore/should_compile/T15056.stderr
- testsuite/tests/simplCore/should_compile/T15445.stderr
- + testsuite/tests/simplCore/should_compile/T26323b.hs
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_compile/simpl017.stderr
- + testsuite/tests/simplCore/should_run/T26323.hs
- + testsuite/tests/simplCore/should_run/T26323.stdout
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/splice-imports/SI29.stderr
- + testsuite/tests/tcplugins/T26395.hs
- + testsuite/tests/tcplugins/T26395.stderr
- + testsuite/tests/tcplugins/T26395_Plugin.hs
- testsuite/tests/tcplugins/all.T
- testsuite/tests/th/T10945.stderr
- testsuite/tests/th/T11452.stderr
- testsuite/tests/th/T15321.stderr
- testsuite/tests/th/T16180.hs
- testsuite/tests/th/T7276.stderr
- testsuite/tests/th/TH_NestedSplicesFail3.stderr
- testsuite/tests/th/TH_NestedSplicesFail4.stderr
- testsuite/tests/th/TH_StaticPointers02.stderr
- testsuite/tests/typecheck/should_compile/T11339.stderr
- testsuite/tests/typecheck/should_compile/T14434.hs
- + testsuite/tests/typecheck/should_compile/T26154.hs
- + testsuite/tests/typecheck/should_compile/T26154_A.hs
- + testsuite/tests/typecheck/should_compile/T26154_B.hs
- + testsuite/tests/typecheck/should_compile/T26154_B.hs-boot
- + testsuite/tests/typecheck/should_compile/T26154_Other.hs
- + testsuite/tests/typecheck/should_compile/T26277.hs
- + testsuite/tests/typecheck/should_compile/T26345.hs
- + testsuite/tests/typecheck/should_compile/T26346.hs
- + testsuite/tests/typecheck/should_compile/T26350.hs
- + testsuite/tests/typecheck/should_compile/T26358.hs
- + testsuite/tests/typecheck/should_compile/T26376.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/DoExpansion3.stderr
- testsuite/tests/typecheck/should_fail/T12177.stderr
- testsuite/tests/typecheck/should_fail/T15801.stderr
- testsuite/tests/typecheck/should_fail/T18851.hs
- testsuite/tests/typecheck/should_fail/T19627.stderr
- testsuite/tests/typecheck/should_fail/T20666.stderr
- testsuite/tests/typecheck/should_fail/T20666a.stderr
- testsuite/tests/typecheck/should_fail/T20666b.stderr
- testsuite/tests/typecheck/should_fail/T22707.stderr
- testsuite/tests/typecheck/should_fail/T22912.stderr
- testsuite/tests/typecheck/should_fail/T23427.stderr
- testsuite/tests/typecheck/should_fail/T24064.stderr
- + testsuite/tests/typecheck/should_fail/T26255a.hs
- + testsuite/tests/typecheck/should_fail/T26255a.stderr
- + testsuite/tests/typecheck/should_fail/T26255b.hs
- + testsuite/tests/typecheck/should_fail/T26255b.stderr
- + testsuite/tests/typecheck/should_fail/T26255c.hs
- + testsuite/tests/typecheck/should_fail/T26255c.stderr
- + testsuite/tests/typecheck/should_fail/T26330.hs
- + testsuite/tests/typecheck/should_fail/T26330.stderr
- testsuite/tests/typecheck/should_fail/T8142.stderr
- testsuite/tests/typecheck/should_fail/T8603.stderr
- testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail128.stderr
- testsuite/tests/typecheck/should_fail/tcfail153.stderr
- testsuite/tests/typecheck/should_fail/tcfail168.stderr
- testsuite/tests/typecheck/should_fail/tcfail177.stderr
- testsuite/tests/typecheck/should_fail/tcfail185.stderr
- testsuite/tests/typecheck/should_run/Typeable1.stderr
- + testsuite/tests/unboxedsums/UbxSumUnpackedSize.hs
- + testsuite/tests/unboxedsums/UbxSumUnpackedSize.stdout
- + testsuite/tests/unboxedsums/UbxSumUnpackedSize.stdout-ws-32
- testsuite/tests/unboxedsums/all.T
- testsuite/tests/unboxedsums/unboxedsums_unit_tests.hs
- utils/check-exact/ExactPrint.hs
- utils/deriveConstants/Main.hs
- utils/genprimopcode/Main.hs
- utils/genprimopcode/Syntax.hs
- utils/ghc-pkg/Main.hs
- utils/ghc-pkg/ghc-pkg.cabal.in
- utils/ghc-toolchain/exe/Main.hs
- utils/ghc-toolchain/ghc-toolchain.cabal
- + utils/ghc-toolchain/src/GHC/Toolchain/Library.hs
- utils/ghc-toolchain/src/GHC/Toolchain/PlatformDetails.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Target.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cc.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cxx.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Link.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Renderer.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Utils.hs
- utils/haddock/haddock-api/src/Haddock/InterfaceFile.hs
- utils/haddock/hypsrc-test/Main.hs
- utils/haddock/hypsrc-test/ref/src/Bug1091.html
- utils/haddock/hypsrc-test/ref/src/CPP.html
- utils/haddock/hypsrc-test/ref/src/Classes.html
- utils/haddock/hypsrc-test/ref/src/Constructors.html
- utils/haddock/hypsrc-test/ref/src/Identifiers.html
- utils/haddock/hypsrc-test/ref/src/LinkingIdentifiers.html
- utils/haddock/hypsrc-test/ref/src/Literals.html
- utils/haddock/hypsrc-test/ref/src/Operators.html
- utils/haddock/hypsrc-test/ref/src/Polymorphism.html
- utils/haddock/hypsrc-test/ref/src/PositionPragmas.html
- utils/haddock/hypsrc-test/ref/src/Quasiquoter.html
- utils/haddock/hypsrc-test/ref/src/Records.html
- utils/haddock/hypsrc-test/ref/src/TemplateHaskellQuasiquotes.html
- utils/haddock/hypsrc-test/ref/src/TemplateHaskellSplices.html
- utils/haddock/hypsrc-test/ref/src/Types.html
- utils/haddock/hypsrc-test/ref/src/UsingQuasiquotes.html
- utils/jsffi/dyld.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3570e1fe238ed6c77255b9042d108e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3570e1fe238ed6c77255b9042d108e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26166] 2 commits: rts: Dynamically initialize built-in closures
by Ben Gamari (@bgamari) 26 Sep '25
by Ben Gamari (@bgamari) 26 Sep '25
26 Sep '25
Ben Gamari pushed to branch wip/T26166 at Glasgow Haskell Compiler / GHC
Commits:
89d0cf88 by Ben Gamari at 2025-09-26T13:31:07-04:00
rts: Dynamically initialize built-in closures
- - - - -
7b7898eb by Ben Gamari at 2025-09-26T13:31:08-04:00
rts: Avoid static symbol references to ghc-internal
- - - - -
26 changed files:
- compiler/GHC/HsToCore/Foreign/C.hs
- + libraries/ghc-internal/cbits/RtsIface.c
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/include/RtsIfaceSymbols.h
- + rts/BuiltinClosures.c
- + rts/BuiltinClosures.h
- rts/Compact.cmm
- rts/ContinuationOps.cmm
- rts/Exception.cmm
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/RtsAPI.c
- rts/RtsStartup.c
- + rts/RtsToHsIface.c
- rts/Schedule.c
- rts/StgMiscClosures.cmm
- rts/StgStdThunks.cmm
- rts/include/Rts.h
- rts/include/RtsAPI.h
- rts/include/rts/Constants.h
- + rts/include/rts/RtsToHsIface.h
- rts/include/stg/MiscClosures.h
- rts/posix/Signals.c
- rts/rts.cabal
- rts/wasm/JSFFI.c
- utils/deriveConstants/Main.hs
Changes:
=====================================
compiler/GHC/HsToCore/Foreign/C.hs
=====================================
@@ -517,8 +517,8 @@ mkFExportCBits dflags c_nm maybe_target arg_htys res_hty is_IO_res_ty cc
text "rts_apply" <> parens (
cap
<> (if is_IO_res_ty
- then text "runIO_closure"
- else text "runNonIO_closure")
+ then text "ghc_hs_iface->runIO_closure"
+ else text "ghc_hs_iface->runNonIO_closure")
<> comma
<> expr_to_run
) <+> comma
=====================================
libraries/ghc-internal/cbits/RtsIface.c
=====================================
@@ -0,0 +1,42 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+#include "Rts.h"
+
+void init_ghc_hs_iface(void) __attribute__((constructor));
+
+#define CLOSURE(module, symbol) \
+ extern StgClosure ghczminternal_##module##_##symbol;
+
+#define UNDEF_CLOSURE(module, symbol)
+
+#define INFO_TBL(module, symbol) \
+ extern StgInfoTable ghczminternal_##module##_##symbol;
+
+#include "RtsIfaceSymbols.h"
+
+#undef CLOSURE
+#undef INFO_TBL
+
+#define CLOSURE(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+#define UNDEF_CLOSURE(module, symbol) \
+ .symbol = NULL,
+
+#define INFO_TBL(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+HsIface the_ghc_hs_iface = {
+#include "RtsIfaceSymbols.h"
+};
+
+void init_ghc_hs_iface(void)
+{
+ ghc_hs_iface = &the_ghc_hs_iface;
+}
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -43,6 +43,7 @@ extra-source-files:
include/winio_structs.h
include/WordSize.h
include/HsIntegerGmp.h.in
+ include/RtsIfaceSymbols.h
install-sh
source-repository head
@@ -457,6 +458,7 @@ Library
cbits/vectorQuotRem.c
cbits/word2float.c
cbits/Stack_c.c
+ cbits/RtsIface.c
cmm-sources:
cbits/StackCloningDecoding.cmm
=====================================
libraries/ghc-internal/include/RtsIfaceSymbols.h
=====================================
@@ -0,0 +1,59 @@
+// See Note [RTS/ghc-internal interface].
+
+#if defined(mingw32_HOST_OS)
+CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#else
+UNDEF_CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#endif
+CLOSURE(GHCziInternalziTopHandler, runIO_closure)
+CLOSURE(GHCziInternalziTopHandler, runNonIO_closure)
+CLOSURE(GHCziInternalziTuple, Z0T_closure)
+CLOSURE(GHCziInternalziTypes, True_closure)
+CLOSURE(GHCziInternalziTypes, False_closure)
+CLOSURE(GHCziInternalziPack, unpackCString_closure)
+CLOSURE(GHCziInternalziWeakziFinalizze, runFinalizzerBatch_closure)
+CLOSURE(GHCziInternalziIOziException, stackOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, heapOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, allocationLimitExceeded_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnMVar_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnSTM_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactFunction_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactPinned_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactMutable_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nonTermination_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nestedAtomically_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, noMatchingContinuationPrompt_closure)
+CLOSURE(GHCziInternalziEventziThread, blockedOnBadFD_closure)
+CLOSURE(GHCziInternalziConcziSync, runSparks_closure)
+CLOSURE(GHCziInternalziConcziIO, ensureIOManagerIsRunning_closure)
+CLOSURE(GHCziInternalziConcziIO, interruptIOManager_closure)
+CLOSURE(GHCziInternalziConcziIO, ioManagerCapabilitiesChanged_closure)
+CLOSURE(GHCziInternalziConcziSignal, runHandlersPtr_closure)
+CLOSURE(GHCziInternalziTopHandler, flushStdHandles_closure)
+CLOSURE(GHCziInternalziTopHandler, runMainIO_closure)
+INFO_TBL(GHCziInternalziTypes, Czh_con_info)
+INFO_TBL(GHCziInternalziTypes, Izh_con_info)
+INFO_TBL(GHCziInternalziTypes, Fzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Dzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Wzh_con_info)
+CLOSURE(GHCziInternalziPrimziPanic, absentSumFieldError_closure)
+CLOSURE(GHCziInternalziAllocationLimitHandler, runAllocationLimitHandler_closure)
+INFO_TBL(GHCziInternalziPtr, Ptr_con_info)
+INFO_TBL(GHCziInternalziPtr, FunPtr_con_info)
+INFO_TBL(GHCziInternalziInt, I8zh_con_info)
+INFO_TBL(GHCziInternalziInt, I16zh_con_info)
+INFO_TBL(GHCziInternalziInt, I32zh_con_info)
+INFO_TBL(GHCziInternalziInt, I64zh_con_info)
+INFO_TBL(GHCziInternalziWord, W8zh_con_info)
+INFO_TBL(GHCziInternalziWord, W16zh_con_info)
+INFO_TBL(GHCziInternalziWord, W32zh_con_info)
+INFO_TBL(GHCziInternalziWord, W64zh_con_info)
+INFO_TBL(GHCziInternalziStable, StablePtr_con_info)
+CLOSURE(GHCziInternalziStackziCloneStack, StackSnapshot_closure)
+CLOSURE(GHCziInternalziExceptionziType, divZZeroException_closure)
+CLOSURE(GHCziInternalziExceptionziType, underflowException_closure)
+CLOSURE(GHCziInternalziExceptionziType, overflowException_closure)
+CLOSURE(GHCziInternalziCString, unpackCStringzh_closure)
+INFO_TBL(GHCziInternalziCString, unpackCStringzh_info)
+INFO_TBL(GHCziInternalziCString, unpackCStringUtf8zh_info)
+
=====================================
rts/BuiltinClosures.c
=====================================
@@ -0,0 +1,29 @@
+#include "Rts.h"
+#include "BuiltinClosures.h"
+
+/*
+ * Note [CHARLIKE and INTLIKE closures]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * These are static representations of Chars and small Ints, so that
+ * we can remove dynamic Chars and Ints during garbage collection and
+ * replace them with references to the static objects.
+ */
+
+StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
+StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+
+void initBuiltinClosures() {
+ // INTLIKE closures
+ for (int i = MIN_INTLIKE; i <= MAX_INTLIKE - MIN_INTLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_INTLIKE_closure[i];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Izh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = MIN_INTLIKE + i;
+ }
+
+ // CHARLIKE closures
+ for (int i = MIN_CHARLIKE; i <= MAX_CHARLIKE - MIN_CHARLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_CHARLIKE_closure[i];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Czh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = MIN_CHARLIKE + i;
+ }
+}
=====================================
rts/BuiltinClosures.h
=====================================
@@ -0,0 +1,14 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ */
+
+#pragma once
+
+#include "BeginPrivate.h"
+
+void initBuiltinClosures(void);
+
+#include "EndPrivate.h"
=====================================
rts/Compact.cmm
=====================================
@@ -10,9 +10,6 @@
#include "Cmm.h"
#include "sm/ShouldCompact.h"
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE g0;
import CLOSURE large_alloc_lim;
@@ -124,7 +121,7 @@ eval:
SMALL_MUT_ARR_PTRS_CLEAN,
SMALL_MUT_ARR_PTRS_DIRTY,
COMPACT_NFDATA: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
+ jump stg_raisezh(HsIface_cannotCompactMutable_closure(W_[ghc_hs_iface]));
}
// We shouldn't see any functions, if this data structure was NFData.
@@ -139,7 +136,7 @@ eval:
BCO,
PAP,
CONTINUATION: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
+ jump stg_raisezh(HsIface_cannotCompactFunction_closure(W_[ghc_hs_iface]));
}
case ARR_WORDS: {
@@ -147,7 +144,7 @@ eval:
(should) = ccall shouldCompact(compact "ptr", p "ptr");
if (should == SHOULDCOMPACT_IN_CNF) { P_[pp] = p; return(); }
if (should == SHOULDCOMPACT_PINNED) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
+ jump stg_raisezh(HsIface_cannotCompactPinned_closure(W_[ghc_hs_iface]));
}
CHECK_HASH();
=====================================
rts/ContinuationOps.cmm
=====================================
@@ -12,7 +12,6 @@
#include "Cmm.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE ALLOC_RTS_ctr;
import CLOSURE ALLOC_RTS_tot;
@@ -104,7 +103,7 @@ stg_control0zh_ll // explicit stack
// see Note [When capturing the continuation fails] in Continuation.c
if (cont == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure);
+ jump stg_raisezh(HsIface_noMatchingContinuationPrompt_closure(W_[ghc_hs_iface]));
}
W_ apply_mask_frame;
=====================================
rts/Exception.cmm
=====================================
@@ -13,10 +13,6 @@
#include "Cmm.h"
#include "RaiseAsync.h"
-import CLOSURE ghczminternal_GHCziInternalziTypes_True_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_underflowException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_overflowException_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE CATCHF_PUSHED_ctr;
import CLOSURE RtsFlags;
@@ -539,7 +535,7 @@ retry_pop_stack:
Sp(10) = exception;
Sp(9) = stg_raise_ret_info;
Sp(8) = exception;
- Sp(7) = ghczminternal_GHCziInternalziTypes_True_closure; // True <=> an exception
+ Sp(7) = HsIface_True_closure(W_[ghc_hs_iface]); // True <=> an exception
Sp(6) = stg_ap_ppv_info;
Sp(5) = 0;
Sp(4) = stg_ap_n_info;
@@ -650,17 +646,17 @@ stg_raiseIOzh (P_ exception)
stg_raiseDivZZerozh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
+ jump stg_raisezh(HsIface_divZZeroException_closure(W_[ghc_hs_iface]));
}
stg_raiseUnderflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
+ jump stg_raisezh(HsIface_underflowException_closure(W_[ghc_hs_iface]));
}
stg_raiseOverflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
+ jump stg_raisezh(HsIface_overflowException_closure(W_[ghc_hs_iface]));
}
/* The FFI doesn't support variadic C functions so we can't directly expose
=====================================
rts/Prelude.h
=====================================
@@ -19,126 +19,69 @@
#define PRELUDE_CLOSURE(i) extern StgClosure (i)
#endif
-/* See Note [Wired-in exceptions are not CAFfy] in GHC.Core.Make. */
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure);
/* Define canonical names so we can abstract away from the actual
* modules these names are defined in.
*/
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTuple_Z0T_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_True_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_False_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCString_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCStringUtf8_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeak_runFinalizzerBatch_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure);
-
#if defined(IN_STG_CODE)
extern W_ ZCMain_main_closure[];
#else
extern StgClosure ZCMain_main_closure;
#endif
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSync_runSparks_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure);
-#if defined(mingw32_HOST_OS)
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure);
-#endif
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziCString_unpackCStringzh_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Czh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Izh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Fzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Dzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Wzh_con_info);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_Ptr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_FunPtr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziStable_StablePtr_con_info);
-
-#define Unit_closure (&(ghczminternal_GHCziInternalziTuple_Z0T_closure))
-#define True_closure (&(ghczminternal_GHCziInternalziTypes_True_closure))
-#define False_closure (&(ghczminternal_GHCziInternalziTypes_False_closure))
-#define unpackCString_closure (&(ghczminternal_GHCziInternalziPack_unpackCString_closure))
-#define runFinalizerBatch_closure (&(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure))
+#define Unit_closure ghc_hs_iface->Z0T_closure
+#define True_closure ghc_hs_iface->True_closure
+#define False_closure ghc_hs_iface->False_closure
+#define unpackCString_closure ghc_hs_iface->unpackCString_closure
+#define runFinalizerBatch_closure ghc_hs_iface->runFinalizzerBatch_closure
#define mainIO_closure (&ZCMain_main_closure)
-#define runSparks_closure (&(ghczminternal_GHCziInternalziConcziSync_runSparks_closure))
-#define ensureIOManagerIsRunning_closure (&(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure))
-#define interruptIOManager_closure (&(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure))
-#define ioManagerCapabilitiesChanged_closure (&(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure))
-#define runHandlersPtr_closure (&(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure))
+#define runSparks_closure ghc_hs_iface->runSparks_closure
+#define ensureIOManagerIsRunning_closure ghc_hs_iface->ensureIOManagerIsRunning_closure
+#define interruptIOManager_closure ghc_hs_iface->interruptIOManager_closure
+#define ioManagerCapabilitiesChanged_closure ghc_hs_iface->ioManagerCapabilitiesChanged_closure
+#define runHandlersPtr_closure ghc_hs_iface->runHandlersPtr_closure
#if defined(mingw32_HOST_OS)
-#define processRemoteCompletion_closure (&(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure))
+#define processRemoteCompletion_closure ghc_hs_iface->processRemoteCompletion_closure
#endif
-#define runAllocationLimitHandler_closure (&(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure))
-
-#define flushStdHandles_closure (&(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure))
-#define runMainIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure))
-
-#define stackOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure))
-#define heapOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure))
-#define allocationLimitExceeded_closure (&(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure))
-#define blockedIndefinitelyOnMVar_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure))
-#define blockedIndefinitelyOnSTM_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure))
-#define cannotCompactFunction_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure))
-#define cannotCompactPinned_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure))
-#define cannotCompactMutable_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure))
-#define nonTermination_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure))
-#define nestedAtomically_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure))
-#define absentSumFieldError_closure (&(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure))
-#define underflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure))
-#define overflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure))
-#define divZeroException_closure (&(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure))
-
-#define blockedOnBadFD_closure (&(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure))
-
-#define Czh_con_info (&(ghczminternal_GHCziInternalziTypes_Czh_con_info))
-#define Izh_con_info (&(ghczminternal_GHCziInternalziTypes_Izh_con_info))
-#define Fzh_con_info (&(ghczminternal_GHCziInternalziTypes_Fzh_con_info))
-#define Dzh_con_info (&(ghczminternal_GHCziInternalziTypes_Dzh_con_info))
-#define Wzh_con_info (&(ghczminternal_GHCziInternalziTypes_Wzh_con_info))
-#define W8zh_con_info (&(ghczminternal_GHCziInternalziWord_W8zh_con_info))
-#define W16zh_con_info (&(ghczminternal_GHCziInternalziWord_W16zh_con_info))
-#define W32zh_con_info (&(ghczminternal_GHCziInternalziWord_W32zh_con_info))
-#define W64zh_con_info (&(ghczminternal_GHCziInternalziWord_W64zh_con_info))
-#define I8zh_con_info (&(ghczminternal_GHCziInternalziInt_I8zh_con_info))
-#define I16zh_con_info (&(ghczminternal_GHCziInternalziInt_I16zh_con_info))
-#define I32zh_con_info (&(ghczminternal_GHCziInternalziInt_I32zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define Ptr_con_info (&(ghczminternal_GHCziInternalziPtr_Ptr_con_info))
-#define FunPtr_con_info (&(ghczminternal_GHCziInternalziPtr_FunPtr_con_info))
-#define StablePtr_static_info (&(ghczminternal_GHCziInternalziStable_StablePtr_static_info))
-#define StablePtr_con_info (&(ghczminternal_GHCziInternalziStable_StablePtr_con_info))
+#define runAllocationLimitHandler_closure ghc_hs_iface->runAllocationLimitHandler_closure
+
+#define flushStdHandles_closure ghc_hs_iface->flushStdHandles_closure
+#define runMainIO_closure ghc_hs_iface->runMainIO_closure
+
+#define stackOverflow_closure ghc_hs_iface->stackOverflow_closure
+#define heapOverflow_closure ghc_hs_iface->heapOverflow_closure
+#define allocationLimitExceeded_closure ghc_hs_iface->allocationLimitExceeded_closure
+#define blockedIndefinitelyOnMVar_closure ghc_hs_iface->blockedIndefinitelyOnMVar_closure
+#define blockedIndefinitelyOnSTM_closure ghc_hs_iface->blockedIndefinitelyOnSTM_closure
+#define cannotCompactFunction_closure ghc_hs_iface->cannotCompactFunction_closure
+#define cannotCompactPinned_closure ghc_hs_iface->cannotCompactPinned_closure
+#define cannotCompactMutable_closure ghc_hs_iface->cannotCompactMutable_closure
+#define nonTermination_closure ghc_hs_iface->nonTermination_closure
+#define nestedAtomically_closure ghc_hs_iface->nestedAtomically_closure
+#define absentSumFieldError_closure ghc_hs_iface->absentSumFieldError_closure
+#define underflowException_closure ghc_hs_iface->underflowException_closure
+#define overflowException_closure ghc_hs_iface->overflowException_closure
+#define divZeroException_closure ghc_hs_iface->divZZeroException_closure
+
+#define blockedOnBadFD_closure ghc_hs_iface->blockedOnBadFD_closure
+
+#define Czh_con_info ghc_hs_iface->Czh_con_info
+#define Izh_con_info ghc_hs_iface->Izh_con_info
+#define Fzh_con_info ghc_hs_iface->Fzh_con_info
+#define Dzh_con_info ghc_hs_iface->Dzh_con_info
+#define Wzh_con_info ghc_hs_iface->Wzh_con_info
+#define W8zh_con_info ghc_hs_iface->W8zh_con_info
+#define W16zh_con_info ghc_hs_iface->W16zh_con_info
+#define W32zh_con_info ghc_hs_iface->W32zh_con_info
+#define W64zh_con_info ghc_hs_iface->W64zh_con_info
+#define I8zh_con_info ghc_hs_iface->I8zh_con_info
+#define I16zh_con_info ghc_hs_iface->I16zh_con_info
+#define I32zh_con_info ghc_hs_iface->I32zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define Ptr_con_info ghc_hs_iface->Ptr_con_info
+#define FunPtr_con_info ghc_hs_iface->FunPtr_con_info
+#define StablePtr_static_info ghc_hs_iface->StablePtr_static_info
+#define StablePtr_con_info ghc_hs_iface->StablePtr_con_info
=====================================
rts/PrimOps.cmm
=====================================
@@ -25,12 +25,8 @@
#include "MachDeps.h"
#include "SMPClosureOps.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_heapOverflow_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
-import CLOSURE ghczminternal_GHCziInternalziTypes_False_closure;
#if defined(PROFILING)
import CLOSURE CCS_MAIN;
#endif
@@ -118,7 +114,7 @@ stg_newByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytes(MyCapability() "ptr", n, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -135,7 +131,7 @@ stg_newPinnedByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
BA_ALIGN, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -149,7 +145,7 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
alignment, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -364,7 +360,7 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -474,7 +470,7 @@ stg_newSmallArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateSmallMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -1090,7 +1086,7 @@ stg_listThreadszh ()
("ptr" arr) = ccall listThreads(MyCapability() "ptr");
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (arr);
@@ -1360,7 +1356,7 @@ stg_atomicallyzh (P_ stm)
/* Nested transactions are not allowed; raise an exception */
if (old_trec != NO_TREC) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
+ jump stg_raisezh(HsIface_nestedAtomically_closure(W_[ghc_hs_iface]));
}
code = stm;
@@ -2231,7 +2227,7 @@ stg_unpackClosurezh ( P_ closure )
dat_arr_sz = SIZEOF_StgArrBytes + WDS(len);
("ptr" dat_arr) = ccall allocateMightFail(MyCapability() "ptr", BYTES_TO_WDS(dat_arr_sz));
if (dat_arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
TICK_ALLOC_PRIM(SIZEOF_StgArrBytes, WDS(len), 0);
@@ -2251,7 +2247,7 @@ for:
("ptr" ptrArray) = foreign "C" heap_view_closurePtrs(MyCapability() "ptr", clos "ptr");
if (ptrArray == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (info, dat_arr, ptrArray);
@@ -2518,13 +2514,13 @@ stg_getSparkzh ()
W_ spark;
#if !defined(THREADED_RTS)
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
#else
("ptr" spark) = ccall findSpark(MyCapability() "ptr");
if (spark != 0) {
return (1,spark);
} else {
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
}
#endif
}
=====================================
rts/RtsAPI.c
=====================================
@@ -509,7 +509,7 @@ void rts_evalStableIOMain(/* inout */ Capability **cap,
SchedulerStatus stat;
p = (StgClosure *)deRefStablePtr(s);
- w = rts_apply(*cap, &ghczminternal_GHCziInternalziTopHandler_runMainIO_closure, p);
+ w = rts_apply(*cap, runMainIO_closure, p);
tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, w);
// async exceptions are always blocked by default in the created
// thread. See #1048.
@@ -961,7 +961,7 @@ void rts_done (void)
void hs_try_putmvar (/* in */ int capability,
/* in */ HsStablePtr mvar)
{
- hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, Unit_closure));
+ hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure));
}
void hs_try_putmvar_with_value (/* in */ int capability,
=====================================
rts/RtsStartup.c
=====================================
@@ -14,6 +14,7 @@
#include "linker/MMap.h"
#include "RtsFlags.h"
#include "RtsUtils.h"
+#include "BuiltinClosures.h"
#include "Prelude.h"
#include "Printer.h" /* DEBUG_LoadSymbols */
#include "Schedule.h" /* initScheduler */
@@ -182,8 +183,8 @@ static void initBuiltinGcRoots(void)
* these closures `Id`s of these can be safely marked as non-CAFFY
* in the compiler.
*/
- getStablePtr((StgPtr)runIO_closure);
- getStablePtr((StgPtr)runNonIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runNonIO_closure);
getStablePtr((StgPtr)flushStdHandles_closure);
getStablePtr((StgPtr)runFinalizerBatch_closure);
@@ -262,6 +263,14 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
setlocale(LC_CTYPE,"");
+ if (ghc_hs_iface == NULL) {
+ errorBelch("hs_init_ghc: ghc_hs_iface is uninitialized");
+ stg_exit(1);
+ }
+
+
+ initBuiltinClosures();
+
/* Initialise the stats department, phase 0 */
initStats0();
=====================================
rts/RtsToHsIface.c
=====================================
@@ -0,0 +1,45 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ *
+ * Note [RTS/ghc-internal interface]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The runtime system depends upon a variety of symbols defined by Haskell
+ * modules living in `ghc-internal`. To avoid cyclic dependencies between
+ * ghc-internal and the RTS, these symbols are referenced indirectly via the
+ * the `HsIface` structure (specifically `ghc_hs_iface`):
+ *
+ * struct HsIface {
+ * StgClosure *runIO; // GHC.Internal.TopHandler.runIO
+ * StgClosure *Z0T; // GHC.Internal.Tuple.()
+ * // etc.
+ * };
+ *
+ * `ghc_hs_iface` is initialized during program loading via the
+ * `init_ghc_hs_iface` constructor in `ghc-interface`
+ *
+ * const struct HsIface the_hs_iface = {
+ * .runIO = &ghczminternal_GHCziInternalziTopHandler_runIO_closure,
+ * .Z0T = &ghczminternal_GHCziInternalziTuple_Z0T_closure,
+ * // etc.
+ * };
+ *
+ * void __attribute__((constructor)) init_ghc_hs_iface() {
+ * ghc_hs_iface = &the_hs_iface;
+ * }
+ *
+ * This effectively breaks the RTS's link-time dependency, replacing it with a
+ * run-time dependency at the cost of an indirection. It also has the pleasant
+ * side-effect of making the interface between the RTS and `ghc-internal`
+ * explicit.
+ *
+ */
+
+#include "Rts.h"
+
+// This captures the symbols provided by ghc-internal which
+// are needed by the RTS.
+const HsIface *ghc_hs_iface = NULL;
=====================================
rts/Schedule.c
=====================================
@@ -1053,7 +1053,7 @@ scheduleProcessInbox (Capability **pcap USED_IF_THREADS)
while (p != NULL) {
pnext = p->link;
performTryPutMVar(cap, (StgMVar*)deRefStablePtr(p->mvar),
- Unit_closure);
+ ghc_hs_iface->Z0T_closure);
freeStablePtr(p->mvar);
stgFree(p);
p = pnext;
=====================================
rts/StgMiscClosures.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
import pthread_mutex_lock;
-import ghczminternal_GHCziInternalziTypes_Czh_info;
-import ghczminternal_GHCziInternalziTypes_Izh_info;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
@@ -23,7 +21,6 @@ import whitehole_lockClosure_spin;
import whitehole_lockClosure_yield;
#endif
-
#if !defined(UnregisterisedCompiler)
import CLOSURE CCS_SYSTEM;
import CLOSURE ENT_DYN_IND_ctr;
@@ -1031,554 +1028,3 @@ INFO_TABLE_CONSTR(stg_ASYNCIO_LIVE0,0,0,0,CONSTR_NOCAF,"ASYNCIO_LIVE0","ASYNCIO_
{ foreign "C" barf("ASYNCIO_LIVE0 object (%p) entered!", R1) never returns; }
CLOSURE(stg_ASYNCIO_LIVE0_closure,stg_ASYNCIO_LIVE0);
-
-/* ----------------------------------------------------------------------------
- Note [CHARLIKE and INTLIKE closures]
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- These are static representations of Chars and small Ints, so that
- we can remove dynamic Chars and Ints during garbage collection and
- replace them with references to the static objects.
- ------------------------------------------------------------------------- */
-
-#define Char_hash_con_info ghczminternal_GHCziInternalziTypes_Czh_con_info
-#define Int_hash_con_info ghczminternal_GHCziInternalziTypes_Izh_con_info
-
-#define CHARLIKE_HDR(n) CLOSURE(Char_hash_con_info, n)
-#define INTLIKE_HDR(n) CLOSURE(Int_hash_con_info, n)
-
-section "data" {
- stg_CHARLIKE_closure:
- CHARLIKE_HDR(0)
- CHARLIKE_HDR(1)
- CHARLIKE_HDR(2)
- CHARLIKE_HDR(3)
- CHARLIKE_HDR(4)
- CHARLIKE_HDR(5)
- CHARLIKE_HDR(6)
- CHARLIKE_HDR(7)
- CHARLIKE_HDR(8)
- CHARLIKE_HDR(9)
- CHARLIKE_HDR(10)
- CHARLIKE_HDR(11)
- CHARLIKE_HDR(12)
- CHARLIKE_HDR(13)
- CHARLIKE_HDR(14)
- CHARLIKE_HDR(15)
- CHARLIKE_HDR(16)
- CHARLIKE_HDR(17)
- CHARLIKE_HDR(18)
- CHARLIKE_HDR(19)
- CHARLIKE_HDR(20)
- CHARLIKE_HDR(21)
- CHARLIKE_HDR(22)
- CHARLIKE_HDR(23)
- CHARLIKE_HDR(24)
- CHARLIKE_HDR(25)
- CHARLIKE_HDR(26)
- CHARLIKE_HDR(27)
- CHARLIKE_HDR(28)
- CHARLIKE_HDR(29)
- CHARLIKE_HDR(30)
- CHARLIKE_HDR(31)
- CHARLIKE_HDR(32)
- CHARLIKE_HDR(33)
- CHARLIKE_HDR(34)
- CHARLIKE_HDR(35)
- CHARLIKE_HDR(36)
- CHARLIKE_HDR(37)
- CHARLIKE_HDR(38)
- CHARLIKE_HDR(39)
- CHARLIKE_HDR(40)
- CHARLIKE_HDR(41)
- CHARLIKE_HDR(42)
- CHARLIKE_HDR(43)
- CHARLIKE_HDR(44)
- CHARLIKE_HDR(45)
- CHARLIKE_HDR(46)
- CHARLIKE_HDR(47)
- CHARLIKE_HDR(48)
- CHARLIKE_HDR(49)
- CHARLIKE_HDR(50)
- CHARLIKE_HDR(51)
- CHARLIKE_HDR(52)
- CHARLIKE_HDR(53)
- CHARLIKE_HDR(54)
- CHARLIKE_HDR(55)
- CHARLIKE_HDR(56)
- CHARLIKE_HDR(57)
- CHARLIKE_HDR(58)
- CHARLIKE_HDR(59)
- CHARLIKE_HDR(60)
- CHARLIKE_HDR(61)
- CHARLIKE_HDR(62)
- CHARLIKE_HDR(63)
- CHARLIKE_HDR(64)
- CHARLIKE_HDR(65)
- CHARLIKE_HDR(66)
- CHARLIKE_HDR(67)
- CHARLIKE_HDR(68)
- CHARLIKE_HDR(69)
- CHARLIKE_HDR(70)
- CHARLIKE_HDR(71)
- CHARLIKE_HDR(72)
- CHARLIKE_HDR(73)
- CHARLIKE_HDR(74)
- CHARLIKE_HDR(75)
- CHARLIKE_HDR(76)
- CHARLIKE_HDR(77)
- CHARLIKE_HDR(78)
- CHARLIKE_HDR(79)
- CHARLIKE_HDR(80)
- CHARLIKE_HDR(81)
- CHARLIKE_HDR(82)
- CHARLIKE_HDR(83)
- CHARLIKE_HDR(84)
- CHARLIKE_HDR(85)
- CHARLIKE_HDR(86)
- CHARLIKE_HDR(87)
- CHARLIKE_HDR(88)
- CHARLIKE_HDR(89)
- CHARLIKE_HDR(90)
- CHARLIKE_HDR(91)
- CHARLIKE_HDR(92)
- CHARLIKE_HDR(93)
- CHARLIKE_HDR(94)
- CHARLIKE_HDR(95)
- CHARLIKE_HDR(96)
- CHARLIKE_HDR(97)
- CHARLIKE_HDR(98)
- CHARLIKE_HDR(99)
- CHARLIKE_HDR(100)
- CHARLIKE_HDR(101)
- CHARLIKE_HDR(102)
- CHARLIKE_HDR(103)
- CHARLIKE_HDR(104)
- CHARLIKE_HDR(105)
- CHARLIKE_HDR(106)
- CHARLIKE_HDR(107)
- CHARLIKE_HDR(108)
- CHARLIKE_HDR(109)
- CHARLIKE_HDR(110)
- CHARLIKE_HDR(111)
- CHARLIKE_HDR(112)
- CHARLIKE_HDR(113)
- CHARLIKE_HDR(114)
- CHARLIKE_HDR(115)
- CHARLIKE_HDR(116)
- CHARLIKE_HDR(117)
- CHARLIKE_HDR(118)
- CHARLIKE_HDR(119)
- CHARLIKE_HDR(120)
- CHARLIKE_HDR(121)
- CHARLIKE_HDR(122)
- CHARLIKE_HDR(123)
- CHARLIKE_HDR(124)
- CHARLIKE_HDR(125)
- CHARLIKE_HDR(126)
- CHARLIKE_HDR(127)
- CHARLIKE_HDR(128)
- CHARLIKE_HDR(129)
- CHARLIKE_HDR(130)
- CHARLIKE_HDR(131)
- CHARLIKE_HDR(132)
- CHARLIKE_HDR(133)
- CHARLIKE_HDR(134)
- CHARLIKE_HDR(135)
- CHARLIKE_HDR(136)
- CHARLIKE_HDR(137)
- CHARLIKE_HDR(138)
- CHARLIKE_HDR(139)
- CHARLIKE_HDR(140)
- CHARLIKE_HDR(141)
- CHARLIKE_HDR(142)
- CHARLIKE_HDR(143)
- CHARLIKE_HDR(144)
- CHARLIKE_HDR(145)
- CHARLIKE_HDR(146)
- CHARLIKE_HDR(147)
- CHARLIKE_HDR(148)
- CHARLIKE_HDR(149)
- CHARLIKE_HDR(150)
- CHARLIKE_HDR(151)
- CHARLIKE_HDR(152)
- CHARLIKE_HDR(153)
- CHARLIKE_HDR(154)
- CHARLIKE_HDR(155)
- CHARLIKE_HDR(156)
- CHARLIKE_HDR(157)
- CHARLIKE_HDR(158)
- CHARLIKE_HDR(159)
- CHARLIKE_HDR(160)
- CHARLIKE_HDR(161)
- CHARLIKE_HDR(162)
- CHARLIKE_HDR(163)
- CHARLIKE_HDR(164)
- CHARLIKE_HDR(165)
- CHARLIKE_HDR(166)
- CHARLIKE_HDR(167)
- CHARLIKE_HDR(168)
- CHARLIKE_HDR(169)
- CHARLIKE_HDR(170)
- CHARLIKE_HDR(171)
- CHARLIKE_HDR(172)
- CHARLIKE_HDR(173)
- CHARLIKE_HDR(174)
- CHARLIKE_HDR(175)
- CHARLIKE_HDR(176)
- CHARLIKE_HDR(177)
- CHARLIKE_HDR(178)
- CHARLIKE_HDR(179)
- CHARLIKE_HDR(180)
- CHARLIKE_HDR(181)
- CHARLIKE_HDR(182)
- CHARLIKE_HDR(183)
- CHARLIKE_HDR(184)
- CHARLIKE_HDR(185)
- CHARLIKE_HDR(186)
- CHARLIKE_HDR(187)
- CHARLIKE_HDR(188)
- CHARLIKE_HDR(189)
- CHARLIKE_HDR(190)
- CHARLIKE_HDR(191)
- CHARLIKE_HDR(192)
- CHARLIKE_HDR(193)
- CHARLIKE_HDR(194)
- CHARLIKE_HDR(195)
- CHARLIKE_HDR(196)
- CHARLIKE_HDR(197)
- CHARLIKE_HDR(198)
- CHARLIKE_HDR(199)
- CHARLIKE_HDR(200)
- CHARLIKE_HDR(201)
- CHARLIKE_HDR(202)
- CHARLIKE_HDR(203)
- CHARLIKE_HDR(204)
- CHARLIKE_HDR(205)
- CHARLIKE_HDR(206)
- CHARLIKE_HDR(207)
- CHARLIKE_HDR(208)
- CHARLIKE_HDR(209)
- CHARLIKE_HDR(210)
- CHARLIKE_HDR(211)
- CHARLIKE_HDR(212)
- CHARLIKE_HDR(213)
- CHARLIKE_HDR(214)
- CHARLIKE_HDR(215)
- CHARLIKE_HDR(216)
- CHARLIKE_HDR(217)
- CHARLIKE_HDR(218)
- CHARLIKE_HDR(219)
- CHARLIKE_HDR(220)
- CHARLIKE_HDR(221)
- CHARLIKE_HDR(222)
- CHARLIKE_HDR(223)
- CHARLIKE_HDR(224)
- CHARLIKE_HDR(225)
- CHARLIKE_HDR(226)
- CHARLIKE_HDR(227)
- CHARLIKE_HDR(228)
- CHARLIKE_HDR(229)
- CHARLIKE_HDR(230)
- CHARLIKE_HDR(231)
- CHARLIKE_HDR(232)
- CHARLIKE_HDR(233)
- CHARLIKE_HDR(234)
- CHARLIKE_HDR(235)
- CHARLIKE_HDR(236)
- CHARLIKE_HDR(237)
- CHARLIKE_HDR(238)
- CHARLIKE_HDR(239)
- CHARLIKE_HDR(240)
- CHARLIKE_HDR(241)
- CHARLIKE_HDR(242)
- CHARLIKE_HDR(243)
- CHARLIKE_HDR(244)
- CHARLIKE_HDR(245)
- CHARLIKE_HDR(246)
- CHARLIKE_HDR(247)
- CHARLIKE_HDR(248)
- CHARLIKE_HDR(249)
- CHARLIKE_HDR(250)
- CHARLIKE_HDR(251)
- CHARLIKE_HDR(252)
- CHARLIKE_HDR(253)
- CHARLIKE_HDR(254)
- CHARLIKE_HDR(255)
-}
-
-section "data" {
- stg_INTLIKE_closure:
- INTLIKE_HDR(-16) /* MIN_INTLIKE == -16 */
- INTLIKE_HDR(-15)
- INTLIKE_HDR(-14)
- INTLIKE_HDR(-13)
- INTLIKE_HDR(-12)
- INTLIKE_HDR(-11)
- INTLIKE_HDR(-10)
- INTLIKE_HDR(-9)
- INTLIKE_HDR(-8)
- INTLIKE_HDR(-7)
- INTLIKE_HDR(-6)
- INTLIKE_HDR(-5)
- INTLIKE_HDR(-4)
- INTLIKE_HDR(-3)
- INTLIKE_HDR(-2)
- INTLIKE_HDR(-1)
- INTLIKE_HDR(0)
- INTLIKE_HDR(1)
- INTLIKE_HDR(2)
- INTLIKE_HDR(3)
- INTLIKE_HDR(4)
- INTLIKE_HDR(5)
- INTLIKE_HDR(6)
- INTLIKE_HDR(7)
- INTLIKE_HDR(8)
- INTLIKE_HDR(9)
- INTLIKE_HDR(10)
- INTLIKE_HDR(11)
- INTLIKE_HDR(12)
- INTLIKE_HDR(13)
- INTLIKE_HDR(14)
- INTLIKE_HDR(15)
- INTLIKE_HDR(16)
- INTLIKE_HDR(17)
- INTLIKE_HDR(18)
- INTLIKE_HDR(19)
- INTLIKE_HDR(20)
- INTLIKE_HDR(21)
- INTLIKE_HDR(22)
- INTLIKE_HDR(23)
- INTLIKE_HDR(24)
- INTLIKE_HDR(25)
- INTLIKE_HDR(26)
- INTLIKE_HDR(27)
- INTLIKE_HDR(28)
- INTLIKE_HDR(29)
- INTLIKE_HDR(30)
- INTLIKE_HDR(31)
- INTLIKE_HDR(32)
- INTLIKE_HDR(33)
- INTLIKE_HDR(34)
- INTLIKE_HDR(35)
- INTLIKE_HDR(36)
- INTLIKE_HDR(37)
- INTLIKE_HDR(38)
- INTLIKE_HDR(39)
- INTLIKE_HDR(40)
- INTLIKE_HDR(41)
- INTLIKE_HDR(42)
- INTLIKE_HDR(43)
- INTLIKE_HDR(44)
- INTLIKE_HDR(45)
- INTLIKE_HDR(46)
- INTLIKE_HDR(47)
- INTLIKE_HDR(48)
- INTLIKE_HDR(49)
- INTLIKE_HDR(50)
- INTLIKE_HDR(51)
- INTLIKE_HDR(52)
- INTLIKE_HDR(53)
- INTLIKE_HDR(54)
- INTLIKE_HDR(55)
- INTLIKE_HDR(56)
- INTLIKE_HDR(57)
- INTLIKE_HDR(58)
- INTLIKE_HDR(59)
- INTLIKE_HDR(60)
- INTLIKE_HDR(61)
- INTLIKE_HDR(62)
- INTLIKE_HDR(63)
- INTLIKE_HDR(64)
- INTLIKE_HDR(65)
- INTLIKE_HDR(66)
- INTLIKE_HDR(67)
- INTLIKE_HDR(68)
- INTLIKE_HDR(69)
- INTLIKE_HDR(70)
- INTLIKE_HDR(71)
- INTLIKE_HDR(72)
- INTLIKE_HDR(73)
- INTLIKE_HDR(74)
- INTLIKE_HDR(75)
- INTLIKE_HDR(76)
- INTLIKE_HDR(77)
- INTLIKE_HDR(78)
- INTLIKE_HDR(79)
- INTLIKE_HDR(80)
- INTLIKE_HDR(81)
- INTLIKE_HDR(82)
- INTLIKE_HDR(83)
- INTLIKE_HDR(84)
- INTLIKE_HDR(85)
- INTLIKE_HDR(86)
- INTLIKE_HDR(87)
- INTLIKE_HDR(88)
- INTLIKE_HDR(89)
- INTLIKE_HDR(90)
- INTLIKE_HDR(91)
- INTLIKE_HDR(92)
- INTLIKE_HDR(93)
- INTLIKE_HDR(94)
- INTLIKE_HDR(95)
- INTLIKE_HDR(96)
- INTLIKE_HDR(97)
- INTLIKE_HDR(98)
- INTLIKE_HDR(99)
- INTLIKE_HDR(100)
- INTLIKE_HDR(101)
- INTLIKE_HDR(102)
- INTLIKE_HDR(103)
- INTLIKE_HDR(104)
- INTLIKE_HDR(105)
- INTLIKE_HDR(106)
- INTLIKE_HDR(107)
- INTLIKE_HDR(108)
- INTLIKE_HDR(109)
- INTLIKE_HDR(110)
- INTLIKE_HDR(111)
- INTLIKE_HDR(112)
- INTLIKE_HDR(113)
- INTLIKE_HDR(114)
- INTLIKE_HDR(115)
- INTLIKE_HDR(116)
- INTLIKE_HDR(117)
- INTLIKE_HDR(118)
- INTLIKE_HDR(119)
- INTLIKE_HDR(120)
- INTLIKE_HDR(121)
- INTLIKE_HDR(122)
- INTLIKE_HDR(123)
- INTLIKE_HDR(124)
- INTLIKE_HDR(125)
- INTLIKE_HDR(126)
- INTLIKE_HDR(127)
- INTLIKE_HDR(128)
- INTLIKE_HDR(129)
- INTLIKE_HDR(130)
- INTLIKE_HDR(131)
- INTLIKE_HDR(132)
- INTLIKE_HDR(133)
- INTLIKE_HDR(134)
- INTLIKE_HDR(135)
- INTLIKE_HDR(136)
- INTLIKE_HDR(137)
- INTLIKE_HDR(138)
- INTLIKE_HDR(139)
- INTLIKE_HDR(140)
- INTLIKE_HDR(141)
- INTLIKE_HDR(142)
- INTLIKE_HDR(143)
- INTLIKE_HDR(144)
- INTLIKE_HDR(145)
- INTLIKE_HDR(146)
- INTLIKE_HDR(147)
- INTLIKE_HDR(148)
- INTLIKE_HDR(149)
- INTLIKE_HDR(150)
- INTLIKE_HDR(151)
- INTLIKE_HDR(152)
- INTLIKE_HDR(153)
- INTLIKE_HDR(154)
- INTLIKE_HDR(155)
- INTLIKE_HDR(156)
- INTLIKE_HDR(157)
- INTLIKE_HDR(158)
- INTLIKE_HDR(159)
- INTLIKE_HDR(160)
- INTLIKE_HDR(161)
- INTLIKE_HDR(162)
- INTLIKE_HDR(163)
- INTLIKE_HDR(164)
- INTLIKE_HDR(165)
- INTLIKE_HDR(166)
- INTLIKE_HDR(167)
- INTLIKE_HDR(168)
- INTLIKE_HDR(169)
- INTLIKE_HDR(170)
- INTLIKE_HDR(171)
- INTLIKE_HDR(172)
- INTLIKE_HDR(173)
- INTLIKE_HDR(174)
- INTLIKE_HDR(175)
- INTLIKE_HDR(176)
- INTLIKE_HDR(177)
- INTLIKE_HDR(178)
- INTLIKE_HDR(179)
- INTLIKE_HDR(180)
- INTLIKE_HDR(181)
- INTLIKE_HDR(182)
- INTLIKE_HDR(183)
- INTLIKE_HDR(184)
- INTLIKE_HDR(185)
- INTLIKE_HDR(186)
- INTLIKE_HDR(187)
- INTLIKE_HDR(188)
- INTLIKE_HDR(189)
- INTLIKE_HDR(190)
- INTLIKE_HDR(191)
- INTLIKE_HDR(192)
- INTLIKE_HDR(193)
- INTLIKE_HDR(194)
- INTLIKE_HDR(195)
- INTLIKE_HDR(196)
- INTLIKE_HDR(197)
- INTLIKE_HDR(198)
- INTLIKE_HDR(199)
- INTLIKE_HDR(200)
- INTLIKE_HDR(201)
- INTLIKE_HDR(202)
- INTLIKE_HDR(203)
- INTLIKE_HDR(204)
- INTLIKE_HDR(205)
- INTLIKE_HDR(206)
- INTLIKE_HDR(207)
- INTLIKE_HDR(208)
- INTLIKE_HDR(209)
- INTLIKE_HDR(210)
- INTLIKE_HDR(211)
- INTLIKE_HDR(212)
- INTLIKE_HDR(213)
- INTLIKE_HDR(214)
- INTLIKE_HDR(215)
- INTLIKE_HDR(216)
- INTLIKE_HDR(217)
- INTLIKE_HDR(218)
- INTLIKE_HDR(219)
- INTLIKE_HDR(220)
- INTLIKE_HDR(221)
- INTLIKE_HDR(222)
- INTLIKE_HDR(223)
- INTLIKE_HDR(224)
- INTLIKE_HDR(225)
- INTLIKE_HDR(226)
- INTLIKE_HDR(227)
- INTLIKE_HDR(228)
- INTLIKE_HDR(229)
- INTLIKE_HDR(230)
- INTLIKE_HDR(231)
- INTLIKE_HDR(232)
- INTLIKE_HDR(233)
- INTLIKE_HDR(234)
- INTLIKE_HDR(235)
- INTLIKE_HDR(236)
- INTLIKE_HDR(237)
- INTLIKE_HDR(238)
- INTLIKE_HDR(239)
- INTLIKE_HDR(240)
- INTLIKE_HDR(241)
- INTLIKE_HDR(242)
- INTLIKE_HDR(243)
- INTLIKE_HDR(244)
- INTLIKE_HDR(245)
- INTLIKE_HDR(246)
- INTLIKE_HDR(247)
- INTLIKE_HDR(248)
- INTLIKE_HDR(249)
- INTLIKE_HDR(250)
- INTLIKE_HDR(251)
- INTLIKE_HDR(252)
- INTLIKE_HDR(253)
- INTLIKE_HDR(254)
- INTLIKE_HDR(255) /* MAX_INTLIKE == 255
- See #16961 for why 255 */
-}
=====================================
rts/StgStdThunks.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
#include "Updates.h"
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringzh_info;
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info;
#if !defined(UnregisterisedCompiler)
import CLOSURE STK_CHK_ctr;
import CLOSURE stg_bh_upd_frame_info;
@@ -348,7 +346,7 @@ stg_do_unpack_cstring(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringzh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringzh_info(W_[ghc_hs_iface]))(node, str);
}
}
@@ -372,7 +370,7 @@ stg_do_unpack_cstring_utf8(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringUtf8zh_info(W_[ghc_hs_iface]))(node, str);
}
}
=====================================
rts/include/Rts.h
=====================================
@@ -229,6 +229,7 @@ void _warnFail(const char *filename, unsigned int linenum);
#include "rts/storage/ClosureTypes.h"
#include "rts/storage/TSO.h"
#include "stg/MiscClosures.h" /* InfoTables, closures etc. defined in the RTS */
+
#include "rts/storage/Block.h"
#include "rts/storage/ClosureMacros.h"
#include "rts/storage/MBlock.h"
=====================================
rts/include/RtsAPI.h
=====================================
@@ -18,6 +18,7 @@ extern "C" {
#include "HsFFI.h"
#include "rts/Time.h"
#include "rts/Types.h"
+#include "rts/RtsToHsIface.h"
/*
* Running the scheduler
@@ -584,11 +585,6 @@ void rts_done (void);
// Note that RtsAPI.h is also included by foreign export stubs in
// the base package itself.
//
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runIO_closure;
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runNonIO_closure;
-
-#define runIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runIO_closure))
-#define runNonIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runNonIO_closure))
/* ------------------------------------------------------------------------ */
=====================================
rts/include/rts/Constants.h
=====================================
@@ -57,11 +57,12 @@
#define MAX_SPEC_CONSTR_SIZE 2
/* Range of built-in table of static small int-like and char-like closures.
+ * Range is inclusive of both minimum and maximum.
*
* NB. This corresponds with the number of actual INTLIKE/CHARLIKE
* closures defined in rts/StgMiscClosures.cmm.
*/
-#define MAX_INTLIKE 255
+#define MAX_INTLIKE 255 /* See #16961 for why 255 */
#define MIN_INTLIKE (-16)
#define MAX_CHARLIKE 255
=====================================
rts/include/rts/RtsToHsIface.h
=====================================
@@ -0,0 +1,64 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+typedef struct {
+ StgClosure *processRemoteCompletion_closure; // GHC.Internal.Event.Windows.processRemoteCompletion_closure
+ StgClosure *runIO_closure; // GHC.Internal.TopHandler.runIO_closure
+ StgClosure *runNonIO_closure; // GHC.Internal.TopHandler.runNonIO_closure
+ StgClosure *Z0T_closure; // GHC.Internal.Tuple.Z0T_closure
+ StgClosure *True_closure; // GHC.Internal.Types.True_closure
+ StgClosure *False_closure; // GHC.Internal.Types.False_closure
+ StgClosure *unpackCString_closure; // GHC.Internal.Pack.unpackCString_closure
+ StgClosure *runFinalizzerBatch_closure; // GHC.Internal.Weak.Finalizze.runFinalizzerBatch_closure
+ StgClosure *stackOverflow_closure; // GHC.Internal.IO.Exception.stackOverflow_closure
+ StgClosure *heapOverflow_closure; // GHC.Internal.IO.Exception.heapOverflow_closure
+ StgClosure *allocationLimitExceeded_closure; // GHC.Internal.IO.Exception.allocationLimitExceeded_closure
+ StgClosure *blockedIndefinitelyOnMVar_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnMVar_closure
+ StgClosure *blockedIndefinitelyOnSTM_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnSTM_closure
+ StgClosure *cannotCompactFunction_closure; // GHC.Internal.IO.Exception.cannotCompactFunction_closure
+ StgClosure *cannotCompactPinned_closure; // GHC.Internal.IO.Exception.cannotCompactPinned_closure
+ StgClosure *cannotCompactMutable_closure; // GHC.Internal.IO.Exception.cannotCompactMutable_closure
+ StgClosure *nonTermination_closure; // GHC.Internal.Control.Exception.Base.nonTermination_closure
+ StgClosure *nestedAtomically_closure; // GHC.Internal.Control.Exception.Base.nestedAtomically_closure
+ StgClosure *noMatchingContinuationPrompt_closure; // GHC.Internal.Control.Exception.Base.noMatchingContinuationPrompt_closure
+ StgClosure *blockedOnBadFD_closure; // GHC.Internal.Event.Thread.blockedOnBadFD_closure
+ StgClosure *runSparks_closure; // GHC.Internal.Conc.Sync.runSparks_closure
+ StgClosure *ensureIOManagerIsRunning_closure; // GHC.Internal.Conc.IO.ensureIOManagerIsRunning_closure
+ StgClosure *interruptIOManager_closure; // GHC.Internal.Conc.IO.interruptIOManager_closure
+ StgClosure *ioManagerCapabilitiesChanged_closure; // GHC.Internal.Conc.IO.ioManagerCapabilitiesChanged_closure
+ StgClosure *runHandlersPtr_closure; // GHC.Internal.Conc.Signal.runHandlersPtr_closure
+ StgClosure *flushStdHandles_closure; // GHC.Internal.TopHandler.flushStdHandles_closure
+ StgClosure *runMainIO_closure; // GHC.Internal.TopHandler.runMainIO_closure
+ StgInfoTable *Czh_con_info; // GHC.Internal.Types.Czh_con_info
+ StgInfoTable *Izh_con_info; // GHC.Internal.Types.Izh_con_info
+ StgInfoTable *Fzh_con_info; // GHC.Internal.Types.Fzh_con_info
+ StgInfoTable *Dzh_con_info; // GHC.Internal.Types.Dzh_con_info
+ StgInfoTable *Wzh_con_info; // GHC.Internal.Types.Wzh_con_info
+ StgClosure *absentSumFieldError_closure; // GHC.Internal.Prim.Panic.absentSumFieldError_closure
+ StgClosure *runAllocationLimitHandler_closure; // GHC.Internal.AllocationLimitHandler.runAllocationLimitHandler_closure
+ StgInfoTable *Ptr_con_info; // GHC.Internal.Ptr.Ptr_con_info
+ StgInfoTable *FunPtr_con_info; // GHC.Internal.Ptr.FunPtr_con_info
+ StgInfoTable *I8zh_con_info; // GHC.Internal.Int.I8zh_con_info
+ StgInfoTable *I16zh_con_info; // GHC.Internal.Int.I16zh_con_info
+ StgInfoTable *I32zh_con_info; // GHC.Internal.Int.I32zh_con_info
+ StgInfoTable *I64zh_con_info; // GHC.Internal.Int.I64zh_con_info
+ StgInfoTable *W8zh_con_info; // GHC.Internal.Word.W8zh_con_info
+ StgInfoTable *W16zh_con_info; // GHC.Internal.Word.W16zh_con_info
+ StgInfoTable *W32zh_con_info; // GHC.Internal.Word.W32zh_con_info
+ StgInfoTable *W64zh_con_info; // GHC.Internal.Word.W64zh_con_info
+ StgInfoTable *StablePtr_con_info; // GHC.Internal.Stable.StablePtr_con_info
+ StgClosure *StackSnapshot_closure; // GHC.Internal.Stack.CloneStack.StackSnapshot_closure
+ StgClosure *divZZeroException_closure; // GHC.Internal.Exception.Type.divZeroException_closure
+ StgClosure *underflowException_closure; // GHC.Internal.Exception.Type.underflowException_closure
+ StgClosure *overflowException_closure; // GHC.Internal.Exception.Type.overflowException_closure
+ StgClosure *unpackCStringzh_closure; // GHC.Internal.CString.unpackCStringzh_closure
+ StgInfoTable *unpackCStringzh_info; // GHC.Internal.CString.unpackCStringzh_info
+ StgInfoTable *unpackCStringUtf8zh_info; // GHC.Internal.CString.unpackCStringUtf8zh_info
+} HsIface;
+
+extern const HsIface *ghc_hs_iface;
=====================================
rts/include/stg/MiscClosures.h
=====================================
@@ -277,8 +277,8 @@ RTS_ENTRY(stg_NO_FINALIZER);
extern StgWordArray stg_CHARLIKE_closure;
extern StgWordArray stg_INTLIKE_closure;
#else
-extern StgIntCharlikeClosure stg_CHARLIKE_closure[];
-extern StgIntCharlikeClosure stg_INTLIKE_closure[];
+extern StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+extern StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
#endif
/* StgStartup */
=====================================
rts/posix/Signals.c
=====================================
@@ -222,7 +222,7 @@ ioManagerDie (void)
void
ioManagerStartCap (Capability **cap)
{
- rts_evalIO(cap,&ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure,NULL);
+ rts_evalIO(cap,ensureIOManagerIsRunning_closure,NULL);
}
void
@@ -493,7 +493,7 @@ startSignalHandlers(Capability *cap)
RtsFlags.GcFlags.initialStkSize,
rts_apply(cap,
rts_apply(cap,
- &ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure,
+ runHandlersPtr_closure,
rts_mkPtr(cap, info)),
rts_mkInt(cap, info->si_signo)));
scheduleThread(cap, t);
=====================================
rts/rts.cabal
=====================================
@@ -334,6 +334,7 @@ library
rts/storage/InfoTables.h
rts/storage/MBlock.h
rts/storage/TSO.h
+ rts/RtsToHsIface.h
stg/MachRegs.h
stg/MachRegs/arm32.h
stg/MachRegs/arm64.h
@@ -403,6 +404,7 @@ library
adjustor/AdjustorPool.c
ExecPage.c
Arena.c
+ BuiltinClosures.c
Capability.c
CheckUnload.c
CheckVectorSupport.c
@@ -448,6 +450,7 @@ library
RtsStartup.c
RtsSymbolInfo.c
RtsSymbols.c
+ RtsToHsIface.c
RtsUtils.c
STM.c
Schedule.c
=====================================
rts/wasm/JSFFI.c
=====================================
@@ -23,8 +23,8 @@ int __main_argc_argv(int argc, char *argv[]) {
hs_init_ghc(&argc, &argv, __conf);
// See Note [threadDelay on wasm] for details.
rts_JSFFI_flag = HS_BOOL_TRUE;
- getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
- rts_threadDelay_impl = getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->raiseJSException_closure);
+ rts_threadDelay_impl = getStablePtr((StgPtr)ghc_hs_iface->threadDelay_closure);
return 0;
}
@@ -112,7 +112,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
SET_HDR(w, &stg_WEAK_info, CCS_SYSTEM);
w->cfinalizers = (StgClosure *)cfin;
w->key = p;
- w->value = Unit_closure;
+ w->value = ghc_hs_iface->Z0T_closure;
w->finalizer = &stg_NO_FINALIZER_closure;
w->link = cap->weak_ptr_list_hd;
cap->weak_ptr_list_hd = w;
@@ -123,7 +123,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
p->payload[0] = (HaskellObj)w;
HaskellObj box = (HaskellObj)allocate(cap, CONSTR_sizeW(1, 0));
- SET_HDR(box, &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info, CCS_SYSTEM);
+ SET_HDR(box, ghc_hs_iface->JSVal_con_info, CCS_SYSTEM);
box->payload[0] = p;
return TAG_CLOSURE(1, box);
@@ -139,7 +139,7 @@ STATIC_INLINE HsJSVal rts_getJSValzh(HaskellObj p) {
HsJSVal rts_getJSVal(HaskellObj);
HsJSVal rts_getJSVal(HaskellObj box) {
- ASSERT(UNTAG_CLOSURE(box)->header.info == &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info);
+ ASSERT(UNTAG_CLOSURE(box)->header.info == ghc_hs_iface->JSVal_con_info);
return rts_getJSValzh(UNTAG_CLOSURE(box)->payload[0]);
}
@@ -188,7 +188,7 @@ void rts_schedulerLoop(void) {
__attribute__((export_name("rts_promiseResolveUnit")))
void rts_promiseResolveUnit(HsStablePtr);
void rts_promiseResolveUnit(HsStablePtr sp)
- mk_rtsPromiseCallback(TAG_CLOSURE(1, Unit_closure))
+ mk_rtsPromiseCallback(TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure))
mk_rtsPromiseResolve(JSVal)
mk_rtsPromiseResolve(Char)
@@ -212,7 +212,7 @@ mk_rtsPromiseResolve(Bool)
__attribute__((export_name("rts_promiseReject")))
void rts_promiseReject(HsStablePtr, HsJSVal);
void rts_promiseReject(HsStablePtr sp, HsJSVal js_err)
- mk_rtsPromiseCallback(rts_apply(cap, &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure, rts_mkJSVal(cap, js_err)))
+ mk_rtsPromiseCallback(rts_apply(cap, ghc_hs_iface->raiseJSException_closure, rts_mkJSVal(cap, js_err)))
__attribute__((export_name("rts_promiseThrowTo")))
void rts_promiseThrowTo(HsStablePtr, HsJSVal);
@@ -229,7 +229,7 @@ void rts_promiseThrowTo(HsStablePtr sp, HsJSVal js_err) {
cap, tso,
rts_apply(
cap,
- &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure,
+ ghc_hs_iface->raiseJSException_closure,
rts_mkJSVal(cap, js_err)));
tryWakeupThread(cap, tso);
rts_schedulerLoop();
=====================================
utils/deriveConstants/Main.hs
=====================================
@@ -667,6 +667,59 @@ wanteds os = concat
,structField C "StgAsyncIOResult" "errCode"]
else []
+ -- struct HsIface
+ ,structField C "HsIface" "processRemoteCompletion_closure"
+ ,structField C "HsIface" "runIO_closure"
+ ,structField C "HsIface" "runNonIO_closure"
+ ,structField C "HsIface" "Z0T_closure"
+ ,structField C "HsIface" "True_closure"
+ ,structField C "HsIface" "False_closure"
+ ,structField C "HsIface" "unpackCString_closure"
+ ,structField C "HsIface" "runFinalizzerBatch_closure"
+ ,structField C "HsIface" "stackOverflow_closure"
+ ,structField C "HsIface" "heapOverflow_closure"
+ ,structField C "HsIface" "allocationLimitExceeded_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnMVar_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnSTM_closure"
+ ,structField C "HsIface" "cannotCompactFunction_closure"
+ ,structField C "HsIface" "cannotCompactPinned_closure"
+ ,structField C "HsIface" "cannotCompactMutable_closure"
+ ,structField C "HsIface" "nonTermination_closure"
+ ,structField C "HsIface" "nestedAtomically_closure"
+ ,structField C "HsIface" "noMatchingContinuationPrompt_closure"
+ ,structField C "HsIface" "blockedOnBadFD_closure"
+ ,structField C "HsIface" "runSparks_closure"
+ ,structField C "HsIface" "ensureIOManagerIsRunning_closure"
+ ,structField C "HsIface" "interruptIOManager_closure"
+ ,structField C "HsIface" "ioManagerCapabilitiesChanged_closure"
+ ,structField C "HsIface" "runHandlersPtr_closure"
+ ,structField C "HsIface" "flushStdHandles_closure"
+ ,structField C "HsIface" "runMainIO_closure"
+ ,structField C "HsIface" "Czh_con_info"
+ ,structField C "HsIface" "Izh_con_info"
+ ,structField C "HsIface" "Fzh_con_info"
+ ,structField C "HsIface" "Dzh_con_info"
+ ,structField C "HsIface" "Wzh_con_info"
+ ,structField C "HsIface" "runAllocationLimitHandler_closure"
+ ,structField C "HsIface" "Ptr_con_info"
+ ,structField C "HsIface" "FunPtr_con_info"
+ ,structField C "HsIface" "I8zh_con_info"
+ ,structField C "HsIface" "I16zh_con_info"
+ ,structField C "HsIface" "I32zh_con_info"
+ ,structField C "HsIface" "I64zh_con_info"
+ ,structField C "HsIface" "W8zh_con_info"
+ ,structField C "HsIface" "W16zh_con_info"
+ ,structField C "HsIface" "W32zh_con_info"
+ ,structField C "HsIface" "W64zh_con_info"
+ ,structField C "HsIface" "StablePtr_con_info"
+ ,structField C "HsIface" "StackSnapshot_closure"
+ ,structField C "HsIface" "divZZeroException_closure"
+ ,structField C "HsIface" "underflowException_closure"
+ ,structField C "HsIface" "overflowException_closure"
+ ,structField C "HsIface" "unpackCStringzh_closure"
+ ,structField C "HsIface" "unpackCStringzh_info"
+ ,structField C "HsIface" "unpackCStringUtf8zh_info"
+
-- pre-compiled thunk types
,constantWord Haskell "MAX_SPEC_SELECTEE_SIZE" "MAX_SPEC_SELECTEE_SIZE"
,constantWord Haskell "MAX_SPEC_AP_SIZE" "MAX_SPEC_AP_SIZE"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6044a10589fd5885c3bcd730fab106…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6044a10589fd5885c3bcd730fab106…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26166] 2 commits: rts: Dynamically initialize built-in closures
by Ben Gamari (@bgamari) 26 Sep '25
by Ben Gamari (@bgamari) 26 Sep '25
26 Sep '25
Ben Gamari pushed to branch wip/T26166 at Glasgow Haskell Compiler / GHC
Commits:
2c168cf3 by Ben Gamari at 2025-09-26T13:23:49-04:00
rts: Dynamically initialize built-in closures
- - - - -
6044a105 by Ben Gamari at 2025-09-26T13:23:49-04:00
rts: Avoid static symbol references to ghc-internal
- - - - -
26 changed files:
- compiler/GHC/HsToCore/Foreign/C.hs
- + libraries/ghc-internal/cbits/RtsIface.c
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/include/RtsIfaceSymbols.h
- + rts/BuiltinClosures.c
- + rts/BuiltinClosures.h
- rts/Compact.cmm
- rts/ContinuationOps.cmm
- rts/Exception.cmm
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/RtsAPI.c
- rts/RtsStartup.c
- + rts/RtsToHsIface.c
- rts/Schedule.c
- rts/StgMiscClosures.cmm
- rts/StgStdThunks.cmm
- rts/include/Rts.h
- rts/include/RtsAPI.h
- rts/include/rts/Constants.h
- + rts/include/rts/RtsToHsIface.h
- rts/include/stg/MiscClosures.h
- rts/posix/Signals.c
- rts/rts.cabal
- rts/wasm/JSFFI.c
- utils/deriveConstants/Main.hs
Changes:
=====================================
compiler/GHC/HsToCore/Foreign/C.hs
=====================================
@@ -517,8 +517,8 @@ mkFExportCBits dflags c_nm maybe_target arg_htys res_hty is_IO_res_ty cc
text "rts_apply" <> parens (
cap
<> (if is_IO_res_ty
- then text "runIO_closure"
- else text "runNonIO_closure")
+ then text "ghc_hs_iface->runIO_closure"
+ else text "ghc_hs_iface->runNonIO_closure")
<> comma
<> expr_to_run
) <+> comma
=====================================
libraries/ghc-internal/cbits/RtsIface.c
=====================================
@@ -0,0 +1,42 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+#include "Rts.h"
+
+void init_ghc_hs_iface(void) __attribute__((constructor));
+
+#define CLOSURE(module, symbol) \
+ extern StgClosure ghczminternal_##module##_##symbol;
+
+#define UNDEF_CLOSURE(module, symbol)
+
+#define INFO_TBL(module, symbol) \
+ extern StgInfoTable ghczminternal_##module##_##symbol;
+
+#include "RtsIfaceSymbols.h"
+
+#undef CLOSURE
+#undef INFO_TBL
+
+#define CLOSURE(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+#define UNDEF_CLOSURE(module, symbol) \
+ .symbol = NULL,
+
+#define INFO_TBL(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+HsIface the_ghc_hs_iface = {
+#include "RtsIfaceSymbols.h"
+};
+
+void init_ghc_hs_iface(void)
+{
+ ghc_hs_iface = &the_ghc_hs_iface;
+}
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -43,6 +43,7 @@ extra-source-files:
include/winio_structs.h
include/WordSize.h
include/HsIntegerGmp.h.in
+ include/RtsIfaceSymbols.h
install-sh
source-repository head
@@ -457,6 +458,7 @@ Library
cbits/vectorQuotRem.c
cbits/word2float.c
cbits/Stack_c.c
+ cbits/RtsIface.c
cmm-sources:
cbits/StackCloningDecoding.cmm
=====================================
libraries/ghc-internal/include/RtsIfaceSymbols.h
=====================================
@@ -0,0 +1,59 @@
+// See Note [RTS/ghc-internal interface].
+
+#if defined(mingw32_HOST_OS)
+CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#else
+UNDEF_CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#endif
+CLOSURE(GHCziInternalziTopHandler, runIO_closure)
+CLOSURE(GHCziInternalziTopHandler, runNonIO_closure)
+CLOSURE(GHCziInternalziTuple, Z0T_closure)
+CLOSURE(GHCziInternalziTypes, True_closure)
+CLOSURE(GHCziInternalziTypes, False_closure)
+CLOSURE(GHCziInternalziPack, unpackCString_closure)
+CLOSURE(GHCziInternalziWeakziFinalizze, runFinalizzerBatch_closure)
+CLOSURE(GHCziInternalziIOziException, stackOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, heapOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, allocationLimitExceeded_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnMVar_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnSTM_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactFunction_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactPinned_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactMutable_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nonTermination_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nestedAtomically_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, noMatchingContinuationPrompt_closure)
+CLOSURE(GHCziInternalziEventziThread, blockedOnBadFD_closure)
+CLOSURE(GHCziInternalziConcziSync, runSparks_closure)
+CLOSURE(GHCziInternalziConcziIO, ensureIOManagerIsRunning_closure)
+CLOSURE(GHCziInternalziConcziIO, interruptIOManager_closure)
+CLOSURE(GHCziInternalziConcziIO, ioManagerCapabilitiesChanged_closure)
+CLOSURE(GHCziInternalziConcziSignal, runHandlersPtr_closure)
+CLOSURE(GHCziInternalziTopHandler, flushStdHandles_closure)
+CLOSURE(GHCziInternalziTopHandler, runMainIO_closure)
+INFO_TBL(GHCziInternalziTypes, Czh_con_info)
+INFO_TBL(GHCziInternalziTypes, Izh_con_info)
+INFO_TBL(GHCziInternalziTypes, Fzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Dzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Wzh_con_info)
+CLOSURE(GHCziInternalziPrimziPanic, absentSumFieldError_closure)
+CLOSURE(GHCziInternalziAllocationLimitHandler, runAllocationLimitHandler_closure)
+INFO_TBL(GHCziInternalziPtr, Ptr_con_info)
+INFO_TBL(GHCziInternalziPtr, FunPtr_con_info)
+INFO_TBL(GHCziInternalziInt, I8zh_con_info)
+INFO_TBL(GHCziInternalziInt, I16zh_con_info)
+INFO_TBL(GHCziInternalziInt, I32zh_con_info)
+INFO_TBL(GHCziInternalziInt, I64zh_con_info)
+INFO_TBL(GHCziInternalziWord, W8zh_con_info)
+INFO_TBL(GHCziInternalziWord, W16zh_con_info)
+INFO_TBL(GHCziInternalziWord, W32zh_con_info)
+INFO_TBL(GHCziInternalziWord, W64zh_con_info)
+INFO_TBL(GHCziInternalziStable, StablePtr_con_info)
+CLOSURE(GHCziInternalziStackziCloneStack, StackSnapshot_closure)
+CLOSURE(GHCziInternalziExceptionziType, divZZeroException_closure)
+CLOSURE(GHCziInternalziExceptionziType, underflowException_closure)
+CLOSURE(GHCziInternalziExceptionziType, overflowException_closure)
+CLOSURE(GHCziInternalziCString, unpackCStringzh_closure)
+INFO_TBL(GHCziInternalziCString, unpackCStringzh_info)
+INFO_TBL(GHCziInternalziCString, unpackCStringUtf8zh_info)
+
=====================================
rts/BuiltinClosures.c
=====================================
@@ -0,0 +1,29 @@
+#include "Rts.h"
+#include "BuiltinClosures.h"
+
+/*
+ * Note [CHARLIKE and INTLIKE closures]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * These are static representations of Chars and small Ints, so that
+ * we can remove dynamic Chars and Ints during garbage collection and
+ * replace them with references to the static objects.
+ */
+
+StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
+StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+
+void initBuiltinClosures() {
+ // INTLIKE closures
+ for (int i = MIN_INTLIKE; i <= MAX_INTLIKE - MIN_INTLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_INTLIKE_closure[i];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Izh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = MIN_INTLIKE + i;
+ }
+
+ // CHARLIKE closures
+ for (int i = MIN_CHARLIKE; i <= MAX_CHARLIKE - MIN_CHARLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_CHARLIKE_closure[i];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Czh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = MIN_CHARLIKE + i;
+ }
+}
=====================================
rts/BuiltinClosures.h
=====================================
@@ -0,0 +1 @@
+void initBuiltinClosures(void);
=====================================
rts/Compact.cmm
=====================================
@@ -10,9 +10,6 @@
#include "Cmm.h"
#include "sm/ShouldCompact.h"
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE g0;
import CLOSURE large_alloc_lim;
@@ -124,7 +121,7 @@ eval:
SMALL_MUT_ARR_PTRS_CLEAN,
SMALL_MUT_ARR_PTRS_DIRTY,
COMPACT_NFDATA: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
+ jump stg_raisezh(HsIface_cannotCompactMutable_closure(W_[ghc_hs_iface]));
}
// We shouldn't see any functions, if this data structure was NFData.
@@ -139,7 +136,7 @@ eval:
BCO,
PAP,
CONTINUATION: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
+ jump stg_raisezh(HsIface_cannotCompactFunction_closure(W_[ghc_hs_iface]));
}
case ARR_WORDS: {
@@ -147,7 +144,7 @@ eval:
(should) = ccall shouldCompact(compact "ptr", p "ptr");
if (should == SHOULDCOMPACT_IN_CNF) { P_[pp] = p; return(); }
if (should == SHOULDCOMPACT_PINNED) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
+ jump stg_raisezh(HsIface_cannotCompactPinned_closure(W_[ghc_hs_iface]));
}
CHECK_HASH();
=====================================
rts/ContinuationOps.cmm
=====================================
@@ -12,7 +12,6 @@
#include "Cmm.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE ALLOC_RTS_ctr;
import CLOSURE ALLOC_RTS_tot;
@@ -104,7 +103,7 @@ stg_control0zh_ll // explicit stack
// see Note [When capturing the continuation fails] in Continuation.c
if (cont == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure);
+ jump stg_raisezh(HsIface_noMatchingContinuationPrompt_closure(W_[ghc_hs_iface]));
}
W_ apply_mask_frame;
=====================================
rts/Exception.cmm
=====================================
@@ -13,10 +13,6 @@
#include "Cmm.h"
#include "RaiseAsync.h"
-import CLOSURE ghczminternal_GHCziInternalziTypes_True_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_underflowException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_overflowException_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE CATCHF_PUSHED_ctr;
import CLOSURE RtsFlags;
@@ -539,7 +535,7 @@ retry_pop_stack:
Sp(10) = exception;
Sp(9) = stg_raise_ret_info;
Sp(8) = exception;
- Sp(7) = ghczminternal_GHCziInternalziTypes_True_closure; // True <=> an exception
+ Sp(7) = HsIface_True_closure(W_[ghc_hs_iface]); // True <=> an exception
Sp(6) = stg_ap_ppv_info;
Sp(5) = 0;
Sp(4) = stg_ap_n_info;
@@ -650,17 +646,17 @@ stg_raiseIOzh (P_ exception)
stg_raiseDivZZerozh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
+ jump stg_raisezh(HsIface_divZZeroException_closure(W_[ghc_hs_iface]));
}
stg_raiseUnderflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
+ jump stg_raisezh(HsIface_underflowException_closure(W_[ghc_hs_iface]));
}
stg_raiseOverflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
+ jump stg_raisezh(HsIface_overflowException_closure(W_[ghc_hs_iface]));
}
/* The FFI doesn't support variadic C functions so we can't directly expose
=====================================
rts/Prelude.h
=====================================
@@ -19,126 +19,69 @@
#define PRELUDE_CLOSURE(i) extern StgClosure (i)
#endif
-/* See Note [Wired-in exceptions are not CAFfy] in GHC.Core.Make. */
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure);
/* Define canonical names so we can abstract away from the actual
* modules these names are defined in.
*/
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTuple_Z0T_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_True_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_False_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCString_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCStringUtf8_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeak_runFinalizzerBatch_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure);
-
#if defined(IN_STG_CODE)
extern W_ ZCMain_main_closure[];
#else
extern StgClosure ZCMain_main_closure;
#endif
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSync_runSparks_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure);
-#if defined(mingw32_HOST_OS)
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure);
-#endif
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziCString_unpackCStringzh_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Czh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Izh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Fzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Dzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Wzh_con_info);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_Ptr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_FunPtr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziStable_StablePtr_con_info);
-
-#define Unit_closure (&(ghczminternal_GHCziInternalziTuple_Z0T_closure))
-#define True_closure (&(ghczminternal_GHCziInternalziTypes_True_closure))
-#define False_closure (&(ghczminternal_GHCziInternalziTypes_False_closure))
-#define unpackCString_closure (&(ghczminternal_GHCziInternalziPack_unpackCString_closure))
-#define runFinalizerBatch_closure (&(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure))
+#define Unit_closure ghc_hs_iface->Z0T_closure
+#define True_closure ghc_hs_iface->True_closure
+#define False_closure ghc_hs_iface->False_closure
+#define unpackCString_closure ghc_hs_iface->unpackCString_closure
+#define runFinalizerBatch_closure ghc_hs_iface->runFinalizzerBatch_closure
#define mainIO_closure (&ZCMain_main_closure)
-#define runSparks_closure (&(ghczminternal_GHCziInternalziConcziSync_runSparks_closure))
-#define ensureIOManagerIsRunning_closure (&(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure))
-#define interruptIOManager_closure (&(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure))
-#define ioManagerCapabilitiesChanged_closure (&(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure))
-#define runHandlersPtr_closure (&(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure))
+#define runSparks_closure ghc_hs_iface->runSparks_closure
+#define ensureIOManagerIsRunning_closure ghc_hs_iface->ensureIOManagerIsRunning_closure
+#define interruptIOManager_closure ghc_hs_iface->interruptIOManager_closure
+#define ioManagerCapabilitiesChanged_closure ghc_hs_iface->ioManagerCapabilitiesChanged_closure
+#define runHandlersPtr_closure ghc_hs_iface->runHandlersPtr_closure
#if defined(mingw32_HOST_OS)
-#define processRemoteCompletion_closure (&(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure))
+#define processRemoteCompletion_closure ghc_hs_iface->processRemoteCompletion_closure
#endif
-#define runAllocationLimitHandler_closure (&(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure))
-
-#define flushStdHandles_closure (&(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure))
-#define runMainIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure))
-
-#define stackOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure))
-#define heapOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure))
-#define allocationLimitExceeded_closure (&(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure))
-#define blockedIndefinitelyOnMVar_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure))
-#define blockedIndefinitelyOnSTM_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure))
-#define cannotCompactFunction_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure))
-#define cannotCompactPinned_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure))
-#define cannotCompactMutable_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure))
-#define nonTermination_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure))
-#define nestedAtomically_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure))
-#define absentSumFieldError_closure (&(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure))
-#define underflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure))
-#define overflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure))
-#define divZeroException_closure (&(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure))
-
-#define blockedOnBadFD_closure (&(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure))
-
-#define Czh_con_info (&(ghczminternal_GHCziInternalziTypes_Czh_con_info))
-#define Izh_con_info (&(ghczminternal_GHCziInternalziTypes_Izh_con_info))
-#define Fzh_con_info (&(ghczminternal_GHCziInternalziTypes_Fzh_con_info))
-#define Dzh_con_info (&(ghczminternal_GHCziInternalziTypes_Dzh_con_info))
-#define Wzh_con_info (&(ghczminternal_GHCziInternalziTypes_Wzh_con_info))
-#define W8zh_con_info (&(ghczminternal_GHCziInternalziWord_W8zh_con_info))
-#define W16zh_con_info (&(ghczminternal_GHCziInternalziWord_W16zh_con_info))
-#define W32zh_con_info (&(ghczminternal_GHCziInternalziWord_W32zh_con_info))
-#define W64zh_con_info (&(ghczminternal_GHCziInternalziWord_W64zh_con_info))
-#define I8zh_con_info (&(ghczminternal_GHCziInternalziInt_I8zh_con_info))
-#define I16zh_con_info (&(ghczminternal_GHCziInternalziInt_I16zh_con_info))
-#define I32zh_con_info (&(ghczminternal_GHCziInternalziInt_I32zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define Ptr_con_info (&(ghczminternal_GHCziInternalziPtr_Ptr_con_info))
-#define FunPtr_con_info (&(ghczminternal_GHCziInternalziPtr_FunPtr_con_info))
-#define StablePtr_static_info (&(ghczminternal_GHCziInternalziStable_StablePtr_static_info))
-#define StablePtr_con_info (&(ghczminternal_GHCziInternalziStable_StablePtr_con_info))
+#define runAllocationLimitHandler_closure ghc_hs_iface->runAllocationLimitHandler_closure
+
+#define flushStdHandles_closure ghc_hs_iface->flushStdHandles_closure
+#define runMainIO_closure ghc_hs_iface->runMainIO_closure
+
+#define stackOverflow_closure ghc_hs_iface->stackOverflow_closure
+#define heapOverflow_closure ghc_hs_iface->heapOverflow_closure
+#define allocationLimitExceeded_closure ghc_hs_iface->allocationLimitExceeded_closure
+#define blockedIndefinitelyOnMVar_closure ghc_hs_iface->blockedIndefinitelyOnMVar_closure
+#define blockedIndefinitelyOnSTM_closure ghc_hs_iface->blockedIndefinitelyOnSTM_closure
+#define cannotCompactFunction_closure ghc_hs_iface->cannotCompactFunction_closure
+#define cannotCompactPinned_closure ghc_hs_iface->cannotCompactPinned_closure
+#define cannotCompactMutable_closure ghc_hs_iface->cannotCompactMutable_closure
+#define nonTermination_closure ghc_hs_iface->nonTermination_closure
+#define nestedAtomically_closure ghc_hs_iface->nestedAtomically_closure
+#define absentSumFieldError_closure ghc_hs_iface->absentSumFieldError_closure
+#define underflowException_closure ghc_hs_iface->underflowException_closure
+#define overflowException_closure ghc_hs_iface->overflowException_closure
+#define divZeroException_closure ghc_hs_iface->divZZeroException_closure
+
+#define blockedOnBadFD_closure ghc_hs_iface->blockedOnBadFD_closure
+
+#define Czh_con_info ghc_hs_iface->Czh_con_info
+#define Izh_con_info ghc_hs_iface->Izh_con_info
+#define Fzh_con_info ghc_hs_iface->Fzh_con_info
+#define Dzh_con_info ghc_hs_iface->Dzh_con_info
+#define Wzh_con_info ghc_hs_iface->Wzh_con_info
+#define W8zh_con_info ghc_hs_iface->W8zh_con_info
+#define W16zh_con_info ghc_hs_iface->W16zh_con_info
+#define W32zh_con_info ghc_hs_iface->W32zh_con_info
+#define W64zh_con_info ghc_hs_iface->W64zh_con_info
+#define I8zh_con_info ghc_hs_iface->I8zh_con_info
+#define I16zh_con_info ghc_hs_iface->I16zh_con_info
+#define I32zh_con_info ghc_hs_iface->I32zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define Ptr_con_info ghc_hs_iface->Ptr_con_info
+#define FunPtr_con_info ghc_hs_iface->FunPtr_con_info
+#define StablePtr_static_info ghc_hs_iface->StablePtr_static_info
+#define StablePtr_con_info ghc_hs_iface->StablePtr_con_info
=====================================
rts/PrimOps.cmm
=====================================
@@ -25,12 +25,8 @@
#include "MachDeps.h"
#include "SMPClosureOps.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_heapOverflow_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
-import CLOSURE ghczminternal_GHCziInternalziTypes_False_closure;
#if defined(PROFILING)
import CLOSURE CCS_MAIN;
#endif
@@ -118,7 +114,7 @@ stg_newByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytes(MyCapability() "ptr", n, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -135,7 +131,7 @@ stg_newPinnedByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
BA_ALIGN, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -149,7 +145,7 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
alignment, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -364,7 +360,7 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -474,7 +470,7 @@ stg_newSmallArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateSmallMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -1090,7 +1086,7 @@ stg_listThreadszh ()
("ptr" arr) = ccall listThreads(MyCapability() "ptr");
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (arr);
@@ -1360,7 +1356,7 @@ stg_atomicallyzh (P_ stm)
/* Nested transactions are not allowed; raise an exception */
if (old_trec != NO_TREC) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
+ jump stg_raisezh(HsIface_nestedAtomically_closure(W_[ghc_hs_iface]));
}
code = stm;
@@ -2231,7 +2227,7 @@ stg_unpackClosurezh ( P_ closure )
dat_arr_sz = SIZEOF_StgArrBytes + WDS(len);
("ptr" dat_arr) = ccall allocateMightFail(MyCapability() "ptr", BYTES_TO_WDS(dat_arr_sz));
if (dat_arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
TICK_ALLOC_PRIM(SIZEOF_StgArrBytes, WDS(len), 0);
@@ -2251,7 +2247,7 @@ for:
("ptr" ptrArray) = foreign "C" heap_view_closurePtrs(MyCapability() "ptr", clos "ptr");
if (ptrArray == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (info, dat_arr, ptrArray);
@@ -2518,13 +2514,13 @@ stg_getSparkzh ()
W_ spark;
#if !defined(THREADED_RTS)
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
#else
("ptr" spark) = ccall findSpark(MyCapability() "ptr");
if (spark != 0) {
return (1,spark);
} else {
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
}
#endif
}
=====================================
rts/RtsAPI.c
=====================================
@@ -509,7 +509,7 @@ void rts_evalStableIOMain(/* inout */ Capability **cap,
SchedulerStatus stat;
p = (StgClosure *)deRefStablePtr(s);
- w = rts_apply(*cap, &ghczminternal_GHCziInternalziTopHandler_runMainIO_closure, p);
+ w = rts_apply(*cap, runMainIO_closure, p);
tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, w);
// async exceptions are always blocked by default in the created
// thread. See #1048.
@@ -961,7 +961,7 @@ void rts_done (void)
void hs_try_putmvar (/* in */ int capability,
/* in */ HsStablePtr mvar)
{
- hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, Unit_closure));
+ hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure));
}
void hs_try_putmvar_with_value (/* in */ int capability,
=====================================
rts/RtsStartup.c
=====================================
@@ -14,6 +14,7 @@
#include "linker/MMap.h"
#include "RtsFlags.h"
#include "RtsUtils.h"
+#include "BuiltinClosures.h"
#include "Prelude.h"
#include "Printer.h" /* DEBUG_LoadSymbols */
#include "Schedule.h" /* initScheduler */
@@ -182,8 +183,8 @@ static void initBuiltinGcRoots(void)
* these closures `Id`s of these can be safely marked as non-CAFFY
* in the compiler.
*/
- getStablePtr((StgPtr)runIO_closure);
- getStablePtr((StgPtr)runNonIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runNonIO_closure);
getStablePtr((StgPtr)flushStdHandles_closure);
getStablePtr((StgPtr)runFinalizerBatch_closure);
@@ -262,6 +263,14 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
setlocale(LC_CTYPE,"");
+ if (ghc_hs_iface == NULL) {
+ errorBelch("hs_init_ghc: ghc_hs_iface is uninitialized");
+ stg_exit(1);
+ }
+
+
+ initBuiltinClosures();
+
/* Initialise the stats department, phase 0 */
initStats0();
=====================================
rts/RtsToHsIface.c
=====================================
@@ -0,0 +1,45 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ *
+ * Note [RTS/ghc-internal interface]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The runtime system depends upon a variety of symbols defined by Haskell
+ * modules living in `ghc-internal`. To avoid cyclic dependencies between
+ * ghc-internal and the RTS, these symbols are referenced indirectly via the
+ * the `HsIface` structure (specifically `ghc_hs_iface`):
+ *
+ * struct HsIface {
+ * StgClosure *runIO; // GHC.Internal.TopHandler.runIO
+ * StgClosure *Z0T; // GHC.Internal.Tuple.()
+ * // etc.
+ * };
+ *
+ * `ghc_hs_iface` is initialized during program loading via the
+ * `init_ghc_hs_iface` constructor in `ghc-interface`
+ *
+ * const struct HsIface the_hs_iface = {
+ * .runIO = &ghczminternal_GHCziInternalziTopHandler_runIO_closure,
+ * .Z0T = &ghczminternal_GHCziInternalziTuple_Z0T_closure,
+ * // etc.
+ * };
+ *
+ * void __attribute__((constructor)) init_ghc_hs_iface() {
+ * ghc_hs_iface = &the_hs_iface;
+ * }
+ *
+ * This effectively breaks the RTS's link-time dependency, replacing it with a
+ * run-time dependency at the cost of an indirection. It also has the pleasant
+ * side-effect of making the interface between the RTS and `ghc-internal`
+ * explicit.
+ *
+ */
+
+#include "Rts.h"
+
+// This captures the symbols provided by ghc-internal which
+// are needed by the RTS.
+const HsIface *ghc_hs_iface = NULL;
=====================================
rts/Schedule.c
=====================================
@@ -1053,7 +1053,7 @@ scheduleProcessInbox (Capability **pcap USED_IF_THREADS)
while (p != NULL) {
pnext = p->link;
performTryPutMVar(cap, (StgMVar*)deRefStablePtr(p->mvar),
- Unit_closure);
+ ghc_hs_iface->Z0T_closure);
freeStablePtr(p->mvar);
stgFree(p);
p = pnext;
=====================================
rts/StgMiscClosures.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
import pthread_mutex_lock;
-import ghczminternal_GHCziInternalziTypes_Czh_info;
-import ghczminternal_GHCziInternalziTypes_Izh_info;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
@@ -23,7 +21,6 @@ import whitehole_lockClosure_spin;
import whitehole_lockClosure_yield;
#endif
-
#if !defined(UnregisterisedCompiler)
import CLOSURE CCS_SYSTEM;
import CLOSURE ENT_DYN_IND_ctr;
@@ -1031,554 +1028,3 @@ INFO_TABLE_CONSTR(stg_ASYNCIO_LIVE0,0,0,0,CONSTR_NOCAF,"ASYNCIO_LIVE0","ASYNCIO_
{ foreign "C" barf("ASYNCIO_LIVE0 object (%p) entered!", R1) never returns; }
CLOSURE(stg_ASYNCIO_LIVE0_closure,stg_ASYNCIO_LIVE0);
-
-/* ----------------------------------------------------------------------------
- Note [CHARLIKE and INTLIKE closures]
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- These are static representations of Chars and small Ints, so that
- we can remove dynamic Chars and Ints during garbage collection and
- replace them with references to the static objects.
- ------------------------------------------------------------------------- */
-
-#define Char_hash_con_info ghczminternal_GHCziInternalziTypes_Czh_con_info
-#define Int_hash_con_info ghczminternal_GHCziInternalziTypes_Izh_con_info
-
-#define CHARLIKE_HDR(n) CLOSURE(Char_hash_con_info, n)
-#define INTLIKE_HDR(n) CLOSURE(Int_hash_con_info, n)
-
-section "data" {
- stg_CHARLIKE_closure:
- CHARLIKE_HDR(0)
- CHARLIKE_HDR(1)
- CHARLIKE_HDR(2)
- CHARLIKE_HDR(3)
- CHARLIKE_HDR(4)
- CHARLIKE_HDR(5)
- CHARLIKE_HDR(6)
- CHARLIKE_HDR(7)
- CHARLIKE_HDR(8)
- CHARLIKE_HDR(9)
- CHARLIKE_HDR(10)
- CHARLIKE_HDR(11)
- CHARLIKE_HDR(12)
- CHARLIKE_HDR(13)
- CHARLIKE_HDR(14)
- CHARLIKE_HDR(15)
- CHARLIKE_HDR(16)
- CHARLIKE_HDR(17)
- CHARLIKE_HDR(18)
- CHARLIKE_HDR(19)
- CHARLIKE_HDR(20)
- CHARLIKE_HDR(21)
- CHARLIKE_HDR(22)
- CHARLIKE_HDR(23)
- CHARLIKE_HDR(24)
- CHARLIKE_HDR(25)
- CHARLIKE_HDR(26)
- CHARLIKE_HDR(27)
- CHARLIKE_HDR(28)
- CHARLIKE_HDR(29)
- CHARLIKE_HDR(30)
- CHARLIKE_HDR(31)
- CHARLIKE_HDR(32)
- CHARLIKE_HDR(33)
- CHARLIKE_HDR(34)
- CHARLIKE_HDR(35)
- CHARLIKE_HDR(36)
- CHARLIKE_HDR(37)
- CHARLIKE_HDR(38)
- CHARLIKE_HDR(39)
- CHARLIKE_HDR(40)
- CHARLIKE_HDR(41)
- CHARLIKE_HDR(42)
- CHARLIKE_HDR(43)
- CHARLIKE_HDR(44)
- CHARLIKE_HDR(45)
- CHARLIKE_HDR(46)
- CHARLIKE_HDR(47)
- CHARLIKE_HDR(48)
- CHARLIKE_HDR(49)
- CHARLIKE_HDR(50)
- CHARLIKE_HDR(51)
- CHARLIKE_HDR(52)
- CHARLIKE_HDR(53)
- CHARLIKE_HDR(54)
- CHARLIKE_HDR(55)
- CHARLIKE_HDR(56)
- CHARLIKE_HDR(57)
- CHARLIKE_HDR(58)
- CHARLIKE_HDR(59)
- CHARLIKE_HDR(60)
- CHARLIKE_HDR(61)
- CHARLIKE_HDR(62)
- CHARLIKE_HDR(63)
- CHARLIKE_HDR(64)
- CHARLIKE_HDR(65)
- CHARLIKE_HDR(66)
- CHARLIKE_HDR(67)
- CHARLIKE_HDR(68)
- CHARLIKE_HDR(69)
- CHARLIKE_HDR(70)
- CHARLIKE_HDR(71)
- CHARLIKE_HDR(72)
- CHARLIKE_HDR(73)
- CHARLIKE_HDR(74)
- CHARLIKE_HDR(75)
- CHARLIKE_HDR(76)
- CHARLIKE_HDR(77)
- CHARLIKE_HDR(78)
- CHARLIKE_HDR(79)
- CHARLIKE_HDR(80)
- CHARLIKE_HDR(81)
- CHARLIKE_HDR(82)
- CHARLIKE_HDR(83)
- CHARLIKE_HDR(84)
- CHARLIKE_HDR(85)
- CHARLIKE_HDR(86)
- CHARLIKE_HDR(87)
- CHARLIKE_HDR(88)
- CHARLIKE_HDR(89)
- CHARLIKE_HDR(90)
- CHARLIKE_HDR(91)
- CHARLIKE_HDR(92)
- CHARLIKE_HDR(93)
- CHARLIKE_HDR(94)
- CHARLIKE_HDR(95)
- CHARLIKE_HDR(96)
- CHARLIKE_HDR(97)
- CHARLIKE_HDR(98)
- CHARLIKE_HDR(99)
- CHARLIKE_HDR(100)
- CHARLIKE_HDR(101)
- CHARLIKE_HDR(102)
- CHARLIKE_HDR(103)
- CHARLIKE_HDR(104)
- CHARLIKE_HDR(105)
- CHARLIKE_HDR(106)
- CHARLIKE_HDR(107)
- CHARLIKE_HDR(108)
- CHARLIKE_HDR(109)
- CHARLIKE_HDR(110)
- CHARLIKE_HDR(111)
- CHARLIKE_HDR(112)
- CHARLIKE_HDR(113)
- CHARLIKE_HDR(114)
- CHARLIKE_HDR(115)
- CHARLIKE_HDR(116)
- CHARLIKE_HDR(117)
- CHARLIKE_HDR(118)
- CHARLIKE_HDR(119)
- CHARLIKE_HDR(120)
- CHARLIKE_HDR(121)
- CHARLIKE_HDR(122)
- CHARLIKE_HDR(123)
- CHARLIKE_HDR(124)
- CHARLIKE_HDR(125)
- CHARLIKE_HDR(126)
- CHARLIKE_HDR(127)
- CHARLIKE_HDR(128)
- CHARLIKE_HDR(129)
- CHARLIKE_HDR(130)
- CHARLIKE_HDR(131)
- CHARLIKE_HDR(132)
- CHARLIKE_HDR(133)
- CHARLIKE_HDR(134)
- CHARLIKE_HDR(135)
- CHARLIKE_HDR(136)
- CHARLIKE_HDR(137)
- CHARLIKE_HDR(138)
- CHARLIKE_HDR(139)
- CHARLIKE_HDR(140)
- CHARLIKE_HDR(141)
- CHARLIKE_HDR(142)
- CHARLIKE_HDR(143)
- CHARLIKE_HDR(144)
- CHARLIKE_HDR(145)
- CHARLIKE_HDR(146)
- CHARLIKE_HDR(147)
- CHARLIKE_HDR(148)
- CHARLIKE_HDR(149)
- CHARLIKE_HDR(150)
- CHARLIKE_HDR(151)
- CHARLIKE_HDR(152)
- CHARLIKE_HDR(153)
- CHARLIKE_HDR(154)
- CHARLIKE_HDR(155)
- CHARLIKE_HDR(156)
- CHARLIKE_HDR(157)
- CHARLIKE_HDR(158)
- CHARLIKE_HDR(159)
- CHARLIKE_HDR(160)
- CHARLIKE_HDR(161)
- CHARLIKE_HDR(162)
- CHARLIKE_HDR(163)
- CHARLIKE_HDR(164)
- CHARLIKE_HDR(165)
- CHARLIKE_HDR(166)
- CHARLIKE_HDR(167)
- CHARLIKE_HDR(168)
- CHARLIKE_HDR(169)
- CHARLIKE_HDR(170)
- CHARLIKE_HDR(171)
- CHARLIKE_HDR(172)
- CHARLIKE_HDR(173)
- CHARLIKE_HDR(174)
- CHARLIKE_HDR(175)
- CHARLIKE_HDR(176)
- CHARLIKE_HDR(177)
- CHARLIKE_HDR(178)
- CHARLIKE_HDR(179)
- CHARLIKE_HDR(180)
- CHARLIKE_HDR(181)
- CHARLIKE_HDR(182)
- CHARLIKE_HDR(183)
- CHARLIKE_HDR(184)
- CHARLIKE_HDR(185)
- CHARLIKE_HDR(186)
- CHARLIKE_HDR(187)
- CHARLIKE_HDR(188)
- CHARLIKE_HDR(189)
- CHARLIKE_HDR(190)
- CHARLIKE_HDR(191)
- CHARLIKE_HDR(192)
- CHARLIKE_HDR(193)
- CHARLIKE_HDR(194)
- CHARLIKE_HDR(195)
- CHARLIKE_HDR(196)
- CHARLIKE_HDR(197)
- CHARLIKE_HDR(198)
- CHARLIKE_HDR(199)
- CHARLIKE_HDR(200)
- CHARLIKE_HDR(201)
- CHARLIKE_HDR(202)
- CHARLIKE_HDR(203)
- CHARLIKE_HDR(204)
- CHARLIKE_HDR(205)
- CHARLIKE_HDR(206)
- CHARLIKE_HDR(207)
- CHARLIKE_HDR(208)
- CHARLIKE_HDR(209)
- CHARLIKE_HDR(210)
- CHARLIKE_HDR(211)
- CHARLIKE_HDR(212)
- CHARLIKE_HDR(213)
- CHARLIKE_HDR(214)
- CHARLIKE_HDR(215)
- CHARLIKE_HDR(216)
- CHARLIKE_HDR(217)
- CHARLIKE_HDR(218)
- CHARLIKE_HDR(219)
- CHARLIKE_HDR(220)
- CHARLIKE_HDR(221)
- CHARLIKE_HDR(222)
- CHARLIKE_HDR(223)
- CHARLIKE_HDR(224)
- CHARLIKE_HDR(225)
- CHARLIKE_HDR(226)
- CHARLIKE_HDR(227)
- CHARLIKE_HDR(228)
- CHARLIKE_HDR(229)
- CHARLIKE_HDR(230)
- CHARLIKE_HDR(231)
- CHARLIKE_HDR(232)
- CHARLIKE_HDR(233)
- CHARLIKE_HDR(234)
- CHARLIKE_HDR(235)
- CHARLIKE_HDR(236)
- CHARLIKE_HDR(237)
- CHARLIKE_HDR(238)
- CHARLIKE_HDR(239)
- CHARLIKE_HDR(240)
- CHARLIKE_HDR(241)
- CHARLIKE_HDR(242)
- CHARLIKE_HDR(243)
- CHARLIKE_HDR(244)
- CHARLIKE_HDR(245)
- CHARLIKE_HDR(246)
- CHARLIKE_HDR(247)
- CHARLIKE_HDR(248)
- CHARLIKE_HDR(249)
- CHARLIKE_HDR(250)
- CHARLIKE_HDR(251)
- CHARLIKE_HDR(252)
- CHARLIKE_HDR(253)
- CHARLIKE_HDR(254)
- CHARLIKE_HDR(255)
-}
-
-section "data" {
- stg_INTLIKE_closure:
- INTLIKE_HDR(-16) /* MIN_INTLIKE == -16 */
- INTLIKE_HDR(-15)
- INTLIKE_HDR(-14)
- INTLIKE_HDR(-13)
- INTLIKE_HDR(-12)
- INTLIKE_HDR(-11)
- INTLIKE_HDR(-10)
- INTLIKE_HDR(-9)
- INTLIKE_HDR(-8)
- INTLIKE_HDR(-7)
- INTLIKE_HDR(-6)
- INTLIKE_HDR(-5)
- INTLIKE_HDR(-4)
- INTLIKE_HDR(-3)
- INTLIKE_HDR(-2)
- INTLIKE_HDR(-1)
- INTLIKE_HDR(0)
- INTLIKE_HDR(1)
- INTLIKE_HDR(2)
- INTLIKE_HDR(3)
- INTLIKE_HDR(4)
- INTLIKE_HDR(5)
- INTLIKE_HDR(6)
- INTLIKE_HDR(7)
- INTLIKE_HDR(8)
- INTLIKE_HDR(9)
- INTLIKE_HDR(10)
- INTLIKE_HDR(11)
- INTLIKE_HDR(12)
- INTLIKE_HDR(13)
- INTLIKE_HDR(14)
- INTLIKE_HDR(15)
- INTLIKE_HDR(16)
- INTLIKE_HDR(17)
- INTLIKE_HDR(18)
- INTLIKE_HDR(19)
- INTLIKE_HDR(20)
- INTLIKE_HDR(21)
- INTLIKE_HDR(22)
- INTLIKE_HDR(23)
- INTLIKE_HDR(24)
- INTLIKE_HDR(25)
- INTLIKE_HDR(26)
- INTLIKE_HDR(27)
- INTLIKE_HDR(28)
- INTLIKE_HDR(29)
- INTLIKE_HDR(30)
- INTLIKE_HDR(31)
- INTLIKE_HDR(32)
- INTLIKE_HDR(33)
- INTLIKE_HDR(34)
- INTLIKE_HDR(35)
- INTLIKE_HDR(36)
- INTLIKE_HDR(37)
- INTLIKE_HDR(38)
- INTLIKE_HDR(39)
- INTLIKE_HDR(40)
- INTLIKE_HDR(41)
- INTLIKE_HDR(42)
- INTLIKE_HDR(43)
- INTLIKE_HDR(44)
- INTLIKE_HDR(45)
- INTLIKE_HDR(46)
- INTLIKE_HDR(47)
- INTLIKE_HDR(48)
- INTLIKE_HDR(49)
- INTLIKE_HDR(50)
- INTLIKE_HDR(51)
- INTLIKE_HDR(52)
- INTLIKE_HDR(53)
- INTLIKE_HDR(54)
- INTLIKE_HDR(55)
- INTLIKE_HDR(56)
- INTLIKE_HDR(57)
- INTLIKE_HDR(58)
- INTLIKE_HDR(59)
- INTLIKE_HDR(60)
- INTLIKE_HDR(61)
- INTLIKE_HDR(62)
- INTLIKE_HDR(63)
- INTLIKE_HDR(64)
- INTLIKE_HDR(65)
- INTLIKE_HDR(66)
- INTLIKE_HDR(67)
- INTLIKE_HDR(68)
- INTLIKE_HDR(69)
- INTLIKE_HDR(70)
- INTLIKE_HDR(71)
- INTLIKE_HDR(72)
- INTLIKE_HDR(73)
- INTLIKE_HDR(74)
- INTLIKE_HDR(75)
- INTLIKE_HDR(76)
- INTLIKE_HDR(77)
- INTLIKE_HDR(78)
- INTLIKE_HDR(79)
- INTLIKE_HDR(80)
- INTLIKE_HDR(81)
- INTLIKE_HDR(82)
- INTLIKE_HDR(83)
- INTLIKE_HDR(84)
- INTLIKE_HDR(85)
- INTLIKE_HDR(86)
- INTLIKE_HDR(87)
- INTLIKE_HDR(88)
- INTLIKE_HDR(89)
- INTLIKE_HDR(90)
- INTLIKE_HDR(91)
- INTLIKE_HDR(92)
- INTLIKE_HDR(93)
- INTLIKE_HDR(94)
- INTLIKE_HDR(95)
- INTLIKE_HDR(96)
- INTLIKE_HDR(97)
- INTLIKE_HDR(98)
- INTLIKE_HDR(99)
- INTLIKE_HDR(100)
- INTLIKE_HDR(101)
- INTLIKE_HDR(102)
- INTLIKE_HDR(103)
- INTLIKE_HDR(104)
- INTLIKE_HDR(105)
- INTLIKE_HDR(106)
- INTLIKE_HDR(107)
- INTLIKE_HDR(108)
- INTLIKE_HDR(109)
- INTLIKE_HDR(110)
- INTLIKE_HDR(111)
- INTLIKE_HDR(112)
- INTLIKE_HDR(113)
- INTLIKE_HDR(114)
- INTLIKE_HDR(115)
- INTLIKE_HDR(116)
- INTLIKE_HDR(117)
- INTLIKE_HDR(118)
- INTLIKE_HDR(119)
- INTLIKE_HDR(120)
- INTLIKE_HDR(121)
- INTLIKE_HDR(122)
- INTLIKE_HDR(123)
- INTLIKE_HDR(124)
- INTLIKE_HDR(125)
- INTLIKE_HDR(126)
- INTLIKE_HDR(127)
- INTLIKE_HDR(128)
- INTLIKE_HDR(129)
- INTLIKE_HDR(130)
- INTLIKE_HDR(131)
- INTLIKE_HDR(132)
- INTLIKE_HDR(133)
- INTLIKE_HDR(134)
- INTLIKE_HDR(135)
- INTLIKE_HDR(136)
- INTLIKE_HDR(137)
- INTLIKE_HDR(138)
- INTLIKE_HDR(139)
- INTLIKE_HDR(140)
- INTLIKE_HDR(141)
- INTLIKE_HDR(142)
- INTLIKE_HDR(143)
- INTLIKE_HDR(144)
- INTLIKE_HDR(145)
- INTLIKE_HDR(146)
- INTLIKE_HDR(147)
- INTLIKE_HDR(148)
- INTLIKE_HDR(149)
- INTLIKE_HDR(150)
- INTLIKE_HDR(151)
- INTLIKE_HDR(152)
- INTLIKE_HDR(153)
- INTLIKE_HDR(154)
- INTLIKE_HDR(155)
- INTLIKE_HDR(156)
- INTLIKE_HDR(157)
- INTLIKE_HDR(158)
- INTLIKE_HDR(159)
- INTLIKE_HDR(160)
- INTLIKE_HDR(161)
- INTLIKE_HDR(162)
- INTLIKE_HDR(163)
- INTLIKE_HDR(164)
- INTLIKE_HDR(165)
- INTLIKE_HDR(166)
- INTLIKE_HDR(167)
- INTLIKE_HDR(168)
- INTLIKE_HDR(169)
- INTLIKE_HDR(170)
- INTLIKE_HDR(171)
- INTLIKE_HDR(172)
- INTLIKE_HDR(173)
- INTLIKE_HDR(174)
- INTLIKE_HDR(175)
- INTLIKE_HDR(176)
- INTLIKE_HDR(177)
- INTLIKE_HDR(178)
- INTLIKE_HDR(179)
- INTLIKE_HDR(180)
- INTLIKE_HDR(181)
- INTLIKE_HDR(182)
- INTLIKE_HDR(183)
- INTLIKE_HDR(184)
- INTLIKE_HDR(185)
- INTLIKE_HDR(186)
- INTLIKE_HDR(187)
- INTLIKE_HDR(188)
- INTLIKE_HDR(189)
- INTLIKE_HDR(190)
- INTLIKE_HDR(191)
- INTLIKE_HDR(192)
- INTLIKE_HDR(193)
- INTLIKE_HDR(194)
- INTLIKE_HDR(195)
- INTLIKE_HDR(196)
- INTLIKE_HDR(197)
- INTLIKE_HDR(198)
- INTLIKE_HDR(199)
- INTLIKE_HDR(200)
- INTLIKE_HDR(201)
- INTLIKE_HDR(202)
- INTLIKE_HDR(203)
- INTLIKE_HDR(204)
- INTLIKE_HDR(205)
- INTLIKE_HDR(206)
- INTLIKE_HDR(207)
- INTLIKE_HDR(208)
- INTLIKE_HDR(209)
- INTLIKE_HDR(210)
- INTLIKE_HDR(211)
- INTLIKE_HDR(212)
- INTLIKE_HDR(213)
- INTLIKE_HDR(214)
- INTLIKE_HDR(215)
- INTLIKE_HDR(216)
- INTLIKE_HDR(217)
- INTLIKE_HDR(218)
- INTLIKE_HDR(219)
- INTLIKE_HDR(220)
- INTLIKE_HDR(221)
- INTLIKE_HDR(222)
- INTLIKE_HDR(223)
- INTLIKE_HDR(224)
- INTLIKE_HDR(225)
- INTLIKE_HDR(226)
- INTLIKE_HDR(227)
- INTLIKE_HDR(228)
- INTLIKE_HDR(229)
- INTLIKE_HDR(230)
- INTLIKE_HDR(231)
- INTLIKE_HDR(232)
- INTLIKE_HDR(233)
- INTLIKE_HDR(234)
- INTLIKE_HDR(235)
- INTLIKE_HDR(236)
- INTLIKE_HDR(237)
- INTLIKE_HDR(238)
- INTLIKE_HDR(239)
- INTLIKE_HDR(240)
- INTLIKE_HDR(241)
- INTLIKE_HDR(242)
- INTLIKE_HDR(243)
- INTLIKE_HDR(244)
- INTLIKE_HDR(245)
- INTLIKE_HDR(246)
- INTLIKE_HDR(247)
- INTLIKE_HDR(248)
- INTLIKE_HDR(249)
- INTLIKE_HDR(250)
- INTLIKE_HDR(251)
- INTLIKE_HDR(252)
- INTLIKE_HDR(253)
- INTLIKE_HDR(254)
- INTLIKE_HDR(255) /* MAX_INTLIKE == 255
- See #16961 for why 255 */
-}
=====================================
rts/StgStdThunks.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
#include "Updates.h"
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringzh_info;
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info;
#if !defined(UnregisterisedCompiler)
import CLOSURE STK_CHK_ctr;
import CLOSURE stg_bh_upd_frame_info;
@@ -348,7 +346,7 @@ stg_do_unpack_cstring(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringzh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringzh_info(W_[ghc_hs_iface]))(node, str);
}
}
@@ -372,7 +370,7 @@ stg_do_unpack_cstring_utf8(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringUtf8zh_info(W_[ghc_hs_iface]))(node, str);
}
}
=====================================
rts/include/Rts.h
=====================================
@@ -229,6 +229,7 @@ void _warnFail(const char *filename, unsigned int linenum);
#include "rts/storage/ClosureTypes.h"
#include "rts/storage/TSO.h"
#include "stg/MiscClosures.h" /* InfoTables, closures etc. defined in the RTS */
+
#include "rts/storage/Block.h"
#include "rts/storage/ClosureMacros.h"
#include "rts/storage/MBlock.h"
=====================================
rts/include/RtsAPI.h
=====================================
@@ -18,6 +18,7 @@ extern "C" {
#include "HsFFI.h"
#include "rts/Time.h"
#include "rts/Types.h"
+#include "rts/RtsToHsIface.h"
/*
* Running the scheduler
@@ -584,11 +585,6 @@ void rts_done (void);
// Note that RtsAPI.h is also included by foreign export stubs in
// the base package itself.
//
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runIO_closure;
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runNonIO_closure;
-
-#define runIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runIO_closure))
-#define runNonIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runNonIO_closure))
/* ------------------------------------------------------------------------ */
=====================================
rts/include/rts/Constants.h
=====================================
@@ -57,11 +57,12 @@
#define MAX_SPEC_CONSTR_SIZE 2
/* Range of built-in table of static small int-like and char-like closures.
+ * Range is inclusive of both minimum and maximum.
*
* NB. This corresponds with the number of actual INTLIKE/CHARLIKE
* closures defined in rts/StgMiscClosures.cmm.
*/
-#define MAX_INTLIKE 255
+#define MAX_INTLIKE 255 /* See #16961 for why 255 */
#define MIN_INTLIKE (-16)
#define MAX_CHARLIKE 255
=====================================
rts/include/rts/RtsToHsIface.h
=====================================
@@ -0,0 +1,64 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+typedef struct {
+ StgClosure *processRemoteCompletion_closure; // GHC.Internal.Event.Windows.processRemoteCompletion_closure
+ StgClosure *runIO_closure; // GHC.Internal.TopHandler.runIO_closure
+ StgClosure *runNonIO_closure; // GHC.Internal.TopHandler.runNonIO_closure
+ StgClosure *Z0T_closure; // GHC.Internal.Tuple.Z0T_closure
+ StgClosure *True_closure; // GHC.Internal.Types.True_closure
+ StgClosure *False_closure; // GHC.Internal.Types.False_closure
+ StgClosure *unpackCString_closure; // GHC.Internal.Pack.unpackCString_closure
+ StgClosure *runFinalizzerBatch_closure; // GHC.Internal.Weak.Finalizze.runFinalizzerBatch_closure
+ StgClosure *stackOverflow_closure; // GHC.Internal.IO.Exception.stackOverflow_closure
+ StgClosure *heapOverflow_closure; // GHC.Internal.IO.Exception.heapOverflow_closure
+ StgClosure *allocationLimitExceeded_closure; // GHC.Internal.IO.Exception.allocationLimitExceeded_closure
+ StgClosure *blockedIndefinitelyOnMVar_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnMVar_closure
+ StgClosure *blockedIndefinitelyOnSTM_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnSTM_closure
+ StgClosure *cannotCompactFunction_closure; // GHC.Internal.IO.Exception.cannotCompactFunction_closure
+ StgClosure *cannotCompactPinned_closure; // GHC.Internal.IO.Exception.cannotCompactPinned_closure
+ StgClosure *cannotCompactMutable_closure; // GHC.Internal.IO.Exception.cannotCompactMutable_closure
+ StgClosure *nonTermination_closure; // GHC.Internal.Control.Exception.Base.nonTermination_closure
+ StgClosure *nestedAtomically_closure; // GHC.Internal.Control.Exception.Base.nestedAtomically_closure
+ StgClosure *noMatchingContinuationPrompt_closure; // GHC.Internal.Control.Exception.Base.noMatchingContinuationPrompt_closure
+ StgClosure *blockedOnBadFD_closure; // GHC.Internal.Event.Thread.blockedOnBadFD_closure
+ StgClosure *runSparks_closure; // GHC.Internal.Conc.Sync.runSparks_closure
+ StgClosure *ensureIOManagerIsRunning_closure; // GHC.Internal.Conc.IO.ensureIOManagerIsRunning_closure
+ StgClosure *interruptIOManager_closure; // GHC.Internal.Conc.IO.interruptIOManager_closure
+ StgClosure *ioManagerCapabilitiesChanged_closure; // GHC.Internal.Conc.IO.ioManagerCapabilitiesChanged_closure
+ StgClosure *runHandlersPtr_closure; // GHC.Internal.Conc.Signal.runHandlersPtr_closure
+ StgClosure *flushStdHandles_closure; // GHC.Internal.TopHandler.flushStdHandles_closure
+ StgClosure *runMainIO_closure; // GHC.Internal.TopHandler.runMainIO_closure
+ StgInfoTable *Czh_con_info; // GHC.Internal.Types.Czh_con_info
+ StgInfoTable *Izh_con_info; // GHC.Internal.Types.Izh_con_info
+ StgInfoTable *Fzh_con_info; // GHC.Internal.Types.Fzh_con_info
+ StgInfoTable *Dzh_con_info; // GHC.Internal.Types.Dzh_con_info
+ StgInfoTable *Wzh_con_info; // GHC.Internal.Types.Wzh_con_info
+ StgClosure *absentSumFieldError_closure; // GHC.Internal.Prim.Panic.absentSumFieldError_closure
+ StgClosure *runAllocationLimitHandler_closure; // GHC.Internal.AllocationLimitHandler.runAllocationLimitHandler_closure
+ StgInfoTable *Ptr_con_info; // GHC.Internal.Ptr.Ptr_con_info
+ StgInfoTable *FunPtr_con_info; // GHC.Internal.Ptr.FunPtr_con_info
+ StgInfoTable *I8zh_con_info; // GHC.Internal.Int.I8zh_con_info
+ StgInfoTable *I16zh_con_info; // GHC.Internal.Int.I16zh_con_info
+ StgInfoTable *I32zh_con_info; // GHC.Internal.Int.I32zh_con_info
+ StgInfoTable *I64zh_con_info; // GHC.Internal.Int.I64zh_con_info
+ StgInfoTable *W8zh_con_info; // GHC.Internal.Word.W8zh_con_info
+ StgInfoTable *W16zh_con_info; // GHC.Internal.Word.W16zh_con_info
+ StgInfoTable *W32zh_con_info; // GHC.Internal.Word.W32zh_con_info
+ StgInfoTable *W64zh_con_info; // GHC.Internal.Word.W64zh_con_info
+ StgInfoTable *StablePtr_con_info; // GHC.Internal.Stable.StablePtr_con_info
+ StgClosure *StackSnapshot_closure; // GHC.Internal.Stack.CloneStack.StackSnapshot_closure
+ StgClosure *divZZeroException_closure; // GHC.Internal.Exception.Type.divZeroException_closure
+ StgClosure *underflowException_closure; // GHC.Internal.Exception.Type.underflowException_closure
+ StgClosure *overflowException_closure; // GHC.Internal.Exception.Type.overflowException_closure
+ StgClosure *unpackCStringzh_closure; // GHC.Internal.CString.unpackCStringzh_closure
+ StgInfoTable *unpackCStringzh_info; // GHC.Internal.CString.unpackCStringzh_info
+ StgInfoTable *unpackCStringUtf8zh_info; // GHC.Internal.CString.unpackCStringUtf8zh_info
+} HsIface;
+
+extern const HsIface *ghc_hs_iface;
=====================================
rts/include/stg/MiscClosures.h
=====================================
@@ -277,8 +277,8 @@ RTS_ENTRY(stg_NO_FINALIZER);
extern StgWordArray stg_CHARLIKE_closure;
extern StgWordArray stg_INTLIKE_closure;
#else
-extern StgIntCharlikeClosure stg_CHARLIKE_closure[];
-extern StgIntCharlikeClosure stg_INTLIKE_closure[];
+extern StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+extern StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
#endif
/* StgStartup */
=====================================
rts/posix/Signals.c
=====================================
@@ -222,7 +222,7 @@ ioManagerDie (void)
void
ioManagerStartCap (Capability **cap)
{
- rts_evalIO(cap,&ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure,NULL);
+ rts_evalIO(cap,ensureIOManagerIsRunning_closure,NULL);
}
void
@@ -493,7 +493,7 @@ startSignalHandlers(Capability *cap)
RtsFlags.GcFlags.initialStkSize,
rts_apply(cap,
rts_apply(cap,
- &ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure,
+ runHandlersPtr_closure,
rts_mkPtr(cap, info)),
rts_mkInt(cap, info->si_signo)));
scheduleThread(cap, t);
=====================================
rts/rts.cabal
=====================================
@@ -334,6 +334,7 @@ library
rts/storage/InfoTables.h
rts/storage/MBlock.h
rts/storage/TSO.h
+ rts/RtsToHsIface.h
stg/MachRegs.h
stg/MachRegs/arm32.h
stg/MachRegs/arm64.h
@@ -403,6 +404,7 @@ library
adjustor/AdjustorPool.c
ExecPage.c
Arena.c
+ BuiltinClosures.c
Capability.c
CheckUnload.c
CheckVectorSupport.c
@@ -448,6 +450,7 @@ library
RtsStartup.c
RtsSymbolInfo.c
RtsSymbols.c
+ RtsToHsIface.c
RtsUtils.c
STM.c
Schedule.c
=====================================
rts/wasm/JSFFI.c
=====================================
@@ -23,8 +23,8 @@ int __main_argc_argv(int argc, char *argv[]) {
hs_init_ghc(&argc, &argv, __conf);
// See Note [threadDelay on wasm] for details.
rts_JSFFI_flag = HS_BOOL_TRUE;
- getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
- rts_threadDelay_impl = getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->raiseJSException_closure);
+ rts_threadDelay_impl = getStablePtr((StgPtr)ghc_hs_iface->threadDelay_closure);
return 0;
}
@@ -112,7 +112,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
SET_HDR(w, &stg_WEAK_info, CCS_SYSTEM);
w->cfinalizers = (StgClosure *)cfin;
w->key = p;
- w->value = Unit_closure;
+ w->value = ghc_hs_iface->Z0T_closure;
w->finalizer = &stg_NO_FINALIZER_closure;
w->link = cap->weak_ptr_list_hd;
cap->weak_ptr_list_hd = w;
@@ -123,7 +123,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
p->payload[0] = (HaskellObj)w;
HaskellObj box = (HaskellObj)allocate(cap, CONSTR_sizeW(1, 0));
- SET_HDR(box, &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info, CCS_SYSTEM);
+ SET_HDR(box, ghc_hs_iface->JSVal_con_info, CCS_SYSTEM);
box->payload[0] = p;
return TAG_CLOSURE(1, box);
@@ -139,7 +139,7 @@ STATIC_INLINE HsJSVal rts_getJSValzh(HaskellObj p) {
HsJSVal rts_getJSVal(HaskellObj);
HsJSVal rts_getJSVal(HaskellObj box) {
- ASSERT(UNTAG_CLOSURE(box)->header.info == &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info);
+ ASSERT(UNTAG_CLOSURE(box)->header.info == ghc_hs_iface->JSVal_con_info);
return rts_getJSValzh(UNTAG_CLOSURE(box)->payload[0]);
}
@@ -188,7 +188,7 @@ void rts_schedulerLoop(void) {
__attribute__((export_name("rts_promiseResolveUnit")))
void rts_promiseResolveUnit(HsStablePtr);
void rts_promiseResolveUnit(HsStablePtr sp)
- mk_rtsPromiseCallback(TAG_CLOSURE(1, Unit_closure))
+ mk_rtsPromiseCallback(TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure))
mk_rtsPromiseResolve(JSVal)
mk_rtsPromiseResolve(Char)
@@ -212,7 +212,7 @@ mk_rtsPromiseResolve(Bool)
__attribute__((export_name("rts_promiseReject")))
void rts_promiseReject(HsStablePtr, HsJSVal);
void rts_promiseReject(HsStablePtr sp, HsJSVal js_err)
- mk_rtsPromiseCallback(rts_apply(cap, &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure, rts_mkJSVal(cap, js_err)))
+ mk_rtsPromiseCallback(rts_apply(cap, ghc_hs_iface->raiseJSException_closure, rts_mkJSVal(cap, js_err)))
__attribute__((export_name("rts_promiseThrowTo")))
void rts_promiseThrowTo(HsStablePtr, HsJSVal);
@@ -229,7 +229,7 @@ void rts_promiseThrowTo(HsStablePtr sp, HsJSVal js_err) {
cap, tso,
rts_apply(
cap,
- &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure,
+ ghc_hs_iface->raiseJSException_closure,
rts_mkJSVal(cap, js_err)));
tryWakeupThread(cap, tso);
rts_schedulerLoop();
=====================================
utils/deriveConstants/Main.hs
=====================================
@@ -667,6 +667,59 @@ wanteds os = concat
,structField C "StgAsyncIOResult" "errCode"]
else []
+ -- struct HsIface
+ ,structField C "HsIface" "processRemoteCompletion_closure"
+ ,structField C "HsIface" "runIO_closure"
+ ,structField C "HsIface" "runNonIO_closure"
+ ,structField C "HsIface" "Z0T_closure"
+ ,structField C "HsIface" "True_closure"
+ ,structField C "HsIface" "False_closure"
+ ,structField C "HsIface" "unpackCString_closure"
+ ,structField C "HsIface" "runFinalizzerBatch_closure"
+ ,structField C "HsIface" "stackOverflow_closure"
+ ,structField C "HsIface" "heapOverflow_closure"
+ ,structField C "HsIface" "allocationLimitExceeded_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnMVar_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnSTM_closure"
+ ,structField C "HsIface" "cannotCompactFunction_closure"
+ ,structField C "HsIface" "cannotCompactPinned_closure"
+ ,structField C "HsIface" "cannotCompactMutable_closure"
+ ,structField C "HsIface" "nonTermination_closure"
+ ,structField C "HsIface" "nestedAtomically_closure"
+ ,structField C "HsIface" "noMatchingContinuationPrompt_closure"
+ ,structField C "HsIface" "blockedOnBadFD_closure"
+ ,structField C "HsIface" "runSparks_closure"
+ ,structField C "HsIface" "ensureIOManagerIsRunning_closure"
+ ,structField C "HsIface" "interruptIOManager_closure"
+ ,structField C "HsIface" "ioManagerCapabilitiesChanged_closure"
+ ,structField C "HsIface" "runHandlersPtr_closure"
+ ,structField C "HsIface" "flushStdHandles_closure"
+ ,structField C "HsIface" "runMainIO_closure"
+ ,structField C "HsIface" "Czh_con_info"
+ ,structField C "HsIface" "Izh_con_info"
+ ,structField C "HsIface" "Fzh_con_info"
+ ,structField C "HsIface" "Dzh_con_info"
+ ,structField C "HsIface" "Wzh_con_info"
+ ,structField C "HsIface" "runAllocationLimitHandler_closure"
+ ,structField C "HsIface" "Ptr_con_info"
+ ,structField C "HsIface" "FunPtr_con_info"
+ ,structField C "HsIface" "I8zh_con_info"
+ ,structField C "HsIface" "I16zh_con_info"
+ ,structField C "HsIface" "I32zh_con_info"
+ ,structField C "HsIface" "I64zh_con_info"
+ ,structField C "HsIface" "W8zh_con_info"
+ ,structField C "HsIface" "W16zh_con_info"
+ ,structField C "HsIface" "W32zh_con_info"
+ ,structField C "HsIface" "W64zh_con_info"
+ ,structField C "HsIface" "StablePtr_con_info"
+ ,structField C "HsIface" "StackSnapshot_closure"
+ ,structField C "HsIface" "divZZeroException_closure"
+ ,structField C "HsIface" "underflowException_closure"
+ ,structField C "HsIface" "overflowException_closure"
+ ,structField C "HsIface" "unpackCStringzh_closure"
+ ,structField C "HsIface" "unpackCStringzh_info"
+ ,structField C "HsIface" "unpackCStringUtf8zh_info"
+
-- pre-compiled thunk types
,constantWord Haskell "MAX_SPEC_SELECTEE_SIZE" "MAX_SPEC_SELECTEE_SIZE"
,constantWord Haskell "MAX_SPEC_AP_SIZE" "MAX_SPEC_AP_SIZE"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c47024a7d6fee9566b5b5769ae849…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c47024a7d6fee9566b5b5769ae849…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26166] 2 commits: rts: Dynamically initialize built-in closures
by Ben Gamari (@bgamari) 26 Sep '25
by Ben Gamari (@bgamari) 26 Sep '25
26 Sep '25
Ben Gamari pushed to branch wip/T26166 at Glasgow Haskell Compiler / GHC
Commits:
2843baef by Ben Gamari at 2025-09-26T12:50:59-04:00
rts: Dynamically initialize built-in closures
- - - - -
0c47024a by Ben Gamari at 2025-09-26T12:50:59-04:00
rts: Avoid static symbol references to ghc-internal
- - - - -
26 changed files:
- compiler/GHC/HsToCore/Foreign/C.hs
- + libraries/ghc-internal/cbits/RtsIface.c
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/include/RtsIfaceSymbols.h
- + rts/BuiltinClosures.c
- + rts/BuiltinClosures.h
- rts/Compact.cmm
- rts/ContinuationOps.cmm
- rts/Exception.cmm
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/RtsAPI.c
- rts/RtsStartup.c
- + rts/RtsToHsIface.c
- rts/Schedule.c
- rts/StgMiscClosures.cmm
- rts/StgStdThunks.cmm
- rts/include/Rts.h
- rts/include/RtsAPI.h
- rts/include/rts/Constants.h
- + rts/include/rts/RtsToHsIface.h
- rts/include/stg/MiscClosures.h
- rts/posix/Signals.c
- rts/rts.cabal
- rts/wasm/JSFFI.c
- utils/deriveConstants/Main.hs
Changes:
=====================================
compiler/GHC/HsToCore/Foreign/C.hs
=====================================
@@ -517,8 +517,8 @@ mkFExportCBits dflags c_nm maybe_target arg_htys res_hty is_IO_res_ty cc
text "rts_apply" <> parens (
cap
<> (if is_IO_res_ty
- then text "runIO_closure"
- else text "runNonIO_closure")
+ then text "ghc_hs_iface->runIO_closure"
+ else text "ghc_hs_iface->runNonIO_closure")
<> comma
<> expr_to_run
) <+> comma
=====================================
libraries/ghc-internal/cbits/RtsIface.c
=====================================
@@ -0,0 +1,42 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+#include "Rts.h"
+
+void init_ghc_hs_iface(void) __attribute__((constructor));
+
+#define CLOSURE(module, symbol) \
+ extern StgClosure ghczminternal_##module##_##symbol;
+
+#define UNDEF_CLOSURE(module, symbol)
+
+#define INFO_TBL(module, symbol) \
+ extern StgInfoTable ghczminternal_##module##_##symbol;
+
+#include "RtsIfaceSymbols.h"
+
+#undef CLOSURE
+#undef INFO_TBL
+
+#define CLOSURE(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+#define UNDEF_CLOSURE(module, symbol) \
+ .symbol = NULL,
+
+#define INFO_TBL(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+HsIface the_ghc_hs_iface = {
+#include "RtsIfaceSymbols.h"
+};
+
+void init_ghc_hs_iface(void)
+{
+ ghc_hs_iface = &the_ghc_hs_iface;
+}
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -43,6 +43,7 @@ extra-source-files:
include/winio_structs.h
include/WordSize.h
include/HsIntegerGmp.h.in
+ include/RtsIfaceSymbols.h
install-sh
source-repository head
@@ -457,6 +458,7 @@ Library
cbits/vectorQuotRem.c
cbits/word2float.c
cbits/Stack_c.c
+ cbits/RtsIface.c
cmm-sources:
cbits/StackCloningDecoding.cmm
=====================================
libraries/ghc-internal/include/RtsIfaceSymbols.h
=====================================
@@ -0,0 +1,59 @@
+// See Note [RTS/ghc-internal interface].
+
+#if defined(mingw32_HOST_OS)
+CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#else
+UNDEF_CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#endif
+CLOSURE(GHCziInternalziTopHandler, runIO_closure)
+CLOSURE(GHCziInternalziTopHandler, runNonIO_closure)
+CLOSURE(GHCziInternalziTuple, Z0T_closure)
+CLOSURE(GHCziInternalziTypes, True_closure)
+CLOSURE(GHCziInternalziTypes, False_closure)
+CLOSURE(GHCziInternalziPack, unpackCString_closure)
+CLOSURE(GHCziInternalziWeakziFinalizze, runFinalizzerBatch_closure)
+CLOSURE(GHCziInternalziIOziException, stackOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, heapOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, allocationLimitExceeded_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnMVar_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnSTM_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactFunction_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactPinned_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactMutable_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nonTermination_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nestedAtomically_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, noMatchingContinuationPrompt_closure)
+CLOSURE(GHCziInternalziEventziThread, blockedOnBadFD_closure)
+CLOSURE(GHCziInternalziConcziSync, runSparks_closure)
+CLOSURE(GHCziInternalziConcziIO, ensureIOManagerIsRunning_closure)
+CLOSURE(GHCziInternalziConcziIO, interruptIOManager_closure)
+CLOSURE(GHCziInternalziConcziIO, ioManagerCapabilitiesChanged_closure)
+CLOSURE(GHCziInternalziConcziSignal, runHandlersPtr_closure)
+CLOSURE(GHCziInternalziTopHandler, flushStdHandles_closure)
+CLOSURE(GHCziInternalziTopHandler, runMainIO_closure)
+INFO_TBL(GHCziInternalziTypes, Czh_con_info)
+INFO_TBL(GHCziInternalziTypes, Izh_con_info)
+INFO_TBL(GHCziInternalziTypes, Fzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Dzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Wzh_con_info)
+CLOSURE(GHCziInternalziPrimziPanic, absentSumFieldError_closure)
+CLOSURE(GHCziInternalziAllocationLimitHandler, runAllocationLimitHandler_closure)
+INFO_TBL(GHCziInternalziPtr, Ptr_con_info)
+INFO_TBL(GHCziInternalziPtr, FunPtr_con_info)
+INFO_TBL(GHCziInternalziInt, I8zh_con_info)
+INFO_TBL(GHCziInternalziInt, I16zh_con_info)
+INFO_TBL(GHCziInternalziInt, I32zh_con_info)
+INFO_TBL(GHCziInternalziInt, I64zh_con_info)
+INFO_TBL(GHCziInternalziWord, W8zh_con_info)
+INFO_TBL(GHCziInternalziWord, W16zh_con_info)
+INFO_TBL(GHCziInternalziWord, W32zh_con_info)
+INFO_TBL(GHCziInternalziWord, W64zh_con_info)
+INFO_TBL(GHCziInternalziStable, StablePtr_con_info)
+CLOSURE(GHCziInternalziStackziCloneStack, StackSnapshot_closure)
+CLOSURE(GHCziInternalziExceptionziType, divZZeroException_closure)
+CLOSURE(GHCziInternalziExceptionziType, underflowException_closure)
+CLOSURE(GHCziInternalziExceptionziType, overflowException_closure)
+CLOSURE(GHCziInternalziCString, unpackCStringzh_closure)
+INFO_TBL(GHCziInternalziCString, unpackCStringzh_info)
+INFO_TBL(GHCziInternalziCString, unpackCStringUtf8zh_info)
+
=====================================
rts/BuiltinClosures.c
=====================================
@@ -0,0 +1,29 @@
+#include "Rts.h"
+#include "BuiltinClosures.h"
+
+/*
+ * Note [CHARLIKE and INTLIKE closures]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * These are static representations of Chars and small Ints, so that
+ * we can remove dynamic Chars and Ints during garbage collection and
+ * replace them with references to the static objects.
+ */
+
+StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
+StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+
+void initBuiltinClosures() {
+ // INTLIKE closures
+ for (int i = MIN_INTLIKE; i <= MAX_INTLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_INTLIKE_closure[i];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Izh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = MIN_INTLIKE + i;
+ }
+
+ // CHARLIKE closures
+ for (int i = MIN_CHARLIKE; i <= MAX_CHARLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_CHARLIKE_closure[i];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Czh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = MIN_CHARLIKE + i;
+ }
+}
=====================================
rts/BuiltinClosures.h
=====================================
@@ -0,0 +1 @@
+void initBuiltinClosures(void);
=====================================
rts/Compact.cmm
=====================================
@@ -10,9 +10,6 @@
#include "Cmm.h"
#include "sm/ShouldCompact.h"
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE g0;
import CLOSURE large_alloc_lim;
@@ -124,7 +121,7 @@ eval:
SMALL_MUT_ARR_PTRS_CLEAN,
SMALL_MUT_ARR_PTRS_DIRTY,
COMPACT_NFDATA: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
+ jump stg_raisezh(HsIface_cannotCompactMutable_closure(W_[ghc_hs_iface]));
}
// We shouldn't see any functions, if this data structure was NFData.
@@ -139,7 +136,7 @@ eval:
BCO,
PAP,
CONTINUATION: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
+ jump stg_raisezh(HsIface_cannotCompactFunction_closure(W_[ghc_hs_iface]));
}
case ARR_WORDS: {
@@ -147,7 +144,7 @@ eval:
(should) = ccall shouldCompact(compact "ptr", p "ptr");
if (should == SHOULDCOMPACT_IN_CNF) { P_[pp] = p; return(); }
if (should == SHOULDCOMPACT_PINNED) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
+ jump stg_raisezh(HsIface_cannotCompactPinned_closure(W_[ghc_hs_iface]));
}
CHECK_HASH();
=====================================
rts/ContinuationOps.cmm
=====================================
@@ -12,7 +12,6 @@
#include "Cmm.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE ALLOC_RTS_ctr;
import CLOSURE ALLOC_RTS_tot;
@@ -104,7 +103,7 @@ stg_control0zh_ll // explicit stack
// see Note [When capturing the continuation fails] in Continuation.c
if (cont == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure);
+ jump stg_raisezh(HsIface_noMatchingContinuationPrompt_closure(W_[ghc_hs_iface]));
}
W_ apply_mask_frame;
=====================================
rts/Exception.cmm
=====================================
@@ -13,10 +13,6 @@
#include "Cmm.h"
#include "RaiseAsync.h"
-import CLOSURE ghczminternal_GHCziInternalziTypes_True_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_underflowException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_overflowException_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE CATCHF_PUSHED_ctr;
import CLOSURE RtsFlags;
@@ -539,7 +535,7 @@ retry_pop_stack:
Sp(10) = exception;
Sp(9) = stg_raise_ret_info;
Sp(8) = exception;
- Sp(7) = ghczminternal_GHCziInternalziTypes_True_closure; // True <=> an exception
+ Sp(7) = HsIface_True_closure(W_[ghc_hs_iface]); // True <=> an exception
Sp(6) = stg_ap_ppv_info;
Sp(5) = 0;
Sp(4) = stg_ap_n_info;
@@ -650,17 +646,17 @@ stg_raiseIOzh (P_ exception)
stg_raiseDivZZerozh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
+ jump stg_raisezh(HsIface_divZZeroException_closure(W_[ghc_hs_iface]));
}
stg_raiseUnderflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
+ jump stg_raisezh(HsIface_underflowException_closure(W_[ghc_hs_iface]));
}
stg_raiseOverflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
+ jump stg_raisezh(HsIface_overflowException_closure(W_[ghc_hs_iface]));
}
/* The FFI doesn't support variadic C functions so we can't directly expose
=====================================
rts/Prelude.h
=====================================
@@ -19,126 +19,69 @@
#define PRELUDE_CLOSURE(i) extern StgClosure (i)
#endif
-/* See Note [Wired-in exceptions are not CAFfy] in GHC.Core.Make. */
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure);
/* Define canonical names so we can abstract away from the actual
* modules these names are defined in.
*/
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTuple_Z0T_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_True_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_False_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCString_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCStringUtf8_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeak_runFinalizzerBatch_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure);
-
#if defined(IN_STG_CODE)
extern W_ ZCMain_main_closure[];
#else
extern StgClosure ZCMain_main_closure;
#endif
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSync_runSparks_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure);
-#if defined(mingw32_HOST_OS)
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure);
-#endif
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziCString_unpackCStringzh_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Czh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Izh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Fzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Dzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Wzh_con_info);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_Ptr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_FunPtr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziStable_StablePtr_con_info);
-
-#define Unit_closure (&(ghczminternal_GHCziInternalziTuple_Z0T_closure))
-#define True_closure (&(ghczminternal_GHCziInternalziTypes_True_closure))
-#define False_closure (&(ghczminternal_GHCziInternalziTypes_False_closure))
-#define unpackCString_closure (&(ghczminternal_GHCziInternalziPack_unpackCString_closure))
-#define runFinalizerBatch_closure (&(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure))
+#define Unit_closure ghc_hs_iface->Z0T_closure
+#define True_closure ghc_hs_iface->True_closure
+#define False_closure ghc_hs_iface->False_closure
+#define unpackCString_closure ghc_hs_iface->unpackCString_closure
+#define runFinalizerBatch_closure ghc_hs_iface->runFinalizzerBatch_closure
#define mainIO_closure (&ZCMain_main_closure)
-#define runSparks_closure (&(ghczminternal_GHCziInternalziConcziSync_runSparks_closure))
-#define ensureIOManagerIsRunning_closure (&(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure))
-#define interruptIOManager_closure (&(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure))
-#define ioManagerCapabilitiesChanged_closure (&(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure))
-#define runHandlersPtr_closure (&(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure))
+#define runSparks_closure ghc_hs_iface->runSparks_closure
+#define ensureIOManagerIsRunning_closure ghc_hs_iface->ensureIOManagerIsRunning_closure
+#define interruptIOManager_closure ghc_hs_iface->interruptIOManager_closure
+#define ioManagerCapabilitiesChanged_closure ghc_hs_iface->ioManagerCapabilitiesChanged_closure
+#define runHandlersPtr_closure ghc_hs_iface->runHandlersPtr_closure
#if defined(mingw32_HOST_OS)
-#define processRemoteCompletion_closure (&(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure))
+#define processRemoteCompletion_closure ghc_hs_iface->processRemoteCompletion_closure
#endif
-#define runAllocationLimitHandler_closure (&(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure))
-
-#define flushStdHandles_closure (&(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure))
-#define runMainIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure))
-
-#define stackOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure))
-#define heapOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure))
-#define allocationLimitExceeded_closure (&(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure))
-#define blockedIndefinitelyOnMVar_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure))
-#define blockedIndefinitelyOnSTM_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure))
-#define cannotCompactFunction_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure))
-#define cannotCompactPinned_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure))
-#define cannotCompactMutable_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure))
-#define nonTermination_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure))
-#define nestedAtomically_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure))
-#define absentSumFieldError_closure (&(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure))
-#define underflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure))
-#define overflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure))
-#define divZeroException_closure (&(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure))
-
-#define blockedOnBadFD_closure (&(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure))
-
-#define Czh_con_info (&(ghczminternal_GHCziInternalziTypes_Czh_con_info))
-#define Izh_con_info (&(ghczminternal_GHCziInternalziTypes_Izh_con_info))
-#define Fzh_con_info (&(ghczminternal_GHCziInternalziTypes_Fzh_con_info))
-#define Dzh_con_info (&(ghczminternal_GHCziInternalziTypes_Dzh_con_info))
-#define Wzh_con_info (&(ghczminternal_GHCziInternalziTypes_Wzh_con_info))
-#define W8zh_con_info (&(ghczminternal_GHCziInternalziWord_W8zh_con_info))
-#define W16zh_con_info (&(ghczminternal_GHCziInternalziWord_W16zh_con_info))
-#define W32zh_con_info (&(ghczminternal_GHCziInternalziWord_W32zh_con_info))
-#define W64zh_con_info (&(ghczminternal_GHCziInternalziWord_W64zh_con_info))
-#define I8zh_con_info (&(ghczminternal_GHCziInternalziInt_I8zh_con_info))
-#define I16zh_con_info (&(ghczminternal_GHCziInternalziInt_I16zh_con_info))
-#define I32zh_con_info (&(ghczminternal_GHCziInternalziInt_I32zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define Ptr_con_info (&(ghczminternal_GHCziInternalziPtr_Ptr_con_info))
-#define FunPtr_con_info (&(ghczminternal_GHCziInternalziPtr_FunPtr_con_info))
-#define StablePtr_static_info (&(ghczminternal_GHCziInternalziStable_StablePtr_static_info))
-#define StablePtr_con_info (&(ghczminternal_GHCziInternalziStable_StablePtr_con_info))
+#define runAllocationLimitHandler_closure ghc_hs_iface->runAllocationLimitHandler_closure
+
+#define flushStdHandles_closure ghc_hs_iface->flushStdHandles_closure
+#define runMainIO_closure ghc_hs_iface->runMainIO_closure
+
+#define stackOverflow_closure ghc_hs_iface->stackOverflow_closure
+#define heapOverflow_closure ghc_hs_iface->heapOverflow_closure
+#define allocationLimitExceeded_closure ghc_hs_iface->allocationLimitExceeded_closure
+#define blockedIndefinitelyOnMVar_closure ghc_hs_iface->blockedIndefinitelyOnMVar_closure
+#define blockedIndefinitelyOnSTM_closure ghc_hs_iface->blockedIndefinitelyOnSTM_closure
+#define cannotCompactFunction_closure ghc_hs_iface->cannotCompactFunction_closure
+#define cannotCompactPinned_closure ghc_hs_iface->cannotCompactPinned_closure
+#define cannotCompactMutable_closure ghc_hs_iface->cannotCompactMutable_closure
+#define nonTermination_closure ghc_hs_iface->nonTermination_closure
+#define nestedAtomically_closure ghc_hs_iface->nestedAtomically_closure
+#define absentSumFieldError_closure ghc_hs_iface->absentSumFieldError_closure
+#define underflowException_closure ghc_hs_iface->underflowException_closure
+#define overflowException_closure ghc_hs_iface->overflowException_closure
+#define divZeroException_closure ghc_hs_iface->divZZeroException_closure
+
+#define blockedOnBadFD_closure ghc_hs_iface->blockedOnBadFD_closure
+
+#define Czh_con_info ghc_hs_iface->Czh_con_info
+#define Izh_con_info ghc_hs_iface->Izh_con_info
+#define Fzh_con_info ghc_hs_iface->Fzh_con_info
+#define Dzh_con_info ghc_hs_iface->Dzh_con_info
+#define Wzh_con_info ghc_hs_iface->Wzh_con_info
+#define W8zh_con_info ghc_hs_iface->W8zh_con_info
+#define W16zh_con_info ghc_hs_iface->W16zh_con_info
+#define W32zh_con_info ghc_hs_iface->W32zh_con_info
+#define W64zh_con_info ghc_hs_iface->W64zh_con_info
+#define I8zh_con_info ghc_hs_iface->I8zh_con_info
+#define I16zh_con_info ghc_hs_iface->I16zh_con_info
+#define I32zh_con_info ghc_hs_iface->I32zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define Ptr_con_info ghc_hs_iface->Ptr_con_info
+#define FunPtr_con_info ghc_hs_iface->FunPtr_con_info
+#define StablePtr_static_info ghc_hs_iface->StablePtr_static_info
+#define StablePtr_con_info ghc_hs_iface->StablePtr_con_info
=====================================
rts/PrimOps.cmm
=====================================
@@ -25,12 +25,8 @@
#include "MachDeps.h"
#include "SMPClosureOps.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_heapOverflow_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
-import CLOSURE ghczminternal_GHCziInternalziTypes_False_closure;
#if defined(PROFILING)
import CLOSURE CCS_MAIN;
#endif
@@ -118,7 +114,7 @@ stg_newByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytes(MyCapability() "ptr", n, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -135,7 +131,7 @@ stg_newPinnedByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
BA_ALIGN, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -149,7 +145,7 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
alignment, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -364,7 +360,7 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -474,7 +470,7 @@ stg_newSmallArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateSmallMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -1090,7 +1086,7 @@ stg_listThreadszh ()
("ptr" arr) = ccall listThreads(MyCapability() "ptr");
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (arr);
@@ -1360,7 +1356,7 @@ stg_atomicallyzh (P_ stm)
/* Nested transactions are not allowed; raise an exception */
if (old_trec != NO_TREC) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
+ jump stg_raisezh(HsIface_nestedAtomically_closure(W_[ghc_hs_iface]));
}
code = stm;
@@ -2231,7 +2227,7 @@ stg_unpackClosurezh ( P_ closure )
dat_arr_sz = SIZEOF_StgArrBytes + WDS(len);
("ptr" dat_arr) = ccall allocateMightFail(MyCapability() "ptr", BYTES_TO_WDS(dat_arr_sz));
if (dat_arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
TICK_ALLOC_PRIM(SIZEOF_StgArrBytes, WDS(len), 0);
@@ -2251,7 +2247,7 @@ for:
("ptr" ptrArray) = foreign "C" heap_view_closurePtrs(MyCapability() "ptr", clos "ptr");
if (ptrArray == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (info, dat_arr, ptrArray);
@@ -2518,13 +2514,13 @@ stg_getSparkzh ()
W_ spark;
#if !defined(THREADED_RTS)
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
#else
("ptr" spark) = ccall findSpark(MyCapability() "ptr");
if (spark != 0) {
return (1,spark);
} else {
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
}
#endif
}
=====================================
rts/RtsAPI.c
=====================================
@@ -509,7 +509,7 @@ void rts_evalStableIOMain(/* inout */ Capability **cap,
SchedulerStatus stat;
p = (StgClosure *)deRefStablePtr(s);
- w = rts_apply(*cap, &ghczminternal_GHCziInternalziTopHandler_runMainIO_closure, p);
+ w = rts_apply(*cap, runMainIO_closure, p);
tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, w);
// async exceptions are always blocked by default in the created
// thread. See #1048.
@@ -961,7 +961,7 @@ void rts_done (void)
void hs_try_putmvar (/* in */ int capability,
/* in */ HsStablePtr mvar)
{
- hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, Unit_closure));
+ hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure));
}
void hs_try_putmvar_with_value (/* in */ int capability,
=====================================
rts/RtsStartup.c
=====================================
@@ -14,6 +14,7 @@
#include "linker/MMap.h"
#include "RtsFlags.h"
#include "RtsUtils.h"
+#include "BuiltinClosures.h"
#include "Prelude.h"
#include "Printer.h" /* DEBUG_LoadSymbols */
#include "Schedule.h" /* initScheduler */
@@ -182,8 +183,8 @@ static void initBuiltinGcRoots(void)
* these closures `Id`s of these can be safely marked as non-CAFFY
* in the compiler.
*/
- getStablePtr((StgPtr)runIO_closure);
- getStablePtr((StgPtr)runNonIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runNonIO_closure);
getStablePtr((StgPtr)flushStdHandles_closure);
getStablePtr((StgPtr)runFinalizerBatch_closure);
@@ -262,6 +263,14 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
setlocale(LC_CTYPE,"");
+ if (ghc_hs_iface == NULL) {
+ errorBelch("hs_init_ghc: ghc_hs_iface is uninitialized");
+ stg_exit(1);
+ }
+
+
+ initBuiltinClosures();
+
/* Initialise the stats department, phase 0 */
initStats0();
=====================================
rts/RtsToHsIface.c
=====================================
@@ -0,0 +1,45 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ *
+ * Note [RTS/ghc-internal interface]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The runtime system depends upon a variety of symbols defined by Haskell
+ * modules living in `ghc-internal`. To avoid cyclic dependencies between
+ * ghc-internal and the RTS, these symbols are referenced indirectly via the
+ * the `HsIface` structure (specifically `ghc_hs_iface`):
+ *
+ * struct HsIface {
+ * StgClosure *runIO; // GHC.Internal.TopHandler.runIO
+ * StgClosure *Z0T; // GHC.Internal.Tuple.()
+ * // etc.
+ * };
+ *
+ * `ghc_hs_iface` is initialized during program loading via the
+ * `init_ghc_hs_iface` constructor in `ghc-interface`
+ *
+ * const struct HsIface the_hs_iface = {
+ * .runIO = &ghczminternal_GHCziInternalziTopHandler_runIO_closure,
+ * .Z0T = &ghczminternal_GHCziInternalziTuple_Z0T_closure,
+ * // etc.
+ * };
+ *
+ * void __attribute__((constructor)) init_ghc_hs_iface() {
+ * ghc_hs_iface = &the_hs_iface;
+ * }
+ *
+ * This effectively breaks the RTS's link-time dependency, replacing it with a
+ * run-time dependency at the cost of an indirection. It also has the pleasant
+ * side-effect of making the interface between the RTS and `ghc-internal`
+ * explicit.
+ *
+ */
+
+#include "Rts.h"
+
+// This captures the symbols provided by ghc-internal which
+// are needed by the RTS.
+const HsIface *ghc_hs_iface = NULL;
=====================================
rts/Schedule.c
=====================================
@@ -1053,7 +1053,7 @@ scheduleProcessInbox (Capability **pcap USED_IF_THREADS)
while (p != NULL) {
pnext = p->link;
performTryPutMVar(cap, (StgMVar*)deRefStablePtr(p->mvar),
- Unit_closure);
+ ghc_hs_iface->Z0T_closure);
freeStablePtr(p->mvar);
stgFree(p);
p = pnext;
=====================================
rts/StgMiscClosures.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
import pthread_mutex_lock;
-import ghczminternal_GHCziInternalziTypes_Czh_info;
-import ghczminternal_GHCziInternalziTypes_Izh_info;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
@@ -23,7 +21,6 @@ import whitehole_lockClosure_spin;
import whitehole_lockClosure_yield;
#endif
-
#if !defined(UnregisterisedCompiler)
import CLOSURE CCS_SYSTEM;
import CLOSURE ENT_DYN_IND_ctr;
@@ -1031,554 +1028,3 @@ INFO_TABLE_CONSTR(stg_ASYNCIO_LIVE0,0,0,0,CONSTR_NOCAF,"ASYNCIO_LIVE0","ASYNCIO_
{ foreign "C" barf("ASYNCIO_LIVE0 object (%p) entered!", R1) never returns; }
CLOSURE(stg_ASYNCIO_LIVE0_closure,stg_ASYNCIO_LIVE0);
-
-/* ----------------------------------------------------------------------------
- Note [CHARLIKE and INTLIKE closures]
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- These are static representations of Chars and small Ints, so that
- we can remove dynamic Chars and Ints during garbage collection and
- replace them with references to the static objects.
- ------------------------------------------------------------------------- */
-
-#define Char_hash_con_info ghczminternal_GHCziInternalziTypes_Czh_con_info
-#define Int_hash_con_info ghczminternal_GHCziInternalziTypes_Izh_con_info
-
-#define CHARLIKE_HDR(n) CLOSURE(Char_hash_con_info, n)
-#define INTLIKE_HDR(n) CLOSURE(Int_hash_con_info, n)
-
-section "data" {
- stg_CHARLIKE_closure:
- CHARLIKE_HDR(0)
- CHARLIKE_HDR(1)
- CHARLIKE_HDR(2)
- CHARLIKE_HDR(3)
- CHARLIKE_HDR(4)
- CHARLIKE_HDR(5)
- CHARLIKE_HDR(6)
- CHARLIKE_HDR(7)
- CHARLIKE_HDR(8)
- CHARLIKE_HDR(9)
- CHARLIKE_HDR(10)
- CHARLIKE_HDR(11)
- CHARLIKE_HDR(12)
- CHARLIKE_HDR(13)
- CHARLIKE_HDR(14)
- CHARLIKE_HDR(15)
- CHARLIKE_HDR(16)
- CHARLIKE_HDR(17)
- CHARLIKE_HDR(18)
- CHARLIKE_HDR(19)
- CHARLIKE_HDR(20)
- CHARLIKE_HDR(21)
- CHARLIKE_HDR(22)
- CHARLIKE_HDR(23)
- CHARLIKE_HDR(24)
- CHARLIKE_HDR(25)
- CHARLIKE_HDR(26)
- CHARLIKE_HDR(27)
- CHARLIKE_HDR(28)
- CHARLIKE_HDR(29)
- CHARLIKE_HDR(30)
- CHARLIKE_HDR(31)
- CHARLIKE_HDR(32)
- CHARLIKE_HDR(33)
- CHARLIKE_HDR(34)
- CHARLIKE_HDR(35)
- CHARLIKE_HDR(36)
- CHARLIKE_HDR(37)
- CHARLIKE_HDR(38)
- CHARLIKE_HDR(39)
- CHARLIKE_HDR(40)
- CHARLIKE_HDR(41)
- CHARLIKE_HDR(42)
- CHARLIKE_HDR(43)
- CHARLIKE_HDR(44)
- CHARLIKE_HDR(45)
- CHARLIKE_HDR(46)
- CHARLIKE_HDR(47)
- CHARLIKE_HDR(48)
- CHARLIKE_HDR(49)
- CHARLIKE_HDR(50)
- CHARLIKE_HDR(51)
- CHARLIKE_HDR(52)
- CHARLIKE_HDR(53)
- CHARLIKE_HDR(54)
- CHARLIKE_HDR(55)
- CHARLIKE_HDR(56)
- CHARLIKE_HDR(57)
- CHARLIKE_HDR(58)
- CHARLIKE_HDR(59)
- CHARLIKE_HDR(60)
- CHARLIKE_HDR(61)
- CHARLIKE_HDR(62)
- CHARLIKE_HDR(63)
- CHARLIKE_HDR(64)
- CHARLIKE_HDR(65)
- CHARLIKE_HDR(66)
- CHARLIKE_HDR(67)
- CHARLIKE_HDR(68)
- CHARLIKE_HDR(69)
- CHARLIKE_HDR(70)
- CHARLIKE_HDR(71)
- CHARLIKE_HDR(72)
- CHARLIKE_HDR(73)
- CHARLIKE_HDR(74)
- CHARLIKE_HDR(75)
- CHARLIKE_HDR(76)
- CHARLIKE_HDR(77)
- CHARLIKE_HDR(78)
- CHARLIKE_HDR(79)
- CHARLIKE_HDR(80)
- CHARLIKE_HDR(81)
- CHARLIKE_HDR(82)
- CHARLIKE_HDR(83)
- CHARLIKE_HDR(84)
- CHARLIKE_HDR(85)
- CHARLIKE_HDR(86)
- CHARLIKE_HDR(87)
- CHARLIKE_HDR(88)
- CHARLIKE_HDR(89)
- CHARLIKE_HDR(90)
- CHARLIKE_HDR(91)
- CHARLIKE_HDR(92)
- CHARLIKE_HDR(93)
- CHARLIKE_HDR(94)
- CHARLIKE_HDR(95)
- CHARLIKE_HDR(96)
- CHARLIKE_HDR(97)
- CHARLIKE_HDR(98)
- CHARLIKE_HDR(99)
- CHARLIKE_HDR(100)
- CHARLIKE_HDR(101)
- CHARLIKE_HDR(102)
- CHARLIKE_HDR(103)
- CHARLIKE_HDR(104)
- CHARLIKE_HDR(105)
- CHARLIKE_HDR(106)
- CHARLIKE_HDR(107)
- CHARLIKE_HDR(108)
- CHARLIKE_HDR(109)
- CHARLIKE_HDR(110)
- CHARLIKE_HDR(111)
- CHARLIKE_HDR(112)
- CHARLIKE_HDR(113)
- CHARLIKE_HDR(114)
- CHARLIKE_HDR(115)
- CHARLIKE_HDR(116)
- CHARLIKE_HDR(117)
- CHARLIKE_HDR(118)
- CHARLIKE_HDR(119)
- CHARLIKE_HDR(120)
- CHARLIKE_HDR(121)
- CHARLIKE_HDR(122)
- CHARLIKE_HDR(123)
- CHARLIKE_HDR(124)
- CHARLIKE_HDR(125)
- CHARLIKE_HDR(126)
- CHARLIKE_HDR(127)
- CHARLIKE_HDR(128)
- CHARLIKE_HDR(129)
- CHARLIKE_HDR(130)
- CHARLIKE_HDR(131)
- CHARLIKE_HDR(132)
- CHARLIKE_HDR(133)
- CHARLIKE_HDR(134)
- CHARLIKE_HDR(135)
- CHARLIKE_HDR(136)
- CHARLIKE_HDR(137)
- CHARLIKE_HDR(138)
- CHARLIKE_HDR(139)
- CHARLIKE_HDR(140)
- CHARLIKE_HDR(141)
- CHARLIKE_HDR(142)
- CHARLIKE_HDR(143)
- CHARLIKE_HDR(144)
- CHARLIKE_HDR(145)
- CHARLIKE_HDR(146)
- CHARLIKE_HDR(147)
- CHARLIKE_HDR(148)
- CHARLIKE_HDR(149)
- CHARLIKE_HDR(150)
- CHARLIKE_HDR(151)
- CHARLIKE_HDR(152)
- CHARLIKE_HDR(153)
- CHARLIKE_HDR(154)
- CHARLIKE_HDR(155)
- CHARLIKE_HDR(156)
- CHARLIKE_HDR(157)
- CHARLIKE_HDR(158)
- CHARLIKE_HDR(159)
- CHARLIKE_HDR(160)
- CHARLIKE_HDR(161)
- CHARLIKE_HDR(162)
- CHARLIKE_HDR(163)
- CHARLIKE_HDR(164)
- CHARLIKE_HDR(165)
- CHARLIKE_HDR(166)
- CHARLIKE_HDR(167)
- CHARLIKE_HDR(168)
- CHARLIKE_HDR(169)
- CHARLIKE_HDR(170)
- CHARLIKE_HDR(171)
- CHARLIKE_HDR(172)
- CHARLIKE_HDR(173)
- CHARLIKE_HDR(174)
- CHARLIKE_HDR(175)
- CHARLIKE_HDR(176)
- CHARLIKE_HDR(177)
- CHARLIKE_HDR(178)
- CHARLIKE_HDR(179)
- CHARLIKE_HDR(180)
- CHARLIKE_HDR(181)
- CHARLIKE_HDR(182)
- CHARLIKE_HDR(183)
- CHARLIKE_HDR(184)
- CHARLIKE_HDR(185)
- CHARLIKE_HDR(186)
- CHARLIKE_HDR(187)
- CHARLIKE_HDR(188)
- CHARLIKE_HDR(189)
- CHARLIKE_HDR(190)
- CHARLIKE_HDR(191)
- CHARLIKE_HDR(192)
- CHARLIKE_HDR(193)
- CHARLIKE_HDR(194)
- CHARLIKE_HDR(195)
- CHARLIKE_HDR(196)
- CHARLIKE_HDR(197)
- CHARLIKE_HDR(198)
- CHARLIKE_HDR(199)
- CHARLIKE_HDR(200)
- CHARLIKE_HDR(201)
- CHARLIKE_HDR(202)
- CHARLIKE_HDR(203)
- CHARLIKE_HDR(204)
- CHARLIKE_HDR(205)
- CHARLIKE_HDR(206)
- CHARLIKE_HDR(207)
- CHARLIKE_HDR(208)
- CHARLIKE_HDR(209)
- CHARLIKE_HDR(210)
- CHARLIKE_HDR(211)
- CHARLIKE_HDR(212)
- CHARLIKE_HDR(213)
- CHARLIKE_HDR(214)
- CHARLIKE_HDR(215)
- CHARLIKE_HDR(216)
- CHARLIKE_HDR(217)
- CHARLIKE_HDR(218)
- CHARLIKE_HDR(219)
- CHARLIKE_HDR(220)
- CHARLIKE_HDR(221)
- CHARLIKE_HDR(222)
- CHARLIKE_HDR(223)
- CHARLIKE_HDR(224)
- CHARLIKE_HDR(225)
- CHARLIKE_HDR(226)
- CHARLIKE_HDR(227)
- CHARLIKE_HDR(228)
- CHARLIKE_HDR(229)
- CHARLIKE_HDR(230)
- CHARLIKE_HDR(231)
- CHARLIKE_HDR(232)
- CHARLIKE_HDR(233)
- CHARLIKE_HDR(234)
- CHARLIKE_HDR(235)
- CHARLIKE_HDR(236)
- CHARLIKE_HDR(237)
- CHARLIKE_HDR(238)
- CHARLIKE_HDR(239)
- CHARLIKE_HDR(240)
- CHARLIKE_HDR(241)
- CHARLIKE_HDR(242)
- CHARLIKE_HDR(243)
- CHARLIKE_HDR(244)
- CHARLIKE_HDR(245)
- CHARLIKE_HDR(246)
- CHARLIKE_HDR(247)
- CHARLIKE_HDR(248)
- CHARLIKE_HDR(249)
- CHARLIKE_HDR(250)
- CHARLIKE_HDR(251)
- CHARLIKE_HDR(252)
- CHARLIKE_HDR(253)
- CHARLIKE_HDR(254)
- CHARLIKE_HDR(255)
-}
-
-section "data" {
- stg_INTLIKE_closure:
- INTLIKE_HDR(-16) /* MIN_INTLIKE == -16 */
- INTLIKE_HDR(-15)
- INTLIKE_HDR(-14)
- INTLIKE_HDR(-13)
- INTLIKE_HDR(-12)
- INTLIKE_HDR(-11)
- INTLIKE_HDR(-10)
- INTLIKE_HDR(-9)
- INTLIKE_HDR(-8)
- INTLIKE_HDR(-7)
- INTLIKE_HDR(-6)
- INTLIKE_HDR(-5)
- INTLIKE_HDR(-4)
- INTLIKE_HDR(-3)
- INTLIKE_HDR(-2)
- INTLIKE_HDR(-1)
- INTLIKE_HDR(0)
- INTLIKE_HDR(1)
- INTLIKE_HDR(2)
- INTLIKE_HDR(3)
- INTLIKE_HDR(4)
- INTLIKE_HDR(5)
- INTLIKE_HDR(6)
- INTLIKE_HDR(7)
- INTLIKE_HDR(8)
- INTLIKE_HDR(9)
- INTLIKE_HDR(10)
- INTLIKE_HDR(11)
- INTLIKE_HDR(12)
- INTLIKE_HDR(13)
- INTLIKE_HDR(14)
- INTLIKE_HDR(15)
- INTLIKE_HDR(16)
- INTLIKE_HDR(17)
- INTLIKE_HDR(18)
- INTLIKE_HDR(19)
- INTLIKE_HDR(20)
- INTLIKE_HDR(21)
- INTLIKE_HDR(22)
- INTLIKE_HDR(23)
- INTLIKE_HDR(24)
- INTLIKE_HDR(25)
- INTLIKE_HDR(26)
- INTLIKE_HDR(27)
- INTLIKE_HDR(28)
- INTLIKE_HDR(29)
- INTLIKE_HDR(30)
- INTLIKE_HDR(31)
- INTLIKE_HDR(32)
- INTLIKE_HDR(33)
- INTLIKE_HDR(34)
- INTLIKE_HDR(35)
- INTLIKE_HDR(36)
- INTLIKE_HDR(37)
- INTLIKE_HDR(38)
- INTLIKE_HDR(39)
- INTLIKE_HDR(40)
- INTLIKE_HDR(41)
- INTLIKE_HDR(42)
- INTLIKE_HDR(43)
- INTLIKE_HDR(44)
- INTLIKE_HDR(45)
- INTLIKE_HDR(46)
- INTLIKE_HDR(47)
- INTLIKE_HDR(48)
- INTLIKE_HDR(49)
- INTLIKE_HDR(50)
- INTLIKE_HDR(51)
- INTLIKE_HDR(52)
- INTLIKE_HDR(53)
- INTLIKE_HDR(54)
- INTLIKE_HDR(55)
- INTLIKE_HDR(56)
- INTLIKE_HDR(57)
- INTLIKE_HDR(58)
- INTLIKE_HDR(59)
- INTLIKE_HDR(60)
- INTLIKE_HDR(61)
- INTLIKE_HDR(62)
- INTLIKE_HDR(63)
- INTLIKE_HDR(64)
- INTLIKE_HDR(65)
- INTLIKE_HDR(66)
- INTLIKE_HDR(67)
- INTLIKE_HDR(68)
- INTLIKE_HDR(69)
- INTLIKE_HDR(70)
- INTLIKE_HDR(71)
- INTLIKE_HDR(72)
- INTLIKE_HDR(73)
- INTLIKE_HDR(74)
- INTLIKE_HDR(75)
- INTLIKE_HDR(76)
- INTLIKE_HDR(77)
- INTLIKE_HDR(78)
- INTLIKE_HDR(79)
- INTLIKE_HDR(80)
- INTLIKE_HDR(81)
- INTLIKE_HDR(82)
- INTLIKE_HDR(83)
- INTLIKE_HDR(84)
- INTLIKE_HDR(85)
- INTLIKE_HDR(86)
- INTLIKE_HDR(87)
- INTLIKE_HDR(88)
- INTLIKE_HDR(89)
- INTLIKE_HDR(90)
- INTLIKE_HDR(91)
- INTLIKE_HDR(92)
- INTLIKE_HDR(93)
- INTLIKE_HDR(94)
- INTLIKE_HDR(95)
- INTLIKE_HDR(96)
- INTLIKE_HDR(97)
- INTLIKE_HDR(98)
- INTLIKE_HDR(99)
- INTLIKE_HDR(100)
- INTLIKE_HDR(101)
- INTLIKE_HDR(102)
- INTLIKE_HDR(103)
- INTLIKE_HDR(104)
- INTLIKE_HDR(105)
- INTLIKE_HDR(106)
- INTLIKE_HDR(107)
- INTLIKE_HDR(108)
- INTLIKE_HDR(109)
- INTLIKE_HDR(110)
- INTLIKE_HDR(111)
- INTLIKE_HDR(112)
- INTLIKE_HDR(113)
- INTLIKE_HDR(114)
- INTLIKE_HDR(115)
- INTLIKE_HDR(116)
- INTLIKE_HDR(117)
- INTLIKE_HDR(118)
- INTLIKE_HDR(119)
- INTLIKE_HDR(120)
- INTLIKE_HDR(121)
- INTLIKE_HDR(122)
- INTLIKE_HDR(123)
- INTLIKE_HDR(124)
- INTLIKE_HDR(125)
- INTLIKE_HDR(126)
- INTLIKE_HDR(127)
- INTLIKE_HDR(128)
- INTLIKE_HDR(129)
- INTLIKE_HDR(130)
- INTLIKE_HDR(131)
- INTLIKE_HDR(132)
- INTLIKE_HDR(133)
- INTLIKE_HDR(134)
- INTLIKE_HDR(135)
- INTLIKE_HDR(136)
- INTLIKE_HDR(137)
- INTLIKE_HDR(138)
- INTLIKE_HDR(139)
- INTLIKE_HDR(140)
- INTLIKE_HDR(141)
- INTLIKE_HDR(142)
- INTLIKE_HDR(143)
- INTLIKE_HDR(144)
- INTLIKE_HDR(145)
- INTLIKE_HDR(146)
- INTLIKE_HDR(147)
- INTLIKE_HDR(148)
- INTLIKE_HDR(149)
- INTLIKE_HDR(150)
- INTLIKE_HDR(151)
- INTLIKE_HDR(152)
- INTLIKE_HDR(153)
- INTLIKE_HDR(154)
- INTLIKE_HDR(155)
- INTLIKE_HDR(156)
- INTLIKE_HDR(157)
- INTLIKE_HDR(158)
- INTLIKE_HDR(159)
- INTLIKE_HDR(160)
- INTLIKE_HDR(161)
- INTLIKE_HDR(162)
- INTLIKE_HDR(163)
- INTLIKE_HDR(164)
- INTLIKE_HDR(165)
- INTLIKE_HDR(166)
- INTLIKE_HDR(167)
- INTLIKE_HDR(168)
- INTLIKE_HDR(169)
- INTLIKE_HDR(170)
- INTLIKE_HDR(171)
- INTLIKE_HDR(172)
- INTLIKE_HDR(173)
- INTLIKE_HDR(174)
- INTLIKE_HDR(175)
- INTLIKE_HDR(176)
- INTLIKE_HDR(177)
- INTLIKE_HDR(178)
- INTLIKE_HDR(179)
- INTLIKE_HDR(180)
- INTLIKE_HDR(181)
- INTLIKE_HDR(182)
- INTLIKE_HDR(183)
- INTLIKE_HDR(184)
- INTLIKE_HDR(185)
- INTLIKE_HDR(186)
- INTLIKE_HDR(187)
- INTLIKE_HDR(188)
- INTLIKE_HDR(189)
- INTLIKE_HDR(190)
- INTLIKE_HDR(191)
- INTLIKE_HDR(192)
- INTLIKE_HDR(193)
- INTLIKE_HDR(194)
- INTLIKE_HDR(195)
- INTLIKE_HDR(196)
- INTLIKE_HDR(197)
- INTLIKE_HDR(198)
- INTLIKE_HDR(199)
- INTLIKE_HDR(200)
- INTLIKE_HDR(201)
- INTLIKE_HDR(202)
- INTLIKE_HDR(203)
- INTLIKE_HDR(204)
- INTLIKE_HDR(205)
- INTLIKE_HDR(206)
- INTLIKE_HDR(207)
- INTLIKE_HDR(208)
- INTLIKE_HDR(209)
- INTLIKE_HDR(210)
- INTLIKE_HDR(211)
- INTLIKE_HDR(212)
- INTLIKE_HDR(213)
- INTLIKE_HDR(214)
- INTLIKE_HDR(215)
- INTLIKE_HDR(216)
- INTLIKE_HDR(217)
- INTLIKE_HDR(218)
- INTLIKE_HDR(219)
- INTLIKE_HDR(220)
- INTLIKE_HDR(221)
- INTLIKE_HDR(222)
- INTLIKE_HDR(223)
- INTLIKE_HDR(224)
- INTLIKE_HDR(225)
- INTLIKE_HDR(226)
- INTLIKE_HDR(227)
- INTLIKE_HDR(228)
- INTLIKE_HDR(229)
- INTLIKE_HDR(230)
- INTLIKE_HDR(231)
- INTLIKE_HDR(232)
- INTLIKE_HDR(233)
- INTLIKE_HDR(234)
- INTLIKE_HDR(235)
- INTLIKE_HDR(236)
- INTLIKE_HDR(237)
- INTLIKE_HDR(238)
- INTLIKE_HDR(239)
- INTLIKE_HDR(240)
- INTLIKE_HDR(241)
- INTLIKE_HDR(242)
- INTLIKE_HDR(243)
- INTLIKE_HDR(244)
- INTLIKE_HDR(245)
- INTLIKE_HDR(246)
- INTLIKE_HDR(247)
- INTLIKE_HDR(248)
- INTLIKE_HDR(249)
- INTLIKE_HDR(250)
- INTLIKE_HDR(251)
- INTLIKE_HDR(252)
- INTLIKE_HDR(253)
- INTLIKE_HDR(254)
- INTLIKE_HDR(255) /* MAX_INTLIKE == 255
- See #16961 for why 255 */
-}
=====================================
rts/StgStdThunks.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
#include "Updates.h"
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringzh_info;
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info;
#if !defined(UnregisterisedCompiler)
import CLOSURE STK_CHK_ctr;
import CLOSURE stg_bh_upd_frame_info;
@@ -348,7 +346,7 @@ stg_do_unpack_cstring(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringzh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringzh_info(W_[ghc_hs_iface]))(node, str);
}
}
@@ -372,7 +370,7 @@ stg_do_unpack_cstring_utf8(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringUtf8zh_info(W_[ghc_hs_iface]))(node, str);
}
}
=====================================
rts/include/Rts.h
=====================================
@@ -229,6 +229,7 @@ void _warnFail(const char *filename, unsigned int linenum);
#include "rts/storage/ClosureTypes.h"
#include "rts/storage/TSO.h"
#include "stg/MiscClosures.h" /* InfoTables, closures etc. defined in the RTS */
+
#include "rts/storage/Block.h"
#include "rts/storage/ClosureMacros.h"
#include "rts/storage/MBlock.h"
=====================================
rts/include/RtsAPI.h
=====================================
@@ -18,6 +18,7 @@ extern "C" {
#include "HsFFI.h"
#include "rts/Time.h"
#include "rts/Types.h"
+#include "rts/RtsToHsIface.h"
/*
* Running the scheduler
@@ -584,11 +585,6 @@ void rts_done (void);
// Note that RtsAPI.h is also included by foreign export stubs in
// the base package itself.
//
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runIO_closure;
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runNonIO_closure;
-
-#define runIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runIO_closure))
-#define runNonIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runNonIO_closure))
/* ------------------------------------------------------------------------ */
=====================================
rts/include/rts/Constants.h
=====================================
@@ -57,11 +57,12 @@
#define MAX_SPEC_CONSTR_SIZE 2
/* Range of built-in table of static small int-like and char-like closures.
+ * Range is inclusive of both minimum and maximum.
*
* NB. This corresponds with the number of actual INTLIKE/CHARLIKE
* closures defined in rts/StgMiscClosures.cmm.
*/
-#define MAX_INTLIKE 255
+#define MAX_INTLIKE 255 /* See #16961 for why 255 */
#define MIN_INTLIKE (-16)
#define MAX_CHARLIKE 255
=====================================
rts/include/rts/RtsToHsIface.h
=====================================
@@ -0,0 +1,64 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+typedef struct {
+ StgClosure *processRemoteCompletion_closure; // GHC.Internal.Event.Windows.processRemoteCompletion_closure
+ StgClosure *runIO_closure; // GHC.Internal.TopHandler.runIO_closure
+ StgClosure *runNonIO_closure; // GHC.Internal.TopHandler.runNonIO_closure
+ StgClosure *Z0T_closure; // GHC.Internal.Tuple.Z0T_closure
+ StgClosure *True_closure; // GHC.Internal.Types.True_closure
+ StgClosure *False_closure; // GHC.Internal.Types.False_closure
+ StgClosure *unpackCString_closure; // GHC.Internal.Pack.unpackCString_closure
+ StgClosure *runFinalizzerBatch_closure; // GHC.Internal.Weak.Finalizze.runFinalizzerBatch_closure
+ StgClosure *stackOverflow_closure; // GHC.Internal.IO.Exception.stackOverflow_closure
+ StgClosure *heapOverflow_closure; // GHC.Internal.IO.Exception.heapOverflow_closure
+ StgClosure *allocationLimitExceeded_closure; // GHC.Internal.IO.Exception.allocationLimitExceeded_closure
+ StgClosure *blockedIndefinitelyOnMVar_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnMVar_closure
+ StgClosure *blockedIndefinitelyOnSTM_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnSTM_closure
+ StgClosure *cannotCompactFunction_closure; // GHC.Internal.IO.Exception.cannotCompactFunction_closure
+ StgClosure *cannotCompactPinned_closure; // GHC.Internal.IO.Exception.cannotCompactPinned_closure
+ StgClosure *cannotCompactMutable_closure; // GHC.Internal.IO.Exception.cannotCompactMutable_closure
+ StgClosure *nonTermination_closure; // GHC.Internal.Control.Exception.Base.nonTermination_closure
+ StgClosure *nestedAtomically_closure; // GHC.Internal.Control.Exception.Base.nestedAtomically_closure
+ StgClosure *noMatchingContinuationPrompt_closure; // GHC.Internal.Control.Exception.Base.noMatchingContinuationPrompt_closure
+ StgClosure *blockedOnBadFD_closure; // GHC.Internal.Event.Thread.blockedOnBadFD_closure
+ StgClosure *runSparks_closure; // GHC.Internal.Conc.Sync.runSparks_closure
+ StgClosure *ensureIOManagerIsRunning_closure; // GHC.Internal.Conc.IO.ensureIOManagerIsRunning_closure
+ StgClosure *interruptIOManager_closure; // GHC.Internal.Conc.IO.interruptIOManager_closure
+ StgClosure *ioManagerCapabilitiesChanged_closure; // GHC.Internal.Conc.IO.ioManagerCapabilitiesChanged_closure
+ StgClosure *runHandlersPtr_closure; // GHC.Internal.Conc.Signal.runHandlersPtr_closure
+ StgClosure *flushStdHandles_closure; // GHC.Internal.TopHandler.flushStdHandles_closure
+ StgClosure *runMainIO_closure; // GHC.Internal.TopHandler.runMainIO_closure
+ StgInfoTable *Czh_con_info; // GHC.Internal.Types.Czh_con_info
+ StgInfoTable *Izh_con_info; // GHC.Internal.Types.Izh_con_info
+ StgInfoTable *Fzh_con_info; // GHC.Internal.Types.Fzh_con_info
+ StgInfoTable *Dzh_con_info; // GHC.Internal.Types.Dzh_con_info
+ StgInfoTable *Wzh_con_info; // GHC.Internal.Types.Wzh_con_info
+ StgClosure *absentSumFieldError_closure; // GHC.Internal.Prim.Panic.absentSumFieldError_closure
+ StgClosure *runAllocationLimitHandler_closure; // GHC.Internal.AllocationLimitHandler.runAllocationLimitHandler_closure
+ StgInfoTable *Ptr_con_info; // GHC.Internal.Ptr.Ptr_con_info
+ StgInfoTable *FunPtr_con_info; // GHC.Internal.Ptr.FunPtr_con_info
+ StgInfoTable *I8zh_con_info; // GHC.Internal.Int.I8zh_con_info
+ StgInfoTable *I16zh_con_info; // GHC.Internal.Int.I16zh_con_info
+ StgInfoTable *I32zh_con_info; // GHC.Internal.Int.I32zh_con_info
+ StgInfoTable *I64zh_con_info; // GHC.Internal.Int.I64zh_con_info
+ StgInfoTable *W8zh_con_info; // GHC.Internal.Word.W8zh_con_info
+ StgInfoTable *W16zh_con_info; // GHC.Internal.Word.W16zh_con_info
+ StgInfoTable *W32zh_con_info; // GHC.Internal.Word.W32zh_con_info
+ StgInfoTable *W64zh_con_info; // GHC.Internal.Word.W64zh_con_info
+ StgInfoTable *StablePtr_con_info; // GHC.Internal.Stable.StablePtr_con_info
+ StgClosure *StackSnapshot_closure; // GHC.Internal.Stack.CloneStack.StackSnapshot_closure
+ StgClosure *divZZeroException_closure; // GHC.Internal.Exception.Type.divZeroException_closure
+ StgClosure *underflowException_closure; // GHC.Internal.Exception.Type.underflowException_closure
+ StgClosure *overflowException_closure; // GHC.Internal.Exception.Type.overflowException_closure
+ StgClosure *unpackCStringzh_closure; // GHC.Internal.CString.unpackCStringzh_closure
+ StgInfoTable *unpackCStringzh_info; // GHC.Internal.CString.unpackCStringzh_info
+ StgInfoTable *unpackCStringUtf8zh_info; // GHC.Internal.CString.unpackCStringUtf8zh_info
+} HsIface;
+
+extern const HsIface *ghc_hs_iface;
=====================================
rts/include/stg/MiscClosures.h
=====================================
@@ -277,8 +277,8 @@ RTS_ENTRY(stg_NO_FINALIZER);
extern StgWordArray stg_CHARLIKE_closure;
extern StgWordArray stg_INTLIKE_closure;
#else
-extern StgIntCharlikeClosure stg_CHARLIKE_closure[];
-extern StgIntCharlikeClosure stg_INTLIKE_closure[];
+extern StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+extern StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
#endif
/* StgStartup */
=====================================
rts/posix/Signals.c
=====================================
@@ -222,7 +222,7 @@ ioManagerDie (void)
void
ioManagerStartCap (Capability **cap)
{
- rts_evalIO(cap,&ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure,NULL);
+ rts_evalIO(cap,ensureIOManagerIsRunning_closure,NULL);
}
void
@@ -493,7 +493,7 @@ startSignalHandlers(Capability *cap)
RtsFlags.GcFlags.initialStkSize,
rts_apply(cap,
rts_apply(cap,
- &ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure,
+ runHandlersPtr_closure,
rts_mkPtr(cap, info)),
rts_mkInt(cap, info->si_signo)));
scheduleThread(cap, t);
=====================================
rts/rts.cabal
=====================================
@@ -334,6 +334,7 @@ library
rts/storage/InfoTables.h
rts/storage/MBlock.h
rts/storage/TSO.h
+ rts/RtsToHsIface.h
stg/MachRegs.h
stg/MachRegs/arm32.h
stg/MachRegs/arm64.h
@@ -403,6 +404,7 @@ library
adjustor/AdjustorPool.c
ExecPage.c
Arena.c
+ BuiltinClosures.c
Capability.c
CheckUnload.c
CheckVectorSupport.c
@@ -448,6 +450,7 @@ library
RtsStartup.c
RtsSymbolInfo.c
RtsSymbols.c
+ RtsToHsIface.c
RtsUtils.c
STM.c
Schedule.c
=====================================
rts/wasm/JSFFI.c
=====================================
@@ -23,8 +23,8 @@ int __main_argc_argv(int argc, char *argv[]) {
hs_init_ghc(&argc, &argv, __conf);
// See Note [threadDelay on wasm] for details.
rts_JSFFI_flag = HS_BOOL_TRUE;
- getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
- rts_threadDelay_impl = getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->raiseJSException_closure);
+ rts_threadDelay_impl = getStablePtr((StgPtr)ghc_hs_iface->threadDelay_closure);
return 0;
}
@@ -112,7 +112,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
SET_HDR(w, &stg_WEAK_info, CCS_SYSTEM);
w->cfinalizers = (StgClosure *)cfin;
w->key = p;
- w->value = Unit_closure;
+ w->value = ghc_hs_iface->Z0T_closure;
w->finalizer = &stg_NO_FINALIZER_closure;
w->link = cap->weak_ptr_list_hd;
cap->weak_ptr_list_hd = w;
@@ -123,7 +123,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
p->payload[0] = (HaskellObj)w;
HaskellObj box = (HaskellObj)allocate(cap, CONSTR_sizeW(1, 0));
- SET_HDR(box, &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info, CCS_SYSTEM);
+ SET_HDR(box, ghc_hs_iface->JSVal_con_info, CCS_SYSTEM);
box->payload[0] = p;
return TAG_CLOSURE(1, box);
@@ -139,7 +139,7 @@ STATIC_INLINE HsJSVal rts_getJSValzh(HaskellObj p) {
HsJSVal rts_getJSVal(HaskellObj);
HsJSVal rts_getJSVal(HaskellObj box) {
- ASSERT(UNTAG_CLOSURE(box)->header.info == &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info);
+ ASSERT(UNTAG_CLOSURE(box)->header.info == ghc_hs_iface->JSVal_con_info);
return rts_getJSValzh(UNTAG_CLOSURE(box)->payload[0]);
}
@@ -188,7 +188,7 @@ void rts_schedulerLoop(void) {
__attribute__((export_name("rts_promiseResolveUnit")))
void rts_promiseResolveUnit(HsStablePtr);
void rts_promiseResolveUnit(HsStablePtr sp)
- mk_rtsPromiseCallback(TAG_CLOSURE(1, Unit_closure))
+ mk_rtsPromiseCallback(TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure))
mk_rtsPromiseResolve(JSVal)
mk_rtsPromiseResolve(Char)
@@ -212,7 +212,7 @@ mk_rtsPromiseResolve(Bool)
__attribute__((export_name("rts_promiseReject")))
void rts_promiseReject(HsStablePtr, HsJSVal);
void rts_promiseReject(HsStablePtr sp, HsJSVal js_err)
- mk_rtsPromiseCallback(rts_apply(cap, &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure, rts_mkJSVal(cap, js_err)))
+ mk_rtsPromiseCallback(rts_apply(cap, ghc_hs_iface->raiseJSException_closure, rts_mkJSVal(cap, js_err)))
__attribute__((export_name("rts_promiseThrowTo")))
void rts_promiseThrowTo(HsStablePtr, HsJSVal);
@@ -229,7 +229,7 @@ void rts_promiseThrowTo(HsStablePtr sp, HsJSVal js_err) {
cap, tso,
rts_apply(
cap,
- &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure,
+ ghc_hs_iface->raiseJSException_closure,
rts_mkJSVal(cap, js_err)));
tryWakeupThread(cap, tso);
rts_schedulerLoop();
=====================================
utils/deriveConstants/Main.hs
=====================================
@@ -667,6 +667,59 @@ wanteds os = concat
,structField C "StgAsyncIOResult" "errCode"]
else []
+ -- struct HsIface
+ ,structField C "HsIface" "processRemoteCompletion_closure"
+ ,structField C "HsIface" "runIO_closure"
+ ,structField C "HsIface" "runNonIO_closure"
+ ,structField C "HsIface" "Z0T_closure"
+ ,structField C "HsIface" "True_closure"
+ ,structField C "HsIface" "False_closure"
+ ,structField C "HsIface" "unpackCString_closure"
+ ,structField C "HsIface" "runFinalizzerBatch_closure"
+ ,structField C "HsIface" "stackOverflow_closure"
+ ,structField C "HsIface" "heapOverflow_closure"
+ ,structField C "HsIface" "allocationLimitExceeded_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnMVar_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnSTM_closure"
+ ,structField C "HsIface" "cannotCompactFunction_closure"
+ ,structField C "HsIface" "cannotCompactPinned_closure"
+ ,structField C "HsIface" "cannotCompactMutable_closure"
+ ,structField C "HsIface" "nonTermination_closure"
+ ,structField C "HsIface" "nestedAtomically_closure"
+ ,structField C "HsIface" "noMatchingContinuationPrompt_closure"
+ ,structField C "HsIface" "blockedOnBadFD_closure"
+ ,structField C "HsIface" "runSparks_closure"
+ ,structField C "HsIface" "ensureIOManagerIsRunning_closure"
+ ,structField C "HsIface" "interruptIOManager_closure"
+ ,structField C "HsIface" "ioManagerCapabilitiesChanged_closure"
+ ,structField C "HsIface" "runHandlersPtr_closure"
+ ,structField C "HsIface" "flushStdHandles_closure"
+ ,structField C "HsIface" "runMainIO_closure"
+ ,structField C "HsIface" "Czh_con_info"
+ ,structField C "HsIface" "Izh_con_info"
+ ,structField C "HsIface" "Fzh_con_info"
+ ,structField C "HsIface" "Dzh_con_info"
+ ,structField C "HsIface" "Wzh_con_info"
+ ,structField C "HsIface" "runAllocationLimitHandler_closure"
+ ,structField C "HsIface" "Ptr_con_info"
+ ,structField C "HsIface" "FunPtr_con_info"
+ ,structField C "HsIface" "I8zh_con_info"
+ ,structField C "HsIface" "I16zh_con_info"
+ ,structField C "HsIface" "I32zh_con_info"
+ ,structField C "HsIface" "I64zh_con_info"
+ ,structField C "HsIface" "W8zh_con_info"
+ ,structField C "HsIface" "W16zh_con_info"
+ ,structField C "HsIface" "W32zh_con_info"
+ ,structField C "HsIface" "W64zh_con_info"
+ ,structField C "HsIface" "StablePtr_con_info"
+ ,structField C "HsIface" "StackSnapshot_closure"
+ ,structField C "HsIface" "divZZeroException_closure"
+ ,structField C "HsIface" "underflowException_closure"
+ ,structField C "HsIface" "overflowException_closure"
+ ,structField C "HsIface" "unpackCStringzh_closure"
+ ,structField C "HsIface" "unpackCStringzh_info"
+ ,structField C "HsIface" "unpackCStringUtf8zh_info"
+
-- pre-compiled thunk types
,constantWord Haskell "MAX_SPEC_SELECTEE_SIZE" "MAX_SPEC_SELECTEE_SIZE"
,constantWord Haskell "MAX_SPEC_AP_SIZE" "MAX_SPEC_AP_SIZE"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/25f24794255333130290c9c83225ab…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/25f24794255333130290c9c83225ab…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T23162-spj] 25 commits: Allow disabling builtin rules (#20298)
by Simon Peyton Jones (@simonpj) 26 Sep '25
by Simon Peyton Jones (@simonpj) 26 Sep '25
26 Sep '25
Simon Peyton Jones pushed to branch wip/T23162-spj at Glasgow Haskell Compiler / GHC
Commits:
5ae89054 by Sylvain Henry at 2025-09-24T17:07:00-04:00
Allow disabling builtin rules (#20298)
Add a way to disable built-in rules programmatically and with a debug flag.
I also took the opportunity to add a debug flag to disable bignum rules,
which was only possible programmatically (e.g. in a plugin).
- - - - -
135242ca by Rodrigo Mesquita at 2025-09-24T17:07:44-04:00
Don't use build CFLAGS and friends as target settings
In the GHC in tree configure, `CFLAGS`, `CXXFLAGS`, and similar tool
configuration flags apply to the BUILD phase of the compiler, i.e. to
the tools run to compile GHC itself.
Notably, they should /not/ be carried over to the Target settings, i.e.
these flags should /not/ apply to the tool which GHC invokes at runtime.
Fixes #25637
- - - - -
b418408b by Irene Knapp at 2025-09-25T09:47:54-04:00
Document etymology of "bind" as the name for `>>=`
It took me twenty years of contemplation to realize why it's called that.
I therefore feel that it may not be obvious to beginners.
- - - - -
e9c5e46f by Brandon Chinn at 2025-09-25T09:48:36-04:00
Fix tabs in string gaps (#26415)
Tabs in string gaps were broken in bb030d0d because previously, string gaps were manually parsed, but now it's lexed by the usual Alex grammar and post-processed after successful lexing.
It broke because of a discrepancy between GHC's lexer grammar and the Haskell Report. The Haskell Report includes tabs in whitechar:
whitechar → newline | vertab | space | tab | uniWhite
$whitechar used to include tabs until 18 years ago, when it was removed in order to exclude tabs from $white_no_nl in order to warn on tabs: 6e202120. In this MR, I'm adding \t back into $whitechar, and explicitly excluding \t from the $white_no_nl+ rule ignoring all whitespace in source code, which more accurately colocates the "ignore all whitespace except tabs, which is handled in the next line" logic.
As a side effect of this MR, tabs are now allowed in pragmas; currently, a pragma written as {-# \t LANGUAGE ... #-} is interpreted as the tab character being the pragma name, and GHC warns "Unrecognized pragma". With this change, tabs are ignored as whitespace, which more closely matches the Report anyway.
- - - - -
8bf5b309 by Cheng Shao at 2025-09-25T09:49:18-04:00
wasm: remove the --no-turbo-fast-api-calls hack from dynamic linker shebang
This patch removes the `--no-turbo-fast-api-calls` hack from the dyld
script shebang; it was used to workaround v8 fast call coredumps in
nodejs and no longer needed, and comes with a performance penalty,
hence the removal.
- - - - -
f0aa9041 by Richard Eisenberg at 2025-09-26T17:16:01+01:00
Move some fundep solving to new spot
Work in progress...[skip ci]
This completes moving dict fundeps to the main loop
We need wanted/wanted fundeps too
...and some other refactors
Wibbles
Make FunDeps into a new module
Solve new_eqs rather than adding them to WantedConstraints
Wibble
Import wibbles
Comments only [skip ci]
WIP on FunDeps [skip ci]
Work in progress [skip ci]
More WIP
Wibbles to fundeps [skip ci]
Kill off kickOutAfterUnification
More wibbles
Need to remove the unification-count stuff entirely
and do more tidying up -- this commit is mainly for CI
Wibbles solver
Iterate the simples more often than plugins
Start to extend to equalities
Whitespace only
Small improvements
Wibbles
- - - - -
d5cc2868 by Simon Peyton Jones at 2025-09-26T17:16:01+01:00
Improved error messages from fundep changes
- - - - -
8613cbba by Simon Peyton Jones at 2025-09-26T17:16:01+01:00
Wibbles
- - - - -
c949c8be by Simon Peyton Jones at 2025-09-26T17:16:01+01:00
Fix typo
- - - - -
c39db9b6 by Simon Peyton Jones at 2025-09-26T17:16:01+01:00
Wibbles
- - - - -
21df47fe by Simon Peyton Jones at 2025-09-26T17:16:01+01:00
Nuke FunDepOrigin1 and 2
- - - - -
15254924 by Simon Peyton Jones at 2025-09-26T17:16:01+01:00
Wibble
- - - - -
92dd9ead by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
More refactoring
- - - - -
df72a283 by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
More tidying up
- - - - -
4993153d by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
Yet more
- - - - -
2656dc08 by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
Wibbles
- - - - -
9a96f472 by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
Wibbles [skip ci]
- - - - -
6d560e2b by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
Naming and comments only [skip ci]
- - - - -
0a4f786e by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
Progress [skip ci]x
- - - - -
c41b5938 by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
Make it compile
.. with now story on WhatUnifications
- - - - -
b3dd75a1 by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
Stop putting QLInstVar into the tc_lvl environment [skip ci]
This is really a bug! See (TCAPP2)
Not done yet
- - - - -
6a5eb4a9 by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
Now it compiles
- - - - -
ea57abeb by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
Accept error message changes
Plus compile time improvement
Metrics: compile_time/bytes allocated
Baseline
Test value New value Change
---------------------- --------------------------------------
T5030(normal) 173,839,232 148,115,248 -14.8% GOOD
hard_hole_fits(normal) 286,768,048 284,015,416 -1.0%
geo. mean -0.2%
minimum -14.8%
maximum +0.3%
Metric Decrease:
T5030
- - - - -
69eec23e by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
QuickLook's tcInstFun should make instantiation variables directly
tcInstFun must make "instantiation variables", not regular
unification variables, when instantiating function types. That was
previously implemented by a hack: set the /ambient/ level to QLInstTyVar.
But the hack finally bit me, when I was refactoring WhatUnifications.
And it was always wrong: see the now-expunged (TCAPP2) note.
This commit does it right, by making tcInstFun call its own
instantiation functions. That entails a small bit of duplication,
but the result is much, much cleaner.
- - - - -
7c68ae04 by Simon Peyton Jones at 2025-09-26T17:16:02+01:00
Wibbles
- - - - -
80 changed files:
- compiler/GHC/Core/Opt/ConstantFold.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/Rules/Config.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Driver/Config/Core/Rules.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/Lexer/String.x
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Instance/FunDeps.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- + compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Zonk/TcType.hs
- compiler/GHC/Types/Basic.hs
- compiler/ghc.cabal.in
- configure.ac
- docs/users_guide/debugging.rst
- libraries/ghc-internal/src/GHC/Internal/Base.hs
- m4/fp_setup_windows_toolchain.m4
- m4/ghc_toolchain.m4
- + testsuite/tests/codeGen/should_compile/T20298a.hs
- + testsuite/tests/codeGen/should_compile/T20298a.stderr
- + testsuite/tests/codeGen/should_compile/T20298b.hs
- + testsuite/tests/codeGen/should_compile/T20298b.stderr
- + testsuite/tests/codeGen/should_compile/T20298c.hs
- + testsuite/tests/codeGen/should_compile/T20298c.stderr
- testsuite/tests/codeGen/should_compile/all.T
- testsuite/tests/default/default-fail05.stderr
- testsuite/tests/dependent/should_fail/T13135_simple.stderr
- testsuite/tests/deriving/should_fail/T3621.stderr
- testsuite/tests/indexed-types/should_fail/T14369.stderr
- testsuite/tests/indexed-types/should_fail/T1897b.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail10.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail13.stderr
- testsuite/tests/parser/should_fail/T20654a.stderr
- + testsuite/tests/parser/should_run/T26415.hs
- + testsuite/tests/parser/should_run/T26415.stdout
- testsuite/tests/parser/should_run/all.T
- testsuite/tests/polykinds/T6068.stdout
- testsuite/tests/rep-poly/RepPolyRightSection.stderr
- testsuite/tests/typecheck/should_compile/T13651.hs
- − testsuite/tests/typecheck/should_compile/T13651.stderr
- + testsuite/tests/typecheck/should_compile/T14745.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/tc126.hs
- testsuite/tests/typecheck/should_fail/AmbigFDs.hs
- − testsuite/tests/typecheck/should_fail/AmbigFDs.stderr
- testsuite/tests/typecheck/should_fail/FD3.stderr
- testsuite/tests/typecheck/should_fail/FDsFromGivens2.stderr
- testsuite/tests/typecheck/should_fail/T13506.stderr
- testsuite/tests/typecheck/should_fail/T16512a.stderr
- testsuite/tests/typecheck/should_fail/T18851b.hs
- − testsuite/tests/typecheck/should_fail/T18851b.stderr
- testsuite/tests/typecheck/should_fail/T18851c.hs
- − testsuite/tests/typecheck/should_fail/T18851c.stderr
- testsuite/tests/typecheck/should_fail/T19415.stderr
- testsuite/tests/typecheck/should_fail/T19415b.stderr
- testsuite/tests/typecheck/should_fail/T25325.stderr
- testsuite/tests/typecheck/should_fail/T5246.stderr
- testsuite/tests/typecheck/should_fail/T5978.stderr
- testsuite/tests/typecheck/should_fail/T9612.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail143.stderr
- utils/jsffi/dyld.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e61cec2ab4aed4b049d29121d8f7db…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e61cec2ab4aed4b049d29121d8f7db…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/jeltsch/obtaining-os-handles] Add operations for obtaining operating-system handles
by Wolfgang Jeltsch (@jeltsch) 26 Sep '25
by Wolfgang Jeltsch (@jeltsch) 26 Sep '25
26 Sep '25
Wolfgang Jeltsch pushed to branch wip/jeltsch/obtaining-os-handles at Glasgow Haskell Compiler / GHC
Commits:
3570e1fe by Wolfgang Jeltsch at 2025-09-26T18:34:02+03:00
Add operations for obtaining operating-system handles
This resolves #26265.
- - - - -
7 changed files:
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- + libraries/base/src/System/IO/OS.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
Changes:
=====================================
libraries/base/base.cabal.in
=====================================
@@ -258,6 +258,7 @@ Library
, System.Exit
, System.IO
, System.IO.Error
+ , System.IO.OS
, System.Mem
, System.Mem.StableName
, System.Posix.Internals
=====================================
libraries/base/changelog.md
=====================================
@@ -7,6 +7,7 @@
* Modify the implementation of `Data.List.sortOn` to use `(>)` instead of `compare`. ([CLC proposal #332](https://github.com/haskell/core-libraries-committee/issues/332))
* `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
* Fix bug where `naturalAndNot` was incorrectly truncating results ([CLC proposal #350](github.com/haskell/core-libraries-committee/issues/350))
+ * Add a new module `System.IO.OS` with operations for obtaining operating-system handles (file descriptors, Windows handles) ([CLC proposal #369](https://github.com/haskell/core-libraries-committee/issues/369))
## 4.22.0.0 *TBA*
* Shipped with GHC 9.14.1
=====================================
libraries/base/src/System/IO/OS.hs
=====================================
@@ -0,0 +1,342 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE RankNTypes #-}
+
+{-|
+ This module bridges between Haskell handles and underlying operating-system
+ features.
+-}
+module System.IO.OS
+(
+ -- * Obtaining file descriptors and Windows handles
+ withFileDescriptorReadingBiased,
+ withFileDescriptorWritingBiased,
+ withWindowsHandleReadingBiased,
+ withWindowsHandleWritingBiased,
+ withFileDescriptorReadingBiasedRaw,
+ withFileDescriptorWritingBiasedRaw,
+ withWindowsHandleReadingBiasedRaw,
+ withWindowsHandleWritingBiasedRaw
+
+ -- ** Caveats
+ -- $with-ref-caveats
+)
+where
+
+import GHC.Internal.Control.Monad (return)
+import GHC.Internal.Control.Concurrent.MVar (MVar)
+import GHC.Internal.Control.Exception (mask)
+import GHC.Internal.Data.Function (const, (.), ($))
+import GHC.Internal.Data.Functor (fmap)
+#if defined(mingw32_HOST_OS)
+import GHC.Internal.Data.Bool (otherwise)
+#endif
+import GHC.Internal.Data.Maybe (Maybe (Nothing), maybe)
+#if defined(mingw32_HOST_OS)
+import GHC.Internal.Data.Maybe (Maybe (Just))
+#endif
+import GHC.Internal.Data.List ((++))
+import GHC.Internal.Data.String (String)
+import GHC.Internal.Data.Typeable (Typeable, cast)
+import GHC.Internal.System.IO (IO)
+import GHC.Internal.IO.FD (fdFD)
+#if defined(mingw32_HOST_OS)
+import GHC.Internal.IO.Windows.Handle
+ (
+ NativeHandle,
+ ConsoleHandle,
+ IoHandle,
+ toHANDLE
+ )
+#endif
+import GHC.Internal.IO.Handle.Types
+ (
+ Handle (FileHandle, DuplexHandle),
+ Handle__ (Handle__, haDevice)
+ )
+import GHC.Internal.IO.Handle.Internals (withHandle_', flushBuffer)
+import GHC.Internal.IO.Exception
+ (
+ IOErrorType (InappropriateType),
+ IOException (IOError),
+ ioException
+ )
+import GHC.Internal.Foreign.Ptr (Ptr)
+import GHC.Internal.Foreign.C.Types (CInt)
+
+-- * Obtaining POSIX file descriptors and Windows handles
+
+{-|
+ Executes a user-provided action on an operating-system handle that underlies
+ a Haskell handle. Before the user-provided action is run, user-defined
+ perparation based on the handle state that contains the operating-system
+ handle is performed. While the user-provided action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withOSHandle :: String
+ -- ^ The name of the overall operation
+ -> (Handle -> MVar Handle__)
+ {-^
+ Obtaining of the handle state variable that holds the
+ operating-system handle
+ -}
+ -> (forall d. Typeable d => d -> IO a)
+ -- ^ Conversion of a device into an operating-system handle
+ -> (Handle__ -> IO ())
+ -- ^ The preparation
+ -> Handle
+ -- ^ The Haskell handle to use
+ -> (a -> IO r)
+ -- ^ The action to execute on the operating-system handle
+ -> IO r
+withOSHandle opName handleStateVar getOSHandle prepare handle act
+ = mask $ \ withOriginalMaskingState ->
+ withHandleState $ \ handleState@Handle__ {haDevice = dev} -> do
+ osHandle <- getOSHandle dev
+ prepare handleState
+ withOriginalMaskingState $ act osHandle
+ where
+
+ withHandleState = withHandle_' opName handle (handleStateVar handle)
+{-
+ The 'withHandle_'' operation, which we use here, already performs masking.
+ Still, we have to employ 'mask', in order do obtain the operation that
+ restores the original masking state. The user-provided action should be
+ executed with this original masking state, as there is no inherent reason to
+ generally perform it with masking in place. The masking that 'withHandle_''
+ performs is only for safely accessing handle state and thus constitutes an
+ implementation detail; it has nothing to do with the user-provided action.
+-}
+{-
+ The order of actions in 'withOSHandle' is such that any exception from
+ 'getOSHandle' is thrown before the flushing of the Haskell-managed buffers.
+-}
+
+{-|
+ Obtains the handle state variable that underlies a handle or specifically
+ the handle state variable for reading if the handle uses different state
+ variables for reading and writing.
+-}
+handleStateVarReadingBiased :: Handle -> MVar Handle__
+handleStateVarReadingBiased (FileHandle _ var) = var
+handleStateVarReadingBiased (DuplexHandle _ readingVar _) = readingVar
+
+{-|
+ Obtains the handle state variable that underlies a handle or specifically
+ the handle state variable for writing if the handle uses different state
+ variables for reading and writing.
+-}
+handleStateVarWritingBiased :: Handle -> MVar Handle__
+handleStateVarWritingBiased (FileHandle _ var) = var
+handleStateVarWritingBiased (DuplexHandle _ _ writingVar) = writingVar
+
+{-|
+ Yields the result of another operation if that operation succeeded, and
+ otherwise throws an exception that signals that the other operation failed
+ because some Haskell handle does not use an operating-system handle of a
+ required type.
+-}
+requiringOSHandleOfType :: String
+ -- ^ The name of the operating-system handle type
+ -> Maybe a
+ {-^
+ The result of the other operation if it succeeded
+ -}
+ -> IO a
+requiringOSHandleOfType osHandleTypeName
+ = maybe (ioException osHandleOfTypeRequired) return
+ where
+
+ osHandleOfTypeRequired :: IOException
+ osHandleOfTypeRequired
+ = IOError Nothing
+ InappropriateType
+ ""
+ ("handle does not use " ++ osHandleTypeName ++ "s")
+ Nothing
+ Nothing
+
+{-|
+ Obtains the POSIX file descriptor of a device if the device contains one,
+ and throws an exception otherwise.
+-}
+getFileDescriptor :: Typeable d => d -> IO CInt
+getFileDescriptor = requiringOSHandleOfType "POSIX file descriptor" .
+ fmap fdFD . cast
+
+{-|
+ Obtains the Windows handle of a device if the device contains one, and
+ throws an exception otherwise.
+-}
+getWindowsHandle :: Typeable d => d -> IO (Ptr ())
+getWindowsHandle = requiringOSHandleOfType "Windows handle" .
+ toMaybeWindowsHandle
+ where
+
+ toMaybeWindowsHandle :: Typeable d => d -> Maybe (Ptr ())
+#if defined(mingw32_HOST_OS)
+ toMaybeWindowsHandle dev
+ | Just nativeHandle <- cast dev :: Maybe (IoHandle NativeHandle)
+ = Just (toHANDLE nativeHandle)
+ | Just consoleHandle <- cast dev :: Maybe (IoHandle ConsoleHandle)
+ = Just (toHANDLE consoleHandle)
+ | otherwise
+ = Nothing
+ {-
+ This is inspired by the implementation of
+ 'System.Win32.Types.withHandleToHANDLENative'.
+ -}
+#else
+ toMaybeWindowsHandle _ = Nothing
+#endif
+
+{-|
+ Executes a user-provided action on the POSIX file descriptor that underlies
+ a handle or specifically on the POSIX file descriptor for reading if the
+ handle uses different file descriptors for reading and writing. The
+ Haskell-managed buffers related to the file descriptor are flushed before
+ the user-provided action is run. While this action is executed, further
+ operations on the handle are blocked to a degree that interference with this
+ action is prevented.
+
+ If the handle does not use POSIX file descriptors, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withFileDescriptorReadingBiased :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorReadingBiased = withOSHandle "withFileDescriptorReadingBiased"
+ handleStateVarReadingBiased
+ getFileDescriptor
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the POSIX file descriptor that underlies
+ a handle or specifically on the POSIX file descriptor for writing if the
+ handle uses different file descriptors for reading and writing. The
+ Haskell-managed buffers related to the file descriptor are flushed before
+ the user-provided action is run. While this action is executed, further
+ operations on the handle are blocked to a degree that interference with this
+ action is prevented.
+
+ If the handle does not use POSIX file descriptors, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withFileDescriptorWritingBiased :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorWritingBiased = withOSHandle "withFileDescriptorWritingBiased"
+ handleStateVarWritingBiased
+ getFileDescriptor
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the Windows handle that underlies a
+ Haskell handle or specifically on the Windows handle for reading if the
+ Haskell handle uses different Windows handles for reading and writing. The
+ Haskell-managed buffers related to the Windows handle are flushed before the
+ user-provided action is run. While this action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ If the Haskell handle does not use Windows handles, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withWindowsHandleReadingBiased :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleReadingBiased = withOSHandle "withWindowsHandleReadingBiased"
+ handleStateVarReadingBiased
+ getWindowsHandle
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the Windows handle that underlies a
+ Haskell handle or specifically on the Windows handle for writing if the
+ Haskell handle uses different Windows handles for reading and writing. The
+ Haskell-managed buffers related to the Windows handle are flushed before the
+ user-provided action is run. While this action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ If the Haskell handle does not use Windows handles, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withWindowsHandleWritingBiased :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleWritingBiased = withOSHandle "withWindowsHandleWritingBiased"
+ handleStateVarWritingBiased
+ getWindowsHandle
+ flushBuffer
+
+{-|
+ Like 'withFileDescriptorReadingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withFileDescriptorReadingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorReadingBiasedRaw
+ = withOSHandle "withFileDescriptorReadingBiasedRaw"
+ handleStateVarReadingBiased
+ getFileDescriptor
+ (const $ return ())
+
+{-|
+ Like 'withFileDescriptorWritingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withFileDescriptorWritingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorWritingBiasedRaw
+ = withOSHandle "withFileDescriptorWritingBiasedRaw"
+ handleStateVarWritingBiased
+ getFileDescriptor
+ (const $ return ())
+
+{-|
+ Like 'withWindowsHandleReadingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withWindowsHandleReadingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleReadingBiasedRaw
+ = withOSHandle "withWindowsHandleReadingBiasedRaw"
+ handleStateVarReadingBiased
+ getWindowsHandle
+ (const $ return ())
+
+{-|
+ Like 'withWindowsHandleWritingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withWindowsHandleWritingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleWritingBiasedRaw
+ = withOSHandle "withWindowsHandleWritingBiasedRaw"
+ handleStateVarWritingBiased
+ getWindowsHandle
+ (const $ return ())
+
+-- ** Caveats
+
+{-$with-ref-caveats
+ #with-ref-caveats#There are the following caveats regarding the above
+ operations:
+
+ * Flushing of buffers can fail if the given handle is readable but not
+ seekable.
+
+ * If one of these operations is performed as part of an action executed by
+ 'System.IO.Unsafe.unsafePerformIO',
+ 'System.IO.Unsafe.unsafeInterleaveIO', or one of their “dupable”
+ variants and the user-provided action receives an asychnchronous
+ exception and does not catch it, then the following happens:
+
+ - Before the overall computation is suspended, the blocking of handle
+ operations is removed.
+
+ - When the computation is later resumed due to another evaluation
+ attempt, the blocking of handle operations is reinstantiated, the
+ Haskell-managed buffers are flushed again, and the user-provided
+ action is run from the beginning.
+
+ Repeating the previously executed part of the user-provided action
+ cannot be avoided apparently. See the @[async]@ note in the source code
+ of "GHC.Internal.IO.Handle.Internals" for further explanation.
+-}
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -10373,6 +10373,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -13419,6 +13419,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -10653,6 +10653,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
=====================================
testsuite/tests/interface-stability/base-exports.stdout-ws-32
=====================================
@@ -10373,6 +10373,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3570e1fe238ed6c77255b9042d108e9…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3570e1fe238ed6c77255b9042d108e9…
You're receiving this email because of your account on gitlab.haskell.org.
1
0