[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dotgnu-pnet-commits] pnet ChangeLog engine/jitc.c engine/jitc_arith....
From: |
Klaus Treichel |
Subject: |
[dotgnu-pnet-commits] pnet ChangeLog engine/jitc.c engine/jitc_arith.... |
Date: |
Thu, 12 Oct 2006 16:07:38 +0000 |
CVSROOT: /cvsroot/dotgnu-pnet
Module name: pnet
Changes by: Klaus Treichel <ktreichel> 06/10/12 16:07:38
Modified files:
. : ChangeLog
engine : jitc.c jitc_arith.c jitc_call.c jitc_const.c
jitc_ptr.c jitc_stack.c
Log message:
2006-10-12 Klaus Treichel <address@hidden>
* engine/jitc.c: Move _ILJitValueConvertExplicit below
_ILJitValueConvertImplicit. Optimize both functions to
minimize the steps needed for the conversion. Extend
_ILJitCreateMethodSignature so that varargs are handled
correctly.
-> Add an additional void * arg for internal methods and set the
jit_abi to vararg for pinvokes.
* engine/jitc_arith.c: Fix the shift right opcodes so that
values
on the stack < Int32 are handled correctly.
* engine/jitc_call.c: Add creation of the call signature.
Inplicitely
convert the args to the type in the signature.
* engine/jitc_const.c: Replace jit_type_void_ptr by
_IL_JIT_TYPE_VPTR
for the LDNULL opcode.
* engine/jitc_ptr.c: Return the array length as int instead of
unsigned
int.
* engine/jitc_stack.c: Set all duplicates of a value null
checked if the
value is checked for null. Check if references to a local/arg
is passed
in a method call and replace this local on the stack with
duplicates.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pnet/ChangeLog?cvsroot=dotgnu-pnet&r1=1.3370&r2=1.3371
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc.c?cvsroot=dotgnu-pnet&r1=1.55&r2=1.56
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_arith.c?cvsroot=dotgnu-pnet&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_call.c?cvsroot=dotgnu-pnet&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_const.c?cvsroot=dotgnu-pnet&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_ptr.c?cvsroot=dotgnu-pnet&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_stack.c?cvsroot=dotgnu-pnet&r1=1.8&r2=1.9
Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/ChangeLog,v
retrieving revision 1.3370
retrieving revision 1.3371
diff -u -b -r1.3370 -r1.3371
--- ChangeLog 10 Oct 2006 17:10:44 -0000 1.3370
+++ ChangeLog 12 Oct 2006 16:07:38 -0000 1.3371
@@ -1,3 +1,28 @@
+2006-10-12 Klaus Treichel <address@hidden>
+
+ * engine/jitc.c: Move _ILJitValueConvertExplicit below
+ _ILJitValueConvertImplicit. Optimize both functions to
+ minimize the steps needed for the conversion. Extend
+ _ILJitCreateMethodSignature so that varargs are handled correctly.
+ -> Add an additional void * arg for internal methods and set the
+ jit_abi to vararg for pinvokes.
+
+ * engine/jitc_arith.c: Fix the shift right opcodes so that values
+ on the stack < Int32 are handled correctly.
+
+ * engine/jitc_call.c: Add creation of the call signature. Inplicitely
+ convert the args to the type in the signature.
+
+ * engine/jitc_const.c: Replace jit_type_void_ptr by _IL_JIT_TYPE_VPTR
+ for the LDNULL opcode.
+
+ * engine/jitc_ptr.c: Return the array length as int instead of unsigned
+ int.
+
+ * engine/jitc_stack.c: Set all duplicates of a value null checked if the
+ value is checked for null. Check if references to a local/arg is passed
+ in a method call and replace this local on the stack with duplicates.
+
2006-10-10 Klaus Treichel <address@hidden>
* engine/jitc.c, engine/jitc_arith.c, engine/jitc_array.c,
Index: engine/jitc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -b -r1.55 -r1.56
--- engine/jitc.c 10 Oct 2006 17:10:45 -0000 1.55
+++ engine/jitc.c 12 Oct 2006 16:07:38 -0000 1.56
@@ -683,24 +683,28 @@
}
/*
- * Do the explicit conversion of an ILJitValue to the given target type.
+ * Do the implicit conversion of an ILJitValue to the given target type.
* The value to convert is on the stack in it's source type. This means that no
* implicit conversion to the stacktype (either INT32, INT64 or a pointer type
* was done.
* Because of this we have to take into account that unsigned values with a
* length < 4 should have been zero extended to a size of an INT32 and signed
* values would have been sign extended.
+ * This means we have the following versions:
+ * 1. Target size is <= 4 bytes:
+ * We can convert directly to the target type because either the source
+ * value is truncated if it's long or the sign is changed if it's int or
+ * unsigned int or it would have been extended to 4 byted depending on it's
+ * own sign.
+ * 2. Both values are signed or both values are unsigned:
+ * we can convert directly to the target type.
*/
-static ILJitValue _ILJitValueConvertExplicit(ILJitFunction func,
+static ILJitValue _ILJitValueConvertImplicit(ILJitFunction func,
ILJitValue value,
-
ILJitType targetType,
-
int isUnsigned,
-
int overflowCheck)
+
ILJitType targetType)
{
ILJitType sourceType = jit_value_get_type(value);
- int sourceSize;
int sourceTypeKind;
- int targetSize;
int targetTypeKind;
if(sourceType == targetType)
@@ -718,129 +722,85 @@
if(_JIT_TYPEKIND_IS_FLOAT(sourceTypeKind))
{
/* We can convert these values directly */
- return jit_insn_convert(func, value, targetType, overflowCheck);
+ return jit_insn_convert(func, value, targetType, 0);
}
- else
- {
- if(_JIT_TYPEKIND_IS_FLOAT(targetTypeKind))
- {
- if(_JIT_TYPEKIND_IS_SIGNED(sourceTypeKind))
- {
- if(isUnsigned)
+ else if(_JIT_TYPEKIND_IS_FLOAT(targetTypeKind))
{
- AdjustSign(func, &value, 1,
overflowCheck);
- }
- }
- else if(_JIT_TYPEKIND_IS_UNSIGNED(sourceTypeKind))
+ if(_JIT_TYPEKIND_IS_UNSIGNED(sourceTypeKind))
{
- if(!isUnsigned)
+ int sourceSize = jit_type_get_size(sourceType);
+
+ if(sourceSize >= 4)
{
- AdjustSign(func, &value, 0,
overflowCheck);
+ /* We have to convert the value to signed first
because we */
+ /* don't know the value of the sign bit. */
+ AdjustSign(func, &value, 0, 0);
}
}
- else if(_JIT_TYPEKIND_IS_POINTER(sourceTypeKind))
- {
- if(isUnsigned)
- {
- value = jit_insn_convert(func, value,
_IL_JIT_TYPE_NUINT,
-
overflowCheck);
+ return jit_insn_convert(func, value, targetType, 0);
}
- else
+ else if(_JIT_TYPEKIND_IS_INT(targetTypeKind))
{
- value = jit_insn_convert(func,
value, _IL_JIT_TYPE_NINT,
-
overflowCheck);
- }
- }
- value = jit_insn_convert(func, value, targetType,
overflowCheck);
+ /* We can convert this directly directly because the source
value is */
+ /* either truncated or expanded to the target type depending on
the */
+ /* sign of the source value. */
+ return jit_insn_convert(func, value, targetType, 0);
}
- else
+ else if(_JIT_TYPEKIND_IS_LONG(targetTypeKind))
{
- sourceSize = jit_type_get_size(sourceType);
- targetSize = jit_type_get_size(targetType);
-
- if(targetSize <= sourceSize)
+ if(_JIT_TYPEKIND_IS_LONG(sourceTypeKind))
{
- /* The value is truncated or the sign is
changed. */
+ /* we can convert this directly because only the sign
is changed. */
+ return jit_insn_convert(func, value, targetType, 0);
}
- else
- {
- if(_JIT_TYPEKIND_IS_LONG(targetTypeKind))
- {
-
if(_JIT_TYPEKIND_IS_SIGNED(targetTypeKind))
- {
- /* In this case we have to zero
extend unsigned source */
- /* values to the size of an
INT32 first. */
-
if(_JIT_TYPEKIND_IS_UNSIGNED(sourceTypeKind))
+ if(_JIT_TYPEKIND_IS_INT(sourceTypeKind))
{
- /* We have to zero
extend the value to the */
- /* size an INT32 first.
*/
- /* I assume that
unsigned source values will be */
- /* zero extended to the
target size. */
- value =
jit_insn_convert(func, value,
-
_IL_JIT_TYPE_INT32,
-
overflowCheck);
- }
- else
if(_JIT_TYPEKIND_IS_POINTER(sourceTypeKind))
+ int sourceIsSigned =
_JIT_TYPEKIND_IS_SIGNED(sourceTypeKind);
+ int targetIsSigned =
_JIT_TYPEKIND_IS_SIGNED(targetTypeKind);
+ int sourceIsUnsigned =
_JIT_TYPEKIND_IS_UNSIGNED(sourceTypeKind);
+ int targetIsUnsigned =
_JIT_TYPEKIND_IS_UNSIGNED(targetTypeKind);
+
+ if((sourceIsSigned && targetIsSigned) ||
+ (sourceIsUnsigned && targetIsUnsigned))
{
- /* Pointers have to be
sign extended in this case. */
- /* So we convert to a
signed NINT first. */
- value =
jit_insn_convert(func, value,
-
_IL_JIT_TYPE_NINT,
-
overflowCheck);
- }
+ /* The signs match so we can convert directly.
*/
+ return jit_insn_convert(func, value,
targetType, 0);
}
- else
if(_JIT_TYPEKIND_IS_UNSIGNED(targetTypeKind))
+ else if(sourceIsUnsigned && targetIsSigned)
{
+ int sourceSize = jit_type_get_size(sourceType);
- /* In this case we have to sign
extend signed source */
- /* values to the size of an
INT32 first. */
-
if(_JIT_TYPEKIND_IS_SIGNED(sourceTypeKind))
+ if(sourceSize < 4)
{
- /* We have to sign
extend the value to the */
- /* size an INT32 first.
*/
- /* I assume that signed
source values will be */
- /* sign extended to the
target size. */
- value =
jit_insn_convert(func, value,
-
_IL_JIT_TYPE_UINT32,
-
overflowCheck);
- }
- else
if(_JIT_TYPEKIND_IS_POINTER(sourceTypeKind))
- {
- /* Pointers have to be
zero extended in this case. */
- /* So we convert to a
unsigned NUINT first. */
- value =
jit_insn_convert(func, value,
-
_IL_JIT_TYPE_NUINT,
-
overflowCheck);
- }
+ /* The source value is 0 extended to
INT32 and then */
+ /* extended to INT64. */
+ /* Because the source value is less
than 4 bytes we */
+ /* know that the sign will be 0 on the
32 bit value. */
+ return jit_insn_convert(func, value,
targetType, 0);
}
-#ifdef IL_NATIVE_INT64
- else
if(_JIT_TYPEKIND_IS_POINTER(targetTypeKind))
- {
- /* This is not allowed in
explicit conversion. */
- /* But we treat pointers like
unsigned values. */
-
if(_JIT_TYPEKIND_IS_SIGNED(sourceTypeKind))
+ else
{
- AdjustSign(func,
&value, 1, overflowCheck);
- }
+ /* Because we don't know the sign of
the 32 bit value we */
+ /* have to convert it to INT32 first. */
+ value = jit_insn_convert(func, value,
_IL_JIT_TYPE_INT32, 0);
+ return jit_insn_convert(func, value,
targetType, 0);
}
-#endif
}
- else
+ else if(sourceIsSigned && targetIsUnsigned)
{
- /* The value would have been zero- or
sign extended to */
- /* the size of an INT32 depending on
the signedness of */
- /* the value. Now we have the less or
the same size so */
- /* we can safely simply convert to the
target type. */
- }
+ /* In this case we'll allways have to do two
conversions. */
+ /* We have to convert it to UINT32 first. */
+ value = jit_insn_convert(func, value,
_IL_JIT_TYPE_UINT32, 0);
+ return jit_insn_convert(func, value,
targetType, 0);
}
- value = jit_insn_convert(func, value, targetType,
overflowCheck);
}
}
- return value;
+ /* All other values can be converted directly. */
+ return jit_insn_convert(func, value, targetType, 0);
}
/*
- * Do the implicit conversion of an ILJitValue to the given target type.
+ * Do the explicit conversion of an ILJitValue to the given target type.
* The value to convert is on the stack in it's source type. This means that no
* implicit conversion to the stacktype (either INT32, INT64 or a pointer type
* was done.
@@ -848,9 +808,11 @@
* length < 4 should have been zero extended to a size of an INT32 and signed
* values would have been sign extended.
*/
-static ILJitValue _ILJitValueConvertImplicit(ILJitFunction func,
+static ILJitValue _ILJitValueConvertExplicit(ILJitFunction func,
ILJitValue value,
-
ILJitType targetType)
+
ILJitType targetType,
+
int isUnsigned,
+
int overflowCheck)
{
ILJitType sourceType = jit_value_get_type(value);
int sourceTypeKind;
@@ -866,102 +828,313 @@
/* something is wrong here. */
return value;
}
+ if(!isUnsigned && !overflowCheck)
+ {
+ /* This is just like the implicit type conversion. */
+ return _ILJitValueConvertImplicit(func,
+
value,
+
targetType);
+ }
+ else if(!isUnsigned)
+ {
+ /* Do a signed type conversion with overflow check. */
+ /* This is just like the implicit type conversion with overflow
check. */
sourceTypeKind = jit_type_get_kind(sourceType);
targetTypeKind = jit_type_get_kind(targetType);
if(_JIT_TYPEKIND_IS_FLOAT(sourceTypeKind))
{
/* We can convert these values directly */
+ return jit_insn_convert(func, value, targetType,
overflowCheck);
+ }
+ else if(_JIT_TYPEKIND_IS_FLOAT(targetTypeKind))
+ {
+ if(_JIT_TYPEKIND_IS_UNSIGNED(sourceTypeKind))
+ {
+ int sourceSize = jit_type_get_size(sourceType);
+
+ if(sourceSize >= 4)
+ {
+ /* We have to convert the value to
signed first because we */
+ /* don't know the value of the sign
bit. */
+ AdjustSign(func, &value, 0, 0);
+ }
+ }
+ return jit_insn_convert(func, value, targetType, 1);
+ }
+ else if(_JIT_TYPEKIND_IS_INT(targetTypeKind))
+ {
+ /* We have to check if the sign has to be adjusted. */
+ if(_JIT_TYPEKIND_IS_UNSIGNED(sourceTypeKind))
+ {
+ int sourceSize = jit_type_get_size(sourceType);
+
+ if(sourceSize >= 4)
+ {
+ /* We have to convert the value to
signed first because we */
+ /* don't know the value of the sign
bit. */
+ AdjustSign(func, &value, 0, 0);
+ }
+ }
+ return jit_insn_convert(func, value, targetType,
overflowCheck);
+ }
+ else if(_JIT_TYPEKIND_IS_LONG(targetTypeKind))
+ {
+ if(_JIT_TYPEKIND_IS_LONG(sourceTypeKind))
+ {
+ /* If the source value is unsigned we have to
convert to */
+ /* signed first. */
+ if(_JIT_TYPEKIND_IS_UNSIGNED(sourceTypeKind))
+ {
+ AdjustSign(func, &value, 0, 0);
+ }
+ return jit_insn_convert(func, value,
targetType, overflowCheck);
+ }
+ if(_JIT_TYPEKIND_IS_INT(sourceTypeKind))
+ {
+ int sourceIsSigned =
_JIT_TYPEKIND_IS_SIGNED(sourceTypeKind);
+ int targetIsSigned =
_JIT_TYPEKIND_IS_SIGNED(targetTypeKind);
+ int sourceIsUnsigned =
_JIT_TYPEKIND_IS_UNSIGNED(sourceTypeKind);
+ int targetIsUnsigned =
_JIT_TYPEKIND_IS_UNSIGNED(targetTypeKind);
+
+ if(sourceIsSigned && targetIsSigned)
+ {
+ /* Both values are signed and the
source type is smaller */
+ /* than the target type. So there won't
be an overflow. */
return jit_insn_convert(func, value, targetType, 0);
}
- else
+ else if(sourceIsUnsigned && targetIsUnsigned)
{
- if(_JIT_TYPEKIND_IS_FLOAT(targetTypeKind))
+ int sourceSize =
jit_type_get_size(sourceType);
+
+ if(sourceSize < 4)
{
- value = jit_insn_convert(func, value, targetType, 0);
+ /* We know that the sign bit is
0 on the stack. */
+ /* So we can convert directly
without overflow check. */
+ /* don't know the value of the
sign bit. */
+ return jit_insn_convert(func,
value, targetType, 0);
+ }
+
+ /* TODO */
+ /* This case is problematic right now
because this type */
+ /* of conversion with overflow check
can't be handled */
+ /* correctly with libjit atm. */
+ /* We should make the source value
signed first before */
+ /* the conversion with overflow check
is done. */
+ /* AdjustSign(func, &value, 0, 0); */
+ return jit_insn_convert(func, value,
targetType, overflowCheck);
+ }
+ else if(sourceIsUnsigned && targetIsSigned)
+ {
+ int sourceSize =
jit_type_get_size(sourceType);
+
+ if(sourceSize < 4)
+ {
+ /* The source value is 0
extended to INT32 and then */
+ /* extended to INT64. */
+ /* Because the source value is
less than 4 bytes we */
+ /* know that the sign will be 0
on the 32 bit value */
+ /* and no overflow is possible.
*/
+ return jit_insn_convert(func,
value, targetType, 0);
}
else
{
+ /* Because we don't know the
sign of the 32 bit value we */
+ /* have to convert it to INT32
first. */
+ value = jit_insn_convert(func,
value, _IL_JIT_TYPE_INT32, 0);
+ return jit_insn_convert(func,
value, targetType, overflowCheck);
+ }
+ }
+ else if(sourceIsSigned && targetIsUnsigned)
+ {
+ /* TODO */
+ /* This case is problematic right now
because this type */
+ /* of conversion with overflow check
can't be handled */
+ /* correctly with libjit atm. */
+ /* We should make the source value
signed first before */
+ /* the conversion with overflow check
is done. */
+ /* value = jit_insn_convert(func,
value, _IL_JIT_TYPE_INT32, 0); */
+ /* to get the correct result we convert
to UINT32 with */
+ /* overflowCheck instead. */
+ value = jit_insn_convert(func, value,
_IL_JIT_TYPE_UINT32, overflowCheck);
+ return jit_insn_convert(func, value,
targetType, overflowCheck);
+ }
+ }
+ }
+ /* We have to check if the sign has to be adjusted before the
*/
+ /* conversion is done. */
+ if(_JIT_TYPEKIND_IS_UNSIGNED(sourceTypeKind))
+ {
int sourceSize = jit_type_get_size(sourceType);
- int targetSize = jit_type_get_size(targetType);
- if(targetSize <= sourceSize)
+ if(sourceSize >= 4)
{
- /* The value is truncated or the sign is
changed. */
+ /* We have to convert the value to signed first
because we */
+ /* don't know the value of the sign bit. */
+ AdjustSign(func, &value, 0, 0);
+ }
+ }
+ return jit_insn_convert(func, value, targetType, overflowCheck);
}
else
{
- if(_JIT_TYPEKIND_IS_LONG(targetTypeKind))
+ /* We do an unsigned conversion. */
+ sourceTypeKind = jit_type_get_kind(sourceType);
+ targetTypeKind = jit_type_get_kind(targetType);
+ if(_JIT_TYPEKIND_IS_FLOAT(sourceTypeKind))
{
-
if(_JIT_TYPEKIND_IS_SIGNED(targetTypeKind))
+ /* We can convert these values directly */
+ return jit_insn_convert(func, value, targetType,
overflowCheck);
+ }
+ else if(_JIT_TYPEKIND_IS_FLOAT(targetTypeKind))
{
- /* In this case we have to zero
extend unsigned source */
- /* values to the size of an
INT32 first. */
-
if(_JIT_TYPEKIND_IS_UNSIGNED(sourceTypeKind))
+ /* We have to adjust the sign first and sign extend the
source */
+ /* value to at least 4 bytes without overflow check. */
+ if(_JIT_TYPEKIND_IS_SIGNED(sourceTypeKind))
+ {
+ int sourceSize = jit_type_get_size(sourceType);
+
+ if(sourceSize <= 4)
{
- /* We have to zero
extend the value to the */
- /* size an INT32 first.
*/
- /* I assume that
unsigned source values will be */
- /* zero extended to the
target size. */
- value =
jit_insn_convert(func, value,
-
_IL_JIT_TYPE_INT32,
-
0);
+ /* We have to convert the value to
UInt32 first. */
+ value = jit_insn_convert(func, value,
_IL_JIT_TYPE_UINT32, 0);
}
- else
if(_JIT_TYPEKIND_IS_POINTER(sourceTypeKind))
+ else if(sourceSize == 8)
{
- /* Pointers have to be
sign extended in this case. */
- /* So we convert to a
signed NINT first. */
- value =
jit_insn_convert(func, value,
-
_IL_JIT_TYPE_NINT,
-
0);
+ /* We have to convert the value to
UInt64 first. */
+ value = jit_insn_convert(func, value,
_IL_JIT_TYPE_UINT64, 0);
}
}
- else
if(_JIT_TYPEKIND_IS_UNSIGNED(targetTypeKind))
+ return jit_insn_convert(func, value, targetType,
overflowCheck);
+ }
+ else if(_JIT_TYPEKIND_IS_INT(targetTypeKind))
{
-
- /* In this case we have to sign
extend signed source */
- /* values to the size of an
INT32 first. */
+ if(!overflowCheck)
+ {
+ /* We can convert this directly directly
because the source value is */
+ /* either truncated or expanded to the target
type depending on the */
+ /* sign of the source value. */
+ return jit_insn_convert(func, value,
targetType, 0);
+ }
+ else
+ {
+ /* We have to adjust the sign first and sign
extend the source */
+ /* value to at least 4 bytes without overflow
check. */
if(_JIT_TYPEKIND_IS_SIGNED(sourceTypeKind))
{
- /* We have to sign
extend the value to the */
- /* size an INT32 first.
*/
- /* I assume that signed
source values will be */
- /* sign extended to the
target size. */
- value =
jit_insn_convert(func, value,
-
_IL_JIT_TYPE_UINT32,
-
0);
- }
- else
if(_JIT_TYPEKIND_IS_POINTER(sourceTypeKind))
- {
- /* Pointers have to be
zero extended in this case. */
- /* So we convert to a
unsigned NUINT first. */
- value =
jit_insn_convert(func, value,
-
_IL_JIT_TYPE_NUINT,
-
0);
+ int sourceSize =
jit_type_get_size(sourceType);
+
+ if(sourceSize <= 4)
+ {
+ /* We have to convert the value
to UInt32 first. */
+ value = jit_insn_convert(func,
value, _IL_JIT_TYPE_UINT32, 0);
+ }
+ else if(sourceSize == 8)
+ {
+ /* We have to convert the value
to UInt64 first. */
+ value = jit_insn_convert(func,
value, _IL_JIT_TYPE_UINT64, 0);
}
}
-#ifdef IL_NATIVE_INT64
- else
if(_JIT_TYPEKIND_IS_POINTER(targetTypeKind))
+ return jit_insn_convert(func, value,
targetType, overflowCheck);
+ }
+ }
+ else if(_JIT_TYPEKIND_IS_LONG(targetTypeKind))
+ {
+ if(_JIT_TYPEKIND_IS_LONG(sourceTypeKind))
{
- /* This is not allowed in
explicit conversion. */
- /* But we treat pointers like
unsigned values. */
+ if(!overflowCheck)
+ {
+ /* we can convert this directly because
only the sign is changed. */
+ return jit_insn_convert(func, value,
targetType, 0);
+ }
+ else
+ {
+ /* We have to adjust the sign of the
source value first. */
if(_JIT_TYPEKIND_IS_SIGNED(sourceTypeKind))
{
- AdjustSign(func,
&value, 1, 0);
+ /* We have to convert the value
to UInt64 first. */
+ value = jit_insn_convert(func,
value, _IL_JIT_TYPE_UINT64, 0);
+ }
+ return jit_insn_convert(func, value,
targetType, overflowCheck);
}
}
-#endif
+ if(_JIT_TYPEKIND_IS_INT(sourceTypeKind))
+ {
+ int sourceIsSigned =
_JIT_TYPEKIND_IS_SIGNED(sourceTypeKind);
+ int targetIsSigned =
_JIT_TYPEKIND_IS_SIGNED(targetTypeKind);
+ int sourceIsUnsigned =
_JIT_TYPEKIND_IS_UNSIGNED(sourceTypeKind);
+ int targetIsUnsigned =
_JIT_TYPEKIND_IS_UNSIGNED(targetTypeKind);
+
+ if(sourceIsSigned && targetIsSigned)
+ {
+ if(!overflowCheck)
+ {
+ /* The signs match so we can
convert directly. */
+ return jit_insn_convert(func,
value, targetType, 0);
}
else
{
- /* The value would have been zero- or
sign extended to */
- /* the size of an INT32 depending on
the signedness of */
- /* the value. Now we have the less or
the same size so */
- /* we can safely simply convert to the
target type. */
+ /* We have to adjust the sign
and sign extend the */
+ /* source value first to 4
bytes. */
+ value = jit_insn_convert(func,
value, _IL_JIT_TYPE_UINT32, overflowCheck);
+ return jit_insn_convert(func,
value, targetType, overflowCheck);
}
}
- value = jit_insn_convert(func, value, targetType, 0);
+ else if (sourceIsUnsigned && targetIsUnsigned)
+ {
+ /* The signs match so we can convert
directly without overflow check. */
+ return jit_insn_convert(func, value,
targetType, 0);
+ }
+ else if(sourceIsUnsigned && targetIsSigned)
+ {
+ int sourceSize =
jit_type_get_size(sourceType);
+
+ if(sourceSize < 4)
+ {
+ /* The source value is 0
extended to INT32 and then */
+ /* extended to INT64. */
+ /* Because the source value is
less than 4 bytes we */
+ /* know that the sign will be 0
on the 32 bit value. */
+ return jit_insn_convert(func,
value, targetType, 0);
+ }
+ else
+ {
+ /* Because we don't know the
sign of the 32 bit */
+ /* value we have to convert it
to INT32 first. */
+ value = jit_insn_convert(func,
value, _IL_JIT_TYPE_INT32, overflowCheck);
+ /* Because the signed value
will be extended we */
+ /* don't have to check for
overflow now. */
+ return jit_insn_convert(func,
value, targetType, 0);
}
}
+ else if(sourceIsSigned && targetIsUnsigned)
+ {
+ /* In this case we'll allways have to
do two conversions. */
+ /* We have to convert it to UINT32
without overflow check */
+ /* first. */
+ value = jit_insn_convert(func, value,
_IL_JIT_TYPE_UINT32, 0);
+ return jit_insn_convert(func, value,
targetType, 0);
+ }
+ }
+ }
+ /* We have to adjust the sign first and sign extend the source
*/
+ /* value to at least 4 bytes without overflow check. */
+ if(_JIT_TYPEKIND_IS_SIGNED(sourceTypeKind))
+ {
+ int sourceSize = jit_type_get_size(sourceType);
+
+ if(sourceSize <= 4)
+ {
+ /* We have to convert the value to UInt32
first. */
+ value = jit_insn_convert(func, value,
_IL_JIT_TYPE_UINT32, 0);
+ }
+ else if(sourceSize == 8)
+ {
+ /* We have to convert the value to UInt64
first. */
+ value = jit_insn_convert(func, value,
_IL_JIT_TYPE_UINT64, 0);
+ }
+ }
+ return jit_insn_convert(func, value, targetType, 0);
+ }
return value;
}
@@ -991,119 +1164,77 @@
* Readjust the stack to normalize binary operands when
* I and I4 are mixed together. Also determine which of
* I4 or I8 to use if the operation involves I.
+ * The verifier makes sure that no invalid combinations are on the stack.
+ * That means:
+ * 1. If one value is a pointer then the second one is a pointer too.
+ * 2. If one value is a float then the second one is a float too.
*/
static void AdjustMixedBinary(ILJITCoder *coder, int isUnsigned,
ILJitValue *value1,
ILJitValue *value2)
{
ILJitType type1 = jit_value_get_type(*value1);
- ILJitType newType1 = _ILJitTypeToStackType(type1);
ILJitType type2 = jit_value_get_type(*value2);
- ILJitType newType2 = _ILJitTypeToStackType(type2);
- int type1Kind = jit_type_get_kind(newType1);
- int type2Kind = jit_type_get_kind(newType2);
+ ILJitType newType = 0;
+ int type1Kind = jit_type_get_kind(type1);
+ int type2Kind = jit_type_get_kind(type2);
int type1IsFloat = _JIT_TYPEKIND_IS_FLOAT(type1Kind);
int type2IsFloat = _JIT_TYPEKIND_IS_FLOAT(type2Kind);
+ int type1IsPointer = _JIT_TYPEKIND_IS_POINTER(type1Kind);
+ int type2IsPointer = _JIT_TYPEKIND_IS_POINTER(type2Kind);
int type1IsLong = _JIT_TYPEKIND_IS_LONG(type1Kind);
int type2IsLong = _JIT_TYPEKIND_IS_LONG(type2Kind);
if(type1IsFloat || type2IsFloat)
{
+ /* Nothing to do here. */
return;
}
-
- /* If the arguments mix I8 and I4, then cast the I4 value to I8 */
- if(type1IsLong && !type2IsLong)
+ else if(type1IsLong || type2IsLong)
{
+ /* If the arguments mix I8 and I4, then cast the I4 value to I8
*/
if(isUnsigned)
{
- newType2 = _IL_JIT_TYPE_UINT64;
+ newType = _IL_JIT_TYPE_UINT64;
}
else
{
- newType2 = _IL_JIT_TYPE_INT64;
+ newType = _IL_JIT_TYPE_INT64;
}
- type2Kind = jit_type_get_kind(newType2);
- type2IsLong = 1;
}
- else if(!type1IsLong && type2IsLong)
+ else if(!type1IsPointer || type2IsPointer)
{
if(isUnsigned)
{
- newType1 = _IL_JIT_TYPE_UINT64;
+ newType = _IL_JIT_TYPE_NUINT;
}
else
{
- newType1 = _IL_JIT_TYPE_INT64;
- }
- type1Kind = jit_type_get_kind(newType1);
- type1IsLong = 1;
- }
-
- if(isUnsigned)
- {
- if(_JIT_TYPEKIND_IS_SIGNED(type1Kind))
- {
- if(type1IsLong)
- {
- newType1 = _IL_JIT_TYPE_UINT64;
- }
- else
- {
- newType1 = _IL_JIT_TYPE_UINT32;
- }
- type1Kind = jit_type_get_kind(newType1);
- }
- if(_JIT_TYPEKIND_IS_SIGNED(type2Kind))
- {
- if(type2IsLong)
- {
- newType2 = _IL_JIT_TYPE_UINT64;
- }
- else
- {
- newType2 = _IL_JIT_TYPE_UINT32;
- }
- type2Kind = jit_type_get_kind(newType2);
+ newType = _IL_JIT_TYPE_NINT;
}
}
else
{
- if(_JIT_TYPEKIND_IS_UNSIGNED(type1Kind))
- {
- if(type1IsLong)
- {
- newType1 = _IL_JIT_TYPE_INT64;
- }
- else
- {
- newType1 = _IL_JIT_TYPE_INT32;
- }
- type1Kind = jit_type_get_kind(newType1);
- }
- if(_JIT_TYPEKIND_IS_UNSIGNED(type2Kind))
- {
- if(type2IsLong)
+ /* We have only 32 bit values left. */
+ if(isUnsigned)
{
- newType2 = _IL_JIT_TYPE_INT64;
+ newType = _IL_JIT_TYPE_UINT32;
}
else
{
- newType2 = _IL_JIT_TYPE_INT32;
- }
- type2Kind = jit_type_get_kind(newType2);
+ newType = _IL_JIT_TYPE_INT32;
}
}
/* now do the conversion if necessairy. */
- if(type1 != newType1)
+ if(type1 != newType)
{
*value1 = _ILJitValueConvertImplicit(coder->jitFunction,
*value1,
-
newType1);
+
newType);
}
- if(type2 != newType2)
+ if(type2 != newType)
{
*value2 = _ILJitValueConvertImplicit(coder->jitFunction,
*value2,
-
newType2);
+
newType);
}
}
@@ -2808,8 +2939,15 @@
{
jitParamTypes[param] = paramType;
#ifdef IL_JIT_THREAD_IN_SIGNATURE
+ args[current - 1] =
_ILJitValueConvertImplicit(func,
+
args[current - 1],
+
paramType);
jitParams[param] = args[current - 1];
+
#else
+ args[current] = _ILJitValueConvertImplicit(func,
+
args[current],
+
paramType);
jitParams[param] = args[current];
#endif
}
@@ -3009,6 +3147,10 @@
int isCtor = ILMethodIsConstructor(method);
/* Some infos that we'll need later. */
ILClass *info = ILMethod_Owner(method);
+#ifdef IL_CONFIG_VARARGS
+ /* Flag to check if this is an internal vararg method. */
+ ILInt32 isInternalVararg = 0;
+#endif
if(ILType_HasThis(signature))
{
@@ -3031,6 +3173,26 @@
}
}
+#ifdef IL_CONFIG_VARARGS
+ /* Vararg methods implemented in the engine have an additional argument
*/
+ /* of type void * which must be added to the jit signature. */
+ if((ILType_CallConv(signature) & IL_META_CALLCONV_MASK) ==
+ IL_META_CALLCONV_VARARG)
+ {
+ if((implementationType & _IL_JIT_IMPL_INTERNALMASK) != 0)
+ {
+ total++;
+ isInternalVararg = 1;
+ }
+ else
+ {
+ /* Methods not implemented internal must have the
vararg calling */
+ /* convertion. */
+ jitAbi = IL_JIT_CALLCONV_VARARG;
+ }
+ }
+#endif
+
/* Array to hold the parameter types. */
ILJitType jitArgs[total];
@@ -3088,11 +3250,12 @@
}
#ifdef IL_CONFIG_VARARGS
- /* Vararg methods can have additional arguments not specified in the
signature. */
- if((ILType_CallConv(signature) & IL_META_CALLCONV_MASK) ==
- IL_META_CALLCONV_VARARG)
+ /* If it's an internal vararg method add the pointer to the vararg */
+ /* information. */
+ if(isInternalVararg)
{
- jitAbi = IL_JIT_CALLCONV_VARARG;
+ jitArgs[jitArgc] = _IL_JIT_TYPE_VPTR;
+ jitArgc++;
}
#endif
Index: engine/jitc_arith.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_arith.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- engine/jitc_arith.c 10 Oct 2006 17:10:45 -0000 1.5
+++ engine/jitc_arith.c 12 Oct 2006 16:07:38 -0000 1.6
@@ -274,8 +274,10 @@
{
case IL_OP_SHL:
{
- AdjustSign(jitCoder->jitFunction,
- &(_ILJitStackItemValue(value1)), 0,
0);
+ AdjustMixedBinary(jitCoder,
+ 0,
+
&(_ILJitStackItemValue(value1)),
+
&(_ILJitStackItemValue(value2)));
result = jit_insn_shl(jitCoder->jitFunction,
_ILJitStackItemValue(value1),
_ILJitStackItemValue(value2));
@@ -284,8 +286,10 @@
case IL_OP_SHR:
{
- AdjustSign(jitCoder->jitFunction,
- &(_ILJitStackItemValue(value1)), 0,
0);
+ AdjustMixedBinary(jitCoder,
+ 0,
+
&(_ILJitStackItemValue(value1)),
+
&(_ILJitStackItemValue(value2)));
result= jit_insn_shr(jitCoder->jitFunction,
_ILJitStackItemValue(value1),
_ILJitStackItemValue(value2));
@@ -294,8 +298,10 @@
case IL_OP_SHR_UN:
{
- AdjustSign(jitCoder->jitFunction,
- &(_ILJitStackItemValue(value1)), 1,
0);
+ AdjustMixedBinary(jitCoder,
+ 1,
+
&(_ILJitStackItemValue(value1)),
+
&(_ILJitStackItemValue(value2)));
result = jit_insn_shr(jitCoder->jitFunction,
_ILJitStackItemValue(value1),
_ILJitStackItemValue(value2));
Index: engine/jitc_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_call.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- engine/jitc_call.c 10 Oct 2006 17:10:45 -0000 1.27
+++ engine/jitc_call.c 12 Oct 2006 16:07:38 -0000 1.28
@@ -21,20 +21,72 @@
#ifdef IL_JITC_CODE
/*
+ * Get the call signature from the methodInfo or the ILCoderMethoInfo.
+ * If the value returned is != 0 then the signature must be destroyed after
+ * the call is done.
+ */
+static ILInt32 _ILJitGetCallSignature(ILJITCoder *coder,
+
ILMethod *method,
+
ILCoderMethodInfo *info,
+
ILJitType *signature)
+{
+ if(method)
+ {
+ ILJitFunction func = ILJitFunctionFromILMethod(method);
+
+ if(!func)
+ {
+ *signature = _ILJitCreateMethodSignature(coder, method,
0);
+ return 1;
+ }
+ else
+ {
+ *signature = jit_function_get_signature(func);
+ return 0;
+ }
+ }
+ return 0;
+}
+
+/*
* Fill the argument array for the methodcall with the args on the stack.
* This function pops the arguments off the stack too.
+ * The signature is filled with the call signature.
+ * If the value returned is != 0 then the signature must be destroyed after
+ * the call is done.
*/
-static void _ILJitFillArguments(ILJITCoder *coder, ILJitValue *args,
-
ILCoderMethodInfo *info)
+static ILInt32 _ILJitFillArguments(ILJITCoder *coder,
+ ILMethod
*method,
+
ILCoderMethodInfo *info,
+ ILJitValue
*args,
+ ILInt32
startParam,
+ ILJitType
*signature)
{
int argCount = _ILJitStackNumArgs(info);
ILJitStackItem *stackItems = _ILJitStackItemGetAndPop(coder, argCount);
+ ILInt32 returnValue = _ILJitGetCallSignature(coder,
+
method,
+
info,
+
signature);
int current = 0;
+ int numJitParams = jit_type_num_params(*signature);
+ ILJitType paramType;
+ ILJitValue value;
+ if(numJitParams != (startParam + argCount))
+ {
+ printf("Argument count mismatch!\n");
+ }
for(current = 0; current < argCount; current++)
{
- args[current] = _ILJitStackItemValue(stackItems[current]);
+ _ILJitStackHandleCallByRefArg(coder, stackItems[current]);
+ paramType = jit_type_get_param(*signature, startParam +
current);
+ value = _ILJitValueConvertImplicit(coder->jitFunction,
+
_ILJitStackItemValue(stackItems[current]),
+
paramType);
+ args[current] = value;
}
+ return returnValue;
}
/*
@@ -581,6 +633,8 @@
int argCount = _ILJitStackNumArgs(info);
ILJitValue jitParams[argCount + 2];
ILJitValue returnValue;
+ ILJitType callSignature = 0;
+ int destroyCallSignature = 0;
char *methodName = 0;
ILInternalInfo fnInfo;
ILJitInlineFunc inlineFunc = 0;
@@ -656,7 +710,21 @@
#endif
/* Call the engine function directly with the supplied args. */
- _ILJitFillArguments(jitCoder, jitParams, info);
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
jitParams,
+
1,
+
&callSignature);
+ #else
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
jitParams,
+
0,
+
&callSignature);
+ #endif
returnValue = _ILJitCallInternal(jitCoder->jitFunction, thread,
methodInfo,
fnInfo.func, methodName,
@@ -666,6 +734,10 @@
{
_ILJitStackPushValue(jitCoder, returnValue);
}
+ if(destroyCallSignature && callSignature)
+ {
+ jit_type_free(callSignature);
+ }
return;
}
@@ -673,9 +745,19 @@
/* Set the ILExecThread argument. */
jitParams[0] = _ILJitCoderGetThread(jitCoder);
- _ILJitFillArguments(jitCoder, &(jitParams[1]), info);
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
&(jitParams[1]),
+
1,
+
&callSignature);
#else
- _ILJitFillArguments(jitCoder, &(jitParams[0]), info);
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
&(jitParams[0]),
+
0,
+
&callSignature);
#endif
/* TODO: create call signature for vararg calls. */
@@ -729,6 +811,10 @@
_ILJitStackPushValue(jitCoder, returnValue);
}
}
+ if(destroyCallSignature && callSignature)
+ {
+ jit_type_free(callSignature);
+ }
}
static void JITCoder_CallIndirect(ILCoder *coder, ILCoderMethodInfo *info,
@@ -771,6 +857,8 @@
ILType *synType;
ILJitFunction jitFunction = ILJitFunctionFromILMethod(methodInfo);
int argCount = _ILJitStackNumArgs(info);
+ ILJitType callSignature = 0;
+ int destroyCallSignature = 0;
ILJitValue jitParams[argCount + 2];
ILJitValue returnValue;
ILInternalInfo fnInfo;
@@ -832,7 +920,21 @@
if(internalType == _IL_JIT_IMPL_INTERNALALLOC)
{
/* This is an allocating constructor. */
- _ILJitFillArguments(jitCoder, jitParams, info);
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
jitParams,
+
1,
+
&callSignature);
+ #else
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
jitParams,
+
0,
+
&callSignature);
+ #endif
returnValue = _ILJitCallInternal(jitCoder->jitFunction,
thread,
methodInfo,
fnInfo.func, methodName,
@@ -844,7 +946,12 @@
{
/* create a newobj and add it to the jitParams[0]. */
_ILJitNewObj(jitCoder, ILMethod_Owner(methodInfo),
&jitParams[0]);
- _ILJitFillArguments(jitCoder, &(jitParams[1]), info);
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
&(jitParams[1]),
+
1,
+
&callSignature);
returnValue = _ILJitCallInternal(jitCoder->jitFunction,
thread,
methodInfo,
@@ -852,6 +959,10 @@
jitParams, argCount + 1);
_ILJitStackPushNotNullValue(jitCoder, jitParams[0]);
}
+ if(destroyCallSignature && callSignature)
+ {
+ jit_type_free(callSignature);
+ }
return;
}
@@ -862,12 +973,22 @@
if((synType && ILType_IsArray(synType)) || ILTypeIsStringClass(type))
{
#ifdef IL_JIT_THREAD_IN_SIGNATURE
- _ILJitFillArguments(jitCoder, &(jitParams[1]), info);
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
&(jitParams[1]),
+
1,
+
&callSignature);
// call the constructor with jitParams as input
returnValue = jit_insn_call(jitCoder->jitFunction, 0,
jitFunction, 0,
jitParams, argCount + 1, 0);
#else
- _ILJitFillArguments(jitCoder, &(jitParams[0]), info);
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
&(jitParams[0]),
+
0,
+
&callSignature);
// call the constructor with jitParams as input
returnValue = jit_insn_call(jitCoder->jitFunction, 0,
jitFunction, 0,
jitParams, argCount, 0);
@@ -879,7 +1000,12 @@
#ifdef IL_JIT_THREAD_IN_SIGNATURE
/* create a newobj and add it to the jitParams[1]. */
_ILJitNewObj(jitCoder, ILMethod_Owner(methodInfo),
&jitParams[1]);
- _ILJitFillArguments(jitCoder, &(jitParams[2]), info);
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
&(jitParams[2]),
+
2,
+
&callSignature);
// call the constructor with jitParams as input
returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
@@ -890,7 +1016,12 @@
#else
/* create a newobj and add it to the jitParams[0]. */
_ILJitNewObj(jitCoder, ILMethod_Owner(methodInfo),
&jitParams[0]);
- _ILJitFillArguments(jitCoder, &(jitParams[1]), info);
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
&(jitParams[1]),
+
1,
+
&callSignature);
// call the constructor with jitParams as input
returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
@@ -900,6 +1031,10 @@
_ILJitStackPushNotNullValue(jitCoder, jitParams[0]);
#endif
}
+ if(destroyCallSignature && callSignature)
+ {
+ jit_type_free(callSignature);
+ }
}
static void JITCoder_CallVirtual(ILCoder *coder, ILCoderMethodInfo *info,
@@ -911,6 +1046,7 @@
int argCount = info->numBaseArgs + info->numVarArgs;
ILJitFunction func = ILJitFunctionFromILMethod(methodInfo);
ILJitType signature;
+ int destroyCallSignature = 0;
ILJitValue jitParams[argCount + 1];
ILJitValue returnValue;
ILJitValue jitFunction;
@@ -938,42 +1074,42 @@
func = ILJitFunctionFromILMethod(methodInfo);
}
- if(!func)
- {
- signature = _ILJitCreateMethodSignature(jitCoder, methodInfo,
0);
- }
- else
- {
- signature = jit_function_get_signature(func);
- }
-#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) &&
defined(_IL_JIT_ENABLE_DEBUG)
- if (jitCoder->flags & IL_CODER_FLAG_STATS)
- {
- ILMutexLock(globalTraceMutex);
- fprintf(stdout,
- "CallInfos: StackTop: %i, ArgCount: %i, Signature
argCount: %i\n",
- jitCoder->stackTop,
- argCount,
- jit_type_num_params(signature));
- ILMutexUnlock(globalTraceMutex);
- }
-#endif
#ifdef IL_JIT_THREAD_IN_SIGNATURE
jitParams[0] = _ILJitCoderGetThread(jitCoder);
- _ILJitFillArguments(jitCoder, &(jitParams[1]), info);
- /* TODO: handle varargs here and create a call signature. */
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
&(jitParams[1]),
+
1,
+
&signature);
jitFunction = _ILJitGetVirtualFunction(jitCoder,
_ILJitStackItemGetTop(jitCoder, -1),
methodInfo->index);
#else
- _ILJitFillArguments(jitCoder, &(jitParams[0]), info);
- /* TODO: handle varargs here and create a call signature. */
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
&(jitParams[0]),
+
0,
+
&signature);
jitFunction = _ILJitGetVirtualFunction(jitCoder,
_ILJitStackItemGetTop(jitCoder, -1),
methodInfo->index);
#endif
+#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) &&
defined(_IL_JIT_ENABLE_DEBUG)
+ if (jitCoder->flags & IL_CODER_FLAG_STATS)
+ {
+ ILMutexLock(globalTraceMutex);
+ fprintf(stdout,
+ "CallInfos: StackTop: %i, ArgCount: %i, Signature
argCount: %i\n",
+ jitCoder->stackTop,
+ argCount,
+ jit_type_num_params(signature));
+ ILMutexUnlock(globalTraceMutex);
+ }
+#endif
if(info->tailCall == 1)
{
#ifdef IL_JIT_THREAD_IN_SIGNATURE
@@ -1006,6 +1142,10 @@
{
_ILJitStackPushValue(jitCoder, returnValue);
}
+ if(destroyCallSignature && signature)
+ {
+ jit_type_free(signature);
+ }
}
static void JITCoder_CallInterface(ILCoder *coder, ILCoderMethodInfo *info,
@@ -1014,21 +1154,13 @@
{
ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
int argCount = info->numBaseArgs + info->numVarArgs;
- ILJitFunction func = ILJitFunctionFromILMethod(methodInfo);
- ILJitType signature;
+ ILJitType signature = 0;
+ int destroyCallSignature = 0;
ILJitValue jitParams[argCount + 1];
ILJitValue returnValue;
ILJitValue jitFunction;
jit_label_t label = jit_label_undefined;
- if(!func)
- {
- signature = _ILJitCreateMethodSignature(jitCoder, methodInfo,
0);
- }
- else
- {
- signature = jit_function_get_signature(func);
- }
#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS)
if (jitCoder->flags & IL_CODER_FLAG_STATS)
{
@@ -1040,37 +1172,45 @@
methodInfo->index);
ILMutexUnlock(globalTraceMutex);
}
-#if defined(_IL_JIT_ENABLE_DEBUG)
- if (jitCoder->flags & IL_CODER_FLAG_STATS)
- {
- ILMutexLock(globalTraceMutex);
- fprintf(stdout,
- "CallInfos: StackTop: %i, ArgCount: %i, Signature
argCount: %i\n",
- jitCoder->stackTop,
- argCount,
- jit_type_num_params(signature));
- ILMutexUnlock(globalTraceMutex);
- }
-#endif
#endif
#ifdef IL_JIT_THREAD_IN_SIGNATURE
jitParams[0] = _ILJitCoderGetThread(jitCoder);
- _ILJitFillArguments(jitCoder, &(jitParams[1]), info);
- /* TODO: handle varargs here and create a call signature. */
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
&(jitParams[1]),
+
1,
+
&signature);
jitFunction = _ILJitGetInterfaceFunction(jitCoder,
_ILJitStackItemGetTop(jitCoder, -1),
methodInfo->member.owner,
methodInfo->index);
#else
- _ILJitFillArguments(jitCoder, &(jitParams[0]), info);
- /* TODO: handle varargs here and create a call signature. */
+ destroyCallSignature = _ILJitFillArguments(jitCoder,
+
methodInfo,
+
info,
+
&(jitParams[0]),
+
0,
+
&signature);
jitFunction = _ILJitGetInterfaceFunction(jitCoder,
_ILJitStackItemGetTop(jitCoder, -1),
methodInfo->member.owner,
methodInfo->index);
#endif
+#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) &&
defined(_IL_JIT_ENABLE_DEBUG)
+ if (jitCoder->flags & IL_CODER_FLAG_STATS)
+ {
+ ILMutexLock(globalTraceMutex);
+ fprintf(stdout,
+ "CallInfos: StackTop: %i, ArgCount: %i, Signature
argCount: %i\n",
+ jitCoder->stackTop,
+ argCount,
+ jit_type_num_params(signature));
+ ILMutexUnlock(globalTraceMutex);
+ }
+#endif
jit_insn_branch_if(jitCoder->jitFunction, jitFunction, &label);
/* TODO: raise a MissingMethodException here. */
@@ -1107,6 +1247,10 @@
{
_ILJitStackPushValue(jitCoder, returnValue);
}
+ if(destroyCallSignature && signature)
+ {
+ jit_type_free(signature);
+ }
}
static int JITCoder_CallInlineable(ILCoder *coder, int inlineType,
@@ -1651,11 +1795,17 @@
}
else
{
+ ILJitType signature =
jit_function_get_signature(jitCoder->jitFunction);
+ ILJitType returnType = jit_type_get_return(signature);
_ILJitStackItemNew(value);
+ ILJitValue returnValue;
_ILJitStackPop(jitCoder, value);
+ returnValue = _ILJitValueConvertImplicit(jitCoder->jitFunction,
+
_ILJitStackItemValue(value),
+
returnType);
jit_insn_return(jitCoder->jitFunction,
- _ILJitStackItemValue(value));
+ returnValue);
}
}
Index: engine/jitc_const.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_const.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- engine/jitc_const.c 10 Oct 2006 17:10:45 -0000 1.7
+++ engine/jitc_const.c 12 Oct 2006 16:07:38 -0000 1.8
@@ -31,7 +31,7 @@
if(opcode == IL_OP_LDNULL)
{
value = jit_value_create_nint_constant(jitCoder->jitFunction,
-
jit_type_void_ptr,
+
_IL_JIT_TYPE_VPTR,
(jit_nint)0);
_ILJitStackPushValue(jitCoder, value);
}
Index: engine/jitc_ptr.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_ptr.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- engine/jitc_ptr.c 10 Oct 2006 17:10:45 -0000 1.14
+++ engine/jitc_ptr.c 12 Oct 2006 16:07:38 -0000 1.15
@@ -36,7 +36,7 @@
ILJitValue len;
len = jit_insn_load_relative(coder->jitFunction, array, 0,
-
_IL_JIT_TYPE_UINT32);
+
_IL_JIT_TYPE_INT32);
return len;
}
Index: engine/jitc_stack.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_stack.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- engine/jitc_stack.c 10 Oct 2006 17:10:45 -0000 1.8
+++ engine/jitc_stack.c 12 Oct 2006 16:07:38 -0000 1.9
@@ -273,10 +273,7 @@
if(((coder)->jitStack[__stackPos].refValue ==
(localSlot)) && \
((coder)->jitStack[__stackPos].flags &
_IL_JIT_VALUE_COPYOF)) \
{ \
- if(!__dupValue) \
- { \
- __dupValue =
jit_insn_dup((coder)->jitFunction, ILJitLocalSlotValue(*localSlot)); \
- } \
+ __dupValue = jit_insn_dup((coder)->jitFunction,
(coder)->jitStack[__stackPos].value); \
(coder)->jitStack[__stackPos].value =
__dupValue; \
(coder)->jitStack[__stackPos].refValue = 0; \
(coder)->jitStack[__stackPos].flags |=
~_IL_JIT_VALUE_COPYOF; \
@@ -285,6 +282,34 @@
} while(0)
/*
+ * Flag all occurances of the value (v) null checked on the stack.
+ */
+#define _ILJitStackSetNullChecked(coder, v) \
+ do { \
+ ILInt32 __stackTop = (coder)->stackTop; \
+ ILInt32 __stackPos ; \
+ for(__stackPos = 0; __stackPos < __stackTop; ++__stackPos) \
+ { \
+ if((coder)->jitStack[__stackPos].value == (v)) \
+ { \
+ (coder)->jitStack[__stackPos].flags |=
_IL_JIT_VALUE_NULLCHECKED; \
+ } \
+ } \
+ } while(0)
+
+/*
+ * Take the actions needed to preserve items on the stack from changing if the
+ * value this stackitem points to is modified during a call.
+ */
+#define _ILJitStackHandleCallByRefArg(coder, stackItem) \
+ do { \
+ if((stackItem).refValue && ((stackItem).flags &
_IL_JIT_VALUE_POINTER_TO)) \
+ { \
+ _ILJitStackDupLocal(coder, (stackItem).refValue); \
+ } \
+ } while(0)
+
+/*
* Check if the stack item has to be duplicated on the first invokation of
* a label.
*/
@@ -477,6 +502,7 @@
{ \
((stackItem).refValue)->flags |=
_IL_JIT_VALUE_NULLCHECKED; \
} \
+ _ILJitStackSetNullChecked(coder,
_ILJitStackItemValue(stackItem)); \
} \
} while(0)
@@ -509,6 +535,19 @@
#define _ILJitStackItemNeedsDupOnLabel(stackItem) (0)
/*
+ * Flag all occurances of the value (v) null checked on the stack.
+ * This is a NOP without optimizations enabled.
+ */
+#define _ILJitStackSetNullChecked(coder, v)
+
+/*
+ * Take the actions needed to preserve items on the stack from changing if the
+ * value this stackitem points to is modified during a call.
+ * This is a NOP without optimizations enabled.
+ */
+#define _ILJitStackHandleCallByRefArg(coder, stackItem)
+
+/*
* Set the value in a stack item.
* The only change allowed for the value are type cnversions.
*/
- [dotgnu-pnet-commits] pnet ChangeLog engine/jitc.c engine/jitc_arith....,
Klaus Treichel <=