bool InvokeOptimizedMethod(IMethod method, MethodInfo mi, MethodInvocationExpression node)
{
if (Array_get_Length == mi)
{
// don't use ldlen for System.Array
if (!GetType(node.Target).IsArray)
return false;
// optimize constructs such as:
// len(anArray)
// anArray.Length
Visit(node.Target);
PopType();
_il.Emit(OpCodes.Ldlen);
PushType(TypeSystemServices.IntType);
return true;
}
if (mi.DeclaringType != Builtins_ArrayTypedConstructor.DeclaringType)
return false;
if (mi.IsGenericMethod)
{
if (Builtins_ArrayGenericConstructor == mi.GetGenericMethodDefinition())
{
// optimize constructs such as:
// array[of int](2)
IType type = method.ConstructedInfo.GenericArguments[0];
EmitNewArray(type, node.Arguments[0]);
return true;
}
if (mi.Name == "matrix")
{
EmitNewMatrix(node);
return true;
}
return false;
}
if (Builtins_ArrayTypedConstructor == mi)
{
// optimize constructs such as:
// array(int, 2)
IType type = TypeSystemServices.GetReferencedType(node.Arguments[0]);
if (null != type)
{
EmitNewArray(type, node.Arguments[1]);
return true;
}
}
else if (Builtins_ArrayTypedCollectionConstructor == mi)
{
// optimize constructs such as:
// array(int, (1, 2, 3))
// array(byte, [1, 2, 3, 4])
IType type = TypeSystemServices.GetReferencedType(node.Arguments[0]);
if (null != type)
{
ListLiteralExpression items = node.Arguments[1] as ListLiteralExpression;
if (null != items)
{
EmitArray(type, items.Items);
PushType(type.MakeArrayType(1));
return true;
}
}
}
return false;
}