Exemplo n.º 1
0
        private void LowerReferenceTypeBox(
            InstructionBuilder instruction,
            IType elementType)
        {
            var token = instruction.InsertBefore(
                Instruction.CreateConstant(
                    new TypeTokenConstant(elementType),
                    GetTypeFromHandleMethod.Parameters[0].Type));

            var type = instruction.InsertBefore(
                Instruction.CreateCall(
                    GetTypeFromHandleMethod,
                    MethodLookup.Static,
                    new ValueTag[] { token }));

            var obj = instruction.InsertBefore(
                Instruction.CreateCall(
                    CreateUninitializedObjectMethod,
                    MethodLookup.Static,
                    new ValueTag[] { type }));

            instruction.Instruction = Instruction.CreateReinterpretCast(
                (PointerType)instruction.ResultType,
                obj);
        }
Exemplo n.º 2
0
        private static bool TrySimplify(InstructionBuilder instruction)
        {
            var proto = instruction.Prototype;

            if (proto is ConstrainedCallPrototype)
            {
                //
                //     constrained_call(f)(this_ref, args...)
                //
                // is equivalent to
                //
                //     call(impl(f), static)(this_ref, args...)  if this_ref == T ref* where T is a value type,
                //     call(f, virtual)(load(this_ref), args...) if this_ref == T any* ref*.

                var constrainedCallProto = (ConstrainedCallPrototype)proto;
                var thisArg     = constrainedCallProto.GetThisArgument(instruction.Instruction);
                var thisRefType = instruction.Graph.GetValueType(thisArg) as PointerType;
                if (thisRefType == null)
                {
                    return(false);
                }

                var thisValType = thisRefType.ElementType;
                if (thisValType is PointerType)
                {
                    instruction.Instruction = Instruction.CreateCall(
                        constrainedCallProto.Callee,
                        MethodLookup.Virtual,
                        instruction.InsertBefore(
                            Instruction.CreateLoad(thisValType, thisArg),
                            "this_value"),
                        constrainedCallProto.GetArgumentList(instruction.Instruction).ToArray());

                    TrySimplify(instruction);
                    return(true);
                }
                else if (!(thisValType is IGenericParameter))
                {
                    var realCallee = thisValType.GetImplementationOf(constrainedCallProto.Callee);
                    if (realCallee != null && realCallee.ParentType == thisValType)
                    {
                        instruction.Instruction = Instruction.CreateCall(
                            realCallee,
                            MethodLookup.Static,
                            constrainedCallProto.GetThisArgument(instruction.Instruction),
                            constrainedCallProto.GetArgumentList(instruction.Instruction).ToArray());

                        return(true);
                    }
                }
            }
            else if (proto is CallPrototype)
            {
                var callProto = (CallPrototype)proto;
                if (callProto.Callee.IsStatic)
                {
                    return(false);
                }

                var thisType = GetActualType(
                    callProto.GetThisArgument(instruction.Instruction),
                    instruction.Graph.ImmutableGraph) as PointerType;

                if (thisType == null)
                {
                    return(false);
                }

                var realCallee = thisType.ElementType.GetImplementationOf(callProto.Callee);
                if (realCallee == null || realCallee == callProto.Callee)
                {
                    return(false);
                }

                instruction.Instruction = Instruction.CreateCall(
                    realCallee,
                    realCallee.IsVirtual() ? MethodLookup.Virtual : MethodLookup.Static,
                    instruction.InsertBefore(
                        Instruction.CreateReinterpretCast(
                            realCallee.ParentType.MakePointerType(thisType.Kind),
                            callProto.GetThisArgument(instruction.Instruction))),
                    callProto.GetArgumentList(instruction.Instruction).ToArray());

                return(true);
            }
            return(false);
        }