Difference between revisions of "Reattachment"

m (Added an initial version with the description of implementation on classic)
 
m (Unification of feature signature: Added an example to demonstrate that feature signature may not be known in advance)
 
(3 intermediate revisions by 2 users not shown)
Line 6: Line 6:
 
All features in a generic derivation with an expanded parameter that involve this generic parameter should be able to handle the case when they are called on a target where this generic parameter is reference, i.e. they should be able to take reference arguments and return reference result.
 
All features in a generic derivation with an expanded parameter that involve this generic parameter should be able to handle the case when they are called on a target where this generic parameter is reference, i.e. they should be able to take reference arguments and return reference result.
 
== Reattachment of generic derivations in classic ==
 
== Reattachment of generic derivations in classic ==
# In addition to the "normal" version of the method generated for a particular feature, a new stub can be generated so that its arguments/result types match those of the generic derivation with reference generic parameters. In order to avoid additional pressure on garbage collector, the values passed to/from the generated methods can be embedded in an EIF_UNION structure that allows to pass objects of basic and reference types "as is", while objects of user-defined expanded type still need to be "boxed" and kept in the heap.
+
=== Dynamic dispatch ===
# The feature <e>{ROUT_TABLE}.is_polymorphic</e> has to be modified so that it allows for different generic derivatins to share the same table, because now it becomes possible to reattach generic derivations with expanded parameters to the generic derivations with reference parameters. Though not all the reattachments are possible (e.g., no reattachment is possible between the types <e>ARRAY [INTEGER]</e> and <e>ARRAY [BOOLEAN]</e>), it's too complicated and/or resource consuming to create the tables for every generic derivation and types that conform to it.
+
The feature <e>{ROUT_TABLE}.is_polymorphic</e> has to be modified so that it allows for different generic derivations to share the same table, because now it becomes possible to reattach generic derivations with expanded parameters to the generic derivations with reference parameters. Though not all the reattachments are possible (e.g., no reattachment is possible between the types <e>ARRAY [INTEGER]</e> and <e>ARRAY [BOOLEAN]</e>), it's too complicated and/or resource consuming to create the tables for every generic derivation and types that conform to it.
# Attributes that are declared of a formal generic type (or as of type, anchored to a feature of a formal generic type) have to be accessed as functions so that they can be safely access from the generic derivations with reference parameters. This involves two changes in code generation:
+
=== Unification of feature signature ===
## Promotion of <e>ATTRIBUTE_B</e> to <e>FEATURE_B</e> if an attribute type is (directly or indirectly) a formal generic.
+
In addition to the "normal" version of the method generated for a particular feature, a new stub can be generated so that its arguments/result types match those of the generic derivation with reference generic parameters. In order to avoid additional pressure on garbage collector, the values passed to/from the generated methods can be embedded in an <c>EIF_UNION</c> structure that allows to pass objects of basic and reference types "as is", while objects of user-defined expanded type still need to be "boxed" and kept in the heap.
## Generation of an accessor for the attribute by setting the field <e>generated_in</e>.
+
 
 +
Unfortunately, this cannot be done in advance due to multiple inheritance and feature merging. This way a feature that has nothing to do with formal generic parameters could be called through this formal-generic capable interface. Consider the following example:
 +
<e>
 +
class A feature
 +
f (x: INTEGER) is do ... end
 +
end
 +
 
 +
class B [G] feature
 +
f (x: G) is do ... end
 +
end
 +
 
 +
class C inherit
 +
A
 +
B [INTEGER]
 +
undefine
 +
f
 +
end
 +
end
 +
</e>
 +
When generating the code for the feature <e>{A}.f</e>, there is no knowledge that it will be called with a polymorphic argument of type <c>EIF_UNION</c> (even if we avoid optimization and "box" expanded arguments instead of using <c>EIF_UNION</c>, the argument type <c>EIF_REFERENCE</c> will be different from the expected <c>EIF_INTEGER</c>).
 +
 
 +
=== Access to attributes ===
 +
Attributes that are declared of a formal generic type (or as of type, anchored to a feature of a formal generic type) have to be accessed as functions so that they can be safely accessed from the generic derivations with reference parameters. This involves two changes in code generation:
 +
# Promotion of <e>ATTRIBUTE_B</e> to <e>FEATURE_B</e> if an attribute type is (directly or indirectly) a formal generic.
 +
# Generation of an accessor for the attribute by setting the field <e>generated_in</e>.

Latest revision as of 06:54, 30 March 2007

See also: Object_Layout, Dynamic_Binding

Introduction

Conformance of expanded types to (particular) reference types implies that objects of generically derived types with expanded parameters can be attached to generically derived types with reference parameters (e.g., ARRAY [INTEGER] can be attached to ARRAY [ANY]). All features in a generic derivation with an expanded parameter that involve this generic parameter should be able to handle the case when they are called on a target where this generic parameter is reference, i.e. they should be able to take reference arguments and return reference result.

Reattachment of generic derivations in classic

Dynamic dispatch

The feature {ROUT_TABLE}.is_polymorphic has to be modified so that it allows for different generic derivations to share the same table, because now it becomes possible to reattach generic derivations with expanded parameters to the generic derivations with reference parameters. Though not all the reattachments are possible (e.g., no reattachment is possible between the types ARRAY [INTEGER] and ARRAY [BOOLEAN]), it's too complicated and/or resource consuming to create the tables for every generic derivation and types that conform to it.

Unification of feature signature

In addition to the "normal" version of the method generated for a particular feature, a new stub can be generated so that its arguments/result types match those of the generic derivation with reference generic parameters. In order to avoid additional pressure on garbage collector, the values passed to/from the generated methods can be embedded in an EIF_UNION structure that allows to pass objects of basic and reference types "as is", while objects of user-defined expanded type still need to be "boxed" and kept in the heap.

Unfortunately, this cannot be done in advance due to multiple inheritance and feature merging. This way a feature that has nothing to do with formal generic parameters could be called through this formal-generic capable interface. Consider the following example:

class A feature
	f (x: INTEGER) is do ... end
end
 
class B [G] feature
	f (x: G) is do ... end
end
 
class C inherit
	A
	B [INTEGER]
		undefine
			f
		end
end

When generating the code for the feature {A}.f, there is no knowledge that it will be called with a polymorphic argument of type EIF_UNION (even if we avoid optimization and "box" expanded arguments instead of using EIF_UNION, the argument type EIF_REFERENCE will be different from the expected EIF_INTEGER).

Access to attributes

Attributes that are declared of a formal generic type (or as of type, anchored to a feature of a formal generic type) have to be accessed as functions so that they can be safely accessed from the generic derivations with reference parameters. This involves two changes in code generation:

  1. Promotion of ATTRIBUTE_B to FEATURE_B if an attribute type is (directly or indirectly) a formal generic.
  2. Generation of an accessor for the attribute by setting the field generated_in.