edit: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/module/remove_method_spec.rb;C807294
File: remove_method_spec.rb
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/module/remove_method_spec.rb;C807294 (server) 2/11/2010 8:56 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/module/remove_method_spec.rb;SingletonOptimizations
@@ -54,4 +54,14 @@
end
}.should raise_error(NameError)
end
+
+ it "removes multiple methods one by one" do
+ M = Module.new do
+ def foo; end
+ def bar; end
+
+ remove_method :foo, :undefined, :bar rescue 0
+ instance_methods.map { |x| x.to_s }.should == ["bar"]
+ end
+ end
end
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/module/undef_method_spec.rb;C807294
File: undef_method_spec.rb
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/module/undef_method_spec.rb;C807294 (server) 2/11/2010 8:56 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/module/undef_method_spec.rb;SingletonOptimizations
@@ -83,3 +83,15 @@
ancestor.another_method_to_undef.should == 1
end
end
+
+describe "Module#undef_method with multiple parameters" do
+ it "undefines methods one by one" do
+ M = Module.new do
+ def foo; end
+ def bar; end
+
+ undef_method :foo, :undefined, :bar rescue 0
+ instance_methods.map { |x| x.to_s }.should == ["bar"]
+ end
+ end
+end
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby4.sln;C1584920
File: Ruby4.sln
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby4.sln;C1584920 (server) 2/10/2010 10:36 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby4.sln;SingletonOptimizations
@@ -121,7 +121,6 @@
SccLocalPath13 = ..\\..\\Hosts\\SilverLight\\Microsoft.Scripting.SilverLight
SccProvider13 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName14 = ..\\..\\Hosts\\SilverLight\\Chiron\\Chiron.csproj
- SccProjectName14 = ../../Hosts/SilverLight/Chiron
SccAuxPath14 = http://vstfdevdiv:8080
SccLocalPath14 = ..\\..\\Hosts\\SilverLight\\Chiron
SccProvider14 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/ClassInitGenerator/Libraries/LibraryDef.cs;C1561136
File: LibraryDef.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/ClassInitGenerator/Libraries/LibraryDef.cs;C1561136 (server) 2/11/2010 8:04 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/ClassInitGenerator/Libraries/LibraryDef.cs;SingletonOptimizations
@@ -192,8 +192,6 @@
get {
return !IsExtension && (
QualifiedName == RubyClass.MainSingletonName
- || QualifiedName == RubyClass.ClassSingletonName
- || QualifiedName == RubyClass.ClassSingletonSingletonName
|| Extends == typeof(Kernel)
|| Extends == typeof(Object)
|| Extends == typeof(RubyClass)
@@ -872,8 +870,6 @@
_output.WriteLine("Context.RegisterPrimitives(");
_output.Indent++;
- _output.WriteLine("Load{0}_Instance,", RubyClass.ClassSingletonName);
- _output.WriteLine("Load{0}_Instance,", RubyClass.ClassSingletonSingletonName);
_output.WriteLine("Load{0}_Instance,", RubyClass.MainSingletonName);
_output.WriteLine(_moduleDefs[typeof(Kernel)].GetInitializerDelegates() + ",");
===================================================================
add: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Experimental/Singletons/DummySingletons.rb
File: DummySingletons.rb
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Experimental/Singletons/DummySingletons.rb;SingletonOptimizations
@@ -1,0 +1,39 @@
+def get_singletons(cls, n)
+ result = [cls]
+ n.times do
+ cls = class << cls; self; end
+ result << cls
+ end
+ result
+end
+
+class MetaModule < Module
+end
+MM = MetaModule.new
+
+[Object, Module, Class, MetaModule].each do |c|
+ s = class << c; self; end
+
+ c.send(:define_method, :f) { c.name }
+ s.send(:define_method, :f) { 'S(' + c.name + ')' }
+end
+
+[
+ MM,
+ module M; self; end,
+ Module,
+ MetaModule
+].each { |c| get_singletons(c, 10) }
+
+[
+ MM,
+ module M; self; end,
+ Module,
+ MetaModule
+].each do |c|
+ get_singletons(c, 3).each do |s|
+ printf '%-50s %s', s, s.f
+ puts
+ end
+ puts
+end
\ No newline at end of file
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Experimental/Singletons/Ultimate.MethodLookup.rb;C791094
File: Ultimate.MethodLookup.rb
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Experimental/Singletons/Ultimate.MethodLookup.rb;C791094 (server) 2/11/2010 10:36 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Experimental/Singletons/Ultimate.MethodLookup.rb;SingletonOptimizations
@@ -53,8 +53,8 @@
$modules = [
module MyModule; self; end,
module MyModule; class << self; self; end; end,
- class MyClass; self; end,
- class << Object.new; self; end,
+ class MyClass; self; end,
+ class << Object.new; self; end,
]
def test met, x, y
@@ -62,25 +62,25 @@
$modules.each { |m|
puts "-- #{m} --------------"
- m.module_eval do
- puts send(met, *[:ai_k, :i_k][x,y]) rescue p $!
- puts send(met, *[:ai_x, :i_x][x,y]) rescue p $!
- puts send(met, *[:ai_o, :i_o][x,y]) rescue p $!
-
- # errors:
-
- puts send(met, *[:ac_k, :c_k][x,y]) rescue p $!
- puts send(met, *[:ac_x, :c_x][x,y]) rescue p $!
- puts send(met, *[:ac_o, :c_o][x,y]) rescue p $!
-
- puts send(met, *[:ai_c, :i_c][x,y]) rescue p $!
- puts send(met, *[:ac_c, :c_c][x,y]) rescue p $!
- puts send(met, *[:ai_m, :i_m][x,y]) rescue p $!
- puts send(met, *[:ac_m, :c_m][x,y]) rescue p $!
-
- end
-
- puts
+ m.module_eval do
+ puts send(met, *[:ai_k, :i_k][x,y]) rescue p $!
+ puts send(met, *[:ai_x, :i_x][x,y]) rescue p $!
+ puts send(met, *[:ai_o, :i_o][x,y]) rescue p $!
+
+ # errors:
+
+ puts send(met, *[:ac_k, :c_k][x,y]) rescue p $!
+ puts send(met, *[:ac_x, :c_x][x,y]) rescue p $!
+ puts send(met, *[:ac_o, :c_o][x,y]) rescue p $!
+
+ puts send(met, *[:ai_c, :i_c][x,y]) rescue p $!
+ puts send(met, *[:ac_c, :c_c][x,y]) rescue p $!
+ puts send(met, *[:ai_m, :i_m][x,y]) rescue p $!
+ puts send(met, *[:ac_m, :c_m][x,y]) rescue p $!
+
+ end
+
+ puts
}
end
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C1569144
File: RubyTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C1569144 (server) 2/11/2010 11:32 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;SingletonOptimizations
@@ -600,6 +600,10 @@
AllowedSingletons1,
AllowedSingletons2,
SingletonMethodDefinitionOnSingletons1,
+ ModuleSingletons1,
+ ClassSingletons1,
+ DummySingletons1,
+ DummySingletons2,
Super1,
SuperParameterless1,
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/CloningTests.cs;C966724
File: CloningTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/CloningTests.cs;C966724 (server) 2/10/2010 7:32 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/CloningTests.cs;SingletonOptimizations
@@ -39,15 +39,15 @@
x.instance_variable_set(:@iv_x, 4);
y = x.clone
- raise unless y.tainted?
+ raise '0' unless y.tainted?
class << y
- raise unless CONST == 1 # singleton constants copied
- raise unless instance_variables.size == 0 # singleton instance variables not copied
+ raise '1' unless CONST == 1 # singleton constants copied
+ raise '2' unless instance_variables.size == 0 # singleton instance variables not copied
end
- raise unless y.foo == 3 # singleton methods copied
- raise unless y.instance_variable_get(:@iv_x) == 4 # instance variables copied
+ raise '3' unless y.foo == 3 # singleton methods copied
+ raise '4' unless y.instance_variable_get(:@iv_x) == 4 # instance variables copied
end
");
}, @"
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ClrTests.cs;C1281974
File: ClrTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ClrTests.cs;C1281974 (server) 2/10/2010 11:02 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ClrTests.cs;SingletonOptimizations
@@ -424,10 +424,11 @@
Context.ObjectClass.EnumerateConstants((module, name, value) => {
RubyModule m = value as RubyModule;
if (m != null && Array.IndexOf(irModules, m.Name) == -1) {
+ var s = m.GetOrCreateSingletonClass();
AssertNoClrNames(ModuleOps.GetInstanceMethods(m, true), m.Name);
AssertNoClrNames(ModuleOps.GetPrivateInstanceMethods(m, true), m.Name);
- AssertNoClrNames(ModuleOps.GetInstanceMethods(m.SingletonClass, true), m.Name);
- AssertNoClrNames(ModuleOps.GetPrivateInstanceMethods(m.SingletonClass, true), m.Name);
+ AssertNoClrNames(ModuleOps.GetInstanceMethods(s, true), m.Name);
+ AssertNoClrNames(ModuleOps.GetPrivateInstanceMethods(s, true), m.Name);
}
return false;
});
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ModuleTests.cs;C1158858
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/SingletonTests.cs;C1544546
File: SingletonTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/SingletonTests.cs;C1544546 (server) 2/11/2010 11:13 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/SingletonTests.cs;SingletonOptimizations
@@ -344,5 +344,148 @@
tfn
");
}
+
+ ///
+ /// Singleton(module)'s super-class is singleton(Module).
+ ///
+ public void ModuleSingletons1() {
+ TestOutput(@"
+class Class
+ def self.c_c
+ :c_c
+ end
+end
+
+class Module
+ def self.c_m
+ :c_m
+ end
+end
+
+module M
+ class << self
+ $SM = self
+ end
+end
+
+$SM.method(:c_c) rescue p $!
+$SM.c_c rescue p $!
+
+p $SM.c_m
+", @"
+#
+#>
+:c_m
+");
+ }
+
+ ///
+ /// Cannot instantiate singleton(class).
+ ///
+ public void ClassSingletons1() {
+ TestOutput(@"
+class C; end
+class << C
+ p method(:new)
+ new rescue p $!
+end
+", @"
+#
+#
+");
+ }
+
+ private const string SingletonHelpers = @"
+def get_singletons(cls, n)
+ result = [cls]
+ n.times do
+ cls = class << cls; self; end
+ result << cls
+ end
+ result
+end
+";
+
+ public void DummySingletons1() {
+ Engine.Execute(SingletonHelpers);
+ AssertOutput(() =>
+ CompilerTest(@"
+[
+ class C; self; end,
+ module M; self; end,
+ class MM < Module; new; end
+].each do |c|
+ get_singletons(c, 4).each do |s|
+ printf '%-50s %s', s, s.superclass rescue print $!
+ puts
+ end
+ puts
+end
+"), @"
+C Object
+# #>
+#> #>>
+#>> #>>>
+#>>> #>>>
+
+undefined method `superclass' for M:Module
+# #>
+#> #>>
+#>> #>>>
+#>>> #>>>
+
+undefined method `superclass' for #
+#> #>>
+#>> #>>>
+#>>> #>>>>
+#>>>> #>>>>
+", OutputFlags.Match);
+ }
+
+ public void DummySingletons2() {
+ Engine.Execute(SingletonHelpers);
+ TestOutput(@"
+class MetaModule < Module
+end
+MM = MetaModule.new
+
+[Object, Module, Class, MetaModule].each do |c|
+ s = class << c; self; end
+
+ c.send(:define_method, :f) { c.name }
+ s.send(:define_method, :f) { 'S(' + c.name + ')' }
+end
+
+[
+ MM,
+ module M; self; end,
+ Module,
+ MetaModule
+].each do |c|
+ get_singletons(c, 2).each do |s| # the results differ from MRI for other values than 2, it seems like a bug in MRI
+ printf '%-30s %s', s, s.f
+ puts
+ end
+ puts
+end
+", @"
+MM MetaModule
+# S(MetaModule)
+#> S(MetaModule)
+
+M Module
+# S(Module)
+#> S(Module)
+
+Module S(Module)
+# S(Class)
+#> S(Class)
+
+MetaModule S(MetaModule)
+# S(Class)
+#> S(Class)
+");
+ }
+
}
}
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C1589071
File: Initializers.Generated.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C1589071 (server) 2/10/2010 2:40 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;SingletonOptimizations
@@ -38,8 +38,6 @@
public sealed class BuiltinsLibraryInitializer : IronRuby.Builtins.LibraryInitializer {
protected override void LoadModules() {
Context.RegisterPrimitives(
- Load__ClassSingleton_Instance,
- Load__ClassSingletonSingleton_Instance,
Load__MainSingleton_Instance,
LoadKernel_Instance, LoadKernel_Class, null,
LoadObject_Instance, LoadObject_Class, LoadObject_Constants,
@@ -48,7 +46,6 @@
);
- // Skipped primitive: __ClassSingleton
// Skipped primitive: __MainSingleton
IronRuby.Builtins.RubyModule def49 = DefineGlobalModule("Comparable", typeof(IronRuby.Builtins.Comparable), 0x0000000F, LoadComparable_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
IronRuby.Builtins.RubyModule def40 = DefineGlobalModule("Enumerable", typeof(IronRuby.Builtins.Enumerable), 0x0000000F, LoadEnumerable_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
@@ -78,7 +75,6 @@
DefineGlobalModule("Signal", typeof(IronRuby.Builtins.Signal), 0x0000000F, null, LoadSignal_Class, null, IronRuby.Builtins.RubyModule.EmptyArray);
#endif
ExtendClass(typeof(System.Type), 0x00000000, null, LoadSystem__Type_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
- // Skipped primitive: __ClassSingletonSingleton
#if !SILVERLIGHT
object def1 = DefineSingleton(Load__Singleton_ArgFilesSingletonOps_Instance, null, null, def40);
#endif
@@ -362,60 +358,6 @@
SetBuiltinConstant(def2, "EXDEV", def17);
}
- private static void Load__ClassSingleton_Instance(IronRuby.Builtins.RubyModule/*!*/ module) {
- DefineLibraryMethod(module, "allocate", 0x51,
- 0x00000000U,
- new Action(IronRuby.Builtins.ClassSingletonOps.Allocate)
- );
-
- DefineLibraryMethod(module, "inherited", 0x52,
- 0x00000002U,
- new Action(IronRuby.Builtins.ClassSingletonOps.Inherited)
- );
-
- DefineLibraryMethod(module, "initialize", 0x52,
- 0x00000000U,
- new Func(IronRuby.Builtins.ClassSingletonOps.Initialize)
- );
-
- DefineLibraryMethod(module, "initialize_copy", 0x52,
- 0x00000000U,
- new Func(IronRuby.Builtins.ClassSingletonOps.InitializeCopy)
- );
-
- DefineLibraryMethod(module, "new", 0x51,
- 0x00000000U,
- new Action(IronRuby.Builtins.ClassSingletonOps.New)
- );
-
- DefineLibraryMethod(module, "superclass", 0x51,
- 0x00000000U,
- new Func(IronRuby.Builtins.ClassSingletonOps.GetSuperClass)
- );
-
- }
-
- private static void Load__ClassSingleton_Class(IronRuby.Builtins.RubyModule/*!*/ module) {
- }
-
- private static void Load__ClassSingletonSingleton_Instance(IronRuby.Builtins.RubyModule/*!*/ module) {
- Load__ClassSingleton_Instance(module);
- DefineLibraryMethod(module, "constants", 0x51,
- 0x00000000U,
- new Func(IronRuby.Builtins.ClassSingletonSingletonOps.GetConstants)
- );
-
- DefineLibraryMethod(module, "nesting", 0x51,
- 0x00000000U,
- new Func(IronRuby.Builtins.ClassSingletonSingletonOps.GetNesting)
- );
-
- }
-
- private static void Load__ClassSingletonSingleton_Class(IronRuby.Builtins.RubyModule/*!*/ module) {
- Load__ClassSingleton_Class(module);
- }
-
private static void Load__MainSingleton_Instance(IronRuby.Builtins.RubyModule/*!*/ module) {
DefineLibraryMethod(module, "include", 0x51,
0x80000000U,
@@ -4859,8 +4801,7 @@
);
DefineLibraryMethod(module, "extend_object", 0x52,
- 0x00000002U, 0x00000000U,
- new Func(IronRuby.Builtins.ModuleOps.ExtendObject),
+ 0x00000000U,
new Func(IronRuby.Builtins.ModuleOps.ExtendObject)
);
@@ -5031,8 +4972,8 @@
);
DefineLibraryMethod(module, "remove_method", 0x52,
- 0x00010002U,
- new Func(IronRuby.Builtins.ModuleOps.RemoveMethod)
+ 0x80010002U,
+ new Func(IronRuby.Builtins.ModuleOps.RemoveMethod)
);
DefineLibraryMethod(module, "to_clr_ref", 0x51,
@@ -5051,8 +4992,8 @@
);
DefineLibraryMethod(module, "undef_method", 0x52,
- 0x00010002U,
- new Func(IronRuby.Builtins.ModuleOps.UndefineMethod)
+ 0x80010002U,
+ new Func(IronRuby.Builtins.ModuleOps.UndefineMethod)
);
}
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ClassOps.cs;C1290543
File: ClassOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ClassOps.cs;C1290543 (server) 2/11/2010 12:14 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ClassOps.cs;SingletonOptimizations
@@ -13,12 +13,11 @@
*
* ***************************************************************************/
-using System;
+using System.Diagnostics;
using System.Runtime.InteropServices;
-using Microsoft.Scripting.Runtime;
using IronRuby.Runtime;
using IronRuby.Runtime.Calls;
-using System.Reflection;
+using Microsoft.Scripting.Runtime;
namespace IronRuby.Builtins {
@@ -70,7 +69,15 @@
[RubyMethod("superclass")]
public static RubyClass GetSuperclass(RubyClass/*!*/ self) {
- return self.SuperClass;
+ if (self.IsSingletonClass) {
+ RubyClass result = self.ImmediateClass;
+ Debug.Assert(result.IsSingletonClass);
+
+ // do not return dummy singletons, also do not create a new singleton (MRI does):
+ return result.IsDummySingletonClass ? self : result;
+ } else {
+ return self.SuperClass;
+ }
}
[RubyMethod("clr_new")]
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/KernelOps.cs;C1561136
File: KernelOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/KernelOps.cs;C1561136 (server) 2/10/2010 2:01 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/KernelOps.cs;SingletonOptimizations
@@ -534,8 +534,10 @@
object self, [NotNull]RubyModule/*!*/ module, [NotNullItems]params RubyModule/*!*/[]/*!*/ modules) {
Assert.NotNull(self, modules);
- RubyUtils.RequireMixins(module.SingletonClass, modules);
+ // TODO: this is strange:
+ RubyUtils.RequireMixins(module.GetOrCreateSingletonClass(), modules);
+
var extendObject = extendObjectStorage.GetCallSite("extend_object", 1);
var extended = extendedStorage.GetCallSite("extended", 1);
@@ -640,7 +642,7 @@
public static object Evaluate(RubyScope/*!*/ scope, object self, [NotNull]MutableString/*!*/ code,
[Optional, NotNull]MutableString file, [DefaultParameterValue(1)]int line) {
- RubyClass singleton = scope.RubyContext.CreateSingletonClass(self);
+ RubyClass singleton = scope.RubyContext.GetOrCreateSingletonClass(self);
return RubyUtils.Evaluate(code, scope, self, singleton, file, line);
}
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C1561136
File: ModuleOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C1561136 (server) 2/10/2010 2:01 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;SingletonOptimizations
@@ -68,17 +68,9 @@
// thread-safe:
[RubyMethod("extend_object", RubyMethodAttributes.PrivateInstance)]
- public static RubyModule/*!*/ ExtendObject(RubyModule/*!*/ self, [NotNull]RubyModule/*!*/ extendedModule) {
- // include self into extendedModule's singleton class
- extendedModule.SingletonClass.IncludeModules(self);
- return self;
- }
-
- // thread-safe:
- [RubyMethod("extend_object", RubyMethodAttributes.PrivateInstance)]
public static object ExtendObject(RubyModule/*!*/ self, object extendedObject) {
// include self into extendedObject's singleton
- self.Context.CreateSingletonClass(extendedObject).IncludeModules(self);
+ self.Context.GetOrCreateSingletonClass(extendedObject).IncludeModules(self);
return extendedObject;
}
@@ -156,7 +148,7 @@
[RubyMethodAttribute("private_class_method")]
public static RubyModule/*!*/ MakeClassMethodsPrivate(RubyModule/*!*/ self,
[DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ methodNames) {
- SetMethodAttributes(self.SingletonClass, methodNames, RubyMethodAttributes.Private);
+ SetMethodAttributes(self.GetOrCreateSingletonClass(), methodNames, RubyMethodAttributes.Private);
return self;
}
@@ -164,7 +156,7 @@
[RubyMethodAttribute("public_class_method")]
public static RubyModule/*!*/ MakeClassMethodsPublic(RubyModule/*!*/ self,
[DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ methodNames) {
- SetMethodAttributes(self.SingletonClass, methodNames, RubyMethodAttributes.Public);
+ SetMethodAttributes(self.GetOrCreateSingletonClass(), methodNames, RubyMethodAttributes.Public);
return self;
}
@@ -211,7 +203,7 @@
method = module.ResolveMethodNoLock(methodName, VisibilityContext.AllVisible, options).Info;
if (method == null) {
- throw RubyExceptions.CreateNameError(RubyExceptions.FormatMethodMissingMessage(context, module, methodName));
+ throw RubyExceptions.CreateUndefinedMethodError(module, methodName);
}
// MRI only adds method to the target module if visibility differs:
@@ -229,7 +221,7 @@
}
if (isModuleFunction) {
- module.SingletonClass.MethodAdded(methodName);
+ module.GetOrCreateSingletonClass().MethodAdded(methodName);
}
}
}
@@ -469,25 +461,29 @@
// thread-safe:
[RubyMethod("remove_method", RubyMethodAttributes.PrivateInstance)]
- public static RubyModule/*!*/ RemoveMethod(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ methodName) {
+ public static RubyModule/*!*/ RemoveMethod(RubyModule/*!*/ self, [DefaultProtocol, NotNullItems]params string[]/*!*/ methodNames) {
// MRI 1.8: reports a warning and allows removal
// MRI 1.9: throws a NameError
- if (self == self.Context.ObjectClass && methodName == Symbols.Initialize) {
- throw RubyExceptions.CreateNameError("Cannot remove Object#initialize");
+ foreach (var methodName in methodNames) {
+ if (self == self.Context.ObjectClass && methodName == Symbols.Initialize) {
+ throw RubyExceptions.CreateNameError("Cannot remove Object#initialize");
+ }
+ if (!self.RemoveMethod(methodName)) {
+ throw RubyExceptions.CreateUndefinedMethodError(self, methodName);
+ }
}
- if (!self.RemoveMethod(methodName)) {
- throw RubyExceptions.CreateUndefinedMethodError(self, methodName);
- }
return self;
}
// thread-safe:
[RubyMethod("undef_method", RubyMethodAttributes.PrivateInstance)]
- public static RubyModule/*!*/ UndefineMethod(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ methodName) {
- if (!self.ResolveMethod(methodName, VisibilityContext.AllVisible).Found) {
- throw RubyExceptions.CreateUndefinedMethodError(self, methodName);
+ public static RubyModule/*!*/ UndefineMethod(RubyModule/*!*/ self, [DefaultProtocol, NotNullItems]params string[]/*!*/ methodNames) {
+ foreach (var methodName in methodNames) {
+ if (!self.ResolveMethod(methodName, VisibilityContext.AllVisible).Found) {
+ throw RubyExceptions.CreateUndefinedMethodError(self, methodName);
+ }
+ self.UndefineMethod(methodName);
}
- self.UndefineMethod(methodName);
return self;
}
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Precision.cs;C1561136
File: Precision.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Precision.cs;C1561136 (server) 2/10/2010 2:22 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Precision.cs;SingletonOptimizations
@@ -78,13 +78,14 @@
/// The host class including the module
[RubyMethod("included", RubyMethodAttributes.PublicSingleton)]
public static object Included(RubyContext/*!*/ context, RubyModule/*!*/ self, RubyModule/*!*/ includedIn) {
- includedIn.SingletonClass.AddMethod(
+ var singleton = includedIn.GetOrCreateSingletonClass();
+ singleton.AddMethod(
context,
"induced_from",
new RubyLibraryMethodInfo(
new[] { LibraryOverload.Create(new Func(InducedFrom), false, 0, 0) },
RubyMethodVisibility.Public,
- includedIn.SingletonClass
+ singleton
)
);
return self;
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SingletonOps.cs;C1561136
File: SingletonOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SingletonOps.cs;C1561136 (server) 2/10/2010 2:06 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SingletonOps.cs;SingletonOptimizations
@@ -86,77 +86,4 @@
#endregion
}
-
- ///
- /// Methods on Singleton(class), Singleton(Singleton(object)).
- ///
- [RubyModule(RubyClass.ClassSingletonName)]
- public static class ClassSingletonOps {
- #region Private Instance Methods
-
- // Reinitialization. Not called when a factory/non-default ctor is called.
- [RubyMethod("initialize", RubyMethodAttributes.PrivateInstance)]
- public static object/*!*/ Initialize(object/*!*/ self) {
- // TODO:
- throw new NotImplementedException("TODO");
- }
-
- [RubyMethod("initialize_copy", RubyMethodAttributes.PrivateInstance)]
- public static object InitializeCopy(object/*!*/ self, object other) {
- // TODO:
- throw new NotImplementedException("TODO");
- }
-
- [RubyMethod("inherited", RubyMethodAttributes.PrivateInstance)]
- public static void Inherited(object/*!*/ self, [NotNull]RubyClass/*!*/ subclass) {
- // TODO:
- throw new NotImplementedException("TODO");
- }
-
- #endregion
-
- #region Public Instance Methods
-
- [RubyMethod("allocate", RubyMethodAttributes.PublicInstance)]
- public static void Allocate(RubyClass/*!*/ self) {
- throw RubyExceptions.CreateTypeError("can't create instance of virtual class");
- }
-
- [RubyMethod("superclass", RubyMethodAttributes.PublicInstance)]
- public static RubyClass/*!*/ GetSuperClass(RubyClass/*!*/ self) {
- RubyClass result = self.SingletonClass;
- Debug.Assert(result != null && result.IsSingletonClass);
-
- // do not return dummy singletons, also do not create a new singleton (MRI does):
- return result.IsDummySingletonClass ? self : result;
- }
-
- [RubyMethod("new", RubyMethodAttributes.PublicInstance)]
- public static void New(RubyClass/*!*/ self) {
- Allocate(self);
- }
-
- #endregion
- }
-
- ///
- /// Methods on Singleton(Singleton(class)), Singleton(Singleton(Singleton(object))).
- ///
- [RubyModule(RubyClass.ClassSingletonSingletonName), Includes(typeof(ClassSingletonOps), Copy = true)]
- public static class ClassSingletonSingletonOps {
-
- #region Public Instance Methods
-
- [RubyMethod("constants", RubyMethodAttributes.PublicInstance)]
- public static RubyArray/*!*/ GetConstants(object/*!*/ self) {
- throw new NotImplementedException("TODO");
- }
-
- [RubyMethod("nesting", RubyMethodAttributes.PublicInstance)]
- public static RubyModule/*!*/ GetNesting(object/*!*/ self) {
- throw new NotImplementedException("TODO");
- }
-
- #endregion
- }
}
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/ParseTree/IronRubyParseTreeOps.cs;C1496258
File: IronRubyParseTreeOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/ParseTree/IronRubyParseTreeOps.cs;C1496258 (server) 2/10/2010 2:39 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/ParseTree/IronRubyParseTreeOps.cs;SingletonOptimizations
@@ -41,7 +41,7 @@
// bool includeNewLines = IncludeNewLines(module.Context, self);
if (isClassMethod) {
- module = module.SingletonClass;
+ module = module.ImmediateClass;
}
var member = module.GetMethod(methodName);
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/LibraryInitializer.cs;C1561136
File: LibraryInitializer.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/LibraryInitializer.cs;C1561136 (server) 2/10/2010 2:01 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/LibraryInitializer.cs;SingletonOptimizations
@@ -120,7 +120,7 @@
}
object result = new RubyObject(_context.ObjectClass);
- RubyClass singleton = _context.CreateInstanceSingleton(result, instanceTrait, classTrait, constantsInitializer, expandedMixins);
+ RubyClass singleton = _context.GetOrCreateInstanceSingleton(result, instanceTrait, classTrait, constantsInitializer, expandedMixins);
return result;
}
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;C1586787
File: RubyClass.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;C1586787 (server) 2/10/2010 11:07 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;SingletonOptimizations
@@ -44,14 +44,16 @@
using AstUtils = Microsoft.Scripting.Ast.Utils;
public sealed partial class RubyClass : RubyModule, IDuplicable {
- public const string/*!*/ ClassSingletonName = "__ClassSingleton";
- public const string/*!*/ ClassSingletonSingletonName = "__ClassSingletonSingleton";
public const string/*!*/ MainSingletonName = "__MainSingleton";
// Level in class hierarchy (0 == Object)
private readonly int _level;
private readonly RubyClass _superClass;
+ // Lazy interlocked init.
+ // Created for classes that represent a subclass of Module class.
+ private RubyClass _dummySingletonClass;
+
// is this class a singleton class?
private readonly bool _isSingletonClass;
@@ -226,6 +228,25 @@
get { return _singletonClassOf; }
}
+ internal void InitializeDummySingleton() {
+ Debug.Assert(_dummySingletonClass == null);
+ _dummySingletonClass = CreateDummySingleton();
+ }
+
+ internal RubyClass/*!*/ GetDummySingletonClass() {
+ if (_dummySingletonClass == null) {
+ Debug.Assert(IsSubclassOf(Context.ModuleClass));
+ Interlocked.CompareExchange(ref _dummySingletonClass, CreateDummySingleton(), null);
+ }
+ return _dummySingletonClass;
+ }
+
+ private RubyClass/*!*/ CreateDummySingleton() {
+ var result = new RubyClass(Context, null, null, this, null, null, null, this.ImmediateClass, null, null, null, false, true, ModuleRestrictions.None);
+ result.InitializeImmediateClass(result);
+ return result;
+ }
+
// A class defined in Ruby code (not libraries, CLR types)
public bool IsRubyClass {
get { return _isRubyClass; }
@@ -271,8 +292,7 @@
public RubyClass(RubyClass/*!*/ rubyClass)
: this(rubyClass.Context, null, null, null, null, null, null, rubyClass.Context.ObjectClass, null, null, null, true, false, ModuleRestrictions.None) {
- // all modules need a singleton (see RubyContext.CreateModule):
- InitializeDummySingletonClass(rubyClass, null);
+ InitializeImmediateClass(rubyClass, null);
}
// friend: RubyContext
@@ -550,7 +570,7 @@
if (!IsSingletonClass) {
// singleton members are copied here, not in InitializeCopy:
- result.SingletonClass.InitializeMembersFrom(SingletonClass);
+ result.ImmediateClass.InitializeMembersFrom(ImmediateClass);
// copy instance variables and taint flag:
Context.CopyInstanceData(this, result, false);
@@ -581,6 +601,9 @@
return false;
}
+ ///
+ /// Returns true if this class is equal to super or it is its descendant.
+ ///
public bool IsSubclassOf(RubyClass/*!*/ super) {
Assert.NotNull(super);
@@ -1230,7 +1253,10 @@
}
public void BuildObjectConstructionNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ methodName) {
- Debug.Assert(!IsSingletonClass, "Cannot instantiate singletons");
+ if (IsSingletonClass) {
+ metaBuilder.SetError(Methods.MakeVirtualClassInstantiatedError.OpCall());
+ return;
+ }
Type type = GetUnderlyingSystemType();
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.Meta.cs;C1107696
File: RubyClass.Meta.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.Meta.cs;C1107696 (server) 2/10/2010 11:08 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.Meta.cs;SingletonOptimizations
@@ -46,7 +46,7 @@
var names = new List();
using (Context.ClassHierarchyLocker()) {
- Value.SingletonClass.ForEachMember(true, RubyMethodAttributes.DefaultVisibility, (name, module, member) => names.Add(name));
+ Value.ImmediateClass.ForEachMember(true, RubyMethodAttributes.DefaultVisibility, (name, module, member) => names.Add(name));
}
return names;
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;C1496258
File: RubyModule.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;C1496258 (server) 2/10/2010 10:47 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;SingletonOptimizations
@@ -99,6 +99,8 @@
}
private readonly RubyContext/*!*/ _context;
+
+ #region CLR Types and Namespaces
// the namespace this module represents or null:
private readonly NamespaceTracker _namespaceTracker;
@@ -107,17 +109,119 @@
// TODO: unify with _underlyingSystemType on classes
private readonly TypeTracker _typeTracker;
+ public TypeTracker TypeTracker {
+ get { return _typeTracker; }
+ }
+
+ public NamespaceTracker NamespaceTracker {
+ get { return _namespaceTracker; }
+ }
+
+ public bool IsInterface {
+ get { return _typeTracker != null && _typeTracker.Type.IsInterface; }
+ }
+
+ public bool IsClrModule {
+ get { return _typeTracker != null && IsModuleType(_typeTracker.Type); }
+ }
+
+ public virtual Type/*!*/ GetUnderlyingSystemType() {
+ if (IsClrModule) {
+ return _typeTracker.Type;
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+
+ #endregion
+
private readonly ModuleRestrictions _restrictions;
private readonly WeakReference/*!*/ _weakSelf;
// name of the module or null for anonymous modules:
private string _name;
- // lazy interlocked init:
- private RubyClass _singletonClass;
+ // Lazy interlocked init'd.
+ private RubyInstanceData _instanceData;
+
+ #region Immediate/Singleton/Super Class
- private RubyInstanceData _instanceData;
+ // Lazy interlocked init'd.
+ // Classes
+ // Null immediately after construction, initialized by RubyContext.CreateClass factory to a singleton class.
+ // This lazy initialization is needed to allow circular references among Kernel, Object, Module and Class.
+ // We create the singleton class eagerly in the factory since classes' singleton classes form a hierarchy parallel
+ // to the main inheritance hierarachy of classes. If we didn't we would need to update super-references of all singleton subclasses
+ // that were created after a singleton class is lazily created.
+ // Modules
+ // Initialized to the class of the module and may later be changed to a singleton class (only if the singleton is needed).
+ // We don't create the singleton class eagerly to optimize rule generation. If we did, each (meta)module instance would receive its own immediate class
+ // different from other instances of the (meta)module. And thus the instances would use different method table versions eventhough they are the same.
+ // Singleton Classes
+ // Self reference for dummy singletons (tha last singletons in the singleton chain).
+ private RubyClass _immediateClass;
+ ///
+ /// A dummy singleton class is an immutable class that has no members and is used to terminate singleton class chain.
+ ///
+ ///
+ /// A method invoked on the last class in the singleton class chain before the dummy singleton is searched in the inheritance hierarchy of the dummy singleton:
+ /// [dummy singleton, singleton(Class), singleton(Module), singleton(Object), Class, Module, Object].
+ /// The ImmediateClass reference cannot be null (that would cause null-ref exception in rules), so we need to set it to the dummy.
+ ///
+ public bool IsDummySingletonClass {
+ get { return _immediateClass == this; }
+ }
+
+ public virtual bool IsSingletonClass {
+ get { return false; }
+ }
+
+ public virtual bool IsClass {
+ get { return false; }
+ }
+
+ public bool IsObjectClass {
+ get { return ReferenceEquals(this, Context.ObjectClass); }
+ }
+
+ public bool IsComClass {
+ get { return ReferenceEquals(this, Context.ComObjectClass); }
+ }
+
+ internal virtual RubyClass GetSuperClass() {
+ return null;
+ }
+
+ // thread safe:
+ internal void InitializeImmediateClass(RubyClass/*!*/ cls) {
+ Debug.Assert(_immediateClass == null);
+ _immediateClass = cls;
+ }
+
+ // thread safe:
+ internal void InitializeImmediateClass(RubyClass/*!*/ singletonSuperClass, Action trait) {
+ Assert.NotNull(singletonSuperClass);
+
+ RubyClass immediate;
+ if (IsClass) {
+ // class: eager singleton class construction:
+ immediate = CreateSingletonClass(singletonSuperClass, trait);
+ immediate.InitializeImmediateClass(_context.ClassClass.GetDummySingletonClass());
+ } else if (trait != null) {
+ // module: eager singleton class construction:
+ immediate = CreateSingletonClass(singletonSuperClass, trait);
+ immediate.InitializeImmediateClass(singletonSuperClass.GetDummySingletonClass());
+ } else {
+ // module: lazy singleton class construction:
+ immediate = singletonSuperClass;
+ }
+
+ InitializeImmediateClass(immediate);
+ }
+
+ #endregion
+
#region Mutable state guarded by ClassHierarchyLock
[Emitted]
@@ -216,45 +320,6 @@
#endregion
- public TypeTracker TypeTracker {
- get { return _typeTracker; }
- }
-
- public NamespaceTracker NamespaceTracker {
- get { return _namespaceTracker; }
- }
-
- public bool IsInterface {
- get { return _typeTracker != null && _typeTracker.Type.IsInterface; }
- }
-
- public bool IsClrModule {
- get { return _typeTracker != null && IsModuleType(_typeTracker.Type); }
- }
-
- public virtual Type/*!*/ GetUnderlyingSystemType() {
- if (IsClrModule) {
- return _typeTracker.Type;
- } else {
- throw new InvalidOperationException();
- }
- }
-
- public RubyClass/*!*/ SingletonClass {
- get {
- Debug.Assert(_singletonClass != null);
- return _singletonClass;
- }
- }
-
- public bool IsDummySingletonClass {
- get { return ReferenceEquals(_singletonClass, this); }
- }
-
- public virtual bool IsSingletonClass {
- get { return false; }
- }
-
public ModuleRestrictions Restrictions {
get { return _restrictions; }
}
@@ -272,22 +337,6 @@
get { return _context; }
}
- public virtual bool IsClass {
- get { return false; }
- }
-
- public bool IsObjectClass {
- get { return ReferenceEquals(this, Context.ObjectClass); }
- }
-
- public bool IsComClass {
- get { return ReferenceEquals(this, Context.ComObjectClass); }
- }
-
- internal virtual RubyClass GetSuperClass() {
- return null;
- }
-
internal virtual RubyGlobalScope GlobalScope {
get { return null; }
}
@@ -297,16 +346,16 @@
}
// default allocator:
- public RubyModule(RubyClass/*!*/ rubyClass)
- : this(rubyClass, null) {
+ public RubyModule(RubyClass/*!*/ metaModuleClass)
+ : this(metaModuleClass, null) {
}
- // creates an empty module:
+ // creates an empty (meta)module:
protected RubyModule(RubyClass/*!*/ metaModuleClass, string name)
: this(metaModuleClass.Context, name, null, null, null, null, null, ModuleRestrictions.None) {
-
- // all modules need a singleton (see RubyContext.CreateModule):
- InitializeDummySingletonClass(metaModuleClass, null);
+
+ // metaModuleClass represents a subclass of Module or its duplicate (Kernel#dup)
+ InitializeImmediateClass(metaModuleClass, null);
}
internal RubyModule(RubyContext/*!*/ context, string name, Action methodsInitializer, Action constantsInitializer,
@@ -548,16 +597,20 @@
}
object IDuplicable.Duplicate(RubyContext/*!*/ context, bool copySingletonMembers) {
- // the meta-module class of this module is the singleton's super class:
- RubyModule result = new RubyModule(_singletonClass.SuperClass, null);
-
+
+ // capture the current immediate class (it can change any time if it not a singleton class)
+ RubyClass immediate = _immediateClass;
+
+ RubyModule result = new RubyModule(immediate.IsSingletonClass ? immediate.SuperClass : immediate, null);
+
// singleton members are copied here, not in InitializeCopy:
- if (copySingletonMembers && !IsSingletonClass) {
+ if (copySingletonMembers && immediate.IsSingletonClass) {
+ var singletonClass = result.GetOrCreateSingletonClass();
using (Context.ClassHierarchyLocker()) {
- result.SingletonClass.InitializeMembersFrom(SingletonClass);
+ singletonClass.InitializeMembersFrom(immediate);
}
}
-
+
// copy instance variables:
_context.CopyInstanceData(this, result, false);
return result;
@@ -569,6 +622,7 @@
// A version of a frozen module can still change if its super-classes/mixins change.
private void Mutate() {
+ Debug.Assert(!IsDummySingletonClass);
if (IsFrozen) {
throw RubyExceptions.CreateTypeError(String.Format("can't modify frozen {0}", IsClass ? "class" : "module"));
}
@@ -664,11 +718,10 @@
// thread-safe:
public RubyClass ImmediateClass {
get {
- return _singletonClass;
+ return _immediateClass;
}
set {
- // all modules have singleton classes initialized at the creation time, these cannot be changed:
- throw Assert.Unreachable;
+ throw new InvalidOperationException("Cannot change the immediate class of a module");
}
}
@@ -730,31 +783,42 @@
}
// thread safe:
- public RubyClass/*!*/ CreateSingletonClass() {
- Debug.Assert(!IsDummySingletonClass);
+ public RubyClass/*!*/ GetOrCreateSingletonClass() {
+ if (IsDummySingletonClass) {
+ throw new InvalidOperationException("Dummy singleton class has no singleton class");
+ }
- var singleton = _singletonClass;
- if (singleton.IsDummySingletonClass) {
- RubyClass super = ((RubyModule)singleton.SingletonClassOf).IsClass ? Context.ClassClass.SingletonClass : Context.ModuleClass.SingletonClass;
- RubyClass newDummy = CreateDummySingletonClass(super, Context.SingletonSingletonTrait);
-
- // update singleton only if it still points to itself:
- Interlocked.CompareExchange(ref singleton._singletonClass, newDummy, singleton);
+ RubyClass immediate = _immediateClass;
+ RubyClass singletonSuper;
+ RubyClass singletonImmediate;
+
+ if (!immediate.IsSingletonClass) {
+ // finish module singleton initialization:
+ Debug.Assert(!IsClass);
+ singletonSuper = immediate;
+ singletonImmediate = immediate.GetDummySingletonClass();
+ } else if (immediate.IsDummySingletonClass) {
+ // expanding singleton chain:
+ singletonSuper = immediate.SuperClass;
+ singletonImmediate = immediate;
+ } else {
+ return immediate;
}
- Debug.Assert(_singletonClass.IsSingletonClass && !_singletonClass.IsDummySingletonClass);
- return _singletonClass;
- }
+ var singleton = CreateSingletonClass(singletonSuper, null);
+ singleton.InitializeImmediateClass(singletonImmediate);
+ Interlocked.CompareExchange(ref _immediateClass, singleton, immediate);
- // thread safe:
- internal void InitializeDummySingletonClass(RubyClass/*!*/ superClass, Action trait) {
- // if multiple threads are trying to set the singleton, the first one should win:
- var previous = Interlocked.CompareExchange(ref _singletonClass, CreateDummySingletonClass(superClass, trait), null);
- Debug.Assert(previous == null);
+ Debug.Assert(_immediateClass.IsSingletonClass && !_immediateClass.IsDummySingletonClass);
+ return _immediateClass;
}
- // thread safe:
- private RubyClass/*!*/ CreateDummySingletonClass(RubyClass/*!*/ superClass, Action trait) {
+ ///
+ /// Create a new singleton class for this module.
+ /// Doesn't attach this module to it yet, the caller needs to do so.
+ ///
+ /// Thread safe.
+ internal RubyClass/*!*/ CreateSingletonClass(RubyClass/*!*/ superClass, Action trait) {
// Note that in MRI, member tables of dummy singleton are shared with the class the dummy is singleton for
// This is obviously an implementation detail leaking to the language and we don't support that.
@@ -770,9 +834,6 @@
#if DEBUG
result.Version.SetName(result.DebugName);
#endif
- result._singletonClass = result;
-
- // MRI:
return result;
}
@@ -1222,7 +1283,8 @@
public void SetModuleFunctionNoEventNoLock(RubyContext/*!*/ callerContext, string/*!*/ name, RubyMemberInfo/*!*/ method) {
// CLR members: Detaches the member from its underlying type (by creating a copy).
// TODO: check for CLR instance members, it should be an error to call module_function on them:
- SingletonClass.SetMethodNoEventNoLock(callerContext, name, method.Copy(RubyMemberFlags.Public, SingletonClass));
+ var singletonClass = GetOrCreateSingletonClass();
+ singletonClass.SetMethodNoEventNoLock(callerContext, name, method.Copy(RubyMemberFlags.Public, singletonClass));
}
// thread-safe:
@@ -1949,7 +2011,8 @@
}
if (classTrait != null) {
- SingletonClass.IncludeTraitNoLock(ref SingletonClass._methodsInitializer, SingletonClass._methodsState, classTrait);
+ var singleton = GetOrCreateSingletonClass();
+ singleton.IncludeTraitNoLock(ref singleton._methodsInitializer, singleton._methodsState, classTrait);
}
// updates the module version:
@@ -1980,7 +2043,7 @@
RubyModule module = singletonOf as RubyModule;
- if (module == null) {
+ if (module == null || !module.IsSingletonClass && module.Name == null) {
nestings++;
result.Append("#<");
result.Append(c.SuperClass.GetName(context));
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyStruct.cs;C1561136
File: RubyStruct.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyStruct.cs;C1561136 (server) 2/10/2010 2:05 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyStruct.cs;SingletonOptimizations
@@ -148,13 +148,15 @@
var newInstance = new RuleGenerator(RuleGenerators.InstanceConstructor);
var context = cls.Context;
- cls.SingletonClass.AddMethod(context, "[]", new RubyCustomMethodInfo(newInstance, RubyMemberFlags.Public, cls.SingletonClass));
- cls.SingletonClass.AddMethod(context, "new", new RubyCustomMethodInfo(newInstance, RubyMemberFlags.Public, cls.SingletonClass));
+ var singletonClass = cls.GetOrCreateSingletonClass();
- cls.SingletonClass.AddMethod(context, "members", new RubyLibraryMethodInfo(
+ singletonClass.AddMethod(context, "[]", new RubyCustomMethodInfo(newInstance, RubyMemberFlags.Public, singletonClass));
+ singletonClass.AddMethod(context, "new", new RubyCustomMethodInfo(newInstance, RubyMemberFlags.Public, singletonClass));
+
+ singletonClass.AddMethod(context, "members", new RubyLibraryMethodInfo(
new[] { LibraryOverload.Create(new Func(GetMembers), false, 0, 0) },
- RubyMemberFlags.Public,
- cls.SingletonClass
+ RubyMemberFlags.Public,
+ singletonClass
));
for (int i = 0; i < structMembers.Length; i++) {
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Compiler/ReflectionCache.Generated.cs;C1569144
File: ReflectionCache.Generated.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Compiler/ReflectionCache.Generated.cs;C1569144 (server) 2/11/2010 12:00 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Compiler/ReflectionCache.Generated.cs;SingletonOptimizations
@@ -402,6 +402,8 @@
private static MethodInfo _MakeTopLevelSuperException;
public static MethodInfo/*!*/ MakeTypeConversionError { get { return _MakeTypeConversionError ?? (_MakeTypeConversionError = CallInstruction.CacheFunc(RubyOps.MakeTypeConversionError)); } }
private static MethodInfo _MakeTypeConversionError;
+ public static MethodInfo/*!*/ MakeVirtualClassInstantiatedError { get { return _MakeVirtualClassInstantiatedError ?? (_MakeVirtualClassInstantiatedError = CallInstruction.CacheFunc(RubyOps.MakeVirtualClassInstantiatedError)); } }
+ private static MethodInfo _MakeVirtualClassInstantiatedError;
public static MethodInfo/*!*/ MakeWrongNumberOfArgumentsError { get { return _MakeWrongNumberOfArgumentsError ?? (_MakeWrongNumberOfArgumentsError = CallInstruction.CacheFunc(RubyOps.MakeWrongNumberOfArgumentsError)); } }
private static MethodInfo _MakeWrongNumberOfArgumentsError;
public static MethodInfo/*!*/ MarkException { get { return _MarkException ?? (_MarkException = CallInstruction.CacheFunc(RubyOps.MarkException)); } }
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;C1561136
File: RubyContext.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;C1561136 (server) 2/10/2010 10:49 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;SingletonOptimizations
@@ -242,8 +242,6 @@
private RubyClass _standardErrorClass;
private RubyClass _comObjectClass;
- private Action/*!*/ _classSingletonTrait;
- private Action/*!*/ _singletonSingletonTrait;
private Action/*!*/ _mainSingletonTrait;
// internally set by Initializer:
@@ -268,9 +266,6 @@
}
}
- internal Action/*!*/ ClassSingletonTrait { get { return _classSingletonTrait; } }
- internal Action/*!*/ SingletonSingletonTrait { get { return _singletonSingletonTrait; } }
-
// Set of names that method_missing defined on any module was resolved for and that are cached. Lazy init.
//
// Note: We used to have this set per module but that doesn't work - see unit test MethodCallCaching_MethodMissing4.
@@ -611,8 +606,6 @@
// TODO: internal
public void RegisterPrimitives(
- Action/*!*/ classSingletonTrait,
- Action/*!*/ singletonSingletonTrait,
Action/*!*/ mainSingletonTrait,
Action/*!*/ kernelInstanceTrait,
@@ -631,12 +624,10 @@
Action/*!*/ classClassTrait,
Action classConstantsInitializer) {
- Assert.NotNull(classSingletonTrait, singletonSingletonTrait, mainSingletonTrait);
+ Assert.NotNull(mainSingletonTrait);
Assert.NotNull(objectInstanceTrait, kernelInstanceTrait, moduleInstanceTrait, classInstanceTrait);
Assert.NotNull(objectClassTrait, kernelClassTrait, moduleClassTrait, classClassTrait);
- _classSingletonTrait = classSingletonTrait;
- _singletonSingletonTrait = singletonSingletonTrait;
_mainSingletonTrait = mainSingletonTrait;
// inheritance hierarchy:
@@ -669,12 +660,20 @@
_objectClass = new RubyClass(this, Symbols.Object, objectTracker.Type, null, objectInstanceTrait, objectConstantsInitializer, null, null, new[] { _kernelModule }, objectTracker, null, false, false, ModuleRestrictions.Builtin & ~ModuleRestrictions.NoOverrides);
_moduleClass = new RubyClass(this, Symbols.Module, typeof(RubyModule), null, moduleInstanceTrait, moduleConstantsInitializer, moduleFactories, _objectClass, null, null, null, false, false, ModuleRestrictions.Builtin);
_classClass = new RubyClass(this, Symbols.Class, typeof(RubyClass), null, classInstanceTrait, classConstantsInitializer, classFactories, _moduleClass, null, null, null, false, false, ModuleRestrictions.Builtin);
+
+ _objectClass.InitializeImmediateClass(_objectClass.CreateSingletonClass(_classClass, objectClassTrait));
+ _moduleClass.InitializeImmediateClass(_moduleClass.CreateSingletonClass(_objectClass.ImmediateClass, moduleClassTrait));
+ _classClass.InitializeImmediateClass(_classClass.CreateSingletonClass(_moduleClass.ImmediateClass, classClassTrait));
- _kernelModule.InitializeDummySingletonClass(_moduleClass, kernelClassTrait);
- _objectClass.InitializeDummySingletonClass(_classClass, objectClassTrait);
- _moduleClass.InitializeDummySingletonClass(_objectClass.SingletonClass, moduleClassTrait);
- _classClass.InitializeDummySingletonClass(_moduleClass.SingletonClass, classClassTrait);
+ _moduleClass.InitializeDummySingleton();
+ _classClass.InitializeDummySingleton();
+ _objectClass.ImmediateClass.InitializeImmediateClass(_classClass.GetDummySingletonClass());
+ _moduleClass.ImmediateClass.InitializeImmediateClass(_classClass.GetDummySingletonClass());
+ _classClass.ImmediateClass.InitializeImmediateClass(_classClass.GetDummySingletonClass());
+
+ _kernelModule.InitializeImmediateClass(_moduleClass, kernelClassTrait);
+
_objectClass.SetConstantNoMutateNoLock(_moduleClass.Name, _moduleClass);
_objectClass.SetConstantNoMutateNoLock(_classClass.Name, _classClass);
_objectClass.SetConstantNoMutateNoLock(_objectClass.Name, _objectClass);
@@ -877,6 +876,9 @@
#region Class and Module Factories (thread-safe)
+ ///
+ /// Class factory. Do not use RubyClass constructor except for special cases (Object, Class, Module, singleton classes).
+ ///
internal RubyClass/*!*/ CreateClass(string name, Type type, object classSingletonOf,
Action instanceTrait, Action classTrait, Action constantsInitializer, Delegate/*!*/[] factories,
RubyClass/*!*/ superClass, RubyModule/*!*/[] expandedMixins, TypeTracker tracker, RubyStruct.Info structInfo,
@@ -888,10 +890,13 @@
isRubyClass, isSingletonClass, restrictions
);
- result.InitializeDummySingletonClass(superClass.SingletonClass, classTrait);
+ result.InitializeImmediateClass(superClass.ImmediateClass, classTrait);
return result;
}
+ ///
+ /// Module factory. Do not use RubyModule constructor except special cases (Kernel).
+ ///
internal RubyModule/*!*/ CreateModule(string name,
Action instanceTrait, Action classTrait, Action constantsInitializer,
RubyModule/*!*/[] expandedMixins, NamespaceTracker namespaceTracker, TypeTracker typeTracker, ModuleRestrictions restrictions) {
@@ -899,27 +904,28 @@
RubyModule result = new RubyModule(
this, name, instanceTrait, constantsInitializer, expandedMixins, namespaceTracker, typeTracker, restrictions
);
- result.InitializeDummySingletonClass(_moduleClass, classTrait);
+
+ result.InitializeImmediateClass(_moduleClass, classTrait);
return result;
}
///
/// Creates a singleton class for specified object unless it already exists.
///
- public RubyClass/*!*/ CreateSingletonClass(object obj) {
+ public RubyClass/*!*/ GetOrCreateSingletonClass(object obj) {
RubyModule module = obj as RubyModule;
if (module != null) {
- return module.CreateSingletonClass();
+ return module.GetOrCreateSingletonClass();
}
- return CreateInstanceSingleton(obj, null, null, null, null);
+ return GetOrCreateInstanceSingleton(obj, null, null, null, null);
}
- internal RubyClass/*!*/ CreateMainSingleton(object obj, RubyModule/*!*/[] expandedMixins) {
- return CreateInstanceSingleton(obj, _mainSingletonTrait, null, null, expandedMixins);
+ internal RubyClass/*!*/ GetOrCreateMainSingleton(object obj, RubyModule/*!*/[] expandedMixins) {
+ return GetOrCreateInstanceSingleton(obj, _mainSingletonTrait, null, null, expandedMixins);
}
- internal RubyClass/*!*/ CreateInstanceSingleton(object obj, Action instanceTrait, Action classTrait,
+ internal RubyClass/*!*/ GetOrCreateInstanceSingleton(object obj, Action instanceTrait, Action classTrait,
Action constantsInitializer, RubyModule/*!*/[] expandedMixins) {
Debug.Assert(!(obj is RubyModule));
Debug.Assert(RubyUtils.HasSingletonClass(obj));
@@ -940,7 +946,7 @@
}
RubyClass result = CreateClass(
- null, null, obj, instanceTrait, classTrait ?? _classSingletonTrait, constantsInitializer, null,
+ null, null, obj, instanceTrait, classTrait, constantsInitializer, null,
immediate, expandedMixins, null, null, true, true, ModuleRestrictions.None
);
@@ -2384,7 +2390,7 @@
}
RubyObject mainObject = new RubyObject(_objectClass);
- RubyClass mainSingleton = CreateMainSingleton(mainObject, null);
+ RubyClass mainSingleton = GetOrCreateMainSingleton(mainObject, null);
RubyGlobalScope result = new RubyGlobalScope(this, globalScope, mainObject, createHosted);
if (bindGlobals) {
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptionData.cs;C1479709
File: RubyExceptionData.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptionData.cs;C1479709 (server) 2/10/2010 2:21 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptionData.cs;SingletonOptimizations
@@ -405,7 +405,7 @@
RubyClass exceptionClass = context.GetClass(exception.GetType());
// new resolves to Class#new built-in method:
- var newMethod = exceptionClass.SingletonClass.ResolveMethod("new", VisibilityContext.AllVisible);
+ var newMethod = exceptionClass.ImmediateClass.ResolveMethod("new", VisibilityContext.AllVisible);
if (newMethod.Found && newMethod.Info.DeclaringModule == context.ClassClass && newMethod.Info is RubyCustomMethodInfo) {
// initialize resolves to a built-in method:
var initializeMethod = exceptionClass.ResolveMethod("initialize", VisibilityContext.AllVisible);
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptions.cs;C1544575
File: RubyExceptions.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptions.cs;C1544575 (server) 2/11/2010 10:48 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptions.cs;SingletonOptimizations
@@ -99,6 +99,11 @@
}
public static Exception/*!*/ CreateUndefinedMethodError(RubyModule/*!*/ module, string/*!*/ methodName) {
+ // MRI doesn't display the singleton's name:
+ if (module.IsSingletonClass) {
+ module = ((RubyClass)module).GetNonSingletonClass();
+ }
+
return CreateNameError("undefined method `{0}' for {2} `{1}'",
methodName, module.Name, module.IsClass ? "class" : "module");
}
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;C1496258
File: RubyOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;C1496258 (server) 2/10/2010 2:01 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;SingletonOptimizations
@@ -504,7 +504,7 @@
instanceOwner = null;
instanceFlags = RubyMemberFlags.Invalid;
- singletonOwner = scope.RubyContext.CreateSingletonClass(target);
+ singletonOwner = scope.RubyContext.GetOrCreateSingletonClass(target);
singletonFlags = RubyMemberFlags.Public;
} else {
var attributesScope = scope.GetMethodAttributesDefinitionScope();
@@ -527,7 +527,7 @@
}
instanceFlags = RubyMemberFlags.Private;
- singletonOwner = instanceOwner.SingletonClass;
+ singletonOwner = instanceOwner.GetOrCreateSingletonClass();
singletonFlags = RubyMemberFlags.Public;
moduleFunction = true;
} else {
@@ -559,7 +559,7 @@
if (moduleFunction) {
Debug.Assert(!method.DeclaringModule.IsClass);
- method.DeclaringModule.SingletonClass.MethodAdded(body.Name);
+ method.DeclaringModule.GetOrCreateSingletonClass().MethodAdded(body.Name);
}
return null;
@@ -642,7 +642,7 @@
if (!RubyUtils.HasSingletonClass(obj)) {
throw RubyExceptions.CreateTypeError(String.Format("no virtual class for {0}", scope.RubyContext.GetClassOf(obj).Name));
}
- return scope.RubyContext.CreateSingletonClass(obj);
+ return scope.RubyContext.GetOrCreateSingletonClass(obj);
}
[Emitted]
@@ -1768,6 +1768,11 @@
}
[Emitted]
+ public static Exception/*!*/ MakeVirtualClassInstantiatedError() {
+ return RubyExceptions.CreateTypeError("can't create instance of virtual class");
+ }
+
+ [Emitted]
public static Exception/*!*/ MakeAbstractMethodCalledError(RuntimeMethodHandle/*!*/ method) {
return new NotImplementedException(String.Format("Abstract method `{0}' not implemented", MethodInfo.GetMethodFromHandle(method)));
}
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyScope.cs;C1561136
File: RubyScope.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyScope.cs;C1561136 (server) 2/10/2010 2:01 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyScope.cs;SingletonOptimizations
@@ -1052,7 +1052,7 @@
RubyModule module = context.CreateModule(null, null, null, null, null, null, null, ModuleRestrictions.None);
RubyObject mainObject = new RubyObject(context.ObjectClass);
- context.CreateMainSingleton(mainObject, new[] { module });
+ context.GetOrCreateMainSingleton(mainObject, new[] { module });
RubyTopLevelScope scope = new RubyTopLevelScope(rubyGlobalScope, module, null, mainObject);
scope.SetDebugName("top-level-wrapped");
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;C1561136
File: RubyUtils.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;C1561136 (server) 2/8/2010 3:12 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;SingletonOptimizations
@@ -885,7 +885,7 @@
}
object result;
- EvaluateBlock(block, block.RubyContext.CreateSingletonClass(self), self, args, out result);
+ EvaluateBlock(block, block.RubyContext.GetOrCreateSingletonClass(self), self, args, out result);
return result;
}
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyMetaBinder.cs;C1475764
File: RubyMetaBinder.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyMetaBinder.cs;C1475764 (server) 2/8/2010 4:17 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyMetaBinder.cs;SingletonOptimizations
@@ -19,19 +19,20 @@
using Microsoft.Scripting.Ast;
#endif
+using System;
+using System.Collections.Generic;
using System.Dynamic;
using System.Diagnostics;
-using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Text;
using Microsoft.Scripting.Utils;
-using System.Collections.Generic;
-using AstUtils = Microsoft.Scripting.Ast.Utils;
-using System.Reflection;
using Microsoft.Scripting;
+using Microsoft.Scripting.Interpreter;
using Microsoft.Scripting.Runtime;
-using System.Runtime.CompilerServices;
-using Microsoft.Scripting.Interpreter;
namespace IronRuby.Runtime.Calls {
+ using AstUtils = Microsoft.Scripting.Ast.Utils;
using Ast = Expression;
public abstract class RubyMetaBinder : DynamicMetaObjectBinder, ILightCallSiteBinder, IExpressionSerializable {
@@ -84,6 +85,22 @@
return null;
}
+#if DEBUG
+ if (RubyOptions.ShowRules) {
+ var sb = new StringBuilder();
+ for (int i = 1; i < args.Length; i++) {
+ sb.Append(RubyUtils.ObjectToMutableString(context, args[i]));
+ sb.Append(", ");
+ }
+
+ Utils.Log(String.Format(
+ "{0}: {1}; {2}",
+ this,
+ sb,
+ args.Length > 1 ? context.GetClassOf(args[1]).DebugName : null
+ ), "BIND");
+ }
+#endif
result = this.LightBind(site, args, context.Options.CompilationThreshold);
CacheTarget(result);
return result;
===================================================================