end
var debug = toolcontext.opt_debug.value
- makefile.write("CC = ccache cc\nCXX = ccache c++\nCFLAGS = -g{ if not debug then " -O2 " else " "}-Wno-unused-value -Wno-switch -Wno-attributes\nCINCL =\nLDFLAGS ?= \nLDLIBS ?= -lm {linker_options.join(" ")}\n\n")
+ makefile.write("CC = ccache cc\nCXX = ccache c++\nCFLAGS = -g{ if not debug then " -O2 " else " "}-Wno-unused-value -Wno-switch -Wno-attributes -Wno-trigraphs\nCINCL =\nLDFLAGS ?= \nLDLIBS ?= -lm {linker_options.join(" ")}\n\n")
makefile.write "\n# SPECIAL CONFIGURATION FLAGS\n"
if platform.supports_libunwind then
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(" #ifndef be32toh")
+ self.header.add_decl(" #define be32toh(val) betoh32(val)")
+ self.header.add_decl(" #endif")
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
else if node isa AClassdef then
# Automatic free init is always inlined since it is empty or contains only attribtes assigments
return true
+ else if node == null then
+ return true
else
abort
end
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 = 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} ({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});")
v.assign(v.frame.returnvar.as(not null), res)
else if mpropdef == mwritepropdef then
assert arguments.length == 2
- v.write_attribute(self.mpropdef.mproperty, arguments.first, arguments[1])
+ var recv = arguments.first
+ var arg = arguments[1]
+ if is_optional then
+ var value = v.new_var(self.mpropdef.static_mtype.as(not null))
+ v.add("if ({arg} == NULL) \{")
+ v.assign(value, evaluate_expr(v, recv))
+ v.add("\} else \{")
+ v.assign(value, arg)
+ v.add("\}")
+ arg = value
+ end
+ v.write_attribute(self.mpropdef.mproperty, arguments.first, arg)
if is_lazy then
var ret = self.mtype
var useiset = not ret.is_c_primitive and not ret isa MNullableType
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)
end
redef class ACharExpr
- redef fun expr(v) do return v.char_instance(self.value.as(not null))
+ redef fun expr(v) do
+ if is_ascii then return v.byte_instance(value.as(not null).ascii)
+ if is_code_point then return v.int_instance(value.as(not null).code_point)
+ return v.char_instance(self.value.as(not null))
+ end
end
redef class AArrayExpr