AnyMath 文档

Julia运行时的初始化

Julia运行时如何执行 julia-e’println("你好世界!")' ?

主要()

执行开始于https://github.com/JuliaLang/julia/blob/master/cli/loader_exe.c[脧锚脧赂`主要()` 在 cli/loader_exe。c],其中调用 jl_load_repl() 在https://github.com/JuliaLang/julia/blob/master/cli/loader_lib.c[脧锚脧赂`cli/loader_lib。c`]其中加载了几个库,最终调用https://github.com/JuliaLang/julia/blob/master/src/jlapi.c[脧锚脧赂`jl_repl_entrypoint()` 在 src/jlapi。c]. jl_repl_entrypoint() 电话https://github.com/JuliaLang/julia/blob/master/src/support/libsupportinit.c[脧锚脧赂`libsupport_init()]设置C库区域设置并初始化"ios"库(请参阅https://github.com/JuliaLang/julia/blob/master/src/support/ios.c[脧锚脧赂`ios_init_stdstreams()]和 遗产 的ios。c)。

下一个https://github.com/JuliaLang/julia/blob/master/src/jloptions.c[脧锚脧赂`jl_parse_opts()]被调用来处理命令行选项。 请注意 `jl_parse_opts() 仅处理影响代码生成或早期初始化的选项。 其他选项稍后由https://github.com/JuliaLang/julia/blob/master/base/client.jl[脧锚脧赂`执行_操作()` 在 基地/客户端。jl]. jl_parse_opts() 将命令行选项存储在https://github.com/JuliaLang/julia/blob/master/src/julia.h[全球 jl_选项 结构]。

朱莉亚*尼特()

脧锚脧赂`朱莉亚*尼特()` 在 初始化。c被称为 主要() 和电话https://github.com/JuliaLang/julia/blob/master/src/init.c[脧锚脧赂`_朱利亚_init()` 在 初始化。c].

_朱利亚_init() 从打电话开始 libsupport_init() 再次(第二次什么也不做)。

脧锚脧赂`restore_signals()`被调用以将信号处理程序掩码归零。

脧锚脧赂`jl_resolve_sysimg_location()`搜索基本系统映像的已配置路径。 见 构建Julia系统映像

脧锚脧赂`jl_gc_init()`为弱引用、保留值和最终确定设置分配池和列表。

脧锚脧赂`jl_init_frontend()`加载并初始化包含扫描仪/解析器的预编译femtolisp图像。

脧锚脧赂`jl_init_types()创建 `jl_datatype_t 类型描述对象的https://github.com/JuliaLang/julia/blob/master/src/julia.h[内置类型定义于 朱莉娅。h]. 例如

jl_any_type = jl_new_abstracttype(jl_symbol("Any"), core, NULL, jl_emptysvec);
jl_any_type->super = jl_any_type;

jl_type_type = jl_new_abstracttype(jl_symbol("Type"), core, jl_any_type, jl_emptysvec);

jl_int32_type = jl_new_primitivetype(jl_symbol("Int32"), core,
                                     jl_any_type, jl_emptysvec, 32);

脧锚脧赂`jl_init_tasks()创建 `jl_datatype_t*jl_task_type 对象;初始化全局 jl_root_task 结构;以及集合 jl_current_task 到根任务。

脧锚脧赂`jl_init_codegen()`初始化https://llvm.org[LLVM库]。

脧锚脧赂`jl_init_serializer()为内建初始化8位序列化标记 `jl_value_t 价值观。

如果没有sysimg文件(!jl_options。图像文件)然后 核心主要 模块被创建和 靴子。jl 被评估: jl_core_module=jl_new_module(jl_symbol("Core"),NULL) 创建朱莉娅 核心 模块。

脧锚脧赂`jl_init_intrinsic_functions()创建一个新的Julia模块 `内在函数 包含常量 jl_intrinsic_type 符号。 这些为每个定义一个整数代码https://github.com/JuliaLang/julia/blob/master/src/intrinsics.cpp[内在功能]。 脧锚脧赂`emit_intrinsic()`在代码生成期间将这些符号转换为LLVM指令。

脧锚脧赂`jl_init_primitives()将C函数与Julia函数符号挂钩。 例如符号 `核心。:(===)() 绑定到c函数指针 jl_f_is() 通过调用 add_builtin_func("===",jl_f_is).

脧锚脧赂`jl_new_main_module()创建全局"主"模块并设置 `+jl_current_task→current_module=jl_main_module+.

注: _朱利亚_init() 然后设置 jl_root_task->current_module=jl_core_module. jl_root_task 是一个别名 jl_current_task 在这一点上,所以 当前_module 设置 jl_new_main_module() 以上被复盖。

脧锚脧赂`jl_load("引导。jl",sizeof("boot.jl"))电话https://github.com/JuliaLang/julia/blob/master/src/ast.c[脧锚脧赂`jl_parse_eval_all[重复调用https://github.com/JuliaLang/julia/blob/master/src/toplevel.c[脧锚脧赂`jl_toplevel_eval_flex()]执行https://github.com/JuliaLang/julia/blob/master/base/boot.jl[脧锚脧赂`靴子。jl]. <!--TODO-深入到eval? -→

脧锚脧赂`jl_get_builtin_hooks()初始化全局c指针到Julia全局变量 `靴子。jl.

脧锚脧赂`jl_init_box_caches()`为最多1024个值预分配全局盒装整数值对象。 这加快了以后盒装ints的分配。 例如:

jl_value_t &ast;jl_box_uint8(uint32_t x)
{
    return boxed_uint8_cache[(uint8_t)x];
}

脧锚脧赂`_朱利亚_init()` 迭代jl_core_module->绑定。表 寻找 jl_datatype_t 值并将类型名称的模块前缀设置为 jl_core_module的.

注: _朱利亚_init() 现在恢复到 jl_root_task->current_module=jl_main_module 就像之前被设定的那样 jl_core_module的 以上。

平台特定的信号处理程序被初始化为 [医]乙状结肠 (OSX,Linux),以及 [医]SIGFPE (窗户)。

其他信号(SIGINFO,SIGBUS,SIGILL,SIGTERM,SIGABRT,SIGQUIT,SIGSYS[医]乙状结肠)被连接到https://github.com/JuliaLang/julia/blob/master/src/signals-unix.c[脧锚脧赂`sigdie_handler()`]它打印了一条后路。

脧锚脧赂`jl_init_restored_module()电话https://github.com/JuliaLang/julia/blob/master/src/module.c[脧锚脧赂`jl_module_run_initializer()]对于每个反序列化模块运行 __init__() 函数。

最后https://github.com/JuliaLang/julia/blob/master/src/signals-unix.c[脧锚脧赂`sigint_handler()]被连接到 `西金特 和电话 jl_throw(jl_interrupt_exception).

_朱利亚_init() 然后返回https://github.com/JuliaLang/julia/blob/master/cli/loader_exe.c[返回 主要()cli/loader_exe。c]和 主要() 电话 repl_entrypoint(argc,(char&ast;&ast;)argv).

sysimg如果有一个sysimg文件,它包含一个预先煮熟的图像 核心主要 模块(以及其他由 靴子。jl). 见 构建Julia系统映像

脧锚脧赂`jl_restore_system_image()将保存的sysimg反序列化到当前Julia运行时环境中,并在之后继续初始化 `jl_init_box_caches() 下面。..

注:https://github.com/JuliaLang/julia/blob/master/src/staticdata.c[脧锚脧赂`jl_restore_system_image()` (和 静态数据。c 一般情况下)]使用[Legacy ios的。c 库](/devdocs/stdio#Legacy-ios。c-文库)。

重放点()

脧锚脧赂`重放点()加载的内容 `argv[] 进入 基地。阿格斯.

如果一个 .jl 在命令行上提供了"程序"文件,然后https://github.com/JuliaLang/julia/blob/master/src/jlapi.c[脧锚脧赂`exec_program()]电话https://github.com/JuliaLang/julia/blob/master/src/toplevel.c[脧锚脧赂`jl_load(程序,len)]哪些调用https://github.com/JuliaLang/julia/blob/master/src/ast.c[脧锚脧赂`jl_parse_eval_all`[重复调用https://github.com/JuliaLang/julia/blob/master/src/toplevel.c[脧锚脧赂`jl_toplevel_eval_flex()`]来执行程序。

但是,在我们的例子中(julia-e’println("你好世界!")'),https://github.com/JuliaLang/julia/blob/master/src/module.c[脧锚脧赂`jl_get_global(jl_base_module,jl_symbol("_start"))]向上看https://github.com/JuliaLang/julia/blob/master/base/client.jl[脧锚脧赂`基地。_启动]和https://github.com/JuliaLang/julia/blob/master/src/julia.h[脧锚脧赂`jl_应用()`]执行它。

基地。_启动

脧锚脧赂`基地。_启动`电话https://github.com/JuliaLang/julia/blob/master/base/client.jl[脧锚脧赂`基地。执行_操作`]哪些调用https://github.com/JuliaLang/julia/blob/master/src/ast.c[脧锚脧赂`jl_parse_input_line("println("Hello World!")")]创建表达式对象和 `核心。eval(主要,ex)执行解析后的表达式 在模块上下文中 主要.

核心。埃瓦尔

核心。eval(主要,ex)电话https://github.com/JuliaLang/julia/blob/master/src/toplevel.c[脧锚脧赂`jl_toplevel_eval_in(m,ex)],其中调用https://github.com/JuliaLang/julia/blob/master/src/toplevel.c[脧锚脧赂`jl_toplevel_eval_flex]. jl_toplevel_eval_flex 实现一个简单的启发式来决定是编译给定的代码thunk还是由解释器运行它。 当给予 println("你好世界!"),它通常会决定通过解释器运行代码,在这种情况下,它会调用https://github.com/JuliaLang/julia/blob/master/src/interpreter.c[脧锚脧赂`jl_interpret_toplevel_thunk`],然后调用https://github.com/JuliaLang/julia/blob/master/src/interpreter.c[脧锚脧赂`eval_body`].

下面的堆栈转储显示了解释器如何通过 基地。打印()基地。印刷()抵达前https://github.com/JuliaLang/julia/blob/master/base/stream.jl[脧锚脧赂`写(s::IO,A::数组{T})其中T]哪个 `ccall(jl_uv_write()).

脧锚脧赂`jl_uv_write()电话 `uv_write() 要写"你好世界!"到 JL_STDOUT. 见 Libuv包装为stdio。:

Hello World!
堆栈帧 源代码 注意事项

jl_uv_write()

jl_uv。c

虽然叫 ccall

julia_write_282942

小溪。jl

功能 写!(s::IO,a::数组{T})其中T

朱莉亚_print_284639

ascii码。jl

print(io::IO,s::String)=(write(io,s);nothing)

jlcall_print_284639

jl_应用()

朱莉娅。h

jl_蹦床()

建造。c

jl_应用()

朱莉娅。h

jl_apply_generic()

gf。c

基地。打印(基地。TTY,字符串)

jl_应用()

朱莉娅。h

jl_蹦床()

建造。c

jl_应用()

朱莉娅。h

jl_apply_generic()

gf。c

基地。打印(基地。TTY,字符串,Char,Char。..)

jl_应用()

朱莉娅。h

jl_f_apply()

建造。c

jl_应用()

朱莉娅。h

jl_蹦床()

建造。c

jl_应用()

朱莉娅。h

jl_apply_generic()

gf。c

基地。println(Base.TTY,字符串,字符串。..)

jl_应用()

朱莉娅。h

jl_蹦床()

建造。c

jl_应用()

朱莉娅。h

jl_apply_generic()

gf。c

基地。println(字符串,)

jl_应用()

朱莉娅。h

do_call()

翻译。c

eval_body()

翻译。c

jl_interpret_toplevel_thunk

翻译。c

jl_toplevel_eval_flex

顶层。c

jl_toplevel_eval_in

顶层。c

核心。埃瓦尔

靴子。jl

由于我们的例子只有一个函数调用,它已经完成了打印"Hello World!",堆栈现在迅速解开回到 主要().

jl_atexit_hook()

主要() 电话https://github.com/JuliaLang/julia/blob/master/src/init.c[脧锚脧赂`jl_atexit_hook()]. 这就要求 `基地。_atexit,然后调用https://github.com/JuliaLang/julia/blob/master/src/gc.c[脧锚脧赂`jl_gc_run_all_finalizers()`]并清理libuv句柄。

julia_save()

最后, 主要() 电话https://github.com/JuliaLang/julia/blob/master/src/init.c[脧锚脧赂`julia_save()],如果在命令行上请求,则将运行时状态保存到新的系统映像。 见https://github.com/JuliaLang/julia/blob/master/src/gf.c[脧锚脧赂`jl_compile_all()]和https://github.com/JuliaLang/julia/blob/master/src/staticdata.c[脧锚脧赂`jl_save_system_image()`].