// Just recalc Name. private void RecalcWorker2(string name) { if (_calcs.ContainsKey(name)) { return; // already computed. } var fi = _parent.Formulas[name]; // Now calculate this node. Will recalc any dependencies if needed. if (fi._binding != null) { var binding = fi._binding; (IntermediateNode irnode, ScopeSymbol ruleScopeSymbol) = IRTranslator.Translate(binding); var scope = this; var v = new EvalVisitor(_cultureInfo); FormulaValue newValue = irnode.Accept(v, SymbolContext.New()); var equal = fi._value != null && // null on initial run. RuntimeHelpers.AreEqual(newValue, fi._value); if (!equal) { _sendUpdates.Add(name); } fi._value = newValue; } _calcs[name] = fi._value; }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { var ecallId = tr.VM.Runtime.VMCall.BREAK; tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId))); return(null); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { var retVar = tr.Context.AllocateVRegister(expr.Type.Value); var method = ((IMethod)expr.Operand).ResolveMethodDef(); var intraLinking = method != null && tr.VM.Settings.IsVirtualized(method); var ecallId = tr.VM.Runtime.VMCall.LDFTN; if (intraLinking) { var sigId = (int)tr.VM.Data.GetId(method.DeclaringType, method.MethodSig); uint entryKey = tr.VM.Data.LookupInfo(method).EntryKey; entryKey = ((uint)tr.VM.Random.Next() & 0xffffff00) | entryKey; tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.FromI4((int)entryKey))); tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.FromI4(sigId))); tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, new IRMetaTarget(method) { LateResolve = true })); tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId))); } else { var methodId = (int)tr.VM.Data.GetId((IMethod)expr.Operand); tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.FromI4(0))); tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(methodId))); } tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar)); return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 2); var ret = tr.Context.AllocateVRegister(expr.Type.Value); tr.Instructions.Add(new IRInstruction(IROpCode.MOV) { Operand1 = ret, Operand2 = tr.Translate(expr.Arguments[0]) }); tr.Instructions.Add(new IRInstruction(IROpCode.ADD) { Operand1 = ret, Operand2 = tr.Translate(expr.Arguments[1]) }); var ecallId = tr.VM.Runtime.VMCall.CKOVERFLOW; var fl = tr.Context.AllocateVRegister(expr.Type.Value); tr.Instructions.Add(new IRInstruction(IROpCode.__GETF) { Operand1 = fl, Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.CARRY) }); tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), fl)); return(ret); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 0); ScopeBlock[] parentScopes = tr.RootScope.SearchBlock(tr.Block); ScopeBlock catchScope = parentScopes[parentScopes.Length - 1]; if (catchScope.Type != ScopeType.Handler || catchScope.ExceptionHandler.HandlerType != ExceptionHandlerType.Catch) { throw new InvalidProgramException(); } IRVariable exVar = tr.Context.ResolveExceptionVar(catchScope.ExceptionHandler); Debug.Assert(exVar != null); int ecallId = tr.VM.Runtime.VMCall.THROW; tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, exVar)); tr.Instructions.Add(new IRInstruction(IROpCode.VCALL) { Operand1 = IRConstant.FromI4(ecallId), Operand2 = IRConstant.FromI4(1) }); return(null); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 2); tr.Instructions.Add(new IRInstruction(IROpCode.CMP) { Operand1 = tr.Translate(expr.Arguments[0]), Operand2 = tr.Translate(expr.Arguments[1]) }); // CF=0 & ZF=0 var ret = tr.Context.AllocateVRegister(ASTType.I4); tr.Instructions.Add(new IRInstruction(IROpCode.__GETF) { Operand1 = ret, Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.CARRY | 1 << tr.Arch.Flags.ZERO) }); tr.Instructions.Add(new IRInstruction(IROpCode.__OR) { Operand1 = ret, Operand2 = ret }); tr.Instructions.Add(new IRInstruction(IROpCode.__GETF) { Operand1 = ret, Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.ZERO) }); return(ret); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { // TODO: overflow? Debug.Assert(expr.Arguments.Length == 1); IIROperand value = tr.Translate(expr.Arguments[0]); ASTType valueType = value.Type; if (valueType == ASTType.Ptr || valueType == ASTType.I4) // no conversion needed. { return(value); } IRVariable retVar = tr.Context.AllocateVRegister(ASTType.Ptr); switch (valueType) { case ASTType.I8: tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, value)); break; case ASTType.R4: case ASTType.R8: IRVariable tmp = tr.Context.AllocateVRegister(ASTType.I8); tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, tmp, value)); tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, tmp)); break; default: throw new NotSupportedException(); } return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { var callInfo = new InstrCallInfo("CALLVIRT") { Method = (IMethod)expr.Operand }; if (expr.Prefixes != null && expr.Prefixes[0].OpCode == OpCodes.Constrained) { callInfo.ConstrainType = (ITypeDefOrRef)expr.Prefixes[0].Operand; } tr.Instructions.Add(new IRInstruction(IROpCode.__BEGINCALL) { Annotation = callInfo }); var args = new IIROperand[expr.Arguments.Length]; for (var i = 0; i < args.Length; i++) { args[i] = tr.Translate(expr.Arguments[i]); tr.Instructions.Add(new IRInstruction(IROpCode.PUSH) { Operand1 = args[i], Annotation = callInfo }); } callInfo.Arguments = args; IIROperand retVal = null; if (expr.Type != null) { retVal = tr.Context.AllocateVRegister(expr.Type.Value); tr.Instructions.Add(new IRInstruction(IROpCode.__CALLVIRT) { Operand1 = new IRMetaTarget(callInfo.Method), Operand2 = retVal, Annotation = callInfo }); } else { tr.Instructions.Add(new IRInstruction(IROpCode.__CALLVIRT) { Operand1 = new IRMetaTarget(callInfo.Method), Annotation = callInfo }); } callInfo.ReturnValue = retVal; tr.Instructions.Add(new IRInstruction(IROpCode.__ENDCALL) { Annotation = callInfo }); return(retVal); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); var value = tr.Translate(expr.Arguments[0]); var targetType = ((ITypeDefOrRef)expr.Operand).ToTypeSig(); if (!targetType.GetElementType().IsPrimitive() && targetType.ElementType != ElementType.Object && !targetType.ToTypeDefOrRef().ResolveTypeDefThrow().IsEnum) { // Non-primitive types => already boxed in VM return(value); } var retVar = tr.Context.AllocateVRegister(expr.Type.Value); var typeId = (int)tr.VM.Data.GetId((ITypeDefOrRef)expr.Operand); var ecallId = tr.VM.Runtime.VMCall.UNBOX; tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, value)); tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(typeId))); tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar)); return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); IIROperand value = tr.Translate(expr.Arguments[0]); var targetType = ((ITypeDefOrRef)expr.Operand).ToTypeSig(); TypeDef boxType = ((ITypeDefOrRef)expr.Operand).ResolveTypeDef(); if (!targetType.GetElementType().IsPrimitive() && (boxType == null || !boxType.IsEnum)) { if (targetType.ElementType != ElementType.String) // Box is used to resolve string ID { return(value); } } IRVariable retVar = tr.Context.AllocateVRegister(expr.Type.Value); int typeId = (int)tr.VM.Data.GetId((ITypeDefOrRef)expr.Operand); int ecallId = tr.VM.Runtime.VMCall.BOX; tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, value)); tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(typeId))); tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar)); return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); var value = tr.Translate(expr.Arguments[0]); var valueType = value.Type; var retVar = tr.Context.AllocateVRegister(ASTType.I4); retVar.RawType = tr.Context.Method.Module.CorLibTypes.Byte; switch (valueType) { case ASTType.I4: case ASTType.I8: case ASTType.Ptr: tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, value)); break; case ASTType.R4: case ASTType.R8: var tmp = tr.Context.AllocateVRegister(ASTType.I8); tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, tmp, value)); tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, tmp)); break; default: throw new NotSupportedException(); } return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); var value = tr.Translate(expr.Arguments[0]); var valueType = value.Type; if (valueType == ASTType.I8) // no conversion needed. { return(value); } var retVar = tr.Context.AllocateVRegister(ASTType.I8); switch (valueType) { case ASTType.I4: tr.Instructions.Add(new IRInstruction(IROpCode.SX, retVar, value)); break; case ASTType.Ptr: tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, value)); break; case ASTType.R4: case ASTType.R8: tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, retVar, value)); break; default: throw new NotSupportedException(); } return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); var value = tr.Translate(expr.Arguments[0]); var valueType = value.Type; var retVar = tr.Context.AllocateVRegister(ASTType.R8); switch (valueType) { case ASTType.I4: var tmpVar = tr.Context.AllocateVRegister(ASTType.I8); tr.Instructions.Add(new IRInstruction(IROpCode.SX, tmpVar, value)); tr.Instructions.Add(new IRInstruction(IROpCode.__SETF) { Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED) }); tr.Instructions.Add(new IRInstruction(IROpCode.FCONV, retVar, tmpVar)); break; case ASTType.I8: tr.Instructions.Add(new IRInstruction(IROpCode.__SETF) { Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED) }); tr.Instructions.Add(new IRInstruction(IROpCode.FCONV, retVar, value)); break; default: throw new NotSupportedException(); } return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); tr.Instructions.Add(new IRInstruction(IROpCode.__EHRET, tr.Translate(expr.Arguments[0]))); tr.Block.Flags |= BlockFlags.ExitEHReturn; return(null); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); IIROperand value = tr.Translate(expr.Arguments[0]); ASTType valueType = value.Type; if (valueType == ASTType.I8) // no conversion needed. { return(value); } IRVariable retVar = tr.Context.AllocateVRegister(ASTType.I8); switch (valueType) { case ASTType.I4: case ASTType.Ptr: tr.Instructions.Add(new IRInstruction(IROpCode.MOV, retVar, value)); break; case ASTType.R4: case ASTType.R8: IRVariable tmp = tr.Context.AllocateVRegister(ASTType.I8); tr.Instructions.Add(new IRInstruction(IROpCode.__SETF) { Operand1 = IRConstant.FromI4(1 << tr.Arch.Flags.UNSIGNED) }); tr.Instructions.Add(new IRInstruction(IROpCode.ICONV, tmp, value)); break; default: throw new NotSupportedException(); } return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 2); var ret = tr.Context.AllocateVRegister(expr.Type.Value); if (expr.Type != null && (expr.Type.Value == ASTType.R4 || expr.Type.Value == ASTType.R8)) { tr.Instructions.Add(new IRInstruction(IROpCode.MOV) { Operand1 = ret, Operand2 = tr.Translate(expr.Arguments[0]) }); tr.Instructions.Add(new IRInstruction(IROpCode.SUB) { Operand1 = ret, Operand2 = tr.Translate(expr.Arguments[1]) }); } else { // A - B = A + (-B) = A + (~B + 1) = A + ~B + 1 var tmp = tr.Context.AllocateVRegister(expr.Type.Value); tr.Instructions.Add(new IRInstruction(IROpCode.MOV) { Operand1 = ret, Operand2 = tr.Translate(expr.Arguments[0]) }); tr.Instructions.Add(new IRInstruction(IROpCode.MOV) { Operand1 = tmp, Operand2 = tr.Translate(expr.Arguments[1]) }); tr.Instructions.Add(new IRInstruction(IROpCode.__NOT) { Operand1 = tmp }); tr.Instructions.Add(new IRInstruction(IROpCode.ADD) { Operand1 = ret, Operand2 = tmp }); tr.Instructions.Add(new IRInstruction(IROpCode.ADD) { Operand1 = ret, Operand2 = IRConstant.FromI4(1) }); } var ecallId = tr.VM.Runtime.VMCall.CKOVERFLOW; var fl = tr.Context.AllocateVRegister(expr.Type.Value); tr.Instructions.Add(new IRInstruction(IROpCode.__GETF) { Operand1 = fl, Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.CARRY) }); tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), fl)); return(ret); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { IRVariable local = tr.Context.ResolveLocal((Local)expr.Operand); IRVariable ret = tr.Context.AllocateVRegister(ASTType.ByRef); tr.Instructions.Add(new IRInstruction(IROpCode.__LEA, ret, local)); return(ret); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); var value = tr.Translate(expr.Arguments[0]); // TODO: no exception possible? return(value); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { var param = tr.Context.ResolveParameter((Parameter)expr.Operand); var ret = tr.Context.AllocateVRegister(ASTType.ByRef); tr.Instructions.Add(new IRInstruction(IROpCode.__LEA, ret, param)); return(ret); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { tr.Instructions.Add(new IRInstruction(IROpCode.JMP) { Operand1 = new IRBlockTarget((IBasicBlock)expr.Operand) }); return(null); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { tr.Instructions.Add(new IRInstruction(IROpCode.__LEAVE) { Operand1 = new IRBlockTarget((IBasicBlock)expr.Operand) }); tr.Block.Flags |= BlockFlags.ExitEHLeave; return(null); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); tr.Instructions.Add(new IRInstruction(IROpCode.MOV) { Operand1 = tr.Context.ResolveParameter((Parameter)expr.Operand), Operand2 = tr.Translate(expr.Arguments[0]) }); return(null); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { IRVariable retVar = tr.Context.AllocateVRegister(expr.Type.Value); int refId = (int)tr.VM.Data.GetId((IMemberRef)expr.Operand); int ecallId = tr.VM.Runtime.VMCall.TOKEN; tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(refId))); tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar)); return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { var typeId = (int)tr.Runtime.Descriptor.Data.GetId((ITypeDefOrRef)expr.Operand); var retVar = tr.Context.AllocateVRegister(expr.Type.Value); var ecallId = tr.VM.Runtime.VMCall.SIZEOF; tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(typeId))); tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar)); return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { var retVar = tr.Context.AllocateVRegister(expr.Type.Value); var fieldId = (int)tr.VM.Data.GetId((IField)expr.Operand); var ecallId = tr.VM.Runtime.VMCall.LDFLD; tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, IRConstant.Null())); tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(fieldId))); tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar)); return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 2); tr.Instructions.Add(new IRInstruction(IROpCode.CMP) { Operand1 = tr.Translate(expr.Arguments[0]), Operand2 = tr.Translate(expr.Arguments[1]) }); // SF<>OF // !((FL=S|O) or (FL=0)), FL=S|O var ret = tr.Context.AllocateVRegister(ASTType.I4); var fl = tr.Context.AllocateVRegister(ASTType.I4); tr.Instructions.Add(new IRInstruction(IROpCode.__GETF) { Operand1 = fl, Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.OVERFLOW | 1 << tr.Arch.Flags.SIGN) }); tr.Instructions.Add(new IRInstruction(IROpCode.MOV) { Operand1 = ret, Operand2 = fl }); TranslationHelpers.EmitCompareEq(tr, ASTType.I4, ret, IRConstant.FromI4(1 << tr.Arch.Flags.OVERFLOW | 1 << tr.Arch.Flags.SIGN)); tr.Instructions.Add(new IRInstruction(IROpCode.__GETF) { Operand1 = ret, Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.ZERO) }); tr.Instructions.Add(new IRInstruction(IROpCode.__AND) { Operand1 = fl, Operand2 = fl }); tr.Instructions.Add(new IRInstruction(IROpCode.__GETF) { Operand1 = fl, Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.ZERO) }); tr.Instructions.Add(new IRInstruction(IROpCode.__OR) { Operand1 = ret, Operand2 = fl }); tr.Instructions.Add(new IRInstruction(IROpCode.__GETF) { Operand1 = ret, Operand2 = IRConstant.FromI4(1 << tr.Arch.Flags.ZERO) }); return(ret); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); var ret = tr.Context.AllocateVRegister(expr.Type.Value); tr.Instructions.Add(new IRInstruction(IROpCode.MOV) { Operand1 = ret, Operand2 = tr.Translate(expr.Arguments[0]) }); return(ret); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); var size = tr.Translate(expr.Arguments[0]); var retVar = tr.Context.AllocateVRegister(expr.Type.Value); var ecallId = tr.VM.Runtime.VMCall.LOCALLOC; tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), size)); tr.Instructions.Add(new IRInstruction(IROpCode.POP, retVar)); return(retVar); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 1); var addr = tr.Translate(expr.Arguments[0]); var typeId = (int)tr.VM.Data.GetId((ITypeDefOrRef)expr.Operand); var ecallId = tr.VM.Runtime.VMCall.INITOBJ; tr.Instructions.Add(new IRInstruction(IROpCode.PUSH, addr)); tr.Instructions.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(typeId))); return(null); }
public IIROperand Translate(ILASTExpression expr, IRTranslator tr) { Debug.Assert(expr.Arguments.Length == 2); var addr = tr.Translate(expr.Arguments[0]); var value = tr.Translate(expr.Arguments[1]); tr.Instructions.Add(new IRInstruction(IROpCode.__STOBJ, addr, value) { Annotation = new PointerInfo("STOBJ", (ITypeDefOrRef)expr.Operand) }); return(null); }