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(); }
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); } }
public CilValueValueType(CilClassInstance value) { Value = value; }
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); } }
private object GetRuntimeThis(CilClassInstance classInstance, CilType type) { return(classInstance?.AsRuntime(type, ManagedMemory, _program)); }