var opt_no_shortcut_range: OptionBool = new OptionBool("Always insantiate a range and its iterator on 'for' loops", "--no-shortcut-range")
# --no-check-covariance
var opt_no_check_covariance: OptionBool = new OptionBool("Disable type tests of covariant parameters (dangerous)", "--no-check-covariance")
- # --no-check-initialization
- var opt_no_check_initialization: OptionBool = new OptionBool("Disable isset tests at the end of constructors (dangerous)", "--no-check-initialization")
+ # --no-check-attr-isset
+ var opt_no_check_attr_isset: OptionBool = new OptionBool("Disable isset tests before each attribute access (dangerous)", "--no-check-attr-isset")
# --no-check-assert
var opt_no_check_assert: OptionBool = new OptionBool("Disable the evaluation of explicit 'assert' and 'as' (dangerous)", "--no-check-assert")
# --no-check-autocast
do
super
self.option_context.add_option(self.opt_output, self.opt_no_cc, self.opt_make_flags, self.opt_compile_dir, self.opt_hardening, self.opt_no_shortcut_range)
- self.option_context.add_option(self.opt_no_check_covariance, self.opt_no_check_initialization, self.opt_no_check_assert, self.opt_no_check_autocast, self.opt_no_check_other)
+ self.option_context.add_option(self.opt_no_check_covariance, self.opt_no_check_attr_isset, self.opt_no_check_assert, self.opt_no_check_autocast, self.opt_no_check_other)
self.option_context.add_option(self.opt_typing_test_metrics, self.opt_invocation_metrics)
self.option_context.add_option(self.opt_stacktrace)
self.option_context.add_option(self.opt_no_gcc_directive)
super
var st = opt_stacktrace.value
- if st == null or st == "none" or st == "libunwind" or st == "gperf" then
+ if st == null or st == "none" or st == "libunwind" or st == "nitstack" then
# Fine, do nothing
else if st == "auto" then
# Default just unset
opt_stacktrace.value = null
else
- print "Error: unknown value `{st}` for --stacktrace. Use `none`, `libunwind`, `gperf` or `auto`."
+ print "Error: unknown value `{st}` for --stacktrace. Use `none`, `libunwind`, `nitstack` or `auto`."
exit(1)
end
end
# The list is initially set with :
# * the toolcontext --cc-path option
# * the NIT_CC_PATH environment variable
- # * some heuristics including the NIT_DIR environment variable and the progname of the process
+ # * `toolcontext.nit_dir`
# Path can be added (or removed) by the client
var cc_paths = new Array[String]
protected fun gather_cc_paths
do
# Look for the the Nit clib path
- var path_env = "NIT_DIR".environ
- if not path_env.is_empty then
+ var path_env = toolcontext.nit_dir
+ if path_env != null then
var libname = "{path_env}/clib"
if libname.file_exists then cc_paths.add(libname)
end
- var libname = "{sys.program_name.dirname}/../clib"
- if libname.file_exists then cc_paths.add(libname.simplify_path)
-
if cc_paths.is_empty then
toolcontext.error(null, "Cannot determine the nit clib path. define envvar NIT_DIR.")
end
fun write_files(compiler: AbstractCompiler, compile_dir: String, cfiles: Array[String])
do
- if self.toolcontext.opt_stacktrace.value == "gperf" then compiler.build_c_to_nit_bindings
+ if self.toolcontext.opt_stacktrace.value == "nitstack" then compiler.build_c_to_nit_bindings
# Add gc_choser.h to aditionnal bodies
var gc_chooser = new ExternCFile("gc_chooser.c", "-DWITH_LIBGC")
end
var ost = toolcontext.opt_stacktrace.value
- if ost == "libunwind" or ost == "gperf" then linker_options.add("-lunwind")
+ if ost == "libunwind" or ost == "nitstack" then linker_options.add("-lunwind")
makefile.write("CC = ccache cc\nCFLAGS = -g -O2\nCINCL = {cc_includes}\nLDFLAGS ?= \nLDLIBS ?= -lm -lgc {linker_options.join(" ")}\n\n")
makefile.write("all: {outpath}\n\n")
dep_rules.add(o)
end
+ var java_files = new Array[ExternFile]
+
# Compile each required extern body into a specific .o
for f in compiler.extern_bodies do
var o = f.makefile_rule_name
makefile.write("{o}: {ff}\n")
makefile.write("\t{f.makefile_rule_content}\n\n")
dep_rules.add(f.makefile_rule_name)
- ofiles.add(o)
+
+ if f.compiles_to_o_file then ofiles.add(o)
+ if f.add_to_jar then java_files.add(f)
+ end
+
+ if not java_files.is_empty then
+ var jar_file = "{outpath}.jar"
+
+ var class_files_array = new Array[String]
+ for f in java_files do class_files_array.add(f.makefile_rule_name)
+ var class_files = class_files_array.join(" ")
+
+ makefile.write("{jar_file}: {class_files}\n")
+ makefile.write("\tjar cf {jar_file} {class_files}\n\n")
+ dep_rules.add jar_file
end
# Link edition
do
var compile_dir = modelbuilder.compile_dir
- var stream = new OFStream.open("{compile_dir}/C_fun_names")
- stream.write("%\{\n#include \"c_functions_hash.h\"\n%\}\n")
- stream.write("%define lookup-function-name get_nit_name\n")
- stream.write("struct C_Nit_Names;\n")
- stream.write("%%\n")
- stream.write("####\n")
+ var stream = new OFStream.open("{compile_dir}/c_functions_hash.c")
+ stream.write("#include <string.h>\n")
+ stream.write("#include <stdlib.h>\n")
+ stream.write("#include \"c_functions_hash.h\"\n")
+ stream.write("typedef struct C_Nit_Names\{char* name; char* nit_name;\}C_Nit_Names;\n")
+ stream.write("const char* get_nit_name(register const char* procproc, register unsigned int len)\{\n")
+ stream.write("char* procname = malloc(len+1);")
+ stream.write("memcpy(procname, procproc, len);")
+ stream.write("procname[len] = '\\0';")
+ stream.write("static const C_Nit_Names map[{names.length}] = \{\n")
for i in names.keys do
+ stream.write("\{\"")
stream.write(i)
- stream.write(",\t\"")
+ stream.write("\",\"")
stream.write(names[i])
- stream.write("\"\n")
- end
- if names.is_empty then
- stream.write("DEAD,\t\"DEAD\"\n") # Force at least one entry
- end
- stream.write("####\n")
- stream.write("%%\n")
+ stream.write("\"\},\n")
+ end
+ stream.write("\};\n")
+ stream.write("int i;")
+ stream.write("for(i = 0; i < {names.length}; i++)\{")
+ stream.write("if(strcmp(procname,map[i].name) == 0)\{")
+ stream.write("free(procname);")
+ stream.write("return map[i].nit_name;")
+ stream.write("\}")
+ stream.write("\}")
+ stream.write("free(procname);")
+ stream.write("return NULL;")
+ stream.write("\}\n")
stream.close
stream = new OFStream.open("{compile_dir}/c_functions_hash.h")
- stream.write("typedef struct C_Nit_Names\{char* name; char* nit_name;\}C_Nit_Names;\n")
- stream.write("const struct C_Nit_Names* get_nit_name(register const char *str, register unsigned int len);\n")
+ stream.write("const char* get_nit_name(register const char* procname, register unsigned int len);\n")
stream.close
- var x = new Process("gperf","{compile_dir}/C_fun_names","-t","-7","--output-file={compile_dir}/c_functions_hash.c","-C")
- x.wait
-
extern_bodies.add(new ExternCFile("{compile_dir}/c_functions_hash.c", ""))
end
var ost = modelbuilder.toolcontext.opt_stacktrace.value
if ost == null then
- ost = "gperf"
+ ost = "nitstack"
modelbuilder.toolcontext.opt_stacktrace.value = ost
end
- if ost == "gperf" or ost == "libunwind" then
+ if ost == "nitstack" or ost == "libunwind" then
v.add_decl("#define UNW_LOCAL_ONLY")
v.add_decl("#include <libunwind.h>")
- if ost == "gperf" then
+ if ost == "nitstack" then
v.add_decl("#include \"c_functions_hash.h\"")
end
end
v.add_decl("\}")
v.add_decl("void show_backtrace (int signo) \{")
- if ost == "gperf" or ost == "libunwind" then
+ if ost == "nitstack" or ost == "libunwind" then
v.add_decl("char* opt = getenv(\"NIT_NO_STACK\");")
v.add_decl("unw_cursor_t cursor;")
v.add_decl("if(opt==NULL)\{")
v.add_decl("printf(\"-------------------------------------------------\\n\");")
v.add_decl("while (unw_step(&cursor) > 0) \{")
v.add_decl(" unw_get_proc_name(&cursor, procname, 100, &ip);")
- if ost == "gperf" then
- v.add_decl(" const C_Nit_Names* recv = get_nit_name(procname, strlen(procname));")
- v.add_decl(" if (recv != 0)\{")
- v.add_decl(" printf(\"` %s\\n\", recv->nit_name);")
+ if ost == "nitstack" then
+ v.add_decl(" const char* recv = get_nit_name(procname, strlen(procname));")
+ v.add_decl(" if (recv != NULL)\{")
+ v.add_decl(" printf(\"` %s\\n\", recv);")
v.add_decl(" \}else\{")
v.add_decl(" printf(\"` %s\\n\", procname);")
v.add_decl(" \}")