X-Git-Url: http://nitlanguage.org diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index b212fed..273ee6f 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -212,7 +212,7 @@ class MakefileToolchain var hfilename = compiler.header.file.name + ".h" var hfilepath = "{compile_dir}/{hfilename}" - var h = new OFStream.open(hfilepath) + var h = new FileWriter.open(hfilepath) for l in compiler.header.decl_lines do h.write l h.write "\n" @@ -227,7 +227,7 @@ class MakefileToolchain for f in compiler.files do var i = 0 var count = 0 - var file: nullable OFStream = null + var file: nullable FileWriter = null for vis in f.writers do if vis == compiler.header then continue var total_lines = vis.lines.length + vis.decl_lines.length @@ -240,7 +240,7 @@ class MakefileToolchain var cfilepath = "{compile_dir}/{cfilename}" self.toolcontext.info("new C source files to compile: {cfilepath}", 3) cfiles.add(cfilename) - file = new OFStream.open(cfilepath) + file = new FileWriter.open(cfilepath) file.write "#include \"{f.name}.0.h\"\n" count = total_lines end @@ -258,8 +258,8 @@ class MakefileToolchain var cfilename = "{f.name}.0.h" var cfilepath = "{compile_dir}/{cfilename}" - var hfile: nullable OFStream = null - hfile = new OFStream.open(cfilepath) + var hfile: nullable FileWriter = null + hfile = new FileWriter.open(cfilepath) hfile.write "#include \"{hfilename}\"\n" for key in f.required_declarations do if not compiler.provided_declarations.has_key(key) then @@ -321,7 +321,7 @@ class MakefileToolchain end var makename = makefile_name(mainmodule) var makepath = "{compile_dir}/{makename}" - var makefile = new OFStream.open(makepath) + var makefile = new FileWriter.open(makepath) var linker_options = new HashSet[String] for m in mainmodule.in_importation.greaters do @@ -371,7 +371,7 @@ class MakefileToolchain if not compiler.linker_script.is_empty then var linker_script_path = "{compile_dir}/linker_script" ofiles.add "linker_script" - var f = new OFStream.open(linker_script_path) + var f = new FileWriter.open(linker_script_path) for l in compiler.linker_script do f.write l f.write "\n" @@ -546,7 +546,7 @@ abstract class AbstractCompiler do var compile_dir = modelbuilder.compile_dir - var stream = new OFStream.open("{compile_dir}/c_functions_hash.c") + var stream = new FileWriter.open("{compile_dir}/c_functions_hash.c") stream.write("#include \n") stream.write("#include \n") stream.write("#include \"c_functions_hash.h\"\n") @@ -576,7 +576,7 @@ abstract class AbstractCompiler stream.write("\}\n") stream.close - stream = new OFStream.open("{compile_dir}/c_functions_hash.h") + stream = new FileWriter.open("{compile_dir}/c_functions_hash.h") stream.write("const char* get_nit_name(register const char* procname, register unsigned int len);\n") stream.close @@ -1078,9 +1078,6 @@ abstract class AbstractCompilerVisitor self.writer = new CodeWriter(compiler.files.last) end - # Force to get the primitive class named `name` or abort - fun get_class(name: String): MClass do return self.compiler.mainmodule.get_primitive_class(name) - # Force to get the primitive property named `name` in the instance `recv` or abort fun get_property(name: String, recv: MType): MMethod do @@ -1387,6 +1384,24 @@ abstract class AbstractCompilerVisitor # Generate a alloc-instance + init-attributes fun init_instance(mtype: MClassType): RuntimeVariable is abstract + # Allocate and init attributes of an instance of a standard or extern class + # + # Does not support universals and the pseudo-internal `NativeArray` class. + fun init_instance_or_extern(mtype: MClassType): RuntimeVariable + do + var recv + var ctype = mtype.ctype + assert mtype.mclass.name != "NativeArray" + if ctype == "val*" then + recv = init_instance(mtype) + else if ctype == "char*" then + recv = new_expr("NULL/*special!*/", mtype) + else + recv = new_expr("({ctype})0/*special!*/", mtype) + end + return recv + end + # Set a GC finalizer on `recv`, only if `recv` isa Finalizable fun set_finalizer(recv: RuntimeVariable) do @@ -1398,6 +1413,11 @@ abstract class AbstractCompilerVisitor end end + # The currently processed module + # + # alias for `compiler.mainmodule` + fun mmodule: MModule do return compiler.mainmodule + # Generate an integer value fun int_instance(value: Int): RuntimeVariable do @@ -1421,14 +1441,14 @@ abstract class AbstractCompilerVisitor # Generate a string value fun string_instance(string: String): RuntimeVariable do - var mtype = self.get_class("String").mclass_type + var mtype = mmodule.string_type var name = self.get_name("varonce") self.add_decl("static {mtype.ctype} {name};") var res = self.new_var(mtype) - self.add("if ({name}) \{") + self.add("if (likely({name}!=NULL)) \{") self.add("{res} = {name};") self.add("\} else \{") - var native_mtype = self.get_class("NativeString").mclass_type + var native_mtype = mmodule.native_string_type var nat = self.new_var(native_mtype) self.add("{nat} = \"{string.escape_to_c}\";") var length = self.int_instance(string.length) @@ -1816,6 +1836,15 @@ redef class MMethodDef var modelbuilder = v.compiler.modelbuilder var val = constant_value var node = modelbuilder.mpropdef2node(self) + + if is_abstract then + 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});") + v.add_raw_abort + return null + end + if node isa APropdef then var oldnode = v.current_node v.current_node = node @@ -1875,13 +1904,6 @@ end redef class AMethPropdef redef fun compile_to_c(v, mpropdef, arguments) do - if mpropdef.is_abstract then - var cn = v.class_name_string(arguments.first) - v.add("PRINT_ERROR(\"Runtime error: Abstract method `%s` called on `%s`\", \"{mpropdef.mproperty.name.escape_to_c}\", {cn});") - v.add_raw_abort - return - end - # Call the implicit super-init var auto_super_inits = self.auto_super_inits if auto_super_inits != null then @@ -2286,7 +2308,7 @@ redef class AAttrPropdef fun init_expr(v: AbstractCompilerVisitor, recv: RuntimeVariable) do - if has_value and not is_lazy then evaluate_expr(v, recv) + if has_value and not is_lazy and not n_expr isa ANullExpr then evaluate_expr(v, recv) end # Evaluate, store and return the default value of the attribute @@ -2805,7 +2827,7 @@ redef class AOnceExpr v.add_decl("static {mtype.ctype} {name};") v.add_decl("static int {guard};") var res = v.new_var(mtype) - v.add("if ({guard}) \{") + v.add("if (likely({guard})) \{") v.add("{res} = {name};") v.add("\} else \{") var i = v.expr(self.n_expr, mtype) @@ -2883,22 +2905,17 @@ redef class ANewExpr do var mtype = self.recvtype assert mtype != null - var recv - var ctype = mtype.ctype + if mtype.mclass.name == "NativeArray" then assert self.n_args.n_exprs.length == 1 var l = v.expr(self.n_args.n_exprs.first, null) assert mtype isa MGenericType var elttype = mtype.arguments.first return v.native_array_instance(elttype, l) - else if ctype == "val*" then - recv = v.init_instance(mtype) - else if ctype == "char*" then - recv = v.new_expr("NULL/*special!*/", mtype) - else - recv = v.new_expr("({ctype})0/*special!*/", mtype) end + var recv = v.init_instance_or_extern(mtype) + var callsite = self.callsite.as(not null) var args = v.varargize(callsite.mpropdef, recv, self.n_args.n_exprs) var res2 = v.compile_callsite(callsite, args)