From: Jean Privat Date: Mon, 23 Mar 2015 15:16:18 +0000 (+0700) Subject: Merge: compiler: introduce and use `MType::is_c_primitive` X-Git-Tag: v0.7.3~14 X-Git-Url: http://nitlanguage.org?hp=be86e36868f07afb3801a56ccde79377d96c0477 Merge: compiler: introduce and use `MType::is_c_primitive` Thus remove all comparaison to "val*" in the code, this is cleaner. Pull-Request: #1214 Reviewed-by: Alexis Laferrière Reviewed-by: Alexandre Terrasa --- diff --git a/contrib/header_keeper/Makefile b/contrib/header_keeper/Makefile new file mode 100644 index 0000000..76d36c6 --- /dev/null +++ b/contrib/header_keeper/Makefile @@ -0,0 +1,7 @@ +bin/header_keeper: + mkdir -p bin + ../../bin/nitc --dir bin src/header_keeper.nit + +tests: bin/header_keeper + gcc -E /usr/include/SDL/SDL_image.h | bin/header_keeper SDL_image.h + gcc -E /usr/include/GLES2/gl2.h | bin/header_keeper gl2.h diff --git a/contrib/header_keeper/src/header_keeper.nit b/contrib/header_keeper/src/header_keeper.nit new file mode 100644 index 0000000..adf6b77 --- /dev/null +++ b/contrib/header_keeper/src/header_keeper.nit @@ -0,0 +1,57 @@ +# This file is part of NIT (http://www.nitlanguage.org). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Filters preprocessed C-like header files to remove included files +# +# This tool is used in the process of parsing header files to extract +# information on the declared services (the functions and structures). +# This information is then used to generate bindings for Nit code +# to access these services. +# +# The C preprocessor extends macros, inline files marked with `#include`, +# and more. This tool acts after the C preprocessor, in a way to keep +# everything but the included files. It searches for line pragmas +# to identify the source of each line. The result is printed to stdout. +# +# Typical usage on the output of `gcc -E` (it would be the same with `clang`): +# +# ~~~sh +# gcc -E /usr/include/SDL/SDL_image.h | header_keeper SDL_image.h > preprocessed_header.h +# ~~~ +# +# This module can also be used as a library. +# The main service is the method `header_keeper`. +module header_keeper + +# Filters the preprocessed `input` to keep only files from `target` and write to the `output` +fun header_keeper(input: Reader, output: Writer, target: String) +do + var in_target = false + while not input.eof do + var line = input.read_line + if not line.is_empty and line[0] == '#' then + in_target = line.has(target) + continue + end + + if in_target then output.write line + "\n" + end +end + +if args.length != 1 then + print "Usage: header_keeper header_name.h" + exit 1 +end + +header_keeper(sys.stdin, sys.stdout, args.first) diff --git a/lib/standard/exec_nit.c b/lib/standard/exec_nit.c index 317e909..5b5ffbb 100644 --- a/lib/standard/exec_nit.c +++ b/lib/standard/exec_nit.c @@ -142,3 +142,11 @@ void exec_NativeProcess_NativeProcess_wait_0(void*d) { data->running = 0; } } + +int string_NativeString_NativeString_system_0(const char *cmd) { + int status = system(cmd); + if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT) { + // cmd exited on SIGINT: in my opinion the user wants the main to be discontinued + kill(getpid(), SIGINT); + } +} diff --git a/lib/standard/exec_nit.h b/lib/standard/exec_nit.h index c6a59d4..fbd040a 100644 --- a/lib/standard/exec_nit.h +++ b/lib/standard/exec_nit.h @@ -31,7 +31,7 @@ struct se_exec_data { se_exec_data_t* exec_Process_Process_basic_exec_execute_4(void *, char *, char *, int, int); -#define string_NativeString_NativeString_system_0(self) (system(self)) +int string_NativeString_NativeString_system_0(const char*); #define exec_NativeProcess_NativeProcess_id_0(self) (((se_exec_data_t*)self)->id) #define exec_NativeProcess_NativeProcess_status_0(self) (((se_exec_data_t*)self)->status) diff --git a/src/astbuilder.nit b/src/astbuilder.nit index 8aa0295..99c8763 100644 --- a/src/astbuilder.nit +++ b/src/astbuilder.nit @@ -32,7 +32,7 @@ class ASTBuilder # Make a new Int literal fun make_int(value: Int): AIntExpr do - return new ADecIntExpr.make(value, mmodule.get_primitive_class("Int").mclass_type) + return new ADecIntExpr.make(value, mmodule.int_type) end # Make a new instatiation diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 5d5a4bc..c3952e3 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -603,9 +603,9 @@ abstract class AbstractCompiler var gccd_disable = modelbuilder.toolcontext.opt_no_gcc_directive.value if gccd_disable.has("noreturn") or gccd_disable.has("all") then # Signal handler function prototype - self.header.add_decl("void show_backtrace(int);") + self.header.add_decl("void fatal_exit(int);") else - self.header.add_decl("void show_backtrace(int) __attribute__ ((noreturn));") + self.header.add_decl("void fatal_exit(int) __attribute__ ((noreturn));") end if gccd_disable.has("likely") or gccd_disable.has("all") then @@ -741,12 +741,7 @@ extern void nitni_global_ref_decr( struct nitni_ref *ref ); v.compiler.header.add_decl("extern long count_isset_checks;") end - v.add_decl("void sig_handler(int signo)\{") - v.add_decl("PRINT_ERROR(\"Caught signal : %s\\n\", strsignal(signo));") - v.add_decl("show_backtrace(signo);") - v.add_decl("\}") - - v.add_decl("void show_backtrace (int signo) \{") + v.add_decl("static void show_backtrace(void) \{") if ost == "nitstack" or ost == "libunwind" then v.add_decl("char* opt = getenv(\"NIT_NO_STACK\");") v.add_decl("unw_cursor_t cursor;") @@ -776,7 +771,19 @@ extern void nitni_global_ref_decr( struct nitni_ref *ref ); v.add_decl("free(procname);") v.add_decl("\}") end - v.add_decl("exit(signo);") + v.add_decl("\}") + + v.add_decl("void sig_handler(int signo)\{") + v.add_decl("PRINT_ERROR(\"Caught signal : %s\\n\", strsignal(signo));") + v.add_decl("show_backtrace();") + # rethrows + v.add_decl("signal(signo, SIG_DFL);") + v.add_decl("kill(getpid(), signo);") + v.add_decl("\}") + + v.add_decl("void fatal_exit(int status) \{") + v.add_decl("show_backtrace();") + v.add_decl("exit(status);") v.add_decl("\}") if no_main then @@ -1078,9 +1085,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 @@ -1416,37 +1420,64 @@ 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 - var res = self.new_var(self.get_class("Int").mclass_type) - self.add("{res} = {value};") + var t = mmodule.int_type + var res = new RuntimeVariable("{value.to_s}l", t, t) + return res + end + + # Generate a char value + fun char_instance(value: Char): RuntimeVariable + do + var t = mmodule.char_type + var res = new RuntimeVariable("'{value.to_s.escape_to_c}'", t, t) + return res + end + + # Generate a float value + # + # FIXME pass a Float, not a string + fun float_instance(value: String): RuntimeVariable + do + var t = mmodule.float_type + var res = new RuntimeVariable("{value}", t, t) return res end # Generate an integer value fun bool_instance(value: Bool): RuntimeVariable do - var res = self.new_var(self.get_class("Bool").mclass_type) - if value then - self.add("{res} = 1;") - else - self.add("{res} = 0;") - end + var s = if value then "1" else "0" + var res = new RuntimeVariable(s, bool_type, bool_type) + return res + end + + # Generate the `null` value + fun null_instance: RuntimeVariable + do + var t = compiler.mainmodule.model.null_type + var res = new RuntimeVariable("((val*)NULL)", t, t) return res end # 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 (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) @@ -1557,7 +1588,7 @@ abstract class AbstractCompilerVisitor else self.add("PRINT_ERROR(\"\\n\");") end - self.add("show_backtrace(1);") + self.add("fatal_exit(1);") end # Add a dynamic cast @@ -2287,7 +2318,7 @@ redef class AAttrPropdef v.assign(res, value) if not useiset then - var true_v = v.new_expr("1", v.bool_type) + var true_v = v.bool_instance(true) v.write_attribute(guard, arguments.first, true_v) end v.add("\}") @@ -2302,7 +2333,7 @@ redef class AAttrPropdef var ret = self.mpropdef.static_mtype var useiset = not ret.is_c_primitive and not ret isa MNullableType if not useiset then - v.write_attribute(self.mlazypropdef.mproperty, arguments.first, v.new_expr("1", v.bool_type)) + v.write_attribute(self.mlazypropdef.mproperty, arguments.first, v.bool_instance(true)) end end else @@ -2700,15 +2731,15 @@ redef class AOrElseExpr end redef class AIntExpr - redef fun expr(v) do return v.new_expr("{self.value.to_s}", self.mtype.as(not null)) + redef fun expr(v) do return v.int_instance(self.value.as(not null)) end redef class AFloatExpr - redef fun expr(v) do return v.new_expr("{self.n_float.text}", self.mtype.as(not null)) # FIXME use value, not n_float + redef fun expr(v) do return v.float_instance("{self.n_float.text}") # FIXME use value, not n_float end redef class ACharExpr - redef fun expr(v) do return v.new_expr("'{self.value.to_s.escape_to_c}'", self.mtype.as(not null)) + redef fun expr(v) do return v.char_instance(self.value.as(not null)) end redef class AArrayExpr @@ -2773,15 +2804,15 @@ redef class AOrangeExpr end redef class ATrueExpr - redef fun expr(v) do return v.new_expr("1", self.mtype.as(not null)) + redef fun expr(v) do return v.bool_instance(true) end redef class AFalseExpr - redef fun expr(v) do return v.new_expr("0", self.mtype.as(not null)) + redef fun expr(v) do return v.bool_instance(false) end redef class ANullExpr - redef fun expr(v) do return v.new_expr("NULL", self.mtype.as(not null)) + redef fun expr(v) do return v.null_instance end redef class AIsaExpr diff --git a/src/compiler/global_compiler.nit b/src/compiler/global_compiler.nit index 9130588..9a89064 100644 --- a/src/compiler/global_compiler.nit +++ b/src/compiler/global_compiler.nit @@ -312,7 +312,7 @@ class GlobalCompilerVisitor var res = self.new_var(mtype) if not compiler.runtime_type_analysis.live_types.has(valtype) then self.add("/*no autobox from {value.mtype} to {mtype}: {value.mtype} is not live! */") - self.add("PRINT_ERROR(\"Dead code executed!\\n\"); show_backtrace(1);") + self.add("PRINT_ERROR(\"Dead code executed!\\n\"); fatal_exit(1);") return res end self.add("{res} = BOX_{valtype.c_name}({value}); /* autobox from {value.mtype} to {mtype} */") @@ -323,7 +323,7 @@ class GlobalCompilerVisitor # Bad things will appen! var res = self.new_var(mtype) self.add("/* {res} left unintialized (cannot convert {value.mtype} to {mtype}) */") - self.add("PRINT_ERROR(\"Cast error: Cannot cast %s to %s.\\n\", \"{value.mtype}\", \"{mtype}\"); show_backtrace(1);") + self.add("PRINT_ERROR(\"Cast error: Cannot cast %s to %s.\\n\", \"{value.mtype}\", \"{mtype}\"); fatal_exit(1);") return res end end @@ -349,7 +349,7 @@ class GlobalCompilerVisitor var res = self.new_var(mtype) if not compiler.runtime_type_analysis.live_types.has(value.mtype.as(MClassType)) then self.add("/*no boxing of {value.mtype}: {value.mtype} is not live! */") - self.add("PRINT_ERROR(\"Dead code executed!\\n\"); show_backtrace(1);") + self.add("PRINT_ERROR(\"Dead code executed!\\n\"); fatal_exit(1);") return res end self.add("{res} = BOX_{valtype.c_name}({value}); /* boxing {value.mtype} */") @@ -402,7 +402,7 @@ class GlobalCompilerVisitor redef fun native_array_instance(elttype: MType, length: RuntimeVariable): RuntimeVariable do - var ret_type = self.get_class("NativeArray").get_mtype([elttype]) + var ret_type = mmodule.native_array_type(elttype) ret_type = anchor(ret_type).as(MClassType) return self.new_expr("NEW_{ret_type.c_name}({length})", ret_type) end @@ -630,7 +630,7 @@ class GlobalCompilerVisitor do if recv.mtype.is_c_primitive then return self.add("PRINT_ERROR(\"BTD BUG: Dynamic type is %s, static type is %s\\n\", class_names[{recv}->classid], \"{recv.mcasttype}\");") - self.add("show_backtrace(1);") + self.add("fatal_exit(1);") end redef fun isset_attribute(a, recv) @@ -894,10 +894,10 @@ class GlobalCompilerVisitor redef fun array_instance(array, elttype) do elttype = self.anchor(elttype) - var arraytype = self.get_class("Array").get_mtype([elttype]) + var arraytype = mmodule.array_type(elttype) var res = self.init_instance(arraytype) self.add("\{ /* {res} = array_instance Array[{elttype}] */") - var nat = self.new_var(self.get_class("NativeArray").get_mtype([elttype])) + var nat = self.new_var(mmodule.native_array_type(elttype)) nat.is_exact = true self.add("{nat} = NEW_{nat.mtype.c_name}({array.length});") for i in [0..array.length[ do @@ -991,7 +991,7 @@ private class CustomizedRuntimeFunction for i in [0..mmethoddef.msignature.arity[ do var mtype = mmethoddef.msignature.mparameters[i].mtype if i == mmethoddef.msignature.vararg_rank then - mtype = v.get_class("Array").get_mtype([mtype]) + mtype = v.mmodule.array_type(mtype) end mtype = v.resolve_for(mtype, selfvar) comment.append(", {mtype}") diff --git a/src/compiler/separate_compiler.nit b/src/compiler/separate_compiler.nit index af3cdd9..8cb75e7 100644 --- a/src/compiler/separate_compiler.nit +++ b/src/compiler/separate_compiler.nit @@ -268,7 +268,7 @@ class SeparateCompiler if mclass.mclass_type.ctype_extern == "val*" then return 0 else if mclass.kind == extern_kind and mclass.name != "NativeString" then - return self.box_kinds[self.mainmodule.get_primitive_class("Pointer")] + return self.box_kinds[self.mainmodule.pointer_type.mclass] else return self.box_kinds[mclass] end @@ -456,14 +456,9 @@ class SeparateCompiler # Collect types to colorize var live_types = runtime_type_analysis.live_types var live_cast_types = runtime_type_analysis.live_cast_types - var mtypes = new HashSet[MType] - mtypes.add_all(live_types) - for c in self.box_kinds.keys do - mtypes.add(c.mclass_type) - end # Compute colors - var poset = poset_from_mtypes(mtypes, live_cast_types) + var poset = poset_from_mtypes(live_types, live_cast_types) var colorer = new POSetColorer[MType] colorer.colorize(poset) type_ids = colorer.ids @@ -471,20 +466,42 @@ class SeparateCompiler type_tables = build_type_tables(poset) # VT and FT are stored with other unresolved types in the big resolution_tables - self.compile_resolution_tables(mtypes) + self.compute_resolution_tables(live_types) return poset end private fun poset_from_mtypes(mtypes, cast_types: Set[MType]): POSet[MType] do var poset = new POSet[MType] + + # Instead of doing the full matrix mtypes X cast_types, + # a grouping is done by the base classes of the type so + # that we compare only types whose base classes are in inheritance. + + var mtypes_by_class = new MultiHashMap[MClass, MType] for e in mtypes do + var c = e.as_notnullable.as(MClassType).mclass + mtypes_by_class[c].add(e) poset.add_node(e) - for o in cast_types do - if e == o then continue - poset.add_node(o) - if e.is_subtype(mainmodule, null, o) then - poset.add_edge(e, o) + end + + var casttypes_by_class = new MultiHashMap[MClass, MType] + for e in cast_types do + var c = e.as_notnullable.as(MClassType).mclass + casttypes_by_class[c].add(e) + poset.add_node(e) + end + + for c1, ts1 in mtypes_by_class do + for c2 in c1.in_hierarchy(mainmodule).greaters do + var ts2 = casttypes_by_class[c2] + for e in ts1 do + for o in ts2 do + if e == o then continue + if e.is_subtype(mainmodule, null, o) then + poset.add_edge(e, o) + end + end end end end @@ -510,9 +527,8 @@ class SeparateCompiler return tables end - protected fun compile_resolution_tables(mtypes: Set[MType]) do - # resolution_tables is used to perform a type resolution at runtime in O(1) - + # resolution_tables is used to perform a type resolution at runtime in O(1) + private fun compute_resolution_tables(mtypes: Set[MType]) do # During the visit of the body of classes, live_unresolved_types are collected # and associated to # Collect all live_unresolved_types (visited in the body of classes) @@ -973,6 +989,7 @@ class SeparateCompiler v.add_decl("NULL,") else var s = "type_{t.c_name}" + undead_types.add(t.mclass_type) v.require_declaration(s) v.add_decl("&{s},") end @@ -1170,7 +1187,7 @@ class SeparateCompilerVisitor var res = self.new_var(mtype) if compiler.runtime_type_analysis != null and not compiler.runtime_type_analysis.live_types.has(valtype) then self.add("/*no autobox from {value.mtype} to {mtype}: {value.mtype} is not live! */") - self.add("PRINT_ERROR(\"Dead code executed!\\n\"); show_backtrace(1);") + self.add("PRINT_ERROR(\"Dead code executed!\\n\"); fatal_exit(1);") return res end self.require_declaration("BOX_{valtype.c_name}") @@ -1184,7 +1201,7 @@ class SeparateCompilerVisitor # Bad things will appen! var res = self.new_var(mtype) self.add("/* {res} left unintialized (cannot convert {value.mtype} to {mtype}) */") - self.add("PRINT_ERROR(\"Cast error: Cannot cast %s to %s.\\n\", \"{value.mtype}\", \"{mtype}\"); show_backtrace(1);") + self.add("PRINT_ERROR(\"Cast error: Cannot cast %s to %s.\\n\", \"{value.mtype}\", \"{mtype}\"); fatal_exit(1);") return res end end @@ -1210,7 +1227,7 @@ class SeparateCompilerVisitor var res = self.new_var(mtype) if compiler.runtime_type_analysis != null and not compiler.runtime_type_analysis.live_types.has(value.mtype.as(MClassType)) then self.add("/*no boxing of {value.mtype}: {value.mtype} is not live! */") - self.add("PRINT_ERROR(\"Dead code executed!\\n\"); show_backtrace(1);") + self.add("PRINT_ERROR(\"Dead code executed!\\n\"); fatal_exit(1);") return res end self.require_declaration("BOX_{valtype.c_name}") @@ -1770,7 +1787,7 @@ class SeparateCompilerVisitor self.add("count_type_test_resolved_{tag}++;") end else - self.add("PRINT_ERROR(\"NOT YET IMPLEMENTED: type_test(%s, {mtype}).\\n\", \"{value.inspect}\"); show_backtrace(1);") + self.add("PRINT_ERROR(\"NOT YET IMPLEMENTED: type_test(%s, {mtype}).\\n\", \"{value.inspect}\"); fatal_exit(1);") end # check color is in table @@ -1967,8 +1984,8 @@ class SeparateCompilerVisitor redef fun array_instance(array, elttype) do - var nclass = self.get_class("NativeArray") - var arrayclass = self.get_class("Array") + var nclass = mmodule.native_array_class + var arrayclass = mmodule.array_class var arraytype = arrayclass.get_mtype([elttype]) var res = self.init_instance(arraytype) self.add("\{ /* {res} = array_instance Array[{elttype}] */") @@ -1985,7 +2002,7 @@ class SeparateCompilerVisitor redef fun native_array_instance(elttype: MType, length: RuntimeVariable): RuntimeVariable do - var mtype = self.get_class("NativeArray").get_mtype([elttype]) + var mtype = mmodule.native_array_type(elttype) self.require_declaration("NEW_{mtype.mclass.c_name}") assert mtype isa MGenericType var compiler = self.compiler @@ -2005,7 +2022,7 @@ class SeparateCompilerVisitor redef fun native_array_def(pname, ret_type, arguments) do var elttype = arguments.first.mtype - var nclass = self.get_class("NativeArray") + var nclass = mmodule.native_array_class var recv = "((struct instance_{nclass.c_name}*){arguments[0]})->values" if pname == "[]" then # Because the objects are boxed, return the box to avoid unnecessary (or broken) unboxing/reboxing @@ -2026,14 +2043,6 @@ class SeparateCompilerVisitor end end - redef fun calloc_array(ret_type, arguments) - do - var mclass = self.get_class("ArrayCapable") - var ft = mclass.mparameters.first - var res = self.native_array_instance(ft, arguments[1]) - self.ret(res) - end - fun link_unresolved_type(mclassdef: MClassDef, mtype: MType) do assert mtype.need_anchor var compiler = self.compiler @@ -2144,7 +2153,7 @@ class SeparateRuntimeFunction for i in [0..called_signature.arity[ do var mtype = called_signature.mparameters[i].mtype if i == called_signature.vararg_rank then - mtype = mmethoddef.mclassdef.mmodule.get_primitive_class("Array").get_mtype([mtype]) + mtype = mmethoddef.mclassdef.mmodule.array_type(mtype) end sig.append(", {mtype.ctype} p{i}") end @@ -2183,7 +2192,7 @@ class SeparateRuntimeFunction for i in [0..msignature.arity[ do var mtype = msignature.mparameters[i].mtype if i == msignature.vararg_rank then - mtype = v.get_class("Array").get_mtype([mtype]) + mtype = v.mmodule.array_type(mtype) end comment.append(", {mtype}") var argvar = new RuntimeVariable("p{i}", mtype, mtype) diff --git a/src/compiler/separate_erasure_compiler.nit b/src/compiler/separate_erasure_compiler.nit index 004d361..2a7f0fa 100644 --- a/src/compiler/separate_erasure_compiler.nit +++ b/src/compiler/separate_erasure_compiler.nit @@ -615,7 +615,7 @@ class SeparateErasureCompilerVisitor var res = self.new_var(mtype) if compiler.runtime_type_analysis != null and not compiler.runtime_type_analysis.live_types.has(value.mtype.as(MClassType)) then self.add("/*no boxing of {value.mtype}: {value.mtype} is not live! */") - self.add("PRINT_ERROR(\"Dead code executed!\\n\"); show_backtrace(1);") + self.add("PRINT_ERROR(\"Dead code executed!\\n\"); fatal_exit(1);") return res end self.require_declaration("BOX_{valtype.c_name}") @@ -643,7 +643,7 @@ class SeparateErasureCompilerVisitor redef fun native_array_instance(elttype, length) do - var nclass = self.get_class("NativeArray") + var nclass = mmodule.native_array_class var mtype = nclass.get_mtype([elttype]) var res = self.new_var(mtype) res.is_exact = true diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index 311d917..aba779a 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -201,8 +201,8 @@ class NaiveInterpreter # Return the integer instance associated with `val`. fun int_instance(val: Int): Instance do - var ic = get_primitive_class("Int") - var instance = new PrimitiveInstance[Int](ic.mclass_type, val) + var t = mainmodule.int_type + var instance = new PrimitiveInstance[Int](t, val) init_instance_primitive(instance) return instance end @@ -210,8 +210,8 @@ class NaiveInterpreter # Return the char instance associated with `val`. fun char_instance(val: Char): Instance do - var ic = get_primitive_class("Char") - var instance = new PrimitiveInstance[Char](ic.mclass_type, val) + var t = mainmodule.char_type + var instance = new PrimitiveInstance[Char](t, val) init_instance_primitive(instance) return instance end @@ -219,8 +219,8 @@ class NaiveInterpreter # Return the float instance associated with `val`. fun float_instance(val: Float): Instance do - var ic = get_primitive_class("Float") - var instance = new PrimitiveInstance[Float](ic.mclass_type, val) + var t = mainmodule.float_type + var instance = new PrimitiveInstance[Float](t, val) init_instance_primitive(instance) return instance end @@ -239,9 +239,9 @@ class NaiveInterpreter fun array_instance(values: Array[Instance], elttype: MType): Instance do assert not elttype.need_anchor - var nat = new PrimitiveInstance[Array[Instance]](get_primitive_class("NativeArray").get_mtype([elttype]), values) + var nat = new PrimitiveInstance[Array[Instance]](mainmodule.native_array_type(elttype), values) init_instance_primitive(nat) - var mtype = get_primitive_class("Array").get_mtype([elttype]) + var mtype = mainmodule.array_type(elttype) var res = new MutableInstance(mtype) self.init_instance(res) self.send(self.force_get_primitive_method("with_native", mtype), [res, nat, self.int_instance(values.length)]) @@ -268,8 +268,8 @@ class NaiveInterpreter do var val = new FlatBuffer.from(txt) val.add('\0') - var ic = get_primitive_class("NativeString") - var instance = new PrimitiveInstance[Buffer](ic.mclass_type, val) + var t = mainmodule.native_string_type + var instance = new PrimitiveInstance[Buffer](t, val) init_instance_primitive(instance) return instance end @@ -588,13 +588,6 @@ class NaiveInterpreter # A hook to initialize a `PrimitiveInstance` fun init_instance_primitive(recv: Instance) do end - # Return the primitive `MClass` corresponding to the `name` given in parameter - # `name` : name of the primitive class - fun get_primitive_class(name: String): MClass - do - return mainmodule.get_primitive_class(name) - end - # This function determines the correct type according to the receiver of the current propdef (self). fun unanchor_type(mtype: MType): MType do @@ -1030,7 +1023,7 @@ redef class AMethPropdef if pname == "files" then var res = new Array[Instance] for f in str.files do res.add v.string_instance(f) - return v.array_instance(res, v.get_primitive_class("String").mclass_type) + return v.array_instance(res, v.mainmodule.string_type) end else if pname == "calloc_string" then return v.native_string_instance("!" * args[1].to_i) @@ -1104,15 +1097,6 @@ redef class AMethPropdef else if pname == "set_buffering_type" then return v.int_instance(recvval.as(PrimitiveNativeFile).set_buffering_type(args[1].to_i, args[2].to_i)) end - else if pname == "calloc_array" then - var recvtype = args.first.mtype.as(MClassType) - var mtype: MType - mtype = recvtype.supertype_to(v.mainmodule, recvtype, v.get_primitive_class("ArrayCapable")) - mtype = mtype.arguments.first - var val = new Array[Instance].filled_with(v.null_instance, args[1].to_i) - var instance = new PrimitiveInstance[Array[Instance]](v.get_primitive_class("NativeArray").get_mtype([mtype]), val) - v.init_instance_primitive(instance) - return instance else if pname == "native_argc" then return v.int_instance(v.arguments.length) else if pname == "native_argv" then @@ -1606,7 +1590,7 @@ redef class ASuperstringExpr if i == null then return null array.add(i) end - var i = v.array_instance(array, v.get_primitive_class("Object").mclass_type) + var i = v.array_instance(array, v.mainmodule.object_type) var res = v.send(v.force_get_primitive_method("to_s", i.mtype), [i]) assert res != null return res diff --git a/src/model/model.nit b/src/model/model.nit index b483543..3a64638 100644 --- a/src/model/model.nit +++ b/src/model/model.nit @@ -195,31 +195,40 @@ redef class MModule private var flatten_mclass_hierarchy_cache: nullable POSet[MClass] = null # The primitive type `Object`, the root of the class hierarchy - fun object_type: MClassType - do - var res = self.object_type_cache - if res != null then return res - res = self.get_primitive_class("Object").mclass_type - self.object_type_cache = res - return res - end - - private var object_type_cache: nullable MClassType + var object_type: MClassType = self.get_primitive_class("Object").mclass_type is lazy # The type `Pointer`, super class to all extern classes var pointer_type: MClassType = self.get_primitive_class("Pointer").mclass_type is lazy # The primitive type `Bool` - fun bool_type: MClassType - do - var res = self.bool_type_cache - if res != null then return res - res = self.get_primitive_class("Bool").mclass_type - self.bool_type_cache = res - return res - end + var bool_type: MClassType = self.get_primitive_class("Bool").mclass_type is lazy + + # The primitive type `Int` + var int_type: MClassType = self.get_primitive_class("Int").mclass_type is lazy + + # The primitive type `Char` + var char_type: MClassType = self.get_primitive_class("Char").mclass_type is lazy + + # The primitive type `Float` + var float_type: MClassType = self.get_primitive_class("Float").mclass_type is lazy + + # The primitive type `String` + var string_type: MClassType = self.get_primitive_class("String").mclass_type is lazy + + # The primitive type `NativeString` + var native_string_type: MClassType = self.get_primitive_class("NativeString").mclass_type is lazy + + # A primitive type of `Array` + fun array_type(elt_type: MType): MClassType do return array_class.get_mtype([elt_type]) + + # The primitive class `Array` + var array_class: MClass = self.get_primitive_class("Array") is lazy + + # A primitive type of `NativeArray` + fun native_array_type(elt_type: MType): MClassType do return native_array_class.get_mtype([elt_type]) - private var bool_type_cache: nullable MClassType + # The primitive class `NativeArray` + var native_array_class: MClass = self.get_primitive_class("NativeArray") is lazy # The primitive type `Sys`, the main type of the program, if any fun sys_type: nullable MClassType diff --git a/src/rapid_type_analysis.nit b/src/rapid_type_analysis.nit index a6cd32e..bcae37f 100644 --- a/src/rapid_type_analysis.nit +++ b/src/rapid_type_analysis.nit @@ -225,9 +225,9 @@ class RapidTypeAnalysis var node = self.modelbuilder.mpropdef2node(mmethoddef) var elttype = mmethoddef.msignature.mparameters[vararg_rank].mtype #elttype = elttype.anchor_to(self.mainmodule, v.receiver) - var vararg = self.mainmodule.get_primitive_class("Array").get_mtype([elttype]) + var vararg = self.mainmodule.array_type(elttype) v.add_type(vararg) - var native = self.mainmodule.get_primitive_class("NativeArray").get_mtype([elttype]) + var native = self.mainmodule.native_array_type(elttype) v.add_type(native) v.add_monomorphic_send(vararg, self.modelbuilder.force_get_primitive_method(node, "with_native", vararg.mclass, self.mainmodule)) end @@ -471,11 +471,6 @@ class RapidTypeVisitor return mtype end - fun get_class(name: String): MClass - do - return analysis.mainmodule.get_primitive_class(name) - end - fun get_method(recv: MType, name: String): MMethod do var mtype = cleanup_type(recv) @@ -540,7 +535,7 @@ redef class AArrayExpr do var mtype = self.mtype.as(MClassType) v.add_type(mtype) - var native = v.analysis.mainmodule.get_primitive_class("NativeArray").get_mtype([mtype.arguments.first]) + var native = v.analysis.mainmodule.native_array_type(mtype.arguments.first) v.add_type(native) mtype = v.cleanup_type(mtype).as(not null) var prop = v.get_method(mtype, "with_native") @@ -551,7 +546,7 @@ end redef class AStringFormExpr redef fun accept_rapid_type_visitor(v) do - var native = v.get_class("NativeString").mclass_type + var native = v.analysis.mainmodule.native_string_type v.add_type(native) var prop = v.get_method(native, "to_s_with_length") v.add_monomorphic_send(native, prop) @@ -561,9 +556,11 @@ end redef class ASuperstringExpr redef fun accept_rapid_type_visitor(v) do - var arraytype = v.get_class("Array").get_mtype([v.get_class("Object").mclass_type]) + var mmodule = v.analysis.mainmodule + var object_type = mmodule.object_type + var arraytype = mmodule.array_type(object_type) v.add_type(arraytype) - v.add_type(v.get_class("NativeArray").get_mtype([v.get_class("Object").mclass_type])) + v.add_type(mmodule.native_array_type(object_type)) var prop = v.get_method(arraytype, "join") v.add_monomorphic_send(arraytype, prop) var prop2 = v.get_method(arraytype, "with_native") diff --git a/src/transform.nit b/src/transform.nit index 8ae2c28..dac3c4f 100644 --- a/src/transform.nit +++ b/src/transform.nit @@ -73,12 +73,6 @@ private class TransformVisitor node.full_transform_visitor(self) end - # Get a primitive class or display a fatal error on `location`. - fun get_class(location: AExpr, name: String): MClass - do - return mmodule.get_primitive_class(name) - end - # Get a primitive method or display a fatal error on `location`. fun get_method(location: AExpr, name: String, recv: MClass): MMethod do diff --git a/src/vm.nit b/src/vm.nit index b253533..97069cf 100644 --- a/src/vm.nit +++ b/src/vm.nit @@ -177,15 +177,6 @@ class VirtualMachine super NaiveInterpreter recv.vtable = recv.mtype.as(MClassType).mclass.vtable end - # Create a virtual table for this `MClass` if not already done - redef fun get_primitive_class(name: String): MClass - do - var mclass = super - - if not mclass.loaded then create_class(mclass) - - return mclass - end # Initialize the internal representation of an object (its attribute values) # `init_instance` is the initial value of attributes