Skip to content

Commit 2b4f4e0

Browse files
committed
Replace jl_load_image_and_init with inlined logic
This makes it clearer that sysimage resolution and `jl_options` setup are the responsibility of `jl_api.c`, not the initialization system.
1 parent 8cd224e commit 2b4f4e0

File tree

7 files changed

+214
-212
lines changed

7 files changed

+214
-212
lines changed

doc/src/manual/embedding.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ linking against `libjulia`.
5454
The first thing that must be done before calling any other Julia C function is to
5555
initialize Julia. This is done by calling `jl_init`, which tries to automatically determine
5656
Julia's install location. If you need to specify a custom location, or specify which system
57-
image to load, use `jl_init_with_image` instead.
57+
image to load, use `jl_init_with_image_file` or `jl_init_with_image_handle` instead.
5858
5959
The second statement in the test program evaluates a Julia statement using a call to `jl_eval_string`.
6060

src/init.c

+3-195
Original file line numberDiff line numberDiff line change
@@ -533,177 +533,6 @@ int jl_isabspath(const char *in) JL_NOTSAFEPOINT
533533
return 0; // relative path
534534
}
535535

536-
static char *absrealpath(const char *in, int nprefix)
537-
{ // compute an absolute realpath location, so that chdir doesn't change the file reference
538-
// ignores (copies directly over) nprefix characters at the start of abspath
539-
#ifndef _OS_WINDOWS_
540-
char *out = realpath(in + nprefix, NULL);
541-
if (out) {
542-
if (nprefix > 0) {
543-
size_t sz = strlen(out) + 1;
544-
char *cpy = (char*)malloc_s(sz + nprefix);
545-
memcpy(cpy, in, nprefix);
546-
memcpy(cpy + nprefix, out, sz);
547-
free(out);
548-
out = cpy;
549-
}
550-
}
551-
else {
552-
size_t sz = strlen(in + nprefix) + 1;
553-
if (in[nprefix] == PATHSEPSTRING[0]) {
554-
out = (char*)malloc_s(sz + nprefix);
555-
memcpy(out, in, sz + nprefix);
556-
}
557-
else {
558-
size_t path_size = JL_PATH_MAX;
559-
char *path = (char*)malloc_s(JL_PATH_MAX);
560-
if (uv_cwd(path, &path_size)) {
561-
jl_error("fatal error: unexpected error while retrieving current working directory");
562-
}
563-
out = (char*)malloc_s(path_size + 1 + sz + nprefix);
564-
memcpy(out, in, nprefix);
565-
memcpy(out + nprefix, path, path_size);
566-
out[nprefix + path_size] = PATHSEPSTRING[0];
567-
memcpy(out + nprefix + path_size + 1, in + nprefix, sz);
568-
free(path);
569-
}
570-
}
571-
#else
572-
// GetFullPathName intentionally errors if given an empty string so manually insert `.` to invoke cwd
573-
char *in2 = (char*)malloc_s(JL_PATH_MAX);
574-
if (strlen(in) - nprefix == 0) {
575-
memcpy(in2, in, nprefix);
576-
in2[nprefix] = '.';
577-
in2[nprefix+1] = '\0';
578-
in = in2;
579-
}
580-
DWORD n = GetFullPathName(in + nprefix, 0, NULL, NULL);
581-
if (n <= 0) {
582-
jl_error("fatal error: jl_options.image_file path too long or GetFullPathName failed");
583-
}
584-
char *out = (char*)malloc_s(n + nprefix);
585-
DWORD m = GetFullPathName(in + nprefix, n, out + nprefix, NULL);
586-
if (n != m + 1) {
587-
jl_error("fatal error: jl_options.image_file path too long or GetFullPathName failed");
588-
}
589-
memcpy(out, in, nprefix);
590-
free(in2);
591-
#endif
592-
return out;
593-
}
594-
595-
// create an absolute-path copy of the input path format string
596-
// formed as `joinpath(replace(pwd(), "%" => "%%"), in)`
597-
// unless `in` starts with `%`
598-
static const char *absformat(const char *in)
599-
{
600-
if (in[0] == '%' || jl_isabspath(in))
601-
return in;
602-
// get an escaped copy of cwd
603-
size_t path_size = JL_PATH_MAX;
604-
char path[JL_PATH_MAX];
605-
if (uv_cwd(path, &path_size)) {
606-
jl_error("fatal error: unexpected error while retrieving current working directory");
607-
}
608-
size_t sz = strlen(in) + 1;
609-
size_t i, fmt_size = 0;
610-
for (i = 0; i < path_size; i++)
611-
fmt_size += (path[i] == '%' ? 2 : 1);
612-
char *out = (char*)malloc_s(fmt_size + 1 + sz);
613-
fmt_size = 0;
614-
for (i = 0; i < path_size; i++) { // copy-replace pwd portion
615-
char c = path[i];
616-
out[fmt_size++] = c;
617-
if (c == '%')
618-
out[fmt_size++] = '%';
619-
}
620-
out[fmt_size++] = PATHSEPSTRING[0]; // path sep
621-
memcpy(out + fmt_size, in, sz); // copy over format, including nul
622-
return out;
623-
}
624-
625-
static void jl_resolve_sysimg_location(JL_IMAGE_SEARCH rel, const char* julia_bindir)
626-
{
627-
// this function resolves the paths in jl_options to absolute file locations as needed
628-
// and it replaces the pointers to `julia_bindir`, `julia_bin`, `image_file`, and output file paths
629-
// it may fail, print an error, and exit(1) if any of these paths are longer than JL_PATH_MAX
630-
//
631-
// note: if you care about lost memory, you should call the appropriate `free()` function
632-
// on the original pointer for each `char*` you've inserted into `jl_options`, after
633-
// calling `julia_init()`
634-
char *free_path = (char*)malloc_s(JL_PATH_MAX);
635-
size_t path_size = JL_PATH_MAX;
636-
if (uv_exepath(free_path, &path_size)) {
637-
jl_error("fatal error: unexpected error while retrieving exepath");
638-
}
639-
if (path_size >= JL_PATH_MAX) {
640-
jl_error("fatal error: jl_options.julia_bin path too long");
641-
}
642-
jl_options.julia_bin = (char*)malloc_s(path_size + 1);
643-
memcpy((char*)jl_options.julia_bin, free_path, path_size);
644-
((char*)jl_options.julia_bin)[path_size] = '\0';
645-
if (julia_bindir == NULL) {
646-
jl_options.julia_bindir = getenv("JULIA_BINDIR");
647-
if (!jl_options.julia_bindir) {
648-
#ifdef _OS_WINDOWS_
649-
jl_options.julia_bindir = strdup(jl_get_libdir());
650-
#else
651-
int written = asprintf((char**)&jl_options.julia_bindir, "%s" PATHSEPSTRING ".." PATHSEPSTRING "%s", jl_get_libdir(), "bin");
652-
if (written < 0)
653-
abort(); // unexpected: memory allocation failed
654-
#endif
655-
}
656-
} else {
657-
jl_options.julia_bindir = julia_bindir;
658-
}
659-
if (jl_options.julia_bindir)
660-
jl_options.julia_bindir = absrealpath(jl_options.julia_bindir, 0);
661-
free(free_path);
662-
free_path = NULL;
663-
if (jl_options.image_file) {
664-
if (rel == JL_IMAGE_JULIA_HOME && !jl_isabspath(jl_options.image_file)) {
665-
// build time path, relative to JULIA_BINDIR
666-
free_path = (char*)malloc_s(JL_PATH_MAX);
667-
int n = snprintf(free_path, JL_PATH_MAX, "%s" PATHSEPSTRING "%s",
668-
jl_options.julia_bindir, jl_options.image_file);
669-
if (n >= JL_PATH_MAX || n < 0) {
670-
jl_error("fatal error: jl_options.image_file path too long");
671-
}
672-
jl_options.image_file = free_path;
673-
}
674-
if (jl_options.image_file)
675-
jl_options.image_file = absrealpath(jl_options.image_file, 0);
676-
if (free_path) {
677-
free(free_path);
678-
free_path = NULL;
679-
}
680-
}
681-
if (jl_options.outputo)
682-
jl_options.outputo = absrealpath(jl_options.outputo, 0);
683-
if (jl_options.outputji)
684-
jl_options.outputji = absrealpath(jl_options.outputji, 0);
685-
if (jl_options.outputbc)
686-
jl_options.outputbc = absrealpath(jl_options.outputbc, 0);
687-
if (jl_options.outputasm)
688-
jl_options.outputasm = absrealpath(jl_options.outputasm, 0);
689-
if (jl_options.machine_file)
690-
jl_options.machine_file = absrealpath(jl_options.machine_file, 0);
691-
if (jl_options.output_code_coverage)
692-
jl_options.output_code_coverage = absformat(jl_options.output_code_coverage);
693-
if (jl_options.tracked_path)
694-
jl_options.tracked_path = absrealpath(jl_options.tracked_path, 0);
695-
696-
const char **cmdp = jl_options.cmds;
697-
if (cmdp) {
698-
for (; *cmdp; cmdp++) {
699-
const char *cmd = *cmdp;
700-
if (cmd[0] == 'L') {
701-
*cmdp = absrealpath(cmd, 1);
702-
}
703-
}
704-
}
705-
}
706-
707536
JL_DLLEXPORT int jl_is_file_tracked(jl_sym_t *path)
708537
{
709538
const char* path_ = jl_symbol_name(path);
@@ -729,7 +558,7 @@ static void restore_fp_env(void)
729558
jl_error("Failed to configure floating point environment");
730559
}
731560
}
732-
static NOINLINE void _finish_julia_init(jl_image_buf_t sysimage, jl_ptls_t ptls, jl_task_t *ct)
561+
static NOINLINE void _finish_jl_init_(jl_image_buf_t sysimage, jl_ptls_t ptls, jl_task_t *ct)
733562
{
734563
JL_TIMING(JULIA_INIT, JULIA_INIT);
735564

@@ -835,7 +664,7 @@ static void init_global_mutexes(void) {
835664
JL_MUTEX_INIT(&profile_show_peek_cond_lock, "profile_show_peek_cond_lock");
836665
}
837666

838-
static void julia_init(jl_image_buf_t sysimage)
667+
JL_DLLEXPORT void jl_init_(jl_image_buf_t sysimage)
839668
{
840669
// initialize many things, in no particular order
841670
// but generally running from simple platform things to optional
@@ -945,28 +774,7 @@ static void julia_init(jl_image_buf_t sysimage)
945774
jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi);
946775
#pragma GCC diagnostic pop
947776
JL_GC_PROMISE_ROOTED(ct);
948-
_finish_julia_init(sysimage, ptls, ct);
949-
}
950-
951-
952-
// This function is responsible for loading the image and initializing paths in jl_options
953-
JL_DLLEXPORT void jl_load_image_and_init(JL_IMAGE_SEARCH rel, const char* julia_bindir, void *handle) {
954-
libsupport_init();
955-
jl_init_timing();
956-
957-
jl_resolve_sysimg_location(rel, julia_bindir);
958-
959-
// loads sysimg if available, and conditionally sets jl_options.cpu_target
960-
jl_image_buf_t sysimage = { JL_IMAGE_KIND_NONE };
961-
if (handle != NULL) {
962-
sysimage = jl_set_sysimg_so(handle);
963-
} else if (rel == JL_IMAGE_IN_MEMORY) {
964-
sysimage = jl_set_sysimg_so(jl_exe_handle);
965-
jl_options.image_file = jl_options.julia_bin;
966-
} else if (jl_options.image_file)
967-
sysimage = jl_preload_sysimg(jl_options.image_file);
968-
969-
julia_init(sysimage);
777+
_finish_jl_init_(sysimage, ptls, ct);
970778
}
971779

972780
#ifdef __cplusplus

src/jl_exported_funcs.inc

+3-1
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,11 @@
235235
XX(jl_hrtime) \
236236
XX(jl_idtable_rehash) \
237237
XX(jl_init) \
238+
XX(jl_init_) \
238239
XX(jl_init_options) \
239240
XX(jl_init_restored_module) \
240-
XX(jl_init_with_image) \
241+
XX(jl_init_with_image_file) \
242+
XX(jl_init_with_image_handle) \
241243
XX(jl_install_sigint_handler) \
242244
XX(jl_instantiate_type_in_env) \
243245
XX(jl_instantiate_unionall) \

0 commit comments

Comments
 (0)