java2beta
is a Java program, which use Java
reflective libraries
(java.lang.Class
, java.lang.reflect.*
)
to open a given class, and map this class and
it's members to apropriate BETA declarations as specified below.
dotnet2beta
is a C# program, which use .NET
reflective libraries
(System.Type
, System.Reflection.*
)
to open a given type/interface, and map this type/interface and
it's members to apropriate BETA declarations as specified below.
The mapping can be outlined as below. The term class is used to denote both classes, types, interfaces below, unless otherwise stated.
INCLUDE
. This is decribed in more detail in
Include Handling.
In .NET valuetypes are used for "small" objects, which need not have
instance-identity. The primary reason for this is efficiency. All
primitive types (e.g. all the integer types) are value types.
All value types are directly derived from
System.ValueType
, which derives directly from
System.Object
. A special exception to this rule is
System.Enum
, which is the base class of all enumeration
types, and which derives directly from System.ValueType
:
System.Object | `- System.ValueType | `- System.Enum...
dotnet2beta
to
a specialization of ExternalClass
, but using a
@
as an indicator in the
className
to tell the compiler that this is to be treated
specially. Example:
DateTime: ExternalClass
(#
_init_int64: cons
(# result: ^DateTime;
arg1: @int64;
enter (arg1)
exit result[]
#);
...
get_Month: proc
(# result: @int32;
exit result
#);
...
ToFileTime: proc
(# result: @int64;
exit result
#);
...
do '@valuetype [mscorlib]System.DateTime' -> className;
#);
This example ValueType has a private int64
instance
field, which is not exposed in the ExternalClass declaration, since
you cannot access a private field.
ECMA 335 defines how to call methods on value types in section 12.1.6.2.4:
The special valuetype indicator allows to compiler to emit the special
Static methods on value types are handled no differently from static methods on an ordinary class: use a call instruction with a metadata token specifying the value type as the class of the method. Non-static methods (i.e. instance and virtual methods) are supported on value types, but they are given special treatment. A non-static method on a class (rather than a value type) expects a this pointer that is an instance of that class. This makes sense for classes, since they have identity and the this pointer represents that identity. Value types, however, have identity only when boxed. To address this issue, the this pointer on a non-static method of a value type is a by-ref parameter of the value type rather than an ordinary by-value parameter. A non-static method on a value type may be called in the following ways:
- Given an unboxed instance of a value type, the compiler will know the exact type of the object statically. The
call
instruction can be used to invoke the function, passing as the first parameter (the this pointer) the address of the instance. The metadata token used with the call instruction shall specify the value type itself as the class of the method.- ...
ldflda
/ ldarga
/ ldloca
instructions
to load the address of the value before issuing the call
instruction, when calling methods on such ValueTypes.
Problems:
The CTS supports an enum (also known as an enumeration type), an alternate name for an existing type. For purposes of matching signatures an enum shall not be the same as the underlying type. Instances of an enum, however, shall be assignment compatible with the underlying type and vice versa. That is: no cast or coercion is required to convert from the enum to the underlying type, nor are they required from the underlying type to the enum. An enum is considerably more restricted than a true type:
- It shall have exactly one instance field, and the type of that field defines the underlying type of the enumeration.
- It shall not have any methods of its own.
- It shall not implement any interfaces of its own.
- It shall not have any properties or events of its own.
- It shall not have any static fields unless they are literal
- The underlying type shall be a built-in integer type.
- Enums shall derive from
System.Enum
, hence they are value types. Like all value types, they shall be sealed
FileAttributes: ExternalClass
(#
ReadOnly:
(# exit 1 #);
Hidden:
(# exit 2 #);
System:
(# exit 4 #);
...
do '@valuetype [mscorlib]System.IO.FileAttributes' -> className;
INNER;
#);
somefunction: proc (# attr: ^FileAttributes #)Problem: How to call
FileAttributes.ReadOnly->somefunction
.
someFunction: proc (# attr: @int32; do 'someFunction'->procname #)Problem: Signature for
somefunction
constructed by
BETA compiler will be wrong, since the type of the parameter will become [mscorlib]System.Int32
,
whereas it should be [mscorlib]System.IO.FileAttributes
.
Example: GENERATOR/BYTECODE/TEST/hellobox.bet
shows an example of this problem (a MessageBox.Show
call,
where the last two parameters are integers instead of enum types,
and where the signature becomes wrong)
procname
. Compiler will need a way to determine if the
procname was full or partial. Scan for parenthesis? Special character?
somefunction: proc (# attr: @FileAttributes #)Problem:
FileAttributes
must be declared with
enter/exit
part. Probably FileAttributes
must derive from some special pattern Enum
declared in betaenv
?
do myFile.getAttributes %Band FileAttributes.ReadOnly = FileAttributes.ReadOnly -> fileIsReadOnly;Possible solution 1: Treating enums as static references (as suggested above) in BETA will probably handle this.
myEnumValue.%asInt32
primitive
(should generate no code, except loading the enum to the stack - as
noted above in the ECMA quote, no cast/coersion is needed in the
generated code: the enum is fully compatible with the underlying type).