import abstract_compiler
import rapid_type_analysis
-import compiler_ffi
+
+redef class ToolContext
+ # option --global
+ var opt_global = new OptionBool("Use global compilation", "--global")
+
+ var global_compiler_phase = new GlobalCompilerPhase(self, null)
+
+ redef init do
+ super
+ option_context.add_option(opt_global)
+ end
+end
+
+class GlobalCompilerPhase
+ super Phase
+ redef fun process_mainmodule(mainmodule, given_mmodules) do
+ if not toolcontext.opt_global.value then return
+
+ var modelbuilder = toolcontext.modelbuilder
+ var analysis = modelbuilder.do_rapid_type_analysis(mainmodule)
+ modelbuilder.run_global_compiler(mainmodule, analysis)
+ end
+end
redef class ModelBuilder
# Entry point to performs a global compilation on the AST of a complete program.
# Compile class names (for the class_name and output_class_name methods)
protected fun compile_class_names do
var v = new_visitor
- self.header.add_decl("extern const char const * class_names[];")
- v.add("const char const * class_names[] = \{")
+ self.header.add_decl("extern const char *class_names[];")
+ v.add("const char *class_names[] = \{")
for t in self.runtime_type_analysis.live_types do
v.add("\"{t}\", /* {self.classid(t)} */")
end
if mtype.mclass.name == "NativeArray" then
# NativeArrays are just a instance header followed by an array of values
+ v.add_decl("int length;")
v.add_decl("{mtype.arguments.first.ctype} values[1];")
end
if is_native_array then
var mtype_elt = mtype.arguments.first
v.add("{res} = nit_alloc(sizeof(struct {mtype.c_name}) + length*sizeof({mtype_elt.ctype}));")
+ v.add("((struct {mtype.c_name}*){res})->length = length;")
else
v.add("{res} = nit_alloc(sizeof(struct {mtype.c_name}));")
end
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("printf(\"Dead code executed!\\n\"); show_backtrace(1);")
+ self.add("PRINT_ERROR(\"Dead code executed!\\n\"); show_backtrace(1);")
return res
end
self.add("{res} = BOX_{valtype.c_name}({value}); /* autobox from {value.mtype} to {mtype} */")
return res
- else if value.mtype.cname_blind == "void*" and mtype.cname_blind == "void*" then
+ else if value.mtype.ctype == "void*" and mtype.ctype == "void*" then
return value
else
# Bad things will appen!
var res = self.new_var(mtype)
self.add("/* {res} left unintialized (cannot convert {value.mtype} to {mtype}) */")
- self.add("printf(\"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}\"); show_backtrace(1);")
return res
end
end
else if pname == "[]=" then
self.add("{recv}[{arguments[1]}]={arguments[2]};")
return
+ else if pname == "length" then
+ self.ret(self.new_expr("((struct {arguments[0].mcasttype.c_name}*){arguments[0]})->length", ret_type.as(not null)))
+ return
else if pname == "copy_to" then
var recv1 = "((struct {arguments[1].mcasttype.c_name}*){arguments[1]})->values"
self.add("memcpy({recv1},{recv},{arguments[2]}*sizeof({elttype.ctype}));")
end
end
+ redef fun native_array_instance(elttype: MType, length: RuntimeVariable): RuntimeVariable
+ do
+ var ret_type = self.get_class("NativeArray").get_mtype([elttype])
+ return self.new_expr("NEW_{ret_type.c_name}({length})", ret_type)
+ end
+
redef fun calloc_array(ret_type, arguments)
do
self.ret(self.new_expr("NEW_{ret_type.c_name}({arguments[1]})", ret_type))
fun bugtype(recv: RuntimeVariable)
do
if recv.mtype.ctype != "val*" then return
- self.add("fprintf(stderr, \"BTD BUG: Dynamic type is %s, static type is %s\\n\", class_names[{recv}->classid], \"{recv.mcasttype}\");")
+ 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);")
end
redef fun type_test(value, mtype, tag)
do
mtype = self.anchor(mtype)
- var mclasstype = mtype
- if mtype isa MNullableType then mclasstype = mtype.mtype
- assert mclasstype isa MClassType
- if not self.compiler.runtime_type_analysis.live_cast_types.has(mclasstype) then
+ if not self.compiler.runtime_type_analysis.live_cast_types.has(mtype) then
debug "problem: {mtype} was detected cast-dead"
abort
end
var frame = new Frame(v, mmethoddef, recv, arguments)
v.frame = frame
- var sig = new Buffer
- var comment = new Buffer
+ var sig = new FlatBuffer
+ var comment = new FlatBuffer
var ret = mmethoddef.msignature.return_mtype
if ret != null then
ret = v.resolve_for(ret, selfvar)