X-Git-Url: http://nitlanguage.org?ds=inline diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 31795fc..ac6edce 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -24,6 +24,8 @@ import c_tools private import annotation import mixin import counter +import pkgconfig +private import explain_assert_api # Add compiling options redef class ToolContext @@ -188,6 +190,8 @@ class MakefileToolchain var time1 = get_time self.toolcontext.info("*** END WRITING C: {time1-time0} ***", 2) + if not toolcontext.check_errors then return + # Execute the Makefile if self.toolcontext.opt_no_cc.value then return @@ -360,8 +364,12 @@ class MakefileToolchain var debug = toolcontext.opt_debug.value makefile.write """ -CC ?= ccache cc -CXX ?= ccache c++ +ifeq ($(origin CC), default) + CC = ccache cc +endif +ifeq ($(origin CXX), default) + CXX = ccache c++ +endif CFLAGS ?= -g {{{if not debug then "-O2" else ""}}} -Wno-unused-value -Wno-switch -Wno-attributes -Wno-trigraphs CINCL = LDFLAGS ?= @@ -462,14 +470,19 @@ endif f.close end - var java_files = new Array[ExternFile] - + # pkg-config annotation support var pkgconfigs = new Array[String] for f in compiler.extern_bodies do pkgconfigs.add_all f.pkgconfigs end - # Protect pkg-config + + # Only test if pkg-config is used if not pkgconfigs.is_empty then + + # Check availability of pkg-config, silence the proc output + toolcontext.check_pkgconfig_packages pkgconfigs + + # Double the check in the Makefile in case it's distributed makefile.write """ # does pkg-config exists? ifneq ($(shell which pkg-config >/dev/null; echo $$?), 0) @@ -487,6 +500,7 @@ endif end # Compile each required extern body into a specific .o + var java_files = new Array[ExternFile] for f in compiler.extern_bodies do var o = f.makefile_rule_name var ff = f.filename.basename @@ -753,9 +767,10 @@ abstract class AbstractCompiler self.header.add_decl """ struct catch_stack_t { int cursor; - jmp_buf envs[100]; + int currentSize; + jmp_buf *envs; }; -extern struct catch_stack_t catchStack; +extern __thread struct catch_stack_t catchStack; """ end @@ -856,7 +871,7 @@ extern void nitni_global_ref_decr( struct nitni_ref *ref ); v.add_decl("int glob_argc;") v.add_decl("char **glob_argv;") v.add_decl("val *glob_sys;") - v.add_decl("struct catch_stack_t catchStack;") + v.add_decl("__thread struct catch_stack_t catchStack = \{-1, 0, NULL\};") if self.modelbuilder.toolcontext.opt_typing_test_metrics.value then for tag in count_type_test_tags do @@ -957,7 +972,6 @@ extern void nitni_global_ref_decr( struct nitni_ref *ref ); v.add "#endif" v.add("glob_argc = argc; glob_argv = argv;") - v.add("catchStack.cursor = -1;") v.add("initialize_gc_option();") v.add "initialize_nitni_global_refs();" @@ -1378,6 +1392,11 @@ abstract class AbstractCompilerVisitor mtype = self.anchor(mtype) var valmtype = value.mcasttype + # CPrimitive is the best you can do + if valmtype.is_c_primitive then + return value + end + # Do nothing if useless autocast if valmtype.is_subtype(self.compiler.mainmodule, null, mtype) then return value @@ -3490,6 +3509,14 @@ redef class ADoExpr redef fun stmt(v) do if self.n_catch != null then + v.add("if(catchStack.currentSize == 0) \{") + v.add(" catchStack.cursor = -1;") + v.add(" catchStack.currentSize = 100;") + v.add(" catchStack.envs = malloc(sizeof(jmp_buf)*100);") + v.add("\} else if(catchStack.cursor == catchStack.currentSize - 1) \{") + v.add(" catchStack.currentSize *= 2;") + v.add(" catchStack.envs = realloc(catchStack.envs, sizeof(jmp_buf)*catchStack.currentSize);") + v.add("\}") v.add("catchStack.cursor += 1;") v.add("if(!setjmp(catchStack.envs[catchStack.cursor]))\{") v.stmt(self.n_block) @@ -3602,6 +3629,9 @@ redef class AAssertExpr 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") @@ -3610,6 +3640,27 @@ redef class AAssertExpr 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 + + nas = v.compiler.modelbuilder.model.get_mclasses_by_name("Array") + if nas == null or nas.is_empty 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