示例#1
0
        public override IValue CreateDefaultValue(CilProgram program)
        {
            if (program.IsExternalType(ClassName))
            {
                var type = ReflectionHelper.GetExternalType(ClassName);

                var getDefault   = GetType().GetMethod(nameof(GetDefaultGeneric), BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(type);
                var defaultValue = getDefault.Invoke(null, null);

                return(new CilValueExternal(defaultValue));
            }

            var @class = program.AllClasses.Single(c => c.Name.ToString() == ClassName.ToString());

            if (@class.IsInterface)
            {
                return(new CilValueNull());
            }

            if (IsValueType(program))
            {
                var emptyInstance = new CilClassInstance(@class, program, null);
                return(new CilValueValueType(emptyInstance));
            }

            return(new CilValueNull());
        }
        protected override void VisitLoadFieldInstruction(LoadFieldInstruction instruction)
        {
            ControlState.EvaluationStack.PopValue(_program, instruction.ClassTypeSpec.GetCilType(_program), out var instanceVal);

            CilClassInstance classInstance = null;

            if (instanceVal is CilValueValueType instanceValValueType)
            {
                classInstance = instanceValValueType.Value;
            }
            else if (instanceVal is CilValueReference instanceValReference)
            {
                classInstance = ManagedMemory.Load(instanceValReference) as CilClassInstance;
            }
            else
            {
                throw new System.NotImplementedException();
            }

            var value = classInstance.Fields[instruction.FieldId];

            ControlState.EvaluationStack.PushValue(value);

            ControlState.MoveToNextInstruction();
        }
示例#3
0
        public override void VisitNewObjectInstruction(NewObjectInstruction instruction)
        {
            var callExternal = _program.IsExternalType(instruction.TypeSpec);

            var methodArgs = PopMethodArgs(instruction);

            if (callExternal)
            {
                object thisObject = null;
                if (instruction.CallConv.IsInstance)
                {
                    thisObject = GetRuntimeEmptyInstance(instruction, methodArgs, true);
                }

                var result    = CallExternalMethod(instruction, null, methodArgs.ToArray(), thisObject);
                var resultVal = instruction.TypeSpec.GetCilType(_program).CreateValueFromRuntime(result, ManagedMemory, _program);

                ControlState.EvaluationStack.PushValue(resultVal);
                ControlState.MoveToNextInstruction();
            }
            else
            {
                var @class = _program.Classes.Single(c => c.Name.ToString() == instruction.TypeSpec.ClassName.ToString());
                var method = @class.Methods.Single(m => m.Name == instruction.MethodName && AreArgumentsAssignable(instruction.SigArgs, m.Arguments));

                var emptyInstance = new CilClassInstance(@class, _program, ManagedMemory);
                var thisRef       = ManagedMemory.Store(emptyInstance);
                ControlState.EvaluationStack.PushValue(thisRef);

                var sigArgsWithThis = CompleteSigArgs(instruction, method);
                var argsWithThis    = CompleteArgs(instruction, methodArgs, thisRef);

                var newMethodState = new CilMethodState(method, sigArgsWithThis, argsWithThis, _program);

                ControlState.MoveToNextInstruction();
                ControlState.CallStack.Push(newMethodState);
            }
        }
示例#4
0
 public CilValueValueType(CilClassInstance value)
 {
     Value = value;
 }
示例#5
0
        public override void VisitCallVirtualInstruction(CallVirtualInstruction instruction)
        {
            if (!instruction.CallConv.IsInstance)
            {
                throw new System.NotImplementedException();
            }

            var methodArgs = PopMethodArgs(instruction);

            ControlState.EvaluationStack.PopValue(_program, instruction.TypeSpec.GetCilType(_program), out var thisVal);

            var callExternal = true;

            CilClassInstance thisClassInstance = null;
            CilObject        thisObject        = null;

            if (thisVal is CilValueReference thisValRef)
            {
                var thisObj = ManagedMemory.Load(thisValRef);

                if (thisObj is CilClassInstance)
                {
                    thisClassInstance = thisObj as CilClassInstance;
                }
                else
                {
                    thisObject   = thisObj;
                    callExternal = true;
                }
            }
            else
            {
                throw new System.NotImplementedException();
            }

            CilMethod method = null;

            if (thisClassInstance != null)
            {
                var currentClass = thisClassInstance.Class;
                while (true)
                {
                    var possibleMethod = currentClass.Methods.SingleOrDefault(m => m.Name == instruction.MethodName && AreArgumentsAssignable(instruction.SigArgs, m.Arguments));
                    if (possibleMethod != null)
                    {
                        method       = possibleMethod;
                        callExternal = false;
                        break;
                    }

                    currentClass = currentClass.Extends;
                    if (currentClass == null)
                    {
                        callExternal = true;
                        break;
                    }
                }
            }

            if (callExternal)
            {
                var result = CallExternalMethod(instruction, thisVal, methodArgs.ToArray(), null);

                if (!(instruction.ReturnType is CilTypeVoid))
                {
                    var resultVal = instruction.ReturnType.CreateValueFromRuntime(result, ManagedMemory, _program);
                    ControlState.EvaluationStack.PushValue(resultVal);
                }

                ControlState.MoveToNextInstruction();
            }
            else
            {
                var sigArgsWithThis = CompleteSigArgs(instruction, method);
                var argsWithThis    = CompleteArgs(instruction, methodArgs, thisVal);

                var newMethodState = new CilMethodState(method, sigArgsWithThis, argsWithThis, _program);

                ControlState.MoveToNextInstruction();
                ControlState.CallStack.Push(newMethodState);
            }
        }
示例#6
0
 private object GetRuntimeThis(CilClassInstance classInstance, CilType type)
 {
     return(classInstance?.AsRuntime(type, ManagedMemory, _program));
 }