public static void SetReturnAddressForStackFrame(uint stackframe, uint value) { Intrinsic.Store32(stackframe, NativeIntSize, value); }
public override string ToString() { string text; switch (op) { case Op.AssignA: text = string.Format("{0} := {1}", lhs, rhsA); break; case Op.AssignImplicit: text = string.Format("_ := {0}", rhsA); break; case Op.APlusB: text = string.Format("{0} := {1} + {2}", lhs, rhsA, rhsB); break; case Op.AMinusB: text = string.Format("{0} := {1} - {2}", lhs, rhsA, rhsB); break; case Op.ATimesB: text = string.Format("{0} := {1} * {2}", lhs, rhsA, rhsB); break; case Op.ADividedByB: text = string.Format("{0} := {1} / {2}", lhs, rhsA, rhsB); break; case Op.AModB: text = string.Format("{0} := {1} % {2}", lhs, rhsA, rhsB); break; case Op.APowB: text = string.Format("{0} := {1} ^ {2}", lhs, rhsA, rhsB); break; case Op.AEqualB: text = string.Format("{0} := {1} == {2}", lhs, rhsA, rhsB); break; case Op.ANotEqualB: text = string.Format("{0} := {1} != {2}", lhs, rhsA, rhsB); break; case Op.AGreaterThanB: text = string.Format("{0} := {1} > {2}", lhs, rhsA, rhsB); break; case Op.AGreatOrEqualB: text = string.Format("{0} := {1} >= {2}", lhs, rhsA, rhsB); break; case Op.ALessThanB: text = string.Format("{0} := {1} < {2}", lhs, rhsA, rhsB); break; case Op.ALessOrEqualB: text = string.Format("{0} := {1} <= {2}", lhs, rhsA, rhsB); break; case Op.AAndB: text = string.Format("{0} := {1} and {2}", lhs, rhsA, rhsB); break; case Op.AOrB: text = string.Format("{0} := {1} or {2}", lhs, rhsA, rhsB); break; case Op.AisaB: text = string.Format("{0} := {1} isa {2}", lhs, rhsA, rhsB); break; case Op.CopyA: text = string.Format("{0} := copy of {1}", lhs, rhsA); break; case Op.NotA: text = string.Format("{0} := not {1}", lhs, rhsA); break; case Op.GotoA: text = string.Format("goto {0}", rhsA); break; case Op.GotoAifB: text = string.Format("goto {0} if {1}", rhsA, rhsB); break; case Op.GotoAifTrulyB: text = string.Format("goto {0} if truly {1}", rhsA, rhsB); break; case Op.GotoAifNotB: text = string.Format("goto {0} if not {1}", rhsA, rhsB); break; case Op.PushParam: text = string.Format("push param {0}", rhsA); break; case Op.CallFunctionA: text = string.Format("{0} := call {1} with {2} args", lhs, rhsA, rhsB); break; case Op.CallIntrinsicA: text = string.Format("intrinsic {0}", Intrinsic.GetByID(rhsA.IntValue())); break; case Op.ReturnA: text = string.Format("{0} := {1}; return", lhs, rhsA); break; case Op.ElemBofA: text = string.Format("{0} = {1}[{2}]", lhs, rhsA, rhsB); break; case Op.ElemBofIterA: text = string.Format("{0} = {1} iter {2}", lhs, rhsA, rhsB); break; case Op.LengthOfA: text = string.Format("{0} = len({1})", lhs, rhsA); break; default: throw new RuntimeException("unknown opcode: " + op); } // if (comment != null) text = text + "\t// " + comment; return(text); }
public static IntrinsicInfo GetInfo(Intrinsic intrin) { return(_intrinTable[(int)intrin]); }
public static void EmitVectorByScalarOpF32(ArmEmitterContext context, Intrinsic inst32, Intrinsic inst64) { OpCode32SimdRegElem op = (OpCode32SimdRegElem)context.CurrOp; Intrinsic inst = (op.Size & 1) != 0 ? inst64 : inst32; EmitVectorByScalarOpSimd32(context, (n, m) => context.AddIntrinsic(inst, n, m)); }
public static ValNumber IntrinsicByName(string name) { return(new ValNumber(Intrinsic.GetByName(name).id)); }
public TypeDefinition GetTypeDefinition(uint slot) { return(new TypeDefinition(Intrinsic.LoadPointer(Ptr, (IntPtr.Size * 4) + (IntPtr.Size * (int)slot)))); }
public static void EmitScalarUnaryOpF32(ArmEmitterContext context, Intrinsic inst32, Intrinsic inst64) { OpCode32SimdS op = (OpCode32SimdS)context.CurrOp; Intrinsic inst = (op.Size & 1) != 0 ? inst64 : inst32; EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m)); }
internal static IntPtr GetFunctionPointerForDelegateInternal(Delegate d) { return(Intrinsic.GetObjectAddress(d).LoadPointer(0).ToIntPtr()); }
public ProtectedRegionDefinition GetProtectedRegionDefinition(uint slot) { return(new ProtectedRegionDefinition(Intrinsic.LoadPointer(Ptr, IntPtr.Size + (IntPtr.Size * (int)slot)))); }
private static void EmitVectorTranspose(ArmEmitterContext context, int part) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; if (Optimizations.UseSsse3) { Operand mask = null; if (op.Size < 3) { long maskE0 = _masksE0_TrnUzpXtn[op.Size]; long maskE1 = _masksE1_TrnUzp [op.Size]; mask = X86GetScalar(context, maskE0); mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3); } Operand n = GetVec(op.Rn); if (op.Size < 3) { n = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask); } Operand m = GetVec(op.Rm); if (op.Size < 3) { m = context.AddIntrinsic(Intrinsic.X86Pshufb, m, mask); } Intrinsic punpckInst = part == 0 ? X86PunpcklInstruction[op.Size] : X86PunpckhInstruction[op.Size]; Operand res = context.AddIntrinsic(punpckInst, n, m); if (op.RegisterSize == RegisterSize.Simd64) { res = context.VectorZeroUpper64(res); } context.Copy(GetVec(op.Rd), res); } else { Operand res = context.VectorZero(); int pairs = op.GetPairsCount() >> op.Size; for (int index = 0; index < pairs; index++) { int pairIndex = index << 1; Operand ne = EmitVectorExtractZx(context, op.Rn, pairIndex + part, op.Size); Operand me = EmitVectorExtractZx(context, op.Rm, pairIndex + part, op.Size); res = EmitVectorInsert(context, res, ne, pairIndex, op.Size); res = EmitVectorInsert(context, res, me, pairIndex + 1, op.Size); } context.Copy(GetVec(op.Rd), res); } }
/// <inheritdoc /> public override object Run(Closure closure) { var operand = closure.Unbox <object>(this.operandNode.Run(closure)); if (operand == null && (this.targetType.CanBeNull || this.isTargetTypeNullable)) { return(null); } var operandType = closure.GetType(operand); var convertType = this.convertExpression.NodeType; if (convertType != ExpressionType.Convert) { convertType = ExpressionType.ConvertChecked; } // un-box if ((this.sourceType == typeof(object) || this.sourceType == typeof(ValueType) || this.sourceType.IsInterface) && this.targetType.IsValueType) { // null un-box if (operand == null) { throw new NullReferenceException(string.Format(Properties.Resources.EXCEPTION_EXECUTION_EXPRESSIONGIVESNULLRESULT, this.convertExpression.Operand)); } // type check for un-box if (operandType == this.targetType) { return(operand); } throw new InvalidCastException(); } // box else if (this.sourceType.IsValueType && (this.targetType == typeof(object) || this.targetType == typeof(ValueType) || this.targetType.IsInterface)) { // type check for box return(this.targetType.IsAssignableFrom(operandType) ? operand : null); } // to enum else if (this.targetType.IsEnum && (this.sourceType == typeof(byte) || this.sourceType == typeof(sbyte) || this.sourceType == typeof(short) || this.sourceType == typeof(ushort) || this.sourceType == typeof(int) || this.sourceType == typeof(uint) || this.sourceType == typeof(long) || this.sourceType == typeof(ulong))) { if (operand == null) { throw new NullReferenceException(string.Format(Properties.Resources.EXCEPTION_EXECUTION_EXPRESSIONGIVESNULLRESULT, this.convertExpression.Operand)); } operand = Intrinsic.InvokeConversion(closure, operand, Enum.GetUnderlyingType(this.targetType), this.convertExpression.NodeType, null); return(Enum.ToObject(this.targetType, closure.Unbox <object>(operand))); } // from enum else if (this.sourceType.IsEnum && (this.targetType == typeof(byte) || this.targetType == typeof(sbyte) || this.targetType == typeof(short) || this.targetType == typeof(ushort) || this.targetType == typeof(int) || this.targetType == typeof(uint) || this.targetType == typeof(long) || this.targetType == typeof(ulong))) { if (operand == null) { throw new NullReferenceException(string.Format(Properties.Resources.EXCEPTION_EXECUTION_EXPRESSIONGIVESNULLRESULT, this.convertExpression.Operand)); } operand = Convert.ChangeType(closure.Unbox <object>(operand), Enum.GetUnderlyingType(this.sourceType)); operand = Intrinsic.InvokeConversion(closure, operand, this.targetType, this.convertExpression.NodeType, null); return(operand); } // from nullable if (this.targetType.IsValueType && this.isSourceTypeNullable) { if (operand == null) { throw new NullReferenceException(string.Format(Properties.Resources.EXCEPTION_EXECUTION_EXPRESSIONGIVESNULLRESULT, this.convertExpression.Operand)); } operand = Intrinsic.InvokeConversion(closure, operand, this.targetType, this.convertExpression.NodeType, null); } else if (this.targetType.IsAssignableFrom(operandType)) { return(operand); } return(Intrinsic.InvokeConversion(closure, operand, this.targetType, convertType, this.operation)); }
private Page *AllocateInternal(uint pages, AllocatePageOptions options = default) { if (KConfig.Log.PageAllocation && TraceOptions.Enabled && pages >= TraceOptions.MinPages) { KernelMessage.Path(DebugName, "Requesting Pages: {1}. Available: {2} DebugName={0}", options.DebugName, pages, _FreePages); } if (pages == 256) { Debug.Nop(); } UninterruptibleMonitor.Enter(this); try { SelfCheck("SC1"); if (pages > 1 && (AddressSpaceKind == AddressSpaceKind.Virtual || options.Continuous)) { if (!MoveToFreeContinuous(pages)) { // Compact //KernelMessage.Path(DebugName, "Compacting Linked List"); //this.DumpPages(); BuildLinkedLists(); if (!MoveToFreeContinuous(pages)) { this.DumpPages(); KernelMessage.WriteLine("Requesting {0} pages failed", pages); Panic.Error("Requesting pages failed: out of memory"); } } } // --- var head = FreeList; var headPage = (Page *)head; FreeList = head->next; list_head.list_del_init(head); headPage->Status = PageStatus.Used; if (KConfig.Log.PageAllocation) { if (options.DebugName != null) { headPage->DebugTag = (uint)Intrinsic.GetObjectAddress(options.DebugName); } else { headPage->DebugTag = null; } } _FreePages--; // --- for (var i = 1; i < pages; i++) { var tmpNextFree = FreeList->next; list_head.list_move_tail(FreeList, head); var p = (Page *)FreeList; if (p->Status == PageStatus.Used) { this.DumpPages(); this.DumpPage(p); KernelMessage.Path(DebugName, "Double Alloc pages={0} allocs={1} free={2} ptr={3:X8}", pages, (uint)_Requests, _FreePages, (uint)p); Panic.Error("Double Alloc"); } p->Status = PageStatus.Used; FreeList = tmpNextFree; _FreePages--; } if (KConfig.Log.PageAllocation && TraceOptions.Enabled && pages >= TraceOptions.MinPages) { KernelMessage.Path(DebugName, "Allocation done. Addr: {0:X8} Available: {1}", GetAddress(headPage), _FreePages); } _Requests++; CheckAllocation(headPage, pages); SelfCheck("SC2"); return(headPage); } finally { UninterruptibleMonitor.Exit(this); } }
/// <summary> /// Decompresses the data using LibLZF algorithm /// </summary> /// <param name="input">Reference to the data to decompress</param> /// <param name="inputLength">Length of the data to decompress</param> /// <param name="output">Reference to a buffer which will contain the decompressed data</param> /// <param name="outputLength">The size of the decompressed archive in the output buffer</param> /// <returns></returns> public static bool Decompress(IntPtr input, uint inputLength, IntPtr output, uint outputLength) { uint iidx = 0; uint oidx = 0; do { //uint ctrl = input[iidx++]; uint ctrl = Intrinsic.Load8(input, iidx); iidx++; if (ctrl < (1 << 5)) /* literal run */ { ctrl++; if (oidx + ctrl > outputLength) { //SET_ERRNO (E2BIG); return(false); } do { //output[oidx++] = input[iidx++]; Intrinsic.Store8(output, oidx, Intrinsic.Load8(input, iidx)); oidx++; iidx++; }while ((--ctrl) != 0); } else /* back reference */ { uint len = ctrl >> 5; uint reference = (uint)(oidx - ((ctrl & 0x1f) << 8) - 1); if (len == 7) { //len += input[iidx++]; len += Intrinsic.Load8(input, iidx); iidx++; } //reference -= input[iidx++]; reference -= Intrinsic.Load8(input, iidx); iidx++; if (oidx + len + 2 > outputLength) { //SET_ERRNO (E2BIG); return(false); } //if (reference < 0) //{ // //SET_ERRNO (EINVAL); // return false; //} //output[oidx++] = output[reference++]; Intrinsic.Store8(output, oidx, Intrinsic.Load8(output, reference)); oidx++; reference++; //output[oidx++] = output[reference++]; Intrinsic.Store8(output, oidx, Intrinsic.Load8(output, reference)); oidx++; reference++; do { //output[oidx++] = output[reference++]; Intrinsic.Store8(output, oidx, Intrinsic.Load8(output, reference)); oidx++; reference++; }while ((--len) != 0); } }while (iidx < inputLength); return(true); }
protected SmbiosStructure(IntPtr address) { this.address = address; length = Intrinsic.Load8(address, 0x01u); handle = Intrinsic.Load16(address, 0x02u); }
public Operand AddIntrinsic(Intrinsic intrin, params Operand[] args) { return(Add(intrin, Local(OperandType.V128), args)); }
// TODO: Doc public void DefineBuiltin(string name, Intrinsic intr) => GlobalScope.Define(new Symbol.Const(name, intr.Type, new Value.User(intr)));
public Operand AddIntrinsicLong(Intrinsic intrin, params Operand[] args) { return(Add(intrin, Local(OperandType.I64), args)); }
public static ValNumber IntrinsicByName(string name) { return(ValNumber.Create(Intrinsic.GetByName(name).id)); }
private object ResolveArgumentValue(CustomAttributeArgument argument, Type type) { var typeCode = argument.ArgumentType.TypeCode; var valuePtr = argument.GetArgumentValue(); // If its an enum type if (argument.ArgumentType.ParentType.Handle == EnumTypePtr.Handle) { typeCode = argument.ArgumentType.ElementType.TypeCode; } switch (typeCode) { // 1 byte case TypeCode.Boolean: return((bool)(Intrinsic.Load8(valuePtr) != 0)); case TypeCode.U1: return((byte)Intrinsic.Load8(valuePtr)); case TypeCode.I1: return((sbyte)Intrinsic.Load8(valuePtr)); // 2 bytes case TypeCode.Char: return((char)Intrinsic.Load16(valuePtr)); case TypeCode.U2: return((ushort)Intrinsic.Load16(valuePtr)); case TypeCode.I2: return((short)Intrinsic.Load16(valuePtr)); // 4 bytes case TypeCode.U4: return((uint)Intrinsic.Load32(valuePtr)); case TypeCode.I4: return((int)Intrinsic.Load32(valuePtr)); case TypeCode.R4: return(Intrinsic.LoadR4(valuePtr)); // 8 bytes case TypeCode.U8: return((ulong)Intrinsic.Load64(valuePtr)); case TypeCode.I8: return((long)Intrinsic.Load64(valuePtr)); case TypeCode.R8: return(Intrinsic.LoadR8(valuePtr)); // SZArray case TypeCode.SZArray: return(ResolveArrayValue(argument, type)); // String case TypeCode.String: return((string)Intrinsic.GetObjectFromAddress(valuePtr)); default: if (type.FullName == "System.Type") { // Get the argument type var argTypeHandle = new RuntimeTypeHandle(argument.ArgumentType.Ptr); return(Type.GetTypeFromHandle(argTypeHandle)); } throw new ArgumentException(); } }
public static void SetUnitTestMethodParameter(uint index, uint value) { Intrinsic.Store32(new IntPtr(Address.UnitTestStack), index * 4, value); }
public static void EmitScalarTernaryOpF32(ArmEmitterContext context, Intrinsic inst32pt1, Intrinsic inst64pt1, Intrinsic inst32pt2, Intrinsic inst64pt2) { OpCode32SimdRegS op = (OpCode32SimdRegS)context.CurrOp; bool doubleSize = (op.Size & 1) != 0; int shift = doubleSize ? 1 : 2; Intrinsic inst1 = doubleSize ? inst64pt1 : inst32pt1; Intrinsic inst2 = doubleSize ? inst64pt2 : inst32pt2; EmitScalarTernaryOpSimd32(context, (d, n, m) => { Operand res = context.AddIntrinsic(inst1, n, m); return(context.AddIntrinsic(inst2, d, res)); }); }
public static void EnterTestReadyLoop() { uint testCount = 0; Debugger.Ready(); Screen.Write("Waiting for unit tests..."); Screen.NextLine(); Screen.NextLine(); // allocate space on stack for parameters uint esp = Native.AllocateStackSpace(MaxParameters * 4); Screen.Write("Stack @ "); Screen.Write((uint)esp, 16, 8); Screen.NextLine(); Screen.NextLine(); uint row = Screen.Row; while (true) { if (testReady == 1) { Screen.Goto(row, 0); Screen.ClearRow(); Screen.Write("Test #: "); Screen.Write(++testCount, 10, 7); testResult = 0; testResultReady = 0; testResultReported = 0; testReady = 0; // copy parameters into stack for (uint index = 0; index < testParameters; index++) { uint value = Intrinsic.Load32(new IntPtr(Address.UnitTestStack), (index * 4)); Intrinsic.Store32(new IntPtr(esp), index * 4, value); } switch (testResultType) { case 0: Native.FrameCall(testMethodAddress); break; case 1: testResult = Native.FrameCallRetU4(testMethodAddress); break; case 2: testResult = Native.FrameCallRetU8(testMethodAddress); break; case 3: testResult = Native.FrameCallRetR8(testMethodAddress); break; default: break; } testResultReady = 1; Native.Int(255); } } }
public static void EmitVectorsByScalarOpF32(ArmEmitterContext context, Intrinsic inst32pt1, Intrinsic inst64pt1, Intrinsic inst32pt2, Intrinsic inst64pt2) { OpCode32SimdRegElem op = (OpCode32SimdRegElem)context.CurrOp; Intrinsic inst1 = (op.Size & 1) != 0 ? inst64pt1 : inst32pt1; Intrinsic inst2 = (op.Size & 1) != 0 ? inst64pt2 : inst32pt2; EmitVectorsByScalarOpSimd32(context, (d, n, m) => { Operand res = context.AddIntrinsic(inst1, n, m); return(res = context.AddIntrinsic(inst2, d, res)); }); }
private static void EmitVectorUnzip(ArmEmitterContext context, int part) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; if (Optimizations.UseSsse3) { if (op.RegisterSize == RegisterSize.Simd128) { Operand mask = default; if (op.Size < 3) { long maskE0 = EvenMasks[op.Size]; long maskE1 = OddMasks [op.Size]; mask = X86GetScalar(context, maskE0); mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3); } Operand n = GetVec(op.Rn); if (op.Size < 3) { n = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask); } Operand m = GetVec(op.Rm); if (op.Size < 3) { m = context.AddIntrinsic(Intrinsic.X86Pshufb, m, mask); } Intrinsic punpckInst = part == 0 ? Intrinsic.X86Punpcklqdq : Intrinsic.X86Punpckhqdq; Operand res = context.AddIntrinsic(punpckInst, n, m); context.Copy(GetVec(op.Rd), res); } else { Operand n = GetVec(op.Rn); Operand m = GetVec(op.Rm); Intrinsic punpcklInst = X86PunpcklInstruction[op.Size]; Operand res = context.AddIntrinsic(punpcklInst, n, m); if (op.Size < 2) { long maskE0 = _masksE0_Uzp[op.Size]; long maskE1 = _masksE1_Uzp[op.Size]; Operand mask = X86GetScalar(context, maskE0); mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3); res = context.AddIntrinsic(Intrinsic.X86Pshufb, res, mask); } Intrinsic punpckInst = part == 0 ? Intrinsic.X86Punpcklqdq : Intrinsic.X86Punpckhqdq; res = context.AddIntrinsic(punpckInst, res, context.VectorZero()); context.Copy(GetVec(op.Rd), res); } } else { Operand res = context.VectorZero(); int pairs = op.GetPairsCount() >> op.Size; for (int index = 0; index < pairs; index++) { int idx = index << 1; Operand ne = EmitVectorExtractZx(context, op.Rn, idx + part, op.Size); Operand me = EmitVectorExtractZx(context, op.Rm, idx + part, op.Size); res = EmitVectorInsert(context, res, ne, index, op.Size); res = EmitVectorInsert(context, res, me, pairs + index, op.Size); } context.Copy(GetVec(op.Rd), res); } }
/// <summary> /// Evaluate this line and return the value that would be stored /// into the lhs. /// </summary> public Value Evaluate(Context context) { if (op == Op.AssignA || op == Op.ReturnA || op == Op.AssignImplicit) { // Assignment is a bit of a special case. It's EXTREMELY common // in TAC, so needs to be efficient, but we have to watch out for // the case of a RHS that is a list or map. This means it was a // literal in the source, and may contain references that need to // be evaluated now. if (rhsA is ValList || rhsA is ValMap) { return(rhsA.FullEval(context)); } else if (rhsA == null) { return(null); } else { return(rhsA.Val(context)); } } if (op == Op.CopyA) { // This opcode is used for assigning a literal. We actually have // to copy the literal, in the case of a mutable object like a // list or map, to ensure that if the same code executes again, // we get a new, unique object. if (rhsA is ValList) { return(((ValList)rhsA).EvalCopy(context)); } else if (rhsA is ValMap) { return(((ValMap)rhsA).EvalCopy(context)); } else if (rhsA == null) { return(null); } else { return(rhsA.Val(context)); } } Value opA = rhsA != null?rhsA.Val(context) : null; Value opB = rhsB != null?rhsB.Val(context) : null; if (op == Op.AisaB) { return(ValNumber.Truth(opA.IsA(opB, context.vm))); } if (op == Op.ElemBofA && opB is ValString) { // You can now look for a string in almost anything... // and we have a convenient (and relatively fast) method for it: ValMap ignored; return(ValSeqElem.Resolve(opA, ((ValString)opB).value, context, out ignored)); } if (op == Op.AEqualB && (opA == null || opB == null)) { return(ValNumber.Truth(opA == opB)); } if (op == Op.ANotEqualB && (opA == null || opB == null)) { return(ValNumber.Truth(opA != opB)); } if (opA is ValNumber) { double fA = ((ValNumber)opA).value; switch (op) { case Op.GotoA: context.lineNum = (int)fA; return(null); case Op.GotoAifB: if (opB != null && opB.BoolValue()) { context.lineNum = (int)fA; } return(null); case Op.GotoAifTrulyB: { // Unlike GotoAifB, which branches if B has any nonzero // value (including 0.5 or 0.001), this branches only if // B is TRULY true, i.e., its integer value is nonzero. // (Used for short-circuit evaluation of "or".) int i = 0; if (opB != null) { i = opB.IntValue(); } if (i != 0) { context.lineNum = (int)fA; } return(null); } case Op.GotoAifNotB: if (opB == null || !opB.BoolValue()) { context.lineNum = (int)fA; } return(null); case Op.CallIntrinsicA: // NOTE: intrinsics do not go through NextFunctionContext. Instead // they execute directly in the current context. (But usually, the // current context is a wrapper function that was invoked via // Op.CallFunction, so it got a parameter context at that time.) Intrinsic.Result result = Intrinsic.Execute((int)fA, context, context.partialResult); if (result.done) { context.partialResult = null; return(result.result); } // OK, this intrinsic function is not yet done with its work. // We need to stay on this same line and call it again with // the partial result, until it reports that its job is complete. context.partialResult = result; context.lineNum--; return(null); case Op.NotA: return(new ValNumber(1.0 - AbsClamp01(fA))); } if (opB is ValNumber || opB == null) { double fB = opB != null ? ((ValNumber)opB).value : 0; switch (op) { case Op.APlusB: return(new ValNumber(fA + fB)); case Op.AMinusB: return(new ValNumber(fA - fB)); case Op.ATimesB: return(new ValNumber(fA * fB)); case Op.ADividedByB: return(new ValNumber(fA / fB)); case Op.AModB: return(new ValNumber(fA % fB)); case Op.APowB: return(new ValNumber(Math.Pow(fA, fB))); case Op.AEqualB: return(ValNumber.Truth(fA == fB)); case Op.ANotEqualB: return(ValNumber.Truth(fA != fB)); case Op.AGreaterThanB: return(ValNumber.Truth(fA > fB)); case Op.AGreatOrEqualB: return(ValNumber.Truth(fA >= fB)); case Op.ALessThanB: return(ValNumber.Truth(fA < fB)); case Op.ALessOrEqualB: return(ValNumber.Truth(fA <= fB)); case Op.AAndB: if (!(opB is ValNumber)) { fB = opB != null && opB.BoolValue() ? 1 : 0; } return(new ValNumber(Clamp01(fA * fB))); case Op.AOrB: if (!(opB is ValNumber)) { fB = opB != null && opB.BoolValue() ? 1 : 0; } return(new ValNumber(Clamp01(fA + fB - fA * fB))); default: break; } } else if (opB is ValString) { // number (op) string string sA = opA.ToString(); string sB = opB.ToString(); switch (op) { case Op.APlusB: return(new ValString(sA + sB)); default: break; } } } else if (opA is ValString) { string sA = ((ValString)opA).value; switch (op) { case Op.APlusB: { if (opB == null) { return(opA); } String sB = opB.ToString(context.vm); if (sA.Length + sB.Length > ValString.maxSize) { throw new LimitExceededException("string too large"); } return(new ValString(sA + sB)); } case Op.AMinusB: { if (opB == null) { return(opA); } string sB = opB.ToString(context.vm); if (sA.EndsWith(sB)) { sA = sA.Substring(0, sA.Length - sB.Length); } return(new ValString(sA)); } case Op.ATimesB: case Op.ADividedByB: { double factor = 0; if (op == Op.ATimesB) { Check.Type(opB, typeof(ValNumber), "string replication"); factor = ((ValNumber)opB).value; } else { Check.Type(opB, typeof(ValNumber), "string division"); factor = 1.0 / ((ValNumber)opB).value; } int repeats = (int)factor; if (repeats < 0) { return(ValString.empty); } if (repeats * sA.Length > ValString.maxSize) { throw new LimitExceededException("string too large"); } var result = new System.Text.StringBuilder(); for (int i = 0; i < repeats; i++) { result.Append(sA); } int extraChars = (int)(sA.Length * (factor - repeats)); if (extraChars > 0) { result.Append(sA.Substring(0, extraChars)); } return(new ValString(result.ToString())); } case Op.AEqualB: return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) == 0)); case Op.ANotEqualB: return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) != 0)); case Op.AGreaterThanB: return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) > 0)); case Op.AGreatOrEqualB: return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) >= 0)); case Op.ALessThanB: return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) < 0)); case Op.ALessOrEqualB: return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) <= 0)); case Op.ElemBofA: case Op.ElemBofIterA: { int idx = opB.IntValue(); Check.Range(idx, -sA.Length, sA.Length - 1, "string index"); if (idx < 0) { idx += sA.Length; } return(new ValString(sA.Substring(idx, 1))); } case Op.LengthOfA: return(new ValNumber(sA.Length)); default: break; } } else if (opA is ValList) { List <Value> list = ((ValList)opA).values; if (op == Op.ElemBofA || op == Op.ElemBofIterA) { // list indexing int idx = opB.IntValue(); Check.Range(idx, -list.Count, list.Count - 1, "list index"); if (idx < 0) { idx += list.Count; } return(list[idx]); } else if (op == Op.LengthOfA) { return(new ValNumber(list.Count)); } else if (op == Op.AEqualB) { return(ValNumber.Truth(((ValList)opA).Equality(opB))); } else if (op == Op.ANotEqualB) { return(ValNumber.Truth(1.0 - ((ValList)opA).Equality(opB))); } else if (op == Op.APlusB) { // list concatenation Check.Type(opB, typeof(ValList), "list concatenation"); List <Value> list2 = ((ValList)opB).values; if (list.Count + list2.Count > ValList.maxSize) { throw new LimitExceededException("list too large"); } List <Value> result = new List <Value>(list.Count + list2.Count); foreach (Value v in list) { result.Add(v == null ? null : v.Val(context)); } foreach (Value v in list2) { result.Add(v == null ? null : v.Val(context)); } return(new ValList(result)); } else if (op == Op.ATimesB || op == Op.ADividedByB) { // list replication (or division) double factor = 0; if (op == Op.ATimesB) { Check.Type(opB, typeof(ValNumber), "list replication"); factor = ((ValNumber)opB).value; } else { Check.Type(opB, typeof(ValNumber), "list division"); factor = 1.0 / ((ValNumber)opB).value; } if (factor <= 0) { return(new ValList()); } int finalCount = (int)(list.Count * factor); if (finalCount > ValList.maxSize) { throw new LimitExceededException("list too large"); } List <Value> result = new List <Value>(finalCount); for (int i = 0; i < finalCount; i++) { result.Add(list[i % list.Count]); } return(new ValList(result)); } else if (op == Op.NotA) { return(ValNumber.Truth(!opA.BoolValue())); } } else if (opA is ValMap) { if (op == Op.ElemBofA) { // map lookup // (note, cases where opB is a string are handled above, along with // all the other types; so we'll only get here for non-string cases) ValSeqElem se = new ValSeqElem(opA, opB); return(se.Val(context)); // (This ensures we walk the "__isa" chain in the standard way.) } else if (op == Op.ElemBofIterA) { // With a map, ElemBofIterA is different from ElemBofA. This one // returns a mini-map containing a key/value pair. return(((ValMap)opA).GetKeyValuePair(opB.IntValue())); } else if (op == Op.LengthOfA) { return(new ValNumber(((ValMap)opA).Count)); } else if (op == Op.AEqualB) { return(ValNumber.Truth(((ValMap)opA).Equality(opB))); } else if (op == Op.ANotEqualB) { return(ValNumber.Truth(1.0 - ((ValMap)opA).Equality(opB))); } else if (op == Op.APlusB) { // map combination Dictionary <Value, Value> map = ((ValMap)opA).map; Check.Type(opB, typeof(ValMap), "map combination"); Dictionary <Value, Value> map2 = ((ValMap)opB).map; ValMap result = new ValMap(); foreach (KeyValuePair <Value, Value> kv in map) { result.map[kv.Key] = kv.Value.Val(context); } foreach (KeyValuePair <Value, Value> kv in map2) { result.map[kv.Key] = kv.Value.Val(context); } return(result); } else if (op == Op.NotA) { return(ValNumber.Truth(!opA.BoolValue())); } } else if (opA is ValFunction && opB is ValFunction) { Function fA = ((ValFunction)opA).function; Function fB = ((ValFunction)opB).function; switch (op) { case Op.AEqualB: return(ValNumber.Truth(fA == fB)); case Op.ANotEqualB: return(ValNumber.Truth(fA != fB)); } } else { // opA is something else... perhaps null switch (op) { case Op.NotA: return(opA != null && opA.BoolValue() ? ValNumber.zero : ValNumber.one); } } if (op == Op.AAndB || op == Op.AOrB) { // We already handled the case where opA was a number above; // this code handles the case where opA is something else. double fA = opA != null && opA.BoolValue() ? 1 : 0; double fB; if (opB is ValNumber) { fB = ((ValNumber)opB).value; } else { fB = opB != null && opB.BoolValue() ? 1 : 0; } double result; if (op == Op.AAndB) { result = fA * fB; } else { result = 1.0 - (1.0 - AbsClamp01(fA)) * (1.0 - AbsClamp01(fB)); } return(new ValNumber(result)); } return(null); }
/// <summary> /// Releases a page to the free list /// </summary> /// <param name="address">The address.</param> public static void Free(IntPtr address) { totalUsedPages--; at += 4; Intrinsic.Store32(at, address.ToInt32()); }
private static void Add(Intrinsic intrin, IntrinsicInfo info) { _intrinTable[(int)intrin] = info; }
internal static IntPtr GetFunctionPointerForDelegateInternal(Delegate d) { return(Intrinsic.LoadPointer(Intrinsic.GetObjectAddress(d), IntPtr.Size * 2)); }
private static void IRQ251() { Intrinsic.SuppressStackFrame(); Native.IRQ251(); }
private static IntPtr GetPointer(uint offset) { return(Intrinsic.LoadPointer(VBEModeInfo, offset)); }