Skip to content

Commit 03b3557

Browse files
committed
fix #12444 (add magic and format version to beginning of .ji files)
1 parent 339033f commit 03b3557

File tree

6 files changed

+97
-12
lines changed

6 files changed

+97
-12
lines changed

base/loading.jl

+10-8
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ function _require_from_serialized(node::Int, path_to_try::ByteString, toplevel_l
8484
restored = _include_from_serialized(content)
8585
end
8686
# otherwise, continue search
87+
88+
if restored !== nothing
89+
for M in restored
90+
if isdefined(M, :__META__)
91+
push!(Base.Docs.modules, M)
92+
end
93+
end
94+
end
8795
return restored
8896
end
8997

@@ -119,14 +127,8 @@ function require(mod::Symbol)
119127
last = toplevel_load::Bool
120128
try
121129
toplevel_load = false
122-
restored = _require_from_serialized(1, mod, last)
123-
if restored !== nothing
124-
for M in restored
125-
if isdefined(M, :__META__)
126-
push!(Base.Docs.modules, M)
127-
end
128-
end
129-
return true
130+
if nothing !== _require_from_serialized(1, mod, last)
131+
return
130132
end
131133
if JLOptions().incremental != 0
132134
# spawn off a new incremental compile task from node 1 for recursive `require` calls

src/dump.c

+45-1
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,25 @@ void jl_serialize_mod_list(ios_t *s)
949949
write_int32(s, 0);
950950
}
951951

952+
// "magic" string and version header of .ji file
953+
static const int JI_FORMAT_VERSION = 0;
954+
static const char JI_MAGIC[] = "\373jli\r\n\032\n"; // based on PNG signature
955+
static const uint16_t BOM = 0xFEFF; // byte-order marker
956+
static void jl_serialize_header(ios_t *s)
957+
{
958+
ios_write(s, JI_MAGIC, strlen(JI_MAGIC));
959+
write_uint16(s, JI_FORMAT_VERSION);
960+
ios_write(s, (char *) &BOM, 2);
961+
write_uint8(s, sizeof(void*));
962+
const char *OS_NAME = jl_get_OS_NAME()->name, *ARCH = jl_get_ARCH()->name;
963+
ios_write(s, OS_NAME, strlen(OS_NAME)+1);
964+
ios_write(s, ARCH, strlen(ARCH)+1);
965+
ios_write(s, JULIA_VERSION_STRING, strlen(JULIA_VERSION_STRING)+1);
966+
const char *branch = jl_git_branch(), *commit = jl_git_commit();
967+
ios_write(s, branch, strlen(branch)+1);
968+
ios_write(s, commit, strlen(commit)+1);
969+
}
970+
952971
// --- deserialize ---
953972

954973
static jl_fptr_t jl_deserialize_fptr(ios_t *s)
@@ -1525,6 +1544,29 @@ int jl_deserialize_verify_mod_list(ios_t *s)
15251544
}
15261545
}
15271546

1547+
static int readstr_verify(ios_t *s, const char *str)
1548+
{
1549+
size_t len = strlen(str);
1550+
for (size_t i=0; i < len; ++i)
1551+
if ((char) read_uint8(s) != str[i])
1552+
return 0;
1553+
return 1;
1554+
}
1555+
1556+
static int jl_deserialize_header(ios_t *s)
1557+
{
1558+
uint16_t bom;
1559+
return (readstr_verify(s, JI_MAGIC) &&
1560+
read_uint16(s) == JI_FORMAT_VERSION &&
1561+
ios_read(s, (char *) &bom, 2) == 2 && bom == BOM &&
1562+
read_uint8(s) == sizeof(void*) &&
1563+
readstr_verify(s, jl_get_OS_NAME()->name) && !read_uint8(s) &&
1564+
readstr_verify(s, jl_get_ARCH()->name) && !read_uint8(s) &&
1565+
readstr_verify(s, JULIA_VERSION_STRING) && !read_uint8(s) &&
1566+
readstr_verify(s, jl_git_branch()) && !read_uint8(s) &&
1567+
readstr_verify(s, jl_git_commit()) && !read_uint8(s));
1568+
}
1569+
15281570
jl_array_t *jl_module_init_order;
15291571

15301572
static void jl_finalize_serializer(ios_t *f) {
@@ -1892,6 +1934,7 @@ DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist)
18921934
return 1;
18931935
}
18941936
serializer_worklist = worklist;
1937+
jl_serialize_header(&f);
18951938
jl_serialize_mod_list(&f); // this can throw, keep it early (before any actual initialization)
18961939

18971940
JL_SIGATOMIC_BEGIN();
@@ -1933,7 +1976,8 @@ static jl_array_t *_jl_restore_incremental(ios_t *f)
19331976
ios_close(f);
19341977
return NULL;
19351978
}
1936-
if (!jl_deserialize_verify_mod_list(f)) {
1979+
if (!jl_deserialize_header(f) ||
1980+
!jl_deserialize_verify_mod_list(f)) {
19371981
ios_close(f);
19381982
return NULL;
19391983
}

src/jlapi.c

+25-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ DLLEXPORT void jl_yield()
203203
jl_call0(yieldfunc);
204204
}
205205

206-
DLLEXPORT jl_value_t *jl_get_field(jl_value_t *o, char *fld)
206+
DLLEXPORT jl_value_t *jl_get_field(jl_value_t *o, const char *fld)
207207
{
208208
jl_value_t *v;
209209
JL_TRY {
@@ -279,6 +279,30 @@ DLLEXPORT const char* jl_ver_string(void)
279279
return JULIA_VERSION_STRING;
280280
}
281281

282+
// return char* from ByteString field in Base.GIT_VERSION_INFO
283+
static const char *git_info_string(const char *fld) {
284+
static jl_value_t *GIT_VERSION_INFO = NULL;
285+
if (!GIT_VERSION_INFO)
286+
GIT_VERSION_INFO = jl_get_global(jl_base_module, jl_symbol("GIT_VERSION_INFO"));
287+
jl_value_t *f = jl_get_field(GIT_VERSION_INFO, fld);
288+
assert(jl_is_byte_string(f));
289+
return jl_string_data(f);
290+
}
291+
292+
DLLEXPORT const char *jl_git_branch()
293+
{
294+
const char *branch = NULL;
295+
if (!branch) branch = git_info_string("branch");
296+
return branch;
297+
}
298+
299+
DLLEXPORT const char *jl_git_commit()
300+
{
301+
const char *commit = NULL;
302+
if (!commit) commit = git_info_string("commit");
303+
return commit;
304+
}
305+
282306
// Create function versions of some useful macros
283307
#undef jl_astaggedvalue
284308
DLLEXPORT jl_taggedvalue_t *jl_astaggedvalue(jl_value_t *v)

src/julia.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ DLLEXPORT jl_value_t *jl_get_nth_field(jl_value_t *v, size_t i);
977977
DLLEXPORT jl_value_t *jl_get_nth_field_checked(jl_value_t *v, size_t i);
978978
DLLEXPORT void jl_set_nth_field(jl_value_t *v, size_t i, jl_value_t *rhs);
979979
DLLEXPORT int jl_field_isdefined(jl_value_t *v, size_t i);
980-
DLLEXPORT jl_value_t *jl_get_field(jl_value_t *o, char *fld);
980+
DLLEXPORT jl_value_t *jl_get_field(jl_value_t *o, const char *fld);
981981
DLLEXPORT jl_value_t *jl_value_ptr(jl_value_t *a);
982982

983983
// arrays
@@ -1073,6 +1073,8 @@ DLLEXPORT int jl_cpu_cores(void);
10731073
DLLEXPORT long jl_getpagesize(void);
10741074
DLLEXPORT long jl_getallocationgranularity(void);
10751075
DLLEXPORT int jl_is_debugbuild(void);
1076+
DLLEXPORT jl_sym_t* jl_get_OS_NAME();
1077+
DLLEXPORT jl_sym_t* jl_get_ARCH();
10761078

10771079
// environment entries
10781080
DLLEXPORT jl_value_t *jl_environ(int i);
@@ -1569,6 +1571,8 @@ DLLEXPORT extern int jl_ver_minor(void);
15691571
DLLEXPORT extern int jl_ver_patch(void);
15701572
DLLEXPORT extern int jl_ver_is_release(void);
15711573
DLLEXPORT extern const char* jl_ver_string(void);
1574+
DLLEXPORT const char *jl_git_branch();
1575+
DLLEXPORT const char *jl_git_commit();
15721576

15731577
// nullable struct representations
15741578
typedef struct {

src/sys.c

+8
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,14 @@ DLLEXPORT jl_sym_t* jl_get_OS_NAME()
731731
#endif
732732
}
733733

734+
DLLEXPORT jl_sym_t* jl_get_ARCH()
735+
{
736+
static jl_sym_t* ARCH = NULL;
737+
if (!ARCH)
738+
ARCH = (jl_sym_t*) jl_get_global(jl_base_module, jl_symbol("ARCH"));
739+
return ARCH;
740+
}
741+
734742
#ifdef __cplusplus
735743
}
736744
#endif

test/compile.jl

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ try
2121
end
2222

2323
Base.compile(Foo_module)
24-
eval(Main, :(import $Foo_module))
24+
25+
# use _require_from_serialized to ensure that the test fails if
26+
# the module doesn't load from the image:
27+
@test nothing !== Base._require_from_serialized(myid(), Foo_module, true)
2528
finally
2629
splice!(Base.LOAD_CACHE_PATH, 1)
2730
splice!(LOAD_PATH, 1)

0 commit comments

Comments
 (0)