var gccd_disable = modelbuilder.toolcontext.opt_no_gcc_directive.value
if gccd_disable.has("noreturn") or gccd_disable.has("all") then
# Signal handler function prototype
- self.header.add_decl("void show_backtrace(int);")
+ self.header.add_decl("void fatal_exit(int);")
else
- self.header.add_decl("void show_backtrace(int) __attribute__ ((noreturn));")
+ self.header.add_decl("void fatal_exit(int) __attribute__ ((noreturn));")
end
if gccd_disable.has("likely") or gccd_disable.has("all") then
v.compiler.header.add_decl("extern long count_isset_checks;")
end
- v.add_decl("void sig_handler(int signo)\{")
- v.add_decl("PRINT_ERROR(\"Caught signal : %s\\n\", strsignal(signo));")
- v.add_decl("show_backtrace(signo);")
- v.add_decl("\}")
-
- v.add_decl("void show_backtrace (int signo) \{")
+ v.add_decl("static void show_backtrace(void) \{")
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("free(procname);")
v.add_decl("\}")
end
- v.add_decl("exit(signo);")
+ v.add_decl("\}")
+
+ v.add_decl("void sig_handler(int signo)\{")
+ v.add_decl("PRINT_ERROR(\"Caught signal : %s\\n\", strsignal(signo));")
+ v.add_decl("show_backtrace();")
+ # rethrows
+ v.add_decl("signal(signo, SIG_DFL);")
+ v.add_decl("kill(getpid(), signo);")
+ v.add_decl("\}")
+
+ v.add_decl("void fatal_exit(int status) \{")
+ v.add_decl("show_backtrace();")
+ v.add_decl("exit(status);")
v.add_decl("\}")
if no_main then
self.writer = new CodeWriter(compiler.files.last)
end
- # Force to get the primitive class named `name` or abort
- fun get_class(name: String): MClass do return self.compiler.mainmodule.get_primitive_class(name)
-
# Force to get the primitive property named `name` in the instance `recv` or abort
fun get_property(name: String, recv: MType): MMethod
do
var recv
var ctype = mtype.ctype
assert mtype.mclass.name != "NativeArray"
- if ctype == "val*" then
+ if not mtype.is_c_primitive then
recv = init_instance(mtype)
else if ctype == "char*" then
recv = new_expr("NULL/*special!*/", mtype)
end
end
+ # The currently processed module
+ #
+ # alias for `compiler.mainmodule`
+ fun mmodule: MModule do return compiler.mainmodule
+
# Generate an integer value
fun int_instance(value: Int): RuntimeVariable
do
- var res = self.new_var(self.get_class("Int").mclass_type)
- self.add("{res} = {value};")
+ var t = mmodule.int_type
+ var res = new RuntimeVariable("{value.to_s}l", t, t)
+ return res
+ end
+
+ # Generate a char value
+ fun char_instance(value: Char): RuntimeVariable
+ do
+ var t = mmodule.char_type
+ var res = new RuntimeVariable("'{value.to_s.escape_to_c}'", t, t)
+ return res
+ end
+
+ # Generate a float value
+ #
+ # FIXME pass a Float, not a string
+ fun float_instance(value: String): RuntimeVariable
+ do
+ var t = mmodule.float_type
+ var res = new RuntimeVariable("{value}", t, t)
return res
end
# Generate an integer value
fun bool_instance(value: Bool): RuntimeVariable
do
- var res = self.new_var(self.get_class("Bool").mclass_type)
- if value then
- self.add("{res} = 1;")
- else
- self.add("{res} = 0;")
- end
+ var s = if value then "1" else "0"
+ var res = new RuntimeVariable(s, bool_type, bool_type)
+ return res
+ end
+
+ # Generate the `null` value
+ fun null_instance: RuntimeVariable
+ do
+ var t = compiler.mainmodule.model.null_type
+ var res = new RuntimeVariable("((val*)NULL)", t, t)
return res
end
# Generate a string value
fun string_instance(string: String): RuntimeVariable
do
- var mtype = self.get_class("String").mclass_type
+ var mtype = mmodule.string_type
var name = self.get_name("varonce")
self.add_decl("static {mtype.ctype} {name};")
var res = self.new_var(mtype)
- self.add("if ({name}) \{")
+ self.add("if (likely({name}!=NULL)) \{")
self.add("{res} = {name};")
self.add("\} else \{")
- var native_mtype = self.get_class("NativeString").mclass_type
+ var native_mtype = mmodule.native_string_type
var nat = self.new_var(native_mtype)
self.add("{nat} = \"{string.escape_to_c}\";")
var length = self.int_instance(string.length)
else
self.add("PRINT_ERROR(\"\\n\");")
end
- self.add("show_backtrace(1);")
+ self.add("fatal_exit(1);")
end
# Add a dynamic cast
# Short name of the `ctype` to use in unions
fun ctypename: String do return "val"
+
+ # Is the associated C type a primitive one?
+ #
+ # ENSURE `result == (ctype != "val*")`
+ fun is_c_primitive: Bool do return false
end
redef class MClassType
- redef fun ctype: String
- do
+ redef var ctype is lazy do
if mclass.name == "Int" then
return "long"
else if mclass.name == "Bool" then
end
end
+ redef var is_c_primitive is lazy do return ctype != "val*"
+
redef fun ctype_extern: String
do
if mclass.kind == extern_kind then
if is_lazy then
var set
var ret = self.mpropdef.static_mtype
- var useiset = ret.ctype == "val*" and not ret isa MNullableType
+ var useiset = not ret.is_c_primitive and not ret isa MNullableType
var guard = self.mlazypropdef.mproperty
if useiset then
set = v.isset_attribute(self.mpropdef.mproperty, recv)
v.assign(res, value)
if not useiset then
- var true_v = v.new_expr("1", v.bool_type)
+ var true_v = v.bool_instance(true)
v.write_attribute(guard, arguments.first, true_v)
end
v.add("\}")
v.write_attribute(self.mpropdef.mproperty, arguments.first, arguments[1])
if is_lazy then
var ret = self.mpropdef.static_mtype
- var useiset = ret.ctype == "val*" and not ret isa MNullableType
+ var useiset = not ret.is_c_primitive and not ret isa MNullableType
if not useiset then
- v.write_attribute(self.mlazypropdef.mproperty, arguments.first, v.new_expr("1", v.bool_type))
+ v.write_attribute(self.mlazypropdef.mproperty, arguments.first, v.bool_instance(true))
end
end
else
fun init_expr(v: AbstractCompilerVisitor, recv: RuntimeVariable)
do
- if has_value and not is_lazy then evaluate_expr(v, recv)
+ if has_value and not is_lazy and not n_expr isa ANullExpr then evaluate_expr(v, recv)
end
# Evaluate, store and return the default value of the attribute
end
redef class AIntExpr
- redef fun expr(v) do return v.new_expr("{self.value.to_s}", self.mtype.as(not null))
+ redef fun expr(v) do return v.int_instance(self.value.as(not null))
end
redef class AFloatExpr
- redef fun expr(v) do return v.new_expr("{self.n_float.text}", self.mtype.as(not null)) # FIXME use value, not n_float
+ redef fun expr(v) do return v.float_instance("{self.n_float.text}") # FIXME use value, not n_float
end
redef class ACharExpr
- redef fun expr(v) do return v.new_expr("'{self.value.to_s.escape_to_c}'", self.mtype.as(not null))
+ redef fun expr(v) do return v.char_instance(self.value.as(not null))
end
redef class AArrayExpr
end
redef class ATrueExpr
- redef fun expr(v) do return v.new_expr("1", self.mtype.as(not null))
+ redef fun expr(v) do return v.bool_instance(true)
end
redef class AFalseExpr
- redef fun expr(v) do return v.new_expr("0", self.mtype.as(not null))
+ redef fun expr(v) do return v.bool_instance(false)
end
redef class ANullExpr
- redef fun expr(v) do return v.new_expr("NULL", self.mtype.as(not null))
+ redef fun expr(v) do return v.null_instance
end
redef class AIsaExpr
var i = v.expr(self.n_expr, null)
if v.compiler.modelbuilder.toolcontext.opt_no_check_assert.value then return i
- if i.mtype.ctype != "val*" then return i
+ if i.mtype.is_c_primitive then return i
v.add("if (unlikely({i} == NULL)) \{")
v.add_abort("Cast failed")
v.add_decl("static {mtype.ctype} {name};")
v.add_decl("static int {guard};")
var res = v.new_var(mtype)
- v.add("if ({guard}) \{")
+ v.add("if (likely({guard})) \{")
v.add("{res} = {name};")
v.add("\} else \{")
var i = v.expr(self.n_expr, mtype)