A prossible call from C, declared explictly after the import keyword

Introduced properties

private var _recv_mtype: MClassType

nitc :: MExplicitCall :: _recv_mtype

Previously resolved mtype
fun csignature: String

nitc :: MExplicitCall :: csignature

Signature of this call in C as seen by user
init defaultinit(recv_mtype: MClassType, mproperty: MProperty, from_mmodule: MModule)

nitc :: MExplicitCall :: defaultinit

protected fun from_mmodule=(from_mmodule: MModule)

nitc :: MExplicitCall :: from_mmodule=

protected fun mproperty=(mproperty: MProperty)

nitc :: MExplicitCall :: mproperty=

fun recv_mtype: MClassType

nitc :: MExplicitCall :: recv_mtype

Previously resolved mtype
protected fun recv_mtype=(recv_mtype: MClassType)

nitc :: MExplicitCall :: recv_mtype=

Previously resolved mtype

Redefined properties

redef fun ==(o: nullable Object): Bool

nitc $ MExplicitCall :: ==

Have self and other the same value?
redef type SELF: MExplicitCall

nitc $ MExplicitCall :: SELF

Type of this instance, automatically specialized in every class
redef fun compile_callback_to_java(mmodule: MModule, mainmodule: MModule, ccu: CCompilationUnit)

nitc :: java $ MExplicitCall :: compile_callback_to_java

Compile C and Java code to implement this callback
redef fun compile_callback_to_objc(mmodule: MModule, mainmodule: MModule)

nitc :: objc $ MExplicitCall :: compile_callback_to_objc

Compile this callback to be callable from Objective-C
redef fun hash: Int

nitc $ MExplicitCall :: hash

The hash code of the object.
redef fun jni_methods_declaration(from_mmodule: MModule): Array[String]

nitc :: java $ MExplicitCall :: jni_methods_declaration

Returns the list of C functions to link with extern Java methods, as required

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
private var _recv_mtype: MClassType

nitc :: MExplicitCall :: _recv_mtype

Previously resolved mtype
protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
fun compile_callback_to_java(mmodule: MModule, mainmodule: MModule, ccu: CCompilationUnit)

nitc :: NitniCallback :: compile_callback_to_java

Compile C and Java code to implement this callback
fun compile_callback_to_objc(mmodule: MModule, mainmodule: MModule)

nitc :: NitniCallback :: compile_callback_to_objc

Compile this callback to be callable from Objective-C
fun csignature: String

nitc :: MExplicitCall :: csignature

Signature of this call in C as seen by user
init defaultinit(recv_mtype: MClassType, mproperty: MProperty, from_mmodule: MModule)

nitc :: MExplicitCall :: defaultinit

protected fun from_mmodule=(from_mmodule: MModule)

nitc :: MExplicitCall :: from_mmodule=

fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
fun hash: Int

core :: Object :: hash

The hash code of the object.
init init

core :: Object :: init

fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
fun jni_methods_declaration(from_module: MModule): Array[String]

nitc :: NitniCallback :: jni_methods_declaration

Returns the list of C functions to link with extern Java methods, as required
protected fun mproperty=(mproperty: MProperty)

nitc :: MExplicitCall :: mproperty=

private intern fun native_class_name: CString

core :: Object :: native_class_name

The class name of the object in CString format.
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
fun recv_mtype: MClassType

nitc :: MExplicitCall :: recv_mtype

Previously resolved mtype
protected fun recv_mtype=(recv_mtype: MClassType)

nitc :: MExplicitCall :: recv_mtype=

Previously resolved mtype
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
package_diagram nitc::MExplicitCall MExplicitCall nitc::NitniCallback NitniCallback nitc::MExplicitCall->nitc::NitniCallback core::Object Object nitc::NitniCallback->core::Object ...core::Object ... ...core::Object->core::Object

Ancestors

interface Object

core :: Object

The root of the class hierarchy.

Parents

interface NitniCallback

nitc :: NitniCallback

Classification for all nitni callbacks

Class definitions

nitc $ MExplicitCall
# A prossible call from C, declared explictly after the `import` keyword
class MExplicitCall
	super NitniCallback

	# Previously resolved mtype
	var recv_mtype: MClassType
	var mproperty: MProperty
	var from_mmodule: MModule

	fun fill_type_for( callback_set: ForeignCallbackSet, from: MModule )
	do
		var first = mproperty.lookup_first_definition( from, recv_mtype )
		var mclassdef = first.mclassdef
		var bound_mtype = mclassdef.bound_mtype

		# receiver / constructor return
		recv_mtype = recv_mtype.resolve_for(bound_mtype, bound_mtype, from, true)
		recv_mtype = recv_mtype.anchor_to(from, bound_mtype)
		callback_set.types.add( recv_mtype )

		if first isa MMethodDef then
			var rmt = first.msignature.return_mtype
			if rmt != null then
				rmt = rmt.resolve_for(bound_mtype, bound_mtype, from, true)
				rmt = rmt.anchor_to(from, bound_mtype)
				callback_set.types.add( rmt )
			end

			for p in first.msignature.mparameters do
				var param_mtype = p.mtype.resolve_for(recv_mtype, recv_mtype, from, true)
				param_mtype = param_mtype.resolve_for(bound_mtype, bound_mtype, from, true)
				param_mtype = param_mtype.anchor_to(from, bound_mtype)
				callback_set.types.add( param_mtype )
			end
		end
	end

	# Signature of this call in C as seen by user
	fun csignature: String
	do
		var mproperty = self.mproperty
		if mproperty isa MMethod then
			var signature = mproperty.intro.msignature
			assert signature != null

			var creturn_type
			if mproperty.is_init then
				creturn_type = recv_mtype.cname
			else if signature.return_mtype != null then
				var ret_mtype = signature.return_mtype
				ret_mtype = ret_mtype.resolve_for(recv_mtype, recv_mtype, from_mmodule, true)
				creturn_type = ret_mtype.cname
			else
				creturn_type = "void"
			end

			var cname
			if mproperty.is_init then
				if mproperty.name == "init" or mproperty.name == "new" or mproperty.name == "defaultinit" then
					cname = "new_{recv_mtype.mangled_cname}"
				else
					cname = "new_{recv_mtype.mangled_cname}_{mproperty.short_cname}"
				end
			else
				cname = "{recv_mtype.mangled_cname}_{mproperty.short_cname}"
			end

			var cparams = new List[String]
			if not mproperty.is_init then
				cparams.add( "{recv_mtype.cname} self" )
			end
			for p in signature.mparameters do
				var param_mtype = p.mtype.resolve_for(recv_mtype, recv_mtype, from_mmodule, true)
				cparams.add( "{param_mtype.cname} {p.name}" )
			end

			return "{creturn_type} {cname}( {cparams.join(", ")} )"
		else
			print "Type of callback from foreign code not yet supported."
			abort
		end
	end

	redef fun hash do return recv_mtype.hash + 1024 * mproperty.hash
	redef fun ==(o) do return o isa MExplicitCall and recv_mtype == o.recv_mtype and mproperty == o.mproperty
end
src/nitni/nitni_callbacks.nit:164,1--249,3

nitc :: c $ MExplicitCall
redef class MExplicitCall
	redef fun compile_callback_to_c(mmodule, ffi_ccu)
	do
		var mproperty = mproperty.as(MMethod)

		var full_cname = mproperty.build_cname(recv_mtype, mmodule, null, long_signature)
		var friendly_cname = mproperty.build_cname(recv_mtype, mmodule, null, short_signature)
		ffi_ccu.body_decl.add("#define {friendly_cname} {full_cname}\n")
	end
end
src/ffi/c.nit:34,1--43,3

nitc :: compiler_ffi $ MExplicitCall
redef class MExplicitCall
	private fun compile_extern_callback(v: AbstractCompilerVisitor, ccu: CCompilationUnit, compile_implementation_too: Bool)
	do
		var mproperty = mproperty
		assert mproperty isa MMethod

		# In nitni files, declare internal function as extern
		var full_friendly_csignature = mproperty.build_csignature(recv_mtype, v.compiler.mainmodule, null, long_signature, internal_call_context)
		ccu.header_decl.add("extern {full_friendly_csignature};\n")

		if not compile_implementation_too then return

		# Internally, implement internal function
		var nitni_visitor = v.compiler.new_visitor
		nitni_visitor.frame = v.frame
		var msignature = mproperty.lookup_first_definition(v.compiler.mainmodule, recv_mtype).msignature
		var csignature_blind = mproperty.build_csignature(recv_mtype, v.compiler.mainmodule, null, long_signature, internal_call_context)

		nitni_visitor.add_decl("/* nitni callback for {mproperty.full_name} */")
		nitni_visitor.add_decl("{csignature_blind} \{")

		var vars = new Array[RuntimeVariable]
		var mtype: MType = recv_mtype
		var recv_var = null
		if mproperty.is_init then
			var recv_mtype = recv_mtype
			recv_var = nitni_visitor.init_instance_or_extern(recv_mtype)
			nitni_visitor.add("{mtype.ctype} self /* var self: {mtype} */;")
			nitni_visitor.add("self = {recv_var};")
		else
			mtype = mtype.anchor_to(v.compiler.mainmodule, recv_mtype)
			recv_var = nitni_visitor.var_from_c("self", mtype)
			recv_var = nitni_visitor.box_extern(recv_var, mtype)
		end

		vars.add(recv_var)

		for p in msignature.mparameters do
			var arg_mtype = p.mtype.anchor_to(v.compiler.mainmodule, recv_mtype)
			var arg = nitni_visitor.var_from_c(p.name, arg_mtype)
			arg = nitni_visitor.box_extern(arg, arg_mtype)
			vars.add(arg)
		end

		var ret_var = nitni_visitor.send(mproperty, vars)

		var return_mtype = msignature.return_mtype
		if mproperty.is_init then
			if recv_mtype.mclass.kind != extern_kind then ret_var = recv_var
			return_mtype = recv_mtype
		end
		if return_mtype != null then
			assert ret_var != null
			return_mtype = return_mtype.anchor_to(v.compiler.mainmodule, recv_mtype)
			ret_var = nitni_visitor.autobox(ret_var, return_mtype)
			ret_var = nitni_visitor.unbox_extern(ret_var, return_mtype)
			nitni_visitor.ret_to_c(ret_var, return_mtype)
		end
		nitni_visitor.add("\}")
	end
end
src/compiler/compiler_ffi/compiler_ffi.nit:83,1--143,3

nitc :: cpp $ MExplicitCall
redef class MExplicitCall
	redef fun compile_callback_to_cpp(mmodule, mainmodule)
	do
		var mproperty = mproperty
		assert mproperty isa MMethod

		var cpp_signature = mproperty.build_csignature(recv_mtype, mainmodule, null, short_signature, from_cpp_call_context)
		var ccall = mproperty.build_ccall(recv_mtype, mainmodule, null, long_signature, from_cpp_call_context, null)
		var fc = new CFunction(cpp_signature)
		fc.exprs.add(ccall)
		mmodule.cpp_file.add_local_function( fc )
	end
end
src/ffi/cpp.nit:202,1--214,3

nitc :: objc $ MExplicitCall
redef class MExplicitCall
	redef fun compile_callback_to_objc(mmodule, mainmodule)
	do
		var mproperty = mproperty
		assert mproperty isa MMethod

		var objc_signature = mproperty.build_csignature(recv_mtype, mainmodule, null, short_signature, from_objc_call_context)
		var ccall = mproperty.build_ccall(recv_mtype, mainmodule, null, long_signature, from_objc_call_context, null)
		var fc = new CFunction(objc_signature)
		fc.exprs.add ccall
		mmodule.objc_file.add_local_function fc
	end
end
src/ffi/objc.nit:190,1--202,3

nitc :: java $ MExplicitCall
redef class MExplicitCall
	redef fun compile_callback_to_java(mmodule, mainmodule, ccu)
	do
		if not mmodule.callbacks_used_from_java.callbacks.has(self) then return

		var mproperty = mproperty
		assert mproperty isa MMethod

		# In C, indirection implementing the Java extern methods
		var csignature = mproperty.build_c_implementation_signature(recv_mtype, mmodule, "___indirect", long_signature, from_java_call_context)
		var cf = new CFunction("JNIEXPORT {csignature}")
		cf.exprs.add "\t{mproperty.build_ccall(recv_mtype, mainmodule, null, long_signature, from_java_call_context, null)}\n"
		ccu.add_non_static_local_function cf

		# In Java, declare the extern method as a private static local method
		var java_signature = mproperty.build_csignature(recv_mtype, mainmodule, null, short_signature, java_call_context)
		mmodule.java_file.class_content.add "private native static {java_signature};\n"
	end

	redef fun jni_methods_declaration(from_mmodule)
	do
		var mproperty = mproperty
		assert mproperty isa MMethod

		var java_name = mproperty.build_cname(recv_mtype, from_mmodule, null, short_signature)
		var jni_format = mproperty.build_jni_format(recv_mtype, from_mmodule)
		var c_name = mproperty.build_cname(recv_mtype, from_mmodule, "___indirect", long_signature)

		return ["""{"{{{java_name}}}", "{{{jni_format}}}", {{{c_name}}}}"""]
	end
end
src/ffi/java.nit:513,1--543,3