# Add compiling options
redef class ToolContext
# --output
- var opt_output = new OptionString("Output file", "-o", "--output")
+ var opt_output = new OptionString("Filename of the generated executable", "-o", "--output")
# --dir
var opt_dir = new OptionString("Output directory", "--dir")
# --no-cc
- var opt_no_cc = new OptionBool("Do not invoke C compiler", "--no-cc")
+ var opt_no_cc = new OptionBool("Do not invoke the C compiler", "--no-cc")
# --no-main
var opt_no_main = new OptionBool("Do not generate main entry point", "--no-main")
# --make-flags
- var opt_make_flags = new OptionString("Additional options to make", "--make-flags")
+ var opt_make_flags = new OptionString("Additional options to the `make` command", "--make-flags")
# --max-c-lines
var opt_max_c_lines = new OptionInt("Maximum number of lines in generated C files. Use 0 for unlimited", 10000, "--max-c-lines")
# --group-c-files
# --no-check-attr-isset
var opt_no_check_attr_isset = new OptionBool("Disable isset tests before each attribute access (dangerous)", "--no-check-attr-isset")
# --no-check-assert
- var opt_no_check_assert = new OptionBool("Disable the evaluation of explicit 'assert' and 'as' (dangerous)", "--no-check-assert")
+ var opt_no_check_assert = new OptionBool("Disable the evaluation of explicit `assert` and `as` (dangerous)", "--no-check-assert")
# --no-check-autocast
var opt_no_check_autocast = new OptionBool("Disable implicit casts on unsafe expression usage (dangerous)", "--no-check-autocast")
# --no-check-null
# --no-stacktrace
var opt_no_stacktrace = new OptionBool("Disable the generation of stack traces", "--no-stacktrace")
# --no-gcc-directives
- var opt_no_gcc_directive = new OptionArray("Disable a advanced gcc directives for optimization", "--no-gcc-directive")
+ var opt_no_gcc_directive = new OptionArray("Disable advanced gcc directives for optimization", "--no-gcc-directive")
# --release
var opt_release = new OptionBool("Compile in release mode and finalize application", "--release")
# -g
- var opt_debug = new OptionBool("Compile in debug mode (no C-side optimization)", "--debug", "-g")
+ var opt_debug = new OptionBool("Compile in debug mode (no C-side optimization)", "-g", "--debug")
redef init
do
self.header.add_decl("#include <sys/types.h>\n")
self.header.add_decl("#include <unistd.h>\n")
self.header.add_decl("#include <stdint.h>\n")
+ self.header.add_decl("#ifdef __linux__")
+ self.header.add_decl(" #include <endian.h>")
+ self.header.add_decl("#endif")
self.header.add_decl("#include <inttypes.h>\n")
self.header.add_decl("#include \"gc_chooser.h\"")
+ self.header.add_decl("#ifdef __APPLE__")
+ self.header.add_decl(" #include <libkern/OSByteOrder.h>")
+ self.header.add_decl(" #define be32toh(x) OSSwapBigToHostInt32(x)")
+ self.header.add_decl("#endif")
+ self.header.add_decl("#ifdef __pnacl__")
+ self.header.add_decl(" #define be16toh(val) (((val) >> 8) | ((val) << 8))")
+ self.header.add_decl(" #define be32toh(val) ((be16toh((val) << 16) | (be16toh((val) >> 16))))")
+ self.header.add_decl("#endif")
self.header.add_decl("#ifdef ANDROID")
+ self.header.add_decl(" #define be32toh(val) betoh32(val)")
self.header.add_decl(" #include <android/log.h>")
self.header.add_decl(" #define PRINT_ERROR(...) (void)__android_log_print(ANDROID_LOG_WARN, \"Nit\", __VA_ARGS__)")
self.header.add_decl("#else")
v.add_decl("int main(int argc, char** argv) \{")
end
+ v.add "#if !defined(__ANDROID__) && !defined(TARGET_OS_IPHONE)"
v.add("signal(SIGABRT, sig_handler);")
v.add("signal(SIGFPE, sig_handler);")
v.add("signal(SIGILL, sig_handler);")
v.add("signal(SIGINT, sig_handler);")
v.add("signal(SIGTERM, sig_handler);")
v.add("signal(SIGSEGV, sig_handler);")
+ v.add "#endif"
v.add("signal(SIGPIPE, SIG_IGN);")
v.add("glob_argc = argc; glob_argv = argv;")
fun calloc_array(ret_type: MType, arguments: Array[RuntimeVariable]) is abstract
- fun native_array_def(pname: String, ret_type: nullable MType, arguments: Array[RuntimeVariable]) is abstract
+ fun native_array_def(pname: String, ret_type: nullable MType, arguments: Array[RuntimeVariable]): Bool do return false
# Return an element of a native array.
# The method is unsafe and is just a direct wrapper for the specific implementation of native arrays
res.add(null_instance)
continue
end
- if param.is_vararg and map.vararg_decl > 0 then
- var vararg = exprs.sub(j, map.vararg_decl)
+ if param.is_vararg and args[i].vararg_decl > 0 then
+ var vararg = exprs.sub(j, args[i].vararg_decl)
var elttype = param.mtype
var arg = self.vararg_instance(mpropdef, recv, vararg, elttype)
res.add(arg)
# This is used for the legacy FFI
fun add_extern(mmodule: MModule)
do
- var file = mmodule.location.file.filename
+ var file = mmodule.filepath
file = file.strip_extension(".nit")
var tryfile = file + ".nit.h"
if tryfile.file_exists then
fun can_inline(v: VISITOR): Bool
do
if is_abstract then return true
+ if constant_value != null then return true
var modelbuilder = v.compiler.modelbuilder
var node = modelbuilder.mpropdef2node(self)
if node isa APropdef then
do
if v.compiler.modelbuilder.toolcontext.opt_no_check_covariance.value then return
+ var msignature = self.msignature.as(not null)
+
for i in [0..msignature.arity[ do
+ var mp = msignature.mparameters[i]
# skip test for vararg since the array is instantiated with the correct polymorphic type
- if msignature.vararg_rank == i then continue
+ if mp.is_vararg then continue
# skip if the cast is not required
var origmtype = self.mproperty.intro.msignature.mparameters[i].mtype
if not origmtype.need_anchor then continue
# get the parameter type
- var mtype = self.msignature.mparameters[i].mtype
+ var mtype = mp.mtype
# generate the cast
# note that v decides if and how to implements the cast
- v.add("/* Covariant cast for argument {i} ({self.msignature.mparameters[i].name}) {arguments[i+1].inspect} isa {mtype} */")
+ v.add("/* Covariant cast for argument {i} ({mp.name}) {arguments[i+1].inspect} isa {mtype} */")
v.add_cast(arguments[i+1], mtype, "covariance")
end
end
# Try special compilation
if mpropdef.is_intern then
if compile_intern_to_c(v, mpropdef, arguments) then return
- else if mpropdef.is_extern then
+ end
+ if mpropdef.is_extern then
if mpropdef.mproperty.is_init then
if compile_externinit_to_c(v, mpropdef, arguments) then return
else
else if pname == "to_b" then
v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
return true
+ else if pname == "code_point" then
+ v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "&" then
+ v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "|" then
+ v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">>" then
+ v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<<" then
+ v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
+ return true
end
else if cname == "Char" then
if pname == "object_id" then
else if pname == "to_i" then
v.ret(v.new_expr("{arguments[0]}-'0'", ret.as(not null)))
return true
+ else if pname == "code_point" then
+ v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
+ return true
end
else if cname == "Byte" then
if pname == "output" then
else if pname == ">=" then
v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
return true
+ else if pname == ">>" then
+ v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<<" then
+ v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "&" then
+ v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
+ return true
else if pname == "to_i" then
v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
return true
else if pname == "to_u32" then
v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
return true
+ else if pname == "ascii" then
+ v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
+ return true
end
else if cname == "Bool" then
if pname == "output" then
else if pname == "fast_cstring" then
v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
return true
+ else if pname == "==" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "!=" then
+ var res = v.equal_test(arguments[0], arguments[1])
+ v.ret(v.new_expr("!{res}", ret.as(not null)))
+ return true
else if pname == "new" then
v.ret(v.new_expr("(char*)nit_alloc({arguments[1]})", ret.as(not null)))
return true
+ else if pname == "fetch_4_chars" then
+ v.ret(v.new_expr("(long)*((uint32_t*)({arguments[0]} + {arguments[1]}))", ret.as(not null)))
+ return true
+ else if pname == "fetch_4_hchars" then
+ v.ret(v.new_expr("(long)be32toh(*((uint32_t*)({arguments[0]} + {arguments[1]})))", ret.as(not null)))
+ return true
end
else if cname == "NativeArray" then
- v.native_array_def(pname, ret, arguments)
- return true
+ return v.native_array_def(pname, ret, arguments)
else if cname == "Int8" then
if pname == "output" then
v.add("printf(\"%\"PRIi8 \"\\n\", {arguments.first});")
redef class AClassdef
private fun compile_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])
do
- if mpropdef == self.mfree_init then
- assert mpropdef.mproperty.is_root_init
+ if mpropdef.mproperty.is_root_init then
assert arguments.length == 1
if not mpropdef.is_intro then
v.supercall(mpropdef, arguments.first.mtype.as(MClassType), arguments)
redef class ASuperExpr
redef fun expr(v)
do
- var recv = v.frame.arguments.first
+ var frame = v.frame.as(not null)
+ var recv = frame.arguments.first
var callsite = self.callsite
if callsite != null then
# Add automatic arguments for the super init call
args = [recv]
for i in [0..callsite.msignature.arity[ do
- args.add(v.frame.arguments[i+1])
+ args.add(frame.arguments[i+1])
end
else
args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs)
var args
if self.n_args.n_exprs.is_empty then
- args = v.frame.arguments
+ args = frame.arguments
else
args = v.varargize(mpropdef, signaturemap, recv, self.n_args.n_exprs)
end
# Here we load an process all modules passed on the command line
var mmodules = modelbuilder.parse(arguments)
-if mmodules.is_empty then
- toolcontext.check_errors
- toolcontext.errors_info
- if toolcontext.error_count > 0 then exit(1) else exit(0)
-end
+if mmodules.is_empty then toolcontext.quit
modelbuilder.run_phases