bug fix #699
This commit is contained in:
parent
6400880643
commit
1fe7c18640
|
|
@ -55,6 +55,7 @@ namespace PascalABCCompiler.NETGenerator
|
|||
private static Hashtable types;
|
||||
private static Hashtable sizes;
|
||||
public static MethodInfo ArrayCopyMethod;
|
||||
public static MethodInfo GetTypeFromHandleMethod;
|
||||
public static MethodInfo ResizeMethod;
|
||||
public static MethodInfo GCHandleFreeMethod;
|
||||
public static MethodInfo StringNullOrEmptyMethod;
|
||||
|
|
@ -120,6 +121,7 @@ namespace PascalABCCompiler.NETGenerator
|
|||
IndexOutOfRangeConstructor = typeof(IndexOutOfRangeException).GetConstructor(Type.EmptyTypes);
|
||||
ParamArrayAttributeConstructor = typeof(ParamArrayAttribute).GetConstructor(Type.EmptyTypes);
|
||||
GCHandleFreeMethod = typeof(GCHandle).GetMethod("Free");
|
||||
GetTypeFromHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle");
|
||||
}
|
||||
|
||||
public static bool IsStandType(Type t)
|
||||
|
|
@ -421,7 +423,7 @@ namespace PascalABCCompiler.NETGenerator
|
|||
|
||||
public static void PushCast(ILGenerator il, Type tp, Type from_value_type)
|
||||
{
|
||||
if (IsPointer(tp)) //INTPTR TODO Здесть проблема с Unbox_Any
|
||||
if (IsPointer(tp))
|
||||
return;
|
||||
//(ssyy) Вставил 15.05.08
|
||||
if (from_value_type != null)
|
||||
|
|
@ -521,7 +523,6 @@ namespace PascalABCCompiler.NETGenerator
|
|||
{
|
||||
ILGenerator il = clone_meth.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldloca_S, (byte)0);
|
||||
//il.Emit(OpCodes.Ldarga_S,(byte)0);
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
if (ti.clone_meth != null)
|
||||
{
|
||||
|
|
@ -541,8 +542,6 @@ namespace PascalABCCompiler.NETGenerator
|
|||
public static void AssignField(MethodBuilder ass_meth, FieldBuilder fb, TypeInfo ti)
|
||||
{
|
||||
ILGenerator il = ass_meth.GetILGenerator();
|
||||
//il.Emit(OpCodes.Ldarga_S, (byte)0);
|
||||
//il.Emit(OpCodes.Ldarga_S, (byte)1);
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarga_S, (byte)1);
|
||||
if (ti.clone_meth != null)
|
||||
|
|
@ -563,8 +562,7 @@ namespace PascalABCCompiler.NETGenerator
|
|||
public static void PushTypeOf(ILGenerator il, Type tp)
|
||||
{
|
||||
il.Emit(OpCodes.Ldtoken, tp);
|
||||
//TODO это надо ускорить хештаблицей!
|
||||
il.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);
|
||||
il.EmitCall(OpCodes.Call, TypeFactory.GetTypeFromHandleMethod, null);
|
||||
}
|
||||
|
||||
public static bool IsPointer(Type tp)
|
||||
|
|
|
|||
|
|
@ -6739,7 +6739,7 @@ namespace PascalABCCompiler.NETGenerator
|
|||
//DarkStar Fixed: type t:=i.gettype();
|
||||
bool _box = value.obj.type.is_value_type && !value.compiled_method.method_info.DeclaringType.IsValueType;
|
||||
if (!_box && value.obj.conversion_type != null)
|
||||
_box = value.obj.conversion_type != null && value.obj.conversion_type.is_value_type;
|
||||
_box = value.obj.conversion_type.is_value_type;
|
||||
if (_box)
|
||||
is_dot_expr = false;
|
||||
value.obj.visit(this);
|
||||
|
|
@ -6757,21 +6757,14 @@ namespace PascalABCCompiler.NETGenerator
|
|||
{
|
||||
il.Emit(OpCodes.Box, helper.GetTypeReference(value.obj.conversion_type).tp);
|
||||
}
|
||||
else if (_box && value.obj.type.is_value_type)
|
||||
{
|
||||
LocalBuilder lb = il.DeclareLocal(helper.GetTypeReference(value.obj.type).tp);
|
||||
il.Emit(OpCodes.Stloc, lb);
|
||||
il.Emit(OpCodes.Ldloca, lb);
|
||||
}
|
||||
is_dot_expr = false;
|
||||
EmitArguments(parameters, real_parameters);
|
||||
/*for (int i = 0; i < real_parameters.Length; i++)
|
||||
{
|
||||
if (parameters[i].parameter_type == parameter_type.var)
|
||||
is_addr = true;
|
||||
real_parameters[i].visit(this);
|
||||
//ICompiledTypeNode ctn = value.real_parameters[i].type as ICompiledTypeNode;
|
||||
ICompiledTypeNode ctn2 = parameters[i].type as ICompiledTypeNode;
|
||||
ITypeNode ctn3 = real_parameters[i].type;
|
||||
if (!(real_parameters[i] is INullConstantNode))
|
||||
if (ctn2 != null && (ctn3.is_value_type || ctn3.is_generic_parameter) && ctn2.compiled_type == TypeFactory.ObjectType)
|
||||
il.Emit(OpCodes.Box, helper.GetTypeReference(ctn3).tp);
|
||||
is_addr = false;
|
||||
}*/
|
||||
MethodInfo mi = value.compiled_method.method_info;
|
||||
if (value.compiled_method.comperehensive_type.is_value_type || !value.virtual_call && value.compiled_method.polymorphic_state == polymorphic_state.ps_virtual || value.compiled_method.polymorphic_state == polymorphic_state.ps_static)
|
||||
{
|
||||
|
|
@ -6916,42 +6909,12 @@ namespace PascalABCCompiler.NETGenerator
|
|||
{
|
||||
il.Emit(OpCodes.Box, helper.GetTypeReference(value.obj.conversion_type).tp);
|
||||
}
|
||||
|
||||
is_dot_expr = false;
|
||||
//bool is_comp_gen = false;
|
||||
//bool need_fee = false;
|
||||
IParameterNode[] parameters = value.method.parameters;
|
||||
EmitArguments(parameters, real_parameters);
|
||||
/*for (int i = 0; i < real_parameters.Length; i++)
|
||||
{
|
||||
if (parameters[i].parameter_type == parameter_type.var)
|
||||
is_addr = true;
|
||||
ITypeNode ctn = real_parameters[i].type;
|
||||
TypeInfo ti = null;
|
||||
|
||||
//(ssyy) moved up
|
||||
ITypeNode tn2 = parameters[i].type;
|
||||
ICompiledTypeNode ctn2 = tn2 as ICompiledTypeNode;
|
||||
ITypeNode ctn3 = real_parameters[i].type;
|
||||
//(ssyy) 07.12.2007 При боксировке нужно вызывать Ldsfld вместо Ldsflda.
|
||||
//Дополнительная проверка введена именно для этого.
|
||||
bool box_awaited =
|
||||
(ctn2 != null && ctn2.compiled_type == TypeFactory.ObjectType || tn2.IsInterface) && (ctn3.is_value_type || ctn3.is_generic_parameter) && !(real_parameters[i] is SemanticTree.INullConstantNode);
|
||||
|
||||
if (!(real_parameters[i] is INullConstantNode))
|
||||
{
|
||||
ti = helper.GetTypeReference(ctn);
|
||||
if (ti.clone_meth != null && ti.tp != null && ti.tp.IsValueType && !box_awaited && !parameters[i].is_const)
|
||||
is_dot_expr = true;
|
||||
}
|
||||
//is_comp_gen = CheckForCompilerGenerated(value.real_parameters[i]);
|
||||
//if (is_comp_gen) need_fee = true;
|
||||
real_parameters[i].visit(this);
|
||||
is_dot_expr = false;
|
||||
CallCloneIfNeed(il, parameters[i], real_parameters[i]);
|
||||
if (box_awaited)
|
||||
il.Emit(OpCodes.Box, helper.GetTypeReference(ctn3).tp);
|
||||
is_addr = false;
|
||||
}*/
|
||||
//вызов метода
|
||||
//(ssyy) Функции размерных типов всегда вызываются через call
|
||||
if (value.method.comperehensive_type.is_value_type || !value.virtual_call && value.method.polymorphic_state == polymorphic_state.ps_virtual || value.method.polymorphic_state == polymorphic_state.ps_static /*|| !value.virtual_call || (value.method.polymorphic_state != polymorphic_state.ps_virtual && value.method.polymorphic_state != polymorphic_state.ps_virtual_abstract && !value.method.common_comprehensive_type.IsInterface)*/)
|
||||
|
|
|
|||
9
TestSuite/boxing3.pas
Normal file
9
TestSuite/boxing3.pas
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
begin
|
||||
var a: BigInteger := 1;
|
||||
var s := byte(a).ToString;
|
||||
var s2 := object(a).ToString;
|
||||
var s3 := BigInteger(1).ToString;
|
||||
assert(s='1');
|
||||
assert(s2='1');
|
||||
assert(s3='1');
|
||||
end.
|
||||
Loading…
Reference in a new issue