static void run_finalizer(jl_value_t *o, jl_value_t *ff) { jl_function_t *f; while (jl_is_tuple(ff)) { f = (jl_function_t*)jl_t0(ff); assert(jl_is_function(f)); JL_TRY { jl_apply(f, (jl_value_t**)&o, 1); } JL_CATCH { JL_PRINTF(JL_STDERR, "error in running finalizer: "); jl_static_show(JL_STDERR, jl_exception_in_transit); JL_PUTC('\n',JL_STDERR); } ff = jl_t1(ff); } f = (jl_function_t*)ff; assert(jl_is_function(f)); JL_TRY { jl_apply(f, (jl_value_t**)&o, 1); } JL_CATCH { JL_PRINTF(JL_STDERR, "error in running finalizer: "); jl_static_show(JL_STDERR, jl_exception_in_transit); JL_PUTC('\n',JL_STDERR); } }
static void run_finalizers(void) { void *o = NULL; jl_function_t *f=NULL; jl_value_t *ff=NULL; JL_GC_PUSH(&o, &f, &ff); while (to_finalize.len > 0) { o = arraylist_pop(&to_finalize); ff = (jl_value_t*)ptrhash_get(&finalizer_table, o); assert(ff != HT_NOTFOUND); ptrhash_remove(&finalizer_table, o); while (jl_is_tuple(ff)) { f = (jl_function_t*)jl_t0(ff); assert(jl_is_function(f)); JL_TRY { jl_apply(f, (jl_value_t**)&o, 1); } JL_CATCH { } ff = jl_t1(ff); } f = (jl_function_t*)ff; assert(jl_is_function(f)); jl_apply(f, (jl_value_t**)&o, 1); } JL_GC_POP(); }
// get binding for adding a method // like jl_get_binding_wr, but uses existing imports instead of warning // and overwriting. DLLEXPORT jl_binding_t *jl_get_binding_for_method_def(jl_module_t *m, jl_sym_t *var) { jl_binding_t **bp = (jl_binding_t**)ptrhash_bp(&m->bindings, var); jl_binding_t *b = *bp; if (b != HT_NOTFOUND) { if (b->owner != m && b->owner != NULL) { jl_binding_t *b2 = jl_get_binding(b->owner, var); if (b2 == NULL) jl_errorf("invalid method definition: imported function %s.%s does not exist", b->owner->name->name, var->name); if (!b->imported && (b2->value==NULL || jl_is_function(b2->value))) { if (b2->value && !jl_is_gf(b2->value)) { jl_errorf("error in method definition: %s.%s cannot be extended", b->owner->name->name, var->name); } else { jl_errorf("error in method definition: function %s.%s must be explicitly imported to be extended", b->owner->name->name, var->name); } } return b2; } b->owner = m; return b; } b = new_binding(var); b->owner = m; *bp = b; jl_gc_wb_buf(m, b); return *bp; }
jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd, jl_tuple_t *argtypes, jl_function_t *f, jl_tuple_t *t) { jl_value_t *gf; if (bnd) { jl_declare_constant(bnd); } if (*bp == NULL) { gf = (jl_value_t*)jl_new_generic_function(name); *bp = gf; } else { gf = *bp; if (!jl_is_gf(gf)) jl_error("in method definition: not a generic function"); } JL_GC_PUSH(&gf); assert(jl_is_function(f)); assert(jl_is_tuple(argtypes)); check_type_tuple(argtypes, name, "method definition"); jl_add_method((jl_function_t*)gf, argtypes, f, t); if (jl_boot_file_loaded && f->linfo && f->linfo->ast && jl_is_expr(f->linfo->ast)) { jl_lambda_info_t *li = f->linfo; li->ast = jl_compress_ast(li->ast); } JL_GC_POP(); return gf; }
jl_function_t *jl_module_get_initializer(jl_module_t *m) { jl_value_t *f = jl_get_global(m, jl_symbol("__init__")); if (f == NULL || !jl_is_function(f)) return NULL; return (jl_function_t*)f; }
jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd, jl_tuple_t *argtypes, jl_function_t *f, jl_tuple_t *t) { jl_value_t *gf; if (bnd) { //jl_declare_constant(bnd); if (bnd->value != NULL && !bnd->constp) { jl_errorf("cannot define function %s; it already has a value", bnd->name->name); } bnd->constp = 1; } if (*bp == NULL) { gf = (jl_value_t*)jl_new_generic_function(name); *bp = gf; } else { gf = *bp; if (!jl_is_gf(gf)) { if (jl_is_datatype(gf) && ((jl_function_t*)gf)->fptr == jl_f_ctor_trampoline) { jl_add_constructors((jl_datatype_t*)gf); } if (!jl_is_gf(gf)) { jl_error("invalid method definition: not a generic function"); } } } JL_GC_PUSH1(&gf); assert(jl_is_function(f)); assert(jl_is_tuple(argtypes)); assert(jl_is_tuple(t)); for(size_t i=0; i < jl_tuple_len(argtypes); i++) { jl_value_t *elt = jl_tupleref(argtypes,i); if (!jl_is_type(elt) && !jl_is_typevar(elt)) { jl_lambda_info_t *li = f->linfo; jl_errorf("invalid type for argument %s in method definition for %s at %s:%d", jl_is_expr(li->ast) ? ((jl_sym_t*)jl_arrayref(jl_lam_args((jl_expr_t*)li->ast),i))->name : "?", name->name, li->file->name, li->line); } } for(size_t i=0; i < jl_tuple_len(t); i++) { if (!jl_is_typevar(jl_tupleref(t,i))) jl_type_error_rt(name->name, "method definition", (jl_value_t*)jl_tvar_type, jl_tupleref(t,i)); } jl_add_method((jl_function_t*)gf, argtypes, f, t); if (jl_boot_file_loaded && f->linfo && f->linfo->ast && jl_is_expr(f->linfo->ast)) { jl_lambda_info_t *li = f->linfo; li->ast = jl_compress_ast(li, li->ast); } JL_GC_POP(); return gf; }
void jl_atexit_hook() { if (jl_base_module) { jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("_atexit")); if (f!=NULL && jl_is_function(f)) { jl_apply((jl_function_t*)f, NULL, 0); } } }
jl_function_t *jl_module_call_func(jl_module_t *m) { if (m->call_func == NULL) { jl_function_t *cf = (jl_function_t*)jl_get_global(m, call_sym); if (cf == NULL || !jl_is_function(cf)) cf = jl_bottom_func; m->call_func = cf; } return m->call_func; }
// get binding for adding a method // like jl_get_binding_wr, but uses existing imports instead of warning // and overwriting. JL_DLLEXPORT jl_binding_t *jl_get_binding_for_method_def(jl_module_t *m, jl_sym_t *var) { if (jl_base_module && m->std_imports && !jl_binding_resolved_p(m,var)) { jl_module_t *opmod = (jl_module_t*)jl_get_global(jl_base_module, jl_symbol("Operators")); if (opmod != NULL && jl_defines_or_exports_p(opmod, var)) { jl_printf(JL_STDERR, "WARNING: module %s should explicitly import %s from %s\n", jl_symbol_name(m->name), jl_symbol_name(var), jl_symbol_name(jl_base_module->name)); jl_module_import(m, opmod, var); } } jl_binding_t **bp = (jl_binding_t**)ptrhash_bp(&m->bindings, var); jl_binding_t *b = *bp; if (b != HT_NOTFOUND) { if (b->owner != m && b->owner != NULL) { jl_binding_t *b2 = jl_get_binding(b->owner, var); if (b2 == NULL) jl_errorf("invalid method definition: imported function %s.%s does not exist", jl_symbol_name(b->owner->name), jl_symbol_name(var)); if (!b->imported && (b2->value==NULL || jl_is_function(b2->value))) { if (b2->value && !jl_is_gf(b2->value)) { jl_errorf("error in method definition: %s.%s cannot be extended", jl_symbol_name(b->owner->name), jl_symbol_name(var)); } else { if (jl_base_module && m->std_imports && b->owner == jl_base_module) { jl_module_t *opmod = (jl_module_t*)jl_get_global(jl_base_module, jl_symbol("Operators")); if (opmod != NULL && jl_defines_or_exports_p(opmod, var)) { jl_printf(JL_STDERR, "WARNING: module %s should explicitly import %s from %s\n", jl_symbol_name(m->name), jl_symbol_name(var), jl_symbol_name(b->owner->name)); return b2; } } jl_errorf("error in method definition: function %s.%s must be explicitly imported to be extended", jl_symbol_name(b->owner->name), jl_symbol_name(var)); } } return b2; } b->owner = m; return b; } b = new_binding(var); b->owner = m; *bp = b; jl_gc_wb_buf(m, b); return *bp; }
void jl_add_constructors(jl_datatype_t *t) { if (t->name == jl_array_typename) { t->fptr = jl_f_no_function; return; } jl_initialize_generic_function((jl_function_t*)t, t->name->name); if (t->name->ctor_factory == (jl_value_t*)jl_nothing || t->name->ctor_factory == (jl_value_t*)jl_null) { } else { assert(jl_tuple_len(t->parameters) > 0); if (t == (jl_datatype_t*)t->name->primary) return; jl_function_t *cfactory = NULL; jl_tuple_t *env = NULL; JL_GC_PUSH2(&cfactory, &env); if (jl_compileropts.compile_enabled) { // instantiating assert(jl_is_function(t->name->ctor_factory)); // add type's static parameters to the ctor factory size_t np = jl_tuple_len(t->parameters); env = jl_alloc_tuple_uninit(np*2); for(size_t i=0; i < np; i++) { jl_tupleset(env, i*2+0, jl_tupleref(((jl_datatype_t*)t->name->primary)->parameters, i)); jl_tupleset(env, i*2+1, jl_tupleref(t->parameters, i)); } cfactory = jl_instantiate_method((jl_function_t*)t->name->ctor_factory, env); cfactory->linfo->ast = jl_prepare_ast(cfactory->linfo, cfactory->linfo->sparams); } else { cfactory = ((jl_datatype_t*)t)->name->static_ctor_factory; if (cfactory == NULL) { JL_PRINTF(JL_STDERR,"code missing for type %s\n", t->name->name); exit(1); } // in generically-compiled case, pass static parameters via closure // environment. env = jl_tuple_append((jl_tuple_t*)cfactory->env, t->parameters); cfactory = jl_new_closure(cfactory->fptr, (jl_value_t*)env, cfactory->linfo); } // call user-defined constructor factory on (type,) jl_value_t *cfargs[1] = { (jl_value_t*)t }; jl_apply(cfactory, cfargs, 1); JL_GC_POP(); } }
DLLEXPORT void jl_checked_assignment(jl_binding_t *b, jl_value_t *rhs) { if (b->constp && b->value != NULL) { if (!jl_egal(rhs, b->value)) { if (jl_typeof(rhs) != jl_typeof(b->value) || jl_is_type(rhs) || jl_is_function(rhs) || jl_is_module(rhs)) { jl_errorf("invalid redefinition of constant %s", b->name->name); } JL_PRINTF(JL_STDERR,"Warning: redefining constant %s\n",b->name->name); } } b->value = rhs; }
static void jl_uv_call_close_callback(void *val) { jl_value_t *cb; if (!jl_old_base_module) { if (close_cb == NULL) close_cb = jl_get_global(jl_base_module, jl_symbol("_uv_hook_close")); cb = close_cb; } else { cb = jl_get_global(jl_base_relative_to(((jl_datatype_t*)jl_typeof(val))->name->module), jl_symbol("_uv_hook_close")); } assert(cb && jl_is_function(cb)); jl_apply((jl_function_t*)cb, (jl_value_t**)&val, 1); }
SEXP jr_cast(jl_value_t *tt){ SEXP ans = R_NilValue; JL_GC_PUSH1(&tt); if (jl_is_nothing(tt) || jl_is_null(tt)) return ans; if (jl_is_array(tt)) { ans = jr_array(tt); } else if(jl_isa(tt, "Range")) { ans = jr_range(tt); } else if(jl_isa(tt, "DataArray")) { ans = jr_data_array(tt); } else if(jl_isa(tt, "DataFrame")) { ans = jr_data_frame(tt); } else if (jl_is_tuple(tt)) { PROTECT(ans = Rf_allocVector(VECSXP, jl_tuple_len(tt))); for (int i = 0; i < jl_tuple_len(tt); i++) SET_VECTOR_ELT(ans, i, jr_cast(jl_tupleref(tt, i))); UNPROTECT(1); } else if(jl_isa(tt, "Dict")) { ans = jr_dict(tt); } else if(jl_is_function(tt)) { ans = jr_func(tt); } else { ans = jr_scalar(tt); } JL_GC_POP(); if (ans == R_NilValue) { jl_error("invaild object"); } return ans; }
JL_DLLEXPORT void jl_checked_assignment(jl_binding_t *b, jl_value_t *rhs) { if (b->constp && b->value != NULL) { if (!jl_egal(rhs, b->value)) { if (jl_typeof(rhs) != jl_typeof(b->value) || jl_is_type(rhs) || jl_is_function(rhs) || jl_is_module(rhs)) { jl_errorf("invalid redefinition of constant %s", jl_symbol_name(b->name)); } jl_printf(JL_STDERR, "WARNING: redefining constant %s\n", jl_symbol_name(b->name)); } } b->value = rhs; jl_gc_wb_binding(b, rhs); }
static void print_profile(void) { size_t i; void **table = jl_base_module->bindings.table; for(i=1; i < jl_base_module->bindings.size; i+=2) { if (table[i] != HT_NOTFOUND) { jl_binding_t *b = (jl_binding_t*)table[i]; if (b->value != NULL && jl_is_function(b->value) && jl_is_gf(b->value)) { ios_printf(ios_stdout, "%d\t%s\n", jl_gf_mtable(b->value)->ncalls, jl_gf_name(b->value)->name); } } } }
DLLEXPORT void uv_atexit_hook() { #if defined(JL_GC_MARKSWEEP) && defined(GC_FINAL_STATS) jl_print_gc_stats(JL_STDERR); #endif if (jl_base_module) { jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("_atexit")); if (f!=NULL && jl_is_function(f)) { JL_TRY { jl_apply((jl_function_t*)f, NULL, 0); } JL_CATCH { JL_PRINTF(JL_STDERR, "\natexit hook threw an error: "); jl_show(jl_stderr_obj(),jl_exception_in_transit); } } }
static void repl_show_value(jl_value_t *v) { if (jl_is_function(v) && !jl_is_struct_type(v)) { // show method table when a function is shown at the top level. jl_show_full_function(v); return; } jl_show(v); if (jl_is_struct_type(v)) { ios_t *s = jl_current_output_stream(); // for convenience, show constructor methods when // a type is shown at the top level. if (jl_is_gf(v)) { ios_putc('\n', s); jl_show_full_function(v); } } }
void jl_add_constructors(jl_struct_type_t *t) { if (t->name == jl_array_typename) { t->fptr = jl_f_no_function; return; } jl_initialize_generic_function((jl_function_t*)t, t->name->name); if (t->ctor_factory == (jl_value_t*)jl_nothing || t->ctor_factory == (jl_value_t*)jl_null) { assert(jl_tuple_len(t->parameters) == 0); } else { assert(jl_tuple_len(t->parameters) > 0); if (t != (jl_struct_type_t*)t->name->primary) { // instantiating assert(jl_is_function(t->ctor_factory)); // add type's static parameters to the ctor factory size_t np = jl_tuple_len(t->parameters); jl_tuple_t *sparams = jl_alloc_tuple_uninit(np*2); jl_function_t *cfactory = NULL; JL_GC_PUSH(&sparams, &cfactory); size_t i; for(i=0; i < np; i++) { jl_tupleset(sparams, i*2+0, jl_tupleref(((jl_struct_type_t*)t->name->primary)->parameters, i)); jl_tupleset(sparams, i*2+1, jl_tupleref(t->parameters, i)); } cfactory = jl_instantiate_method((jl_function_t*)t->ctor_factory, sparams); cfactory->linfo->ast = jl_prepare_ast(cfactory->linfo, cfactory->linfo->sparams); // call user-defined constructor factory on (type,) jl_value_t *cfargs[1] = { (jl_value_t*)t }; jl_apply(cfactory, cfargs, 1); JL_GC_POP(); } } }
jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd, jl_tuple_t *argtypes, jl_function_t *f, jl_tuple_t *t) { jl_value_t *gf; if (bnd) { jl_declare_constant(bnd); } if (*bp == NULL) { gf = (jl_value_t*)jl_new_generic_function(name); *bp = gf; } else { gf = *bp; if (!jl_is_gf(gf)) { if (jl_is_struct_type(gf) && ((jl_function_t*)gf)->fptr == jl_f_ctor_trampoline) { jl_add_constructors((jl_struct_type_t*)gf); } if (!jl_is_gf(gf)) { jl_error("invalid method definition: not a generic function"); } } } JL_GC_PUSH(&gf); assert(jl_is_function(f)); assert(jl_is_tuple(argtypes)); assert(jl_is_tuple(t)); jl_check_type_tuple(argtypes, name, "method definition"); for(size_t i=0; i < t->length; i++) { if (!jl_is_typevar(jl_tupleref(t,i))) jl_type_error_rt(name->name, "method definition", (jl_value_t*)jl_tvar_type, jl_tupleref(t,i)); } jl_add_method((jl_function_t*)gf, argtypes, f, t); if (jl_boot_file_loaded && f->linfo && f->linfo->ast && jl_is_expr(f->linfo->ast)) { jl_lambda_info_t *li = f->linfo; li->ast = jl_compress_ast(li, li->ast); } JL_GC_POP(); return gf; }
DLLEXPORT void jl_atexit_hook(int exitcode) { if (exitcode == 0) julia_save(); jl_print_gc_stats(JL_STDERR); if (jl_options.code_coverage) jl_write_coverage_data(); if (jl_options.malloc_log) jl_write_malloc_log(); if (jl_base_module) { jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("_atexit")); if (f!=NULL && jl_is_function(f)) { JL_TRY { jl_apply((jl_function_t*)f, NULL, 0); } JL_CATCH { jl_printf(JL_STDERR, "\natexit hook threw an error: "); jl_static_show(JL_STDERR, jl_exception_in_transit); } } }
void jl_module_run_initializer(jl_module_t *m) { jl_value_t *f = jl_get_global(m, jl_symbol("__init__")); if (f == NULL || !jl_is_function(f)) return; int build_mode = (jl_compileropts.build_path != NULL); if (build_mode) { if (jl_module_init_order == NULL) jl_module_init_order = jl_alloc_cell_1d(0); jl_cell_1d_push(jl_module_init_order, (jl_value_t*)m); } JL_TRY { jl_apply((jl_function_t*)f, NULL, 0); } JL_CATCH { JL_PRINTF(JL_STDERR, "Warning: error initializing module %s:\n", m->name->name); jl_static_show(JL_STDERR, jl_exception_in_transit); JL_PRINTF(JL_STDERR, "\n"); } }
void jl_binding_deprecation_warning(jl_binding_t *b) { if (b->deprecated && jl_options.depwarn) { if (jl_options.depwarn != JL_OPTIONS_DEPWARN_ERROR) jl_printf(JL_STDERR, "WARNING: "); if (b->owner) jl_printf(JL_STDERR, "%s.%s is deprecated", jl_symbol_name(b->owner->name), jl_symbol_name(b->name)); else jl_printf(JL_STDERR, "%s is deprecated", jl_symbol_name(b->name)); jl_value_t *v = b->value; if (v && (jl_is_type(v) || (jl_is_function(v) && jl_is_gf(v)))) { jl_printf(JL_STDERR, ", use "); if (b->owner && strcmp(jl_symbol_name(b->owner->name), "Base") == 0 && strcmp(jl_symbol_name(b->name), "Uint") == 0) { // TODO: Suggesting type b->value is wrong for typealiases. // Uncommon in Base, hardcoded here for now, see #13221 jl_printf(JL_STDERR, "UInt"); } else { jl_static_show(JL_STDERR, v); } jl_printf(JL_STDERR, " instead"); } jl_printf(JL_STDERR, ".\n"); if (jl_options.depwarn != JL_OPTIONS_DEPWARN_ERROR) jl_printf(JL_STDERR, " likely near %s:%d\n", jl_filename, jl_lineno); if (jl_options.depwarn == JL_OPTIONS_DEPWARN_ERROR) { if (b->owner) jl_errorf("deprecated binding: %s.%s", jl_symbol_name(b->owner->name), jl_symbol_name(b->name)); else jl_errorf("deprecated binding: %s", jl_symbol_name(b->name)); } } }
jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd, jl_tuple_t *argtypes, jl_function_t *f) { jl_value_t *gf; if (bnd) { jl_declare_constant(bnd); } if (*bp == NULL) { gf = (jl_value_t*)jl_new_generic_function(name); *bp = gf; } else { gf = *bp; if (!jl_is_gf(gf)) jl_error("in method definition: not a generic function"); } JL_GC_PUSH(&gf); assert(jl_is_function(f)); assert(jl_is_tuple(argtypes)); check_type_tuple(argtypes, name, "method definition"); jl_add_method((jl_function_t*)gf, argtypes, f); JL_GC_POP(); return gf; }
DLLEXPORT void uv_atexit_hook() { #if defined(JL_GC_MARKSWEEP) && defined(GC_FINAL_STATS) jl_print_gc_stats(JL_STDERR); #endif if (jl_base_module) { jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("_atexit")); if (f!=NULL && jl_is_function(f)) { jl_apply((jl_function_t*)f, NULL, 0); } } uv_loop_t* loop = jl_global_event_loop(); struct uv_shutdown_queue queue = {NULL, NULL}; uv_walk(loop, jl_uv_exitcleanup_walk, &queue); // close stdout and stderr last, since we like being // able to show stuff (incl. printf's) jl_uv_exitcleanup_add((uv_handle_t*)jl_uv_stdout, &queue); jl_uv_exitcleanup_add((uv_handle_t*)jl_uv_stderr, &queue); struct uv_shutdown_queue_item *item = queue.first; while (item) { uv_handle_t *handle = item->h; if (uv_is_closing(handle)) { item = item->next; continue; } switch(handle->type) { case UV_TTY: case UV_UDP: //#ifndef __WIN32__ // unix only supports shutdown on TCP and NAMED_PIPE // but uv_shutdown doesn't seem to be particularly reliable, so we'll avoid it in general jl_close_uv(handle); break; //#endif case UV_TCP: case UV_NAMED_PIPE: if (uv_is_writable((uv_stream_t*)handle)) { // uv_shutdown returns an error if not writable uv_shutdown_t *req = malloc(sizeof(uv_shutdown_t)); int err = uv_shutdown(req, (uv_stream_t*)handle, jl_shutdown_uv_cb); if (err != 0) { printf("shutdown err: %s\n", uv_strerror(uv_last_error(jl_global_event_loop()))); jl_close_uv(handle); } } else { jl_close_uv(handle); } break; case UV_POLL: case UV_TIMER: case UV_PREPARE: case UV_CHECK: case UV_IDLE: case UV_ASYNC: case UV_SIGNAL: case UV_PROCESS: case UV_FS_EVENT: case UV_FS_POLL: jl_close_uv(handle); break; case UV_HANDLE: case UV_STREAM: case UV_UNKNOWN_HANDLE: case UV_HANDLE_TYPE_MAX: case UV_RAW_FD: case UV_RAW_HANDLE: default: assert(0); } item = item->next; } uv_run(loop,UV_RUN_DEFAULT); //let libuv spin until everything has finished closing }
jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd, jl_tuple_t *argtypes, jl_function_t *f, jl_tuple_t *t) { jl_value_t *gf; if (bnd) { //jl_declare_constant(bnd); if (bnd->value != NULL && !bnd->constp) { jl_errorf("cannot define function %s; it already has a value", bnd->name->name); } bnd->constp = 1; } if (*bp == NULL) { gf = (jl_value_t*)jl_new_generic_function(name); *bp = gf; } else { gf = *bp; if (!jl_is_gf(gf)) { if (jl_is_datatype(gf) && ((jl_function_t*)gf)->fptr == jl_f_ctor_trampoline) { jl_add_constructors((jl_datatype_t*)gf); } if (!jl_is_gf(gf)) { jl_error("invalid method definition: not a generic function"); } } } JL_GC_PUSH1(&gf); assert(jl_is_function(f)); assert(jl_is_tuple(argtypes)); assert(jl_is_tuple(t)); for(size_t i=0; i < jl_tuple_len(argtypes); i++) { jl_value_t *elt = jl_tupleref(argtypes,i); if (!jl_is_type(elt) && !jl_is_typevar(elt)) { jl_lambda_info_t *li = f->linfo; jl_errorf("invalid type for argument %s in method definition for %s at %s:%d", jl_is_expr(li->ast) ? ((jl_sym_t*)jl_arrayref(jl_lam_args((jl_expr_t*)li->ast),i))->name : "?", name->name, li->file->name, li->line); } } int ishidden = !!strchr(name->name, '#'); for(size_t i=0; i < jl_tuple_len(t); i++) { jl_value_t *tv = jl_tupleref(t,i); if (!jl_is_typevar(tv)) jl_type_error_rt(name->name, "method definition", (jl_value_t*)jl_tvar_type, tv); if (!ishidden && !type_contains((jl_value_t*)argtypes, tv)) { JL_PRINTF(JL_STDERR, "Warning: static parameter %s does not occur in signature for %s", ((jl_tvar_t*)tv)->name->name, name->name); print_func_loc(JL_STDERR, f->linfo); JL_PRINTF(JL_STDERR, ".\nThe method will not be callable.\n"); } } jl_add_method((jl_function_t*)gf, argtypes, f, t); if (jl_boot_file_loaded && f->linfo && f->linfo->ast && jl_is_expr(f->linfo->ast)) { jl_lambda_info_t *li = f->linfo; li->ast = jl_compress_ast(li, li->ast); } JL_GC_POP(); return gf; }
DLLEXPORT void uv_atexit_hook() { #if defined(JL_GC_MARKSWEEP) && defined(GC_FINAL_STATS) jl_print_gc_stats(JL_STDERR); #endif if (jl_base_module) { jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("_atexit")); if (f!=NULL && jl_is_function(f)) { jl_apply((jl_function_t*)f, NULL, 0); } } uv_loop_t* loop = jl_global_event_loop(); struct uv_shutdown_queue queue = {NULL, NULL}; uv_walk(loop, jl_uv_exitcleanup_walk, &queue); // close stdout and stderr last, since we like being // able to show stuff (incl. printf's) jl_uv_exitcleanup_add((uv_handle_t*)jl_uv_stdout, &queue); jl_uv_exitcleanup_add((uv_handle_t*)jl_uv_stderr, &queue); struct uv_shutdown_queue_item *item = queue.first; while (item) { uv_handle_t *handle = item->h; if (uv_is_closing(handle)) { item = item->next; continue; } switch(handle->type) { case UV_TTY: case UV_UDP: //#ifndef _OS_WINDOWS_ // unix only supports shutdown on TCP and NAMED_PIPE // but uv_shutdown doesn't seem to be particularly reliable, so we'll avoid it in general jl_close_uv(handle); break; //#endif case UV_TCP: case UV_NAMED_PIPE: // These will be shut down in jl_close_uv. jl_close_uv(handle); break; //Don't close these directly, but rather let the GC take care of it case UV_POLL: uv_poll_stop((uv_poll_t*)handle); handle->data = NULL; uv_unref(handle); break; case UV_TIMER: uv_timer_stop((uv_timer_t*)handle); handle->data = NULL; uv_unref(handle); break; case UV_IDLE: uv_idle_stop((uv_idle_t*)handle); case UV_ASYNC: handle->data = NULL; uv_unref(handle); break; case UV_FS_EVENT: handle->data = NULL; uv_unref(handle); break; case UV_FS_POLL: uv_fs_poll_stop((uv_fs_poll_t*)handle); handle->data = NULL; uv_unref(handle); break; case UV_PREPARE: case UV_CHECK: case UV_SIGNAL: case UV_PROCESS: jl_close_uv(handle); break; case UV_HANDLE: case UV_STREAM: case UV_UNKNOWN_HANDLE: case UV_HANDLE_TYPE_MAX: case UV_RAW_FD: case UV_RAW_HANDLE: default: assert(0); } item = item->next; } uv_run(loop,UV_RUN_DEFAULT); //let libuv spin until everything has finished closing }
DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd, jl_tuple_t *argtypes, jl_function_t *f, jl_value_t *isstaged, jl_value_t *call_func, int iskw) { // argtypes is a tuple ((types...), (typevars...)) jl_tuple_t *t = (jl_tuple_t*)jl_t1(argtypes); argtypes = (jl_tuple_t*)jl_t0(argtypes); jl_value_t *gf=NULL; JL_GC_PUSH3(&gf, &argtypes, &t); if (bnd && bnd->value != NULL && !bnd->constp) { jl_errorf("cannot define function %s; it already has a value", bnd->name->name); } if (*bp != NULL) { gf = *bp; if (!jl_is_gf(gf)) { if (jl_is_datatype(gf)) { // DataType: define `call`, for backwards compat with outer constructors if (call_func == NULL) call_func = (jl_value_t*)jl_module_call_func(jl_current_module); size_t na = jl_tuple_len(argtypes); jl_tuple_t *newargtypes = jl_alloc_tuple(1 + na); JL_GC_PUSH1(&newargtypes); size_t i=0; if (iskw) { assert(na > 0); // for kw sorter, keep container argument first jl_tupleset(newargtypes, 0, jl_tupleref(argtypes, 0)); i++; } jl_tupleset(newargtypes, i, jl_wrap_Type(gf)); i++; for(; i < na+1; i++) { jl_tupleset(newargtypes, i, jl_tupleref(argtypes, i-1)); } argtypes = newargtypes; JL_GC_POP(); gf = call_func; name = call_sym; // edit args, insert type first if (!jl_is_expr(f->linfo->ast)) f->linfo->ast = jl_uncompress_ast(f->linfo, f->linfo->ast); jl_array_t *al = jl_lam_args((jl_expr_t*)f->linfo->ast); if (jl_array_len(al) == 0) { al = jl_alloc_cell_1d(1); jl_exprarg(f->linfo->ast, 0) = (jl_value_t*)al; } else { jl_array_grow_beg(al, 1); } if (iskw) { jl_cellset(al, 0, jl_cellref(al, 1)); jl_cellset(al, 1, (jl_value_t*)jl_gensym()); } else { jl_cellset(al, 0, (jl_value_t*)jl_gensym()); } } if (!jl_is_gf(gf)) { jl_error("invalid method definition: not a generic function"); } } if (iskw) { bp = (jl_value_t**)&((jl_methtable_t*)((jl_function_t*)gf)->env)->kwsorter; gf = *bp; } } size_t na = jl_tuple_len(argtypes); for(size_t i=0; i < na; i++) { jl_value_t *elt = jl_tupleref(argtypes,i); if (!jl_is_type(elt) && !jl_is_typevar(elt)) { jl_lambda_info_t *li = f->linfo; jl_errorf("invalid type for argument %s in method definition for %s at %s:%d", jl_lam_argname(li,i)->name, name->name, li->file->name, li->line); } } int ishidden = !!strchr(name->name, '#'); for(size_t i=0; i < jl_tuple_len(t); i++) { jl_value_t *tv = jl_tupleref(t,i); if (!jl_is_typevar(tv)) jl_type_error_rt(name->name, "method definition", (jl_value_t*)jl_tvar_type, tv); if (!ishidden && !type_contains((jl_value_t*)argtypes, tv)) { JL_PRINTF(JL_STDERR, "Warning: static parameter %s does not occur in signature for %s", ((jl_tvar_t*)tv)->name->name, name->name); print_func_loc(JL_STDERR, f->linfo); JL_PRINTF(JL_STDERR, ".\nThe method will not be callable.\n"); } } if (bnd) { bnd->constp = 1; } if (*bp == NULL) { gf = (jl_value_t*)jl_new_generic_function(name); *bp = gf; } assert(jl_is_function(f)); assert(jl_is_tuple(argtypes)); assert(jl_is_tuple(t)); jl_add_method((jl_function_t*)gf, argtypes, f, t, isstaged == jl_true); if (jl_boot_file_loaded && f->linfo && f->linfo->ast && jl_is_expr(f->linfo->ast)) { jl_lambda_info_t *li = f->linfo; li->ast = jl_compress_ast(li, li->ast); } JL_GC_POP(); return gf; }
DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_value_t *bp_owner, jl_binding_t *bnd, jl_svec_t *argdata, jl_function_t *f, jl_value_t *isstaged, jl_value_t *call_func, int iskw) { jl_module_t *module = (bnd ? bnd->owner : NULL); // argdata is svec({types...}, svec(typevars...)) jl_tupletype_t *argtypes = (jl_tupletype_t*)jl_svecref(argdata,0); jl_svec_t *tvars = (jl_svec_t*)jl_svecref(argdata,1); jl_value_t *gf = NULL; JL_GC_PUSH4(&gf, &tvars, &argtypes, &f); if (bnd && bnd->value != NULL && !bnd->constp) { jl_errorf("cannot define function %s; it already has a value", bnd->name->name); } if (*bp != NULL) { gf = *bp; if (!jl_is_gf(gf)) { if (jl_is_datatype(gf)) { // DataType: define `call`, for backwards compat with outer constructors if (call_func == NULL) call_func = (jl_value_t*)jl_module_call_func(jl_current_module); size_t na = jl_nparams(argtypes); jl_svec_t *newargtypes = jl_alloc_svec(1 + na); jl_lambda_info_t *new_linfo = NULL; JL_GC_PUSH2(&newargtypes, &new_linfo); new_linfo = jl_copy_lambda_info(f->linfo); f = jl_new_closure(f->fptr, f->env, new_linfo); size_t i=0; if (iskw) { assert(na > 0); // for kw sorter, keep container argument first jl_svecset(newargtypes, 0, jl_tparam(argtypes, 0)); i++; } jl_svecset(newargtypes, i, jl_wrap_Type(gf)); i++; for(; i < na+1; i++) { jl_svecset(newargtypes, i, jl_tparam(argtypes, i-1)); } argtypes = jl_apply_tuple_type(newargtypes); JL_GC_POP(); gf = call_func; name = call_sym; // edit args, insert type first if (!jl_is_expr(f->linfo->ast)) { f->linfo->ast = jl_uncompress_ast(f->linfo, f->linfo->ast); jl_gc_wb(f->linfo, f->linfo->ast); } else { // Do not mutate the original ast since it might // be reused somewhere else f->linfo->ast = jl_copy_ast(f->linfo->ast); jl_gc_wb(f->linfo, f->linfo->ast); } jl_array_t *al = jl_lam_args((jl_expr_t*)f->linfo->ast); if (jl_array_len(al) == 0) { al = jl_alloc_cell_1d(1); jl_exprargset(f->linfo->ast, 0, (jl_value_t*)al); } else { jl_array_grow_beg(al, 1); } if (iskw) { jl_cellset(al, 0, jl_cellref(al, 1)); jl_cellset(al, 1, (jl_value_t*)jl_gensym()); } else { jl_cellset(al, 0, (jl_value_t*)jl_gensym()); } } if (!jl_is_gf(gf)) { jl_errorf("cannot define function %s; it already has a value", name->name); } } if (iskw) { jl_methtable_t *mt = jl_gf_mtable(gf); assert(!module); module = mt->module; bp = (jl_value_t**)&mt->kwsorter; bp_owner = (jl_value_t*)mt; gf = *bp; } } // TODO size_t na = jl_nparams(argtypes); for(size_t i=0; i < na; i++) { jl_value_t *elt = jl_tparam(argtypes,i); if (!jl_is_type(elt) && !jl_is_typevar(elt)) { jl_lambda_info_t *li = f->linfo; jl_exceptionf(jl_argumenterror_type, "invalid type for argument %s in method definition for %s at %s:%d", jl_lam_argname(li,i)->name, name->name, li->file->name, li->line); } } int ishidden = !!strchr(name->name, '#'); for(size_t i=0; i < jl_svec_len(tvars); i++) { jl_value_t *tv = jl_svecref(tvars,i); if (!jl_is_typevar(tv)) jl_type_error_rt(name->name, "method definition", (jl_value_t*)jl_tvar_type, tv); if (!ishidden && !type_contains((jl_value_t*)argtypes, tv)) { jl_printf(JL_STDERR, "WARNING: static parameter %s does not occur in signature for %s", ((jl_tvar_t*)tv)->name->name, name->name); print_func_loc(JL_STDERR, f->linfo); jl_printf(JL_STDERR, ".\nThe method will not be callable.\n"); } } if (bnd) { bnd->constp = 1; } if (*bp == NULL) { gf = (jl_value_t*)jl_new_generic_function(name, module); *bp = gf; if (bp_owner) jl_gc_wb(bp_owner, gf); } assert(jl_is_function(f)); assert(jl_is_tuple_type(argtypes)); assert(jl_is_svec(tvars)); jl_add_method((jl_function_t*)gf, argtypes, f, tvars, isstaged == jl_true); if (jl_boot_file_loaded && f->linfo && f->linfo->ast && jl_is_expr(f->linfo->ast)) { jl_lambda_info_t *li = f->linfo; li->ast = jl_compress_ast(li, li->ast); jl_gc_wb(li, li->ast); } JL_GC_POP(); return gf; }
static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl) { if (jl_is_symbol(e)) { jl_value_t *v; size_t i; for(i=0; i < nl; i++) { if (locals[i*2] == e) { v = locals[i*2+1]; break; } } if (i >= nl) { v = jl_get_global(jl_current_module, (jl_sym_t*)e); } if (v == NULL) { jl_errorf("%s not defined", ((jl_sym_t*)e)->name); } return v; } if (jl_is_symbolnode(e)) { return eval((jl_value_t*)jl_symbolnode_sym(e), locals, nl); } if (jl_is_quotenode(e)) { return jl_fieldref(e,0); } if (jl_is_topnode(e)) { jl_sym_t *s = (jl_sym_t*)jl_fieldref(e,0); jl_value_t *v = jl_get_global(jl_base_relative_to(jl_current_module),s); if (v == NULL) jl_errorf("%s not defined", s->name); return v; } if (!jl_is_expr(e)) { if (jl_is_getfieldnode(e)) { jl_value_t *v = eval(jl_getfieldnode_val(e), locals, nl); jl_value_t *gfargs[2] = {v, (jl_value_t*)jl_getfieldnode_name(e)}; return jl_f_get_field(NULL, gfargs, 2); } if (jl_is_lambda_info(e)) { return (jl_value_t*)jl_new_closure(NULL, (jl_value_t*)jl_null, (jl_lambda_info_t*)e); } if (jl_is_linenode(e)) { jl_lineno = jl_linenode_line(e); } return e; } jl_expr_t *ex = (jl_expr_t*)e; jl_value_t **args = &jl_cellref(ex->args,0); size_t nargs = jl_array_len(ex->args); if (ex->head == call_sym || ex->head == call1_sym) { jl_function_t *f = (jl_function_t*)eval(args[0], locals, nl); if (!jl_is_func(f)) jl_type_error("apply", (jl_value_t*)jl_function_type, (jl_value_t*)f); return do_call(f, &args[1], nargs-1, locals, nl); } else if (ex->head == assign_sym) { jl_value_t *sym = args[0]; size_t i; for (i=0; i < nl; i++) { if (locals[i*2] == sym) { return (locals[i*2+1] = eval(args[1], locals, nl)); } } jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)sym); jl_value_t *rhs = eval(args[1], locals, nl); jl_checked_assignment(b, rhs); return rhs; } else if (ex->head == new_sym) { jl_value_t *thetype = eval(args[0], locals, nl); jl_value_t *v=NULL; JL_GC_PUSH(&thetype, &v); assert(jl_is_structtype(thetype)); v = jl_new_struct_uninit((jl_datatype_t*)thetype); for(size_t i=1; i < nargs; i++) { jl_set_nth_field(v, i-1, eval(args[i], locals, nl)); } JL_GC_POP(); return v; } else if (ex->head == null_sym) { return (jl_value_t*)jl_nothing; } else if (ex->head == body_sym) { return eval_body(ex->args, locals, nl, 0); } else if (ex->head == exc_sym) { return jl_exception_in_transit; } else if (ex->head == static_typeof_sym) { return (jl_value_t*)jl_any_type; } else if (ex->head == method_sym) { jl_sym_t *fname = (jl_sym_t*)args[0]; jl_value_t **bp=NULL; jl_binding_t *b=NULL; jl_value_t *gf=NULL; int kw=0; if (jl_is_expr(fname)) { if (((jl_expr_t*)fname)->head == kw_sym) { kw = 1; fname = (jl_sym_t*)jl_exprarg(fname, 0); } gf = eval((jl_value_t*)fname, locals, nl); assert(jl_is_function(gf)); assert(jl_is_gf(gf)); if (!kw) { fname = (jl_sym_t*)jl_fieldref(jl_exprarg(fname, 2), 0); bp = &gf; } else { bp = (jl_value_t**)&((jl_methtable_t*)((jl_function_t*)gf)->env)->kwsorter; } assert(jl_is_symbol(fname)); } else { for (size_t i=0; i < nl; i++) { if (locals[i*2] == (jl_value_t*)fname) { bp = &locals[i*2+1]; break; } } if (bp == NULL) { b = jl_get_binding_for_method_def(jl_current_module, fname); bp = &b->value; } } jl_value_t *atypes=NULL, *meth=NULL, *tvars=NULL; JL_GC_PUSH(&atypes, &meth, &tvars); atypes = eval(args[1], locals, nl); meth = eval(args[2], locals, nl); tvars = eval(args[3], locals, nl); jl_method_def(fname, bp, b, (jl_tuple_t*)atypes, (jl_function_t*)meth, (jl_tuple_t*)tvars); JL_GC_POP(); return *bp; } else if (ex->head == const_sym) { jl_value_t *sym = args[0]; for (size_t i=0; i < nl; i++) { if (locals[i*2] == sym) { return (jl_value_t*)jl_nothing; } } jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)sym); jl_declare_constant(b); return (jl_value_t*)jl_nothing; } else if (ex->head == global_sym) { // create uninitialized mutable binding for "global x" decl // TODO: handle type decls for (size_t i=0; i < jl_array_len(ex->args); i++) { assert(jl_is_symbol(args[i])); jl_get_binding_wr(jl_current_module, (jl_sym_t*)args[i]); } return (jl_value_t*)jl_nothing; } else if (ex->head == abstracttype_sym) { jl_value_t *name = args[0]; jl_value_t *para = eval(args[1], locals, nl); jl_value_t *super = NULL; JL_GC_PUSH(¶, &super); jl_datatype_t *dt = jl_new_abstracttype(name, jl_any_type, (jl_tuple_t*)para); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); jl_checked_assignment(b, (jl_value_t*)dt); super = eval(args[2], locals, nl); jl_set_datatype_super(dt, super); JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == bitstype_sym) { jl_value_t *name = args[0]; jl_value_t *super = NULL, *para = NULL, *vnb = NULL; JL_GC_PUSH(¶, &super, &vnb); para = eval(args[1], locals, nl); vnb = eval(args[2], locals, nl); if (!jl_is_long(vnb)) jl_errorf("invalid declaration of bits type %s", ((jl_sym_t*)name)->name); int32_t nb = jl_unbox_long(vnb); if (nb < 1 || nb>=(1<<23) || (nb&7) != 0) jl_errorf("invalid number of bits in type %s", ((jl_sym_t*)name)->name); jl_datatype_t *dt = jl_new_bitstype(name, jl_any_type, (jl_tuple_t*)para, nb); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); jl_checked_assignment(b, (jl_value_t*)dt); super = eval(args[3], locals, nl); jl_set_datatype_super(dt, super); JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == compositetype_sym) { void jl_add_constructors(jl_datatype_t *t); jl_value_t *name = args[0]; jl_value_t *para = eval(args[1], locals, nl); jl_value_t *fnames = NULL; jl_value_t *super = NULL; jl_datatype_t *dt = NULL; JL_GC_PUSH(¶, &super, &fnames, &dt); fnames = eval(args[2], locals, nl); dt = jl_new_datatype((jl_sym_t*)name, jl_any_type, (jl_tuple_t*)para, (jl_tuple_t*)fnames, NULL, 0, args[6]==jl_true ? 1 : 0); dt->fptr = jl_f_ctor_trampoline; dt->ctor_factory = eval(args[3], locals, nl); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); jl_checked_assignment(b, (jl_value_t*)dt); inside_typedef = 1; dt->types = (jl_tuple_t*)eval(args[5], locals, nl); inside_typedef = 0; jl_check_type_tuple(dt->types, dt->name->name, "type definition"); super = eval(args[4], locals, nl); jl_set_datatype_super(dt, super); jl_compute_field_offsets(dt); jl_add_constructors(dt); JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == macro_sym) { jl_sym_t *nm = (jl_sym_t*)args[0]; assert(jl_is_symbol(nm)); jl_function_t *f = (jl_function_t*)eval(args[1], locals, nl); assert(jl_is_function(f)); if (jl_boot_file_loaded && f->linfo && f->linfo->ast && jl_is_expr(f->linfo->ast)) { jl_lambda_info_t *li = f->linfo; li->ast = jl_compress_ast(li, li->ast); li->name = nm; } jl_set_global(jl_current_module, nm, (jl_value_t*)f); return (jl_value_t*)jl_nothing; } else if (ex->head == line_sym) { jl_lineno = jl_unbox_long(jl_exprarg(ex,0)); return (jl_value_t*)jl_nothing; } else if (ex->head == module_sym) { return jl_eval_module_expr(ex); } else if (ex->head == error_sym || ex->head == jl_continue_sym) { if (jl_is_byte_string(args[0])) jl_errorf("syntax: %s", jl_string_data(args[0])); jl_throw(args[0]); } jl_errorf("unsupported or misplaced expression %s", ex->head->name); return (jl_value_t*)jl_nothing; }
static void jl_serialize_value_(ios_t *s, jl_value_t *v) { if (v == NULL) { write_uint8(s, Null_tag); return; } void **bp = ptrhash_bp(&ser_tag, v); if (*bp != HT_NOTFOUND) { write_as_tag(s, (uint8_t)(ptrint_t)*bp); return; } if (tree_literal_values) { // compressing tree if (!is_ast_node(v)) { writetag(s, (jl_value_t*)LiteralVal_tag); write_uint16(s, literal_val_id(v)); return; } } else { bp = ptrhash_bp(&backref_table, v); if (*bp != HT_NOTFOUND) { write_uint8(s, BackRef_tag); write_int32(s, (ptrint_t)*bp); return; } ptrhash_put(&backref_table, v, (void*)(ptrint_t)ios_pos(s)); } size_t i; if (jl_is_tuple(v)) { size_t l = ((jl_tuple_t*)v)->length; if (l <= 255) { writetag(s, jl_tuple_type); write_uint8(s, (uint8_t)l); } else { writetag(s, (jl_value_t*)LongTuple_tag); write_int32(s, l); } for(i=0; i < l; i++) { jl_serialize_value(s, jl_tupleref(v, i)); } } else if (jl_is_symbol(v)) { size_t l = strlen(((jl_sym_t*)v)->name); if (l <= 255) { writetag(s, jl_symbol_type); write_uint8(s, (uint8_t)l); } else { writetag(s, (jl_value_t*)LongSymbol_tag); write_int32(s, l); } ios_write(s, ((jl_sym_t*)v)->name, l); } else if (jl_is_array(v)) { jl_array_t *ar = (jl_array_t*)v; writetag(s, (jl_value_t*)jl_array_type); jl_serialize_value(s, ar->type); jl_value_t *elty = jl_tparam0(ar->type); for (i=0; i < ar->ndims; i++) jl_serialize_value(s, jl_box_long(jl_array_dim(ar,i))); if (jl_is_bits_type(elty)) { size_t tot = ar->length * ar->elsize; ios_write(s, ar->data, tot); } else { for(i=0; i < ar->length; i++) { jl_serialize_value(s, jl_cellref(v, i)); } } } else if (jl_is_expr(v)) { jl_expr_t *e = (jl_expr_t*)v; size_t l = e->args->length; if (l <= 255) { writetag(s, jl_expr_type); write_uint8(s, (uint8_t)l); } else { writetag(s, (jl_value_t*)LongExpr_tag); write_int32(s, l); } jl_serialize_value(s, e->head); jl_serialize_value(s, e->etype); for(i=0; i < l; i++) { jl_serialize_value(s, jl_exprarg(e, i)); } } else if (jl_is_some_tag_type(v)) { jl_serialize_tag_type(s, v); } else if (jl_is_typevar(v)) { writetag(s, jl_tvar_type); jl_serialize_value(s, ((jl_tvar_t*)v)->name); jl_serialize_value(s, ((jl_tvar_t*)v)->lb); jl_serialize_value(s, ((jl_tvar_t*)v)->ub); write_int8(s, ((jl_tvar_t*)v)->bound); } else if (jl_is_function(v)) { writetag(s, jl_func_kind); jl_serialize_value(s, v->type); jl_function_t *f = (jl_function_t*)v; jl_serialize_value(s, (jl_value_t*)f->linfo); jl_serialize_value(s, f->env); if (f->linfo && f->linfo->ast && (jl_is_expr(f->linfo->ast) || jl_is_tuple(f->linfo->ast)) && f->fptr != &jl_trampoline) { write_int32(s, 0); } else { jl_serialize_fptr(s, f->fptr); } } else if (jl_is_lambda_info(v)) { writetag(s, jl_lambda_info_type); jl_lambda_info_t *li = (jl_lambda_info_t*)v; jl_serialize_value(s, li->ast); jl_serialize_value(s, (jl_value_t*)li->sparams); // don't save cached type info for code in the Base module, because // it might reference types in the old System module. if (li->module == jl_base_module) jl_serialize_value(s, (jl_value_t*)jl_null); else jl_serialize_value(s, (jl_value_t*)li->tfunc); jl_serialize_value(s, (jl_value_t*)li->name); jl_serialize_value(s, (jl_value_t*)li->specTypes); jl_serialize_value(s, (jl_value_t*)li->specializations); jl_serialize_value(s, (jl_value_t*)li->inferred); jl_serialize_value(s, (jl_value_t*)li->file); jl_serialize_value(s, (jl_value_t*)li->line); jl_serialize_value(s, (jl_value_t*)li->module); } else if (jl_typeis(v, jl_module_type)) { jl_serialize_module(s, (jl_module_t*)v); } else if (jl_typeis(v, jl_methtable_type)) { writetag(s, jl_methtable_type); jl_methtable_t *mt = (jl_methtable_t*)v; jl_serialize_methlist(s, mt->defs); jl_serialize_methlist(s, mt->cache); jl_serialize_value(s, mt->cache_1arg); write_int32(s, mt->max_args); } else if (jl_typeis(v, jl_task_type)) { jl_error("Task cannot be serialized"); } else { jl_value_t *t = (jl_value_t*)jl_typeof(v); if (jl_is_bits_type(t)) { void *data = jl_bits_data(v); if (t == (jl_value_t*)jl_int64_type && *(int64_t*)data >= S32_MIN && *(int64_t*)data <= S32_MAX) { writetag(s, (jl_value_t*)SmallInt64_tag); write_int32(s, (int32_t)*(int64_t*)data); } else { int nb = ((jl_bits_type_t*)t)->nbits; writetag(s, jl_bits_kind); jl_serialize_value(s, t); ios_write(s, data, nb/8); } } else if (jl_is_struct_type(t)) { writetag(s, jl_struct_kind); jl_serialize_value(s, t); size_t nf = ((jl_struct_type_t*)t)->names->length; size_t i; for(i=0; i < nf; i++) { jl_value_t *fld = ((jl_value_t**)v)[i+1]; jl_serialize_value(s, fld); } if (t == jl_idtable_type) { jl_cell_1d_push(idtable_list, v); } } else { assert(0); } } }