public static void Abort(BinaryOpStorage/*!*/ writeStorage, object/*!*/ self, [DefaultProtocol, NotNull]MutableString/*!*/ message) { var site = writeStorage.GetCallSite("write", 1); site.Target(site, writeStorage.Context.StandardErrorOutput, message); Exit(self, 1); }
public void Initialize(BinaryOpStorage/*!*/ comparisonStorage, RubyContext/*!*/ context, object begin, object end, bool excludeEnd) { if (_initialized) { throw RubyExceptions.CreateNameError("`initialize' called twice"); } // Range tests whether the items can be compared, and uses that to determine if the range is valid // Only a non-existent <=> method or a result of nil seems to trigger the exception. object compareResult; var site = comparisonStorage.GetCallSite("<=>"); try { compareResult = site.Target(site, begin, end); } catch (Exception) { compareResult = null; } if (compareResult == null) { throw RubyExceptions.CreateArgumentError("bad value for range"); } _begin = begin; _end = end; _excludeEnd = excludeEnd; _initialized = true; }
public static object Abs(BinaryOpStorage/*!*/ lessThanStorage, UnaryOpStorage/*!*/ minusStorage, object self) { var lessThan = lessThanStorage.GetCallSite("<"); if (RubyOps.IsTrue(lessThan.Target(lessThan, self, 0))) { var minus = minusStorage.GetCallSite("-@"); return minus.Target(minus, self); } return self; }
public static object DefineFinalizer(RespondToStorage/*!*/ respondTo, BinaryOpStorage/*!*/ call, RubyModule/*!*/ self, object obj, object finalizer) { if (!Protocols.RespondTo(respondTo, finalizer, "call")) { throw RubyExceptions.CreateArgumentError("finalizer should be callable (respond to :call)"); } respondTo.Context.SetInstanceVariable(obj, FinalizerInvoker.InstanceVariableName, new FinalizerInvoker(call.GetCallSite("call"), finalizer)); RubyArray result = new RubyArray(2); result.Add(0); result.Add(finalizer); return result; }
/// <summary> /// Try to compare the lhs and rhs. Throws and exception if comparison returns null. Returns null on failure, -1/0/+1 otherwise. /// </summary> private static int? Compare(BinaryOpStorage/*!*/ compareStorage, BinaryOpStorage/*!*/ lessThanStorage, BinaryOpStorage/*!*/ greaterThanStorage, object lhs, object rhs) { // calls method_missing, doesn't catch any exception: var compare = compareStorage.GetCallSite("<=>"); object compareResult = compare.Target(compare, lhs, rhs); if (compareResult != null) { return Protocols.ConvertCompareResult(lessThanStorage, greaterThanStorage, compareResult); } else { throw RubyExceptions.MakeComparisonError(lessThanStorage.Context, lhs, rhs); } }
public static bool Equal(BinaryOpStorage/*!*/ compareStorage, object self, object other) { if (self == other) { return true; } // calls method_missing: var compare = compareStorage.GetCallSite("<=>"); object compareResult; try { compareResult = compare.Target(compare, self, other); } catch (SystemException) { // catches StandardError (like rescue) return false; } return compareResult is int && (int)compareResult == 0; }
public static object Compare(BinaryOpStorage/*!*/ comparisonStorage, RespondToStorage/*!*/ respondToStorage, object/*!*/ self, object other) { // Self is object so that we can reuse this method. // We test to see if other responds to to_str AND <=> // Ruby never attempts to convert other to a string via to_str and call Compare ... which is strange -- feels like a BUG in Ruby if (Protocols.RespondTo(respondToStorage, other, "to_str") && Protocols.RespondTo(respondToStorage, other, "<=>")) { var site = comparisonStorage.GetCallSite("<=>"); object result = Integer.TryUnaryMinus(site.Target(site, other, self)); if (result == null) { throw RubyExceptions.CreateTypeError(String.Format("{0} can't be coerced into Fixnum", comparisonStorage.Context.GetClassDisplayName(result))); } return result; } return null; }
public static object Modulo(BinaryOpStorage /*!*/ moduloStorage, object self, object other) { var modulo = moduloStorage.GetCallSite("%"); return(modulo.Target(modulo, self, other)); }
public static object CopyStream( ConversionStorage<MutableString>/*!*/ toPath, ConversionStorage<int>/*!*/ toInt, RespondToStorage/*!*/ respondTo, BinaryOpStorage/*!*/ writeStorage, CallSiteStorage<Func<CallSite, object, object, object, object>>/*!*/ readStorage, RubyClass/*!*/ self, object src, object dst, [DefaultParameterValue(-1)]int count, [DefaultParameterValue(-1)]int src_offset) { if (count < -1) { throw RubyExceptions.CreateArgumentError("count should be >= -1"); } if (src_offset < -1) { throw RubyExceptions.CreateArgumentError("src_offset should be >= -1"); } RubyIO srcIO = src as RubyIO; RubyIO dstIO = dst as RubyIO; Stream srcStream = null, dstStream = null; var context = toPath.Context; CallSite<Func<CallSite, object, object, object>> writeSite = null; CallSite<Func<CallSite, object, object, object, object>> readSite = null; try { if (srcIO == null || dstIO == null) { var toPathSite = toPath.GetSite(TryConvertToPathAction.Make(toPath.Context)); var srcPath = toPathSite.Target(toPathSite, src); if (srcPath != null) { srcStream = new FileStream(context.DecodePath(srcPath), FileMode.Open, FileAccess.Read); } else { readSite = readStorage.GetCallSite("read", 2); } var dstPath = toPathSite.Target(toPathSite, dst); if (dstPath != null) { dstStream = new FileStream(context.DecodePath(dstPath), FileMode.Truncate); } else { writeSite = writeStorage.GetCallSite("write", 1); } } else { srcStream = srcIO.GetReadableStream(); dstStream = dstIO.GetWritableStream(); } if (src_offset != -1) { if (srcStream == null) { throw RubyExceptions.CreateArgumentError("cannot specify src_offset for non-IO"); } srcStream.Seek(src_offset, SeekOrigin.Current); } MutableString userBuffer = null; byte[] buffer = null; long bytesCopied = 0; long remaining = (count < 0) ? Int64.MaxValue : count; int minBufferSize = 16 * 1024; if (srcStream != null) { buffer = new byte[Math.Min(minBufferSize, remaining)]; } while (remaining > 0) { int bytesRead; int chunkSize = (int)Math.Min(minBufferSize, remaining); if (srcStream != null) { userBuffer = null; bytesRead = srcStream.Read(buffer, 0, chunkSize); } else { userBuffer = MutableString.CreateBinary(); bytesRead = Protocols.CastToFixnum(toInt, readSite.Target(readSite, src, chunkSize, userBuffer)); } if (bytesRead <= 0) { break; } if (dstStream != null) { if (userBuffer != null) { dstStream.Write(userBuffer, 0, bytesRead); } else { dstStream.Write(buffer, 0, bytesRead); } } else { if (userBuffer == null) { userBuffer = MutableString.CreateBinary(bytesRead).Append(buffer, 0, bytesRead); } else { userBuffer.SetByteCount(bytesRead); } writeSite.Target(writeSite, dst, userBuffer); } bytesCopied += bytesRead; remaining -= bytesRead; } return Protocols.Normalize(bytesCopied); } finally { if (srcStream != null) { srcStream.Close(); } if (dstStream != null) { dstStream.Close(); } } }
public static void Write(BinaryOpStorage/*!*/ writeStorage, object target, object value) { var site = writeStorage.GetCallSite("write"); site.Target(site, target, value); }
public static int ConvertCompareResult( BinaryOpStorage/*!*/ lessThanStorage, BinaryOpStorage/*!*/ greaterThanStorage, object/*!*/ result) { Debug.Assert(result != null); var greaterThanSite = greaterThanStorage.GetCallSite(">"); if (RubyOps.IsTrue(greaterThanSite.Target(greaterThanSite, result, 0))) { return 1; } var lessThanSite = lessThanStorage.GetCallSite("<"); if (RubyOps.IsTrue(lessThanSite.Target(lessThanSite, result, 0))) { return -1; } return 0; }
public static object Compare(BinaryOpStorage/*!*/ comparisonStorage, IList/*!*/ self, [DefaultProtocol, NotNull]IList/*!*/ other) { using (IDisposable handle = _infiniteComparisonTracker.TrackObject(self)) { if (handle == null) { return 0; } int limit = Math.Min(self.Count, other.Count); var compare = comparisonStorage.GetCallSite("<=>"); for (int i = 0; i < limit; i++) { object result = compare.Target(compare, self[i], other[i]); if (!(result is int) || (int)result != 0) { return result; } } return ScriptingRuntimeHelpers.Int32ToObject(Math.Sign(self.Count - other.Count)); } }
public static object Remainder( BinaryOpStorage/*!*/ equals, BinaryOpStorage/*!*/ greaterThanStorage, BinaryOpStorage/*!*/ lessThanStorage, BinaryOpStorage/*!*/ minusStorage, BinaryOpStorage/*!*/ moduloStorage, RubyContext/*!*/ context, object self, object other) { var modulo = moduloStorage.GetCallSite("%"); object remainder = modulo.Target(modulo, context, self, other); if (!Protocols.IsEqual(equals, context, remainder, 0)) { var greaterThan = greaterThanStorage.GetCallSite(">"); var lessThan = lessThanStorage.GetCallSite("<"); // modulo is not zero if (RubyOps.IsTrue(lessThan.Target(lessThan, context, self, 0)) && RubyOps.IsTrue(greaterThan.Target(greaterThan, context, other, 0)) || RubyOps.IsTrue(greaterThan.Target(greaterThan, context, self, 0)) && RubyOps.IsTrue(lessThan.Target(lessThan, context, other, 0))) { // (self is negative and other is positive) OR (self is positive and other is negative) var minus = minusStorage.GetCallSite("-"); return minus.Target(minus, context, remainder, other); } } // Either modulo is zero or self and other are not of the same sign return remainder; }
public static object Modulo( BinaryOpStorage/*!*/ moduloStorage, RubyContext/*!*/ context, object self, object other) { var modulo = moduloStorage.GetCallSite("%"); return modulo.Target(modulo, context, self, other); }
public static object Div( BinaryOpStorage/*!*/ divideStorage, RubyContext/*!*/ context, object self, object other) { var divide = divideStorage.GetCallSite("/"); return Floor(context, divide.Target(divide, context, self, other)); }
public static bool Equals(RespondToStorage/*!*/ respondToStorage, BinaryOpStorage/*!*/ equalsStorage, object/*!*/ self, object other) { // Self is object so that we can reuse this method. if (!Protocols.RespondTo(respondToStorage, other, "to_str")) { return false; } var equals = equalsStorage.GetCallSite("=="); return Protocols.IsTrue(equals.Target(equals, other, self)); }
public static object Quo(BinaryOpStorage /*!*/ divideStorage, object self, object other) { var site = divideStorage.GetCallSite("/"); return(site.Target(site, self, other)); }
public static object Modulo(BinaryOpStorage /*!*/ moduloStorage, RubyContext /*!*/ context, BigDecimal /*!*/ self, double other) { var modulo = moduloStorage.GetCallSite("modulo"); return(modulo.Target(modulo, BigDecimal.ToFloat(GetConfig(context), self), other)); }
public static object Step( BinaryOpStorage /*!*/ equals, BinaryOpStorage /*!*/ greaterThanStorage, BinaryOpStorage /*!*/ lessThanStorage, BinaryOpStorage /*!*/ addStorage, ConversionStorage <double> /*!*/ tofStorage, BlockParam block, object self, object limit, [Optional] object step) { if (step == Missing.Value) { step = ClrInteger.One; } if (self is double || limit is double || step is double) { var site = tofStorage.GetSite(ConvertToFAction.Make(tofStorage.Context)); // At least one of the arguments is double so convert all to double and run the Float version of Step double floatSelf = self is double?(double)self : site.Target(site, self); double floatLimit = limit is double?(double)self : site.Target(site, limit); double floatStep = step is double?(double)self : site.Target(site, step); return(Step(block, floatSelf, floatLimit, floatStep)); } else { #region The generic step algorithm: // current = self // if step is postive then // while current < limit do // yield(current) // current = current + step // end // else // while current > limit do // yield(current) // current = current + step // end // return self #endregion bool isStepZero = Protocols.IsEqual(equals, step, 0); if (isStepZero) { throw RubyExceptions.CreateArgumentError("step can't be 0"); } var greaterThan = greaterThanStorage.GetCallSite(">"); bool isStepPositive = RubyOps.IsTrue(greaterThan.Target(greaterThan, step, 0)); var compare = isStepPositive ? greaterThan : lessThanStorage.GetCallSite("<"); object current = self; while (!RubyOps.IsTrue(compare.Target(compare, current, limit))) { object result; if (YieldStep(block, current, out result)) { return(result); } var add = addStorage.GetCallSite("+"); current = add.Target(add, current, step); } return(self); } }
public static object Wrap(BinaryOpStorage/*!*/ newStorage, UnaryOpStorage/*!*/ closeStorage, BlockParam block, RubyClass/*!*/ self, object io) { var newSite = newStorage.GetCallSite("new"); GZipFile gzipFile = (GZipFile)newSite.Target(newSite, self, io); return gzipFile.Do(block); }
public static object Next(BinaryOpStorage/*!*/ addStorage, RubyContext/*!*/ context, object/*!*/ self) { var site = addStorage.GetCallSite("+"); return site.Target(site, context, self, 1); }
public static RubyArray DivMod( BinaryOpStorage/*!*/ divideStorage, BinaryOpStorage/*!*/ moduloStorage, RubyContext/*!*/ context, object self, object other) { object div = Div(divideStorage, context, self, other); var modulo = moduloStorage.GetCallSite("modulo"); object mod = modulo.Target(modulo, context, self, other); return RubyOps.MakeArray2(div, mod); }
public static void ReportWarning(BinaryOpStorage/*!*/ writeStorage, ConversionStorage<MutableString>/*!*/ tosConversion, object self, object message) { if (writeStorage.Context.Verbose != null) { var output = writeStorage.Context.StandardErrorOutput; // MRI: unlike Kernel#puts this outputs \n even if the message ends with \n: var site = writeStorage.GetCallSite("write", 1); site.Target(site, output, RubyIOOps.ToPrintedString(tosConversion, message)); RubyIOOps.PutsEmptyLine(writeStorage, output); } }
public static object Quo(BinaryOpStorage/*!*/ divideStorage, RubyContext/*!*/ context, object self, object other) { var site = divideStorage.GetCallSite("/"); return site.Target(site, context, self, other); }
internal static Exception/*!*/ CreateExceptionToRaise(RespondToStorage/*!*/ respondToStorage, UnaryOpStorage/*!*/ storage0, BinaryOpStorage/*!*/ storage1, CallSiteStorage<Action<CallSite, Exception, RubyArray>>/*!*/ setBackTraceStorage, object/*!*/ obj, object arg, RubyArray backtrace) { if (Protocols.RespondTo(respondToStorage, obj, "exception")) { Exception e = null; if (arg != Missing.Value) { var site = storage1.GetCallSite("exception"); e = site.Target(site, obj, arg) as Exception; } else { var site = storage0.GetCallSite("exception"); e = site.Target(site, obj) as Exception; } if (e != null) { if (backtrace != null) { var site = setBackTraceStorage.GetCallSite("set_backtrace", 1); site.Target(site, e, backtrace); } return e; } } throw RubyExceptions.CreateTypeError("exception class/object expected"); }
public static object Step( BinaryOpStorage/*!*/ equals, BinaryOpStorage/*!*/ greaterThanStorage, BinaryOpStorage/*!*/ lessThanStorage, BinaryOpStorage/*!*/ addStorage, RubyContext/*!*/ context, BlockParam block, object self, object limit, [Optional]object step) { if (step == Missing.Value) { step = ScriptingRuntimeHelpers.Int32ToObject(1); } if (self is double || limit is double || step is double) { // At least one of the arguments is double so convert all to double and run the Float version of Step double floatSelf = Protocols.ConvertToFloat(context, self); double floatLimit = Protocols.ConvertToFloat(context, limit); double floatStep = Protocols.ConvertToFloat(context, step); return Step(context, block, floatSelf, floatLimit, floatSelf); } else { #region The generic step algorithm: // current = self // if step is postive then // while current < limit do // yield(current) // current = current + step // end // else // while current > limit do // yield(current) // current = current + step // end // return self #endregion bool isStepZero = Protocols.IsEqual(equals, context, step, 0); if (isStepZero) { throw RubyExceptions.CreateArgumentError("step can't be 0"); } var greaterThan = greaterThanStorage.GetCallSite(">"); bool isStepPositive = RubyOps.IsTrue(greaterThan.Target(greaterThan, context, step, 0)); var compare = isStepPositive ? greaterThan : lessThanStorage.GetCallSite("<"); object current = self; while (!RubyOps.IsTrue(compare.Target(compare, context, current, limit))) { object result; if (YieldStep(block, current, out result)) { return result; } var add = addStorage.GetCallSite("+"); current = add.Target(add, context, current, step); } return self; } }
public static object DownTo(BinaryOpStorage/*!*/ lessThanStorage, BinaryOpStorage/*!*/ subtractStorage, BlockParam block, object/*!*/ self, object other) { object i = self; object compare = null; var lessThan = lessThanStorage.GetCallSite("<"); while (RubyOps.IsFalse(compare)) { // Rather than test i >= other we test !(i < other) compare = lessThan.Target(lessThan, i, other); // If the comparison failed (i.e. returned null) then we throw an error. if (compare == null) { throw RubyExceptions.MakeComparisonError(lessThanStorage.Context, i, other); } // If the comparison worked but returned false then we if (RubyOps.IsFalse(compare)) { object result; if (block == null) { throw RubyExceptions.NoBlockGiven(); } if (block.Yield(i, out result)) { return result; } var subtract = subtractStorage.GetCallSite("-"); i = subtract.Target(subtract, i, 1); } } return self; }
/// <summary> /// Try to compare the lhs and rhs. Throws and exception if comparison returns null. Returns -1/0/+1 otherwise. /// </summary> public static int Compare( BinaryOpStorage/*!*/ comparisonStorage, BinaryOpStorage/*!*/ lessThanStorage, BinaryOpStorage/*!*/ greaterThanStorage, object lhs, object rhs) { var compare = comparisonStorage.GetCallSite("<=>"); var result = compare.Target(compare, lhs, rhs); if (result != null) { return Protocols.ConvertCompareResult(lessThanStorage, greaterThanStorage, result); } else { throw RubyExceptions.MakeComparisonError(comparisonStorage.Context, lhs, rhs); } }
public static object Next(BinaryOpStorage/*!*/ addStorage, object/*!*/ self) { var site = addStorage.GetCallSite("+"); return site.Target(site, self, ClrInteger.One); }
/// <summary> /// Protocol for determining value equality in Ruby (uses IsTrue protocol on result of == call) /// </summary> public static bool IsEqual(BinaryOpStorage/*!*/ equals, object lhs, object rhs) { return IsEqual(equals.GetCallSite("=="), lhs, rhs); }
public static object Times(BinaryOpStorage/*!*/ lessThanStorage, BinaryOpStorage/*!*/ addStorage, BlockParam block, object/*!*/ self) { object i = 0; var lessThan = lessThanStorage.GetCallSite("<"); while (RubyOps.IsTrue(lessThan.Target(lessThan, i, self))) { if (block == null) { throw RubyExceptions.NoBlockGiven(); } object result; if (block.Yield(i, out result)) { return result; } var add = addStorage.GetCallSite("+"); i = add.Target(add, i, 1); } return self; }
private static bool TryCoerceAndApply( BinaryOpStorage/*!*/ coercionStorage, BinaryOpStorage/*!*/ binaryOpStorage, string/*!*/ binaryOp, object self, object other, out object result) { var coerce = coercionStorage.GetCallSite("coerce", new RubyCallSignature(1, RubyCallFlags.HasImplicitSelf)); IList coercedValues; try { // Swap self and other around to do the coercion. coercedValues = coerce.Target(coerce, other, self) as IList; } catch (SystemException) { // catches StandardError (like rescue) result = null; return false; } if (coercedValues != null && coercedValues.Count == 2) { var opSite = binaryOpStorage.GetCallSite(binaryOp); result = opSite.Target(opSite, coercedValues[0], coercedValues[1]); return true; } result = null; return false; }
public static object UpTo(BinaryOpStorage/*!*/ greaterThanStorage, BinaryOpStorage/*!*/ addStorage, BlockParam block, object/*!*/ self, object other) { object i = self; object compare = null; var greaterThan = greaterThanStorage.GetCallSite(">"); while (RubyOps.IsFalse(compare)) { // Rather than test i <= other we test !(i > other) compare = greaterThan.Target(greaterThan, i, other); // If the comparison failed (i.e. returned null) then we throw an error. if (compare == null) { throw RubyExceptions.MakeComparisonError(greaterThanStorage.Context, i, other); } // If the comparison worked but returned false then we carry on if (RubyOps.IsFalse(compare)) { if (block == null) { throw RubyExceptions.NoBlockGiven(); } object result; if (block.Yield(i, out result)) { return result; } var add = addStorage.GetCallSite("+"); i = add.Target(add, i, 1); } } return self; }
public static RubyArray Grep(CallSiteStorage<EachSite>/*!*/ each, BinaryOpStorage/*!*/ caseEquals, BlockParam action, object self, object pattern) { RubyArray result = new RubyArray(); var site = caseEquals.GetCallSite("==="); Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) { if (RubyOps.IsTrue(site.Target(site, pattern, item))) { if (action != null) { if (action.Yield(item, out item)) { return item; } } result.Add(item); } return null; })); return result; }
public static bool ValueNotEquals(BinaryOpStorage /*!*/ eql, object self, object other) { var site = eql.GetCallSite("==", 1); return(RubyOps.IsFalse(site.Target(site, self, other))); }