This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
dev:crosscompiler:type_checking [2015/04/06 08:50] – ursgraf | dev:crosscompiler:type_checking [2022/12/20 11:43] (current) – ursgraf | ||
---|---|---|---|
Line 13: | Line 13: | ||
Hint: As soon as there is a type check against an array of interfaces, a type descriptor for this interface must be created. On the other hand, if the object at runtime is of type array of standard class, then the interface descriptor won't be used. It will be used solely in case when the type at runtime is itself of type array of interfaces. | Hint: As soon as there is a type check against an array of interfaces, a type descriptor for this interface must be created. On the other hand, if the object at runtime is of type array of standard class, then the interface descriptor won't be used. It will be used solely in case when the type at runtime is itself of type array of interfaces. | ||
- | ==== Special Case //Object// ==== | + | ==== Special Case 'Object' |
- | When you check against //Object//, the result must be '' | + | When you check against //Object//, the result must be '' |
A check against an array of //Object// leads to two cases: | A check against an array of //Object// leads to two cases: | ||
- The reference points to an array of regular classes: the check returns '' | - The reference points to an array of regular classes: the check returns '' | ||
Line 22: | Line 22: | ||
All the explanations above were for // | All the explanations above were for // | ||
- The check against //Object// is never necessary. It will be eliminated already in the Bytecode. | - The check against //Object// is never necessary. It will be eliminated already in the Bytecode. | ||
- | - Bei einer misslungenen Prüfung wird eine Trap-Instruktion ausgelöst. | + | - A failing check has to cause an exception. |
- A '' | - A '' | ||
Line 31: | Line 31: | ||
- this address must be identical with the address of the type descriptor of the actual object. | - this address must be identical with the address of the type descriptor of the actual object. | ||
The type descriptor of a class is constructed as follows: the base class 0 is always //Object//. The entry contains the address of the type descriptor of //Object//. This entry is followed by the other superclasses. The address of the own class is entered as the last entry. All derived classes must have the same order for the base classes. The example below shows the execution of a type check. | The type descriptor of a class is constructed as follows: the base class 0 is always //Object//. The entry contains the address of the type descriptor of //Object//. This entry is followed by the other superclasses. The address of the own class is entered as the last entry. All derived classes must have the same order for the base classes. The example below shows the execution of a type check. | ||
- | [{{ .: | + | [{{ .: |
For the java code | For the java code | ||
Line 50: | Line 50: | ||
Here again, the compiler calculates the offset to be 2. However, the reference points to // | Here again, the compiler calculates the offset to be 2. However, the reference points to // | ||
\\ | \\ | ||
- | Es muss sichergestellt werden, dass alle Typdecriptoren die gleiche Anzahl von Einträgen aufweisen. Das bedeutet, dass die Descriptoren der Basisklassen mit der notwendigen Anzahl von leeren Einträgen gefüllt werden müssen. Damit wird vermieden, dass ungültige Adressen gelesen werden können. Als Beispiel dazu: | + | \\ |
+ | All the type descriptors must have the same number of entries. All descriptors must be filled with empty entries up to the maximal number of entries. This ensures that non-valid addresses are read, see the following example. | ||
<code java> | <code java> | ||
ClassA1 o = new ClassA21(); | ClassA1 o = new ClassA21(); | ||
((ClassA3)o).m1(); | ((ClassA3)o).m1(); | ||
</ | </ | ||
- | Hier wird der Offset | + | The offset will be calculated to be 3. In the type descriptor of //ClassA21// the entry at offset |
\\ | \\ | ||
- | Warum müssen alle Typdescriptoren die gleiche (maximale) Anzahl von Einträgen aufweisen? Nehmen wir den Code | + | Let's consider another case: |
<code java> | <code java> | ||
Object o; | Object o; | ||
((ClassX)o).m1(); | ((ClassX)o).m1(); | ||
</ | </ | ||
- | Weil o vom Typ statischen Typ // | + | The static type of //o// is //Object//. The runtime type could be anything. Therefore, we could check against any type. For instance, |
==== Type Check for Interface Type ==== | ==== Type Check for Interface Type ==== | ||
- | Interfaceklassen dürfen nicht in der Tabelle mit den Standardklassen aufgeführt werden. Der folgende Fall zeigt warum:\\ | + | Interface classes cannot be listed |
- | [{{ .: | + | [{{ .: |
- | Je nach Vererbungshierarchie belegt das Interface einen anderen Platz in der Tabelle und der Compiler kann keinen fixen Offset berechnen mit dem in der Tabelle geprüft werden könnte. \\ Aus diesem Grund gibt es eine Tabelle im Typdescriptor mit allen Interfaces, die diese Klasse implementiert und auf die überhaupt je ein Typtest gemacht wird. \\ | + | Depending on the extension hierarchy the interface occupies different places |
- | [{{ .: | + | For this reason the type descriptor has a table with all interfaces that this class implements. The compiler will determine at compile time for which interfaces there is ever a type check. Only these will be inserted into the table. \\ |
- | Die betroffenen Interfaces werden alle nummeriert | + | [{{ .: |
- | Auch hier muss wieder wie oben ein Unterschied zwischen | + | All the affected interfaces get numbered |
+ | Here again, | ||
- | ==== Anwendungsfall: | + | ==== Complex Use Case ==== |
- | Der folgende Code | + | The following code |
<code java> | <code java> | ||
- | Object[][][] | + | Object[][][] |
A[] x = new AA[5]; | A[] x = new AA[5]; | ||
- | | + | |
- | | + | |
short[][] y = new short[2][3]; | short[][] y = new short[2][3]; | ||
- | | + | |
- | | + | |
</ | </ | ||
- | führt auf die folgende Abbildung\\ | + | leads to\\ |
- | [{{ .: | + | [{{ .: |
- | Dieses Beispiel befindet sich auch in den Testfällen | + | This example can be found in the test cases (//org.deepjava.comp.targettest.arrays.ArrayInstanceTest.testInstance4//). |