deep

a Cross Development Platform for Java

User Tools

Site Tools


dev:crosscompiler:type_checking

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
dev:crosscompiler:type_checking [2015/04/06 08:50] ursgrafdev: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 ''true'' if the object is an array.\\+When you check against //Object//, the result must be ''true'' if the object is an array (of any type).\\
 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 ''true'' if the dimension (of the type to check against) is lower or equal than the actual dimension.   - The reference points to an array of regular classes: the check returns ''true'' if the dimension (of the type to check against) is lower or equal than the actual dimension.
Line 22: Line 22:
 All the explanations above were for //instanceof//. For //checkcast// there are some modifications:  All the explanations above were for //instanceof//. For //checkcast// there are some modifications: 
   - 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 ''null'' reference results in a positive check.   - A ''null'' reference results in a positive check.
  
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.
-[{{ .:typecheck.png?700&direct | // Example of a type check //}}]+[{{ .:typecheck.png?600&direct | //Example 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 //ClassA21//. With offset 2 the address of //ClassA21// will be fetched and compared to //ClassA20//. The check must return ''false''. Here again, the compiler calculates the offset to be 2. However, the reference points to //ClassA21//. With offset 2 the address of //ClassA21// will be fetched and compared to //ClassA20//. The check must return ''false''.
 \\  \\ 
-Es muss sichergestellt werden, dass alle Typdecriptoren die gleiche Anzahl von Einträgen aufweisenDas bedeutet, dass die Descriptoren der Basisklassen mit der notwendigen Anzahl von leeren Einträgen gefüllt werden müssenDamit wird vermiedendass ungültige Adressen gelesen werden könnenAls Beispiel dazu:+\\ 
 +All the type descriptors must have the same number of entriesAll descriptors must be filled with empty entries up to the maximal number of entriesThis ensures that non-valid addresses are readsee the following example.
 <code java> <code java>
 ClassA1 o = new ClassA21(); ClassA1 o = new ClassA21();
 ((ClassA3)o).m1(); ((ClassA3)o).m1();
 </code> </code>
-Hier wird der Offset berechnetIm Typdescriptor von ClassA21 darf beim Offset kein zufälliger anderer Eintrag vorhanden sein.+The offset will be calculated to be 3. In the type descriptor of //ClassA21// the entry at offset must be 0.
 \\ \\
-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();
 </code> </code>
-Weil vom Typ statischen Typ //Object// istder dynamische Typ aber beliebig sein kann, kann hier auf einen beliebigen Typ geprüft werden. //ClassX// könnte z.B. den Offset 10 habenAlso müssen alle Typdescriptoren mindestens 10 (wenn auch leere) Einträge haben.+The static type of //o// is //Object//. The runtime type could be anything. Thereforewe could check against any typeFor instance, //ClassX// could have the offset 10. Hence, all type descriptors must have at least 10 entries.
  
 ==== Type Check for Interface Type ==== ==== Type Check for Interface Type ====
-Interfaceklassen dürfen nicht in der Tabelle mit den Standardklassen aufgeführt werdenDer folgende Fall zeigt warum:\\ +Interface classes cannot be listed in the table with the standard classes. The reason is that interface classes do not have fixed offsets.\\ 
-[{{ .:interfacetypecheck1.png?600&direct | // Interfaceklassen haben unterschiedlichen Offset //}}] +[{{ .:interfacetypecheck1.png?600&direct |//Interface classes have different offsets//}}] 
-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 in the table and the compiler cannot calculate a fixed offset to check against. \\  
-[{{ .:interfacetypecheck2.png?250&direct | // Typdescriptor mit CheckIds seiner Interfaces //}}] +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 (chkId) und in der Tabelle beginnend mit der grössten Nummer eingetragen. Die Typprüfung läuft nun so ab, dass der Compiler die //chkId// der zu testenden Klasse in der Tabelle des Typdescritors des aktuellen Typs suchtWird sie gefunden, liefert der Test //true// andernfalls //false//. Der letzte Eintrag in der Tabelle muss sein.\\ +[{{ .:interfacetypecheck2.png?300&direct | // Type descriptor with //checkIds// of its interfaces //}}] 
-Auch hier muss wieder wie oben ein Unterschied zwischen //checkcast// und //instanceof// gemacht werden.+All the affected interfaces get numbered (//chkId//) and will be inserted into the table starting with the highest numberThe checking can now run as follows: the compiler knows the //chkId// of the interface to check against. It will search //chkId// in the table. If found, the check returns ''true'' else ''false''. The last entry must be in order to end the search.\\ 
 +Here again, //checkcast// and //instanceof// differ slightly.
  
-==== Anwendungsfall: Typprüfung ==== +==== Complex Use Case ==== 
-Der folgende Code+The following code 
 <code java> <code java>
-  Object[][][] a1 = new Object[2][3][4];+  Object[][][] = new Object[2][3][4]; 
   A[] x = new AA[5];   A[] x = new AA[5];
-  a1[0][0] = x; +  o[0][0] = x; 
-  a1[0][1][2] = x;+  o[0][1][2] = x;
   short[][] y = new short[2][3];   short[][] y = new short[2][3];
-  a1[1][0] = y; +  o[1][0] = y; 
-  a1[1][1][0] = y;+  o[1][1][0] = y;
 </code> </code>
-führt auf die folgende Abbildung\\ +leads to\\ 
-[{{ .:typecheckexample1.png?700| // Speicherabbild für obenstehendes Beispiel //}}]\\ +[{{ .:typecheckexample1.png?600|//Type descriptors for complex use case//}}]\\ 
-Dieses Beispiel befindet sich auch in den Testfällen (ch.ntb.inf.deep.comp.targettest.arrays.ArrayInstanceTest.testInstance4).+This example can be found in the test cases (//org.deepjava.comp.targettest.arrays.ArrayInstanceTest.testInstance4//).
dev/crosscompiler/type_checking.1428303048.txt.gz · Last modified: 2016/02/25 13:33 (external edit)