Пример #1
0
        private void StartImportingBasicBlock(BasicBlock basicBlock)
        {
            // Import all associated EH regions
            foreach (ExceptionRegion ehRegion in _exceptionRegions)
            {
                ILExceptionRegion region = ehRegion.ILRegion;
                if (region.TryOffset == basicBlock.StartOffset)
                {
                    MarkBasicBlock(_basicBlocks[region.HandlerOffset]);
                    if (region.Kind == ILExceptionRegionKind.Filter)
                    {
                        MarkBasicBlock(_basicBlocks[region.FilterOffset]);
                    }

                    // Once https://github.com/dotnet/corert/issues/3460 is done, this should be deleted.
                    // Throwing InvalidProgram is not great, but we want to do *something* if this happens
                    // because doing nothing means problems at runtime. This is not worth piping a
                    // a new exception with a fancy message for.
                    if (region.Kind == ILExceptionRegionKind.Catch)
                    {
                        TypeDesc catchType = (TypeDesc)_methodIL.GetObject(region.ClassToken);
                        if (catchType.IsRuntimeDeterminedSubtype)
                        {
                            ThrowHelper.ThrowInvalidProgramException();
                        }
                    }
                }
            }

            _currentInstructionOffset  = -1;
            _previousInstructionOffset = -1;
        }
Пример #2
0
        private void StartImportingBasicBlock(BasicBlock basicBlock)
        {
            // Import all associated EH regions
            foreach (ExceptionRegion ehRegion in _exceptionRegions)
            {
                ILExceptionRegion region = ehRegion.ILRegion;
                if (region.TryOffset == basicBlock.StartOffset)
                {
                    MarkBasicBlock(_basicBlocks[region.HandlerOffset]);
                    if (region.Kind == ILExceptionRegionKind.Filter)
                    {
                        MarkBasicBlock(_basicBlocks[region.FilterOffset]);
                    }
                }
            }

            _currentInstructionOffset  = -1;
            _previousInstructionOffset = -1;
        }
Пример #3
0
        public override ILExceptionRegion[] GetExceptionRegions()
        {
            if (_ilExceptionRegions != null)
            {
                return(_ilExceptionRegions);
            }

            ImmutableArray <ExceptionRegion> exceptionRegions = _methodBody.ExceptionRegions;

            ILExceptionRegion[] ilExceptionRegions;

            int length = exceptionRegions.Length;

            if (length == 0)
            {
                ilExceptionRegions = Array.Empty <ILExceptionRegion>();
            }
            else
            {
                ilExceptionRegions = new ILExceptionRegion[length];
                for (int i = 0; i < length; i++)
                {
                    var exceptionRegion = exceptionRegions[i];

                    ilExceptionRegions[i] = new ILExceptionRegion(
                        (ILExceptionRegionKind)exceptionRegion.Kind, // assumes that ILExceptionRegionKind and ExceptionRegionKind enums are in sync
                        exceptionRegion.TryOffset,
                        exceptionRegion.TryLength,
                        exceptionRegion.HandlerOffset,
                        exceptionRegion.HandlerLength,
                        MetadataTokens.GetToken(exceptionRegion.CatchType),
                        exceptionRegion.FilterOffset);
                }
            }

            Interlocked.CompareExchange(ref _ilExceptionRegions, ilExceptionRegions, null);
            return(_ilExceptionRegions);
        }
Пример #4
0
        public override ILExceptionRegion[] GetExceptionRegions()
        {
            if (_ilExceptionRegions != null)
                return _ilExceptionRegions;

            ImmutableArray<ExceptionRegion> exceptionRegions = _methodBody.ExceptionRegions;
            ILExceptionRegion[] ilExceptionRegions;

            int length = exceptionRegions.Length;
            if (length == 0)
            {
                ilExceptionRegions = Array.Empty<ILExceptionRegion>();
            }
            else
            {
                ilExceptionRegions = new ILExceptionRegion[length];
                for (int i = 0; i < length; i++)
                {
                    var exceptionRegion = exceptionRegions[i];

                    ilExceptionRegions[i] = new ILExceptionRegion(
                        (ILExceptionRegionKind)exceptionRegion.Kind, // assumes that ILExceptionRegionKind and ExceptionRegionKind enums are in sync
                        exceptionRegion.TryOffset,
                        exceptionRegion.TryLength,
                        exceptionRegion.HandlerOffset,
                        exceptionRegion.HandlerLength,
                        MetadataTokens.GetToken(exceptionRegion.CatchType),
                        exceptionRegion.FilterOffset);
                }
            }

            return (_ilExceptionRegions = ilExceptionRegions);
        }
Пример #5
0
            public bool Initialize(MutableModule mutableModule, EcmaMethodIL wrappedMethod)
            {
                bool failedToReplaceToken = false;

                try
                {
                    Debug.Assert(mutableModule.ModuleThatIsCurrentlyTheSourceOfNewReferences == null);
                    mutableModule.ModuleThatIsCurrentlyTheSourceOfNewReferences = ((EcmaMethod)wrappedMethod.OwningMethod).Module;
                    var owningMethodHandle = mutableModule.TryGetEntityHandle(wrappedMethod.OwningMethod);
                    if (!owningMethodHandle.HasValue)
                    {
                        return(false);
                    }
                    _mutableModule    = mutableModule;
                    _maxStack         = wrappedMethod.MaxStack;
                    _isInitLocals     = wrappedMethod.IsInitLocals;
                    _owningMethod     = wrappedMethod.OwningMethod;
                    _exceptionRegions = (ILExceptionRegion[])wrappedMethod.GetExceptionRegions().Clone();
                    _ilBytes          = (byte[])wrappedMethod.GetILBytes().Clone();
                    _locals           = (LocalVariableDefinition[])wrappedMethod.GetLocals();

                    for (int i = 0; i < _exceptionRegions.Length; i++)
                    {
                        var region = _exceptionRegions[i];
                        if (region.Kind == ILExceptionRegionKind.Catch)
                        {
                            var newHandle = _mutableModule.TryGetHandle((TypeSystemEntity)wrappedMethod.GetObject(region.ClassToken));
                            if (!newHandle.HasValue)
                            {
                                return(false);
                            }
                            _exceptionRegions[i] = new ILExceptionRegion(region.Kind, region.TryOffset, region.TryLength, region.HandlerOffset, region.HandlerLength, newHandle.Value, newHandle.Value);
                        }
                    }

                    ILTokenReplacer.Replace(_ilBytes, GetMutableModuleToken);
#if DEBUG
                    Debug.Assert(ReadyToRunStandaloneMethodMetadata.Compute((EcmaMethod)_owningMethod) != null);
#endif // DEBUG
                }
                finally
                {
                    mutableModule.ModuleThatIsCurrentlyTheSourceOfNewReferences = null;
                }


                return(!failedToReplaceToken);

                int GetMutableModuleToken(int token)
                {
                    object result = wrappedMethod.GetObject(token);
                    int?   newToken;

                    if (result is string str)
                    {
                        newToken = mutableModule.TryGetStringHandle(str);
                    }
                    else
                    {
                        newToken = mutableModule.TryGetHandle((TypeSystemEntity)result);
                    }
                    if (!newToken.HasValue)
                    {
                        // Toekn replacement has failed. Do not attempt to use this IL.
                        failedToReplaceToken = true;
                        return(1);
                    }
                    return(newToken.Value);
                }
            }