X-Git-Url: http://nitlanguage.org diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 8ddd662..c785dd6 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -42,8 +42,6 @@ redef class ToolContext var opt_compile_dir = new OptionString("Directory used to generate temporary files", "--compile-dir") # --hardening var opt_hardening = new OptionBool("Generate contracts in the C code against bugs in the compiler", "--hardening") - # --no-shortcut-range - var opt_no_shortcut_range = new OptionBool("Always insantiate a range and its iterator on 'for' loops", "--no-shortcut-range") # --no-check-covariance var opt_no_check_covariance = new OptionBool("Disable type tests of covariant parameters (dangerous)", "--no-check-covariance") # --no-check-attr-isset @@ -72,7 +70,7 @@ redef class ToolContext redef init do super - self.option_context.add_option(self.opt_output, self.opt_dir, self.opt_no_cc, self.opt_no_main, self.opt_make_flags, self.opt_compile_dir, self.opt_hardening, self.opt_no_shortcut_range) + self.option_context.add_option(self.opt_output, self.opt_dir, self.opt_no_cc, self.opt_no_main, self.opt_make_flags, self.opt_compile_dir, self.opt_hardening) self.option_context.add_option(self.opt_no_check_covariance, self.opt_no_check_attr_isset, self.opt_no_check_assert, self.opt_no_check_autocast, self.opt_no_check_null, self.opt_no_check_all) self.option_context.add_option(self.opt_typing_test_metrics, self.opt_invocation_metrics, self.opt_isset_checks_metrics) self.option_context.add_option(self.opt_stacktrace) @@ -1279,6 +1277,14 @@ abstract class AbstractCompilerVisitor return name end + # Insert a C label for associated with an escapemark + fun add_escape_label(e: nullable EscapeMark) + do + if e == null then return + if e.escapes.is_empty then return + add("BREAK_{escapemark_name(e)}: (void)0;") + end + private var escapemark_names = new HashMap[EscapeMark, String] # Return a "const char*" variable associated to the classname of the dynamic type of an object @@ -1839,7 +1845,7 @@ redef class MMethodDef if modelbuilder.mpropdef2npropdef.has_key(self) then var npropdef = modelbuilder.mpropdef2npropdef[self] return npropdef.can_inline - else if self.mproperty.name == "init" then + else if self.mproperty.is_root_init then # Automatic free init is always inlined since it is empty or contains only attribtes assigments return true else @@ -1859,7 +1865,7 @@ redef class MMethodDef self.compile_parameter_check(v, arguments) npropdef.compile_to_c(v, self, arguments) v.current_node = oldnode - else if self.mproperty.name == "init" then + else if self.mproperty.is_root_init then var nclassdef = modelbuilder.mclassdef2nclassdef[self.mclassdef] var oldnode = v.current_node v.current_node = nclassdef @@ -1983,8 +1989,6 @@ redef class AMethPropdef var ret = mpropdef.msignature.return_mtype if ret != null then ret = v.resolve_for(ret, arguments.first) - else if mpropdef.mproperty.is_new then - ret = arguments.first.mcasttype end if pname != "==" and pname != "!=" then v.adapt_signature(mpropdef, arguments) @@ -2165,7 +2169,7 @@ redef class AMethPropdef else if pname == "atoi" then v.ret(v.new_expr("atoi({arguments[0]});", ret.as(not null))) return true - else if pname == "init" then + else if pname == "new" then v.ret(v.new_expr("(char*)nit_alloc({arguments[1]})", ret.as(not null))) return true end @@ -2397,8 +2401,7 @@ redef class AExpr # Do not call this method directly, use `v.stmt` instead private fun stmt(v: AbstractCompilerVisitor) do - var res = expr(v) - if res != null then v.add("{res};") + expr(v) end end @@ -2440,12 +2443,6 @@ redef class AVarExpr end redef class AVarAssignExpr - redef fun stmt(v) - do - var variable = self.variable.as(not null) - var i = v.expr(self.n_value, variable.declared_type) - v.assign(v.variable(variable), i) - end redef fun expr(v) do var variable = self.variable.as(not null) @@ -2471,11 +2468,7 @@ redef class ASelfExpr redef fun expr(v) do return v.frame.arguments.first end -redef class AContinueExpr - redef fun stmt(v) do v.add("goto CONTINUE_{v.escapemark_name(self.escapemark)};") -end - -redef class ABreakExpr +redef class AEscapeExpr redef fun stmt(v) do v.add("goto BREAK_{v.escapemark_name(self.escapemark)};") end @@ -2538,10 +2531,7 @@ redef class ADoExpr redef fun stmt(v) do v.stmt(self.n_block) - var escapemark = self.escapemark - if escapemark != null then - v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;") - end + v.add_escape_label(break_mark) end end @@ -2552,9 +2542,9 @@ redef class AWhileExpr var cond = v.expr_bool(self.n_expr) v.add("if (!{cond}) break;") v.stmt(self.n_block) - v.add("CONTINUE_{v.escapemark_name(escapemark)}: (void)0;") + v.add_escape_label(continue_mark) v.add("\}") - v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;") + v.add_escape_label(break_mark) end end @@ -2563,47 +2553,15 @@ redef class ALoopExpr do v.add("for(;;) \{") v.stmt(self.n_block) - v.add("CONTINUE_{v.escapemark_name(escapemark)}: (void)0;") + v.add_escape_label(continue_mark) v.add("\}") - v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;") + v.add_escape_label(break_mark) end end redef class AForExpr redef fun stmt(v) do - # Shortcut on explicit range - # Avoid the instantiation of the range and the iterator - var nexpr = self.n_expr - if self.variables.length == 1 and nexpr isa ARangeExpr and not v.compiler.modelbuilder.toolcontext.opt_no_shortcut_range.value then - var from = v.expr(nexpr.n_expr, null) - var to = v.expr(nexpr.n_expr2, null) - var variable = v.variable(variables.first) - var one = v.new_expr("1", v.get_class("Int").mclass_type) - - v.assign(variable, from) - v.add("for(;;) \{ /* shortcut range */") - - var ok - if nexpr isa AOrangeExpr then - ok = v.send(v.get_property("<", variable.mtype), [variable, to]) - else - ok = v.send(v.get_property("<=", variable.mtype), [variable, to]) - end - assert ok != null - v.add("if(!{ok}) break;") - - v.stmt(self.n_block) - - v.add("CONTINUE_{v.escapemark_name(escapemark)}: (void)0;") - var succ = v.send(v.get_property("successor", variable.mtype), [variable, one]) - assert succ != null - v.assign(variable, succ) - v.add("\}") - v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;") - return - end - var cl = v.expr(self.n_expr, null) var it_meth = self.method_iterator assert it_meth != null @@ -2636,12 +2594,12 @@ redef class AForExpr abort end v.stmt(self.n_block) - v.add("CONTINUE_{v.escapemark_name(escapemark)}: (void)0;") + v.add_escape_label(continue_mark) var next_meth = self.method_next assert next_meth != null v.compile_callsite(next_meth, [it]) v.add("\}") - v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;") + v.add_escape_label(break_mark) var method_finish = self.method_finish if method_finish != null then @@ -2940,7 +2898,8 @@ end redef class ANewExpr redef fun expr(v) do - var mtype = self.mtype.as(MClassType) + var mtype = self.recvtype + assert mtype != null var recv var ctype = mtype.ctype if mtype.mclass.name == "NativeArray" then @@ -2978,12 +2937,13 @@ redef class AAttrExpr end redef class AAttrAssignExpr - redef fun stmt(v) + redef fun expr(v) do var recv = v.expr(self.n_expr, null) var i = v.expr(self.n_value, null) var mproperty = self.mproperty.as(not null) v.write_attribute(mproperty, recv, i) + return i end end