From: Jean Privat Date: Thu, 10 Mar 2016 04:55:35 +0000 (-0500) Subject: Merge: Misc text: some improvement on `join` and `to_base` X-Git-Url: http://nitlanguage.org?hp=3099b07c441dec089a1675f3b0aad73b9b72944a Merge: Misc text: some improvement on `join` and `to_base` Pull-Request: #1977 Reviewed-by: Alexis Laferrière --- diff --git a/lib/core/file.nit b/lib/core/file.nit index 66b81aa..0454f1d 100644 --- a/lib/core/file.nit +++ b/lib/core/file.nit @@ -1145,11 +1145,16 @@ redef class String # Create a directory (and all intermediate directories if needed) # + # The optional `mode` parameter specifies the permissions of the directory, + # the default value is `0o777`. + # # Return an error object in case of error. # # assert "/etc/".mkdir != null - fun mkdir: nullable Error + fun mkdir(mode: nullable Int): nullable Error do + mode = mode or else 0o777 + var dirs = self.split_with("/") var path = new FlatBuffer if dirs.is_empty then return null @@ -1162,7 +1167,7 @@ redef class String if d.is_empty then continue path.append(d) path.add('/') - var res = path.to_s.to_cstring.file_mkdir + var res = path.to_s.to_cstring.file_mkdir(mode) if not res and error == null then error = new IOError("Cannot create directory `{path}`: {sys.errno.strerror}") end @@ -1326,7 +1331,7 @@ redef class NativeString return stat_element; `} - private fun file_mkdir: Bool `{ return !mkdir(self, 0777); `} + private fun file_mkdir(mode: Int): Bool `{ return !mkdir(self, mode); `} private fun rmdir: Bool `{ return !rmdir(self); `} diff --git a/src/compiler/compiler_ffi/compiler_ffi.nit b/src/compiler/compiler_ffi/compiler_ffi.nit index 79c2f14..7a536b1 100644 --- a/src/compiler/compiler_ffi/compiler_ffi.nit +++ b/src/compiler/compiler_ffi/compiler_ffi.nit @@ -262,18 +262,20 @@ redef class MExplicitCast # # In nitni files, declare internal function as extern - var full_friendly_csignature = "int {v.compiler.mainmodule.name }___{from.mangled_cname}_is_a_{to.mangled_cname}({from.cname_blind})" + var full_friendly_csignature = "int {v.compiler.mainmodule.c_name }___{from.mangled_cname}_is_a_{to.mangled_cname}({from.cname_blind})" ccu.header_decl.add("extern {full_friendly_csignature};\n") # In nitni files, #define friendly as extern - ccu.header_decl.add("#define {check_cname} {v.compiler.mainmodule.name}___{check_cname}\n") + ccu.header_decl.add "#ifndef {check_cname}\n" + ccu.header_decl.add "#define {check_cname} {v.compiler.mainmodule.c_name}___{check_cname}\n" + ccu.header_decl.add "#endif\n" if compile_implementation_too then # Internally, implement internal function var nitni_visitor = v.compiler.new_visitor nitni_visitor.frame = v.frame - var full_internal_csignature = "int {v.compiler.mainmodule.name }___{from.mangled_cname}_is_a_{to.mangled_cname}({internal_call_context.name_mtype(from)} from)" + var full_internal_csignature = "int {v.compiler.mainmodule.c_name }___{from.mangled_cname}_is_a_{to.mangled_cname}({internal_call_context.name_mtype(from)} from)" nitni_visitor.add_decl("/* nitni check for {from} to {to} */") nitni_visitor.add_decl("{full_internal_csignature} \{") @@ -289,7 +291,9 @@ redef class MExplicitCast # special checks if from == to.as_nullable then # format A_is_null - ccu.header_decl.add("#define {from.mangled_cname}_is_null !{from.mangled_cname}_is_a_{to.mangled_cname}\n") + ccu.header_decl.add "#ifndef {from.mangled_cname}_is_null\n" + ccu.header_decl.add "#define {from.mangled_cname}_is_null !{from.mangled_cname}_is_a_{to.mangled_cname}\n" + ccu.header_decl.add "#endif\n" end # @@ -297,18 +301,20 @@ redef class MExplicitCast # # In nitni files, declare internal function as extern - full_friendly_csignature = "{to.cname_blind} {v.compiler.mainmodule.name }___{from.mangled_cname}_as_{to.mangled_cname}({from.cname_blind})" + full_friendly_csignature = "{to.cname_blind} {v.compiler.mainmodule.c_name }___{from.mangled_cname}_as_{to.mangled_cname}({from.cname_blind})" ccu.header_decl.add("extern {full_friendly_csignature};\n") # In nitni files, #define friendly as extern - ccu.header_decl.add("#define {cast_cname} {v.compiler.mainmodule.name}___{cast_cname}\n") + ccu.header_decl.add "#ifndef {cast_cname}\n" + ccu.header_decl.add "#define {cast_cname} {v.compiler.mainmodule.c_name}___{cast_cname}\n" + ccu.header_decl.add "#endif\n" if compile_implementation_too then # Internally, implement internal function var nitni_visitor = v.compiler.new_visitor nitni_visitor.frame = v.frame - var full_internal_csignature = "{to.cname_blind} {v.compiler.mainmodule.name }___{from.mangled_cname}_as_{to.mangled_cname}({internal_call_context.name_mtype(from)} from)" + var full_internal_csignature = "{to.cname_blind} {v.compiler.mainmodule.c_name }___{from.mangled_cname}_as_{to.mangled_cname}({internal_call_context.name_mtype(from)} from)" nitni_visitor.add_decl("/* nitni cast for {from} to {to} */") nitni_visitor.add_decl("{full_internal_csignature} \{") @@ -333,12 +339,16 @@ redef class MExplicitCast # special casts if from.as_nullable == to then # format A_as_nullable - ccu.header_decl.add("#define {from.mangled_cname}_as_nullable {from.mangled_cname}_as_{to.mangled_cname}\n") + ccu.header_decl.add "#ifndef {from.mangled_cname}_as_nullable\n" + ccu.header_decl.add "#define {from.mangled_cname}_as_nullable {from.mangled_cname}_as_{to.mangled_cname}\n" + ccu.header_decl.add "#endif\n" end if from == to.as_nullable then # format A_as_nullable - ccu.header_decl.add("#define {to.mangled_cname}_as_not_nullable {from.mangled_cname}_as_{to.mangled_cname}\n") + ccu.header_decl.add "#ifndef {to.mangled_cname}_as_not_nullable\n" + ccu.header_decl.add "#define {to.mangled_cname}_as_not_nullable {from.mangled_cname}_as_{to.mangled_cname}\n" + ccu.header_decl.add "#endif\n" end end end diff --git a/src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit b/src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit index 85deec6..ab9e845 100644 --- a/src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit +++ b/src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit @@ -20,6 +20,15 @@ import c_tools import nitni import ffi import naive_interpreter +import debugger_socket # To linearize `ToolContext::init` + +redef class ToolContext + + # --compile-dir + var opt_compile_dir = new OptionString("Directory used to generate temporary files", "--compile-dir") + + init do option_context.add_option opt_compile_dir +end redef class AMethPropdef # Does this method definition use the FFI and is it supported by the interpreter? @@ -45,10 +54,25 @@ redef class AMethPropdef end redef class NaiveInterpreter + redef fun start(mainmodule) + do + super + + # Delete temporary files + var compile_dir = compile_dir + if compile_dir.file_exists then compile_dir.rmdir + end + # Where to store generated C and extracted code - # - # TODO make customizable and delete when execution completes - private var compile_dir = "nit_compile" + private var compile_dir: String is lazy do + # Prioritize the user supplied directory + var opt = modelbuilder.toolcontext.opt_compile_dir.value + if opt != null then return opt + return "/tmp/niti_ffi_{process_id}" + end + + # Identifier for this process, unique between running interpreters + private fun process_id: Int `{ return getpid(); `} # Path of the compiled foreign code library # @@ -75,7 +99,7 @@ redef class AModule var compile_dir = v.compile_dir var foreign_code_lib_path = v.foreign_code_lib_path(mmodule) - if not compile_dir.file_exists then compile_dir.mkdir + if not compile_dir.file_exists then compile_dir.mkdir(0o700) # Compile the common FFI part ensure_compile_ffi_wrapper diff --git a/src/nitni/nitni_utilities.nit b/src/nitni/nitni_utilities.nit index c0a8a15..910877b 100644 --- a/src/nitni/nitni_utilities.nit +++ b/src/nitni/nitni_utilities.nit @@ -19,7 +19,7 @@ import nitni_base redef class MMethod # Build a C function name for the FFI implementation (uses friendly naming). - # * On a specific static receiver mype `recv_mtype` + # * On a specific static receiver type `recv_mtype` # * In referene to the module `from_module` (used for type resolving and as a possible prefix) # * Has a possible `suffix` to the method name (may be "__super", "__impl", null, etc.) # * With a specified length indicating whether it uses the sort name or the long name with @@ -39,13 +39,13 @@ redef class MMethod if suffix != null then cname = "{cname}{suffix}" - if length.long then cname = "{from_mmodule.name}___{cname}" + if length.long then cname = "{from_mmodule.c_name}___{cname}" return cname end # Build a C function signature for the FFI implementation (uses friendly naming). - # * On a specific static receiver mype `recv_mtype` + # * On a specific static receiver type `recv_mtype` # * In referene to the module `from_module` (used for type resolving and as a possible prefix) # * Has a possible `suffix` to the method name (may be "__super", "__impl", null, etc.) # * With a specified length indicating whether it uses the sort name or the long name with @@ -83,7 +83,7 @@ redef class MMethod end # Build a C function call for the FFI implementation (uses friendly naming). - # * On a specific static receiver mype `recv_mtype` + # * On a specific static receiver type `recv_mtype` # * In referene to the module `from_module` (used for type resolving and as a possible prefix) # * Has a possible `suffix` to the method name (may be "__super", "__impl", null, etc.) # * With a specified length indicating whether it uses the sort name or the long name with