Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
273 lines (236 sloc) 7.26 KB
/*
init.c
system initialization and global state
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <setjmp.h>
#include <assert.h>
#if defined(__linux) || defined(__APPLE__)
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <sys/mman.h>
#include <unistd.h>
#endif
#include <limits.h>
#include <errno.h>
#include <math.h>
#include <signal.h>
#include <libgen.h>
#include <getopt.h>
#include "julia.h"
int jl_boot_file_loaded = 0;
char *jl_stack_lo;
char *jl_stack_hi;
size_t jl_page_size;
static void jl_find_stack_bottom(void)
{
size_t stack_size;
#if defined(__linux) || defined(__APPLE__)
struct rlimit rl;
getrlimit(RLIMIT_STACK, &rl);
stack_size = rl.rlim_cur;
#else
stack_size = 262144; // guess
#endif
jl_stack_hi = (char*)&stack_size;
jl_stack_lo = jl_stack_hi - stack_size;
}
void fpe_handler(int arg)
{
(void)arg;
sigset_t sset;
sigemptyset(&sset);
sigaddset(&sset, SIGFPE);
sigprocmask(SIG_UNBLOCK, &sset, NULL);
jl_divide_by_zero_error();
}
void segv_handler(int sig, siginfo_t *info, void *context)
{
sigset_t sset;
sigemptyset(&sset);
sigaddset(&sset, SIGSEGV);
sigprocmask(SIG_UNBLOCK, &sset, NULL);
#ifdef COPY_STACKS
if ((char*)info->si_addr > (char*)jl_stack_lo-3000000 &&
(char*)info->si_addr < (char*)jl_stack_hi) {
#else
if ((char*)info->si_addr > (char*)jl_current_task->stack-8192 &&
(char*)info->si_addr <
(char*)jl_current_task->stack+jl_current_task->ssize) {
#endif
jl_raise(jl_stackovf_exception);
}
else {
signal(SIGSEGV, SIG_DFL);
}
}
volatile sig_atomic_t jl_signal_pending = 0;
volatile sig_atomic_t jl_defer_signal = 0;
void sigint_handler(int sig, siginfo_t *info, void *context)
{
sigset_t sset;
sigemptyset(&sset);
sigaddset(&sset, SIGINT);
sigprocmask(SIG_UNBLOCK, &sset, NULL);
if (jl_defer_signal) {
jl_signal_pending = sig;
}
else {
jl_signal_pending = 0;
jl_raise(jl_interrupt_exception);
}
}
void jl_get_builtin_hooks(void);
void *jl_dl_handle;
#ifdef COPY_STACKS
void jl_switch_stack(jl_task_t *t, jmp_buf *where);
extern jmp_buf * volatile jl_jmp_target;
#endif
void julia_init(char *imageFile)
{
jl_page_size = sysconf(_SC_PAGESIZE);
jl_find_stack_bottom();
jl_dl_handle = jl_load_dynamic_library(NULL);
#ifdef JL_GC_MARKSWEEP
jl_gc_init();
jl_gc_disable();
#endif
jl_init_frontend();
jl_init_types();
jl_init_tasks(jl_stack_lo, jl_stack_hi-jl_stack_lo);
jl_init_codegen();
jl_an_empty_cell = (jl_value_t*)jl_alloc_cell_1d(0);
jl_init_serializer();
if (!imageFile) {
jl_base_module = jl_new_module(jl_symbol("Base"));
jl_current_module = jl_base_module;
jl_init_intrinsic_functions();
jl_init_primitives();
jl_load("src/boot.j");
jl_get_builtin_hooks();
jl_boot_file_loaded = 1;
jl_init_box_caches();
}
if (imageFile) {
JL_TRY {
jl_restore_system_image(imageFile);
}
JL_CATCH {
ios_printf(ios_stderr, "error during init:\n");
jl_show(jl_exception_in_transit);
ios_printf(ios_stdout, "\n");
exit(1);
}
}
struct sigaction actf;
memset(&actf, 0, sizeof(struct sigaction));
sigemptyset(&actf.sa_mask);
actf.sa_handler = fpe_handler;
actf.sa_flags = 0;
if (sigaction(SIGFPE, &actf, NULL) < 0) {
ios_printf(ios_stderr, "sigaction: %s\n", strerror(errno));
exit(1);
}
stack_t ss;
ss.ss_flags = 0;
ss.ss_size = SIGSTKSZ;
ss.ss_sp = malloc(ss.ss_size);
if (sigaltstack(&ss, NULL) < 0) {
ios_printf(ios_stderr, "sigaltstack: %s\n", strerror(errno));
exit(1);
}
struct sigaction act;
memset(&act, 0, sizeof(struct sigaction));
sigemptyset(&act.sa_mask);
act.sa_sigaction = segv_handler;
act.sa_flags = SA_ONSTACK | SA_SIGINFO;
if (sigaction(SIGSEGV, &act, NULL) < 0) {
ios_printf(ios_stderr, "sigaction: %s\n", strerror(errno));
exit(1);
}
memset(&act, 0, sizeof(struct sigaction));
sigemptyset(&act.sa_mask);
act.sa_sigaction = sigint_handler;
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGINT, &act, NULL) < 0) {
ios_printf(ios_stderr, "sigaction: %s\n", strerror(errno));
exit(1);
}
#ifdef JL_GC_MARKSWEEP
jl_gc_enable();
#endif
}
DLLEXPORT
int julia_trampoline(int argc, char *argv[], int (*pmain)(int ac,char *av[]))
{
#ifdef COPY_STACKS
// initialize base context of root task
jl_root_task->stackbase = (char*)&argc;
if (setjmp(jl_root_task->base_ctx)) {
jl_switch_stack(jl_current_task, jl_jmp_target);
}
#endif
return pmain(argc, argv);
}
jl_function_t *jl_typeinf_func=NULL;
DLLEXPORT void jl_enable_inference(void)
{
if (jl_typeinf_func != NULL) return;
jl_typeinf_func = (jl_function_t*)jl_get_global(jl_system_module,
jl_symbol("typeinf_ext"));
}
static jl_value_t *base(char *name)
{
return jl_get_global(jl_base_module, jl_symbol(name));
}
static jl_value_t *sysmod(char *name)
{
return jl_get_global(jl_system_module, jl_symbol(name));
}
jl_function_t *jl_method_missing_func=NULL;
// fetch references to things defined in boot.j
void jl_get_builtin_hooks(void)
{
jl_nothing = base("nothing");
jl_root_task->tls = jl_nothing;
jl_char_type = (jl_bits_type_t*)base("Char");
jl_int8_type = (jl_bits_type_t*)base("Int8");
jl_uint8_type = (jl_bits_type_t*)base("Uint8");
jl_int16_type = (jl_bits_type_t*)base("Int16");
jl_uint16_type = (jl_bits_type_t*)base("Uint16");
jl_uint32_type = (jl_bits_type_t*)base("Uint32");
jl_uint64_type = (jl_bits_type_t*)base("Uint64");
jl_float32_type = (jl_bits_type_t*)base("Float32");
jl_float64_type = (jl_bits_type_t*)base("Float64");
jl_stackovf_exception =
jl_apply((jl_function_t*)base("StackOverflowError"), NULL, 0);
jl_divbyzero_exception =
jl_apply((jl_function_t*)base("DivideByZeroError"), NULL, 0);
jl_undefref_exception =
jl_apply((jl_function_t*)base("UndefRefError"),NULL,0);
jl_interrupt_exception =
jl_apply((jl_function_t*)base("InterruptException"),NULL,0);
jl_memory_exception =
jl_apply((jl_function_t*)base("MemoryError"),NULL,0);
jl_weakref_type = (jl_struct_type_t*)base("WeakRef");
jl_ascii_string_type = (jl_struct_type_t*)base("ASCIIString");
jl_utf8_string_type = (jl_struct_type_t*)base("UTF8String");
jl_symbolnode_type = (jl_struct_type_t*)base("SymbolNode");
jl_array_uint8_type =
(jl_type_t*)jl_apply_type((jl_value_t*)jl_array_type,
jl_tuple2(jl_uint8_type,
jl_box_long(1)));
}
DLLEXPORT void jl_get_system_hooks(void)
{
if (jl_method_missing_func) return; // only do this once
jl_errorexception_type = (jl_struct_type_t*)sysmod("ErrorException");
jl_typeerror_type = (jl_struct_type_t*)sysmod("TypeError");
jl_loaderror_type = (jl_struct_type_t*)sysmod("LoadError");
jl_backtrace_type = (jl_struct_type_t*)sysmod("BackTrace");
jl_method_missing_func = (jl_function_t*)sysmod("method_missing");
}
Jump to Line
Something went wrong with that request. Please try again.