The type error was detected by nitg in complex cases.
hfile.write "#include \"{hfilename}\"\n"
for key in f.required_declarations do
if not compiler.provided_declarations.has_key(key) then
- print "No provided declaration for {key}"
+ var node = compiler.requirers_of_declarations.get_or_null(key)
+ if node != null then
+ node.debug "No provided declaration for {key}"
+ else
+ print "No provided declaration for {key}"
+ end
abort
end
hfile.write compiler.provided_declarations[key]
private var provided_declarations = new HashMap[String, String]
+ private var requirers_of_declarations = new HashMap[String, ANode]
+
# Builds the .c and .h files to be used when generating a Stack Trace
# Binds the generated C function names to Nit function names
fun build_c_to_nit_bindings
# Request the presence of a global declaration
fun require_declaration(key: String)
do
- self.writer.file.required_declarations.add(key)
+ var reqs = self.writer.file.required_declarations
+ if reqs.has(key) then return
+ reqs.add(key)
+ var node = current_node
+ if node != null then compiler.requirers_of_declarations[key] = node
end
# Add a declaration in the local-header
end
# stantard call-next-method
- return v.supercall(v.frame.mpropdef.as(MMethodDef), recv.mtype.as(MClassType), args)
+ return v.supercall(mpropdef.as(not null), recv.mtype.as(MClassType), args)
end
end
# provides tools to write C .c and .h files
module c_tools
-import compiling_writer
+import template
# Accumulates all C code for a compilation unit
class CCompilationUnit
## header
# comments and native interface imports
- var header_c_base : Writer = new Writer
+ var header_c_base = new Template
# custom C header code or generated for other languages
- var header_custom : Writer = new Writer
+ var header_custom = new Template
# types of extern classes and friendly types
- var header_c_types : Writer = new Writer
+ var header_c_types = new Template
# implementation declaration for extern methods
- var header_decl : Writer = new Writer
+ var header_decl = new Template
## body
# comments, imports, etc
- var body_decl : Writer = new Writer
+ var body_decl = new Template
# custom code and generated for ffi
- var body_custom : Writer = new Writer
+ var body_custom = new Template
# implementation body of extern methods
- var body_impl : Writer = new Writer
+ var body_impl = new Template
# files to compile TODO check is appropriate
var files = new Array[String]
do
body_decl.add( "{efc.signature};\n" )
body_impl.add( "\n" )
- body_impl.append( efc.to_writer )
+ body_impl.add( efc.to_writer )
end
fun add_exported_function( efc : CFunction )
do
header_decl.add( "{efc.signature};\n" )
body_impl.add( "\n" )
- body_impl.append( efc.to_writer )
+ body_impl.add( efc.to_writer )
end
fun compile_header_core( stream : OStream )
do
- header_c_base.write_to_stream( stream )
- header_custom.write_to_stream( stream )
- header_c_types.write_to_stream( stream )
- header_decl.write_to_stream( stream )
+ header_c_base.write_to( stream )
+ header_custom.write_to( stream )
+ header_c_types.write_to( stream )
+ header_decl.write_to( stream )
end
fun compile_body_core( stream : OStream )
do
- body_decl.write_to_stream( stream )
- body_custom.write_to_stream( stream )
- body_impl.write_to_stream( stream )
+ body_decl.write_to( stream )
+ body_custom.write_to( stream )
+ body_impl.write_to( stream )
end
end
class CFunction
var signature : String
- var decls : Writer = new Writer
- var exprs : Writer = new Writer
+ var decls = new Template
+ var exprs = new Template
- fun to_writer : Writer
+ fun to_writer: Template
do
- var w = new Writer
-
- w.add( "{signature}\n\{\n" )
-
- w.append( decls )
- w.add( "\n" )
- w.append( exprs )
-
- w.add( "\}\n" )
+ var w = new Template
+
+ w.add(signature)
+ w.add("\n\{\n")
+ w.add(decls)
+ w.add("\n")
+ w.add(exprs)
+ w.add("\}\n")
return w
end
+++ /dev/null
-# 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.
-
-# Collect super sends
-module collect_super_sends
-
-import modelbuilder
-private import modelize_property
-private import typing
-
-private class CollectSuperSends
- super Visitor
- var modelbuilder: ModelBuilder
- var res = new ArraySet[MMethodDef]
- var mpropdef: nullable MMethodDef
-
- # Get a new visitor on a classef to add type count in `typecount`.
- init(modelbuilder: ModelBuilder)
- do
- self.modelbuilder = modelbuilder
- end
-
- redef fun visit(n)
- do
- if n isa AMethPropdef then
- assert mpropdef == null
- mpropdef = n.mpropdef
- n.visit_all(self)
- mpropdef = null
- return
- end
- n.visit_all(self)
- if (n isa ASuperExpr and n.callsite == null) or n isa ASuperExternCall then
- var mprop = mpropdef
- assert mprop != null
- res.add(mprop)
- end
- end
-end
-
-redef class ModelBuilder
- # Visit the AST and return all method definitions that performs a `super`.
- fun collect_super_sends: Set[MMethodDef]
- do
- var visitor = new CollectSuperSends(self)
-
- # Visit all the source code to collect data
- for nmodule in self.nmodules do
- visitor.enter_visit(nmodule)
- end
-
- return visitor.res
- end
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2010 Jean Privat <jean@pryen.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.
-
-# Helps to generate complex strings.
-# Can be used to simplify complex file generation where text addition is not only done at the end
-module compiling_writer
-
-# A writer is used to store a sequence of strings and sub-writers
-class Writer
- # Add a new string at the end of the writer
- fun add(s: String): Writer
- do
- assert not is_frozen
- var c = _last_string
- var c2 = new WriterStrings(s)
- if c == null then
- internal_append(c2)
- else
- c._next = c2
- end
- _last_string = c2
- return self
- end
-
- # Add each string of the array but separate them
- fun add_all(a: Array[String], separator: String): Writer
- do
- assert not is_frozen
- var first = true
- for s in a do
- if first then first = false else add(separator)
- add(s)
- end
- return self
- end
-
- var _first_sub_writer: nullable WriterNode = null
- var _last_sub_writer: nullable WriterNode = null
-
- # Last string added. Implies that _last_sub_writer isa WriterStrings
- var _last_string: nullable WriterStrings = null
-
- # Insert an other Writer at the end of the writer
- fun append(c: Writer): Writer
- do
- assert not is_frozen
- internal_append(new WriterCoreNode(c))
- _last_string = null # next add will create a new WriterStrings after c
- return self
- end
-
- # Insert a writer as a sub-one
- private fun internal_append(c: WriterNode)
- do
- if _first_sub_writer == null then _first_sub_writer = c
- var l = _last_sub_writer
- if l != null then l._next_writer = c
- _last_sub_writer = c
- end
-
- # Create a sub-writer that can be used as a new string insertion point
- fun sub: Writer
- do
- var c = new Writer
- append(c)
- return c
- end
-
- var _is_writing: Bool = false
-
- # Write all strings (including nested ones) to a stream
- fun write_to_stream(s: OStream)
- do
- assert not _is_writing
- _is_writing = true
- var cur = _first_sub_writer
- while cur != null do
- cur.internal_write_to_stream(s)
- cur = cur._next_writer
- end
- _is_writing = false
- end
-
- # Return true if the string writer is frozen
- readable var _is_frozen: Bool = false
-
- # Disable further writer modification: nor add or append are allowed
- fun freeze
- do
- if is_frozen then return
- _is_frozen = true
- end
-
- init do end
-end
-
-# Simple linked list of Writers contents
-private abstract class WriterNode
- # The next writer in the list
- var _next_writer: nullable WriterNode = null
-
- # Write all strings (including nested ones) to a stream
- fun internal_write_to_stream(s: OStream) is abstract
-end
-
-# A writer node that contains a full writer
-private class WriterCoreNode
- super WriterNode
- var _writer: Writer
-
- redef fun internal_write_to_stream(s) do _writer.write_to_stream(s)
-
- init(w: Writer) do _writer = w
-end
-
-# A simple writer node that contains only strings
-private class WriterStrings
- super WriterNode
- # The first string
- var _string: String
-
- # The next strings
- var _next: nullable WriterStrings = null
-
- init(s: String)
- do
- _string = s
- end
-
- redef fun internal_write_to_stream(s)
- do
- var cur: nullable WriterStrings = self
- while cur != null do
- s.write(cur._string)
- cur = cur._next
- end
- end
-end
-
private var propdef_names = new HashSet[String]
end
+redef class MPropDef
+ # Does the MPropDef contains a call to super or a call of a super-constructor?
+ # Subsequent phases of the frontend (esp. typing) set it if required
+ var has_supercall: Bool writable = false
+end
+
redef class AClassdef
var build_properties_is_done: Bool = false
# The list of super-constructor to call at the start of the free constructor
return v.char_instance(recv.succ)
else if pname == "prec" then
return v.char_instance(recv.prec)
+ else if pname == "+" then
+ return v.char_instance(recv + args[1].to_i)
+ else if pname == "-" then
+ return v.char_instance(recv - args[1].to_i)
else if pname == "<" then
return v.bool_instance(recv < args[1].val.as(Char))
else if pname == ">" then
return v.float_instance(args[0].to_f.pow(args[1].to_f))
else if pname == "rand" then
return v.float_instance(args[0].to_f.rand)
+ else if pname == "abs" then
+ return v.float_instance(args[0].to_f.abs)
+ else if pname == "hypot_with" then
+ return v.float_instance(args[0].to_f.hypot_with(args[1].to_f))
+ else if pname == "is_nan" then
+ return v.bool_instance(args[0].to_f.is_nan)
+ else if pname == "is_inf_extern" then
+ return v.bool_instance(args[0].to_f.is_inf != 0)
end
else if pname == "native_argc" then
return v.int_instance(v.arguments.length)
end
# stantard call-next-method
- var mpropdef = v.frame.mpropdef
+ var mpropdef = self.mpropdef
mpropdef = mpropdef.lookup_next_definition(v.mainmodule, recv.mtype)
- assert mpropdef isa MMethodDef
var res = v.call_without_varargs(mpropdef, args)
return res
end
do
callback_set.supers.add( new MExplicitSuper( npropdef.mpropdef.as(not null) ) )
callback_set.types.add( npropdef.mpropdef.mclassdef.mclass.mclass_type )
+ npropdef.mpropdef.has_supercall = true
end
end
return
end
- v.analysis.add_super_send(v.receiver, v.mpropdef.as(MMethodDef))
+ v.analysis.add_super_send(v.receiver, mpropdef.as(not null))
end
end
import abstract_compiler
import layout_builders
import rapid_type_analysis
-import collect_super_sends
import compiler_ffi
# Add separate compiler specific options
end
end
+ # Collect all super calls (dead or not)
+ var all_super_calls = new HashSet[MMethodDef]
+ for mmodule in self.mainmodule.in_importation.greaters do
+ for mclassdef in mmodule.mclassdefs do
+ for mpropdef in mclassdef.mpropdefs do
+ if not mpropdef isa MMethodDef then continue
+ if mpropdef.has_supercall then
+ all_super_calls.add(mpropdef)
+ end
+ end
+ end
+ end
+
# lookup super calls and add it to the list of mmethods to build layout with
var super_calls
if runtime_type_analysis != null then
super_calls = runtime_type_analysis.live_super_sends
else
- super_calls = modelbuilder.collect_super_sends
+ super_calls = all_super_calls
end
+
for mmethoddef in super_calls do
var mclass = mmethoddef.mclassdef.mclass
mmethods[mclass].add(mmethoddef)
self.compile_color_consts(method_layout.pos)
# attribute null color to dead supercalls
- for mmodule in self.mainmodule.in_importation.greaters do
- for mclassdef in mmodule.mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef.has_supercall then
- compile_color_const(new_visitor, mpropdef, -1)
- end
- end
- end
+ for mpropdef in all_super_calls do
+ if super_calls.has(mpropdef) then continue
+ compile_color_const(new_visitor, mpropdef, -1)
end
# attributes coloration
var typing_phase: Phase = new TypingPhase(self, [flow_phase, modelize_property_phase, local_var_init_phase])
end
-redef class MPropDef
- # Does the MPropDef contains a call to super or a call of a super-constructor?
- var has_supercall: Bool = false
-end
-
private class TypingPhase
super Phase
redef fun process_npropdef(npropdef) do npropdef.do_typing(toolcontext.modelbuilder)
# Note: if the super is a normal call-next-method, then this attribute is null
var callsite: nullable CallSite
+ # The method to call is the super is a standard `call-next-method` super-call
+ # Note: if the super is a special super-init-call, then this attribute is null
+ var mpropdef: nullable MMethodDef
+
redef fun accept_typing(v)
do
var recvtype = v.nclassdef.mclassdef.bound_mtype
self.mtype = msignature.return_mtype
self.is_typed = true
v.mpropdef.has_supercall = true
+ mpropdef = v.mpropdef.as(MMethodDef)
end
private fun process_superinit(v: TypeVisitor)
-closure
init_inherit
init_linext
inline
-test_extern
-nitc
test_json
-closure
init_inherit
init_linext
inline
-test_extern
-nitc
nitg
test_json
-closure
init_inherit
init_linext
inline
-test_extern
-nitc
test_json
-closure
init_inherit
init_linext
inline
#include "test_extern_nit.h"
-long int foo(Object s) { return 10; }
-long int bar(Object s, long int i) { return i*2; }
-Object baz(Object s, Object a) { return a; }
+long int foo(void *s) { return 10; }
+long int bar(void *s, long int i) { return i*2; }
+void *baz(void *s, void *a) { return a; }
-#include <test_extern._nitni.h>
-long int foo(Object);
-long int bar(Object, long int);
-Object baz(Object, Object);
+long int foo(void *);
+long int bar(void *, long int);
+void *baz(void *, void *);
remains="$remains $OLD"
else
echo "[fixme] out/$pattern.res $FIXME"
+ echo >>$xml "<skipped/>"
fi
todos="$todos $pattern"
elif [ -n "$SOSO" ]; then
echo "not ok - $description # TODO not yet implemented"
else
echo "[todo] out/$pattern.res -> not yet implemented"
+ echo >>$xml "<skipped/>"
fi
todos="$todos $pattern"
elif [ -n "$SOSOF" ]; then
echo "not ok - $description # TODO SOSO expected failure"
else
echo "[fixme soso] out/$pattern.res $SOSOF"
+ echo >>$xml "<skipped/>"
fi
todos="$todos $pattern"
elif [ -n "$NSAV" ]; then
# Sould we skip the input for this engine?
need_skip $bff " $name" $pack && continue
+ # use a specific inputs file, if required
+ if [ -f "$bff.inputs" ]; then
+ ffinputs="$bff.inputs"
+ else
+ ffinputs=$inputs
+ fi
+
rm -rf "$fff.res" "$fff.err" "$fff.write" 2> /dev/null
if [ "x$verbose" = "xtrue" ]; then
echo ""
test -z "$tap" && echo -n "==> $name "
echo "./$ff.bin $args" > "./$fff.bin"
chmod +x "./$fff.bin"
- WRITE="$fff.write" sh -c "NIT_NO_STACK=1 $TIMEOUT ./$fff.bin < $inputs > $fff.res 2>$fff.err"
+ WRITE="$fff.write" sh -c "NIT_NO_STACK=1 $TIMEOUT ./$fff.bin < $ffinputs > $fff.res 2>$fff.err"
if [ "x$verbose" = "xtrue" ]; then
cat "$fff.res"
cat >&2 "$fff.err"