Наследование: IMetadataTokenProvider
Пример #1
0
		public ResolutionException (MemberReference member)
			: base ("Failed to resolve " + member.FullName)
		{
			if (member == null)
				throw new ArgumentNullException ("member");

			this.member = member;
		}
Пример #2
0
		public void AddMemberReference (MemberReference member)
		{
			MemberReferences [member.token.RID - 1] = member;
		}
Пример #3
0
        private void ExecuteMethod(out ObjectInstance retVal, out bool doJmpCall, out MemberReference jmpCallToken)
        {
            jmpCallToken = null;
            doJmpCall = false;
            retVal = null;

            EvalLoop:
            try
            {
                this.ExecuteMethodCore(out retVal, out doJmpCall, out jmpCallToken);
            }
            catch (InazumaRuntimeException ex)
            {
                // TODO: check throwable
                // TODO: isuncatchable (ThreadAbort)
                var handleEx = false;

                if (_methInfo2.Body.HasExceptionHandlers)
                {
                    var curOffset = _instructions[_instructionPtr].Offset;

                    // Perform a filter scan or regular walk of the EH Table. Filter scan is performed when
                    // we are evaluating a series of filters to handle the exception until the first handler
                    // (filter's or otherwise) that will handle the exception.
                    foreach (var exceptionHandler in _methInfo2.Body.ExceptionHandlers)
                    {
                        var handlerOffset = 0;

                        // First, is the current offset in the try block?
                        if (exceptionHandler.TryStart.Offset <= curOffset && exceptionHandler.TryEnd.Offset >= curOffset)
                        {
                            // CORINFO_EH_CLAUSE_NONE represents 'catch' blocks
                            if (exceptionHandler.FilterStart == null)
                            {
                                // Now, does the catch block handle the thrown exception type?
                                var excType = _classLoader.LoadTypeFromTypeRef(exceptionHandler.CatchType);
                                if (ex.ExceptionObject.MethodTable == excType)
                                {
                                    _opStack.Clear();
                                    _opStack.Push(ex.ExceptionObject);
                                    handlerOffset = _instructions.Select((x, i) => new { Index = i, IsMatched = x == exceptionHandler.HandlerStart }).First(x => x.IsMatched).Index; // TODO: FIXME
                                    handleEx = true;
                                    //_filterNextScan = 0;
                                }
                            }
                            else
                            {
                                throw ThrowHelper.NotImplementedYet;
                            }

                            // Reset the interpreter loop in preparation of calling the handler.
                            if (handleEx)
                            {
                                // Set the IL offset of the handler.
                                _instructionPtr = handlerOffset;

                                // If an exception occurs while attempting to leave a protected scope,
                                // we empty the 'leave' info stack upon entering the handler.
                                // TODO: infoStack

                                // Some things are set up before a call, and must be cleared on an exception caught be the caller.
                                // A method that returns a struct allocates local space for the return value, and "registers" that
                                // space and the type so that it's scanned if a GC happens.  "Unregister" it if we throw an exception
                                // in the call, and handle it in the caller.  (If it's not handled by the caller, the Interpreter is
                                // deallocated, so it's value doesn't matter.)
                                _callThisArg = null;
                                _args.Clear();

                                break;
                            }
                        }
                    }
                }

                if (handleEx)
                {
                    goto EvalLoop;
                }
                else
                {
                    throw;
                }
            }
        }
Пример #4
0
        private void ExecuteMethodCore(out ObjectInstance retVal, out bool doJmpCall, out MemberReference jmpCallToken)
        {
            jmpCallToken = null;
            doJmpCall = false;
            retVal = null;

            for (; _instructions.Length > _instructionPtr; _instructionPtr++)
            {
                var inst = _instructions[_instructionPtr];

                if (inst.OpCode == OpCodes.Nop)
                {
                    continue;
                }
                else if (inst.OpCode == OpCodes.Break)
                {
                    continue;
                }

                else if (inst.OpCode == OpCodes.Ldarg_0)
                {
                    LdArg(0);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldarg_1)
                {
                    LdArg(1);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldarg_2)
                {
                    LdArg(2);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldarg_3)
                {
                    LdArg(3);
                    continue;
                }

                else if (inst.OpCode == OpCodes.Ldloc_0)
                {
                    LdLoc(0);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldloc_1)
                {
                    LdLoc(1);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldloc_2)
                {
                    LdLoc(2);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldloc_3)
                {
                    LdLoc(3);
                    continue;
                }

                else if (inst.OpCode == OpCodes.Stloc_0)
                {
                    StLoc(0);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Stloc_1)
                {
                    StLoc(1);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Stloc_2)
                {
                    StLoc(2);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Stloc_3)
                {
                    StLoc(3);
                    continue;
                }

                else if (inst.OpCode == OpCodes.Ldarg_S)
                {
                    // TODO: get index directly
                    var index = (inst.Operand is ParameterReference) ? ((ParameterReference)inst.Operand).Index : ((VariableReference)inst.Operand).Index;
                    LdArg(index);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldarga_S)
                {
                    // TODO: get index directly
                    var index = (inst.Operand is ParameterReference) ? ((ParameterReference)inst.Operand).Index : ((VariableReference)inst.Operand).Index;
                    LdArgA(index);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Starg_S)
                {
                    // TODO: get index directly
                    var index = (inst.Operand is ParameterReference) ? ((ParameterReference)inst.Operand).Index : ((VariableReference)inst.Operand).Index;
                    StArg(index);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldloc_S)
                {
                    // TODO: get index directly
                    var index = (inst.Operand is ParameterReference) ? ((ParameterReference)inst.Operand).Index : ((VariableReference)inst.Operand).Index;
                    LdLoc(index);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldloca_S)
                {
                    // TODO: get index directly
                    var index = (inst.Operand is ParameterReference) ? ((ParameterReference)inst.Operand).Index : ((VariableReference)inst.Operand).Index;
                    LdLocA(index);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Stloc_S)
                {
                    // TODO: get index directly
                    var index = (inst.Operand is ParameterReference) ? ((ParameterReference)inst.Operand).Index : ((VariableReference)inst.Operand).Index;
                    StLoc(index);
                    continue;
                }

                else if (inst.OpCode == OpCodes.Ldnull)
                {
                    Ldnull();
                    continue;
                }

                else if (inst.OpCode == OpCodes.Ldc_I4_M1)
                {
                    LdIcon(-1);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_0)
                {
                    LdIcon(0);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_1)
                {
                    LdIcon(1);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_2)
                {
                    LdIcon(2);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_3)
                {
                    LdIcon(3);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_4)
                {
                    LdIcon(4);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_5)
                {
                    LdIcon(5);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_6)
                {
                    LdIcon(6);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_7)
                {
                    LdIcon(7);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_8)
                {
                    LdIcon(8);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_S)
                {
                    LdIcon(inst.Operand);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldc_I4)
                {
                    LdIcon(inst.Operand);
                    continue;
                }

                else if (inst.OpCode == OpCodes.Ldstr)
                {
                    LdStr();
                    continue;
                }

                else if (inst.OpCode == OpCodes.Ldfld)
                {
                    LdFld();
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldflda)
                {
                    LdFldA();
                    continue;
                }
                else if (inst.OpCode == OpCodes.Stfld)
                {
                    StFld();
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldsfld)
                {
                    LdSFld();
                    continue;
                }
                else if (inst.OpCode == OpCodes.Ldsflda)
                {
                    LdSFldA();
                    continue;
                }
                else if (inst.OpCode == OpCodes.Stsfld)
                {
                    StSFld();
                    continue;
                }
                else if (inst.OpCode == OpCodes.Stobj)
                {
                    StObj();
                    continue;
                }

                // ...
                else if (inst.OpCode == OpCodes.Add)
                {
                    Add(checkOverflow: false, unsigned: false);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Add_Ovf)
                {
                    Add(checkOverflow: true, unsigned: false);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Add_Ovf_Un)
                {
                    Add(checkOverflow: true, unsigned: true);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Sub)
                {
                    Sub(checkOverflow: false, unsigned: false);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Sub_Ovf)
                {
                    Sub(checkOverflow: true, unsigned: false);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Sub_Ovf_Un)
                {
                    Sub(checkOverflow: true, unsigned: true);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Mul)
                {
                    Mul(checkOverflow: false, unsigned: false);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Mul_Ovf)
                {
                    Mul(checkOverflow: true, unsigned: false);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Mul_Ovf_Un)
                {
                    Mul(checkOverflow: true, unsigned: true);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Div)
                {
                    Div(checkOverflow: true, unsigned: false);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Div_Un)
                {
                    Div(checkOverflow: true, unsigned: true);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Rem)
                {
                    Rem(checkOverflow: true, unsigned: false);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Rem_Un)
                {
                    Rem(checkOverflow: true, unsigned: true);
                    continue;
                }

                else if (inst.OpCode == OpCodes.Newobj)
                {
                    NewObj();
                    continue;
                }

                else if (inst.OpCode == OpCodes.Box)
                {
                    // TODO: not implemented yet
                    continue;
                }

                else if (inst.OpCode == OpCodes.Call)
                {
                    Call(virtualCall: false);
                    continue;
                }
                else if (inst.OpCode == OpCodes.Callvirt)
                {
                    Call(virtualCall: true);
                    continue;
                }

                else if (inst.OpCode == OpCodes.Ret)
                {
                    // TODO: use reference or type
                    if (_methInfo2.ReturnType.Namespace == "System" && _methInfo2.ReturnType.Name == "Void")
                    {
                        Debug.Assert(_opStack.Count == 0);
                    }
                    else
                    {
                        Debug.Assert(_opStack.Count != 0);
                        retVal = _opStack.Pop();
                    }

                    return; // goto ExitEvalLoop;
                }

                else if (inst.OpCode == OpCodes.Br_S)
                {
                    // TODO: below code is too slow
                    _instructionPtr = _instructions.Select((x, i) => new { Index = i, IsMatched = x == inst.Operand }).First(x => x.IsMatched).Index - 1; // increments ops ptr after "continue;". ptr must be subtracted here.
                    continue;
                }
                else if (inst.OpCode == OpCodes.Leave_S)
                {
                    _opStack.Clear();
                    throw ThrowHelper.NotImplementedYet;
                }
                else if (inst.OpCode == OpCodes.Brfalse_S)
                {
                    // TODO: below code is too slow
                    var value = _opStack.Pop();
                    if ((value.IsReference && value.IsNull) || value.I == 0)
                    {
                        _instructionPtr = _instructions.Select((x, i) => new { Index = i, IsMatched = x == inst.Operand }).First(x => x.IsMatched).Index - 1; // increments ops ptr after "continue;". ptr must be subtracted here.
                    }
                    continue;
                }
                else if (inst.OpCode == OpCodes.Brtrue_S)
                {
                    // TODO: below code is too slow
                    var value = _opStack.Pop();
                    if ((value.IsReference && !value.IsNull) || value.I != 0)
                    {
                        _instructionPtr = _instructions.Select((x, i) => new { Index = i, IsMatched = x == inst.Operand }).First(x => x.IsMatched).Index - 1; // increments ops ptr after "continue;". ptr must be subtracted here.
                    }
                    continue;
                }

                // case CEE_PREFIX1:
                else if (inst.OpCode == OpCodes.Arglist)
                {
                    throw ThrowHelper.NotImplementedYet;
                }
                else if (inst.OpCode == OpCodes.Ceq)
                {
                    var value2 = _opStack.Pop();
                    var value1 = _opStack.Pop();

                    if (value1.Type == CorInfoType.Class)
                    {
                        _opStack.Push(ObjectInstance.FromClrObject((value1 == value2) ? 1 : 0));
                    }
                    else if (value1.Type == CorInfoType.String)
                    {
                        _opStack.Push(ObjectInstance.FromClrObject((value1.ObjectRef == value2.ObjectRef) ? 1 : 0));
                    }
                    else
                    {
                        _opStack.Push(ObjectInstance.FromClrObject((value1.I == value2.I) ? 1 : 0));
                    }
                    continue;
                }
                else if (inst.OpCode == OpCodes.Cgt)
                {
                    var value2 = _opStack.Pop().I;
                    var value1 = _opStack.Pop().I;
                    _opStack.Push(ObjectInstance.FromClrObject((value1 > value2) ? 1 : 0));
                    continue;
                }
                else if (inst.OpCode == OpCodes.Cgt_Un)
                {
                    var value2 = _opStack.Pop();
                    var value1 = _opStack.Pop();

                    if (value1.Type == CorInfoType.Class)
                    {
                        _opStack.Push(ObjectInstance.FromClrObject((value1 != value2) ? 1 : 0));
                    }
                    else if (value1.Type == CorInfoType.String)
                    {
                        _opStack.Push(ObjectInstance.FromClrObject((value1.ObjectRef != value2.ObjectRef) ? 1 : 0));
                    }
                    else
                    {
                        _opStack.Push(ObjectInstance.FromClrObject(((ulong)value1.I > (ulong)value2.I) ? 1 : 0));
                    }

                    continue;
                }
                else if (inst.OpCode == OpCodes.Clt)
                {
                    var value2 = _opStack.Pop().I;
                    var value1 = _opStack.Pop().I;
                    _opStack.Push(ObjectInstance.FromClrObject((value1 < value2) ? 1 : 0));
                    continue;
                }
                else if (inst.OpCode == OpCodes.Clt_Un)
                {
                    var value2 = (ulong)_opStack.Pop().I;
                    var value1 = (ulong)_opStack.Pop().I;
                    _opStack.Push(ObjectInstance.FromClrObject((value1 < value2) ? 1 : 0));
                    continue;
                }

                else if (inst.OpCode == OpCodes.Throw)
                {
                    Throw();
                    continue;
                }

                throw new InazumaExecutionException("Unknown OpCode: " + inst.OpCode.ToString());
            }
        }