compiler: do not call C `nit_alloc` directly but a Nit method.
[nit.git] / src / compiler / abstract_compiler.nit
index 0263e11..e9eacef 100644 (file)
@@ -577,7 +577,7 @@ abstract class AbstractCompiler
 
        # The list of all associated files
        # Used to generate .c files
-       var files = new List[CodeFile]
+       var files = new Array[CodeFile]
 
        # Initialize a visitor specific for a compiler engine
        fun new_visitor: VISITOR is abstract
@@ -1127,8 +1127,8 @@ end
 # Where to store generated lines
 class CodeWriter
        var file: CodeFile
-       var lines: List[String] = new List[String]
-       var decl_lines: List[String] = new List[String]
+       var lines = new Array[String]
+       var decl_lines = new Array[String]
 
        # Add a line in the main part of the generated C
        fun add(s: String) do self.lines.add(s)
@@ -1208,8 +1208,6 @@ abstract class AbstractCompilerVisitor
 
        fun native_array_instance(elttype: MType, length: RuntimeVariable): RuntimeVariable is abstract
 
-       fun calloc_array(ret_type: MType, arguments: Array[RuntimeVariable]) is abstract
-
        fun native_array_def(pname: String, ret_type: nullable MType, arguments: Array[RuntimeVariable]): Bool do return false
 
        # Return an element of a native array.
@@ -1220,6 +1218,16 @@ abstract class AbstractCompilerVisitor
        # The method is unsafe and is just a direct wrapper for the specific implementation of native arrays
        fun native_array_set(native_array: RuntimeVariable, index: Int, value: RuntimeVariable) is abstract
 
+       # Allocate `size` bytes with the low_level `nit_alloc` C function
+       #
+       # This method can be redefined to inject statistic or tracing code.
+       #
+       # `tag` if any, is used to mark the class of the allocated object.
+       fun nit_alloc(size: String, tag: nullable String): String
+       do
+               return "nit_alloc({size})"
+       end
+
        # Evaluate `args` as expressions in the call of `mpropdef` on `recv`.
        # This method is used to manage varargs in signatures and returns the real array
        # of runtime variables to use in the call.
@@ -1652,9 +1660,9 @@ abstract class AbstractCompilerVisitor
                var native_mtype = mmodule.native_string_type
                var nat = self.new_var(native_mtype)
                self.add("{nat} = \"{string.escape_to_c}\";")
-               var bytelen = self.int_instance(string.bytelen)
+               var byte_length = self.int_instance(string.byte_length)
                var unilen = self.int_instance(string.length)
-               self.add("{res} = {self.send(self.get_property("to_s_full", native_mtype), [nat, bytelen, unilen]).as(not null)};")
+               self.add("{res} = {self.send(self.get_property("to_s_full", native_mtype), [nat, byte_length, unilen]).as(not null)};")
                self.add("{name} = {res};")
                self.add("\}")
                return res
@@ -2551,7 +2559,8 @@ redef class AMethPropdef
                                v.ret(v.new_expr("!{res}", ret.as(not null)))
                                return true
                        else if pname == "new" then
-                               v.ret(v.new_expr("(char*)nit_alloc({arguments[1]})", ret.as(not null)))
+                               var alloc = v.nit_alloc(arguments[1].to_s, "NativeString")
+                               v.ret(v.new_expr("(char*){alloc}", ret.as(not null)))
                                return true
                        else if pname == "fetch_4_chars" then
                                v.ret(v.new_expr("(long)*((uint32_t*)({arguments[0]} + {arguments[1]}))", ret.as(not null)))
@@ -3004,12 +3013,6 @@ redef class AMethPropdef
                else if pname == "sys" then
                        v.ret(v.new_expr("glob_sys", ret.as(not null)))
                        return true
-               else if pname == "calloc_string" then
-                       v.ret(v.new_expr("(char*)nit_alloc({arguments[1]})", ret.as(not null)))
-                       return true
-               else if pname == "calloc_array" then
-                       v.calloc_array(ret.as(not null), arguments)
-                       return true
                else if pname == "object_id" then
                        v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
                        return true
@@ -3162,7 +3165,7 @@ redef class AAttrPropdef
 
        fun init_expr(v: AbstractCompilerVisitor, recv: RuntimeVariable)
        do
-               if has_value and not is_lazy and not n_expr isa ANullExpr then evaluate_expr(v, recv)
+               if has_value and not is_lazy and not is_optional and not n_expr isa ANullExpr then evaluate_expr(v, recv)
        end
 
        # Evaluate, store and return the default value of the attribute