edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C448258 File: Initializers.Generated.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C448258 (server) 5/24/2008 10:02 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;rails-6 @@ -54,7 +54,7 @@ #endif // Skipped primitive: Object ExtendModule(typeof(System.Collections.Generic.IDictionary), new System.Action(LoadSystem__Collections__Generic__IDictionary_Instance), null, new Ruby.Builtins.RubyModule[] {def16, }); - ExtendModule(typeof(System.Collections.IEnumerable), new System.Action(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def16, }); + Ruby.Builtins.RubyModule def29 = ExtendModule(typeof(System.Collections.IEnumerable), new System.Action(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def16, }); ExtendModule(typeof(System.Collections.IList), new System.Action(LoadSystem__Collections__IList_Instance), null, new Ruby.Builtins.RubyModule[] {def16, }); ExtendModule(typeof(System.IComparable), new System.Action(LoadSystem__IComparable_Instance), null, new Ruby.Builtins.RubyModule[] {def25, }); DefineGlobalClass("Array", typeof(Ruby.Builtins.RubyArray), Context.ObjectClass, new System.Action(LoadArray_Instance), new System.Action(LoadArray_Class), new Ruby.Builtins.RubyModule[] {def16, }, new System.Delegate[] { @@ -67,7 +67,7 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ArrayOps.CreateArray), }); DefineGlobalClass("Binding", typeof(Ruby.Builtins.Binding), Context.ObjectClass, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - DefineGlobalClass("ClrString", typeof(System.String), Context.ObjectClass, new System.Action(LoadClrString_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, null); + DefineGlobalClass("ClrString", typeof(System.String), Context.ObjectClass, new System.Action(LoadClrString_Instance), null, new Ruby.Builtins.RubyModule[] {def29, }, null); DefineGlobalClass("Dir", typeof(Ruby.Builtins.RubyDir), Context.ObjectClass, new System.Action(LoadDir_Instance), new System.Action(LoadDir_Class), new Ruby.Builtins.RubyModule[] {def16, }, null); Ruby.Builtins.RubyClass def26 = Context.ExceptionClass = DefineGlobalClass("Exception", typeof(System.Exception), Context.ObjectClass, new System.Action(LoadException_Instance), new System.Action(LoadException_Class), Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ExceptionOps.Factory), @@ -2369,6 +2369,10 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.GetLocalVariableNames), }); + module.DefineLibraryMethod("loop", 0x2a, new System.Delegate[] { + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.Loop), + }); + module.DefineLibraryMethod("method", 0x29, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.GetMethod), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.GetMethod), @@ -2581,6 +2585,10 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.GetLocalVariableNames), }); + module.DefineLibraryMethod("loop", 0x31, new System.Delegate[] { + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.Loop), + }); + module.DefineLibraryMethod("method_missing", 0x31, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.MethodMissing), }); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C448258 File: Kernel.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C448258 (server) 5/24/2008 10:02 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;rails-6 @@ -319,8 +319,22 @@ return result; } - //loop + private static readonly DynamicSite/*!*/ _LoopSite = + CallSiteFactory.CreateSimpleCallSite(RubyContext.RubyBinder); + [RubyMethod("loop", RubyMethodAttributes.PrivateInstance)] + [RubyMethod("loop", RubyMethodAttributes.PublicSingleton)] + public static object Loop(CodeContext/*!*/ context, object self, BlockParam block) { + if (block == null) + throw RubyExceptions.CreateLocalJumpError("no block given"); + + while (true) { + object result = _LoopSite.Invoke(context, block); + if (block.BlockJumped(result)) + return result; + } + } + [RubyMethod("method_missing", RubyMethodAttributes.PrivateInstance)] [RubyMethod("method_missing", RubyMethodAttributes.PublicSingleton)] [RubyStackTraceHidden] =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;C444795 File: IDictionaryOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;C444795 (server) 5/24/2008 10:02 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;rails-6 @@ -68,6 +68,13 @@ return list; } + internal static RubyArray/*!*/ MakeArray(object key, object value) { + RubyArray list = new RubyArray(2); + list.Add(BaseSymbolDictionary.ObjToNull(key)); + list.Add(value); + return list; + } + // Replaces the data in dest with the data from src internal static T ReplaceData(T dest, IEnumerable> src) where T : IDictionary { dest.Clear(); @@ -204,35 +211,55 @@ [RubyMethod("each")] public static object Each(CodeContext/*!*/ context, IDictionary/*!*/ self, BlockParam block) { - foreach (KeyValuePair pair in self) { - object result = _EachSite1.Invoke(context, block, MakeArray(pair)); - if (block.BlockJumped(result)) { - return result; - } + if (self.Count > 0) { + // Must make a copy of the Keys array so that we can iterate over a static set of keys. Remember + // that the block can modify the hash, hence the need for a copy of the keys + object[] keys = new object[self.Count]; + self.Keys.CopyTo(keys, 0); - } - return self; - } - - [RubyMethod("each_pair")] - public static object EachPair(CodeContext/*!*/ context, IDictionary/*!*/ self, BlockParam block) { - foreach (KeyValuePair pair in self) { - object result = _EachPairSite.Invoke(context, block, BaseSymbolDictionary.ObjToNull(pair.Key), pair.Value); - if (block.BlockJumped(result)) { - return result; + // TODO: what are all the scenarios where the block can mutate the hash? can it remove keys? if so, what happens? + for (int i = 0; i < keys.Length; i++) { + object result = _EachSite1.Invoke(context, block, MakeArray(keys[i], self[keys[i]])); + if (block.BlockJumped(result)) + return result; } - } return self; } + [RubyMethod("each_pair")] + public static object EachPair(CodeContext/*!*/ context, IDictionary/*!*/ self, BlockParam block) { + if (self.Count > 0) { + // Must make a copy of the Keys array so that we can iterate over a static set of keys. Remember + // that the block can modify the hash, hence the need for a copy of the keys + object[] keys = new object[self.Count]; + self.Keys.CopyTo(keys, 0); + + // TODO: what are all the scenarios where the block can mutate the hash? can it remove keys? if so, what happens? + for (int i = 0; i < keys.Length; i++) { + object result = _EachPairSite.Invoke(context, block, BaseSymbolDictionary.ObjToNull(keys[i]), self[keys[i]]); + if (block.BlockJumped(result)) + return result; + } + } + + return self; + } + [RubyMethod("each_key")] public static object EachKey(CodeContext/*!*/ context, IDictionary/*!*/ self, BlockParam block) { - foreach (object key in self.Keys) { - object result = _EachKeySite.Invoke(context, block, BaseSymbolDictionary.ObjToNull(key)); - if (block.BlockJumped(result)) { - return result; + if (self.Count > 0) { + // Must make a copy of the Keys array so that we can iterate over a static set of keys. Remember + // that the block can modify the hash, hence the need for a copy of the keys + object[] keys = new object[self.Count]; + self.Keys.CopyTo(keys, 0); + + // TODO: what are all the scenarios where the block can mutate the hash? can it remove keys? if so, what happens? + for (int i = 0; i < keys.Length; i++) { + object result = _EachKeySite.Invoke(context, block, BaseSymbolDictionary.ObjToNull(keys[i])); + if (block.BlockJumped(result)) + return result; } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Scripts/Bat/mail.rb;C428038 File: mail.rb =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Scripts/Bat/mail.rb;C428038 (server) 5/24/2008 10:26 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Scripts/Bat/mail.rb;rails-6 @@ -59,7 +59,7 @@ mail.Subject = "Code Review: #{shelveset}" body = <<-EOF -tfpt review /shelveset:#{shelveset};#{ENV['USERDOMAIN']}\\#{ENV['USERNAME']} +tfpt review "/shelveset:#{shelveset};#{ENV['USERDOMAIN']}\\#{ENV['USERNAME']}" EOF ===================================================================