diff --git a/base/loading.jl b/base/loading.jl index 528a33ecb4944..2803460cadb4d 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -378,8 +378,8 @@ end # remote/parallel load include_string(txt::String, fname::String) = - ccall(:jl_load_file_string, Any, (Ptr{UInt8},Csize_t,Ptr{UInt8},Csize_t), - txt, sizeof(txt), fname, sizeof(fname)) + ccall(:jl_load_file_string, Any, (Ptr{UInt8},Csize_t,Cstring), + txt, sizeof(txt), fname) include_string(txt::AbstractString, fname::AbstractString="string") = include_string(String(txt), String(fname)) diff --git a/src/array.c b/src/array.c index 9656498997a29..bc014ff6c5dd8 100644 --- a/src/array.c +++ b/src/array.c @@ -791,6 +791,46 @@ JL_DLLEXPORT jl_value_t *(jl_array_data_owner)(jl_array_t *a) return jl_array_data_owner(a); } +STATIC_INLINE int jl_has_implicit_byte_owned(jl_array_t *a) +{ + assert(a->flags.how != 3); + if (!a->flags.isshared) + return 1; + return a->flags.how == 1; +} + +STATIC_INLINE int jl_has_implicit_byte(jl_array_t *a) +{ + // * unshared: + // * how: 0-2 + // We own and allocated the data. + // It should have the extra byte. + // * shared: + // * how: 0, 2 + // The data might come from external source without implicit NUL byte. + // There could be an entra byte for a `reinterpreted` array + // but that should be unlikely for strings. + // * how: 1 + // We allocated the data with the extra byte. + // * how: 3 + // We should check the owner. + if (a->flags.how == 3) { + a = (jl_array_t*)jl_array_data_owner(a); + return a->elsize == 1 && jl_has_implicit_byte_owned(a); + } + return jl_has_implicit_byte_owned(a); +} + +// Create an array with the same content +JL_DLLEXPORT jl_array_t *jl_array_cconvert_cstring(jl_array_t *a) +{ + assert(jl_typeof(a) == jl_array_uint8_type); + if (!jl_has_implicit_byte(a)) + a = jl_array_copy(a); + ((char*)a->data)[a->nrows] = 0; + return a; +} + #ifdef __cplusplus } #endif diff --git a/src/ast.c b/src/ast.c index b01980ba100aa..e620d1a94eb4b 100644 --- a/src/ast.c +++ b/src/ast.c @@ -641,7 +641,7 @@ JL_DLLEXPORT jl_value_t *jl_parse_string(const char *str, size_t len, } // parse and eval a whole file, possibly reading from a string (`content`) -jl_value_t *jl_parse_eval_all(const char *fname, size_t len, +jl_value_t *jl_parse_eval_all(const char *fname, const char *content, size_t contentlen) { if (in_pure_callback) @@ -649,6 +649,7 @@ jl_value_t *jl_parse_eval_all(const char *fname, size_t len, jl_ast_context_t *ctx = jl_ast_ctx_enter(); fl_context_t *fl_ctx = &ctx->fl; value_t f, ast; + size_t len = strlen(fname); f = cvalue_static_cstrn(fl_ctx, fname, len); fl_gc_handle(fl_ctx, &f); if (content != NULL) { @@ -723,9 +724,9 @@ jl_value_t *jl_parse_eval_all(const char *fname, size_t len, } JL_DLLEXPORT jl_value_t *jl_load_file_string(const char *text, size_t len, - char *filename, size_t namelen) + char *filename) { - return jl_parse_eval_all(filename, namelen, text, len); + return jl_parse_eval_all(filename, text, len); } JL_DLLEXPORT int jl_parse_depwarn(int warn) diff --git a/src/init.c b/src/init.c index 06df5fb4112e1..6b794c68cf2bf 100644 --- a/src/init.c +++ b/src/init.c @@ -653,7 +653,7 @@ void _julia_init(JL_IMAGE_SEARCH rel) jl_all_tls_states[t]->root_task->current_module = jl_current_module; } - jl_load("boot.jl", sizeof("boot.jl")-1); + jl_load("boot.jl"); jl_get_builtin_hooks(); jl_boot_file_loaded = 1; jl_init_box_caches(); diff --git a/src/julia.h b/src/julia.h index c80cb6ebe62ad..ad021d135319c 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1315,7 +1315,7 @@ JL_DLLEXPORT jl_value_t *jl_parse_string(const char *str, size_t len, int pos0, int greedy); JL_DLLEXPORT int jl_parse_depwarn(int warn); JL_DLLEXPORT jl_value_t *jl_load_file_string(const char *text, size_t len, - char *filename, size_t namelen); + char *filename); JL_DLLEXPORT jl_value_t *jl_expand(jl_value_t *expr); JL_DLLEXPORT jl_value_t *jl_eval_string(const char *str); @@ -1350,7 +1350,7 @@ JL_DLLEXPORT const char *jl_lookup_soname(const char *pfx, size_t n); // compiler JL_DLLEXPORT jl_value_t *jl_toplevel_eval(jl_value_t *v); JL_DLLEXPORT jl_value_t *jl_toplevel_eval_in(jl_module_t *m, jl_value_t *ex); -JL_DLLEXPORT jl_value_t *jl_load(const char *fname, size_t len); +JL_DLLEXPORT jl_value_t *jl_load(const char *fname); JL_DLLEXPORT jl_value_t *jl_interpret_toplevel_expr_in(jl_module_t *m, jl_value_t *e, jl_lambda_info_t *lam); JL_DLLEXPORT jl_module_t *jl_base_relative_to(jl_module_t *m); diff --git a/src/julia_internal.h b/src/julia_internal.h index 2edfe782d1ad4..40c184c35bba4 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -196,7 +196,7 @@ jl_value_t *jl_toplevel_eval_in_warn(jl_module_t *m, jl_value_t *ex, jl_lambda_info_t *jl_wrap_expr(jl_value_t *expr); jl_value_t *jl_eval_global_var(jl_module_t *m, jl_sym_t *e); -jl_value_t *jl_parse_eval_all(const char *fname, size_t len, +jl_value_t *jl_parse_eval_all(const char *fname, const char *content, size_t contentlen); jl_value_t *jl_interpret_toplevel_thunk(jl_lambda_info_t *lam); jl_value_t *jl_interpret_toplevel_expr(jl_value_t *e); @@ -662,6 +662,8 @@ STATIC_INLINE void *jl_get_frame_addr(void) #endif } +JL_DLLEXPORT jl_array_t *jl_array_cconvert_cstring(jl_array_t *a); + #ifdef __cplusplus } #endif diff --git a/src/toplevel.c b/src/toplevel.c index 69a0f55f41d3e..ea048c1c8eff5 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -551,28 +551,30 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval(jl_value_t *v) return jl_toplevel_eval_flex(v, 1, 0); } -JL_DLLEXPORT jl_value_t *jl_load(const char *fname, size_t len) +JL_DLLEXPORT jl_value_t *jl_load(const char *fname) { - if (NULL != memchr(fname, 0, len)) - jl_exceptionf(jl_argumenterror_type, "file name may not contain \\0"); if (jl_current_module->istopmod) { jl_printf(JL_STDOUT, "%s\r\n", fname); #ifdef _OS_WINDOWS_ uv_run(uv_default_loop(), (uv_run_mode)1); #endif } - char *fpath = (char*)fname; uv_stat_t stbuf; - if (jl_stat(fpath, (char*)&stbuf) != 0 || (stbuf.st_mode & S_IFMT) != S_IFREG) { - jl_errorf("could not open file %s", fpath); + if (jl_stat(fname, (char*)&stbuf) != 0 || (stbuf.st_mode & S_IFMT) != S_IFREG) { + jl_errorf("could not open file %s", fname); } - return jl_parse_eval_all(fpath, len, NULL, 0); + return jl_parse_eval_all(fname, NULL, 0); } // load from filename given as a String object JL_DLLEXPORT jl_value_t *jl_load_(jl_value_t *str) { - return jl_load(jl_string_data(str), jl_string_len(str)); + jl_array_t *ary = + jl_array_cconvert_cstring((jl_array_t*)(jl_data_ptr(str)[0])); + JL_GC_PUSH1(&ary); + jl_value_t *res = jl_load((const char*)ary->data); + JL_GC_POP(); + return res; } // method definition ---------------------------------------------------------- diff --git a/test/loading.jl b/test/loading.jl index b7687d65d71e8..8d40b2c16981c 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -4,10 +4,8 @@ using Base.Test @test @__LINE__ == 5 -@test_throws ArgumentError Core.include("test_sourcepath.jl\0") - include("test_sourcepath.jl") -thefname = "the fname!//\\&\0\1*" +thefname = "the fname!//\\&\1*" @test include_string("include_string_test() = @__FILE__", thefname)() == Base.source_path() @test include_string("Base.source_path()", thefname) == Base.source_path() @test basename(@__FILE__) == "loading.jl" diff --git a/ui/repl.c b/ui/repl.c index c7f391a8189b4..b3ce29a1d4ece 100644 --- a/ui/repl.c +++ b/ui/repl.c @@ -487,7 +487,7 @@ static int exec_program(char *program) JL_EH_POP(); return 1; } - jl_load(program, strlen(program)); + jl_load(program); } JL_CATCH { err = 1;