private import annotation
import mixin
import counter
+private import explain_assert_api
# Add compiling options
redef class ToolContext
var cond = v.expr_bool(self.n_expr)
v.add("if (unlikely(!{cond})) \{")
v.stmt(self.n_else)
+
+ explain_assert v
+
var nid = self.n_id
if nid != null then
v.add_abort("Assert '{nid.text}' failed")
end
v.add("\}")
end
+
+ # Explain assert if it fails
+ private fun explain_assert(v: AbstractCompilerVisitor)
+ do
+ var explain_assert_str = explain_assert_str
+ if explain_assert_str == null then return
+
+ var nas = v.compiler.modelbuilder.model.get_mclasses_by_name("NativeArray")
+ if nas == null then return
+
+ var expr = explain_assert_str.expr(v)
+ if expr == null then return
+
+ var cstr = v.send(v.get_property("to_cstring", expr.mtype), [expr])
+ if cstr == null then return
+
+ v.add "PRINT_ERROR(\"Runtime assert: %s\\n\", {cstr});"
+ end
end
redef class AOrExpr
import mixin
import primitive_types
private import model::serialize_model
+private import frontend::explain_assert_api
redef class ToolContext
# --discover-call-trace
if not cond.is_true then
v.stmt(self.n_else)
if v.is_escaping then return
+
+ # Explain assert if it fails
+ var explain_assert_str = explain_assert_str
+ if explain_assert_str != null then
+ var i = v.expr(explain_assert_str)
+ if i isa MutableInstance then
+ var res = v.send(v.force_get_primitive_method("to_cstring", i.mtype), [i])
+ if res != null then
+ var val = res.val
+ if val != null then
+ print_error "Runtime assert: {val.to_s}"
+ end
+ end
+ end
+ end
+
var nid = self.n_id
if nid != null then
fatal(v, "Assert '{nid.text}' failed")