X-Git-Url: http://nitlanguage.org diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 35c07d5..9ec830a 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -411,7 +411,7 @@ ifeq ($(uname_S),Darwin) endif # Special configuration for Windows under mingw64 -ifeq ($(uname_S),MINGW64_NT-10.0) +ifneq ($(findstring MINGW64,$(uname_S)),) # Use the pcreposix regex library LDLIBS += -lpcreposix @@ -1450,7 +1450,7 @@ abstract class AbstractCompilerVisitor # Checks # Can value be null? (according to current knowledge) - fun maybenull(value: RuntimeVariable): Bool + fun maybe_null(value: RuntimeVariable): Bool do return value.mcasttype isa MNullableType or value.mcasttype isa MNullType end @@ -1460,7 +1460,7 @@ abstract class AbstractCompilerVisitor do if self.compiler.modelbuilder.toolcontext.opt_no_check_null.value then return - if maybenull(recv) then + if maybe_null(recv) then self.add("if (unlikely({recv} == NULL)) \{") self.add_abort("Receiver is null") self.add("\}") @@ -1825,17 +1825,30 @@ abstract class AbstractCompilerVisitor # used by aborts, asserts, casts, etc. fun add_abort(message: String) do + add_raw_throw + self.add("PRINT_ERROR(\"Runtime error: %s\", \"{message.escape_to_c}\");") + add_raw_abort + end + + # Generate a long jump if there is a catch block. + # + # This method should be called before the error messages and before a `add_raw_abort`. + fun add_raw_throw + do self.add("if(catchStack.cursor >= 0)\{") self.add("longjmp(catchStack.envs[catchStack.cursor], 1);") self.add("\}") - self.add("PRINT_ERROR(\"Runtime error: %s\", \"{message.escape_to_c}\");") - add_raw_abort end + # Generate abort without a message. + # + # Used when one need a more complex message. + # Do not forget to call `add_raw_abort` before the display of a custom user message. fun add_raw_abort do - if self.current_node != null and self.current_node.location.file != null and - self.current_node.location.file.mmodule != null then + var current_node = self.current_node + if current_node != null and current_node.location.file != null and + current_node.location.file.mmodule != null then var f = "FILE_{self.current_node.location.file.mmodule.c_name}" self.require_declaration(f) self.add("PRINT_ERROR(\" (%s:%d)\\n\", {f}, {current_node.location.line_start});") @@ -1850,6 +1863,7 @@ abstract class AbstractCompilerVisitor do var res = self.type_test(value, mtype, tag) self.add("if (unlikely(!{res})) \{") + self.add_raw_throw var cn = self.class_name_string(value) self.add("PRINT_ERROR(\"Runtime error: Cast failed. Expected `%s`, got `%s`\", \"{mtype.to_s.escape_to_c}\", {cn});") self.add_raw_abort @@ -2179,6 +2193,7 @@ redef class MMethodDef var node = modelbuilder.mpropdef2node(self) if is_abstract then + v.add_raw_throw var cn = v.class_name_string(arguments.first) v.current_node = node v.add("PRINT_ERROR(\"Runtime error: Abstract method `%s` called on `%s`\", \"{mproperty.name.escape_to_c}\", {cn});") @@ -2290,6 +2305,7 @@ redef class AMethPropdef end # We have a problem + v.add_raw_throw var cn = v.class_name_string(arguments.first) v.add("PRINT_ERROR(\"Runtime error: uncompiled method `%s` called on `%s`. NOT YET IMPLEMENTED\", \"{mpropdef.mproperty.name.escape_to_c}\", {cn});") v.add_raw_abort @@ -3211,7 +3227,7 @@ redef class AAttrPropdef assert arguments.length == 2 var recv = arguments.first var arg = arguments[1] - if is_optional and v.maybenull(arg) then + if is_optional and v.maybe_null(arg) 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)) @@ -3645,7 +3661,7 @@ redef class AOrElseExpr var res = v.new_var(self.mtype.as(not null)) var i1 = v.expr(self.n_expr, null) - if not v.maybenull(i1) then return i1 + if not v.maybe_null(i1) then return i1 v.add("if ({i1}!=NULL) \{") v.assign(res, i1) @@ -3898,7 +3914,7 @@ redef class AAsNotnullExpr var i = v.expr(self.n_expr, null) if v.compiler.modelbuilder.toolcontext.opt_no_check_assert.value then return i - if not v.maybenull(i) then return i + if not v.maybe_null(i) then return i v.add("if (unlikely({i} == NULL)) \{") v.add_abort("Cast failed")