X-Git-Url: http://nitlanguage.org diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 3d6d939..7824b92 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -28,15 +28,15 @@ import counter # Add compiling options redef class ToolContext # --output - var opt_output = new OptionString("Output file", "-o", "--output") + var opt_output = new OptionString("Filename of the generated executable", "-o", "--output") # --dir var opt_dir = new OptionString("Output directory", "--dir") # --no-cc - var opt_no_cc = new OptionBool("Do not invoke C compiler", "--no-cc") + var opt_no_cc = new OptionBool("Do not invoke the C compiler", "--no-cc") # --no-main var opt_no_main = new OptionBool("Do not generate main entry point", "--no-main") # --make-flags - var opt_make_flags = new OptionString("Additional options to make", "--make-flags") + var opt_make_flags = new OptionString("Additional options to the `make` command", "--make-flags") # --max-c-lines var opt_max_c_lines = new OptionInt("Maximum number of lines in generated C files. Use 0 for unlimited", 10000, "--max-c-lines") # --group-c-files @@ -50,7 +50,7 @@ redef class ToolContext # --no-check-attr-isset var opt_no_check_attr_isset = new OptionBool("Disable isset tests before each attribute access (dangerous)", "--no-check-attr-isset") # --no-check-assert - var opt_no_check_assert = new OptionBool("Disable the evaluation of explicit 'assert' and 'as' (dangerous)", "--no-check-assert") + var opt_no_check_assert = new OptionBool("Disable the evaluation of explicit `assert` and `as` (dangerous)", "--no-check-assert") # --no-check-autocast var opt_no_check_autocast = new OptionBool("Disable implicit casts on unsafe expression usage (dangerous)", "--no-check-autocast") # --no-check-null @@ -66,11 +66,11 @@ redef class ToolContext # --no-stacktrace var opt_no_stacktrace = new OptionBool("Disable the generation of stack traces", "--no-stacktrace") # --no-gcc-directives - var opt_no_gcc_directive = new OptionArray("Disable a advanced gcc directives for optimization", "--no-gcc-directive") + var opt_no_gcc_directive = new OptionArray("Disable advanced gcc directives for optimization", "--no-gcc-directive") # --release var opt_release = new OptionBool("Compile in release mode and finalize application", "--release") # -g - var opt_debug = new OptionBool("Compile in debug mode (no C-side optimization)", "--debug", "-g") + var opt_debug = new OptionBool("Compile in debug mode (no C-side optimization)", "-g", "--debug") redef init do @@ -853,12 +853,14 @@ extern void nitni_global_ref_decr( struct nitni_ref *ref ); v.add_decl("int main(int argc, char** argv) \{") end + v.add "#ifndef ANDROID" 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;") @@ -1147,6 +1149,7 @@ abstract class AbstractCompilerVisitor fun compile_callsite(callsite: CallSite, arguments: Array[RuntimeVariable]): nullable RuntimeVariable do + if callsite.is_broken then return null var initializers = callsite.mpropdef.initializers if not initializers.is_empty then var recv = arguments.first @@ -1221,8 +1224,8 @@ abstract class AbstractCompilerVisitor 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) @@ -2021,6 +2024,7 @@ redef class MMethodDef fun can_inline(v: VISITOR): Bool do if is_abstract then return true + if constant_value != null then return true var modelbuilder = v.compiler.modelbuilder var node = modelbuilder.mpropdef2node(self) if node isa APropdef then @@ -2073,20 +2077,23 @@ redef class MMethodDef do if v.compiler.modelbuilder.toolcontext.opt_no_check_covariance.value then return + 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 = self.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} ({self.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 @@ -2243,6 +2250,21 @@ redef class AMethPropdef 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 @@ -2276,6 +2298,9 @@ redef class AMethPropdef 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 @@ -2324,6 +2349,15 @@ redef class AMethPropdef 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 @@ -2345,6 +2379,9 @@ redef class AMethPropdef 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 @@ -3306,53 +3343,68 @@ end redef class AForExpr redef fun stmt(v) do - var cl = v.expr(self.n_expr, null) - var it_meth = self.method_iterator - assert it_meth != null - var it = v.compile_callsite(it_meth, [cl]) - assert it != null + for g in n_groups do + var cl = v.expr(g.n_expr, null) + var it_meth = g.method_iterator + assert it_meth != null + var it = v.compile_callsite(it_meth, [cl]) + assert it != null + g.it = it + end v.add("for(;;) \{") - var isok_meth = self.method_is_ok - assert isok_meth != null - var ok = v.compile_callsite(isok_meth, [it]) - assert ok != null - v.add("if(!{ok}) break;") - if self.variables.length == 1 then - var item_meth = self.method_item - assert item_meth != null - var i = v.compile_callsite(item_meth, [it]) - assert i != null - v.assign(v.variable(variables.first), i) - else if self.variables.length == 2 then - var key_meth = self.method_key - assert key_meth != null - var i = v.compile_callsite(key_meth, [it]) - assert i != null - v.assign(v.variable(variables[0]), i) - var item_meth = self.method_item - assert item_meth != null - i = v.compile_callsite(item_meth, [it]) - assert i != null - v.assign(v.variable(variables[1]), i) - else - abort + for g in n_groups do + var it = g.it + var isok_meth = g.method_is_ok + assert isok_meth != null + var ok = v.compile_callsite(isok_meth, [it]) + assert ok != null + v.add("if(!{ok}) break;") + if g.variables.length == 1 then + var item_meth = g.method_item + assert item_meth != null + var i = v.compile_callsite(item_meth, [it]) + assert i != null + v.assign(v.variable(g.variables.first), i) + else if g.variables.length == 2 then + var key_meth = g.method_key + assert key_meth != null + var i = v.compile_callsite(key_meth, [it]) + assert i != null + v.assign(v.variable(g.variables[0]), i) + var item_meth = g.method_item + assert item_meth != null + i = v.compile_callsite(item_meth, [it]) + assert i != null + v.assign(v.variable(g.variables[1]), i) + else + abort + end end v.stmt(self.n_block) v.add_escape_label(continue_mark) - var next_meth = self.method_next - assert next_meth != null - v.compile_callsite(next_meth, [it]) + for g in n_groups do + var next_meth = g.method_next + assert next_meth != null + v.compile_callsite(next_meth, [g.it]) + end v.add("\}") v.add_escape_label(break_mark) - var method_finish = self.method_finish - if method_finish != null then - # TODO: Find a way to call this also in long escape (e.g. return) - v.compile_callsite(method_finish, [it]) + for g in n_groups do + var method_finish = g.method_finish + if method_finish != null then + # TODO: Find a way to call this also in long escape (e.g. return) + v.compile_callsite(method_finish, [g.it]) + end end end end +redef class AForGroup + # C variable representing the iterator + private var it: RuntimeVariable is noinit +end + redef class AAssertExpr redef fun stmt(v) do @@ -3650,6 +3702,7 @@ redef class ASendExpr do var recv = v.expr(self.n_expr, null) var callsite = self.callsite.as(not null) + if callsite.is_broken then return null var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments) return v.compile_callsite(callsite, args) end @@ -3660,6 +3713,7 @@ redef class ASendReassignFormExpr do var recv = v.expr(self.n_expr, null) var callsite = self.callsite.as(not null) + if callsite.is_broken then return var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments) var value = v.expr(self.n_value, null) @@ -3678,17 +3732,19 @@ end redef class ASuperExpr redef fun expr(v) do - var recv = v.frame.arguments.first + var frame = v.frame.as(not null) + var recv = frame.arguments.first var callsite = self.callsite if callsite != null then + if callsite.is_broken then return null var args if self.n_args.n_exprs.is_empty then # Add automatic arguments for the super init call args = [recv] for i in [0..callsite.msignature.arity[ do - args.add(v.frame.arguments[i+1]) + args.add(frame.arguments[i+1]) end else args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs) @@ -3703,7 +3759,7 @@ redef class ASuperExpr var args if self.n_args.n_exprs.is_empty then - args = v.frame.arguments + args = frame.arguments else args = v.varargize(mpropdef, signaturemap, recv, self.n_args.n_exprs) end @@ -3731,6 +3787,7 @@ redef class ANewExpr var callsite = self.callsite if callsite == null then return recv + if callsite.is_broken then return null var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs) var res2 = v.compile_callsite(callsite, args) @@ -3870,11 +3927,7 @@ end # Here we load an process all modules passed on the command line var mmodules = modelbuilder.parse(arguments) -if mmodules.is_empty then - toolcontext.check_errors - toolcontext.errors_info - if toolcontext.error_count > 0 then exit(1) else exit(0) -end +if mmodules.is_empty then toolcontext.quit modelbuilder.run_phases