|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Objectorg.vishia.java2C.test.TestAllConcepts
public class TestAllConcepts
This class contains some examples to demonstrate and test all features of Java2C.
The elements all explained respecting the Java2C-features which are tested there.
Most of the methods demonstrates a programming style, which is opportune also in C.
The class is represent in C wit a struct type definition:
typedef struct TestAllConcepts_Test_t
{
union { ObjectJc object; ImplIfc_Test_s super;} base;
int32 simpleInt;
...etc.
}
The first element of struct is a union, which pools the super class, all interfaces and the ObjectJc-base.
The most inner super class has ObjectJc as its first Element, the access to that base of all super classes
can accessed immediately in this unit.
| Field Summary | |
|---|---|
private AnyClass |
anyRef
|
(package private) SimpleDataStruct[] |
dataArrayEmbedded
|
(package private) SimpleDataStruct[] |
dataArrayRef
|
(package private) SimpleDataStruct[] |
dataArraySimpleEmbedded
|
(package private) SimpleDataStruct[] |
dataAssociatedEmbeddedArray
A array of embedded elements, not final. |
(package private) SimpleDataStruct[] |
dataAssociatedRefArray
|
(package private) SimpleDataStruct[] |
dataRefArray
A array of references, but the head is embedded |
(package private) SimpleDataStruct[] |
dataRefArrayEmbedded
|
(package private) SimpleDataStruct |
embeddedData
In Java it is a fix build instance at construction time. |
(package private) ExpandedDataStruct |
embeddedDataExpand
In Java it is a fix build instance at construction time. |
(package private) SimpleDataStruct |
embeddedDataNotEnpand
In Java it is a fix build instance at construction time. |
private ExtendsImpl |
extendsImpl
|
private Ifc |
ifc
A class reference to an interface, set one time final. |
private Ifc |
ifc2
A class reference to an interface, but set only if used. |
private Ifc2 |
ifc3
|
private ImplIfc |
ifc4
A initialized but not final reference. |
private Ifc |
ifcNonVirtual
A class reference to an interface, but it is set to only one instance: Therefore the call of methods at C-level uses the methods of the implemtation, it doesn't use the dynamic call. |
private ImplIfc |
implifc
An instance which implements a interface, using to test interface access. |
private ImplIfc |
implifc2
A second instance which implements a interface, using to test interface access. |
private int[] |
intArray
A initialized array, it is embedded because it's final. |
private int[] |
intArrayRef
A initialized array, but it is not embedded because it isn't final. |
private int[] |
intArrayRef2
A simple reference to an array. |
private int[] |
intArrayRefSimple
A initialized array, but it is not embedded because it isn't final. |
private int[] |
intArraySimple
A initialized array, it is embedded because it's final. |
(package private) static int[] |
intArrayStaticConst
|
(package private) static char |
kCharConst
A final constant not-int-value, it is a const variable in C. |
(package private) static int |
kIdxMsgOutputFile
|
(package private) static int |
kMsgBlockHeap
A total constant value, it is a #define kMsgBlockHeap 9000 in C. |
(package private) static int |
nrofInstances
A static, but not final variable. |
private int |
simpleInt
A simple class variable. |
(package private) java.lang.StringBuffer |
stringBufferMain
|
private TestAnonymous |
testAnonymous
|
(package private) TestString |
testString
|
(package private) TestStringFormatter |
testStringFormatter
|
(package private) TestThread |
testThread
|
(package private) TestWaitNotify |
testWaitNotify
|
(package private) TestWaitNotify.WaitNotifyData |
testWaitNotifyData
|
| Constructor Summary | |
|---|---|
TestAllConcepts()
The Constructor of this example. |
|
| Method Summary | |
|---|---|
void |
access(float x)
A method with same name but other parameter types. |
int |
access(int x)
|
private int |
checkConcatCallReturnAnything()
|
private int |
checkConcatCallReturnThisTypefixNonVirtual()
Deprecated. In this case the calling instance is the same as the returned instance, which is the calling instance for the next concatenated call. In Java it is written: a =implifc.returnThisA(34).returnThisA(56).processIfcMethod(44);Because the reference implifc is a embedded instance and the type of it is fix,
(the same is for stack instances or @ java2c=instanceType:"Type"-designated references),
all method-calls are execute non-dynamic.
Because a @ java2c=return-this is designated to the called method, the Java2C-translator
accept that the result instance is the same as calling instance, but because that is type-fix,
the concatenated call is execute non-dynamic too.
a = ( returnThisA_ImplIfcTest_F(& (ythis->implifc), 34, _thCxt) , returnThisA_ImplIfcTest_F(& (ythis->implifc), 56, _thCxt) , processIfcMethod_i_ImplIfcTest_F(&((& ((ythis->implifc).base.IfcToTest))->base.object), 44, _thCxt) );The instance to call the method is implifc always, it's the first parameter of any called method.
That is because the methods are labeled to @ java2c=return-this. The concatenation in Java is presented
as a comma-separated expression, see checkConcatenationSimple().
But in this case no temporary references are needed, it is more simple. Lastly the concatenated methods in Java
are only a simplifying of writing of the method calls with the same reference.
Note: the expression &((& ((ythis->implifc).base.IfcToTest))->base.object) is needed
because the processIfcMethod_i_ImplIfcTest_F is a method of the interface type. |
private int |
checkConcatenationDynamicCall()
Example to show concatenated calls of override-able methods. |
private int |
checkConcatenationDynamicCallToBaseMethods()
Example to test dynamic and static calls to methods, which are methods of the base class. |
private int |
checkConcatenationSimple()
Example to show concatenated calls in a simple variant. |
(package private) void |
checkNonVirtual()
Example for a non-dynamic call of an interface referenced method. |
private int |
checkSomeDynamicCalls()
This method shows some calls of interface methods, see org.vishia.java2C.Docu.SuperClassesAndInterfaces#callingOverrideableMethods(). |
boolean |
equals(java.lang.Object cmp)
Check whether Object.equals() will be overridden. |
boolean |
equals(java.lang.String cmp)
This method doesn't override Object.equals. |
void |
finalize()
Example for a special finalize method body. finalize is called by garbage collection if the object is deleted finally. |
private void |
main()
|
static void |
main(java.lang.String[] args)
|
TestAllConcepts |
returnThisOverrideable_Test(int value)
This method helps to test concatenations with return-this, but override-able. |
(package private) int |
testAccessIfc()
|
(package private) int |
testAccessIfcMtbl()
|
(package private) int |
testAccessIfcMtbl2(boolean bTest)
|
(package private) void |
testInternalDynCall()
Example to check how an dynamic call of own methods is implemented in C. |
| Methods inherited from class java.lang.Object |
|---|
clone, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
|---|
private int simpleInt
int32 simpleInt;The type
int32 is defined in os_types_def.h platform-depending, so that a 32-bit-integer
is used.
25 is done in the Constructor, see TestAllConcepts()
static final int kMsgBlockHeap
static final int kIdxMsgOutputFile
static final char kCharConst
static int nrofInstances
int32 nrofInstances_TestAllConcepts = 5;
It may be better, to write in a common initializeStatics()-Method, to regard more complex expressions.
final SimpleDataStruct embeddedData
final SimpleDataStruct embeddedDataNotEnpand
final ExpandedDataStruct embeddedDataExpand
final TestWaitNotify.WaitNotifyData testWaitNotifyData
final TestThread testThread
final TestWaitNotify testWaitNotify
final java.lang.StringBuffer stringBufferMain
final TestString testString
final TestStringFormatter testStringFormatter
private final int[] intArray
private int[] intArrayRef
private int[] intArrayRef2
private final int[] intArraySimple
private int[] intArrayRefSimple
static final int[] intArrayStaticConst
SimpleDataStruct[] dataArrayRef
final SimpleDataStruct[] dataArrayEmbedded
final SimpleDataStruct[] dataArraySimpleEmbedded
final SimpleDataStruct[] dataRefArrayEmbedded
final SimpleDataStruct[] dataRefArray
SimpleDataStruct[] dataAssociatedEmbeddedArray
SimpleDataStruct[] dataAssociatedRefArray
private final ImplIfc implifc
private final Ifc2 ifc3
private ImplIfc implifc2
private final Ifc ifc
private final Ifc ifcNonVirtual
private Ifc ifc2
private final ExtendsImpl extendsImpl
private ImplIfc ifc4
private final AnyClass anyRef
private final TestAnonymous testAnonymous
| Constructor Detail |
|---|
public TestAllConcepts()
SimpleDataStruct).
than this initialization isn't happen.
null-references,
and all values are default set to 0.
init_ObjectJc(object, sizeof(Instance), ident);
manually at C-level. Static instances can be defined at C-level before starting initialization
in the C-typical wise.
struct TestAllConcepts_Test_t* ctorO_TestAllConcepts_Test(ObjectJc* othis, ThCxt* _thCxt)
{ TestAllConcepts_Test_s* ythis = (TestAllConcepts_Test_s*)othis; //upcasting to the real class.
STACKTRC_TENTRY("ctorO_TestAllConcepts_Test");
checkConsistence_ObjectJc(othis, sizeof(TestAllConcepts_Test_s), null, _thCxt);
setReflection_ObjectJc(othis, &reflection_TestAllConcepts_Test_s, sizeof(TestAllConcepts_Test_s));
ObjectJc*-Reference. This is,
because the calling environment supplied only this base reference. This ObjectJc is initialized,
especially the size of the memory area is set in ObjectJc.objectIdentSize.
ThCxt* _thCxt is the reference of the threadContext. It is necessary for exception handling.
STACKTRC_TENTRY(...) registers the method stack level in thread context.
It is for exception handling with stack-trace dump.
checkConsistence_ObjectJc(...) tests whether the memory area
referenced with ythis is initialized properly. Especially the size of the area is tested.
This routine calls an Exception if the conditions are not true. The conditions should be met any time,
elsewhere a user software error is happen. After this test the continuation of initialize is safety.
Without such test the software may be crash here causing of an external error.
setReflection(...) completes the ObjectJc-Data with the only one special information
regarding the implementation instance. The reflection include the method table too. It is a structured data
defined at C-level in this compilation unit.
| Method Detail |
|---|
public int access(int x)
private int checkSomeDynamicCalls()
org.vishia.java2C.Docu.SuperClassesAndInterfaces#callingOverrideableMethods().
private final int checkConcatenationSimple()
myInstance.ref->refOfRef->variable.
It is the adequate construct. The usage of methods instead the immediately getting of the reference
is the concept of ObjectOrientation and Encapsulation: The access to the class data should be done
always using get-methods. The advantage is: Any access check can be implemented in the get-method.
The programming can be implemented more safety. But Lastly it's possible to present a get-method
with a primitive macro in C. Than no extra method call is produced, the machine code is the same
like the immediately access.
int a = 234 + implifc.returnAnyInstance().returnRef().returnAnyInstance().addValue(24) + 27;
sbufferFix.append("Value=").append(simpleInt).append(" miles");
In comparison with C++, the usage of an C++-expression cout << "Value=" << simpleInt << " miles"
phrases the same. The shift operator should phrase a association to "shift in pipe",
but at syntactical level it is an concatenation like shown above.
AnyClass_Test_s* _tempRef1; ImplIfcTest_s* _tempRef2; AnyClass_Test_s* _tempRef3;
a = 234 +
( _tempRef1= returnAnyInstance_ImplIfcTest(& (ythis->implifc), _thCxt)
, _tempRef2= returnRef_AnyClass_Test(_tempRef1, _thCxt)
, _tempRef3= returnAnyInstance_ImplIfcTest(_tempRef2, _thCxt)
, addValue_AnyClass_Test(_tempRef3, 24, _thCxt)
) + 27;
( append_s_StringBufferJc(& (ythis->sbufferFix.sb), s0_StringJc("Value="), _thCxt)
, append_i_StringBufferJc(& (ythis->sbufferFix.sb), ythis->simpleInt, _thCxt)
, append_s_StringBufferJc(& (ythis->sbufferFix.sb), s0_StringJc(" miles"), _thCxt)
);
In the first concatenation example: The references from each call are parked in temporary variables.
That is because the result from the first call is the first parameter of the next call.
If temporary variables are not used, the first call may be placed as first parameter of the second call etc.
This construct may be lesser able to read, it is a nesting of calls. There is another problem thereby:
If method tables are necessary for dynamic calls, the reference is needed twice. Therefore a explicitly
temporary reference is proper.
return this;in its implementation. That is labeled at the methods. The translator knows that therefore and can optimize: All methods use the same reference. The concatenation in Java is translated to a simple order of routine call.
private int checkConcatenationDynamicCall()
a = 234 + implifc2.returnAnyInstanceOverrideable().returnRefOverrideable().returnAnyInstanceOverrideable().addValueOverrideable(24) + 27;is related to the first line in
checkConcatenationSimple(), but the difference is:
all methods are dynamically called. It is a simple non-prepared dynamic call,
therefore the code in C may be look catastrophic for real time.
The method table of the references have to be got. It is a call of getMtbl_ObjectJc(...)
with the given reference as first parameter. But the calculation time is not so expensive,
it may be a few nanoseconds if the derivation is not deep, and some more nanoseconds if it is deeper,
but not more. Only for hard real-time it is non-opportune. The lines in C are:
AnyClass_Test_s* _tempRef1; ImplIfcTest_s* _tempRef2; AnyClass_Test_s* _tempRef3;
a = 234 +
( _tempRef1= ((Mtbl_ImplIfcTest const*)getMtbl_ObjectJc(&(REFJc(ythis->implifc2))->base.object, sign_Mtbl_ImplIfcTest) )->returnAnyInstanceOverrideable(REFJc(ythis->implifc2), _thCxt)
, _tempRef2= ((Mtbl_AnyClass_Test const*)getMtbl_ObjectJc(&(_tempRef1)->base.object, sign_Mtbl_AnyClass_Test) )->returnRefOverrideable(_tempRef1, _thCxt)
, _tempRef3= ((Mtbl_ImplIfcTest const*)getMtbl_ObjectJc(&(_tempRef2)->base.object, sign_Mtbl_ImplIfcTest) )->returnAnyInstanceOverrideable(_tempRef2, _thCxt)
, ((Mtbl_AnyClass_Test const*)getMtbl_ObjectJc(&(_tempRef3)->base.object, sign_Mtbl_AnyClass_Test) )->addValueOverrideable(_tempRef3, 24, _thCxt)
) + 27;
The second line in Java
a += this.returnThisOverrideable_Test(34).returnThisOverrideable_Test(45).access(56);shows a concatenated call of overrideable methods, which returns this and uses this as first reference. Because this is supported as method-table-reference if it is need, with one access to
getMtbl_ObjectJc(...)
in the method, and the mthis is used for all calls because the return this-property
of the called method is known, this is a optimized access. In C it is:
Mtbl_TestAllConcepts_Test const* mtthis = (Mtbl_TestAllConcepts_Test const*)getMtbl_ObjectJc(&ythis->base.object, sign_Mtbl_TestAllConcepts_Test);
...
a +=
( mtthis->returnThisOverrideable_Test(ythis, 34)
, mtthis->returnThisOverrideable_Test(ythis, 45)
, mtthis->access_i(ythis, 56, _thCxt)
);
whereby the first line is generated only one time in the method.
this,
why wet even the reference is the same for all three calls. The reference is copied into a stack variable,
which is labeled with @ java2c=dynamic-call. Therefore in C a so named "method-table-reference" is built.
This reference contains the pointer to the method table beside the pointer of data. The pointer to the method table
is got calling getMtbl_ObjectJc(...) only on setting the reference.
It's a part of the macro SETMTBJc(...). So the C-code is optimized. The Java-lines are:
/ **This reference is build in stack because it contains the method-table-reference too: @ java2c=dynamic-call. * / AnyClass anyRef2 = anyRef; anyRef2.returnThisOverrideable(45).returnThisOverrideable(234).addValueOverrideable(67);The translated C-code is:
SETMTBJc(anyRef2, REFJc(ythis->anyRef), AnyClass_Test);
a +=
( anyRef2.mtbl->returnThisOverrideable( (anyRef2.ref), 45, _thCxt)
, anyRef2.mtbl->returnThisOverrideable( (anyRef2.ref), 234, _thCxt)
, anyRef2.mtbl->addValueOverrideable( (anyRef2.ref), 67, _thCxt)
);
In opposite, if the special stack-local method-table-reference is not built, the C-code isn't optimize,
but able to run (translated from next Java line using anyRef as class reference):
a +=
( ((Mtbl_AnyClass_Test const*)getMtbl_ObjectJc(&(REFJc(ythis->anyRef))->base.object, sign_Mtbl_AnyClass_Test) )->returnThisOverrideable(REFJc(ythis->anyRef), 345, _thCxt)
, ((Mtbl_AnyClass_Test const*)getMtbl_ObjectJc(&(REFJc(ythis->anyRef))->base.object, sign_Mtbl_AnyClass_Test) )->returnThisOverrideable(REFJc(ythis->anyRef), 3234, _thCxt)
, ((Mtbl_AnyClass_Test const*)getMtbl_ObjectJc(&(REFJc(ythis->anyRef))->base.object, sign_Mtbl_AnyClass_Test) )->addValueOverrideable(REFJc(ythis->anyRef), 367, _thCxt)
);
shows a call of a dynamic-linked method of a other instance, whereby the return this-property
is known too, and the reference is prepared as a locally method-table-reference:
mthis.
@ java2c=dynamic-call or it is an interface-reference.
If the methods returns this, and they are labeled with @ java2c=return-this,
the access is optimized.
private int checkConcatenationDynamicCallToBaseMethods()
private int checkConcatCallReturnThisTypefixNonVirtual()
a =implifc.returnThisA(34).returnThisA(56).processIfcMethod(44);Because the reference
implifc is a embedded instance and the type of it is fix,
(the same is for stack instances or @ java2c=instanceType:"Type"-designated references),
all method-calls are execute non-dynamic.
Because a @ java2c=return-this is designated to the called method, the Java2C-translator
accept that the result instance is the same as calling instance, but because that is type-fix,
the concatenated call is execute non-dynamic too.
a = ( returnThisA_ImplIfcTest_F(& (ythis->implifc), 34, _thCxt) , returnThisA_ImplIfcTest_F(& (ythis->implifc), 56, _thCxt) , processIfcMethod_i_ImplIfcTest_F(&((& ((ythis->implifc).base.IfcToTest))->base.object), 44, _thCxt) );The instance to call the method is
implifc always, it's the first parameter of any called method.
That is because the methods are labeled to @ java2c=return-this. The concatenation in Java is presented
as a comma-separated expression, see checkConcatenationSimple().
But in this case no temporary references are needed, it is more simple. Lastly the concatenated methods in Java
are only a simplifying of writing of the method calls with the same reference.
&((& ((ythis->implifc).base.IfcToTest))->base.object) is needed
because the processIfcMethod_i_ImplIfcTest_F is a method of the interface type.
private int checkConcatCallReturnAnything()
public TestAllConcepts returnThisOverrideable_Test(int value)
@ java2c=return-this is written.
value - any value
void checkNonVirtual()
public boolean equals(java.lang.Object cmp)
equals in class java.lang.ObjectObject.equals(java.lang.Object)public boolean equals(java.lang.String cmp)
public void access(float x)
x - int testAccessIfc()
int testAccessIfcMtbl()
int testAccessIfcMtbl2(boolean bTest)
final void testInternalDynCall()
testAccessIfcMtbl() is called twice:
public void finalize()
TODO copy from C
finalize in class java.lang.Objectprivate void main()
public static void main(java.lang.String[] args)
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||